From 485ae77dc7f484563707557ccf8c5d228980619f Mon Sep 17 00:00:00 2001 From: Sven Anders Date: Thu, 24 Aug 2006 17:11:50 +0200 Subject: [WATCHDOG] Winbond SMsC37B787 watchdog driver New watchdog driver for the Winbond SMsC37B787 chipset. Signed-off-by: Sven Anders Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 20 ++ drivers/char/watchdog/Makefile | 1 + drivers/char/watchdog/smsc37b787_wdt.c | 614 +++++++++++++++++++++++++++++++++ 3 files changed, 635 insertions(+) create mode 100644 drivers/char/watchdog/smsc37b787_wdt.c (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 89e46d6dfc4..8d2ebc73c89 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -395,6 +395,26 @@ config CPU5_WDT To compile this driver as a module, choose M here: the module will be called cpu5wdt. +config SMSC37B787_WDT + tristate "Winbond SMsC37B787 Watchdog Timer" + depends on WATCHDOG && X86 + ---help--- + This is the driver for the hardware watchdog component on the + Winbond SMsC37B787 chipset as used on the NetRunner Mainboard + from Vision Systems and maybe others. + + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. + + Usually a userspace daemon will notify the kernel WDT driver that + userspace is still alive, at regular intervals. + + To compile this driver as a module, choose M here: the + module will be called smsc37b787_wdt. + + Most people will say N. + config W83627HF_WDT tristate "W83627HF Watchdog Timer" depends on WATCHDOG && X86 diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 7f70abad465..630526f1237 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o +obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c new file mode 100644 index 00000000000..47141c0b6f2 --- /dev/null +++ b/drivers/char/watchdog/smsc37b787_wdt.c @@ -0,0 +1,614 @@ +/* + * SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x + * + * Based on acquirewdt.c by Alan Cox + * and some other existing drivers + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * The authors do NOT admit liability nor provide warranty for + * any of this software. This material is provided "AS-IS" in + * the hope that it may be useful for others. + * + * (C) Copyright 2003-2006 Sven Anders + * + * History: + * 2003 - Created version 1.0 for Linux 2.4.x. + * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE + * features. Released version 1.1 + * + * Theory of operation: + * + * A Watchdog Timer (WDT) is a hardware circuit that can + * reset the computer system in case of a software fault. + * You probably knew that already. + * + * Usually a userspace daemon will notify the kernel WDT driver + * via the /dev/watchdog special device file that userspace is + * still alive, at regular intervals. When such a notification + * occurs, the driver will usually tell the hardware watchdog + * that everything is in order, and that the watchdog should wait + * for yet another little while to reset the system. + * If userspace fails (RAM error, kernel bug, whatever), the + * notifications cease to occur, and the hardware watchdog will + * reset the system (causing a reboot) after the timeout occurs. + * + * Create device with: + * mknod /dev/watchdog c 10 130 + * + * For an example userspace keep-alive daemon, see: + * Documentation/watchdog/watchdog.txt + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* enable support for minutes as units? */ +/* (does not always work correctly, so disabled by default!) */ +#define SMSC_SUPPORT_MINUTES +#undef SMSC_SUPPORT_MINUTES + +#define MAX_TIMEOUT 255 + +#define UNIT_SECOND 0 +#define UNIT_MINUTE 1 + +#define MODNAME "smsc37b787_wdt: " +#define VERSION "1.1" + +#define WATCHDOG_MINOR 130 + +#define IOPORT 0x3F0 +#define IOPORT_SIZE 2 +#define IODEV_NO 8 + +static int unit = UNIT_SECOND; /* timer's unit */ +static int timeout = 60; /* timeout value: default is 60 "units" */ +static int timer_enabled = 0; /* is the timer enabled? */ + +static char expect_close; /* is the close expected? */ + +static int nowayout = WATCHDOG_NOWAYOUT; + +/* -- Low level function ----------------------------------------*/ + +/* unlock the IO chip */ + +static inline void open_io_config(void) +{ + outb(0x55, IOPORT); + mdelay(1); + outb(0x55, IOPORT); +} + +/* lock the IO chip */ +static inline void close_io_config(void) +{ + outb(0xAA, IOPORT); +} + +/* select the IO device */ +static inline void select_io_device(unsigned char devno) +{ + outb(0x07, IOPORT); + outb(devno, IOPORT+1); +} + +/* write to the control register */ +static inline void write_io_cr(unsigned char reg, unsigned char data) +{ + outb(reg, IOPORT); + outb(data, IOPORT+1); +} + +/* read from the control register */ +static inline char read_io_cr(unsigned char reg) +{ + outb(reg, IOPORT); + return inb(IOPORT+1); +} + +/* -- Medium level functions ------------------------------------*/ + +static inline void gpio_bit12(unsigned char reg) +{ + // -- General Purpose I/O Bit 1.2 -- + // Bit 0, In/Out: 0 = Output, 1 = Input + // Bit 1, Polarity: 0 = No Invert, 1 = Invert + // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable + // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, + // 11 = Either Edge Triggered Intr. 2 + // Bit 5/6 (Reserved) + // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain + write_io_cr(0xE2, reg); +} + +static inline void gpio_bit13(unsigned char reg) +{ + // -- General Purpose I/O Bit 1.3 -- + // Bit 0, In/Out: 0 = Output, 1 = Input + // Bit 1, Polarity: 0 = No Invert, 1 = Invert + // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable + // Bit 3, Function select: 0 = GPI/O, 1 = LED + // Bit 4-6 (Reserved) + // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain + write_io_cr(0xE3, reg); +} + +static inline void wdt_timer_units(unsigned char new_units) +{ + // -- Watchdog timer units -- + // Bit 0-6 (Reserved) + // Bit 7, WDT Time-out Value Units Select + // (0 = Minutes, 1 = Seconds) + write_io_cr(0xF1, new_units); +} + +static inline void wdt_timeout_value(unsigned char new_timeout) +{ + // -- Watchdog Timer Time-out Value -- + // Bit 0-7 Binary coded units (0=Disabled, 1..255) + write_io_cr(0xF2, new_timeout); +} + +static inline void wdt_timer_conf(unsigned char conf) +{ + // -- Watchdog timer configuration -- + // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O + // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. + // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. + // Bit 3 Reset the timer + // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) + // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, + // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) + write_io_cr(0xF3, conf); +} + +static inline void wdt_timer_ctrl(unsigned char reg) +{ + // -- Watchdog timer control -- + // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured + // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz + // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) + // Bit 3 P20 Force Timeout enabled: + // 0 = P20 activity does not generate the WD timeout event + // 1 = P20 Allows rising edge of P20, from the keyboard + // controller, to force the WD timeout event. + // Bit 4 (Reserved) + // -- Soft power management -- + // Bit 5 Stop Counter: 1 = Stop software power down counter + // set via register 0xB8, (self-cleaning) + // (Upon read: 0 = Counter running, 1 = Counter stopped) + // Bit 6 Restart Counter: 1 = Restart software power down counter + // set via register 0xB8, (self-cleaning) + // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) + + write_io_cr(0xF4, reg); +} + +/* -- Higher level functions ------------------------------------*/ + +/* initialize watchdog */ + +static void wb_smsc_wdt_initialize(void) +{ + unsigned char old; + + open_io_config(); + select_io_device(IODEV_NO); + + // enable the watchdog + gpio_bit13(0x08); // Select pin 80 = LED not GPIO + gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert + + // disable the timeout + wdt_timeout_value(0); + + // reset control register + wdt_timer_ctrl(0x00); + + // reset configuration register + wdt_timer_conf(0x00); + + // read old (timer units) register + old = read_io_cr(0xF1) & 0x7F; + if (unit == UNIT_SECOND) old |= 0x80; // set to seconds + + // set the watchdog timer units + wdt_timer_units(old); + + close_io_config(); +} + +/* shutdown the watchdog */ + +static void wb_smsc_wdt_shutdown(void) +{ + open_io_config(); + select_io_device(IODEV_NO); + + // disable the watchdog + gpio_bit13(0x09); + gpio_bit12(0x09); + + // reset watchdog config register + wdt_timer_conf(0x00); + + // reset watchdog control register + wdt_timer_ctrl(0x00); + + // disable timeout + wdt_timeout_value(0x00); + + close_io_config(); +} + +/* set timeout => enable watchdog */ + +static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) +{ + open_io_config(); + select_io_device(IODEV_NO); + + // set Power LED to blink, if we enable the timeout + wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); + + // set timeout value + wdt_timeout_value(new_timeout); + + close_io_config(); +} + +/* get timeout */ + +static unsigned char wb_smsc_wdt_get_timeout(void) +{ + unsigned char set_timeout; + + open_io_config(); + select_io_device(IODEV_NO); + set_timeout = read_io_cr(0xF2); + close_io_config(); + + return set_timeout; +} + +/* disable watchdog */ + +static void wb_smsc_wdt_disable(void) +{ + // set the timeout to 0 to disable the watchdog + wb_smsc_wdt_set_timeout(0); +} + +/* enable watchdog by setting the current timeout */ + +static void wb_smsc_wdt_enable(void) +{ + // set the current timeout... + wb_smsc_wdt_set_timeout(timeout); +} + +/* reset the timer */ + +static void wb_smsc_wdt_reset_timer(void) +{ + open_io_config(); + select_io_device(IODEV_NO); + + // reset the timer + wdt_timeout_value(timeout); + wdt_timer_conf(0x08); + + close_io_config(); +} + +/* return, if the watchdog is enabled (timeout is set...) */ + +static int wb_smsc_wdt_status(void) +{ + return (wb_smsc_wdt_get_timeout() == 0) ? 0 : WDIOF_KEEPALIVEPING; +} + + +/* -- File operations -------------------------------------------*/ + +/* open => enable watchdog and set initial timeout */ + +static int wb_smsc_wdt_open(struct inode *inode, struct file *file) +{ + /* /dev/watchdog can only be opened once */ + + if (timer_enabled) + return -EBUSY; + + if (nowayout) + __module_get(THIS_MODULE); + + /* Reload and activate timer */ + timer_enabled = 1; + wb_smsc_wdt_enable(); + + printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); + + return nonseekable_open(inode, file); +} + +/* close => shut off the timer */ + +static int wb_smsc_wdt_release(struct inode *inode, struct file *file) +{ + /* Shut off the timer. */ + + if (expect_close == 42) { + wb_smsc_wdt_disable(); + printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); + } else { + printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); + wb_smsc_wdt_reset_timer(); + } + + timer_enabled = 0; + expect_close = 0; + return 0; +} + +/* write => update the timer to keep the machine alive */ + +static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + /* See if we got the magic character 'V' and reload the timer */ + if (len) { + if (!nowayout) { + size_t i; + + /* reset expect flag */ + expect_close = 0; + + /* scan to see whether or not we got the magic character */ + for (i = 0; i != len; i++) { + char c; + if (get_user(c, data+i)) + return -EFAULT; + if (c == 'V') + expect_close = 42; + } + } + + /* someone wrote to us, we should reload the timer */ + wb_smsc_wdt_reset_timer(); + } + return len; +} + +/* ioctl => control interface */ + +static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int new_timeout; + + union { + struct watchdog_info __user *ident; + int __user *i; + } uarg; + + static struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | + WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "SMsC 37B787 Watchdog" + }; + + uarg.i = (int __user *)arg; + + switch (cmd) { + default: + return -ENOTTY; + + case WDIOC_GETSUPPORT: + return copy_to_user(uarg.ident, &ident, sizeof(ident)); + + case WDIOC_GETSTATUS: + return put_user(wb_smsc_wdt_status(), uarg.i); + + case WDIOC_GETBOOTSTATUS: + return put_user(0, uarg.i); + + case WDIOC_KEEPALIVE: + wb_smsc_wdt_reset_timer(); + return 0; + + case WDIOC_SETTIMEOUT: + if (get_user(new_timeout, uarg.i)) + return -EFAULT; + + // the API states this is given in secs + if (unit == UNIT_MINUTE) + new_timeout /= 60; + + if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) + return -EINVAL; + + timeout = new_timeout; + wb_smsc_wdt_set_timeout(timeout); + + // fall through and return the new timeout... + + case WDIOC_GETTIMEOUT: + + new_timeout = timeout; + + if (unit == UNIT_MINUTE) + new_timeout *= 60; + + return put_user(new_timeout, uarg.i); + + case WDIOC_SETOPTIONS: + { + int options, retval = -EINVAL; + + if (get_user(options, uarg.i)) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) { + wb_smsc_wdt_disable(); + retval = 0; + } + + if (options & WDIOS_ENABLECARD) { + wb_smsc_wdt_enable(); + retval = 0; + } + + return retval; + } + } +} + +/* -- Notifier funtions -----------------------------------------*/ + +static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) +{ + if (code == SYS_DOWN || code == SYS_HALT) + { + // set timeout to 0, to avoid possible race-condition + timeout = 0; + wb_smsc_wdt_disable(); + } + return NOTIFY_DONE; +} + +/* -- Module's structures ---------------------------------------*/ + +static struct file_operations wb_smsc_wdt_fops = +{ + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wb_smsc_wdt_write, + .ioctl = wb_smsc_wdt_ioctl, + .open = wb_smsc_wdt_open, + .release = wb_smsc_wdt_release +}; + +static struct notifier_block wb_smsc_wdt_notifier = +{ + .notifier_call = wb_smsc_wdt_notify_sys +}; + +static struct miscdevice wb_smsc_wdt_miscdev = +{ + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wb_smsc_wdt_fops, +}; + +/* -- Module init functions -------------------------------------*/ + +/* module's "constructor" */ + +static int __init wb_smsc_wdt_init(void) +{ + int ret; + + printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); + + if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { + printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); + ret = -EBUSY; + goto out_pnp; + } + + ret = register_reboot_notifier(&wb_smsc_wdt_notifier); + if (ret) { + printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); + goto out_io; + } + + ret = misc_register(&wb_smsc_wdt_miscdev); + if (ret) { + printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); + goto out_rbt; + } + + // init the watchdog timer + wb_smsc_wdt_initialize(); + + // set new maximum, if it's too big + if (timeout > MAX_TIMEOUT) + timeout = MAX_TIMEOUT; + + // output info + printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); + printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); + + // ret = 0 + +out_clean: + return ret; + +out_rbt: + unregister_reboot_notifier(&wb_smsc_wdt_notifier); + +out_io: + release_region(IOPORT, IOPORT_SIZE); + +out_pnp: + goto out_clean; +} + +/* module's "destructor" */ + +static void __exit wb_smsc_wdt_exit(void) +{ + /* Stop the timer before we leave */ + if (!nowayout) + { + wb_smsc_wdt_shutdown(); + printk(KERN_INFO MODNAME "Watchdog disabled.\n"); + } + + misc_deregister(&wb_smsc_wdt_miscdev); + unregister_reboot_notifier(&wb_smsc_wdt_notifier); + release_region(IOPORT, IOPORT_SIZE); + + printk("SMsC 37B787 watchdog component driver removed.\n"); +} + +module_init(wb_smsc_wdt_init); +module_exit(wb_smsc_wdt_exit); + +MODULE_AUTHOR("Sven Anders "); +MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); +MODULE_LICENSE("GPL"); + +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + +#ifdef SMSC_SUPPORT_MINUTES +module_param(unit, int, 0); +MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); +#endif + +module_param(timeout, int, 60); +MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); -- cgit From 8386c8cfb2131b2a9caae3db6bf94292bbbe1caf Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 2 Sep 2006 19:32:26 +0200 Subject: [WATCHDOG] Winbond SMsC37B787 - remove trailing whitespace Remove trailing whitespace. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/smsc37b787_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c index 47141c0b6f2..1d01b3074db 100644 --- a/drivers/char/watchdog/smsc37b787_wdt.c +++ b/drivers/char/watchdog/smsc37b787_wdt.c @@ -8,7 +8,7 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * + * * The authors do NOT admit liability nor provide warranty for * any of this software. This material is provided "AS-IS" in * the hope that it may be useful for others. @@ -422,7 +422,7 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, switch (cmd) { default: - return -ENOTTY; + return -ENOTTY; case WDIOC_GETSUPPORT: return copy_to_user(uarg.ident, &ident, sizeof(ident)); @@ -573,7 +573,7 @@ out_io: out_pnp: goto out_clean; -} +} /* module's "destructor" */ -- cgit From aa1fd4d7c3b131026bf156da40fdf94bcbd705aa Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 2 Sep 2006 20:53:19 +0200 Subject: [WATCHDOG] Winbond SMsC37B787 watchdog fixes * Added io spinlocking * Deleted WATCHDOG_MINOR (it's in the miscdevice include * Changed timer_enabled to use set_bit functions * WDIOC_GETSUPPORT should return -EFAULT or 0 * timeout should be correct before we initialize the watchdog * we should initialize the watchdog before we give access to userspace * Third parameter of module_param is not the default or initial value Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/smsc37b787_wdt.c | 47 ++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c index 1d01b3074db..9f56913b484 100644 --- a/drivers/char/watchdog/smsc37b787_wdt.c +++ b/drivers/char/watchdog/smsc37b787_wdt.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -72,18 +73,18 @@ #define MODNAME "smsc37b787_wdt: " #define VERSION "1.1" -#define WATCHDOG_MINOR 130 - #define IOPORT 0x3F0 #define IOPORT_SIZE 2 #define IODEV_NO 8 static int unit = UNIT_SECOND; /* timer's unit */ static int timeout = 60; /* timeout value: default is 60 "units" */ -static int timer_enabled = 0; /* is the timer enabled? */ +static unsigned long timer_enabled = 0; /* is the timer enabled? */ static char expect_close; /* is the close expected? */ +static spinlock_t io_lock; /* to guard the watchdog from io races */ + static int nowayout = WATCHDOG_NOWAYOUT; /* -- Low level function ----------------------------------------*/ @@ -210,6 +211,7 @@ static void wb_smsc_wdt_initialize(void) { unsigned char old; + spin_lock(&io_lock); open_io_config(); select_io_device(IODEV_NO); @@ -234,12 +236,14 @@ static void wb_smsc_wdt_initialize(void) wdt_timer_units(old); close_io_config(); + spin_unlock(&io_lock); } /* shutdown the watchdog */ static void wb_smsc_wdt_shutdown(void) { + spin_lock(&io_lock); open_io_config(); select_io_device(IODEV_NO); @@ -257,12 +261,14 @@ static void wb_smsc_wdt_shutdown(void) wdt_timeout_value(0x00); close_io_config(); + spin_unlock(&io_lock); } /* set timeout => enable watchdog */ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) { + spin_lock(&io_lock); open_io_config(); select_io_device(IODEV_NO); @@ -273,6 +279,7 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) wdt_timeout_value(new_timeout); close_io_config(); + spin_unlock(&io_lock); } /* get timeout */ @@ -281,10 +288,12 @@ static unsigned char wb_smsc_wdt_get_timeout(void) { unsigned char set_timeout; + spin_lock(&io_lock); open_io_config(); select_io_device(IODEV_NO); set_timeout = read_io_cr(0xF2); close_io_config(); + spin_unlock(&io_lock); return set_timeout; } @@ -309,6 +318,7 @@ static void wb_smsc_wdt_enable(void) static void wb_smsc_wdt_reset_timer(void) { + spin_lock(&io_lock); open_io_config(); select_io_device(IODEV_NO); @@ -317,6 +327,7 @@ static void wb_smsc_wdt_reset_timer(void) wdt_timer_conf(0x08); close_io_config(); + spin_unlock(&io_lock); } /* return, if the watchdog is enabled (timeout is set...) */ @@ -335,14 +346,13 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file) { /* /dev/watchdog can only be opened once */ - if (timer_enabled) + if (test_and_set_bit(0, &timer_enabled)) return -EBUSY; if (nowayout) __module_get(THIS_MODULE); /* Reload and activate timer */ - timer_enabled = 1; wb_smsc_wdt_enable(); printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); @@ -364,7 +374,7 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file) wb_smsc_wdt_reset_timer(); } - timer_enabled = 0; + clear_bit(0, &timer_enabled); expect_close = 0; return 0; } @@ -425,7 +435,8 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, return -ENOTTY; case WDIOC_GETSUPPORT: - return copy_to_user(uarg.ident, &ident, sizeof(ident)); + return copy_to_user(uarg.ident, &ident, + sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: return put_user(wb_smsc_wdt_status(), uarg.i); @@ -506,12 +517,12 @@ static struct file_operations wb_smsc_wdt_fops = .write = wb_smsc_wdt_write, .ioctl = wb_smsc_wdt_ioctl, .open = wb_smsc_wdt_open, - .release = wb_smsc_wdt_release + .release = wb_smsc_wdt_release, }; static struct notifier_block wb_smsc_wdt_notifier = { - .notifier_call = wb_smsc_wdt_notify_sys + .notifier_call = wb_smsc_wdt_notify_sys, }; static struct miscdevice wb_smsc_wdt_miscdev = @@ -529,6 +540,8 @@ static int __init wb_smsc_wdt_init(void) { int ret; + spin_lock_init(&io_lock); + printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { @@ -537,6 +550,13 @@ static int __init wb_smsc_wdt_init(void) goto out_pnp; } + // set new maximum, if it's too big + if (timeout > MAX_TIMEOUT) + timeout = MAX_TIMEOUT; + + // init the watchdog timer + wb_smsc_wdt_initialize(); + ret = register_reboot_notifier(&wb_smsc_wdt_notifier); if (ret) { printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); @@ -549,13 +569,6 @@ static int __init wb_smsc_wdt_init(void) goto out_rbt; } - // init the watchdog timer - wb_smsc_wdt_initialize(); - - // set new maximum, if it's too big - if (timeout > MAX_TIMEOUT) - timeout = MAX_TIMEOUT; - // output info printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); @@ -607,7 +620,7 @@ module_param(unit, int, 0); MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); #endif -module_param(timeout, int, 60); +module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); module_param(nowayout, int, 0); -- cgit From f9a8c8913a95aed91bfa81f7d4043c6430423bf8 Mon Sep 17 00:00:00 2001 From: Marcus Junker Date: Thu, 24 Aug 2006 17:11:50 +0200 Subject: [WATCHDOG] w83697hf WDT driver New watchdog driver for the Winbond W83697HF chipset. Signed-off-by: Marcus Junker Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 13 ++ drivers/char/watchdog/Makefile | 1 + drivers/char/watchdog/w83697hf_wdt.c | 367 +++++++++++++++++++++++++++++++++++ 3 files changed, 381 insertions(+) create mode 100644 drivers/char/watchdog/w83697hf_wdt.c (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 8d2ebc73c89..3e67e01b073 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -430,6 +430,19 @@ config W83627HF_WDT Most people will say N. +config W83697HF_WDT + tristate "W83697HF Watchdog Timer" + depends on WATCHDOG && X86 + ---help--- + This is the driver for the hardware watchdog on the W83697HF chipset + This watchdog simply watches your kernel to make sure it doesn't freeze, + and if it does, it reboots your computer after a certain amount of time. + + To compile this driver as a module, choose M here: the + module will be called w83697hf_wdt. + + Most people will say N. + config W83877F_WDT tristate "W83877F (EMACS) Watchdog Timer" depends on WATCHDOG && X86 diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 630526f1237..ee3474190e2 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o +obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o obj-$(CONFIG_MACHZ_WDT) += machzwd.o diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c new file mode 100644 index 00000000000..ef6612e1b91 --- /dev/null +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -0,0 +1,367 @@ +/* + * w83697hf WDT driver + * + * (c) Copyright 2006 Marcus Junker + * + * Based on w83627hf_wdt.c advantechwdt.c which is based on wdt.c. + * Original copyright messages: + * + * (c) Copyright 2003 Pádraig Brady + * + * (c) Copyright 2000-2001 Marek Michalkiewicz + * + * (c) Copyright 1996 Alan Cox , All Rights Reserved. + * http://www.redhat.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Neither Marcus Junker nor ANDURAS AG admit liability nor provide + * warranty for any of this software. This material is provided + * "AS-IS" and at no charge. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define WATCHDOG_NAME "w83697hf WDT" +#define PFX WATCHDOG_NAME ": " +#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ + +static unsigned long wdt_is_open; +static char expect_close; + +/* You must set this - there is no sane way to probe for this board. */ +static int wdt_io = 0x2E; +module_param(wdt_io, int, 0); +MODULE_PARM_DESC(wdt_io, "w83697hf WDT io port (default 0x2E)"); + +static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); + +/* + * Kernel methods. + */ + +#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ +#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ +#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ + +static void +w83697hf_select_wd_register(void) +{ + outb_p(0x87, WDT_EFER); /* Enter extended function mode */ + outb_p(0x87, WDT_EFER); /* Again according to manual */ + + outb_p(0x29, WDT_EFER); /* select CR29 */ + outb_p(0x20, WDT_EFDR); /* select WDTO */ + + outb_p(0x07, WDT_EFER); /* point to logical device number reg */ + outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ + outb_p(0x30, WDT_EFER); /* select CR30 */ + outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ +} + +static void +w83697hf_unselect_wd_register(void) +{ + outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ +} + +/* tyan motherboards seem to set F5 to 0x4C ? + * So explicitly init to appropriate value. */ +static void +w83697hf_init(void) +{ + unsigned char t; + + w83697hf_select_wd_register(); + + outb_p(0xF3, WDT_EFER); /* Select CRF3 */ + + t=inb_p(WDT_EFDR); /* read CRF6 */ + if (t != 0) { + printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); + outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ + } + outb_p(0xF4, WDT_EFER); /* Select CRF4 */ + t=inb_p(WDT_EFDR); /* read CRF4 */ + t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ + outb_p(t, WDT_EFDR); /* Write back to CRF5 */ + + w83697hf_unselect_wd_register(); +} + +static void +wdt_ctrl(int timeout) +{ + w83697hf_select_wd_register(); + + outb_p(0xF4, WDT_EFER); /* Select CRF4 */ + outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ + + w83697hf_unselect_wd_register(); +} + +static int +wdt_ping(void) +{ + wdt_ctrl(timeout); + return 0; +} + +static int +wdt_disable(void) +{ + wdt_ctrl(0); + return 0; +} + +static int +wdt_set_heartbeat(int t) +{ + if ((t < 1) || (t > 63)) + return -EINVAL; + + timeout = t; + return 0; +} + +static ssize_t +wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + if (count) { + if (!nowayout) { + size_t i; + + expect_close = 0; + + for (i = 0; i != count; i++) { + char c; + if (get_user(c, buf+i)) + return -EFAULT; + if (c == 'V') + expect_close = 42; + } + } + wdt_ping(); + } + return count; +} + +static int +wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + int new_timeout; + static struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, + .firmware_version = 1, + .identity = "W83697HF WDT", + }; + + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user(argp, &ident, sizeof(ident))) + return -EFAULT; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, p); + + case WDIOC_KEEPALIVE: + wdt_ping(); + break; + + case WDIOC_SETTIMEOUT: + if (get_user(new_timeout, p)) + return -EFAULT; + if (wdt_set_heartbeat(new_timeout)) + return -EINVAL; + wdt_ping(); + /* Fall */ + + case WDIOC_GETTIMEOUT: + return put_user(timeout, p); + + case WDIOC_SETOPTIONS: + { + int options, retval = -EINVAL; + + if (get_user(options, p)) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) { + wdt_disable(); + retval = 0; + } + + if (options & WDIOS_ENABLECARD) { + wdt_ping(); + retval = 0; + } + + return retval; + } + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int +wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(0, &wdt_is_open)) + return -EBUSY; + /* + * Activate + */ + + wdt_ping(); + return nonseekable_open(inode, file); +} + +static int +wdt_close(struct inode *inode, struct file *file) +{ + if (expect_close == 42) { + wdt_disable(); + } else { + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + wdt_ping(); + } + expect_close = 0; + clear_bit(0, &wdt_is_open); + return 0; +} + +/* + * Notifier for system down + */ + +static int +wdt_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + if (code == SYS_DOWN || code == SYS_HALT) { + /* Turn the WDT off */ + wdt_disable(); + } + return NOTIFY_DONE; +} + +/* + * Kernel Interfaces + */ + +static struct file_operations wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wdt_write, + .ioctl = wdt_ioctl, + .open = wdt_open, + .release = wdt_close, +}; + +static struct miscdevice wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops, +}; + +/* + * The WDT needs to learn about soft shutdowns in order to + * turn the timebomb registers off. + */ + +static struct notifier_block wdt_notifier = { + .notifier_call = wdt_notify_sys, +}; + +static int __init +wdt_init(void) +{ + int ret; + + printk(KERN_INFO "WDT driver for the Winbond(TM) W83697HF Super I/O chip initialising.\n"); + + if (wdt_set_heartbeat(timeout)) { + wdt_set_heartbeat(WATCHDOG_TIMEOUT); + printk (KERN_INFO PFX "timeout value must be 1<=timeout<=63, using %d\n", + WATCHDOG_TIMEOUT); + } + + if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { + printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", + wdt_io); + ret = -EIO; + goto out; + } + + w83697hf_init(); + + ret = register_reboot_notifier(&wdt_notifier); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + ret); + goto unreg_regions; + } + + ret = misc_register(&wdt_miscdev); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); + goto unreg_reboot; + } + + printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", + timeout, nowayout); + +out: + return ret; +unreg_reboot: + unregister_reboot_notifier(&wdt_notifier); +unreg_regions: + release_region(wdt_io, 1); + goto out; +} + +static void __exit +wdt_exit(void) +{ + misc_deregister(&wdt_miscdev); + unregister_reboot_notifier(&wdt_notifier); + release_region(wdt_io,1); +} + +module_init(wdt_init); +module_exit(wdt_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marcus Junker "); +MODULE_DESCRIPTION("w83697hf WDT driver"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit From e0845bf4e1df07e16fa39d96508a1ba4a480ce3e Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 2 Sep 2006 17:59:54 +0200 Subject: [WATCHDOG] Kconfig clean-up * fix typo's according to spellings checker * Fix some leading and trailing spaces Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 3e67e01b073..00b21db8eee 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -13,7 +13,7 @@ config WATCHDOG subsequently opening the file and then failing to write to it for longer than 1 minute will result in rebooting the machine. This could be useful for a networked machine that needs to come back - online as fast as possible after a lock-up. There's both a watchdog + on-line as fast as possible after a lock-up. There's both a watchdog implementation entirely in software (which can sometimes fail to reboot the machine) and a driver for hardware watchdog boards, which are more robust and can also keep track of the temperature inside @@ -71,7 +71,7 @@ config 21285_WATCHDOG tristate "DC21285 watchdog" depends on WATCHDOG && FOOTBRIDGE help - The Intel Footbridge chip contains a builtin watchdog circuit. Say Y + The Intel Footbridge chip contains a built-in watchdog circuit. Say Y here if you wish to use this. Alternatively say M to compile the driver as a module, which will be called wdt285. @@ -273,7 +273,7 @@ config IBMASR depends on WATCHDOG && X86 help This is the driver for the IBM Automatic Server Restart watchdog - timer builtin into some eServer xSeries machines. + timer built-in into some eServer xSeries machines. To compile this driver as a module, choose M here: the module will be called ibmasr. @@ -431,17 +431,17 @@ config W83627HF_WDT Most people will say N. config W83697HF_WDT - tristate "W83697HF Watchdog Timer" - depends on WATCHDOG && X86 - ---help--- - This is the driver for the hardware watchdog on the W83697HF chipset - This watchdog simply watches your kernel to make sure it doesn't freeze, - and if it does, it reboots your computer after a certain amount of time. + tristate "W83697HF Watchdog Timer" + depends on WATCHDOG && X86 + ---help--- + This is the driver for the hardware watchdog on the W83697HF chipset + This watchdog simply watches your kernel to make sure it doesn't freeze, + and if it does, it reboots your computer after a certain amount of time. - To compile this driver as a module, choose M here: the - module will be called w83697hf_wdt. + To compile this driver as a module, choose M here: the + module will be called w83697hf_wdt. - Most people will say N. + Most people will say N. config W83877F_WDT tristate "W83877F (EMACS) Watchdog Timer" @@ -476,7 +476,7 @@ config MACHZ_WDT depends on WATCHDOG && X86 ---help--- If you are using a ZF Micro MachZ processor, say Y here, otherwise - N. This is the driver for the watchdog timer builtin on that + N. This is the driver for the watchdog timer built-in on that processor using ZF-Logic interface. This watchdog simply watches your kernel to make sure it doesn't freeze, and if it does, it reboots your computer after a certain amount of time. -- cgit From ab9d441425559aa035ba6327f21e8922e8a13927 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 2 Sep 2006 18:50:20 +0200 Subject: [WATCHDOG] w836?7hf_wdt spinlock fixes. Add io spinlocks to prevent possible race conditions between start and stop operations that are issued from different child processes where the master process opened /dev/watchdog. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83627hf_wdt.c | 8 ++++++++ drivers/char/watchdog/w83697hf_wdt.c | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c index b4adc527e68..07d4bff2722 100644 --- a/drivers/char/watchdog/w83627hf_wdt.c +++ b/drivers/char/watchdog/w83627hf_wdt.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ static unsigned long wdt_is_open; static char expect_close; +static spinlock_t io_lock; /* You must set this - there is no sane way to probe for this board. */ static int wdt_io = 0x2E; @@ -110,12 +112,16 @@ w83627hf_init(void) static void wdt_ctrl(int timeout) { + spin_lock(&io_lock); + w83627hf_select_wd_register(); outb_p(0xF6, WDT_EFER); /* Select CRF6 */ outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */ w83627hf_unselect_wd_register(); + + spin_unlock(&io_lock); } static int @@ -303,6 +309,8 @@ wdt_init(void) { int ret; + spin_lock_init(&io_lock); + printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n"); if (wdt_set_heartbeat(timeout)) { diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index ef6612e1b91..21e822e0eee 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ static unsigned long wdt_is_open; static char expect_close; +static spinlock_t io_lock; /* You must set this - there is no sane way to probe for this board. */ static int wdt_io = 0x2E; @@ -114,12 +116,16 @@ w83697hf_init(void) static void wdt_ctrl(int timeout) { + spin_lock(&io_lock); + w83697hf_select_wd_register(); outb_p(0xF4, WDT_EFER); /* Select CRF4 */ outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ w83697hf_unselect_wd_register(); + + spin_unlock(&io_lock); } static int @@ -307,6 +313,8 @@ wdt_init(void) { int ret; + spin_lock_init(&io_lock); + printk(KERN_INFO "WDT driver for the Winbond(TM) W83697HF Super I/O chip initialising.\n"); if (wdt_set_heartbeat(timeout)) { -- cgit From c310e2b950c949cfc14754baed877eadb1a26f6b Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 2 Sep 2006 19:04:02 +0200 Subject: [WATCHDOG] Kconfig clean up fixed some more trailing spaces. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 00b21db8eee..ecae59cd767 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -269,9 +269,9 @@ config IB700_WDT Most people will say N. config IBMASR - tristate "IBM Automatic Server Restart" - depends on WATCHDOG && X86 - help + tristate "IBM Automatic Server Restart" + depends on WATCHDOG && X86 + help This is the driver for the IBM Automatic Server Restart watchdog timer built-in into some eServer xSeries machines. @@ -505,7 +505,6 @@ config SBC_EPX_C3_WATCHDOG To compile this driver as a module, choose M here: the module will be called sbc_epx_c3. - # PowerPC Architecture config 8xx_WDT @@ -535,7 +534,7 @@ config WATCHDOG_RTAS help This driver adds watchdog support for the RTAS watchdog. - To compile this driver as a module, choose M here. The module + To compile this driver as a module, choose M here. The module will be called wdrtas. # MIPS Architecture -- cgit From 196f29c8e8cd3352d26ed7bdf44f622e14adb931 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Wed, 13 Sep 2006 21:27:29 +0200 Subject: [WATCHDOG] use ENOTTY instead of ENOIOCTLCMD in ioctl() Return ENOTTY instead of ENOIOCTLCMD in user-visible ioctl() results The watchdog drivers used to return ENOIOCTLCMD for bad ioctl() commands. ENOIOCTLCMD should not be visible by the user, so use ENOTTY instead. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck Acked-by: Alan Cox Signed-off-by: Andrew Morton --- drivers/char/watchdog/w83697hf_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 21e822e0eee..32710a97b16 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -233,7 +233,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } default: - return -ENOIOCTLCMD; + return -ENOTTY; } return 0; } -- cgit From 8de6fc1e2023954ec21d4e84d002839afed4cad3 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 1 This is patch 1 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - the note concerning tyan motherboards has been copied from another driver, This doesn't apply here. - the comments concerning CRF6 are wrong as CRF3 is manipulated and CRF6 is never read nor written. - the comments concerning CRF5 are wrong as CRF4 is manipulated and CRF5 is never read nor written. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 32710a97b16..c31121eab3c 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -89,8 +89,6 @@ w83697hf_unselect_wd_register(void) outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ } -/* tyan motherboards seem to set F5 to 0x4C ? - * So explicitly init to appropriate value. */ static void w83697hf_init(void) { @@ -100,15 +98,15 @@ w83697hf_init(void) outb_p(0xF3, WDT_EFER); /* Select CRF3 */ - t=inb_p(WDT_EFDR); /* read CRF6 */ + t=inb_p(WDT_EFDR); /* read CRF3 */ if (t != 0) { printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); - outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ + outb_p(timeout, WDT_EFDR); /* Write back to CRF3 */ } outb_p(0xF4, WDT_EFER); /* Select CRF4 */ t=inb_p(WDT_EFDR); /* read CRF4 */ t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ - outb_p(t, WDT_EFDR); /* Write back to CRF5 */ + outb_p(t, WDT_EFDR); /* Write back to CRF4 */ w83697hf_unselect_wd_register(); } -- cgit From b41a9f59d13a4c4c3f0e0b8d9ff15743607096a2 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 2 This is patch 2 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - wdt_io is 2 bytes long. We should do a request_region for 2 bytes instead of 1. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index c31121eab3c..4f81943fe7f 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -321,7 +321,7 @@ wdt_init(void) WATCHDOG_TIMEOUT); } - if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { + if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", wdt_io); ret = -EIO; @@ -352,7 +352,7 @@ out: unreg_reboot: unregister_reboot_notifier(&wdt_notifier); unreg_regions: - release_region(wdt_io, 1); + release_region(wdt_io, 2); goto out; } @@ -361,7 +361,7 @@ wdt_exit(void) { misc_deregister(&wdt_miscdev); unregister_reboot_notifier(&wdt_notifier); - release_region(wdt_io,1); + release_region(wdt_io, 2); } module_init(wdt_init); -- cgit From db16525e63f8cf554696045e0e360b81e2263279 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 3 This is patch 3 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Fix identation. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 66 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 4f81943fe7f..12bdcab17b9 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -6,7 +6,7 @@ * Based on w83627hf_wdt.c advantechwdt.c which is based on wdt.c. * Original copyright messages: * - * (c) Copyright 2003 Pádraig Brady + * (c) Copyright 2003 Pádraig Brady * * (c) Copyright 2000-2001 Marek Michalkiewicz * @@ -96,16 +96,16 @@ w83697hf_init(void) w83697hf_select_wd_register(); - outb_p(0xF3, WDT_EFER); /* Select CRF3 */ + outb_p(0xF3, WDT_EFER); /* Select CRF3 */ t=inb_p(WDT_EFDR); /* read CRF3 */ if (t != 0) { printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); outb_p(timeout, WDT_EFDR); /* Write back to CRF3 */ } - outb_p(0xF4, WDT_EFER); /* Select CRF4 */ - t=inb_p(WDT_EFDR); /* read CRF4 */ - t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ + outb_p(0xF4, WDT_EFER); /* Select CRF4 */ + t=inb_p(WDT_EFDR); /* read CRF4 */ + t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ outb_p(t, WDT_EFDR); /* Write back to CRF4 */ w83697hf_unselect_wd_register(); @@ -187,51 +187,51 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user(argp, &ident, sizeof(ident))) - return -EFAULT; - break; + if (copy_to_user(argp, &ident, sizeof(ident))) + return -EFAULT; + break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, p); + return put_user(0, p); case WDIOC_KEEPALIVE: - wdt_ping(); - break; + wdt_ping(); + break; case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, p)) - return -EFAULT; - if (wdt_set_heartbeat(new_timeout)) - return -EINVAL; - wdt_ping(); - /* Fall */ + if (get_user(new_timeout, p)) + return -EFAULT; + if (wdt_set_heartbeat(new_timeout)) + return -EINVAL; + wdt_ping(); + /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(timeout, p); + return put_user(timeout, p); case WDIOC_SETOPTIONS: { - int options, retval = -EINVAL; + int options, retval = -EINVAL; - if (get_user(options, p)) - return -EFAULT; + if (get_user(options, p)) + return -EFAULT; - if (options & WDIOS_DISABLECARD) { - wdt_disable(); - retval = 0; - } + if (options & WDIOS_DISABLECARD) { + wdt_disable(); + retval = 0; + } - if (options & WDIOS_ENABLECARD) { - wdt_ping(); - retval = 0; - } + if (options & WDIOS_ENABLECARD) { + wdt_ping(); + retval = 0; + } - return retval; + return retval; } default: - return -ENOTTY; + return -ENOTTY; } return 0; } @@ -255,7 +255,7 @@ wdt_close(struct inode *inode, struct file *file) if (expect_close == 42) { wdt_disable(); } else { - printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); wdt_ping(); } expect_close = 0; @@ -313,7 +313,7 @@ wdt_init(void) spin_lock_init(&io_lock); - printk(KERN_INFO "WDT driver for the Winbond(TM) W83697HF Super I/O chip initialising.\n"); + printk (KERN_INFO "WDT driver for the Winbond(TM) W83697HF Super I/O chip initialising.\n"); if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); -- cgit From eb64419e397aaea55b2ef6904e86b6263a80acc7 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 4 This is patch 4 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - limits the watchdog timeout to 1-63 while this device accepts 1-255. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 12bdcab17b9..94b1655e70c 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -54,7 +54,7 @@ MODULE_PARM_DESC(wdt_io, "w83697hf WDT io port (default 0x2E)"); static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); @@ -143,7 +143,7 @@ wdt_disable(void) static int wdt_set_heartbeat(int t) { - if ((t < 1) || (t > 63)) + if ((t < 1) || (t > 255)) return -EINVAL; timeout = t; @@ -317,7 +317,7 @@ wdt_init(void) if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); - printk (KERN_INFO PFX "timeout value must be 1<=timeout<=63, using %d\n", + printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", WATCHDOG_TIMEOUT); } -- cgit From 44d7d3282baa4080b73adca31648e6ef1e191874 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 5 This is patch 5 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Rename the Extended Function Registers to the names used in the data-sheet. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 94b1655e70c..c44f281f356 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -64,29 +64,29 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON * Kernel methods. */ -#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ -#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ -#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ +#define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ +#define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ +#define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ static void w83697hf_select_wd_register(void) { - outb_p(0x87, WDT_EFER); /* Enter extended function mode */ - outb_p(0x87, WDT_EFER); /* Again according to manual */ + outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ + outb_p(0x87, W83697HF_EFER); /* Again according to manual */ - outb_p(0x29, WDT_EFER); /* select CR29 */ - outb_p(0x20, WDT_EFDR); /* select WDTO */ + outb_p(0x29, W83697HF_EFER); /* select CR29 */ + outb_p(0x20, W83697HF_EFDR); /* select WDTO */ - outb_p(0x07, WDT_EFER); /* point to logical device number reg */ - outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ - outb_p(0x30, WDT_EFER); /* select CR30 */ - outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ + outb_p(0x07, W83697HF_EFER); /* point to logical device number reg */ + outb_p(0x08, W83697HF_EFDR); /* select logical device 8 (GPIO2) */ + outb_p(0x30, W83697HF_EFER); /* select CR30 */ + outb_p(0x01, W83697HF_EFDR); /* set bit 0 to activate GPIO2 */ } static void w83697hf_unselect_wd_register(void) { - outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ + outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ } static void @@ -96,17 +96,17 @@ w83697hf_init(void) w83697hf_select_wd_register(); - outb_p(0xF3, WDT_EFER); /* Select CRF3 */ + outb_p(0xF3, W83697HF_EFER); /* Select CRF3 */ - t=inb_p(WDT_EFDR); /* read CRF3 */ + t=inb_p(W83697HF_EFDR); /* read CRF3 */ if (t != 0) { printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); - outb_p(timeout, WDT_EFDR); /* Write back to CRF3 */ + outb_p(timeout, W83697HF_EFDR); /* Write back to CRF3 */ } - outb_p(0xF4, WDT_EFER); /* Select CRF4 */ - t=inb_p(WDT_EFDR); /* read CRF4 */ - t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ - outb_p(t, WDT_EFDR); /* Write back to CRF4 */ + outb_p(0xF4, W83697HF_EFER); /* Select CRF4 */ + t=inb_p(W83697HF_EFDR); /* read CRF4 */ + t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ + outb_p(t, W83697HF_EFDR); /* Write back to CRF4 */ w83697hf_unselect_wd_register(); } @@ -118,8 +118,8 @@ wdt_ctrl(int timeout) w83697hf_select_wd_register(); - outb_p(0xF4, WDT_EFER); /* Select CRF4 */ - outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ + outb_p(0xF4, W83697HF_EFER); /* Select CRF4 */ + outb_p(timeout, W83697HF_EFDR); /* Write Timeout counter to CRF4 */ w83697hf_unselect_wd_register(); -- cgit From de710d6871c7f569da007f1074710fadf1708c29 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 6 This is patch 6 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - The driver works for both the w83697hf and the w83697hg chipset's. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index c44f281f356..ad397f912bd 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -1,9 +1,10 @@ /* - * w83697hf WDT driver + * w83697hf/hg WDT driver * * (c) Copyright 2006 Marcus Junker * - * Based on w83627hf_wdt.c advantechwdt.c which is based on wdt.c. + * Based on w83627hf_wdt.c which is based on advantechwdt.c + * which is based on wdt.c. * Original copyright messages: * * (c) Copyright 2003 Pádraig Brady @@ -39,7 +40,7 @@ #include #include -#define WATCHDOG_NAME "w83697hf WDT" +#define WATCHDOG_NAME "w83697hf/hg WDT" #define PFX WATCHDOG_NAME ": " #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ @@ -313,7 +314,7 @@ wdt_init(void) spin_lock_init(&io_lock); - printk (KERN_INFO "WDT driver for the Winbond(TM) W83697HF Super I/O chip initialising.\n"); + printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); @@ -369,5 +370,5 @@ module_exit(wdt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marcus Junker "); -MODULE_DESCRIPTION("w83697hf WDT driver"); +MODULE_DESCRIPTION("w83697hf/hg WDT driver"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit From f7be3328b6e8b09b3a910a93ef569cba162ea81d Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 7 This is patch 7 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - add w83697hf_unlock function to enter the chipsets extended function mode. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index ad397f912bd..b1f22579850 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -69,11 +69,17 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON #define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ #define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ -static void -w83697hf_select_wd_register(void) +static inline void +w83697hf_unlock(void) { outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ outb_p(0x87, W83697HF_EFER); /* Again according to manual */ +} + +static void +w83697hf_select_wd_register(void) +{ + w83697hf_unlock(); outb_p(0x29, W83697HF_EFER); /* select CR29 */ outb_p(0x20, W83697HF_EFDR); /* select WDTO */ -- cgit From fe851ebade80af9b58599c74d61718657b02cfd3 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 8 This is patch 8 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - add w83697hf_lock function to leave the chipsets extended function mode. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index b1f22579850..6a357a818c8 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -76,6 +76,12 @@ w83697hf_unlock(void) outb_p(0x87, W83697HF_EFER); /* Again according to manual */ } +static inline void +w83697hf_lock(void) +{ + outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ +} + static void w83697hf_select_wd_register(void) { @@ -93,7 +99,7 @@ w83697hf_select_wd_register(void) static void w83697hf_unselect_wd_register(void) { - outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ + w83697hf_lock(); } static void -- cgit From 0cd544763bacad14d0d15fb16d29999b450cb77f Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 9 This is patch 9 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - add w83697hf_get_reg() and w83697hf_set_reg() functions. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 42 +++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 6a357a818c8..f62f1723871 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -82,18 +82,34 @@ w83697hf_lock(void) outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ } +/* + * The two functions w83697hf_get_reg() and w83697hf_set_reg() + * must be called with the device unlocked. + */ + +static unsigned char +w83697hf_get_reg(unsigned char reg) +{ + outb_p(reg, W83697HF_EFIR); + return inb_p(W83697HF_EFDR); +} + +static void +w83697hf_set_reg(unsigned char reg, unsigned char data) +{ + outb_p(reg, W83697HF_EFIR); + outb_p(data, W83697HF_EFDR); +} + static void w83697hf_select_wd_register(void) { w83697hf_unlock(); - outb_p(0x29, W83697HF_EFER); /* select CR29 */ - outb_p(0x20, W83697HF_EFDR); /* select WDTO */ + w83697hf_set_reg(0x29, 0x20); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ - outb_p(0x07, W83697HF_EFER); /* point to logical device number reg */ - outb_p(0x08, W83697HF_EFDR); /* select logical device 8 (GPIO2) */ - outb_p(0x30, W83697HF_EFER); /* select CR30 */ - outb_p(0x01, W83697HF_EFDR); /* set bit 0 to activate GPIO2 */ + w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ + w83697hf_set_reg(0x30, 0x01); /* Enable timer/activate GPIO2 via bit 0 */ } static void @@ -109,17 +125,14 @@ w83697hf_init(void) w83697hf_select_wd_register(); - outb_p(0xF3, W83697HF_EFER); /* Select CRF3 */ - - t=inb_p(W83697HF_EFDR); /* read CRF3 */ + t = w83697hf_get_reg(0xF3); /* Read CRF3 */ if (t != 0) { printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); - outb_p(timeout, W83697HF_EFDR); /* Write back to CRF3 */ + w83697hf_set_reg(0xF3, timeout); /* Write new timeout */ } - outb_p(0xF4, W83697HF_EFER); /* Select CRF4 */ - t=inb_p(W83697HF_EFDR); /* read CRF4 */ + t = w83697hf_get_reg(0xF4); /* Read CRF4 */ t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ - outb_p(t, W83697HF_EFDR); /* Write back to CRF4 */ + w83697hf_set_reg(0xF4, t); /* Write back to CRF4 */ w83697hf_unselect_wd_register(); } @@ -131,8 +144,7 @@ wdt_ctrl(int timeout) w83697hf_select_wd_register(); - outb_p(0xF4, W83697HF_EFER); /* Select CRF4 */ - outb_p(timeout, W83697HF_EFDR); /* Write Timeout counter to CRF4 */ + w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ w83697hf_unselect_wd_register(); -- cgit From c81b2996253a94278057f83a24dfa9053f0dee7a Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 10 This is patch 10 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - check whether the device is really present (we *can* probe for the device now). Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 54 +++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index f62f1723871..4e0bd4e714e 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -49,9 +49,9 @@ static char expect_close; static spinlock_t io_lock; /* You must set this - there is no sane way to probe for this board. */ -static int wdt_io = 0x2E; +static int wdt_io = 0x2e; module_param(wdt_io, int, 0); -MODULE_PARM_DESC(wdt_io, "w83697hf WDT io port (default 0x2E)"); +MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); @@ -331,28 +331,62 @@ static struct notifier_block wdt_notifier = { .notifier_call = wdt_notify_sys, }; +static int +w83697hf_check_wdt(void) +{ + if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { + printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); + return -EIO; + } + + printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); + w83697hf_unlock(); + if (w83697hf_get_reg(0x20) == 0x60) { + printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); + w83697hf_lock(); + return 0; + } + w83697hf_lock(); /* Reprotect in case it was a compatible device */ + + printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); + release_region(wdt_io, 2); + return -EIO; +} + static int __init wdt_init(void) { - int ret; + int ret, autodetect; spin_lock_init(&io_lock); printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); + autodetect = wdt_io == 0; + if (autodetect) + wdt_io = 0x2e; + + if (!w83697hf_check_wdt()) + goto found; + + if (autodetect) { + wdt_io = 0x4e; + if (!w83697hf_check_wdt()) + goto found; + } + + printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); + ret = -EIO; + goto out; + +found: + if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", WATCHDOG_TIMEOUT); } - if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { - printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", - wdt_io); - ret = -EIO; - goto out; - } - w83697hf_init(); ret = register_reboot_notifier(&wdt_notifier); -- cgit From a7933e05d46f49385841d09028ee07fae2b383f2 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 11 This is patch 11 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Add w83697hf_select_wdt() and w83697hf_deselect_wdt() so that the start/stop/ping code can directly talk to the watchdog. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 4e0bd4e714e..b12f8b80076 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -101,6 +101,19 @@ w83697hf_set_reg(unsigned char reg, unsigned char data) outb_p(data, W83697HF_EFDR); } +static void +w83697hf_select_wdt(void) +{ + w83697hf_unlock(); + w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ +} + +static inline void +w83697hf_deselect_wdt(void) +{ + w83697hf_lock(); +} + static void w83697hf_select_wd_register(void) { @@ -142,11 +155,11 @@ wdt_ctrl(int timeout) { spin_lock(&io_lock); - w83697hf_select_wd_register(); + w83697hf_select_wdt(); w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ - w83697hf_unselect_wd_register(); + w83697hf_deselect_wdt(); spin_unlock(&io_lock); } -- cgit From d46ab596e251e35a7e27c95e4e4d01921f3e579e Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 12 This is patch 12 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Add w83697hf_write_timeout() to set the watchdog's timeout value. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index b12f8b80076..b3dcc81abbb 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -83,8 +83,8 @@ w83697hf_lock(void) } /* - * The two functions w83697hf_get_reg() and w83697hf_set_reg() - * must be called with the device unlocked. + * The three functions w83697hf_get_reg(), w83697hf_set_reg() and + * w83697hf_write_timeout() must be called with the device unlocked. */ static unsigned char @@ -101,6 +101,12 @@ w83697hf_set_reg(unsigned char reg, unsigned char data) outb_p(data, W83697HF_EFDR); } +static void +w83697hf_write_timeout(int timeout) +{ + w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ +} + static void w83697hf_select_wdt(void) { @@ -157,7 +163,7 @@ wdt_ctrl(int timeout) w83697hf_select_wdt(); - w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ + w83697hf_write_timeout(timeout); w83697hf_deselect_wdt(); -- cgit From 089d8139f4c19c2f4d6984323e9d8a6e77cc92f7 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 13 This is patch 13 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Remove wdt_ctrl (it has been replaced with the w83697hf_write_timeout() function) and redo/clean-up the start/stop/ping code. - Make sure that the watchdog is enabled or disabled When starting or stoping the device (with a call to w83697hf_set_reg(0x30, ?); ). Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index b3dcc81abbb..2b3ce434c19 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -156,31 +156,44 @@ w83697hf_init(void) w83697hf_unselect_wd_register(); } -static void -wdt_ctrl(int timeout) +static int +wdt_ping(void) { spin_lock(&io_lock); - w83697hf_select_wdt(); w83697hf_write_timeout(timeout); w83697hf_deselect_wdt(); - spin_unlock(&io_lock); + return 0; } static int -wdt_ping(void) +wdt_enable(void) { - wdt_ctrl(timeout); + spin_lock(&io_lock); + w83697hf_select_wdt(); + + w83697hf_write_timeout(timeout); + w83697hf_set_reg(0x30, 1); /* Enable timer */ + + w83697hf_deselect_wdt(); + spin_unlock(&io_lock); return 0; } static int wdt_disable(void) { - wdt_ctrl(0); + spin_lock(&io_lock); + w83697hf_select_wdt(); + + w83697hf_set_reg(0x30, 0); /* Disable timer */ + w83697hf_write_timeout(0); + + w83697hf_deselect_wdt(); + spin_unlock(&io_lock); return 0; } @@ -267,7 +280,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } if (options & WDIOS_ENABLECARD) { - wdt_ping(); + wdt_enable(); retval = 0; } @@ -289,7 +302,7 @@ wdt_open(struct inode *inode, struct file *file) * Activate */ - wdt_ping(); + wdt_enable(); return nonseekable_open(inode, file); } -- cgit From fa69afd3c224252890cb30864dc648d1399dd9fe Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 14 This is patch 14 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Clean-up initialization code (part 1: remove w83697hf_select_wd_register() and w83697hf_unselect_wd_register() functions). - Make sure that the watchdog device is stopped as soon as we found it. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 2b3ce434c19..1ea43bf2c35 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -120,29 +120,14 @@ w83697hf_deselect_wdt(void) w83697hf_lock(); } -static void -w83697hf_select_wd_register(void) -{ - w83697hf_unlock(); - - w83697hf_set_reg(0x29, 0x20); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ - - w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ - w83697hf_set_reg(0x30, 0x01); /* Enable timer/activate GPIO2 via bit 0 */ -} - -static void -w83697hf_unselect_wd_register(void) -{ - w83697hf_lock(); -} - static void w83697hf_init(void) { unsigned char t; - w83697hf_select_wd_register(); + w83697hf_select_wdt(); + + w83697hf_set_reg(0x29, 0x20); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ t = w83697hf_get_reg(0xF3); /* Read CRF3 */ if (t != 0) { @@ -153,7 +138,7 @@ w83697hf_init(void) t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ w83697hf_set_reg(0xF4, t); /* Write back to CRF4 */ - w83697hf_unselect_wd_register(); + w83697hf_deselect_wdt(); } static int @@ -412,6 +397,8 @@ wdt_init(void) goto out; found: + w83697hf_init(); + wdt_disable(); /* Disable watchdog until first use */ if (wdt_set_heartbeat(timeout)) { wdt_set_heartbeat(WATCHDOG_TIMEOUT); @@ -419,8 +406,6 @@ found: WATCHDOG_TIMEOUT); } - w83697hf_init(); - ret = register_reboot_notifier(&wdt_notifier); if (ret != 0) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", -- cgit From b7b9868ba6f528d60e5869b4a6aad1fe49838b03 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 15 This is patch 15 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Clean-up initialization code - part 2: * the line reading "set second mode & disable keyboard ..." is plain wrong, the register being manipulated (CRF4) is the counter itself, not the control byte (CRF3) -- looks like it has been copied from another driver. * I think garbage is being written in CRF3 (the control word) as the timeout value is being stored in this register (such as 60 for 60 seconds). * We only want to set pin 119 to WDTO# mode and leave the rest of CR29 like it is. * Set count mode to seconds and not minutes. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 1ea43bf2c35..78b6540e874 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -123,20 +123,18 @@ w83697hf_deselect_wdt(void) static void w83697hf_init(void) { - unsigned char t; + unsigned char bbuf; w83697hf_select_wdt(); - w83697hf_set_reg(0x29, 0x20); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ + bbuf = w83697hf_get_reg(0x29); + bbuf &= ~0x60; + bbuf |= 0x20; + w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ - t = w83697hf_get_reg(0xF3); /* Read CRF3 */ - if (t != 0) { - printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); - w83697hf_set_reg(0xF3, timeout); /* Write new timeout */ - } - t = w83697hf_get_reg(0xF4); /* Read CRF4 */ - t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ - w83697hf_set_reg(0xF4, t); /* Write back to CRF4 */ + bbuf = w83697hf_get_reg(0xF3); + bbuf &= ~0x04; + w83697hf_set_reg(0xF3, bbuf); /* Count mode is seconds */ w83697hf_deselect_wdt(); } -- cgit From 3fdee8db010d5cbf890ec49332ac4946f3f63720 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - patch 16 This is patch 16 in the series of patches that converts Marcus Junker's w83697hf watchdog driver to Samuel Tardieau's w83697hf/hg watchdog driver. This patch contains following changes: - Add copyright notice for Samuel Tardieu also. This is the last patch in this series. The original description for Samuel's driver was: driver for the Winbond W83697HF/W83697HG watchdog timer The Winbond SuperIO W83697HF/HG includes a watchdog that can count from 1 to 255 seconds (or minutes). This drivers allows the seconds mode to be used. It exposes a standard /dev/watchdog interface. This chip is currently being used on some motherboards designed by VIA. By default, the module looks for a chip at I/O port 0x2e. The chip can be configured to be at 0x4e on some motherboards, the address can be chosen using the wdt_io module parameter. Using 0 will try to autodetect the address. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 78b6540e874..21052de8a0c 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -1,6 +1,7 @@ /* * w83697hf/hg WDT driver * + * (c) Copyright 2006 Samuel Tardieu * (c) Copyright 2006 Marcus Junker * * Based on w83627hf_wdt.c which is based on advantechwdt.c @@ -442,6 +443,6 @@ module_init(wdt_init); module_exit(wdt_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Marcus Junker "); +MODULE_AUTHOR("Marcus Junker , Samuel Tardieu "); MODULE_DESCRIPTION("w83697hf/hg WDT driver"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit From e223f01a822e999b0aea2e720e12d8bb3532da70 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Fri, 15 Sep 2006 17:59:07 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - autodetect patch Change the autodetect code so that it is more generic. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/w83697hf_wdt.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c index 21052de8a0c..7768b55487c 100644 --- a/drivers/char/watchdog/w83697hf_wdt.c +++ b/drivers/char/watchdog/w83697hf_wdt.c @@ -369,33 +369,35 @@ w83697hf_check_wdt(void) return -EIO; } +static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; + static int __init wdt_init(void) { - int ret, autodetect; + int ret, i, found = 0; spin_lock_init(&io_lock); printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); - autodetect = wdt_io == 0; - if (autodetect) - wdt_io = 0x2e; - - if (!w83697hf_check_wdt()) - goto found; - - if (autodetect) { - wdt_io = 0x4e; + if (wdt_io == 0) { + /* 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()) + found++; + } + } else { if (!w83697hf_check_wdt()) - goto found; + found++; } - printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); - ret = -EIO; - goto out; + if (!found) { + printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); + ret = -EIO; + goto out; + } -found: w83697hf_init(); wdt_disable(); /* Disable watchdog until first use */ -- cgit From ff02cfc76a5040ee125c597baa1cfc9874918ed2 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 7 Sep 2006 11:57:00 +0200 Subject: [WATCHDOG] w83697hf/hg WDT driver - Kconfig patch Update Kconfig for the w83697hf/hg watchdog driver. Signed-off-by: Samuel Tardieu Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index ecae59cd767..847a26064b6 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -431,12 +431,14 @@ config W83627HF_WDT Most people will say N. config W83697HF_WDT - tristate "W83697HF Watchdog Timer" + tristate "W83697HF/W83697HG Watchdog Timer" depends on WATCHDOG && X86 ---help--- - This is the driver for the hardware watchdog on the W83697HF chipset - This watchdog simply watches your kernel to make sure it doesn't freeze, - and if it does, it reboots your computer after a certain amount of time. + This is the driver for the hardware watchdog on the W83697HF/HG + chipset as used in Dedibox/VIA motherboards (and likely others). + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. To compile this driver as a module, choose M here: the module will be called w83697hf_wdt. -- cgit From e34477e9906acc137329b654a51fb7d4598813f7 Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Fri, 6 Oct 2006 13:41:12 -0700 Subject: [WATCHDOG] ioremap balanced with iounmap for drivers/char/watchdog/s3c2410_wdt.c ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Signed-off-by: Amol Lad Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton --- drivers/char/watchdog/s3c2410_wdt.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index b36a04ae9ab..d54d0efe075 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c @@ -381,18 +381,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { printk(KERN_INFO PFX "failed to get irq resource\n"); + iounmap(wdt_base); return -ENOENT; } ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); if (ret != 0) { printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); + iounmap(wdt_base); return ret; } wdt_clock = clk_get(&pdev->dev, "watchdog"); if (wdt_clock == NULL) { printk(KERN_INFO PFX "failed to find watchdog clock source\n"); + iounmap(wdt_base); return -ENOENT; } @@ -416,6 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", WATCHDOG_MINOR, ret); + iounmap(wdt_base); return ret; } @@ -452,6 +456,7 @@ static int s3c2410wdt_remove(struct platform_device *dev) wdt_clock = NULL; } + iounmap(wdt_base); misc_deregister(&s3c2410wdt_miscdev); return 0; } -- cgit From bcbf25bd0d4afb108a755e1c4e4e2d854a2869d7 Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Wed, 4 Oct 2006 14:18:29 +0200 Subject: [WATCHDOG] add ich8 support to iTCO_wdt.c Add ICH8 support to the iTCO_wdt driver. Signed-off-by: Arnaud Patard Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/iTCO_wdt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c index aaac94db0d8..639d84f0c02 100644 --- a/drivers/char/watchdog/iTCO_wdt.c +++ b/drivers/char/watchdog/iTCO_wdt.c @@ -85,6 +85,7 @@ enum iTCO_chipsets { TCO_ICH7, /* ICH7 & ICH7R */ TCO_ICH7M, /* ICH7-M */ TCO_ICH7MDH, /* ICH7-M DH */ + TCO_ICH8, /* ICH8 */ }; static struct { @@ -108,6 +109,7 @@ static struct { {"ICH7 or ICH7R", 2}, {"ICH7-M", 2}, {"ICH7-M DH", 2}, + {"ICH8 or ICH8R", 2}, {NULL,0} }; @@ -135,6 +137,7 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7 }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 }, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); -- cgit From a8edd74e4404d011ab821d5bf35b27335d26f001 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sun, 8 Oct 2006 21:05:21 +0200 Subject: [WATCHDOG] add ich8 support to iTCO_wdt.c (patch 2) Add ICH8 support to the iTCO_wdt driver. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/iTCO_wdt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c index 639d84f0c02..505aae91776 100644 --- a/drivers/char/watchdog/iTCO_wdt.c +++ b/drivers/char/watchdog/iTCO_wdt.c @@ -35,6 +35,10 @@ * 82801GDH (ICH7DH) : document number 307013-002, 307014-009, * 82801GBM (ICH7-M) : document number 307013-002, 307014-009, * 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009, + * 82801HB (ICH8) : document number 313056-002, 313057-004, + * 82801HR (ICH8R) : document number 313056-002, 313057-004, + * 82801HH (ICH8DH) : document number 313056-002, 313057-004, + * 82801HO (ICH8DO) : document number 313056-002, 313057-004, * 6300ESB (6300ESB) : document number 300641-003 */ @@ -45,7 +49,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" #define DRV_VERSION "1.00" -#define DRV_RELDATE "30-Jul-2006" +#define DRV_RELDATE "08-Oct-2006" #define PFX DRV_NAME ": " /* Includes */ @@ -85,7 +89,9 @@ enum iTCO_chipsets { TCO_ICH7, /* ICH7 & ICH7R */ TCO_ICH7M, /* ICH7-M */ TCO_ICH7MDH, /* ICH7-M DH */ - TCO_ICH8, /* ICH8 */ + TCO_ICH8, /* ICH8 & ICH8R */ + TCO_ICH8DH, /* ICH8DH */ + TCO_ICH8DO, /* ICH8DO */ }; static struct { @@ -110,6 +116,8 @@ static struct { {"ICH7-M", 2}, {"ICH7-M DH", 2}, {"ICH8 or ICH8R", 2}, + {"ICH8DH", 2}, + {"ICH8DO", 2}, {NULL,0} }; @@ -138,6 +146,8 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO }, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); -- cgit From 73f5e28b336772c4b08ee82e5bf28ab872898ee1 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 9 Oct 2006 21:58:54 +0200 Subject: r8169: PCI ID for Corega Gigabit network card Fix for http://bugzilla.kernel.org/show_bug.cgi?id=7239. Signed-off-by: Andrew Morton Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4c47c5b10ba..c7309e98f89 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -214,6 +214,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, -- cgit From 80060362aaefec507ac2d7a7bd156716d7a7ca91 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 10 Oct 2006 03:40:44 -0400 Subject: [WATCHDOG] watchdog/iTCO_wdt: fix bug related to gcc uninit warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc emits the following warning: drivers/char/watchdog/iTCO_wdt.c: In function ‘iTCO_wdt_ioctl’: drivers/char/watchdog/iTCO_wdt.c:429: warning: ‘time_left’ may be used uninitialized in this function This indicates a condition near enough to a bug, to want to fix. iTCO_wdt_get_timeleft() stores a value in 'time_left' iff iTCO_version==(1 or 2). This driver only supports versions 1 or 2, so this is ok. However, since (a) the return value of iTCO_wdt_get_timeleft() is handled anyway, (b) it fixes the warning, and (c) it future-proofs the driver, we go ahead and add the obvious return value. Signed-off-by: Jeff Garzik Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton --- drivers/char/watchdog/iTCO_wdt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c index 505aae91776..b6f29cb8bd3 100644 --- a/drivers/char/watchdog/iTCO_wdt.c +++ b/drivers/char/watchdog/iTCO_wdt.c @@ -368,7 +368,8 @@ static int iTCO_wdt_get_timeleft (int *time_left) spin_unlock(&iTCO_wdt_private.io_lock); *time_left = (val8 * 6) / 10; - } + } else + return -EINVAL; return 0; } @@ -439,7 +440,6 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, { int new_options, retval = -EINVAL; int new_heartbeat; - int time_left; void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { @@ -499,6 +499,8 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, case WDIOC_GETTIMELEFT: { + int time_left; + if (iTCO_wdt_get_timeleft(&time_left)) return -EINVAL; -- cgit From 733b736c91dd2c556f35dffdcf77e667cf10cefc Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 12 Oct 2006 22:33:31 +0200 Subject: r8169: fix infinite loop during hotplug Bug reported for PCMCIA. Signed-off-by: Arnaud Patard Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index c7309e98f89..c2c9a86e445 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2702,6 +2702,7 @@ static void rtl8169_down(struct net_device *dev) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned int poll_locked = 0; + unsigned int intrmask; rtl8169_delete_timer(dev); @@ -2740,8 +2741,11 @@ core_down: * 2) dev->change_mtu * -> rtl8169_poll can not be issued again and re-enable the * interruptions. Let's simply issue the IRQ down sequence again. + * + * No loop if hotpluged or major error (0xffff). */ - if (RTL_R16(IntrMask)) + intrmask = RTL_R16(IntrMask); + if (intrmask && (intrmask != 0xffff)) goto core_down; rtl8169_tx_clear(tp); -- cgit From bdcff3458f5448fac585a6174ad9342f361b5135 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Tue, 26 Sep 2006 17:49:30 +0200 Subject: [WATCHDOG] Atmel AT91RM9200 rename. The new Atmel AT91SAM9261 and AT91SAM9260 processors use a different internal watchdog peripheral. This watchdog driver is therefore AT91RM9200-specific. This patch renames at91_wdt.c to at91rm9200_wdt.c, and changes the name of the configuration option. Signed-off-by: Andrew Victor Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 2 +- drivers/char/watchdog/Makefile | 2 +- drivers/char/watchdog/at91_wdt.c | 287 --------------------------------- drivers/char/watchdog/at91rm9200_wdt.c | 287 +++++++++++++++++++++++++++++++++ 4 files changed, 289 insertions(+), 289 deletions(-) delete mode 100644 drivers/char/watchdog/at91_wdt.c create mode 100644 drivers/char/watchdog/at91rm9200_wdt.c (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 847a26064b6..529f0a70690 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -60,7 +60,7 @@ config SOFT_WATCHDOG # ARM Architecture -config AT91_WATCHDOG +config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" depends on WATCHDOG && ARCH_AT91RM9200 help diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index ee3474190e2..36440497047 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o # ARM Architecture -obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o +obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_21285_WATCHDOG) += wdt285.o obj-$(CONFIG_977_WATCHDOG) += wdt977.o diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c deleted file mode 100644 index 4e7a1145e78..00000000000 --- a/drivers/char/watchdog/at91_wdt.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Watchdog driver for Atmel AT91RM9200 (Thunder) - * - * Copyright (C) 2003 SAN People (Pty) Ltd - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define WDT_DEFAULT_TIME 5 /* seconds */ -#define WDT_MAX_TIME 256 /* seconds */ - -static int wdt_time = WDT_DEFAULT_TIME; -static int nowayout = WATCHDOG_NOWAYOUT; - -module_param(wdt_time, int, 0); -MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); - -#ifdef CONFIG_WATCHDOG_NOWAYOUT -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -#endif - - -static unsigned long at91wdt_busy; - -/* ......................................................................... */ - -/* - * Disable the watchdog. - */ -static void inline at91_wdt_stop(void) -{ - at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); -} - -/* - * Enable and reset the watchdog. - */ -static void inline at91_wdt_start(void) -{ - at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); -} - -/* - * Reload the watchdog timer. (ie, pat the watchdog) - */ -static void inline at91_wdt_reload(void) -{ - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); -} - -/* ......................................................................... */ - -/* - * Watchdog device is opened, and watchdog starts running. - */ -static int at91_wdt_open(struct inode *inode, struct file *file) -{ - if (test_and_set_bit(0, &at91wdt_busy)) - return -EBUSY; - - at91_wdt_start(); - return nonseekable_open(inode, file); -} - -/* - * Close the watchdog device. - * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also - * disabled. - */ -static int at91_wdt_close(struct inode *inode, struct file *file) -{ - if (!nowayout) - at91_wdt_stop(); /* Disable the watchdog when file is closed */ - - clear_bit(0, &at91wdt_busy); - return 0; -} - -/* - * Change the watchdog time interval. - */ -static int at91_wdt_settimeout(int new_time) -{ - /* - * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz - * - * Since WDV is a 16-bit counter, the maximum period is - * 65536 / 0.256 = 256 seconds. - */ - if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) - return -EINVAL; - - /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ - wdt_time = new_time; - return 0; -} - -static struct watchdog_info at91_wdt_info = { - .identity = "at91 watchdog", - .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, -}; - -/* - * Handle commands from user-space. - */ -static int at91_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int __user *p = argp; - int new_value; - - switch(cmd) { - case WDIOC_KEEPALIVE: - at91_wdt_reload(); /* pat the watchdog */ - return 0; - - case WDIOC_GETSUPPORT: - return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; - - case WDIOC_SETTIMEOUT: - if (get_user(new_value, p)) - return -EFAULT; - - if (at91_wdt_settimeout(new_value)) - return -EINVAL; - - /* Enable new time value */ - at91_wdt_start(); - - /* Return current value */ - return put_user(wdt_time, p); - - case WDIOC_GETTIMEOUT: - return put_user(wdt_time, p); - - case WDIOC_GETSTATUS: - case WDIOC_GETBOOTSTATUS: - return put_user(0, p); - - case WDIOC_SETOPTIONS: - if (get_user(new_value, p)) - return -EFAULT; - - if (new_value & WDIOS_DISABLECARD) - at91_wdt_stop(); - if (new_value & WDIOS_ENABLECARD) - at91_wdt_start(); - return 0; - - default: - return -ENOTTY; - } -} - -/* - * Pat the watchdog whenever device is written to. - */ -static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) -{ - at91_wdt_reload(); /* pat the watchdog */ - return len; -} - -/* ......................................................................... */ - -static const struct file_operations at91wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .ioctl = at91_wdt_ioctl, - .open = at91_wdt_open, - .release = at91_wdt_close, - .write = at91_wdt_write, -}; - -static struct miscdevice at91wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &at91wdt_fops, -}; - -static int __init at91wdt_probe(struct platform_device *pdev) -{ - int res; - - if (at91wdt_miscdev.dev) - return -EBUSY; - at91wdt_miscdev.dev = &pdev->dev; - - res = misc_register(&at91wdt_miscdev); - if (res) - return res; - - printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); - return 0; -} - -static int __exit at91wdt_remove(struct platform_device *pdev) -{ - int res; - - res = misc_deregister(&at91wdt_miscdev); - if (!res) - at91wdt_miscdev.dev = NULL; - - return res; -} - -static void at91wdt_shutdown(struct platform_device *pdev) -{ - at91_wdt_stop(); -} - -#ifdef CONFIG_PM - -static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) -{ - at91_wdt_stop(); - return 0; -} - -static int at91wdt_resume(struct platform_device *pdev) -{ - if (at91wdt_busy) - at91_wdt_start(); - return 0; -} - -#else -#define at91wdt_suspend NULL -#define at91wdt_resume NULL -#endif - -static struct platform_driver at91wdt_driver = { - .probe = at91wdt_probe, - .remove = __exit_p(at91wdt_remove), - .shutdown = at91wdt_shutdown, - .suspend = at91wdt_suspend, - .resume = at91wdt_resume, - .driver = { - .name = "at91_wdt", - .owner = THIS_MODULE, - }, -}; - -static int __init at91_wdt_init(void) -{ - /* Check that the heartbeat value is within range; if not reset to the default */ - if (at91_wdt_settimeout(wdt_time)) { - at91_wdt_settimeout(WDT_DEFAULT_TIME); - pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); - } - - return platform_driver_register(&at91wdt_driver); -} - -static void __exit at91_wdt_exit(void) -{ - platform_driver_unregister(&at91wdt_driver); -} - -module_init(at91_wdt_init); -module_exit(at91_wdt_exit); - -MODULE_AUTHOR("Andrew Victor"); -MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/char/watchdog/at91rm9200_wdt.c b/drivers/char/watchdog/at91rm9200_wdt.c new file mode 100644 index 00000000000..4e7a1145e78 --- /dev/null +++ b/drivers/char/watchdog/at91rm9200_wdt.c @@ -0,0 +1,287 @@ +/* + * Watchdog driver for Atmel AT91RM9200 (Thunder) + * + * Copyright (C) 2003 SAN People (Pty) Ltd + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define WDT_DEFAULT_TIME 5 /* seconds */ +#define WDT_MAX_TIME 256 /* seconds */ + +static int wdt_time = WDT_DEFAULT_TIME; +static int nowayout = WATCHDOG_NOWAYOUT; + +module_param(wdt_time, int, 0); +MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); + +#ifdef CONFIG_WATCHDOG_NOWAYOUT +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +#endif + + +static unsigned long at91wdt_busy; + +/* ......................................................................... */ + +/* + * Disable the watchdog. + */ +static void inline at91_wdt_stop(void) +{ + at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); +} + +/* + * Enable and reset the watchdog. + */ +static void inline at91_wdt_start(void) +{ + at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + +/* + * Reload the watchdog timer. (ie, pat the watchdog) + */ +static void inline at91_wdt_reload(void) +{ + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + +/* ......................................................................... */ + +/* + * Watchdog device is opened, and watchdog starts running. + */ +static int at91_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(0, &at91wdt_busy)) + return -EBUSY; + + at91_wdt_start(); + return nonseekable_open(inode, file); +} + +/* + * Close the watchdog device. + * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also + * disabled. + */ +static int at91_wdt_close(struct inode *inode, struct file *file) +{ + if (!nowayout) + at91_wdt_stop(); /* Disable the watchdog when file is closed */ + + clear_bit(0, &at91wdt_busy); + return 0; +} + +/* + * Change the watchdog time interval. + */ +static int at91_wdt_settimeout(int new_time) +{ + /* + * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz + * + * Since WDV is a 16-bit counter, the maximum period is + * 65536 / 0.256 = 256 seconds. + */ + if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) + return -EINVAL; + + /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ + wdt_time = new_time; + return 0; +} + +static struct watchdog_info at91_wdt_info = { + .identity = "at91 watchdog", + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, +}; + +/* + * Handle commands from user-space. + */ +static int at91_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + int new_value; + + switch(cmd) { + case WDIOC_KEEPALIVE: + at91_wdt_reload(); /* pat the watchdog */ + return 0; + + case WDIOC_GETSUPPORT: + return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; + + case WDIOC_SETTIMEOUT: + if (get_user(new_value, p)) + return -EFAULT; + + if (at91_wdt_settimeout(new_value)) + return -EINVAL; + + /* Enable new time value */ + at91_wdt_start(); + + /* Return current value */ + return put_user(wdt_time, p); + + case WDIOC_GETTIMEOUT: + return put_user(wdt_time, p); + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, p); + + case WDIOC_SETOPTIONS: + if (get_user(new_value, p)) + return -EFAULT; + + if (new_value & WDIOS_DISABLECARD) + at91_wdt_stop(); + if (new_value & WDIOS_ENABLECARD) + at91_wdt_start(); + return 0; + + default: + return -ENOTTY; + } +} + +/* + * Pat the watchdog whenever device is written to. + */ +static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) +{ + at91_wdt_reload(); /* pat the watchdog */ + return len; +} + +/* ......................................................................... */ + +static const struct file_operations at91wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = at91_wdt_ioctl, + .open = at91_wdt_open, + .release = at91_wdt_close, + .write = at91_wdt_write, +}; + +static struct miscdevice at91wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &at91wdt_fops, +}; + +static int __init at91wdt_probe(struct platform_device *pdev) +{ + int res; + + if (at91wdt_miscdev.dev) + return -EBUSY; + at91wdt_miscdev.dev = &pdev->dev; + + res = misc_register(&at91wdt_miscdev); + if (res) + return res; + + printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); + return 0; +} + +static int __exit at91wdt_remove(struct platform_device *pdev) +{ + int res; + + res = misc_deregister(&at91wdt_miscdev); + if (!res) + at91wdt_miscdev.dev = NULL; + + return res; +} + +static void at91wdt_shutdown(struct platform_device *pdev) +{ + at91_wdt_stop(); +} + +#ifdef CONFIG_PM + +static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) +{ + at91_wdt_stop(); + return 0; +} + +static int at91wdt_resume(struct platform_device *pdev) +{ + if (at91wdt_busy) + at91_wdt_start(); + return 0; +} + +#else +#define at91wdt_suspend NULL +#define at91wdt_resume NULL +#endif + +static struct platform_driver at91wdt_driver = { + .probe = at91wdt_probe, + .remove = __exit_p(at91wdt_remove), + .shutdown = at91wdt_shutdown, + .suspend = at91wdt_suspend, + .resume = at91wdt_resume, + .driver = { + .name = "at91_wdt", + .owner = THIS_MODULE, + }, +}; + +static int __init at91_wdt_init(void) +{ + /* Check that the heartbeat value is within range; if not reset to the default */ + if (at91_wdt_settimeout(wdt_time)) { + at91_wdt_settimeout(WDT_DEFAULT_TIME); + pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); + } + + return platform_driver_register(&at91wdt_driver); +} + +static void __exit at91_wdt_exit(void) +{ + platform_driver_unregister(&at91wdt_driver); +} + +module_init(at91_wdt_init); +module_exit(at91_wdt_exit); + +MODULE_AUTHOR("Andrew Victor"); +MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit From cbf40d3f04c2c76a58f1183bb4a9a82fefb842e3 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Sat, 14 Oct 2006 20:18:47 +0200 Subject: [WATCHDOG] remove experimental on iTCO_wdt.c The iTCO_wdt.c driver has been tested enough. So we can remove the experimental classification. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/Kconfig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 529f0a70690..0187b118532 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -316,13 +316,16 @@ config I8XX_TCO To compile this driver as a module, choose M here: the module will be called i8xx_tco. + Note: This driver will be removed in the near future. Please + use the Intel TCO Timer/Watchdog driver. + config ITCO_WDT - tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)" - depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL + tristate "Intel TCO Timer/Watchdog" + depends on WATCHDOG && (X86 || IA64) && PCI ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB + Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer @@ -590,7 +593,7 @@ config SH_WDT_MMAP help If you say Y here, user applications will be able to mmap the WDT/CPG registers. -# + # SPARC64 Architecture config WATCHDOG_CP1XXX -- cgit From 18088748d2a493ce9f6adf0be7f833b04041807e Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 4 Oct 2006 14:56:44 +0200 Subject: [AGPGART] uninorth: Add module param 'aperture' for aperture size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In contrast to most if not all PC BIOSes, OpenFirmware (OF) on PowerMacs with UniNorth bridges does not allow changing the aperture size. The size set up by OF is usually 16 MB, which is too low for graphics intensive environments. Hence, add a module parameter that allows changing the aperture size at driver initialization time. When the parameter is not specified, the default is 32 MB. Signed-off-by: Michel Dänzer Acked-by: Benjamin Herrenschmidt Signed-off-by: Dave Jones --- drivers/char/agp/uninorth-agp.c | 54 ++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 91b71e750ee..dffc19382f7 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -27,32 +27,42 @@ static int uninorth_rev; static int is_u3; +static char __devinitdata *aperture = NULL; static int uninorth_fetch_size(void) { - int i; - u32 temp; - struct aper_size_info_32 *values; - - pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp); - temp &= ~(0xfffff000); - values = A_SIZE_32(agp_bridge->driver->aperture_sizes); - - for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { - if (temp == values[i].size_value) { - agp_bridge->previous_size = - agp_bridge->current_size = (void *) (values + i); - agp_bridge->aperture_size_idx = i; - return values[i].size; + int i, size = 0; + struct aper_size_info_32 *values = + A_SIZE_32(agp_bridge->driver->aperture_sizes); + + if (aperture) { + char *save = aperture; + + size = memparse(aperture, &aperture) >> 20; + aperture = save; + + for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) + if (size == values[i].size) + break; + + if (i == agp_bridge->driver->num_aperture_sizes) { + printk(KERN_ERR PFX "Invalid aperture size, using" + " default\n"); + size = 0; + aperture = NULL; } } - agp_bridge->previous_size = - agp_bridge->current_size = (void *) (values + 1); - agp_bridge->aperture_size_idx = 1; - return values[1].size; + if (!size) { + for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) + if (values[i].size == 32) + break; + } - return 0; + agp_bridge->previous_size = + agp_bridge->current_size = (void *)(values + i); + agp_bridge->aperture_size_idx = i; + return values[i].size; } static void uninorth_tlbflush(struct agp_memory *mem) @@ -683,5 +693,11 @@ static void __exit agp_uninorth_cleanup(void) module_init(agp_uninorth_init); module_exit(agp_uninorth_cleanup); +module_param(aperture, charp, 0); +MODULE_PARM_DESC(aperture, + "Aperture size, must be power of two between 4MB and an\n" + "\t\tupper limit specific to the UniNorth revision.\n" + "\t\tDefault: 32M"); + MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); MODULE_LICENSE("GPL"); -- cgit From 3693ec670b3bb4d11295856bea3592dd8f37f9a5 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 26 Sep 2006 13:22:41 -0500 Subject: [PATCH] bcm43xx: fix race condition in periodic work handler There is a potential race condition in the periodic_work_handler routine of bcm43xx-softmac. In addition to fixing this condition, the size of code is reduced by moving the mutex lock outside the if. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index bad3452ea89..0f047d42158 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3164,12 +3164,12 @@ static void bcm43xx_periodic_work_handler(void *d) u32 savedirqs = 0; int badness; + mutex_lock(&bcm->mutex); badness = estimate_periodic_work_badness(bcm->periodic_state); if (badness > BADNESS_LIMIT) { /* Periodic work will take a long time, so we want it to * be preemtible. */ - mutex_lock(&bcm->mutex); netif_tx_disable(bcm->net_dev); spin_lock_irqsave(&bcm->irq_lock, flags); bcm43xx_mac_suspend(bcm); @@ -3182,7 +3182,6 @@ static void bcm43xx_periodic_work_handler(void *d) /* Periodic work should take short time, so we want low * locking overhead. */ - mutex_lock(&bcm->mutex); spin_lock_irqsave(&bcm->irq_lock, flags); } -- cgit From 7c28ad2d83ecc637237fe684659a6afbce0bb2a8 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 27 Sep 2006 15:26:33 +0300 Subject: [PATCH] softmac: Fix WX and association related races This fixes some race conditions in the WirelessExtension handling and association handling code. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 2 +- drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index c3f90c8563d..2ddbec6bf15 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) //TODO break; case BCM43xx_LED_ASSOC: - if (bcm->softmac->associated) + if (bcm->softmac->associnfo.associated) turn_on = 1; break; #ifdef CONFIG_BCM43XX_DEBUG diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 9b7b15cf656..d27016f8c73 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d unsigned long flags; wstats = &bcm->stats.wstats; - if (!mac->associated) { + if (!mac->associnfo.associated) { wstats->miss.beacon = 0; // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? wstats->discard.retries = 0; -- cgit From 16bfa676a7cc64695f7e9694c380ebd26c461ae5 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 28 Sep 2006 00:10:55 -0500 Subject: [PATCH] bcm43xx-softmac: check returned value from pci_enable_device Linus's tree now has a configuration option that prints a warning whenever the returned value of any routine is ignored. This patch fixes the only such warning for bcm43xx. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 0f047d42158..7776b5c42ac 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -4207,7 +4207,11 @@ static int bcm43xx_resume(struct pci_dev *pdev) dprintk(KERN_INFO PFX "Resuming...\n"); pci_set_power_state(pdev, 0); - pci_enable_device(pdev); + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR PFX "Failure with pci_enable_device!\n"); + return err; + } pci_restore_state(pdev); bcm43xx_chipset_attach(bcm); -- cgit From 8da81e52b743edac0bfbb7d0c1286f919b2f209b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 2 Oct 2006 23:48:54 -0500 Subject: [PATCH] bcm43xx-softmac: Fix system hang for x86-64 with >1GB RAM The bcm43xx-softmac software currently fails when running on x86_64 systems with more than 1GB RAM and one of the card variants with 30-bit DMA addressing. This patch uses the address extension bits in the hardware to set the correct DMA mask for the specific card in use. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 28 +++++++++++++++++++++++----- drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 17 +++++++++++++++++ drivers/net/wireless/bcm43xx/bcm43xx_main.c | 25 ++++++------------------- 3 files changed, 46 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index 76e3aed4b47..978ed099e28 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) struct bcm43xx_dmaring *ring; int err = -ENOMEM; int dma64 = 0; - u32 sbtmstatehi; + u64 mask = bcm43xx_get_supported_dma_mask(bcm); + int nobits; - sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT) + if (mask == DMA_64BIT_MASK) { dma64 = 1; + nobits = 64; + } else if (mask == DMA_32BIT_MASK) + nobits = 32; + else + nobits = 30; + err = pci_set_dma_mask(bcm->pci_dev, mask); + err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask); + if (err) { +#ifdef CONFIG_BCM43XX_PIO + printk(KERN_WARNING PFX "DMA not supported on this device." + " Falling back to PIO.\n"); + bcm->__using_pio = 1; + return -ENOSYS; +#else + printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " + "Please recompile the driver with PIO support.\n"); + return -ENODEV; +#endif /* CONFIG_BCM43XX_PIO */ + } /* setup TX DMA channels. */ ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); @@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) dma->rx_ring3 = ring; } - dprintk(KERN_INFO PFX "%s DMA initialized\n", - dma64 ? "64-bit" : "32-bit"); + dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits); err = 0; out: return err; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index e04bcaddd1d..ea16078cfe9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h @@ -314,6 +314,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm, struct ieee80211_txb *txb); void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); +/* Helper function that returns the dma mask for this device. */ +static inline +u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm) +{ + int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) & + BCM43xx_SBTMSTATEHIGH_DMA64BIT; + u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0); + u32 mask = BCM43xx_DMA32_TXADDREXT_MASK; + + if (dma64) + return DMA_64BIT_MASK; + bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask); + if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask) + return DMA_32BIT_MASK; + return DMA_30BIT_MASK; +} + #else /* CONFIG_BCM43XX_DMA */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 7776b5c42ac..a94c6d8826f 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -2925,10 +2925,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm, bcm43xx_write16(bcm, 0x043C, 0x000C); if (active_wlcore) { - if (bcm43xx_using_pio(bcm)) + if (bcm43xx_using_pio(bcm)) { err = bcm43xx_pio_init(bcm); - else + } else { err = bcm43xx_dma_init(bcm); + if (err == -ENOSYS) + err = bcm43xx_pio_init(bcm); + } if (err) goto err_chip_cleanup; } @@ -3992,8 +3995,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, struct net_device *net_dev, struct pci_dev *pci_dev) { - int err; - bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm->ieee = netdev_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev); @@ -4011,22 +4012,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, (void (*)(unsigned long))bcm43xx_interrupt_tasklet, (unsigned long)bcm); tasklet_disable_nosync(&bcm->isr_tasklet); - if (modparam_pio) { + if (modparam_pio) bcm->__using_pio = 1; - } else { - err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); - err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); - if (err) { -#ifdef CONFIG_BCM43XX_PIO - printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); - bcm->__using_pio = 1; -#else - printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " - "Recompile the driver with PIO support, please.\n"); - return -ENODEV; -#endif /* CONFIG_BCM43XX_PIO */ - } - } bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; /* default to sw encryption for now */ -- cgit From 431aca5a18f15f61cc51c466073928c4f9565fe4 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Tue, 10 Oct 2006 16:46:30 -0400 Subject: [PATCH] airo.c: check returned values create_proc_entry() can fail and return NULL in setup_proc_entry(), the result must be checked before dereferencing. (Coverity ID 1443) init_wifidev() & setup_proc_entry() can also fail in _init_airo_card(). This adds the checks & cleanup code and removes some whitespace. Signed-off-by: Florin Malita Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 98 +++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 0a33c8a56e1..9d5427a6e60 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2897,6 +2897,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, goto err_out_map; } ai->wifidev = init_wifidev(ai, dev); + if (!ai->wifidev) + goto err_out_reg; set_bit(FLAG_REGISTERED,&ai->flags); airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", @@ -2908,11 +2910,18 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, for( i = 0; i < MAX_FIDS; i++ ) ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); - setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ + if (setup_proc_entry(dev, dev->priv) < 0) + goto err_out_wifi; + netif_start_queue(dev); SET_MODULE_OWNER(dev); return dev; +err_out_wifi: + unregister_netdev(ai->wifidev); + free_netdev(ai->wifidev); +err_out_reg: + unregister_netdev(dev); err_out_map: if (test_bit(FLAG_MPI,&ai->flags) && pci) { pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); @@ -4495,91 +4504,128 @@ static int setup_proc_entry( struct net_device *dev, apriv->proc_entry = create_proc_entry(apriv->proc_name, S_IFDIR|airo_perm, airo_entry); - apriv->proc_entry->uid = proc_uid; - apriv->proc_entry->gid = proc_gid; - apriv->proc_entry->owner = THIS_MODULE; + if (!apriv->proc_entry) + goto fail; + apriv->proc_entry->uid = proc_uid; + apriv->proc_entry->gid = proc_gid; + apriv->proc_entry->owner = THIS_MODULE; /* Setup the StatsDelta */ entry = create_proc_entry("StatsDelta", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_stats_delta; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_statsdelta_ops); /* Setup the Stats */ entry = create_proc_entry("Stats", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_stats; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_stats_ops); /* Setup the Status */ entry = create_proc_entry("Status", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_status; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_status_ops); /* Setup the Config */ entry = create_proc_entry("Config", S_IFREG | proc_perm, apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_config; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_config_ops); /* Setup the SSID */ entry = create_proc_entry("SSID", S_IFREG | proc_perm, apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_ssid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_SSID_ops); /* Setup the APList */ entry = create_proc_entry("APList", S_IFREG | proc_perm, apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_aplist; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_APList_ops); /* Setup the BSSList */ entry = create_proc_entry("BSSList", S_IFREG | proc_perm, apriv->proc_entry); + if (!entry) + goto fail_bsslist; entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_BSSList_ops); /* Setup the WepKey */ entry = create_proc_entry("WepKey", S_IFREG | proc_perm, apriv->proc_entry); - entry->uid = proc_uid; - entry->gid = proc_gid; + if (!entry) + goto fail_wepkey; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_wepkey_ops); return 0; + +fail_wepkey: + remove_proc_entry("BSSList", apriv->proc_entry); +fail_bsslist: + remove_proc_entry("APList", apriv->proc_entry); +fail_aplist: + remove_proc_entry("SSID", apriv->proc_entry); +fail_ssid: + remove_proc_entry("Config", apriv->proc_entry); +fail_config: + remove_proc_entry("Status", apriv->proc_entry); +fail_status: + remove_proc_entry("Stats", apriv->proc_entry); +fail_stats: + remove_proc_entry("StatsDelta", apriv->proc_entry); +fail_stats_delta: + remove_proc_entry(apriv->proc_name, airo_entry); +fail: + return -ENOMEM; } static int takedown_proc_entry( struct net_device *dev, -- cgit From 7e4e8d99c2288a490a0806b9cb40016913312cfe Mon Sep 17 00:00:00 2001 From: Jean Tourrilhes Date: Tue, 10 Oct 2006 14:45:44 -0700 Subject: [PATCH] orinoco: fix WE-21 buffer overflow This patch fixes the Orinoco driver overflow issue with WE-21. Cc: Valdis Kletnieks Cc: Pavel Roskin Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index b779c7dcc1a..336cabac13b 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -2457,6 +2457,7 @@ void free_orinocodev(struct net_device *dev) /* Wireless extensions */ /********************************************************************/ +/* Return : < 0 -> error code ; >= 0 -> length */ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]) { @@ -2501,9 +2502,9 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, len = le16_to_cpu(essidbuf.len); BUG_ON(len > IW_ESSID_MAX_SIZE); - memset(buf, 0, IW_ESSID_MAX_SIZE+1); + memset(buf, 0, IW_ESSID_MAX_SIZE); memcpy(buf, p, len); - buf[len] = '\0'; + err = len; fail_unlock: orinoco_unlock(priv, &flags); @@ -3027,17 +3028,18 @@ static int orinoco_ioctl_getessid(struct net_device *dev, if (netif_running(dev)) { err = orinoco_hw_get_essid(priv, &active, essidbuf); - if (err) + if (err < 0) return err; + erq->length = err; } else { if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); + memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); + erq->length = strlen(priv->desired_essid); orinoco_unlock(priv, &flags); } erq->flags = 1; - erq->length = strlen(essidbuf); return 0; } @@ -3075,10 +3077,10 @@ static int orinoco_ioctl_getnick(struct net_device *dev, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); + memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE); orinoco_unlock(priv, &flags); - nrq->length = strlen(nickbuf); + nrq->length = strlen(priv->nick); return 0; } -- cgit From 683f8c9e00d2aa911382186ca891bd221efaea74 Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Tue, 10 Oct 2006 14:45:45 -0700 Subject: [PATCH] zd1201: Possible NULL dereference If we enter the if(!zd) and set free to 1, we dereference zd in the exit code. Signed-off-by: Eric Sesterhenn Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/zd1201.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 30057a335a7..36b29ff0581 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -193,10 +193,8 @@ static void zd1201_usbrx(struct urb *urb) struct sk_buff *skb; unsigned char type; - if (!zd) { - free = 1; - goto exit; - } + if (!zd) + return; switch(urb->status) { case -EILSEQ: -- cgit From 53077944f119808df3d1c6be07241f17a87e7c28 Mon Sep 17 00:00:00 2001 From: Jean Tourrilhes Date: Tue, 10 Oct 2006 14:45:46 -0700 Subject: [PATCH] wireless: More WE-21 potential overflows... After the Orinoco issue, I did an audit of other drivers for the same issue. Three drivers were NULL terminating the ESSID, which could cause an overflow in WE-21 when the ESSID has maximum size. Signed-off-by: Jean Tourrilhes Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 1 - drivers/net/wireless/atmel.c | 2 -- drivers/net/wireless/ray_cs.c | 1 - 3 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 9d5427a6e60..e0710fa9702 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5970,7 +5970,6 @@ static int airo_get_essid(struct net_device *dev, /* Get the current SSID */ memcpy(extra, status_rid.SSID, status_rid.SSIDlen); - extra[status_rid.SSIDlen] = '\0'; /* If none, we may want to get the one that was set */ /* Push it out ! */ diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 31eed85de60..0c07b8b7250 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1678,11 +1678,9 @@ static int atmel_get_essid(struct net_device *dev, /* Get the current SSID */ if (priv->new_SSID_size != 0) { memcpy(extra, priv->new_SSID, priv->new_SSID_size); - extra[priv->new_SSID_size] = '\0'; dwrq->length = priv->new_SSID_size; } else { memcpy(extra, priv->SSID, priv->SSID_size); - extra[priv->SSID_size] = '\0'; dwrq->length = priv->SSID_size; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0b381d77015..7fbfc9e41d0 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1198,7 +1198,6 @@ static int ray_get_essid(struct net_device *dev, /* Get the essid that was set */ memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); - extra[IW_ESSID_MAX_SIZE] = '\0'; /* Push it out ! */ dwrq->length = strlen(extra); -- cgit From 5bb85f18087b10a908bd793e9fd3ccd63aebb724 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 10 Oct 2006 14:45:46 -0700 Subject: [PATCH] airo: check if need to freeze The airo driver used to break out of while loop if there were any signals pending. Since it no longer checks for signals, it at least needs to check if it needs to be frozen. Signed-off-by: Dave Kleikamp Cc: Jean Tourrilhes Cc: Sukadev Bhattiprolu Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index e0710fa9702..efcdaf1c5f7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -3098,7 +3098,8 @@ static int airo_thread(void *data) { set_bit(JOB_AUTOWEP, &ai->jobs); break; } - if (!kthread_should_stop()) { + if (!kthread_should_stop() && + !freezing(current)) { unsigned long wake_at; if (!ai->expires || !ai->scan_timeout) { wake_at = max(ai->expires, @@ -3110,7 +3111,8 @@ static int airo_thread(void *data) { schedule_timeout(wake_at - jiffies); continue; } - } else if (!kthread_should_stop()) { + } else if (!kthread_should_stop() && + !freezing(current)) { schedule(); continue; } -- cgit From 41072a1be57f63bf83afc31c44d72de018d800fa Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 17 Oct 2006 13:47:40 -0400 Subject: [PATCH] zd1211rw: fix build-break caused by association race fix The break was caused by 7c28ad2d83ecc637237fe684659a6afbce0bb2a8. Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 2d12837052b..a7d29bddb29 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1099,7 +1099,7 @@ static void link_led_handler(void *p) int r; spin_lock_irq(&mac->lock); - is_associated = sm->associated != 0; + is_associated = sm->associnfo.associated != 0; spin_unlock_irq(&mac->lock); r = zd_chip_control_leds(chip, -- cgit From 082c44d20eb4c6c4aa60ae7429ea184854cb0610 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 19 Oct 2006 16:16:18 +0900 Subject: sh: Cleanup board header directories. Now with the ide.h mess sorted out, most of these boards don't need their own directory. Move the headers out, and update the driver paths. Signed-off-by: Paul Mundt --- drivers/input/touchscreen/hp680_ts_input.c | 2 +- drivers/video/hitfb.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index e31c6c55b2e..58fca316786 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #define MODNAME "hp680_ts_input" diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 3afb472763c..3dc49424dc7 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -29,7 +29,6 @@ #include #include #include -#include #define WIDTH 640 -- cgit From a1bae67243512ca30ceda48e3e24e25b543f8ab7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] i386: Disable nmi watchdog on all ThinkPads Even newer Thinkpads have bugs in SMM code that causes hangs with NMI watchdog. Signed-off-by: Andi Kleen --- drivers/firmware/dmi_scan.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index b8b596d5778..37deee6c0c1 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -326,6 +326,26 @@ char *dmi_get_system_info(int field) } EXPORT_SYMBOL(dmi_get_system_info); + +/** + * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. + * @str: Case sensitive Name + */ +int dmi_name_in_vendors(char *str) +{ + static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, + DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, + DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE }; + int i; + for (i = 0; fields[i] != DMI_NONE; i++) { + int f = fields[i]; + if (dmi_ident[f] && strstr(dmi_ident[f], str)) + return 1; + } + return 0; +} +EXPORT_SYMBOL(dmi_name_in_vendors); + /** * dmi_find_device - find onboard device by type/name * @type: device type or %DMI_DEV_TYPE_ANY to match all device types -- cgit From 718ecac2ed7ae1b3d61388ddbff2938a377b1a11 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 20 Oct 2006 14:42:04 -0700 Subject: [PATCH] Update smc91x driver with ARM Versatile board info We need to specify a Versatile-specific SMC_IRQ_FLAGS value or the new generic IRQ layer will complain thusly: No IRQF_TRIGGER set_type function for IRQ 25 () Signed-off-by: Deepak Saxena Cc: Jeff Garzik Cc: Russell King Cc: Nicolas Pitre Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/smc91x.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 0c9f1e7dab2..a8640169fc7 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -416,6 +416,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS (0) +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + #else #define SMC_CAN_USE_8BIT 1 -- cgit From 6f0f6d87a2a5fc96fc54e90961d5244d668e5fbb Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 20 Oct 2006 14:43:15 -0700 Subject: [PATCH] WAN/pc300: handle, propagate minor errors - move definition of 'tmc' and 'br' locals closer to usage - handle clock_rate_calc() error - propagate errors back to upper level open routine Signed-off-by: Jeff Garzik Cc: Krzysztof Halasa Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/wan/pc300_drv.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 5823e3bca17..36d1c3ff707 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -2867,7 +2867,6 @@ static int ch_config(pc300dev_t * d) uclong clktype = chan->conf.phys_settings.clock_type; ucshort encoding = chan->conf.proto_settings.encoding; ucshort parity = chan->conf.proto_settings.parity; - int tmc, br; ucchar md0, md2; /* Reset the channel */ @@ -2940,8 +2939,12 @@ static int ch_config(pc300dev_t * d) case PC300_RSV: case PC300_X21: if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { + int tmc, br; + /* Calculate the clkrate parameters */ tmc = clock_rate_calc(clkrate, card->hw.clock, &br); + if (tmc < 0) + return -EIO; cpc_writeb(scabase + M_REG(TMCT, ch), tmc); cpc_writeb(scabase + M_REG(TXS, ch), (TXS_DTRXC | TXS_IBRG | br)); @@ -3097,14 +3100,16 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding, return 0; } -static void cpc_opench(pc300dev_t * d) +static int cpc_opench(pc300dev_t * d) { pc300ch_t *chan = (pc300ch_t *) d->chan; pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel; + int ch = chan->channel, rc; void __iomem *scabase = card->hw.scabase; - ch_config(d); + rc = ch_config(d); + if (rc) + return rc; rx_config(d); @@ -3113,6 +3118,8 @@ static void cpc_opench(pc300dev_t * d) /* Assert RTS and DTR */ cpc_writeb(scabase + M_REG(CTL, ch), cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); + + return 0; } static void cpc_closech(pc300dev_t * d) @@ -3168,9 +3175,16 @@ int cpc_open(struct net_device *dev) } sprintf(ifr.ifr_name, "%s", dev->name); - cpc_opench(d); + result = cpc_opench(d); + if (result) + goto err_out; + netif_start_queue(dev); return 0; + +err_out: + hdlc_close(dev); + return result; } static int cpc_close(struct net_device *dev) -- cgit From 7347b03d25ad7d7f001373cf64f709457c6af618 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 20 Oct 2006 14:42:14 -0700 Subject: [PATCH] e1000: Reset all functions after a PCI error During the handling of the PCI error recovery sequence, the current e1000 driver erroneously blocks a device reset for any but the first PCI function. It shouldn't -- this is a cut-n-paste error from a different driver (which tolerated only one hardware reset per hardware card). Signed-off-by: Linas Vepstas Cc: Jesse Brandeburg Acked-by: Auke Kok Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ce0d35fe394..fa849831d09 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4914,10 +4914,6 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); - /* Perform card reset only on one instance of the card */ - if (PCI_FUNC (pdev->devfn) != 0) - return PCI_ERS_RESULT_RECOVERED; - e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); -- cgit From 470ea7eba4aaa517533f9b02ac9a104e77264548 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Oct 2006 17:06:11 -0700 Subject: [PATCH] sky2: 88E803X transmit lockup The reason sky2 driver was locking up on transmit on the Yukon-FE chipset is that it was misconfiguring the internal RAM buffer so the transmitter and receiver were sharing the same space. The code assumed there was 16K of RAM on Yukon-FE (taken from vendor driver sk98lin which is even more f*cked up on this). Then it assigned based on that. The giveaway was that the registers would only hold 9bits so both RX/TX had 0..1ff for space. It is a wonder it worked at all! This patch addresses this, and fixes an easily reproducible hang on Transmit. Only the Yukon-FE chip is Marvell 88E803X (10/100 only) are affected. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 67ecd66f26d..95efdb5bbbe 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -699,16 +699,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) } -/* Assign Ram Buffer allocation. - * start and end are in units of 4k bytes - * ram registers are in units of 64bit words - */ -static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) +/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */ +static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) { - u32 start, end; - - start = startk * 4096/8; - end = (endk * 4096/8) - 1; + pr_debug(PFX "q %d %#x %#x\n", q, start, end); sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); sky2_write32(hw, RB_ADDR(q, RB_START), start); @@ -717,7 +711,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) sky2_write32(hw, RB_ADDR(q, RB_RP), start); if (q == Q_R1 || q == Q_R2) { - u32 space = (endk - startk) * 4096/8; + u32 space = end - start + 1; u32 tp = space - space/4; /* On receive queue's set the thresholds @@ -1199,19 +1193,16 @@ static int sky2_up(struct net_device *dev) sky2_mac_init(hw, port); - /* Determine available ram buffer space (in 4K blocks). - * Note: not sure about the FE setting below yet - */ - if (hw->chip_id == CHIP_ID_YUKON_FE) - ramsize = 4; - else - ramsize = sky2_read8(hw, B2_E_0); + /* Determine available ram buffer space in qwords. */ + ramsize = sky2_read8(hw, B2_E_0) * 4096/8; - /* Give transmitter one third (rounded up) */ - rxspace = ramsize - (ramsize + 2) / 3; + if (ramsize > 6*1024/8) + rxspace = ramsize - (ramsize + 2) / 3; + else + rxspace = ramsize / 2; - sky2_ramset(hw, rxqaddr[port], 0, rxspace); - sky2_ramset(hw, txqaddr[port], rxspace, ramsize); + sky2_ramset(hw, rxqaddr[port], 0, rxspace-1); + sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1); /* Make sure SyncQ is disabled */ sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), -- cgit From 18a8e8649d2687283da51fbcf8218372dc5a8f6f Mon Sep 17 00:00:00 2001 From: Li Yang Date: Thu, 19 Oct 2006 21:07:34 -0500 Subject: [PATCH] ucc_geth: changes to ucc_geth driver as a result of qe_lib changes and bugfixes changes due to qe_lib changes include: o removed inclusion of platform header file o removed platform_device code, replaced with of_device o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o removed irrelevant comments, added others to resemble removed BD_ defines o const'd and uncasted all get_property() assignments bugfixes, courtesy of Scott Wood, include: - Read phy_address as a u32, not u8. - Match on type == "network" as well as compatible == "ucc_geth", as device_is_compatible() will only compare up to the length of the test string, allowing "ucc_geth_phy" to match as well. - fixes the MAC setting code in ucc_geth.c. The old code was overwriting and dereferencing random stack contents. Signed-off-by: Li Yang Signed-off-by: Kim Phillips Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- drivers/net/ucc_geth.c | 633 ++++++++++++++++++++++++--------------------- drivers/net/ucc_geth.h | 248 +++++++++--------- drivers/net/ucc_geth_phy.c | 26 +- drivers/net/ucc_geth_phy.h | 2 +- 5 files changed, 475 insertions(+), 436 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ab92cc794c6..e2ed24918a5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2288,7 +2288,7 @@ config UGETH_TX_ON_DEMOND config UGETH_HAS_GIGA bool - depends on UCC_GETH && MPC836x + depends on UCC_GETH && PPC_MPC836x config MV643XX_ETH tristate "MV-643XX Ethernet support" diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 12cd7b561f3..b3788801106 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2,14 +2,11 @@ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. * * Author: Shlomi Gridish + * Li Yang * * Description: * QE UCC Gigabit Ethernet Driver * - * Changelog: - * Jul 6, 2006 Li Yang - * - Rearrange code and style fixes - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -31,9 +28,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -70,7 +67,7 @@ static DEFINE_SPINLOCK(ugeth_lock); -static ucc_geth_info_t ugeth_primary_info = { +static struct ucc_geth_info ugeth_primary_info = { .uf_info = { .bd_mem_part = MEM_PART_SYSTEM, .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, @@ -163,7 +160,7 @@ static ucc_geth_info_t ugeth_primary_info = { .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, }; -static ucc_geth_info_t ugeth_info[8]; +static struct ucc_geth_info ugeth_info[8]; #ifdef DEBUG static void mem_disp(u8 *addr, int size) @@ -219,8 +216,8 @@ static struct list_head *dequeue(struct list_head *lh) } } -static int get_interface_details(enet_interface_e enet_interface, - enet_speed_e *speed, +static int get_interface_details(enum enet_interface enet_interface, + enum enet_speed *speed, int *r10m, int *rmm, int *rpm, @@ -283,7 +280,7 @@ static int get_interface_details(enet_interface_e enet_interface, return 0; } -static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) +static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) { struct sk_buff *skb = NULL; @@ -303,21 +300,19 @@ static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) skb->dev = ugeth->dev; - BD_BUFFER_SET(bd, + out_be32(&((struct qe_bd *)bd)->buf, dma_map_single(NULL, skb->data, ugeth->ug_info->uf_info.max_rx_buf_length + UCC_GETH_RX_DATA_BUF_ALIGNMENT, DMA_FROM_DEVICE)); - BD_STATUS_AND_LENGTH_SET(bd, - (R_E | R_I | - (BD_STATUS_AND_LENGTH(bd) & R_W))); + out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W))); return skb; } -static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) +static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) { u8 *bd; u32 bd_status; @@ -328,7 +323,7 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) i = 0; do { - bd_status = BD_STATUS_AND_LENGTH(bd); + bd_status = in_be32((u32*)bd); skb = get_new_skb(ugeth, bd); if (!skb) /* If can not allocate data buffer, @@ -338,19 +333,19 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) ugeth->rx_skbuff[rxQ][i] = skb; /* advance the BD pointer */ - bd += UCC_GETH_SIZE_OF_BD; + bd += sizeof(struct qe_bd); i++; } while (!(bd_status & R_W)); return 0; } -static int fill_init_enet_entries(ucc_geth_private_t *ugeth, +static int fill_init_enet_entries(struct ucc_geth_private *ugeth, volatile u32 *p_start, u8 num_entries, u32 thread_size, u32 thread_alignment, - qe_risc_allocation_e risc, + enum qe_risc_allocation risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -383,10 +378,10 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth, return 0; } -static int return_init_enet_entries(ucc_geth_private_t *ugeth, +static int return_init_enet_entries(struct ucc_geth_private *ugeth, volatile u32 *p_start, u8 num_entries, - qe_risc_allocation_e risc, + enum qe_risc_allocation risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -416,11 +411,11 @@ static int return_init_enet_entries(ucc_geth_private_t *ugeth, } #ifdef DEBUG -static int dump_init_enet_entries(ucc_geth_private_t *ugeth, +static int dump_init_enet_entries(struct ucc_geth_private *ugeth, volatile u32 *p_start, u8 num_entries, u32 thread_size, - qe_risc_allocation_e risc, + enum qe_risc_allocation risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -456,14 +451,14 @@ static int dump_init_enet_entries(ucc_geth_private_t *ugeth, #endif #ifdef CONFIG_UGETH_FILTERING -static enet_addr_container_t *get_enet_addr_container(void) +static struct enet_addr_container *get_enet_addr_container(void) { - enet_addr_container_t *enet_addr_cont; + struct enet_addr_container *enet_addr_cont; /* allocate memory */ - enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL); + enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL); if (!enet_addr_cont) { - ugeth_err("%s: No memory for enet_addr_container_t object.", + ugeth_err("%s: No memory for enet_addr_container object.", __FUNCTION__); return NULL; } @@ -472,45 +467,43 @@ static enet_addr_container_t *get_enet_addr_container(void) } #endif /* CONFIG_UGETH_FILTERING */ -static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont) +static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont) { kfree(enet_addr_cont); } +static int set_mac_addr(__be16 __iomem *reg, u8 *mac) +{ + out_be16(®[0], ((u16)mac[5] << 8) | mac[4]); + out_be16(®[1], ((u16)mac[3] << 8) | mac[2]); + out_be16(®[2], ((u16)mac[1] << 8) | mac[0]); +} + #ifdef CONFIG_UGETH_FILTERING -static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr, u8 paddr_num) +static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, + u8 *p_enet_addr, u8 paddr_num) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); + ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__); return -EINVAL; } p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> addressfiltering; /* Ethernet frames are defined in Little Endian mode, */ /* therefore to insert the address we reverse the bytes. */ - out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, - (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | - (u16) (*p_enet_addr)[4])); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, - (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | - (u16) (*p_enet_addr)[2])); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, - (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | - (u16) (*p_enet_addr)[0])); - + set_mac_addr(&p_82xx_addr_filt->paddr[paddr_num].h, p_enet_addr); return 0; } #endif /* CONFIG_UGETH_FILTERING */ -static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) +static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); @@ -518,7 +511,7 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) } p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> addressfiltering; /* Writing address ff.ff.ff.ff.ff.ff disables address @@ -530,14 +523,14 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) return 0; } -static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) +static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, + u8 *p_enet_addr) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; u32 cecr_subblock; p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> addressfiltering; cecr_subblock = @@ -546,25 +539,18 @@ static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, /* Ethernet frames are defined in Little Endian mode, therefor to insert */ /* the address to the hash (Big Endian mode), we reverse the bytes.*/ - out_be16(&p_82xx_addr_filt->taddr.h, - (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | - (u16) (*p_enet_addr)[4])); - out_be16(&p_82xx_addr_filt->taddr.m, - (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | - (u16) (*p_enet_addr)[2])); - out_be16(&p_82xx_addr_filt->taddr.l, - (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | - (u16) (*p_enet_addr)[0])); + + set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); + QE_CR_PROTOCOL_ETHERNET, 0); } #ifdef CONFIG_UGETH_MAGIC_PACKET -static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) +static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) { - ucc_fast_private_t *uccf; - ucc_geth_t *ug_regs; + struct ucc_fast_private *uccf; + struct ucc_geth *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -581,10 +567,10 @@ static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) out_be32(&ug_regs->maccfg2, maccfg2); } -static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) +static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) { - ucc_fast_private_t *uccf; - ucc_geth_t *ug_regs; + struct ucc_fast_private *uccf; + struct ucc_geth *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -602,26 +588,26 @@ static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) } #endif /* MAGIC_PACKET */ -static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2) +static inline int compare_addr(u8 **addr1, u8 **addr2) { return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); } #ifdef DEBUG -static void get_statistics(ucc_geth_private_t *ugeth, - ucc_geth_tx_firmware_statistics_t * +static void get_statistics(struct ucc_geth_private *ugeth, + struct ucc_geth_tx_firmware_statistics * tx_firmware_statistics, - ucc_geth_rx_firmware_statistics_t * + struct ucc_geth_rx_firmware_statistics * rx_firmware_statistics, - ucc_geth_hardware_statistics_t *hardware_statistics) + struct ucc_geth_hardware_statistics *hardware_statistics) { - ucc_fast_t *uf_regs; - ucc_geth_t *ug_regs; - ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; - ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; + struct ucc_fast *uf_regs; + struct ucc_geth *ug_regs; + struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; + struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; ug_regs = ugeth->ug_regs; - uf_regs = (ucc_fast_t *) ug_regs; + uf_regs = (struct ucc_fast *) ug_regs; p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; @@ -727,7 +713,7 @@ static void get_statistics(ucc_geth_private_t *ugeth, } } -static void dump_bds(ucc_geth_private_t *ugeth) +static void dump_bds(struct ucc_geth_private *ugeth) { int i; int length; @@ -736,7 +722,7 @@ static void dump_bds(ucc_geth_private_t *ugeth) if (ugeth->p_tx_bd_ring[i]) { length = (ugeth->ug_info->bdRingLenTx[i] * - UCC_GETH_SIZE_OF_BD); + sizeof(struct qe_bd)); ugeth_info("TX BDs[%d]", i); mem_disp(ugeth->p_tx_bd_ring[i], length); } @@ -745,14 +731,14 @@ static void dump_bds(ucc_geth_private_t *ugeth) if (ugeth->p_rx_bd_ring[i]) { length = (ugeth->ug_info->bdRingLenRx[i] * - UCC_GETH_SIZE_OF_BD); + sizeof(struct qe_bd)); ugeth_info("RX BDs[%d]", i); mem_disp(ugeth->p_rx_bd_ring[i], length); } } } -static void dump_regs(ucc_geth_private_t *ugeth) +static void dump_regs(struct ucc_geth_private *ugeth) { int i; @@ -893,7 +879,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_thread_data_tx[i]); mem_disp((u8 *) & ugeth->p_thread_data_tx[i], - sizeof(ucc_geth_thread_data_tx_t)); + sizeof(struct ucc_geth_thread_data_tx)); } } if (ugeth->p_thread_data_rx) { @@ -927,7 +913,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_thread_data_rx[i]); mem_disp((u8 *) & ugeth->p_thread_data_rx[i], - sizeof(ucc_geth_thread_data_rx_t)); + sizeof(struct ucc_geth_thread_data_rx)); } } if (ugeth->p_exf_glbl_param) { @@ -1105,7 +1091,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_send_q_mem_reg->sqqd[i]); mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i], - sizeof(ucc_geth_send_queue_qd_t)); + sizeof(struct ucc_geth_send_queue_qd)); } } if (ugeth->p_scheduler) { @@ -1187,7 +1173,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) qe_muram_addr(in_be32 (&ugeth->p_rx_bd_qs_tbl[i]. bdbaseptr)), - sizeof(ucc_geth_rx_prefetched_bds_t)); + sizeof(struct ucc_geth_rx_prefetched_bds)); } } if (ugeth->p_init_enet_param_shadow) { @@ -1198,7 +1184,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) mem_disp((u8 *) ugeth->p_init_enet_param_shadow, sizeof(*ugeth->p_init_enet_param_shadow)); - size = sizeof(ucc_geth_thread_rx_pram_t); + size = sizeof(struct ucc_geth_thread_rx_pram); if (ugeth->ug_info->rxExtendedFiltering) { size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; @@ -1216,7 +1202,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) &(ugeth->p_init_enet_param_shadow-> txthread[0]), ENET_INIT_PARAM_MAX_ENTRIES_TX, - sizeof(ucc_geth_thread_tx_pram_t), + sizeof(struct ucc_geth_thread_tx_pram), ugeth->ug_info->riscTx, 0); dump_init_enet_entries(ugeth, &(ugeth->p_init_enet_param_shadow-> @@ -1578,12 +1564,12 @@ static int init_min_frame_len(u16 min_frame_length, return 0; } -static int adjust_enet_interface(ucc_geth_private_t *ugeth) +static int adjust_enet_interface(struct ucc_geth_private *ugeth) { - ucc_geth_info_t *ug_info; - ucc_geth_t *ug_regs; - ucc_fast_t *uf_regs; - enet_speed_e speed; + struct ucc_geth_info *ug_info; + struct ucc_geth *ug_regs; + struct ucc_fast *uf_regs; + enum enet_speed speed; int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = 0, limited_to_full_duplex = 0; u32 upsmr, maccfg2, utbipar, tbiBaseAddress; @@ -1691,8 +1677,8 @@ static int adjust_enet_interface(ucc_geth_private_t *ugeth) */ static void adjust_link(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_geth_t *ug_regs; + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_geth *ug_regs; u32 tempval; struct ugeth_mii_info *mii_info = ugeth->mii_info; @@ -1722,7 +1708,7 @@ static void adjust_link(struct net_device *dev) if (mii_info->speed != ugeth->oldspeed) { switch (mii_info->speed) { case 1000: -#ifdef CONFIG_MPC836x +#ifdef CONFIG_PPC_MPC836x /* FIXME: This code is for 100Mbs BUG fixing, remove this when it is fixed!!! */ if (ugeth->ug_info->enet_interface == @@ -1768,7 +1754,7 @@ remove this when it is fixed!!! */ break; case 100: case 10: -#ifdef CONFIG_MPC836x +#ifdef CONFIG_PPC_MPC836x /* FIXME: This code is for 100Mbs BUG fixing, remove this lines when it will be fixed!!! */ ugeth->ug_info->enet_interface = ENET_100_RGMII; @@ -1827,9 +1813,9 @@ remove this lines when it will be fixed!!! */ */ static int init_phy(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); struct phy_info *curphy; - ucc_mii_mng_t *mii_regs; + struct ucc_mii_mng *mii_regs; struct ugeth_mii_info *mii_info; int err; @@ -1914,17 +1900,17 @@ static int init_phy(struct net_device *dev) } #ifdef CONFIG_UGETH_TX_ON_DEMOND -static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth) +static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth) { - ucc_fast_transmit_on_demand(ugeth->uccf); + struct ucc_fastransmit_on_demand(ugeth->uccf); return 0; } #endif -static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) +static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; u32 cecr_subblock; u32 temp; @@ -1940,7 +1926,7 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); + QE_CR_PROTOCOL_ETHERNET, 0); /* Wait for command to complete */ do { @@ -1952,9 +1938,9 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) return 0; } -static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) +static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; u32 cecr_subblock; u8 temp; @@ -1973,7 +1959,7 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. ucc_num); qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); + QE_CR_PROTOCOL_ETHERNET, 0); temp = ugeth->p_rx_glbl_pram->rxgstpack; } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); @@ -1983,41 +1969,40 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) return 0; } -static int ugeth_restart_tx(ucc_geth_private_t *ugeth) +static int ugeth_restart_tx(struct ucc_geth_private *ugeth) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; u32 cecr_subblock; uccf = ugeth->uccf; cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, - 0); + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); uccf->stopped_tx = 0; return 0; } -static int ugeth_restart_rx(ucc_geth_private_t *ugeth) +static int ugeth_restart_rx(struct ucc_geth_private *ugeth) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; u32 cecr_subblock; uccf = ugeth->uccf; cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, + qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); uccf->stopped_rx = 0; return 0; } -static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) +static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; int enabled_tx, enabled_rx; uccf = ugeth->uccf; @@ -2044,9 +2029,9 @@ static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) } -static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) +static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) { - ucc_fast_private_t *uccf; + struct ucc_fast_private *uccf; uccf = ugeth->uccf; @@ -2069,7 +2054,7 @@ static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) return 0; } -static void ugeth_dump_regs(ucc_geth_private_t *ugeth) +static void ugeth_dump_regs(struct ucc_geth_private *ugeth) { #ifdef DEBUG ucc_fast_dump_regs(ugeth->uccf); @@ -2079,9 +2064,9 @@ static void ugeth_dump_regs(ucc_geth_private_t *ugeth) } #ifdef CONFIG_UGETH_FILTERING -static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * +static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params * p_UccGethTadParams, - qe_fltr_tad_t *qe_fltr_tad) + struct qe_fltr_tad *qe_fltr_tad) { u16 temp; @@ -2119,11 +2104,11 @@ static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * return 0; } -static enet_addr_container_t - *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) +static struct enet_addr_container_t + *ugeth_82xx_filtering_get_match_addr_in_hash(struct ucc_geth_private *ugeth, + struct enet_addr *p_enet_addr) { - enet_addr_container_t *enet_addr_cont; + struct enet_addr_container *enet_addr_cont; struct list_head *p_lh; u16 i, num; int32_t j; @@ -2144,7 +2129,7 @@ static enet_addr_container_t for (i = 0; i < num; i++) { enet_addr_cont = - (enet_addr_container_t *) + (struct enet_addr_container *) ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) { if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j]) @@ -2157,11 +2142,11 @@ static enet_addr_container_t return NULL; } -static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) +static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth, + struct enet_addr *p_enet_addr) { - ucc_geth_enet_address_recognition_location_e location; - enet_addr_container_t *enet_addr_cont; + enum ucc_geth_enet_address_recognition_location location; + struct enet_addr_container *enet_addr_cont; struct list_head *p_lh; u8 i; u32 limit; @@ -2196,18 +2181,17 @@ static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ ++(*p_counter); - hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); - + hw_add_addr_in_hash(ugeth, enet_addr_cont->address); return 0; } -static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) +static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *ugeth, + struct enet_addr *p_enet_addr) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - enet_addr_container_t *enet_addr_cont; - ucc_fast_private_t *uccf; - comm_dir_e comm_dir; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct enet_addr_container *enet_addr_cont; + struct ucc_fast_private *uccf; + enum comm_dir comm_dir; u16 i, num; struct list_head *p_lh; u32 *addr_h, *addr_l; @@ -2216,7 +2200,7 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, uccf = ugeth->uccf; p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> addressfiltering; if (! @@ -2256,9 +2240,9 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, num = --(*p_counter); for (i = 0; i < num; i++) { enet_addr_cont = - (enet_addr_container_t *) + (struct enet_addr_container *) ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); - hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); + hw_add_addr_in_hash(ugeth, enet_addr_cont->address); enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ } @@ -2269,14 +2253,14 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, } #endif /* CONFIG_UGETH_FILTERING */ -static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * +static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * ugeth, - enet_addr_type_e + enum enet_addr_type enet_addr_type) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - ucc_fast_private_t *uccf; - comm_dir_e comm_dir; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_fast_private *uccf; + enum comm_dir comm_dir; struct list_head *p_lh; u16 i, num; u32 *addr_h, *addr_l; @@ -2285,7 +2269,7 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * uccf = ugeth->uccf; p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> addressfiltering; if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { @@ -2331,8 +2315,8 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * } #ifdef CONFIG_UGETH_FILTERING -static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr, +static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth, + struct enet_addr *p_enet_addr, u8 paddr_num) { int i; @@ -2352,14 +2336,14 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, } #endif /* CONFIG_UGETH_FILTERING */ -static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth, +static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) { ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */ return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ } -static void ucc_geth_memclean(ucc_geth_private_t *ugeth) +static void ucc_geth_memclean(struct ucc_geth_private *ugeth) { u16 i, j; u8 *bd; @@ -2433,8 +2417,8 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { if (ugeth->tx_skbuff[i][j]) { dma_unmap_single(NULL, - BD_BUFFER_ARG(bd), - (BD_STATUS_AND_LENGTH(bd) & + ((qe_bd_t *)bd)->buf, + (in_be32((u32 *)bd) & BD_LENGTH_MASK), DMA_TO_DEVICE); dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); @@ -2460,18 +2444,17 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) bd = ugeth->p_rx_bd_ring[i]; for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { if (ugeth->rx_skbuff[i][j]) { - dma_unmap_single(NULL, BD_BUFFER(bd), - ugeth->ug_info-> - uf_info. - max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT, - DMA_FROM_DEVICE); - - dev_kfree_skb_any(ugeth-> - rx_skbuff[i][j]); + dma_unmap_single(NULL, + ((struct qe_bd *)bd)->buf, + ugeth->ug_info-> + uf_info.max_rx_buf_length + + UCC_GETH_RX_DATA_BUF_ALIGNMENT, + DMA_FROM_DEVICE); + dev_kfree_skb_any( + ugeth->rx_skbuff[i][j]); ugeth->rx_skbuff[i][j] = NULL; } - bd += UCC_GETH_SIZE_OF_BD; + bd += sizeof(struct qe_bd); } kfree(ugeth->rx_skbuff[i]); @@ -2496,11 +2479,11 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) static void ucc_geth_set_multi(struct net_device *dev) { - ucc_geth_private_t *ugeth; + struct ucc_geth_private *ugeth; struct dev_mc_list *dmi; - ucc_fast_t *uf_regs; - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - enet_addr_t tempaddr; + struct ucc_fast *uf_regs; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + u8 tempaddr[6]; u8 *mcptr, *tdptr; int i, j; @@ -2517,7 +2500,7 @@ static void ucc_geth_set_multi(struct net_device *dev) uf_regs->upsmr &= ~UPSMR_PRO; p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> p_rx_glbl_pram->addressfiltering; if (dev->flags & IFF_ALLMULTI) { @@ -2546,23 +2529,22 @@ static void ucc_geth_set_multi(struct net_device *dev) * copy bytes MSB first from dmi_addr. */ mcptr = (u8 *) dmi->dmi_addr + 5; - tdptr = (u8 *) & tempaddr; + tdptr = (u8 *) tempaddr; for (j = 0; j < 6; j++) *tdptr++ = *mcptr--; /* Ask CPM to run CRC and set bit in * filter mask. */ - hw_add_addr_in_hash(ugeth, &tempaddr); - + hw_add_addr_in_hash(ugeth, tempaddr); } } } } -static void ucc_geth_stop(ucc_geth_private_t *ugeth) +static void ucc_geth_stop(struct ucc_geth_private *ugeth) { - ucc_geth_t *ug_regs = ugeth->ug_regs; + struct ucc_geth *ug_regs = ugeth->ug_regs; u32 tempval; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -2605,15 +2587,15 @@ static void ucc_geth_stop(ucc_geth_private_t *ugeth) ucc_geth_memclean(ugeth); } -static int ucc_geth_startup(ucc_geth_private_t *ugeth) +static int ucc_geth_startup(struct ucc_geth_private *ugeth) { - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - ucc_geth_init_pram_t *p_init_enet_pram; - ucc_fast_private_t *uccf; - ucc_geth_info_t *ug_info; - ucc_fast_info_t *uf_info; - ucc_fast_t *uf_regs; - ucc_geth_t *ug_regs; + struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + struct ucc_geth_init_pram *p_init_enet_pram; + struct ucc_fast_private *uccf; + struct ucc_geth_info *ug_info; + struct ucc_fast_info *uf_info; + struct ucc_fast *uf_regs; + struct ucc_geth *ug_regs; int ret_val = -EINVAL; u32 remoder = UCC_GETH_REMODER_INIT; u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; @@ -2788,7 +2770,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); uf_regs = uccf->uf_regs; - ug_regs = (ucc_geth_t *) (uccf->uf_regs); + ug_regs = (struct ucc_geth *) (uccf->uf_regs); ugeth->ug_regs = ug_regs; init_default_reg_vals(&uf_regs->upsmr, @@ -2869,10 +2851,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Allocate in multiple of UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, according to spec */ - length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) + length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) % + if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) % UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { @@ -2904,13 +2886,13 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } /* Zero unused end of bd ring, according to spec */ memset(ugeth->p_tx_bd_ring[j] + - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0, - length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD); + ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0, + length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); } /* Allocate Rx bds */ for (j = 0; j < ug_info->numQueuesRx; j++) { - length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD; + length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd); if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { u32 align = 4; if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) @@ -2960,12 +2942,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { - BD_BUFFER_CLEAR(bd); - BD_STATUS_AND_LENGTH_SET(bd, 0); - bd += UCC_GETH_SIZE_OF_BD; + /* clear bd buffer */ + out_be32(&((struct qe_bd *)bd)->buf, 0); + /* set bd status and length */ + out_be32((u32 *)bd, 0); + bd += sizeof(struct qe_bd); } - bd -= UCC_GETH_SIZE_OF_BD; - BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */ + bd -= sizeof(struct qe_bd); + /* set bd status and length */ + out_be32((u32 *)bd, T_W); /* for last BD set Wrap bit */ } /* Init Rx bds */ @@ -2989,12 +2974,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) ugeth->skb_currx[j] = 0; bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { - BD_STATUS_AND_LENGTH_SET(bd, R_I); - BD_BUFFER_CLEAR(bd); - bd += UCC_GETH_SIZE_OF_BD; + /* set bd status and length */ + out_be32((u32 *)bd, R_I); + /* clear bd buffer */ + out_be32(&((struct qe_bd *)bd)->buf, 0); + bd += sizeof(struct qe_bd); } - bd -= UCC_GETH_SIZE_OF_BD; - BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */ + bd -= sizeof(struct qe_bd); + /* set bd status and length */ + out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */ } /* @@ -3003,7 +2991,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Tx global PRAM */ /* Allocate global tx parameter RAM page */ ugeth->tx_glbl_pram_offset = - qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t), + qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram), UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT); if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) { ugeth_err @@ -3013,10 +3001,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) return -ENOMEM; } ugeth->p_tx_glbl_pram = - (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth-> tx_glbl_pram_offset); /* Zero out p_tx_glbl_pram */ - memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t)); + memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); /* Fill global PRAM */ @@ -3024,7 +3012,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Size varies with number of Tx threads */ ugeth->thread_dat_tx_offset = qe_muram_alloc(numThreadsTxNumerical * - sizeof(ucc_geth_thread_data_tx_t) + + sizeof(struct ucc_geth_thread_data_tx) + 32 * (numThreadsTxNumerical == 1), UCC_GETH_THREAD_DATA_ALIGNMENT); if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) { @@ -3036,7 +3024,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_thread_data_tx = - (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth-> thread_dat_tx_offset); out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); @@ -3053,7 +3041,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Size varies with number of Tx queues */ ugeth->send_q_mem_reg_offset = qe_muram_alloc(ug_info->numQueuesTx * - sizeof(ucc_geth_send_queue_qd_t), + sizeof(struct ucc_geth_send_queue_qd), UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) { ugeth_err @@ -3064,7 +3052,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_send_q_mem_reg = - (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth-> send_q_mem_reg_offset); out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); @@ -3073,7 +3061,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) for (i = 0; i < ug_info->numQueuesTx; i++) { endOfRing = ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] - - 1) * UCC_GETH_SIZE_OF_BD; + 1) * sizeof(struct qe_bd); if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, (u32) virt_to_phys(ugeth->p_tx_bd_ring[i])); @@ -3096,7 +3084,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) if (ug_info->numQueuesTx > 1) { /* scheduler exists only if more than 1 tx queue */ ugeth->scheduler_offset = - qe_muram_alloc(sizeof(ucc_geth_scheduler_t), + qe_muram_alloc(sizeof(struct ucc_geth_scheduler), UCC_GETH_SCHEDULER_ALIGNMENT); if (IS_MURAM_ERR(ugeth->scheduler_offset)) { ugeth_err @@ -3107,12 +3095,12 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_scheduler = - (ucc_geth_scheduler_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_scheduler *) qe_muram_addr(ugeth-> scheduler_offset); out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, ugeth->scheduler_offset); /* Zero out p_scheduler */ - memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t)); + memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); /* Set values in scheduler */ out_be32(&ugeth->p_scheduler->mblinterval, @@ -3144,7 +3132,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { ugeth->tx_fw_statistics_pram_offset = qe_muram_alloc(sizeof - (ucc_geth_tx_firmware_statistics_pram_t), + (struct ucc_geth_tx_firmware_statistics_pram), UCC_GETH_TX_STATISTICS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) { ugeth_err @@ -3154,11 +3142,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) return -ENOMEM; } ugeth->p_tx_fw_statistics_pram = - (ucc_geth_tx_firmware_statistics_pram_t *) + (struct ucc_geth_tx_firmware_statistics_pram *) qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); /* Zero out p_tx_fw_statistics_pram */ memset(ugeth->p_tx_fw_statistics_pram, - 0, sizeof(ucc_geth_tx_firmware_statistics_pram_t)); + 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); } /* temoder */ @@ -3183,7 +3171,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Rx global PRAM */ /* Allocate global rx parameter RAM page */ ugeth->rx_glbl_pram_offset = - qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t), + qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram), UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) { ugeth_err @@ -3193,10 +3181,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) return -ENOMEM; } ugeth->p_rx_glbl_pram = - (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth-> rx_glbl_pram_offset); /* Zero out p_rx_glbl_pram */ - memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t)); + memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); /* Fill global PRAM */ @@ -3204,7 +3192,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Size varies with number of Rx threads */ ugeth->thread_dat_rx_offset = qe_muram_alloc(numThreadsRxNumerical * - sizeof(ucc_geth_thread_data_rx_t), + sizeof(struct ucc_geth_thread_data_rx), UCC_GETH_THREAD_DATA_ALIGNMENT); if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) { ugeth_err @@ -3215,7 +3203,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_thread_data_rx = - (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth-> thread_dat_rx_offset); out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); @@ -3227,7 +3215,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { ugeth->rx_fw_statistics_pram_offset = qe_muram_alloc(sizeof - (ucc_geth_rx_firmware_statistics_pram_t), + (struct ucc_geth_rx_firmware_statistics_pram), UCC_GETH_RX_STATISTICS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) { ugeth_err @@ -3237,11 +3225,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) return -ENOMEM; } ugeth->p_rx_fw_statistics_pram = - (ucc_geth_rx_firmware_statistics_pram_t *) + (struct ucc_geth_rx_firmware_statistics_pram *) qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); /* Zero out p_rx_fw_statistics_pram */ memset(ugeth->p_rx_fw_statistics_pram, 0, - sizeof(ucc_geth_rx_firmware_statistics_pram_t)); + sizeof(struct ucc_geth_rx_firmware_statistics_pram)); } /* intCoalescingPtr */ @@ -3249,7 +3237,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Size varies with number of Rx queues */ ugeth->rx_irq_coalescing_tbl_offset = qe_muram_alloc(ug_info->numQueuesRx * - sizeof(ucc_geth_rx_interrupt_coalescing_entry_t), + sizeof(struct ucc_geth_rx_interrupt_coalescing_entry), UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { ugeth_err @@ -3260,7 +3248,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_rx_irq_coalescing_tbl = - (ucc_geth_rx_interrupt_coalescing_table_t *) + (struct ucc_geth_rx_interrupt_coalescing_table *) qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, ugeth->rx_irq_coalescing_tbl_offset); @@ -3300,7 +3288,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) l3qt = 0; for (i = 0; i < 8; i++) l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i)); - out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt); + out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt); } /* vlantype */ @@ -3316,8 +3304,8 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Size varies with number of Rx queues */ ugeth->rx_bd_qs_tbl_offset = qe_muram_alloc(ug_info->numQueuesRx * - (sizeof(ucc_geth_rx_bd_queues_entry_t) + - sizeof(ucc_geth_rx_prefetched_bds_t)), + (sizeof(struct ucc_geth_rx_bd_queues_entry) + + sizeof(struct ucc_geth_rx_prefetched_bds)), UCC_GETH_RX_BD_QUEUES_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) { ugeth_err @@ -3328,14 +3316,14 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_rx_bd_qs_tbl = - (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth-> rx_bd_qs_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); /* Zero out p_rx_bd_qs_tbl */ memset(ugeth->p_rx_bd_qs_tbl, 0, - ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) + - sizeof(ucc_geth_rx_prefetched_bds_t))); + ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + + sizeof(struct ucc_geth_rx_prefetched_bds))); /* Setup the table */ /* Assume BD rings are already established */ @@ -3406,7 +3394,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Allocate memory for extended filtering Mode Global Parameters */ ugeth->exf_glbl_param_offset = - qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t), + qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram), UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) { ugeth_err @@ -3417,7 +3405,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_exf_glbl_param = - (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth-> + (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth-> exf_glbl_param_offset); out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, ugeth->exf_glbl_param_offset); @@ -3439,7 +3427,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) INIT_LIST_HEAD(&ugeth->ind_hash_q); } p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> + (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> p_rx_glbl_pram->addressfiltering; ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, @@ -3462,7 +3450,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) * allocated resources can be released when the channel is freed. */ if (!(ugeth->p_init_enet_param_shadow = - (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t), + (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) { ugeth_err ("%s: Can not allocate memory for" @@ -3472,7 +3460,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } /* Zero out *p_init_enet_param_shadow */ memset((char *)ugeth->p_init_enet_param_shadow, - 0, sizeof(ucc_geth_init_pram_t)); + 0, sizeof(struct ucc_geth_init_pram)); /* Fill shadow InitEnet command parameter structure */ @@ -3506,7 +3494,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } ugeth->p_init_enet_param_shadow->largestexternallookupkeysize = ug_info->largestexternallookupkeysize; - size = sizeof(ucc_geth_thread_rx_pram_t); + size = sizeof(struct ucc_geth_thread_rx_pram); if (ug_info->rxExtendedFiltering) { size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; if (ug_info->largestexternallookupkeysize == @@ -3537,7 +3525,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) fill_init_enet_entries(ugeth, &(ugeth->p_init_enet_param_shadow-> txthread[0]), numThreadsTxNumerical, - sizeof(ucc_geth_thread_tx_pram_t), + sizeof(struct ucc_geth_thread_tx_pram), UCC_GETH_THREAD_TX_PRAM_ALIGNMENT, ug_info->riscTx, 0)) != 0) { ugeth_err("%s: Can not fill p_init_enet_param_shadow.", @@ -3557,7 +3545,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) } /* Allocate InitEnet command parameter structure */ - init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4); + init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4); if (IS_MURAM_ERR(init_enet_pram_offset)) { ugeth_err ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", @@ -3566,7 +3554,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) return -ENOMEM; } p_init_enet_pram = - (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset); + (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset); /* Copy shadow InitEnet command parameter structure into PRAM */ p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; @@ -3591,7 +3579,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* Issue QE command */ cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, + qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, init_enet_pram_offset); /* Free InitEnet command parameter */ @@ -3603,7 +3591,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) /* returns a net_device_stats structure pointer */ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); return &(ugeth->stats); } @@ -3614,7 +3602,7 @@ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) * starting over will fix the problem. */ static void ucc_geth_timeout(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3634,7 +3622,7 @@ static void ucc_geth_timeout(struct net_device *dev) /* It is pointed to by the dev->hard_start_xmit function pointer */ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); u8 *bd; /* BD pointer */ u32 bd_status; u8 txQ = 0; @@ -3647,7 +3635,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Start from the next BD that should be filled */ bd = ugeth->txBd[txQ]; - bd_status = BD_STATUS_AND_LENGTH(bd); + bd_status = in_be32((u32 *)bd); /* Save the skb pointer so we can free it later */ ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; @@ -3657,20 +3645,21 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); /* set up the buffer descriptor */ - BD_BUFFER_SET(bd, + out_be32(&((struct qe_bd *)bd)->buf, dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); - //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); + /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; - BD_STATUS_AND_LENGTH_SET(bd, bd_status); + /* set bd status and length */ + out_be32((u32 *)bd, bd_status); dev->trans_start = jiffies; /* Move to next BD in the ring */ if (!(bd_status & T_W)) - ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD; + ugeth->txBd[txQ] = bd + sizeof(struct qe_bd); else ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; @@ -3695,7 +3684,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) +static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) { struct sk_buff *skb; u8 *bd; @@ -3709,11 +3698,11 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) /* collect received buffers */ bd = ugeth->rxBd[rxQ]; - bd_status = BD_STATUS_AND_LENGTH(bd); + bd_status = in_be32((u32 *)bd); /* while there are received buffers and BD is full (~R_E) */ while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { - bdBuffer = (u8 *) BD_BUFFER(bd); + bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf); length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; @@ -3768,9 +3757,9 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) if (bd_status & R_W) bd = ugeth->p_rx_bd_ring[rxQ]; else - bd += UCC_GETH_SIZE_OF_BD; + bd += sizeof(struct qe_bd); - bd_status = BD_STATUS_AND_LENGTH(bd); + bd_status = in_be32((u32 *)bd); } ugeth->rxBd[rxQ] = bd; @@ -3781,12 +3770,12 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) static int ucc_geth_tx(struct net_device *dev, u8 txQ) { /* Start from the next BD that should be filled */ - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); u8 *bd; /* BD pointer */ u32 bd_status; bd = ugeth->confBd[txQ]; - bd_status = BD_STATUS_AND_LENGTH(bd); + bd_status = in_be32((u32 *)bd); /* Normal processing. */ while ((bd_status & T_R) == 0) { @@ -3813,7 +3802,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Advance the confirmation BD pointer */ if (!(bd_status & T_W)) - ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD; + ugeth->confBd[txQ] += sizeof(struct qe_bd); else ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; } @@ -3823,7 +3812,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) #ifdef CONFIG_UGETH_NAPI static int ucc_geth_poll(struct net_device *dev, int *budget) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); int howmany; int rx_work_limit = *budget; u8 rxQ = 0; @@ -3847,9 +3836,9 @@ static int ucc_geth_poll(struct net_device *dev, int *budget) static irqreturn_t ucc_geth_irq_handler(int irq, void *info) { struct net_device *dev = (struct net_device *)info; - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_fast_private_t *uccf; - ucc_geth_info_t *ug_info; + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_fast_private *uccf; + struct ucc_geth_info *ug_info; register u32 ucce = 0; register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; @@ -3912,7 +3901,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) static irqreturn_t phy_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3932,8 +3921,8 @@ static irqreturn_t phy_interrupt(int irq, void *dev_id) static void ugeth_phy_change(void *data) { struct net_device *dev = (struct net_device *)data; - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_geth_t *ug_regs; + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_geth *ug_regs; int result = 0; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3963,7 +3952,7 @@ static void ugeth_phy_change(void *data) static void ugeth_phy_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); schedule_work(&ugeth->tq); @@ -3979,7 +3968,7 @@ static void ugeth_phy_timer(unsigned long data) static void ugeth_phy_startup_timer(unsigned long data) { struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; - ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev); + struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev); static int secondary = UGETH_AN_TIMEOUT; int result; @@ -4034,7 +4023,7 @@ static void ugeth_phy_startup_timer(unsigned long data) /* Returns 0 for success. */ static int ucc_geth_open(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); int err; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4111,7 +4100,7 @@ static int ucc_geth_open(struct net_device *dev) /* Stops the kernel queue, and halts the controller */ static int ucc_geth_close(struct net_device *dev) { - ucc_geth_private_t *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4130,30 +4119,53 @@ static int ucc_geth_close(struct net_device *dev) const struct ethtool_ops ucc_geth_ethtool_ops = { }; -static int ucc_geth_probe(struct device *device) +static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) { - struct platform_device *pdev = to_platform_device(device); - struct ucc_geth_platform_data *ugeth_pdata; + struct device *device = &ofdev->dev; + struct device_node *np = ofdev->node; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; - int err; + struct resource res; + struct device_node *phy; + int err, ucc_num, phy_interface; static int mii_mng_configured = 0; + const phandle *ph; + const unsigned int *prop; ugeth_vdbg("%s: IN", __FUNCTION__); - ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data; + prop = get_property(np, "device-id", NULL); + ucc_num = *prop - 1; + if ((ucc_num < 0) || (ucc_num > 7)) + return -ENODEV; + + ug_info = &ugeth_info[ucc_num]; + ug_info->uf_info.ucc_num = ucc_num; + prop = get_property(np, "rx-clock", NULL); + ug_info->uf_info.rx_clock = *prop; + prop = get_property(np, "tx-clock", NULL); + ug_info->uf_info.tx_clock = *prop; + err = of_address_to_resource(np, 0, &res); + if (err) + return -EINVAL; + + ug_info->uf_info.regs = res.start; + ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); + + ph = get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); - ug_info = &ugeth_info[pdev->id]; - ug_info->uf_info.ucc_num = pdev->id; - ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock; - ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock; - ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr; - ug_info->uf_info.irq = platform_get_irq(pdev, 0); - ug_info->phy_address = ugeth_pdata->phy_id; - ug_info->enet_interface = ugeth_pdata->phy_interface; - ug_info->board_flags = ugeth_pdata->board_flags; - ug_info->phy_interrupt = ugeth_pdata->phy_interrupt; + if (phy == NULL) + return -ENODEV; + + prop = get_property(phy, "reg", NULL); + ug_info->phy_address = *prop; + prop = get_property(phy, "interface", NULL); + ug_info->enet_interface = *prop; + ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0); + ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)? + 0:FSL_UGETH_BRD_HAS_PHY_INTR; printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, @@ -4161,12 +4173,44 @@ static int ucc_geth_probe(struct device *device) if (ug_info == NULL) { ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__, - pdev->id); + ucc_num); return -ENODEV; } + /* FIXME: Work around for early chip rev. */ + /* There's a bug in initial chip rev(s) in the RGMII ac */ + /* timing. */ + /* The following compensates by writing to the reserved */ + /* QE Port Output Hold Registers (CPOH1?). */ + prop = get_property(phy, "interface", NULL); + phy_interface = *prop; + if ((phy_interface == ENET_1000_RGMII) || + (phy_interface == ENET_100_RGMII) || + (phy_interface == ENET_10_RGMII)) { + struct device_node *soc; + phys_addr_t immrbase = -1; + u32 *tmp_reg; + u32 tmp_val; + + soc = of_find_node_by_type(NULL, "soc"); + if (soc) { + unsigned int size; + const void *prop = get_property(soc, "reg", &size); + immrbase = of_translate_address(soc, prop); + of_node_put(soc); + }; + + tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4); + tmp_val = in_be32(tmp_reg); + if (ucc_num == 1) + out_be32(tmp_reg, tmp_val | 0x00003000); + else if (ucc_num == 2) + out_be32(tmp_reg, tmp_val | 0x0c000000); + iounmap(tmp_reg); + } + if (!mii_mng_configured) { - ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num); + ucc_set_qe_mux_mii_mng(ucc_num); mii_mng_configured = 1; } @@ -4213,13 +4257,14 @@ static int ucc_geth_probe(struct device *device) ugeth->ug_info = ug_info; ugeth->dev = dev; - memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6); + memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6); return 0; } -static int ucc_geth_remove(struct device *device) +static int ucc_geth_remove(struct of_device* ofdev) { + struct device *device = &ofdev->dev; struct net_device *dev = dev_get_drvdata(device); struct ucc_geth_private *ugeth = netdev_priv(dev); @@ -4230,28 +4275,38 @@ static int ucc_geth_remove(struct device *device) return 0; } -/* Structure for a device driver */ -static struct device_driver ucc_geth_driver = { - .name = DRV_NAME, - .bus = &platform_bus_type, - .probe = ucc_geth_probe, - .remove = ucc_geth_remove, +static struct of_device_id ucc_geth_match[] = { + { + .type = "network", + .compatible = "ucc_geth", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, ucc_geth_match); + +static struct of_platform_driver ucc_geth_driver = { + .name = DRV_NAME, + .match_table = ucc_geth_match, + .probe = ucc_geth_probe, + .remove = ucc_geth_remove, }; static int __init ucc_geth_init(void) { int i; + printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); for (i = 0; i < 8; i++) memcpy(&(ugeth_info[i]), &ugeth_primary_info, sizeof(ugeth_primary_info)); - return driver_register(&ucc_geth_driver); + return of_register_driver(&ucc_geth_driver); } static void __exit ucc_geth_exit(void) { - driver_unregister(&ucc_geth_driver); + of_unregister_driver(&ucc_geth_driver); } module_init(ucc_geth_init); diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 005965f5dd9..a6656125359 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -36,24 +36,24 @@ #define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 #define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 -typedef struct ucc_mii_mng { +struct ucc_mii_mng { u32 miimcfg; /* MII management configuration reg */ u32 miimcom; /* MII management command reg */ u32 miimadd; /* MII management address reg */ u32 miimcon; /* MII management control reg */ u32 miimstat; /* MII management status reg */ u32 miimind; /* MII management indication reg */ -} __attribute__ ((packed)) ucc_mii_mng_t; +} __attribute__ ((packed)); -typedef struct ucc_geth { - ucc_fast_t uccf; +struct ucc_geth { + struct ucc_fast uccf; u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */ u32 ipgifg; /* interframe gap reg. */ u32 hafdup; /* half-duplex reg. */ u8 res1[0x10]; - ucc_mii_mng_t miimng; /* MII management structure */ + struct ucc_mii_mng miimng; /* MII management structure */ u32 ifctl; /* interface control reg */ u32 ifstat; /* interface statux reg */ u32 macstnaddr1; /* mac station address part 1 reg */ @@ -111,7 +111,7 @@ typedef struct ucc_geth { u32 scar; /* Statistics carry register */ u32 scam; /* Statistics caryy mask register */ u8 res5[0x200 - 0x1c4]; -} __attribute__ ((packed)) ucc_geth_t; +} __attribute__ ((packed)); /* UCC GETH TEMODR Register */ #define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics @@ -508,39 +508,39 @@ typedef struct ucc_geth { /* UCC GETH UDSR (Data Synchronization Register) */ #define UDSR_MAGIC 0x067E -typedef struct ucc_geth_thread_data_tx { +struct ucc_geth_thread_data_tx { u8 res0[104]; -} __attribute__ ((packed)) ucc_geth_thread_data_tx_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_thread_data_rx { +struct ucc_geth_thread_data_rx { u8 res0[40]; -} __attribute__ ((packed)) ucc_geth_thread_data_rx_t; +} __attribute__ ((packed)); /* Send Queue Queue-Descriptor */ -typedef struct ucc_geth_send_queue_qd { +struct ucc_geth_send_queue_qd { u32 bd_ring_base; /* pointer to BD ring base address */ u8 res0[0x8]; u32 last_bd_completed_address;/* initialize to last entry in BD ring */ u8 res1[0x30]; -} __attribute__ ((packed)) ucc_geth_send_queue_qd_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_send_queue_mem_region { - ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES]; -} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t; +struct ucc_geth_send_queue_mem_region { + struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES]; +} __attribute__ ((packed)); -typedef struct ucc_geth_thread_tx_pram { +struct ucc_geth_thread_tx_pram { u8 res0[64]; -} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_thread_rx_pram { +struct ucc_geth_thread_rx_pram { u8 res0[128]; -} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t; +} __attribute__ ((packed)); #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 -typedef struct ucc_geth_scheduler { +struct ucc_geth_scheduler { u16 cpucount0; /* CPU packet counter */ u16 cpucount1; /* CPU packet counter */ u16 cecount0; /* QE packet counter */ @@ -574,9 +574,9 @@ typedef struct ucc_geth_scheduler { /**< weight factor for queues */ u32 minw; /* temporary variable handled by QE */ u8 res1[0x70 - 0x64]; -} __attribute__ ((packed)) ucc_geth_scheduler_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_tx_firmware_statistics_pram { +struct ucc_geth_tx_firmware_statistics_pram { u32 sicoltx; /* single collision */ u32 mulcoltx; /* multiple collision */ u32 latecoltxfr; /* late collision */ @@ -596,9 +596,9 @@ typedef struct ucc_geth_tx_firmware_statistics_pram { and 1518 octets */ u32 txpktsjumbo; /* total packets (including bad) between 1024 and MAXLength octets */ -} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_firmware_statistics_pram { +struct ucc_geth_rx_firmware_statistics_pram { u32 frrxfcser; /* frames with crc error */ u32 fraligner; /* frames with alignment error */ u32 inrangelenrxer; /* in range length error */ @@ -630,33 +630,33 @@ typedef struct ucc_geth_rx_firmware_statistics_pram { replaced */ u32 insertvlan; /* total frames that had their VLAN tag inserted */ -} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_interrupt_coalescing_entry { +struct ucc_geth_rx_interrupt_coalescing_entry { u32 interruptcoalescingmaxvalue; /* interrupt coalescing max value */ u32 interruptcoalescingcounter; /* interrupt coalescing counter, initialize to interruptcoalescingmaxvalue */ -} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_interrupt_coalescing_table { - ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES]; +struct ucc_geth_rx_interrupt_coalescing_table { + struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES]; /**< interrupt coalescing entry */ -} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_prefetched_bds { - qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ -} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t; +struct ucc_geth_rx_prefetched_bds { + struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_bd_queues_entry { +struct ucc_geth_rx_bd_queues_entry { u32 bdbaseptr; /* BD base pointer */ u32 bdptr; /* BD pointer */ u32 externalbdbaseptr; /* external BD base pointer */ u32 externalbdptr; /* external BD pointer */ -} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_tx_global_pram { +struct ucc_geth_tx_global_pram { u16 temoder; u8 res0[0x38 - 0x02]; u32 sqptr; /* a base pointer to send queue memory region */ @@ -670,15 +670,15 @@ typedef struct ucc_geth_tx_global_pram { u32 tqptr; /* a base pointer to the Tx Queues Memory Region */ u8 res2[0x80 - 0x74]; -} __attribute__ ((packed)) ucc_geth_tx_global_pram_t; +} __attribute__ ((packed)); /* structure representing Extended Filtering Global Parameters in PRAM */ -typedef struct ucc_geth_exf_global_pram { +struct ucc_geth_exf_global_pram { u32 l2pcdptr; /* individual address filter, high */ u8 res0[0x10 - 0x04]; -} __attribute__ ((packed)) ucc_geth_exf_global_pram_t; +} __attribute__ ((packed)); -typedef struct ucc_geth_rx_global_pram { +struct ucc_geth_rx_global_pram { u32 remoder; /* ethernet mode reg. */ u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ u32 res0[0x1]; @@ -710,12 +710,12 @@ typedef struct ucc_geth_rx_global_pram { u32 exfGlobalParam; /* base address for extended filtering global parameters */ u8 res6[0x100 - 0xC4]; /* Initialize to zero */ -} __attribute__ ((packed)) ucc_geth_rx_global_pram_t; +} __attribute__ ((packed)); #define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 /* structure representing InitEnet command */ -typedef struct ucc_geth_init_pram { +struct ucc_geth_init_pram { u8 resinit1; u8 resinit2; u8 resinit3; @@ -729,7 +729,7 @@ typedef struct ucc_geth_init_pram { u32 txglobal; /* tx global */ u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ u8 res3[0x1]; -} __attribute__ ((packed)) ucc_geth_init_pram_t; +} __attribute__ ((packed)); #define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) #define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) @@ -746,27 +746,27 @@ typedef struct ucc_geth_init_pram { #define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 /* structure representing 82xx Address Filtering Enet Address in PRAM */ -typedef struct ucc_geth_82xx_enet_address { +struct ucc_geth_82xx_enet_address { u8 res1[0x2]; u16 h; /* address (MSB) */ u16 m; /* address */ u16 l; /* address (LSB) */ -} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t; +} __attribute__ ((packed)); /* structure representing 82xx Address Filtering PRAM */ -typedef struct ucc_geth_82xx_address_filtering_pram { +struct ucc_geth_82xx_address_filtering_pram { u32 iaddr_h; /* individual address filter, high */ u32 iaddr_l; /* individual address filter, low */ u32 gaddr_h; /* group address filter, high */ u32 gaddr_l; /* group address filter, low */ - ucc_geth_82xx_enet_address_t taddr; - ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS]; + struct ucc_geth_82xx_enet_address taddr; + struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS]; u8 res0[0x40 - 0x38]; -} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t; +} __attribute__ ((packed)); /* GETH Tx firmware statistics structure, used when calling UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_tx_firmware_statistics { +struct ucc_geth_tx_firmware_statistics { u32 sicoltx; /* single collision */ u32 mulcoltx; /* multiple collision */ u32 latecoltxfr; /* late collision */ @@ -786,11 +786,11 @@ typedef struct ucc_geth_tx_firmware_statistics { and 1518 octets */ u32 txpktsjumbo; /* total packets (including bad) between 1024 and MAXLength octets */ -} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t; +} __attribute__ ((packed)); /* GETH Rx firmware statistics structure, used when calling UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_rx_firmware_statistics { +struct ucc_geth_rx_firmware_statistics { u32 frrxfcser; /* frames with crc error */ u32 fraligner; /* frames with alignment error */ u32 inrangelenrxer; /* in range length error */ @@ -822,11 +822,11 @@ typedef struct ucc_geth_rx_firmware_statistics { replaced */ u32 insertvlan; /* total frames that had their VLAN tag inserted */ -} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t; +} __attribute__ ((packed)); /* GETH hardware statistics structure, used when calling UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_hardware_statistics { +struct ucc_geth_hardware_statistics { u32 tx64; /* Total number of frames (including bad frames) transmitted that were exactly of the minimal length (64 for un tagged, 68 for @@ -871,7 +871,7 @@ typedef struct ucc_geth_hardware_statistics { u32 rbca; /* Total number of frames received succesfully that had destination address equal to the broadcast address */ -} __attribute__ ((packed)) ucc_geth_hardware_statistics_t; +} __attribute__ ((packed)); /* UCC GETH Tx errors returned via TxConf callback */ #define TX_ERRORS_DEF 0x0200 @@ -1013,21 +1013,21 @@ typedef struct ucc_geth_hardware_statistics { (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) /* Ethernet speed */ -typedef enum enet_speed { +enum enet_speed { ENET_SPEED_10BT, /* 10 Base T */ ENET_SPEED_100BT, /* 100 Base T */ ENET_SPEED_1000BT /* 1000 Base T */ -} enet_speed_e; +}; /* Ethernet Address Type. */ -typedef enum enet_addr_type { +enum enet_addr_type { ENET_ADDR_TYPE_INDIVIDUAL, ENET_ADDR_TYPE_GROUP, ENET_ADDR_TYPE_BROADCAST -} enet_addr_type_e; +}; /* TBI / MII Set Register */ -typedef enum enet_tbi_mii_reg { +enum enet_tbi_mii_reg { ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ @@ -1040,10 +1040,10 @@ typedef enum enet_tbi_mii_reg { ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ -} enet_tbi_mii_reg_e; +}; /* UCC GETH 82xx Ethernet Address Recognition Location */ -typedef enum ucc_geth_enet_address_recognition_location { +enum ucc_geth_enet_address_recognition_location { UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station address */ UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional @@ -1065,10 +1065,10 @@ typedef enum ucc_geth_enet_address_recognition_location { UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual hash */ -} ucc_geth_enet_address_recognition_location_e; +}; /* UCC GETH vlan operation tagged */ -typedef enum ucc_geth_vlan_operation_tagged { +enum ucc_geth_vlan_operation_tagged { UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG = 0x1, /* Tagged - replace vid portion of q tag */ @@ -1076,18 +1076,18 @@ typedef enum ucc_geth_vlan_operation_tagged { = 0x2, /* Tagged - if vid0 replace vid with default value */ UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME = 0x3 /* Tagged - extract q tag from frame */ -} ucc_geth_vlan_operation_tagged_e; +}; /* UCC GETH vlan operation non-tagged */ -typedef enum ucc_geth_vlan_operation_non_tagged { +enum ucc_geth_vlan_operation_non_tagged { UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - q tag insert */ -} ucc_geth_vlan_operation_non_tagged_e; +}; /* UCC GETH Rx Quality of Service Mode */ -typedef enum ucc_geth_qos_mode { +enum ucc_geth_qos_mode { UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue determined @@ -1097,11 +1097,11 @@ typedef enum ucc_geth_qos_mode { determined by L3 criteria */ -} ucc_geth_qos_mode_e; +}; /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together for combined functionality */ -typedef enum ucc_geth_statistics_gathering_mode { +enum ucc_geth_statistics_gathering_mode { UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No statistics gathering */ @@ -1122,10 +1122,10 @@ typedef enum ucc_geth_statistics_gathering_mode { statistics gathering */ -} ucc_geth_statistics_gathering_mode_e; +}; /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ -typedef enum ucc_geth_maccfg2_pad_and_crc_mode { +enum ucc_geth_maccfg2_pad_and_crc_mode { UCC_GETH_PAD_AND_CRC_MODE_NONE = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding short frames @@ -1135,61 +1135,59 @@ typedef enum ucc_geth_maccfg2_pad_and_crc_mode { CRC only */ UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC -} ucc_geth_maccfg2_pad_and_crc_mode_e; +}; /* UCC GETH upsmr Flow Control Mode */ -typedef enum ucc_geth_flow_control_mode { +enum ucc_geth_flow_control_mode { UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic flow control */ UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY = 0x00004000 /* Send pause frame when RxFIFO reaches its emergency threshold */ -} ucc_geth_flow_control_mode_e; +}; /* UCC GETH number of threads */ -typedef enum ucc_geth_num_of_threads { +enum ucc_geth_num_of_threads { UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ -} ucc_geth_num_of_threads_e; +}; /* UCC GETH number of station addresses */ -typedef enum ucc_geth_num_of_station_addresses { +enum ucc_geth_num_of_station_addresses { UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ -} ucc_geth_num_of_station_addresses_e; - -typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS]; +}; /* UCC GETH 82xx Ethernet Address Container */ -typedef struct enet_addr_container { - enet_addr_t address; /* ethernet address */ - ucc_geth_enet_address_recognition_location_e location; /* location in +struct enet_addr_container { + u8 address[ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ + enum ucc_geth_enet_address_recognition_location location; /* location in 82xx address recognition hardware */ struct list_head node; -} enet_addr_container_t; +}; -#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node) +#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node) /* UCC GETH Termination Action Descriptor (TAD) structure. */ -typedef struct ucc_geth_tad_params { +struct ucc_geth_tad_params { int rx_non_dynamic_extended_features_mode; int reject_frame; - ucc_geth_vlan_operation_tagged_e vtag_op; - ucc_geth_vlan_operation_non_tagged_e vnontag_op; - ucc_geth_qos_mode_e rqos; + enum ucc_geth_vlan_operation_tagged vtag_op; + enum ucc_geth_vlan_operation_non_tagged vnontag_op; + enum ucc_geth_qos_mode rqos; u8 vpri; u16 vid; -} ucc_geth_tad_params_t; +}; /* GETH protocol initialization structure */ -typedef struct ucc_geth_info { - ucc_fast_info_t uf_info; +struct ucc_geth_info { + struct ucc_fast_info uf_info; u8 numQueuesTx; u8 numQueuesRx; int ipCheckSumCheck; @@ -1251,51 +1249,51 @@ typedef struct ucc_geth_info { u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; u16 bdRingLenTx[NUM_TX_QUEUES]; u16 bdRingLenRx[NUM_RX_QUEUES]; - enet_interface_e enet_interface; - ucc_geth_num_of_station_addresses_e numStationAddresses; - qe_fltr_largest_external_tbl_lookup_key_size_e + enum enet_interface enet_interface; + enum ucc_geth_num_of_station_addresses numStationAddresses; + enum qe_fltr_largest_external_tbl_lookup_key_size largestexternallookupkeysize; - ucc_geth_statistics_gathering_mode_e statisticsMode; - ucc_geth_vlan_operation_tagged_e vlanOperationTagged; - ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged; - ucc_geth_qos_mode_e rxQoSMode; - ucc_geth_flow_control_mode_e aufc; - ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc; - ucc_geth_num_of_threads_e numThreadsTx; - ucc_geth_num_of_threads_e numThreadsRx; - qe_risc_allocation_e riscTx; - qe_risc_allocation_e riscRx; -} ucc_geth_info_t; + enum ucc_geth_statistics_gathering_mode statisticsMode; + enum ucc_geth_vlan_operation_tagged vlanOperationTagged; + enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged; + enum ucc_geth_qos_mode rxQoSMode; + enum ucc_geth_flow_control_mode aufc; + enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc; + enum ucc_geth_num_of_threads numThreadsTx; + enum ucc_geth_num_of_threads numThreadsRx; + enum qe_risc_allocation riscTx; + enum qe_risc_allocation riscRx; +}; /* structure representing UCC GETH */ -typedef struct ucc_geth_private { - ucc_geth_info_t *ug_info; - ucc_fast_private_t *uccf; +struct ucc_geth_private { + struct ucc_geth_info *ug_info; + struct ucc_fast_private *uccf; struct net_device *dev; struct net_device_stats stats; /* linux network statistics */ - ucc_geth_t *ug_regs; - ucc_geth_init_pram_t *p_init_enet_param_shadow; - ucc_geth_exf_global_pram_t *p_exf_glbl_param; + struct ucc_geth *ug_regs; + struct ucc_geth_init_pram *p_init_enet_param_shadow; + struct ucc_geth_exf_global_pram *p_exf_glbl_param; u32 exf_glbl_param_offset; - ucc_geth_rx_global_pram_t *p_rx_glbl_pram; + struct ucc_geth_rx_global_pram *p_rx_glbl_pram; u32 rx_glbl_pram_offset; - ucc_geth_tx_global_pram_t *p_tx_glbl_pram; + struct ucc_geth_tx_global_pram *p_tx_glbl_pram; u32 tx_glbl_pram_offset; - ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg; + struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg; u32 send_q_mem_reg_offset; - ucc_geth_thread_data_tx_t *p_thread_data_tx; + struct ucc_geth_thread_data_tx *p_thread_data_tx; u32 thread_dat_tx_offset; - ucc_geth_thread_data_rx_t *p_thread_data_rx; + struct ucc_geth_thread_data_rx *p_thread_data_rx; u32 thread_dat_rx_offset; - ucc_geth_scheduler_t *p_scheduler; + struct ucc_geth_scheduler *p_scheduler; u32 scheduler_offset; - ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; + struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; u32 tx_fw_statistics_pram_offset; - ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; + struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; u32 rx_fw_statistics_pram_offset; - ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl; + struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl; u32 rx_irq_coalescing_tbl_offset; - ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; + struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl; u32 rx_bd_qs_tbl_offset; u8 *p_tx_bd_ring[NUM_TX_QUEUES]; u32 tx_bd_ring_offset[NUM_TX_QUEUES]; @@ -1308,7 +1306,7 @@ typedef struct ucc_geth_private { u16 cpucount[NUM_TX_QUEUES]; volatile u16 *p_cpucount[NUM_TX_QUEUES]; int indAddrRegUsed[NUM_OF_PADDRS]; - enet_addr_t paddr[NUM_OF_PADDRS]; + u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ u8 numGroupAddrInHash; u8 numIndAddrInHash; u8 numIndAddrInReg; @@ -1334,6 +1332,6 @@ typedef struct ucc_geth_private { int oldspeed; int oldduplex; int oldlink; -} ucc_geth_private_t; +}; #endif /* __UCC_GETH_H__ */ diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c index 67260eb3188..5360ec05eaa 100644 --- a/drivers/net/ucc_geth_phy.c +++ b/drivers/net/ucc_geth_phy.c @@ -42,7 +42,6 @@ #include "ucc_geth.h" #include "ucc_geth_phy.h" -#include #define ugphy_printk(level, format, arg...) \ printk(level format "\n", ## arg) @@ -72,16 +71,14 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info); u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); -static u8 *bcsr_regs = NULL; - /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) { - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_mii_mng_t *mii_regs; - enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_mii_mng *mii_regs; + enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; u32 tmp_reg; ugphy_vdbg("%s: IN", __FUNCTION__); @@ -116,9 +113,9 @@ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) /* configuration has to be done through the TSEC1 MIIM regs */ int read_phy_reg(struct net_device *dev, int mii_id, int regnum) { - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_mii_mng_t *mii_regs; - enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_mii_mng *mii_regs; + enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; u32 tmp_reg; u16 value; @@ -634,11 +631,6 @@ static void dm9161_close(struct ugeth_mii_info *mii_info) static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) { -/* FIXME: This lines are for BUG fixing in the mpc8325. -Remove this from here when it's fixed */ - if (bcsr_regs == NULL) - bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); - bcsr_regs[14] |= 0x40; ugphy_vdbg("%s: IN", __FUNCTION__); /* Clear the interrupts by reading the reg */ @@ -650,12 +642,6 @@ Remove this from here when it's fixed */ static int dm9161_config_intr(struct ugeth_mii_info *mii_info) { -/* FIXME: This lines are for BUG fixing in the mpc8325. -Remove this from here when it's fixed */ - if (bcsr_regs == NULL) { - bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); - bcsr_regs[14] &= ~0x40; - } ugphy_vdbg("%s: IN", __FUNCTION__); if (mii_info->interrupts == MII_INTERRUPT_ENABLED) diff --git a/drivers/net/ucc_geth_phy.h b/drivers/net/ucc_geth_phy.h index 2f98b8f1bb0..f5740783670 100644 --- a/drivers/net/ucc_geth_phy.h +++ b/drivers/net/ucc_geth_phy.h @@ -126,7 +126,7 @@ struct ugeth_mii_info { /* And management functions */ struct phy_info *phyinfo; - ucc_mii_mng_t *mii_regs; + struct ucc_mii_mng *mii_regs; /* forced speed & duplex (no autoneg) * partner speed & duplex & pause (autoneg) -- cgit From 089fff2aa8cc2a0383ea9fce17afd10bfab9ac7c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 18 Oct 2006 00:30:27 -0400 Subject: [PATCH] Remove useless comment from sb1250 Signed-off-by: Dave Jones Signed-off-by: Jeff Garzik --- drivers/net/sb1250-mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index db2324939b6..1eae16b72b4 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2903,7 +2903,7 @@ sbmac_init_module(void) dev = alloc_etherdev(sizeof(struct sbmac_softc)); if (!dev) - return -ENOMEM; /* return ENOMEM */ + return -ENOMEM; printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); -- cgit From cfadbd298e8b3e7f2e324696b653bb74094590db Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 18 Oct 2006 02:15:37 +0100 Subject: [PATCH] Fix timer race When closing the driver or reinitializing the hardware there is the usual del_timer() race condition that exists when timers re-add themselves. Fix by conversion to del_timer_sync(). Signed-off-by: Ralf Baechle Signed-off-by: Jeff Garzik --- drivers/net/ioc3-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index e963dbf816b..f56b00ee385 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1017,7 +1017,7 @@ static void ioc3_init(struct net_device *dev) struct ioc3_private *ip = netdev_priv(dev); struct ioc3 *ioc3 = ip->regs; - del_timer(&ip->ioc3_timer); /* Kill if running */ + del_timer_sync(&ip->ioc3_timer); /* Kill if running */ ioc3_w_emcr(EMCR_RST); /* Reset */ (void) ioc3_r_emcr(); /* Flush WB */ @@ -1081,7 +1081,7 @@ static int ioc3_close(struct net_device *dev) { struct ioc3_private *ip = netdev_priv(dev); - del_timer(&ip->ioc3_timer); + del_timer_sync(&ip->ioc3_timer); netif_stop_queue(dev); -- cgit From 5826cade4341a6298eb10d476dccc5f403ca7ad8 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 13 Oct 2006 14:20:59 +1000 Subject: [PATCH] ibmveth: Fix index increment calculation On Thu, Oct 12, 2006 at 06:22:14PM +1000, David Gibson wrote: > Your recent ibmveth commit, 751ae21c6cd1493e3d0a4935b08fb298b9d89773 > ("fix int rollover panic"), causes a rapid oops on my test machine > (POWER5 LPAR). > > I've bisected it down to that commit, but am still investigating the > cause of the crash itself. Found the problem, I believe: an object lesson in the need for great caution using ++. [...] @@ -213,6 +213,7 @@ static void ibmveth_replenish_buffer_poo } free_index = pool->consumer_index++ % pool->size; + pool->consumer_index = free_index; index = pool->free_map[free_index]; ibmveth_assert(index != IBM_VETH_INVALID_MAP); Since the ++ is used as post-increment, the increment is not included in free_index, and so the added line effectively reverts the increment. The produced_index side has an analagous bug. The following change corrects this: The recent commit 751ae21c6cd1493e3d0a4935b08fb298b9d89773 introduced a bug in the producer/consumer index calculation in the ibmveth driver - incautious use of the post-increment ++ operator resulted in an increment being immediately reverted. This patch corrects the logic. Without this patch, the driver oopses almost immediately after activation on at least some machines. Signed-off-by: David Gibson Signed-off-by: Jeff Garzik --- drivers/net/ibmveth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2802db23d3c..44c9f993dcc 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -212,8 +212,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc break; } - free_index = pool->consumer_index++ % pool->size; - pool->consumer_index = free_index; + free_index = pool->consumer_index; + pool->consumer_index = (pool->consumer_index + 1) % pool->size; index = pool->free_map[free_index]; ibmveth_assert(index != IBM_VETH_INVALID_MAP); @@ -329,8 +329,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 adapter->rx_buff_pool[pool].buff_size, DMA_FROM_DEVICE); - free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size; - adapter->rx_buff_pool[pool].producer_index = free_index; + free_index = adapter->rx_buff_pool[pool].producer_index; + adapter->rx_buff_pool[pool].producer_index + = (adapter->rx_buff_pool[pool].producer_index + 1) + % adapter->rx_buff_pool[pool].size; adapter->rx_buff_pool[pool].free_map[free_index] = index; mb(); -- cgit From 158f30c8945fea7cf0d0161cd9463cf2f3d2c19e Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Thu, 19 Oct 2006 13:27:39 -0700 Subject: [PATCH] libata: use correct map_db values for ICH8 Use valid values for ICH8 map_db. With the old values, when the controller was in Native mode, and SCC was 1 (drives configured for IDE), any drive plugged into a slave port was not recognized. For Combined Mode (and SCC is still 1), 2 is a value value for MAP.map_value, and needs to be recognized. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 5719704eb0e..5250187ffce 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -432,9 +432,9 @@ static const struct piix_map_db ich8_map_db = { .present_shift = 8, .map = { /* PM PS SM SS MAP */ - { P0, NA, P1, NA }, /* 00b (hardwired) */ + { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ { RV, RV, RV, RV }, - { RV, RV, RV, RV }, /* 10b (never) */ + { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ { RV, RV, RV, RV }, }, }; -- cgit From bf2d401bca3681f5380f711be65f2026255cc166 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 20 Oct 2006 14:39:35 -0700 Subject: [PATCH] ATA must depend on BLOCK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following compile error with CONFIG_ATA=y, CONFIG_BLOCK=n: ... CC drivers/ata/libata-scsi.o /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c: In function ‘ata_scsi_dev_config’: /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:791: warning: implicit declaration of function ‘blk_queue_max_sectors’ /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:799: error: ‘request_queue_t’ undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:799: error: (Each undeclared identifier is reported only once /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:799: error: for each function it appears in.) /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:799: error: ‘q’ undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:800: warning: implicit declaration of function ‘blk_queue_max_hw_segments’ /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c: In function ‘ata_scsi_slave_config’: /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/ata/libata-scsi.c:831: warning: implicit declaration of function ‘blk_queue_max_phys_segments’ make[3]: *** [drivers/ata/libata-scsi.o] Error 1 Bug report by Jesper Juhl. Signed-off-by: Adrian Bunk Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 3f4aa0c99ee..03f6338acc8 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -6,6 +6,7 @@ menu "Serial ATA (prod) and Parallel ATA (experimental) drivers" config ATA tristate "ATA device support" + depends on BLOCK depends on !(M32R || M68K) || BROKEN depends on !SUN4 || BROKEN select SCSI -- cgit From 12a87d36b3c5cb76a182c35f40d959a615d1c862 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 16 Oct 2006 16:21:40 +0100 Subject: [PATCH] ahci: readability tweak Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 25929123fff..cef2e70d64f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1041,7 +1041,7 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) + if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) return; /* ignore interim PIO setup fis interrupts */ -- cgit From 8eb166bf805cc1c1d38d57211e8737631376b9ba Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 16 Oct 2006 16:24:50 +0100 Subject: [PATCH] libata-sff: Allow for wacky systems There are some Linux supported platforms that simply cannot hit the low I/O addresses used by ATA legacy mode PCI mappings. These platforms have a window for PCI space that is fixed by the board logic and doesn't include the neccessary locations. Provide a config option so that such platforms faced with a controller that they cannot support simply error it and punt Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 06daaa3736a..7645f2b30cc 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -981,6 +981,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, mask = (1 << 2) | (1 << 0); if ((tmp8 & mask) != mask) legacy_mode = (1 << 3); +#if defined(CONFIG_NO_ATA_LEGACY) + /* Some platforms with PCI limits cannot address compat + port space. In that case we punt if their firmware has + left a device in compatibility mode */ + if (legacy_mode) { + printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); + return -EOPNOTSUPP; + } +#endif } rc = pci_request_regions(pdev, DRV_NAME); -- cgit From 86fbf1486a44a4bce4fdcbe3665a7d8a62ba958a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 21 Oct 2006 10:24:01 -0700 Subject: [PATCH] Char: correct pci_get_device changes Commits 881a8c120acf7ec09c90289e2996b7c70f51e996 and efe1ec27837d6639eae82e1f5876910ba6433c3f corrects pci device matching in only one way; it no longer oopses/crashes, despite hotplug is not solved in these changes. Whenever pci_find_device -> pci_get_device change is performed, also pci_dev_get and pci_dev_put should be in most cases called to properly handle hotplug. This patch does exactly this thing -- increase refcount to let kernel know, that we are using this piece of HW just now. It affects moxa and rio char drivers. Cc: Acked-by: Amit Gud Acked-by: Greg Kroah-Hartman Acked-by: Alan Cox Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/moxa.c | 9 +++++++++ drivers/char/rio/host.h | 1 + drivers/char/rio/rio_linux.c | 9 +++++++++ 3 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index b401383808c..96cb1f07332 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] = typedef struct _moxa_pci_devinfo { ushort busNum; ushort devNum; + struct pci_dev *pdev; } moxa_pci_devinfo; typedef struct _moxa_board_conf { @@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf board->busType = MOXA_BUS_TYPE_PCI; board->pciInfo.busNum = p->bus->number; board->pciInfo.devNum = p->devfn >> 3; + board->pciInfo.pdev = p; + /* don't lose the reference in the next pci_get_device iteration */ + pci_dev_get(p); return (0); } @@ -493,6 +497,11 @@ static void __exit moxa_exit(void) if (tty_unregister_driver(moxaDriver)) printk("Couldn't unregister MOXA Intellio family serial driver\n"); put_tty_driver(moxaDriver); + + for (i = 0; i < MAX_BOARDS; i++) + if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) + pci_dev_put(moxa_boards[i].pciInfo.pdev); + if (verbose) printk("Done\n"); } diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h index ee2ddea7a63..23d0681fe49 100644 --- a/drivers/char/rio/host.h +++ b/drivers/char/rio/host.h @@ -44,6 +44,7 @@ ** the host. */ struct Host { + struct pci_dev *pdev; unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ unsigned char Ivec; /* POLLED or ivec number */ unsigned char Mode; /* Control stuff */ diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index c382df0f82f..7ac68cb3bed 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -1017,6 +1017,10 @@ static int __init rio_init(void) rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); fix_rio_pci(pdev); + + p->RIOHosts[p->RIONumHosts].pdev = pdev; + pci_dev_get(pdev); + p->RIOLastPCISearch = 0; p->RIONumHosts++; found++; @@ -1066,6 +1070,9 @@ static int __init rio_init(void) ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); + p->RIOHosts[p->RIONumHosts].pdev = pdev; + pci_dev_get(pdev); + p->RIOLastPCISearch = 0; p->RIONumHosts++; found++; @@ -1181,6 +1188,8 @@ static void __exit rio_exit(void) } /* It is safe/allowed to del_timer a non-active timer */ del_timer(&hp->timer); + if (hp->Type == RIO_PCI) + pci_dev_put(hp->pdev); } if (misc_deregister(&rio_fw_device) < 0) { -- cgit From 3c5473f80770768ab5712eb5a7492c16e97209fe Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 21 Oct 2006 10:24:06 -0700 Subject: [PATCH] drivers/ide/pci/generic.c: re-add the __setup("all-generic-ide",...) The change from __setup() to module_param_named() requires users to prefix the option with "generic.". This patch re-adds the __setup() additionally to the module_param_named(). Usually it would make sense getting rid of such an obsolete __setup() at some time, but considering that drivers/ide/ is slowly approaching a RIP status it's already implicitely scheduled for removal. This patch fixes kernel Bugzilla #7353. Signed-off-by: Adrian Bunk Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/generic.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 5b77a5bcbf0..ad418ce882c 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -40,6 +40,19 @@ static int ide_generic_all; /* Set to claim all devices */ +/* + * the module_param_named() was added for the modular case + * the __setup() is left as compatibility for existing setups + */ +#ifndef MODULE +static int __init ide_generic_all_on(char *unused) +{ + ide_generic_all = 1; + printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers."); + return 1; +} +__setup("all-generic-ide", ide_generic_all_on); +#endif module_param_named(all_generic_ide, ide_generic_all, bool, 0444); MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); -- cgit From 2e333e89860431d22816c1bdaa2ea72c2753396e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 21 Oct 2006 10:24:07 -0700 Subject: [PATCH] md: fix calculation of ->degraded for multipath and raid10 Two less-used md personalities have bugs in the calculation of ->degraded (the extent to which the array is degraded). Signed-off-by: Neil Brown Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/multipath.c | 2 +- drivers/md/raid10.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 171ff41b52b..a6260f0e3b9 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -501,7 +501,7 @@ static int multipath_run (mddev_t *mddev) mdname(mddev)); goto out_free_conf; } - mddev->degraded = conf->raid_disks = conf->working_disks; + mddev->degraded = conf->raid_disks - conf->working_disks; conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, sizeof(struct multipath_bh)); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 1250f0eab4a..74f17a9a6eb 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev) disk = conf->mirrors + i; if (!disk->rdev || - !test_bit(In_sync, &rdev->flags)) { + !test_bit(In_sync, &disk->rdev->flags)) { disk->head_position = 0; mddev->degraded++; } -- cgit From 1c05b4bc22cd640d3a534bd2851a8413d5df3709 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 21 Oct 2006 10:24:08 -0700 Subject: [PATCH] md: endian annotation for v1 superblock access Includes a couple of bugfixes found by sparse. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index f7f19088f3b..7daa7b1e145 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) * version 1 superblock */ -static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) +static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb) { - unsigned int disk_csum, csum; + __le32 disk_csum; + u32 csum; unsigned long long newcsum; int size = 256 + le32_to_cpu(sb->max_dev)*2; - unsigned int *isuper = (unsigned int*)sb; + __le32 *isuper = (__le32*)sb; int i; disk_csum = sb->sb_csum; @@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) newcsum += le32_to_cpu(*isuper++); if (size == 2) - newcsum += le16_to_cpu(*(unsigned short*) isuper); + newcsum += le16_to_cpu(*(__le16*) isuper); csum = (newcsum & 0xffffffff) + (newcsum >> 32); sb->sb_csum = disk_csum; @@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) if (le32_to_cpu(sb->chunksize)) rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1); - if (le32_to_cpu(sb->size) > rdev->size*2) + if (le64_to_cpu(sb->size) > rdev->size*2) return -EINVAL; return ret; } @@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) else sb->resync_offset = cpu_to_le64(0); - sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); + sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors)); sb->raid_disks = cpu_to_le32(mddev->raid_disks); sb->size = cpu_to_le64(mddev->size<<1); -- cgit From 4f2e639af4bd5e152fc79256e333643d3dd6c10f Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 21 Oct 2006 10:24:09 -0700 Subject: [PATCH] md: endian annotations for the bitmap superblock And a couple of bug fixes found by sparse. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index d47d38ac71b..d6f614738bb 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) " "-- forcing full recovery\n", bmname(bitmap), events, (unsigned long long) bitmap->mddev->events); - sb->state |= BITMAP_STALE; + sb->state |= cpu_to_le32(BITMAP_STALE); } success: /* assign fields using values from superblock */ @@ -544,11 +544,11 @@ success: bitmap->daemon_sleep = daemon_sleep; bitmap->daemon_lastrun = jiffies; bitmap->max_write_behind = write_behind; - bitmap->flags |= sb->state; + bitmap->flags |= le32_to_cpu(sb->state); if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) bitmap->flags |= BITMAP_HOSTENDIAN; bitmap->events_cleared = le64_to_cpu(sb->events_cleared); - if (sb->state & BITMAP_STALE) + if (sb->state & cpu_to_le32(BITMAP_STALE)) bitmap->events_cleared = bitmap->mddev->events; err = 0; out: @@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, spin_unlock_irqrestore(&bitmap->lock, flags); sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); switch (op) { - case MASK_SET: sb->state |= bits; + case MASK_SET: sb->state |= cpu_to_le32(bits); break; - case MASK_UNSET: sb->state &= ~bits; + case MASK_UNSET: sb->state &= cpu_to_le32(~bits); break; default: BUG(); } -- cgit From 78f32668e64caea8f638b9133da7b97c5aec20d1 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Sat, 21 Oct 2006 10:24:10 -0700 Subject: [PATCH] clocksource: acpi_pm: add another greylist chipset I have an acpi_pm that goes backwards, but it's not intel. I tested the verified read and my acpi_pm started to function properly. So I added it to the greylist. I'm assuming that's the right spot. I also added an unlikely() to the while, cause it seems appropriate. Signed-off-by: Daniel Walker Acked-by: John Stultz Acked-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/clocksource/acpi_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 7ad3be8c0f4..7fcb77a9d01 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -54,8 +54,8 @@ static cycle_t acpi_pm_read_verified(void) v1 = read_pmtmr(); v2 = read_pmtmr(); v3 = read_pmtmr(); - } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2)); + } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) + || (v3 > v1 && v3 < v2))); return (cycle_t)v2; } @@ -138,6 +138,8 @@ static void __devinit acpi_pm_check_graylist(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, acpi_pm_check_graylist); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, + acpi_pm_check_graylist); #endif -- cgit From 047a66d4bb24aaf19f41d620f8f0534c2153cd0b Mon Sep 17 00:00:00 2001 From: David Gibson Date: Sat, 21 Oct 2006 10:24:13 -0700 Subject: [PATCH] ibmveth: Fix index increment calculation The recent commit 751ae21c6cd1493e3d0a4935b08fb298b9d89773 introduced a bug in the producer/consumer index calculation in the ibmveth driver - incautious use of the post-increment ++ operator resulted in an increment being immediately reverted. This patch corrects the logic. Without this patch, the driver oopses almost immediately after activation on at least some machines. Signed-off-by: David Gibson Acked-by: Santiago Leon Cc: Jeff Garzik Cc: Martin Schwidefsky Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/ibmveth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2802db23d3c..44c9f993dcc 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -212,8 +212,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc break; } - free_index = pool->consumer_index++ % pool->size; - pool->consumer_index = free_index; + free_index = pool->consumer_index; + pool->consumer_index = (pool->consumer_index + 1) % pool->size; index = pool->free_map[free_index]; ibmveth_assert(index != IBM_VETH_INVALID_MAP); @@ -329,8 +329,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 adapter->rx_buff_pool[pool].buff_size, DMA_FROM_DEVICE); - free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size; - adapter->rx_buff_pool[pool].producer_index = free_index; + free_index = adapter->rx_buff_pool[pool].producer_index; + adapter->rx_buff_pool[pool].producer_index + = (adapter->rx_buff_pool[pool].producer_index + 1) + % adapter->rx_buff_pool[pool].size; adapter->rx_buff_pool[pool].free_map[free_index] = index; mb(); -- cgit From 8a7822a61ca9c22f464c0b79f455e62cccee747e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 21 Oct 2006 10:24:17 -0700 Subject: [PATCH] i2o/exec-osm.c: use "unsigned long flags;" Just like everyone else. Signed-off-by: Alexey Dobriyan Cc: Markus Lidel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/exec-osm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 91f95d172ca..01a5a702b03 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -127,7 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, DECLARE_WAIT_QUEUE_HEAD(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; - long flags; + unsigned long flags; int rc = 0; wait = i2o_exec_wait_alloc(); -- cgit From 3f7705eab6722ad1a346d748c4aad55755d6c241 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 21 Oct 2006 10:24:19 -0700 Subject: [PATCH] cciss: Fix warnings (and bug on 1TB discs) CCISS was producing warnings about shifts being greater than the size of the type and pointers being of incompatible type. Turns out this is because it's calling do_div on a 32-bit quantity. Upon further investigation, the sector_t total_size is being assigned to an int, and then we're calling do_div on that int. Obviously, sector_div is called for here, and I took the chance to refactor the code a little. Signed-off-by: Matthew Wilcox Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/cciss.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index dcccaf2782f..bc6602606fb 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1923,7 +1923,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, { int return_code; unsigned long t; - unsigned long rem; memset(inq_buff, 0, sizeof(InquiryData_struct)); if (withirq) @@ -1939,26 +1938,23 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, printk(KERN_WARNING "cciss: reading geometry failed, volume " "does not support reading geometry\n"); - drv->block_size = block_size; - drv->nr_blocks = total_size; drv->heads = 255; drv->sectors = 32; // Sectors per track - t = drv->heads * drv->sectors; - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); } else { - drv->block_size = block_size; - drv->nr_blocks = total_size; drv->heads = inq_buff->data_byte[6]; drv->sectors = inq_buff->data_byte[7]; drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8; drv->cylinders += inq_buff->data_byte[5]; drv->raid_level = inq_buff->data_byte[8]; - t = drv->heads * drv->sectors; - if (t > 1) { - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); - } + } + drv->block_size = block_size; + drv->nr_blocks = total_size; + t = drv->heads * drv->sectors; + if (t > 1) { + unsigned rem = sector_div(total_size, t); + if (rem) + total_size++; + drv->cylinders = total_size; } } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); -- cgit From b45eccdb51c102e3c5ff9eaecc36200ab2eb09c0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 20 Oct 2006 19:49:45 -0700 Subject: [ATM]: No need to return void The module_exit function has return-type void and pci_unregister_driver() returns void anyway. Signed-off-by: Tobias Klauser Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/ambassador.c | 4 ++-- drivers/atm/horizon.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 323592de047..9fffa7af6db 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -2452,8 +2452,8 @@ static int __init amb_module_init (void) static void __exit amb_module_exit (void) { PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module"); - - return pci_unregister_driver(&amb_driver); + + pci_unregister_driver(&amb_driver); } module_init(amb_module_init); diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index f59349206dd..44268cba5a5 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -2932,8 +2932,8 @@ static int __init hrz_module_init (void) { static void __exit hrz_module_exit (void) { PRINTD (DBG_FLOW, "cleanup_module"); - - return pci_unregister_driver(&hrz_driver); + + pci_unregister_driver(&hrz_driver); } module_init(hrz_module_init); -- cgit From 663bab6fd097c18ae0c7a7fd1b4a44558b998cdb Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 20 Oct 2006 19:50:50 -0700 Subject: [ATM] firestream: handle thrown error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc emits the following warning: drivers/atm/firestream.c: In function ‘fs_open’: drivers/atm/firestream.c:870: warning: ‘tmc0’ may be used uninitialized in this function This indicates a real bug. We should check make_rate() return value for potential errors. Signed-off-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/firestream.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 40ab9b65fae..697ad82f663 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -1002,6 +1002,10 @@ static int fs_open(struct atm_vcc *atm_vcc) r = ROUND_UP; } error = make_rate (pcr, r, &tmc0, NULL); + if (error) { + kfree(tc); + return error; + } } fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr); } -- cgit From 69c3014763966b0ae2bd190dac3654dd6cebdd45 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 20 Oct 2006 19:51:46 -0700 Subject: [ATM] nicstar: Fix a bogus casting warning Not enough to make Nicstar 64bit friendly but got squashed in passing so might as well be applied Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/nicstar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 632ede55276..bd090459480 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -2759,7 +2759,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) { ns_dev *card; pool_levels pl; - int btype; + long btype; unsigned long flags; card = dev->dev_data; @@ -2859,7 +2859,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) case NS_ADJBUFLEV: if (!capable(CAP_NET_ADMIN)) return -EPERM; - btype = (int) arg; /* an int is the same size as a pointer */ + btype = (long) arg; /* a long is the same size as a pointer or bigger */ switch (btype) { case NS_BUFTYPE_SMALL: -- cgit From 4e8a5201506423e0241202de1349422af4260296 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 Oct 2006 21:00:33 -0700 Subject: [PKT_SCHED] netem: Orphan SKB when adding to queue. The networking emulator can queue SKBs for a very long time, so if you're using netem on the sender side for large bandwidth/delay product testing, the SKB socket send queue sizes become artificially larger. Correct this by calling skb_orphan() in netem_enqueue(). Signed-off-by: David S. Miller --- drivers/pci/quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e8a7f1b1b2b..ecf8e4d6b9d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1634,7 +1634,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1 * is marked here since the boot video device will be the only enabled * video device at this point. */ - +#if 0 static void __devinit fixup_video(struct pci_dev *pdev) { struct pci_dev *bridge; @@ -1663,7 +1663,7 @@ static void __devinit fixup_video(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video); - +#endif static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { -- cgit From 0c0e4668e0e65dd1404e8cf066d147235f95561d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 23 Oct 2006 14:25:30 -0700 Subject: Revert unintentional and bogus change to drivers/pci/quirks.c In commit 4e8a5201506423e0241202de1349422af4260296 ("[PKT_SCHED] netem: Orphan SKB when adding to queue.") Davem mistakenly also included a temporary diff in his tree that disabled the pci_fixup_video VGA quirk, which broke sparc64. This reverts that part of the commit. Sayeth Davem: "Greg KH has a patch coming to you soon which will move that VGA code back into x86/x86_64/IA64 specific areas and will fix the sparc64 problem properly." Special thanks to Claudio Martins for noticing the error in the first place. Cc: Claudio Martins Cc: David Miller Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ecf8e4d6b9d..e8a7f1b1b2b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1634,7 +1634,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1 * is marked here since the boot video device will be the only enabled * video device at this point. */ -#if 0 + static void __devinit fixup_video(struct pci_dev *pdev) { struct pci_dev *bridge; @@ -1663,7 +1663,7 @@ static void __devinit fixup_video(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video); -#endif + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { -- cgit From a1aa28970316d7fb606321d5ab7fb3873641ab54 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 24 Oct 2006 21:45:00 +1000 Subject: drm: radeon: only allow specific type-3 packetss through verifier only allow specific type-3 packets to pass the verifier instead of all for r100/r200 as others might be unsafe (r300 already does this), and add checking for these we need but aren't safe. Check the RADEON_CP_INDX_BUFFER packet on both r200 and r300 as it isn't safe neither. Signed-off-by: Dave Airlie --- drivers/char/drm/r300_cmdbuf.c | 33 +++++++++++- drivers/char/drm/radeon_state.c | 109 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 26bdf2ca59d..d14477ba367 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c @@ -538,6 +538,36 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, return 0; } +static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, + drm_radeon_kcmd_buffer_t *cmdbuf) +{ + u32 *cmd = (u32 *) cmdbuf->buf; + int count, ret; + RING_LOCALS; + + count=(cmd[0]>>16) & 0x3fff; + + if ((cmd[1] & 0x8000ffff) != 0x80000810) { + DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); + return DRM_ERR(EINVAL); + } + ret = r300_check_offset(dev_priv, cmd[2]); + if (ret) { + DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); + return DRM_ERR(EINVAL); + } + + BEGIN_RING(count+2); + OUT_RING(cmd[0]); + OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); + ADVANCE_RING(); + + cmdbuf->buf += (count+2)*4; + cmdbuf->bufsz -= (count+2)*4; + + return 0; +} + static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, drm_radeon_kcmd_buffer_t *cmdbuf) { @@ -578,10 +608,11 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, case RADEON_CNTL_BITBLT_MULTI: return r300_emit_bitblt_multi(dev_priv, cmdbuf); + case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ + return r300_emit_indx_buffer(dev_priv, cmdbuf); case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ - case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ case RADEON_WAIT_FOR_IDLE: case RADEON_CP_NOP: /* these packets are safe */ diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index feac5f005d4..6e04fdd732a 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -275,6 +275,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * unsigned int *cmdsz) { u32 *cmd = (u32 *) cmdbuf->buf; + u32 offset, narrays; + int count, i, k; *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); @@ -288,10 +290,106 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * return DRM_ERR(EINVAL); } - /* Check client state and fix it up if necessary */ - if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */ - u32 offset; + switch(cmd[0] & 0xff00) { + /* XXX Are there old drivers needing other packets? */ + case RADEON_3D_DRAW_IMMD: + case RADEON_3D_DRAW_VBUF: + case RADEON_3D_DRAW_INDX: + case RADEON_WAIT_FOR_IDLE: + case RADEON_CP_NOP: + case RADEON_3D_CLEAR_ZMASK: +/* case RADEON_CP_NEXT_CHAR: + case RADEON_CP_PLY_NEXTSCAN: + case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */ + /* these packets are safe */ + break; + + case RADEON_CP_3D_DRAW_IMMD_2: + case RADEON_CP_3D_DRAW_VBUF_2: + case RADEON_CP_3D_DRAW_INDX_2: + case RADEON_3D_CLEAR_HIZ: + /* safe but r200 only */ + if (dev_priv->microcode_version != UCODE_R200) { + DRM_ERROR("Invalid 3d packet for r100-class chip\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_3D_LOAD_VBPNTR: + count = (cmd[0] >> 16) & 0x3fff; + + if (count > 18) { /* 12 arrays max */ + DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", + count); + return DRM_ERR(EINVAL); + } + + /* carefully check packet contents */ + narrays = cmd[1] & ~0xc000; + k = 0; + i = 2; + while ((k < narrays) && (i < (count + 2))) { + i++; /* skip attribute field */ + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { + DRM_ERROR + ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", + k, i); + return DRM_ERR(EINVAL); + } + k++; + i++; + if (k == narrays) + break; + /* have one more to process, they come in pairs */ + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { + DRM_ERROR + ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", + k, i); + return DRM_ERR(EINVAL); + } + k++; + i++; + } + /* do the counts match what we expect ? */ + if ((k != narrays) || (i != (count + 2))) { + DRM_ERROR + ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", + k, i, narrays, count + 1); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_3D_RNDR_GEN_INDX_PRIM: + if (dev_priv->microcode_version != UCODE_R100) { + DRM_ERROR("Invalid 3d packet for r200-class chip\n"); + return DRM_ERR(EINVAL); + } + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) { + DRM_ERROR("Invalid rndr_gen_indx offset\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CP_INDX_BUFFER: + if (dev_priv->microcode_version != UCODE_R200) { + DRM_ERROR("Invalid 3d packet for r100-class chip\n"); + return DRM_ERR(EINVAL); + } + if ((cmd[1] & 0x8000ffff) != 0x80000810) { + DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); + return DRM_ERR(EINVAL); + } + if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) { + DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CNTL_HOSTDATA_BLT: + case RADEON_CNTL_PAINT_MULTI: + case RADEON_CNTL_BITBLT_MULTI: + /* MSB of opcode: next DWORD GUI_CNTL */ if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; @@ -313,6 +411,11 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * } cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; } + break; + + default: + DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); + return DRM_ERR(EINVAL); } return 0; -- cgit From 10eee0fe9114694401c7ae154e8cfb2ab2f59c10 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Tue, 24 Oct 2006 21:46:55 +1000 Subject: drm: savage: dev->agp_buffer_map is not initialized for AGP DMA on savages fd.o bug 8662 Signed-off-by: Dave Airlie --- drivers/char/drm/savage_bci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 59c7520bf9a..a9a84f88df5 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c @@ -728,6 +728,7 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init) dev_priv->status = NULL; } if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { + dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { -- cgit From 958de71b1ab01c20c1b385035235746c9227b24f Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Tue, 24 Oct 2006 21:52:23 +1000 Subject: drm: mga: set dev_priv_size fd.o bug 1746 Signed-off-by: Dave Airlie --- drivers/char/drm/mga_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index e30f556b79f..be49dbb9ec3 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c @@ -47,6 +47,7 @@ static struct drm_driver driver = { DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + .dev_priv_size = sizeof(drm_mga_buf_priv_t), .load = mga_driver_load, .unload = mga_driver_unload, .lastclose = mga_driver_lastclose, -- cgit From f586fbd0ef273a80d88a07f911d9f2f2a8ac1679 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 20 Oct 2006 00:56:28 +0100 Subject: [ARM] 3897/1: corgi_bl fix module compiling Fix module compiling: WARNING: drivers/video/backlight/corgi_bl.o - Section mismatch: reference to .init.text: from .data between '$d' (at offset 0x0) and 'bl_mutex' Cc: Richard Purdie Signed-off-by: Anton Vorontsov Signed-off-by: Russell King --- drivers/video/backlight/corgi_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 2ebbfd95145..6697778650d 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -111,7 +111,7 @@ static struct backlight_properties corgibl_data = { .update_status = corgibl_set_intensity, }; -static int __init corgibl_probe(struct platform_device *pdev) +static int corgibl_probe(struct platform_device *pdev) { struct corgibl_machinfo *machinfo = pdev->dev.platform_data; -- cgit From 62c877b9b7c463aa16ffbc9a322cb094fdb5827a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 20 Oct 2006 00:58:49 +0100 Subject: [ARM] 3898/1: corgi_bl fix module loading Fix module loading: corgi_bl: module license 'GPLv2' taints kernel. corgi_bl: Unknown symbol platform_driver_unregister corgi_bl: Unknown symbol __symbol_get corgi_bl: Unknown symbol platform_driver_register Cc: Richard Purdie Signed-off-by: pHilipp Zabel Signed-off-by: Anton Vorontsov Signed-off-by: Russell King --- drivers/video/backlight/corgi_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 6697778650d..d07ecb53c68 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -166,4 +166,4 @@ module_exit(corgibl_exit); MODULE_AUTHOR("Richard Purdie "); MODULE_DESCRIPTION("Corgi Backlight Driver"); -MODULE_LICENSE("GPLv2"); +MODULE_LICENSE("GPL"); -- cgit From 4ccc12aeece8ab14ad96461c4db269aea080715d Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 24 Oct 2006 14:45:53 -0700 Subject: e1000: FIX: don't poke at manageability registers for incompatible adapters The MANC register should not be read for PCI-E adapters at all, as well as 82543 and older where 82543 would master abort when this register was accessed. Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_ethtool.c | 3 ++- drivers/net/e1000/e1000_main.c | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 773821e4cf5..71fb27880f6 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -461,7 +461,8 @@ e1000_get_regs(struct net_device *netdev, regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ if (hw->mac_type >= e1000_82540 && - hw->media_type == e1000_media_type_copper) { + hw->mac_type < e1000_82571 && + hw->media_type == e1000_media_type_copper) { regs_buff[26] = E1000_READ_REG(hw, MANC); } } diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index fa849831d09..fb83082c4f7 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -699,7 +699,10 @@ e1000_reset(struct e1000_adapter *adapter) phy_data); } - if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) { + if ((adapter->en_mng_pt) && + (adapter->hw.mac_type >= e1000_82540) && + (adapter->hw.mac_type < e1000_82571) && + (adapter->hw.media_type == e1000_media_type_copper)) { manc = E1000_READ_REG(&adapter->hw, MANC); manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); E1000_WRITE_REG(&adapter->hw, MANC, manc); @@ -1076,8 +1079,9 @@ e1000_remove(struct pci_dev *pdev) flush_scheduled_work(); - if (adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -4773,8 +4777,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - if (adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -4825,8 +4830,9 @@ e1000_resume(struct pci_dev *pdev) netif_device_attach(netdev); - if (adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(&adapter->hw, MANC, manc); @@ -4944,6 +4950,7 @@ static void e1000_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); manc &= ~(E1000_MANC_ARP_EN); -- cgit From dc1f71f6b30c258704885cd488582eb3d68b3e8e Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 24 Oct 2006 14:45:55 -0700 Subject: e1000: FIX: 82542 doesn't support WoL Exclude 82542 when setting up WoL. This card does not do WoL at all. Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_ethtool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 71fb27880f6..c564adbd669 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1691,6 +1691,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol int retval = 1; /* fail by default */ switch (hw->device_id) { + case E1000_DEV_ID_82542: case E1000_DEV_ID_82543GC_FIBER: case E1000_DEV_ID_82543GC_COPPER: case E1000_DEV_ID_82544EI_FIBER: -- cgit From 225a5dbd68f5271b7425f2f783ae64a1f6863b51 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 24 Oct 2006 14:45:58 -0700 Subject: e1000: FIX: fix wrong txdctl threshold bitmasks Threshold bitmasks for prefetch, host and writeback were clearing bits that they were not supposed to. The leftmost 2 bits in the byte for each threshold are reserved. Signed-off-by: Bruce Allan Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_hw.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 112447fd8bf..449a60303e0 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1961,9 +1961,9 @@ struct e1000_hw { #define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */ /* Transmit Descriptor Control */ -#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */ -#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */ -#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ +#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ -- cgit From e64d7d02090e475cfd7efbc830146d0c6dd579bc Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 24 Oct 2006 14:46:01 -0700 Subject: e1000: FIX: Disable Packet Split for non jumbo frames Allocations using alloc_page are taking too long for normal MTU, so use LPE only for jumbo frames. Signed-off-bu: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index fb83082c4f7..7362e124017 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1808,9 +1808,11 @@ e1000_setup_rctl(struct e1000_adapter *adapter) * followed by the page buffers. Therefore, skb->data is * sized to hold the largest protocol header. */ + /* allocations using alloc_page take too long for regular MTU + * so only enable packet split for jumbo frames */ pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) && - PAGE_SIZE <= 16384) + if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) && + PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE)) adapter->rx_ps_pages = pages; else adapter->rx_ps_pages = 0; -- cgit From 032fe6e9e253ebb37a0df0893844674dea9210fd Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 24 Oct 2006 14:46:04 -0700 Subject: e1000: FIX: Don't limit descriptor size to 4kb for PCI-E adapters 82571 and newer chispets don't need to limit desc. length to 4kb and can handle 8kb sizes. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 7362e124017..e75909ee6d8 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2992,6 +2992,11 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } + /* 82571 and newer doesn't need the workaround that limited descriptor + * length to 4kB */ + if (adapter->hw.mac_type >= e1000_82571) + max_per_txd = 8192; + #ifdef NETIF_F_TSO mss = skb_shinfo(skb)->gso_size; /* The controller does a simple calculation to -- cgit From d2a1e2131aee7b3feb815636dc7917a96e49fd8e Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 24 Oct 2006 14:46:06 -0700 Subject: e1000: FIX: move length adjustment due to crc stripping disabled. Move the length (rx_bytes counter) adjustment of 4 bytes down to after the TBI_ACCEPT workaround. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index e75909ee6d8..66ed920df40 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3786,9 +3786,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); - /* adjust length to remove Ethernet CRC */ - length -= 4; - if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" @@ -3816,6 +3813,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, } } + /* adjust length to remove Ethernet CRC, this must be + * done after the TBI_ACCEPT workaround above */ + length -= 4; + /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ -- cgit From ff1e55b078676d3c449ace6b99d95c0e22c905d6 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 24 Oct 2006 14:46:09 -0700 Subject: e1000: Increment version to 7.2.9-k4 Significant fixes -> increment driver version. Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 66ed920df40..8d04752777a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -35,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.2.9-k2"DRIVERNAPI +#define DRV_VERSION "7.2.9-k4"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; -- cgit From 824545e7031541f83245d254caca012bf6bdc6cd Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 24 Oct 2006 14:49:44 -0700 Subject: e100: account for closed interface when shutting down Account for the interface being closed before disabling polling on a device, to fix shutdown on some systems that explcitly close the netdevice before calling shutdown. Signed-off-by: Auke Kok --- drivers/net/e100.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index a3a08a5dd18..19ab3441269 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2719,7 +2719,10 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - netif_poll_disable(nic->netdev); +#ifdef CONFIG_E100_NAPI + if (netif_running(netdev)) + netif_poll_disable(nic->netdev); +#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); @@ -2763,7 +2766,10 @@ static void e100_shutdown(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - netif_poll_disable(nic->netdev); +#ifdef CONFIG_E100_NAPI + if (netif_running(netdev)) + netif_poll_disable(nic->netdev); +#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); -- cgit From 977a415f2b70b5693aaa23b1a16ad57ea20a1dce Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 24 Oct 2006 16:16:39 -0700 Subject: [ATM] horizon: read_bia() needs to be __devinit Thanks to Randy Dunlap. Signed-off-by: David S. Miller --- drivers/atm/horizon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 44268cba5a5..4dc10105d61 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1789,7 +1789,7 @@ static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl) WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK); } -static u16 __init read_bia (const hrz_dev * dev, u16 addr) +static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) { u32 ctrl = rd_regl (dev, CONTROL_0_REG); -- cgit From aa6c2e62bbe7a20ccc85906f75bc63465d899227 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Oct 2006 11:16:29 +0100 Subject: [PATCH] IOC4 should depend on PCI Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b6c045dc97b..00db31c314e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -30,6 +30,7 @@ config IBM_ASM config SGI_IOC4 tristate "SGI IOC4 Base IO support" + depends on PCI ---help--- This option enables basic support for the IOC4 chip on certain SGI IO controller cards (IO9, IO10, and PCI-RT). This option -- cgit From 016002312d50004908a79df37174b336e3682e18 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Oct 2006 11:17:37 +0100 Subject: [PATCH] missing include of dma-mapping.h Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index ea16078cfe9..d1105e569a4 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include -- cgit From 2099c99e3b24f86b131566aa9854249189ae9ea2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Oct 2006 11:17:06 +0100 Subject: [PATCH] missing includes of io.h Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/misc/ioc4.c | 1 + drivers/mmc/tifm_sd.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 1c3c14a3839..79354bbbbd6 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -32,6 +32,7 @@ #include #include #include +#include /*************** * Definitions * diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index 2bacff60913..0fdc55b08a6 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c @@ -14,6 +14,7 @@ #include #include #include +#include #define DRIVER_NAME "tifm_sd" #define DRIVER_VERSION "0.6" -- cgit From bcbaecbb9968750d4bfb2686a97e396f681f88ef Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 25 Oct 2006 16:49:36 +1000 Subject: [CRYPTO] users: Select ECB/CBC where needed CRYPTO_MANAGER is selected automatically by CONFIG_ECB and CONFIG_CBC. config CRYPTO_ECB tristate "ECB support" select CRYPTO_BLKCIPHER select CRYPTO_MANAGER I've added CONFIG_ECB to the ones you mentioned and CONFIG_CBC to gssapi. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e2ed24918a5..e38846eb51f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2717,6 +2717,7 @@ config PPP_MPPE select CRYPTO select CRYPTO_SHA1 select CRYPTO_ARC4 + select CRYPTO_ECB ---help--- Support for the MPPE Encryption protocol, as employed by the Microsoft Point-to-Point Tunneling Protocol. -- cgit From 0d960d26c42888cf327df7faa1a8aa62bab53fa4 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 18 Oct 2006 00:26:39 -0400 Subject: fix return code in error case. The other failure returns in this function are negative, so make this one do the same. Signed-off-by: Dave Jones Signed-off-by: Dave Airlie --- drivers/char/drm/savage_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c index ef2581d1614..1ca1e9cb5a3 100644 --- a/drivers/char/drm/savage_state.c +++ b/drivers/char/drm/savage_state.c @@ -994,7 +994,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) if (cmdbuf.size) { kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); if (kcmd_addr == NULL) - return ENOMEM; + return DRM_ERR(ENOMEM); if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, cmdbuf.size * 8)) -- cgit From 24f73c92a990ecd3d1bb846267780a264d830065 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 10 Oct 2006 14:23:37 -0700 Subject: drm: fix error returns, sysfs error handling - callers of drm_sysfs_create() and drm_sysfs_device_add() looked for errors using IS_ERR(), but the functions themselves only ever returned NULL on error. Fixed. - unwind from, and propagate sysfs errors Signed-off-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/drm/drm_sysfs.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 51ad98c685c..ba4b8de83cf 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c @@ -42,13 +42,24 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); struct class *drm_sysfs_create(struct module *owner, char *name) { struct class *class; + int err; class = class_create(owner, name); - if (!class) - return class; + if (!class) { + err = -ENOMEM; + goto err_out; + } + + err = class_create_file(class, &class_attr_version); + if (err) + goto err_out_class; - class_create_file(class, &class_attr_version); return class; + +err_out_class: + class_destroy(class); +err_out: + return ERR_PTR(err); } /** @@ -96,20 +107,36 @@ static struct class_device_attribute class_device_attrs[] = { struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) { struct class_device *class_dev; - int i; + int i, j, err; class_dev = class_device_create(cs, NULL, MKDEV(DRM_MAJOR, head->minor), &(head->dev->pdev)->dev, "card%d", head->minor); - if (!class_dev) - return NULL; + if (!class_dev) { + err = -ENOMEM; + goto err_out; + } class_set_devdata(class_dev, head); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(class_dev, &class_device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + err = class_device_create_file(class_dev, + &class_device_attrs[i]); + if (err) + goto err_out_files; + } + return class_dev; + +err_out_files: + if (i > 0) + for (j = 0; j < i; j++) + class_device_remove_file(class_dev, + &class_device_attrs[i]); + class_device_unregister(class_dev); +err_out: + return ERR_PTR(err); } /** -- cgit From 85abb3f95010b277a6efbc9b8031a7854af87e10 Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Wed, 25 Oct 2006 09:55:34 -0700 Subject: drm: ioremap balanced with iounmap for drivers/char/drm ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Tested (compilation only) to make sure the files are compiling without any warning/error due to new changes Signed-off-by: Amol Lad Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 029baea33b6..6eafff13dab 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -237,6 +237,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); if (!list) { + if (map->type == _DRM_REGISTERS) + drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -252,6 +254,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, map->offset; ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { + if (map->type == _DRM_REGISTERS) + drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(list, sizeof(*list), DRM_MEM_MAPS); mutex_unlock(&dev->struct_mutex); -- cgit From a77b8950019289611f836c8fc19f91592822efcd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 20 Oct 2006 14:36:00 -0700 Subject: intel fb: switch to pci_get API Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/video/intelfb/intelfbhw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index eeeeff9a09e..eae60f97e26 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -161,7 +161,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, return 1; /* Find the bridge device. It is always 0:0.0 */ - if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) { + if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) { ERR_MSG("cannot find bridge device\n"); return 1; } @@ -169,6 +169,8 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, /* Get the fb aperture size and "stolen" memory amount. */ tmp = 0; pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); + pci_dev_put(bridge_dev); + switch (pdev->device) { case PCI_DEVICE_ID_INTEL_915G: case PCI_DEVICE_ID_INTEL_915GM: -- cgit From f84fcb06a1f7ab4ac0444ece82b25b0701369641 Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Fri, 20 Oct 2006 14:35:59 -0700 Subject: Remove unnecessary check in drivers/video/intelfb/intelfbhw.c All callers and the function itself dereference dinfo, so we can remove the check. (coverity id #1371) Signed-off-by: Eric Sesterhenn Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/video/intelfb/intelfbhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index eae60f97e26..a95836839e1 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -664,7 +664,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) int index = dinfo->pll_index; DBG_MSG("intelfbhw_print_hw_state\n"); - if (!hw || !dinfo) + if (!hw) return; /* Read in as much of the HW state as possible. */ printk("hw state dump start\n"); -- cgit From 811c93666c3f4a0e99382c24a84480b03c7262f6 Mon Sep 17 00:00:00 2001 From: Henne Date: Tue, 3 Oct 2006 19:51:59 +0200 Subject: [SCSI] Scsi_Cmnd convertion in sun3-driver Change the obsolete Scsi_Cmnd to struct scsi_cmnd in the sun3-driver. Signed-off-by: Henrik Kretzschmar Signed-off-by: James Bottomley --- drivers/scsi/sun3_NCR5380.c | 109 ++++++++++++++++++++++--------------------- drivers/scsi/sun3_scsi.c | 7 +-- drivers/scsi/sun3_scsi.h | 7 +-- drivers/scsi/sun3_scsi_vme.c | 7 +-- 4 files changed, 69 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 5ec5af8e337..3b3f3050a87 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -266,8 +266,8 @@ static struct scsi_host_template *the_template = NULL; (struct NCR5380_hostdata *)(in)->hostdata #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) -#define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble)) -#define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) +#define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble)) +#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble)) #define HOSTNO instance->host_no #define H_NO(cmd) (cmd)->device->host->host_no @@ -360,7 +360,7 @@ static void __init init_tags( void ) * conditions. */ -static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) +static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) { SETUP_HOSTDATA(cmd->device->host); @@ -384,7 +384,7 @@ static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) * untagged. */ -static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) +static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) { SETUP_HOSTDATA(cmd->device->host); @@ -416,7 +416,7 @@ static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) * unlock the LUN. */ -static void cmd_free_tag( Scsi_Cmnd *cmd ) +static void cmd_free_tag(struct scsi_cmnd *cmd) { SETUP_HOSTDATA(cmd->device->host); @@ -460,18 +460,18 @@ static void free_all_tags( void ) /* - * Function: void merge_contiguous_buffers( Scsi_Cmnd *cmd ) + * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd) * * Purpose: Try to merge several scatter-gather requests into one DMA * transfer. This is possible if the scatter buffers lie on * physical contiguous addresses. * - * Parameters: Scsi_Cmnd *cmd + * Parameters: struct scsi_cmnd *cmd * The command to work on. The first scatter buffer's data are * assumed to be already transfered into ptr/this_residual. */ -static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) +static void merge_contiguous_buffers(struct scsi_cmnd *cmd) { unsigned long endaddr; #if (NDEBUG & NDEBUG_MERGING) @@ -501,15 +501,15 @@ static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) } /* - * Function : void initialize_SCp(Scsi_Cmnd *cmd) + * Function : void initialize_SCp(struct scsi_cmnd *cmd) * * Purpose : initialize the saved data pointers for cmd to point to the * start of the buffer. * - * Inputs : cmd - Scsi_Cmnd structure to have pointers reset. + * Inputs : cmd - struct scsi_cmnd structure to have pointers reset. */ -static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) +static __inline__ void initialize_SCp(struct scsi_cmnd *cmd) { /* * Initialize the Scsi Pointer field so that all of the commands in the @@ -753,14 +753,15 @@ static void NCR5380_print_status (struct Scsi_Host *instance) do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ pos += sprintf(pos, fmt , ## args); } while(0) static -char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); +char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, + int length); -static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, - off_t offset, int length, int inout) +static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, + char **start, off_t offset, int length, int inout) { char *pos = buffer; struct NCR5380_hostdata *hostdata; - Scsi_Cmnd *ptr; + struct scsi_cmnd *ptr; unsigned long flags; off_t begin = 0; #define check_offset() \ @@ -784,18 +785,19 @@ static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **s if (!hostdata->connected) SPRINTF("scsi%d: no currently connected command\n", HOSTNO); else - pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, + pos = lprint_Scsi_Cmnd ((struct scsi_cmnd *) hostdata->connected, pos, buffer, length); SPRINTF("scsi%d: issue_queue\n", HOSTNO); check_offset(); - for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { + for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) + { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); } SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); check_offset(); - for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; + for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); @@ -810,8 +812,8 @@ static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **s return length; } -static char * -lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) +static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, + int length) { int i, s; unsigned char *command; @@ -888,8 +890,8 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) } /* - * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, - * void (*done)(Scsi_Cmnd *)) + * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd, + * void (*done)(struct scsi_cmnd *)) * * Purpose : enqueues a SCSI command * @@ -906,10 +908,11 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) */ /* Only make static if a wrapper function is used */ -static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static int NCR5380_queue_command(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) { SETUP_HOSTDATA(cmd->device->host); - Scsi_Cmnd *tmp; + struct scsi_cmnd *tmp; unsigned long flags; #if (NDEBUG & NDEBUG_NO_WRITE) @@ -990,7 +993,7 @@ static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) NEXT(cmd) = hostdata->issue_queue; hostdata->issue_queue = cmd; } else { - for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; + for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; NEXT(tmp); tmp = NEXT(tmp)) ; LIST(cmd, tmp); @@ -1030,7 +1033,7 @@ static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) static void NCR5380_main (void *bl) { - Scsi_Cmnd *tmp, *prev; + struct scsi_cmnd *tmp, *prev; struct Scsi_Host *instance = first_instance; struct NCR5380_hostdata *hostdata = HOSTDATA(instance); int done; @@ -1073,12 +1076,12 @@ static void NCR5380_main (void *bl) * for a target that's not busy. */ #if (NDEBUG & NDEBUG_LISTS) - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; + for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) ; if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/ #endif - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, + for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { #if (NDEBUG & NDEBUG_LISTS) @@ -1339,7 +1342,8 @@ static irqreturn_t NCR5380_intr (int irq, void *dev_id) } #ifdef NCR5380_STATS -static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) +static void collect_stats(struct NCR5380_hostdata *hostdata, + struct scsi_cmnd *cmd) { # ifdef NCR5380_STAT_LIMIT if (cmd->request_bufflen > NCR5380_STAT_LIMIT) @@ -1365,8 +1369,8 @@ static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) #endif /* - * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, - * int tag); + * Function : int NCR5380_select(struct Scsi_Host *instance, + * struct scsi_cmnd *cmd, int tag); * * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, * including ARBITRATION, SELECTION, and initial message out for @@ -1395,7 +1399,8 @@ static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) * cmd->result host byte set to DID_BAD_TARGET. */ -static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) +static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd, + int tag) { SETUP_HOSTDATA(instance); unsigned char tmp[3], phase; @@ -1985,7 +1990,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) #endif unsigned char *data; unsigned char phase, tmp, extended_msg[10], old_phase=0xff; - Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected; + struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected; #ifdef SUN3_SCSI_VME dregs->csr |= CSR_INTR; @@ -2272,7 +2277,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) local_irq_save(flags); LIST(cmd,hostdata->issue_queue); NEXT(cmd) = hostdata->issue_queue; - hostdata->issue_queue = (Scsi_Cmnd *) cmd; + hostdata->issue_queue = (struct scsi_cmnd *) cmd; local_irq_restore(flags); QU_PRINTK("scsi%d: REQUEST SENSE added to head of " "issue queue\n", H_NO(cmd)); @@ -2502,7 +2507,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) * Function : void NCR5380_reselect (struct Scsi_Host *instance) * * Purpose : does reselection, initializing the instance->connected - * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q + * field to point to the struct scsi_cmnd for which the I_T_L or I_T_L_Q * nexus has been reestablished, * * Inputs : instance - this instance of the NCR5380. @@ -2521,7 +2526,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) unsigned char tag; #endif unsigned char msg[3]; - Scsi_Cmnd *tmp = NULL, *prev; + struct scsi_cmnd *tmp = NULL, *prev; /* unsigned long flags; */ /* @@ -2577,7 +2582,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) * just reestablished, and remove it from the disconnected queue. */ - for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; + for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) #ifdef SUPPORT_TAGS @@ -2668,11 +2673,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) /* - * Function : int NCR5380_abort (Scsi_Cmnd *cmd) + * Function : int NCR5380_abort(struct scsi_cmnd *cmd) * * Purpose : abort a command * - * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the + * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the * host byte of the result field to, if zero DID_ABORTED is * used. * @@ -2684,11 +2689,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) * called where the loop started in NCR5380_main(). */ -static int NCR5380_abort (Scsi_Cmnd *cmd) +static int NCR5380_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *instance = cmd->device->host; SETUP_HOSTDATA(instance); - Scsi_Cmnd *tmp, **prev; + struct scsi_cmnd *tmp, **prev; unsigned long flags; printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); @@ -2753,9 +2758,9 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) * Case 2 : If the command hasn't been issued yet, we simply remove it * from the issue queue. */ - for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), - tmp = (Scsi_Cmnd *) hostdata->issue_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) + for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), + tmp = (struct scsi_cmnd *) hostdata->issue_queue; + tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) if (cmd == tmp) { REMOVE(5, *prev, tmp, NEXT(tmp)); (*prev) = NEXT(tmp); @@ -2812,7 +2817,7 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) * it from the disconnected queue. */ - for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; + for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = NEXT(tmp)) if (cmd == tmp) { local_irq_restore(flags); @@ -2826,8 +2831,8 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) do_abort (instance); local_irq_save(flags); - for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), - tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; + for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), + tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) if (cmd == tmp) { REMOVE(5, *prev, tmp, NEXT(tmp)); @@ -2868,7 +2873,7 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) /* - * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd) + * Function : int NCR5380_bus_reset(struct scsi_cmnd *cmd) * * Purpose : reset the SCSI bus. * @@ -2876,13 +2881,13 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) * */ -static int NCR5380_bus_reset( Scsi_Cmnd *cmd) +static int NCR5380_bus_reset(struct scsi_cmnd *cmd) { SETUP_HOSTDATA(cmd->device->host); int i; unsigned long flags; #if 1 - Scsi_Cmnd *connected, *disconnected_queue; + struct scsi_cmnd *connected, *disconnected_queue; #endif @@ -2914,9 +2919,9 @@ static int NCR5380_bus_reset( Scsi_Cmnd *cmd) * remembered in local variables first. */ local_irq_save(flags); - connected = (Scsi_Cmnd *)hostdata->connected; + connected = (struct scsi_cmnd *)hostdata->connected; hostdata->connected = NULL; - disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue; + disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue; hostdata->disconnected_queue = NULL; #ifdef SUPPORT_TAGS free_all_tags(); diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index e625b4c5833..d56d85dd9ba 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -119,7 +119,7 @@ module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); -static Scsi_Cmnd *sun3_dma_setup_done = NULL; +static struct scsi_cmnd *sun3_dma_setup_done = NULL; #define AFTER_RESET_DELAY (HZ/2) @@ -521,8 +521,9 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) return last_residual; } -static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, - int write_flag) +static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, + struct scsi_cmnd *cmd, + int write_flag) { if(blk_fs_request(cmd->request)) return wanted; diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h index 834dab42801..a1103b3e203 100644 --- a/drivers/scsi/sun3_scsi.h +++ b/drivers/scsi/sun3_scsi.h @@ -47,11 +47,12 @@ #define IOBASE_SUN3_VMESCSI 0xff200000 -static int sun3scsi_abort (Scsi_Cmnd *); +static int sun3scsi_abort(struct scsi_cmnd *); static int sun3scsi_detect (struct scsi_host_template *); static const char *sun3scsi_info (struct Scsi_Host *); -static int sun3scsi_bus_reset(Scsi_Cmnd *); -static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +static int sun3scsi_bus_reset(struct scsi_cmnd *); +static int sun3scsi_queue_command(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); static int sun3scsi_release (struct Scsi_Host *); #ifndef CMD_PER_LUN diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index e8faab16567..92def310a84 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c @@ -84,7 +84,7 @@ module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); -static Scsi_Cmnd *sun3_dma_setup_done = NULL; +static struct scsi_cmnd *sun3_dma_setup_done = NULL; #define AFTER_RESET_DELAY (HZ/2) @@ -455,8 +455,9 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) return last_residual; } -static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, - int write_flag) +static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, + struct scsi_cmnd *cmd, + int write_flag) { if(blk_fs_request(cmd->request)) return wanted; -- cgit From a24342b90c9c829fc5fea9ee01b127f81bca18ef Mon Sep 17 00:00:00 2001 From: Henne Date: Tue, 3 Oct 2006 21:31:14 +0200 Subject: [SCSI] Scsi_Cmnd conversion in qlogicfas408 driver Change obsolete Scsi_Cmnd to struct scsi_cmnd in the Qlocic FAS408 driver. Signed-off-by: Henrik Kretzschmar rejections fixed and Signed-off-by: James Bottomley --- drivers/scsi/qlogicfas408.c | 18 +++++++++--------- drivers/scsi/qlogicfas408.h | 29 +++++++++++++++-------------- 2 files changed, 24 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index e0725353c99..2e7db18f5ae 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -209,7 +209,7 @@ static int ql_wai(struct qlogicfas408_priv *priv) * caller must hold host lock */ -static void ql_icmd(Scsi_Cmnd * cmd) +static void ql_icmd(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); int qbase = priv->qbase; @@ -256,7 +256,7 @@ static void ql_icmd(Scsi_Cmnd * cmd) * Process scsi command - usually after interrupt */ -static unsigned int ql_pcmd(Scsi_Cmnd * cmd) +static unsigned int ql_pcmd(struct scsi_cmnd *cmd) { unsigned int i, j; unsigned long k; @@ -407,7 +407,7 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) static void ql_ihandl(void *dev_id) { - Scsi_Cmnd *icmd; + struct scsi_cmnd *icmd; struct Scsi_Host *host = dev_id; struct qlogicfas408_priv *priv = get_priv_by_host(host); int qbase = priv->qbase; @@ -447,7 +447,8 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) * Queued command */ -int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) +int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, + void (*done) (struct scsi_cmnd *)) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); if (scmd_id(cmd) == priv->qinitid) { @@ -470,9 +471,8 @@ int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) * Return bios parameters */ -int qlogicfas408_biosparam(struct scsi_device * disk, - struct block_device *dev, - sector_t capacity, int ip[]) +int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, + sector_t capacity, int ip[]) { /* This should mimic the DOS Qlogic driver's behavior exactly */ ip[0] = 0x40; @@ -494,7 +494,7 @@ int qlogicfas408_biosparam(struct scsi_device * disk, * Abort a command in progress */ -int qlogicfas408_abort(Scsi_Cmnd * cmd) +int qlogicfas408_abort(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); priv->qabort = 1; @@ -508,7 +508,7 @@ int qlogicfas408_abort(Scsi_Cmnd * cmd) * the PCMCIA qlogic_stub code. This wants fixing */ -int qlogicfas408_bus_reset(Scsi_Cmnd * cmd) +int qlogicfas408_bus_reset(struct scsi_cmnd *cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); unsigned long flags; diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h index 8fd5555c75b..260626427a3 100644 --- a/drivers/scsi/qlogicfas408.h +++ b/drivers/scsi/qlogicfas408.h @@ -75,15 +75,15 @@ /*----------------------------------------------------------------*/ struct qlogicfas408_priv { - int qbase; /* Port */ - int qinitid; /* initiator ID */ - int qabort; /* Flag to cause an abort */ - int qlirq; /* IRQ being used */ - int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ - char qinfo[80]; /* description */ - Scsi_Cmnd *qlcmd; /* current command being processed */ - struct Scsi_Host *shost; /* pointer back to host */ - struct qlogicfas408_priv *next; /* next private struct */ + int qbase; /* Port */ + int qinitid; /* initiator ID */ + int qabort; /* Flag to cause an abort */ + int qlirq; /* IRQ being used */ + int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ + char qinfo[80]; /* description */ + struct scsi_cmnd *qlcmd; /* current command being processed */ + struct Scsi_Host *shost; /* pointer back to host */ + struct qlogicfas408_priv *next; /* next private struct */ }; /* The qlogic card uses two register maps - These macros select which one */ @@ -103,12 +103,13 @@ struct qlogicfas408_priv { #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0]) irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id); -int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)); +int qlogicfas408_queuecommand(struct scsi_cmnd * cmd, + void (*done) (struct scsi_cmnd *)); int qlogicfas408_biosparam(struct scsi_device * disk, - struct block_device *dev, - sector_t capacity, int ip[]); -int qlogicfas408_abort(Scsi_Cmnd * cmd); -int qlogicfas408_bus_reset(Scsi_Cmnd * cmd); + struct block_device *dev, + sector_t capacity, int ip[]); +int qlogicfas408_abort(struct scsi_cmnd * cmd); +int qlogicfas408_bus_reset(struct scsi_cmnd * cmd); const char *qlogicfas408_info(struct Scsi_Host *host); int qlogicfas408_get_chip_type(int qbase, int int_type); void qlogicfas408_setup(int qbase, int id, int int_type); -- cgit From 413f73272090a69e35a03c938272ec661b1d3d4c Mon Sep 17 00:00:00 2001 From: Kai Makisara Date: Thu, 5 Oct 2006 22:59:46 +0300 Subject: [SCSI] st: Fixup -ENOMEDIUM Based on the original patch from Hannes Reinecke Fix st_open() to return -ENOMEDIUM instead of -EIO if no medium is found. Signed-off-by: Kai Makisara Signed-off-by: James Bottomley --- drivers/scsi/st.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3babdc76b3f..e1a52c525ed 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -1177,7 +1177,10 @@ static int st_open(struct inode *inode, struct file *filp) goto err_out; if ((filp->f_flags & O_NONBLOCK) == 0 && retval != CHKRES_READY) { - retval = (-EIO); + if (STp->ready == NO_TAPE) + retval = (-ENOMEDIUM); + else + retval = (-EIO); goto err_out; } return 0; -- cgit From 75c28851c9eee889ef4347ff6f55b2dd1e1ceb81 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 6 Oct 2006 00:11:17 +0200 Subject: [SCSI] tmscsim: set max_sectors AM53C974A's Start Transfer Counter register has 24 bits, thus maximum transfer length is 16MiB. But the maximum I can test is 8MiB, so use that until somebody tests 16MiB. Signed-off-by: Guennadi Liakhovetski Signed-off-by: James Bottomley --- drivers/scsi/tmscsim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index d03aa6ce8fe..fa5382e354b 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -2304,6 +2304,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, + .max_sectors = 0x4000, /* 8MiB = 16 * 1024 * 512 */ }; /*********************************************************************** -- cgit From 5ae16db36988e811410494fb5d07c81e14453e7b Mon Sep 17 00:00:00 2001 From: Doug Maxey Date: Thu, 5 Oct 2006 23:50:07 -0500 Subject: [SCSI] qla4xxx: fix double printk on load There is a dup printk at the tail of qla4xxx_module_init(). Remove the first instance as it's before the complete success of the function. Signed-off-by: James Bottomley --- drivers/scsi/qla4xxx/ql4_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 178fcddcfd8..4fa01535fb6 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -1724,13 +1724,13 @@ static int __init qla4xxx_module_init(void) goto release_srb_cache; } - printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); ret = pci_register_driver(&qla4xxx_pci_driver); if (ret) goto unregister_transport; printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); return 0; + unregister_transport: iscsi_unregister_transport(&qla4xxx_iscsi_transport); release_srb_cache: -- cgit From 80f1443c66de3ec42e28d151bd43a80de398877e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 6 Oct 2006 09:22:41 +0200 Subject: [SCSI] aic7xxx: Adjust .max_sectors According to the adaptec sources aic7xxx / aic79xx really can do 4MB transfers. So we should adjust .max_sectors. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx_osm.c | 1 + drivers/scsi/aic7xxx/aic7xxx_osm.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index f8e60486167..d8d6687e20a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -773,6 +773,7 @@ struct scsi_host_template aic79xx_driver_template = { #endif .can_queue = AHD_MAX_QUEUE, .this_id = -1, + .max_sectors = 8192, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .slave_alloc = ahd_linux_slave_alloc, diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 43ab753d273..ad8578e9593 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -777,6 +777,7 @@ struct scsi_host_template aic7xxx_driver_template = { #endif .can_queue = AHC_MAX_QUEUE, .this_id = -1, + .max_sectors = 8192, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .slave_alloc = ahc_linux_slave_alloc, -- cgit From 11010fecd2a1fdae684237b61709367ae6a93289 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 6 Oct 2006 09:54:59 -0700 Subject: [SCSI] Maintain module-parameter name consistency with qla2xxx/qla4xxx. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.h | 14 +++++++------- drivers/scsi/qla2xxx/qla_gbl.h | 2 +- drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 8 ++++---- drivers/scsi/qla4xxx/ql4_dbg.h | 4 ++-- drivers/scsi/qla4xxx/ql4_glbl.h | 2 +- drivers/scsi/qla4xxx/ql4_mbx.c | 2 +- drivers/scsi/qla4xxx/ql4_os.c | 8 ++++---- 8 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 90dad7e8898..5b12278968e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -38,7 +38,7 @@ * Macros use for debugging the driver. */ -#define DEBUG(x) do { if (qla2_extended_error_logging) { x; } } while (0) +#define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0) #if defined(QL_DEBUG_LEVEL_1) #define DEBUG1(x) do {x;} while (0) @@ -46,12 +46,12 @@ #define DEBUG1(x) do {} while (0) #endif -#define DEBUG2(x) do { if (qla2_extended_error_logging) { x; } } while (0) -#define DEBUG2_3(x) do { if (qla2_extended_error_logging) { x; } } while (0) -#define DEBUG2_3_11(x) do { if (qla2_extended_error_logging) { x; } } while (0) -#define DEBUG2_9_10(x) do { if (qla2_extended_error_logging) { x; } } while (0) -#define DEBUG2_11(x) do { if (qla2_extended_error_logging) { x; } } while (0) -#define DEBUG2_13(x) do { if (qla2_extended_error_logging) { x; } } while (0) +#define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) #if defined(QL_DEBUG_LEVEL_3) #define DEBUG3(x) do {x;} while (0) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 7da69832d74..b51ce8f59cb 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -60,7 +60,7 @@ extern int ql2xplogiabsentdevice; extern int ql2xloginretrycount; extern int ql2xfdmienable; extern int ql2xallocfwdump; -extern int qla2_extended_error_logging; +extern int ql2xextended_error_logging; extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 833b93085fd..d5e0a124c4f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1644,7 +1644,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) * Set host adapter parameters. */ if (nv->host_p[0] & BIT_7) - qla2_extended_error_logging = 1; + ql2xextended_error_logging = 1; ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); /* Always load RISC code on non ISP2[12]00 chips. */ if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3f20d765563..34b6eb71e45 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -61,9 +61,9 @@ MODULE_PARM_DESC(ql2xallocfwdump, "during HBA initialization. Memory allocation requirements " "vary by ISP type. Default is 1 - allocate memory."); -int qla2_extended_error_logging; -module_param(qla2_extended_error_logging, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(qla2_extended_error_logging, +int ql2xextended_error_logging; +module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR); +MODULE_PARM_DESC(ql2xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging. 1 - log errors."); @@ -2697,7 +2697,7 @@ qla2x00_module_init(void) /* Derive version string. */ strcpy(qla2x00_version_str, QLA2XXX_VERSION); - if (qla2_extended_error_logging) + if (ql2xextended_error_logging) strcat(qla2x00_version_str, "-debug"); qla2xxx_transport_template = diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h index 3e99dcfd5a9..d861c3b411c 100644 --- a/drivers/scsi/qla4xxx/ql4_dbg.h +++ b/drivers/scsi/qla4xxx/ql4_dbg.h @@ -22,14 +22,14 @@ #endif #if defined(QL_DEBUG_LEVEL_2) -#define DEBUG2(x) do {if(qla4_extended_error_logging == 2) x;} while (0); +#define DEBUG2(x) do {if(ql4xextended_error_logging == 2) x;} while (0); #define DEBUG2_3(x) do {x;} while (0); #else /* */ #define DEBUG2(x) do {} while (0); #endif /* */ #if defined(QL_DEBUG_LEVEL_3) -#define DEBUG3(x) do {if(qla4_extended_error_logging == 3) x;} while (0); +#define DEBUG3(x) do {if(ql4xextended_error_logging == 3) x;} while (0); #else /* */ #define DEBUG3(x) do {} while (0); #if !defined(QL_DEBUG_LEVEL_2) diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2c803edf2de..1b221ff0f6f 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -72,7 +72,7 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, uint32_t fw_ddb_index, uint32_t state); -extern int qla4_extended_error_logging; +extern int ql4xextended_error_logging; extern int ql4xdiscoverywait; extern int ql4xdontresethba; #endif /* _QLA4x_GBL_H */ diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index ef82399c085..b721dc5dd71 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -701,7 +701,7 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", ha->host_no, num_valid_entries)); - if (qla4_extended_error_logging == 3) { + if (ql4xextended_error_logging == 3) { if (oldest_entry == 0) { /* Circular Buffer has not wrapped around */ for (i=0; i < num_valid_entries; i++) { diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 4fa01535fb6..5b8db610953 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -34,9 +34,9 @@ MODULE_PARM_DESC(ql4xdontresethba, " default it will reset hba :0" " set to 1 to avoid resetting HBA"); -int qla4_extended_error_logging = 0; /* 0 = off, 1 = log errors */ -module_param(qla4_extended_error_logging, int, S_IRUGO | S_IRUSR); -MODULE_PARM_DESC(qla4_extended_error_logging, +int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */ +module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR); +MODULE_PARM_DESC(ql4xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging, 1 - debug logging"); @@ -1714,7 +1714,7 @@ static int __init qla4xxx_module_init(void) /* Derive version string. */ strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION); - if (qla4_extended_error_logging) + if (ql4xextended_error_logging) strcat(qla4xxx_version_str, "-debug"); qla4xxx_scsi_transport = -- cgit From 35508e46aae4b57bd07d095eb11533e296b254dc Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Fri, 6 Oct 2006 15:39:25 -0500 Subject: [SCSI] mptfc: stall eh handlers if resetting while rport blocked Thanks to James Smart for the inspiration. Stall error handler if attempting recovery while an rport is blocked. This avoids device offline scenarios due to errors in the error handler. Also verify that VirtDevice is available before issuing scsi command. VirtDevice is removed when fc transport removes a target. See James Smart's patch of 08/17/2006 for greater detail. http://marc.theaimsgroup.com/?l=linux-scsi&m=115583213624803&w=2 Also bump version number per Eric's request. Signed-off-by: Michael Reed Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 4 +- drivers/message/fusion/mptfc.c | 89 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index c537d71c18e..a4afad4ecab 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -75,8 +75,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.01" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01" +#define MPT_LINUX_VERSION_COMMON "3.04.02" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.02" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index e57bb035a02..1dd49177315 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -96,6 +96,10 @@ static int mptfc_qcmd(struct scsi_cmnd *SCpnt, static void mptfc_target_destroy(struct scsi_target *starget); static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); static void __devexit mptfc_remove(struct pci_dev *pdev); +static int mptfc_abort(struct scsi_cmnd *SCpnt); +static int mptfc_dev_reset(struct scsi_cmnd *SCpnt); +static int mptfc_bus_reset(struct scsi_cmnd *SCpnt); +static int mptfc_host_reset(struct scsi_cmnd *SCpnt); static struct scsi_host_template mptfc_driver_template = { .module = THIS_MODULE, @@ -110,10 +114,10 @@ static struct scsi_host_template mptfc_driver_template = { .target_destroy = mptfc_target_destroy, .slave_destroy = mptscsih_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, - .eh_abort_handler = mptscsih_abort, - .eh_device_reset_handler = mptscsih_dev_reset, - .eh_bus_reset_handler = mptscsih_bus_reset, - .eh_host_reset_handler = mptscsih_host_reset, + .eh_abort_handler = mptfc_abort, + .eh_device_reset_handler = mptfc_dev_reset, + .eh_bus_reset_handler = mptfc_bus_reset, + .eh_host_reset_handler = mptfc_host_reset, .bios_param = mptscsih_bios_param, .can_queue = MPT_FC_CAN_QUEUE, .this_id = -1, @@ -171,6 +175,77 @@ static struct fc_function_template mptfc_transport_functions = { .show_host_symbolic_name = 1, }; +static int +mptfc_block_error_handler(struct scsi_cmnd *SCpnt, + int (*func)(struct scsi_cmnd *SCpnt), + const char *caller) +{ + struct scsi_device *sdev = SCpnt->device; + struct Scsi_Host *shost = sdev->host; + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + unsigned long flags; + int ready; + + spin_lock_irqsave(shost->host_lock, flags); + while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { + spin_unlock_irqrestore(shost->host_lock, flags); + dfcprintk ((MYIOC_s_INFO_FMT + "mptfc_block_error_handler.%d: %d:%d, port status is " + "DID_IMM_RETRY, deferring %s recovery.\n", + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + SCpnt->device->id,SCpnt->device->lun,caller)); + msleep(1000); + spin_lock_irqsave(shost->host_lock, flags); + } + spin_unlock_irqrestore(shost->host_lock, flags); + + if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { + dfcprintk ((MYIOC_s_INFO_FMT + "%s.%d: %d:%d, failing recovery, " + "port state %d, vdev %p.\n", caller, + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + SCpnt->device->id,SCpnt->device->lun,ready, + SCpnt->device->hostdata)); + return FAILED; + } + dfcprintk ((MYIOC_s_INFO_FMT + "%s.%d: %d:%d, executing recovery.\n", caller, + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, + ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + SCpnt->device->id,SCpnt->device->lun)); + return (*func)(SCpnt); +} + +static int +mptfc_abort(struct scsi_cmnd *SCpnt) +{ + return + mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__); +} + +static int +mptfc_dev_reset(struct scsi_cmnd *SCpnt) +{ + return + mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__); +} + +static int +mptfc_bus_reset(struct scsi_cmnd *SCpnt) +{ + return + mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__); +} + +static int +mptfc_host_reset(struct scsi_cmnd *SCpnt) +{ + return + mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); +} + static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { @@ -562,6 +637,12 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) return 0; } + if (!SCpnt->device->hostdata) { /* vdev */ + SCpnt->result = DID_NO_CONNECT << 16; + done(SCpnt); + return 0; + } + /* dd_data is null until finished adding target */ ri = *((struct mptfc_rport_info **)rport->dd_data); if (unlikely(!ri)) { -- cgit From 8e394aec14f24e3b41a315a2dc53537024190c8a Mon Sep 17 00:00:00 2001 From: Henne Date: Mon, 9 Oct 2006 15:38:34 +0200 Subject: [SCSI] fix typo in previous Scsi_Cmnd convertion in aic7xxx_old.c Fixes a typo in the aic7xxx_old.c. Signed-off-by: Olaf Hering Signed-off-by: Henrik Kretzschmar Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx_old.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index bcd7fffab90..46eed10b25d 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -2646,7 +2646,7 @@ static void aic7xxx_done_cmds_complete(struct aic7xxx_host *p) while (p->completeq.head != NULL) { cmd = p->completeq.head; - p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble; + p->completeq.head = (struct scsi_cmnd *) cmd->host_scribble; cmd->host_scribble = NULL; cmd->scsi_done(cmd); } -- cgit From 46c43db1eabcdc46ad9a3d711edff1d698ecd21f Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 8 Oct 2006 15:55:55 +0400 Subject: [SCSI] scsi_lib.c: use BUILD_BUG_ON Signed-off-by: Alexey Dobriyan Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 743f67ed764..d2c02df12fd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1084,7 +1084,7 @@ static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) { struct request *req = cmd->request; - BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); cmd->cmd_len = req->cmd_len; if (!req->data_len) -- cgit From 0b3a82d391563da15df2b3a0d245d41748822489 Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Tue, 10 Oct 2006 14:41:43 -0700 Subject: [SCSI] lpfc: check before dereference in lpfc_ct.c If we fail to allocate mp->virt during the first while loop iteration, mlist is still uninitialized, therefore we should check if before dereferencing. Signed-off-by: Eric Sesterhenn Acked-by: James Smart Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_ct.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1b53afb1cb5..3add7c23785 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -188,7 +188,8 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, if (!mp->virt) { kfree(mp); - lpfc_free_ct_rsp(phba, mlist); + if (mlist) + lpfc_free_ct_rsp(phba, mlist); return NULL; } -- cgit From c543a3739c2a3034c80d77a189bd187c43a00feb Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Tue, 10 Oct 2006 14:41:45 -0700 Subject: [SCSI] Scsi_Cmnd conversion in psi240i driver Changes the obsolete Scsi_Cmnd to struct scsi_cmnd in psi240i-driver. Signed-off-by: Henrik Kretzschmar Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/psi240i.c | 31 ++++++++++++++++++------------- drivers/scsi/psi240i.h | 6 +++--- 2 files changed, 21 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index a720c9265e6..ac0419e2714 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -87,11 +87,11 @@ typedef struct { USHORT ports[13]; OUR_DEVICE device[8]; - Scsi_Cmnd *pSCmnd; + struct scsi_cmnd *pSCmnd; IDE_STRUCT ide; ULONG startSector; USHORT sectorCount; - Scsi_Cmnd *SCpnt; + struct scsi_cmnd *SCpnt; VOID *buffer; USHORT expectingIRQ; } ADAPTER240I, *PADAPTER240I; @@ -253,12 +253,12 @@ static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status) ****************************************************************/ static void Irq_Handler (int irq, void *dev_id) { - struct Scsi_Host *shost; // Pointer to host data block - PADAPTER240I padapter; // Pointer to adapter control structure - USHORT *pports; // I/O port array - Scsi_Cmnd *SCpnt; - UCHAR status; - int z; + struct Scsi_Host *shost; // Pointer to host data block + PADAPTER240I padapter; // Pointer to adapter control structure + USHORT *pports; // I/O port array + struct scsi_cmnd *SCpnt; + UCHAR status; + int z; DEB(printk ("\npsi240i received interrupt\n")); @@ -389,12 +389,17 @@ static irqreturn_t do_Irq_Handler (int irq, void *dev_id) * Returns: Status code. * ****************************************************************/ -static int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) +static int Psi240i_QueueCommand(struct scsi_cmnd *SCpnt, + void (*done)(struct scsi_cmnd *)) { - UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB - PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); // Pointer to adapter control structure - POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];// Pointer to device information - UCHAR rc; // command return code + UCHAR *cdb = (UCHAR *)SCpnt->cmnd; + // Pointer to SCSI CDB + PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); + // Pointer to adapter control structure + POUR_DEVICE pdev = &padapter->device [SCpnt->device->id]; + // Pointer to device information + UCHAR rc; + // command return code SCpnt->scsi_done = done; padapter->ide.ide.ides.spigot = pdev->spigot; diff --git a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h index 6a598766df5..21ebb921400 100644 --- a/drivers/scsi/psi240i.h +++ b/drivers/scsi/psi240i.h @@ -309,7 +309,7 @@ typedef struct _IDENTIFY_DATA2 { #endif // PSI_EIDE_SCSIOP // function prototypes -int Psi240i_Command (Scsi_Cmnd *SCpnt); -int Psi240i_Abort (Scsi_Cmnd *SCpnt); -int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); +int Psi240i_Command(struct scsi_cmnd *SCpnt); +int Psi240i_Abort(struct scsi_cmnd *SCpnt); +int Psi240i_Reset(struct scsi_cmnd *SCpnt, unsigned int flags); #endif -- cgit From 0fc82d5e84825ab43006f40935633120d23c2e15 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Tue, 10 Oct 2006 14:41:41 -0700 Subject: [SCSI] convert ninja driver to struct scsi_cmnd Changes the obsolete typedefd Scsi_Cmnd to struct scsi_cmnd in the ninja scsi pcmcia driver. Signed-off-by: Henrik Kretzschmar Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/pcmcia/nsp_cs.c | 42 ++++++++++++++++++----------------- drivers/scsi/pcmcia/nsp_cs.h | 46 +++++++++++++++++++++------------------ drivers/scsi/pcmcia/nsp_debug.c | 4 ++-- drivers/scsi/pcmcia/nsp_message.c | 4 ++-- 4 files changed, 51 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index b1d34604952..f2d79c3f0b8 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -183,7 +183,7 @@ static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ... * Clenaup parameters and call done() functions. * You must be set SCpnt->result before call this function. */ -static void nsp_scsi_done(Scsi_Cmnd *SCpnt) +static void nsp_scsi_done(struct scsi_cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -192,7 +192,8 @@ static void nsp_scsi_done(Scsi_Cmnd *SCpnt) SCpnt->scsi_done(SCpnt); } -static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) +static int nsp_queuecommand(struct scsi_cmnd *SCpnt, + void (*done)(struct scsi_cmnd *)) { #ifdef NSP_DEBUG /*unsigned int host_id = SCpnt->device->host->this_id;*/ @@ -365,7 +366,7 @@ static int nsphw_init(nsp_hw_data *data) /* * Start selection phase */ -static int nsphw_start_selection(Scsi_Cmnd *SCpnt) +static int nsphw_start_selection(struct scsi_cmnd *SCpnt) { unsigned int host_id = SCpnt->device->host->this_id; unsigned int base = SCpnt->device->host->io_port; @@ -446,7 +447,7 @@ static struct nsp_sync_table nsp_sync_table_20M[] = { /* * setup synchronous data transfer mode */ -static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) +static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt) { unsigned char target = scmd_id(SCpnt); // unsigned char lun = SCpnt->device->lun; @@ -504,7 +505,7 @@ static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) /* * start ninja hardware timer */ -static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) +static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -517,7 +518,8 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) /* * wait for bus phase change */ -static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) +static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask, + char *str) { unsigned int base = SCpnt->device->host->io_port; unsigned char reg; @@ -544,9 +546,9 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) /* * expect Ninja Irq */ -static int nsp_expect_signal(Scsi_Cmnd *SCpnt, - unsigned char current_phase, - unsigned char mask) +static int nsp_expect_signal(struct scsi_cmnd *SCpnt, + unsigned char current_phase, + unsigned char mask) { unsigned int base = SCpnt->device->host->io_port; int time_out; @@ -579,7 +581,7 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt, /* * transfer SCSI message */ -static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) +static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -619,7 +621,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) /* * get extra SCSI data from fifo */ -static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) +static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; unsigned int count; @@ -651,7 +653,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) /* * accept reselection */ -static int nsp_reselected(Scsi_Cmnd *SCpnt) +static int nsp_reselected(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned int host_id = SCpnt->device->host->this_id; @@ -690,7 +692,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt) /* * count how many data transferd */ -static int nsp_fifo_count(Scsi_Cmnd *SCpnt) +static int nsp_fifo_count(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned int count; @@ -717,7 +719,7 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) /* * read data in DATA IN phase */ -static void nsp_pio_read(Scsi_Cmnd *SCpnt) +static void nsp_pio_read(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned long mmio_base = SCpnt->device->host->base; @@ -812,7 +814,7 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt) /* * write data in DATA OUT phase */ -static void nsp_pio_write(Scsi_Cmnd *SCpnt) +static void nsp_pio_write(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned long mmio_base = SCpnt->device->host->base; @@ -905,7 +907,7 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt) /* * setup synchronous/asynchronous data transfer mode */ -static int nsp_nexus(Scsi_Cmnd *SCpnt) +static int nsp_nexus(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned char target = scmd_id(SCpnt); @@ -952,7 +954,7 @@ static irqreturn_t nspintr(int irq, void *dev_id) { unsigned int base; unsigned char irq_status, irq_phase, phase; - Scsi_Cmnd *tmpSC; + struct scsi_cmnd *tmpSC; unsigned char target, lun; unsigned int *sync_neg; int i, tmp; @@ -1530,7 +1532,7 @@ nsp_proc_info( /*---------------------------------------------------------------*/ /* -static int nsp_eh_abort(Scsi_Cmnd *SCpnt) +static int nsp_eh_abort(struct scsi_cmnd *SCpnt) { nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); @@ -1558,7 +1560,7 @@ static int nsp_bus_reset(nsp_hw_data *data) return SUCCESS; } -static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) +static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -1567,7 +1569,7 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) return nsp_bus_reset(data); } -static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) +static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index a88714f4c05..625ca97da52 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -266,7 +266,7 @@ typedef struct _nsp_hw_data { int TimerCount; int SelectionTimeOut; - Scsi_Cmnd *CurrentSC; + struct scsi_cmnd *CurrentSC; //int CurrnetTarget; int FifoCount; @@ -319,30 +319,34 @@ static int nsp_proc_info ( int hostno, #endif int inout); -static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt)); +static int nsp_queuecommand(struct scsi_cmnd *SCpnt, + void (* done)(struct scsi_cmnd *SCpnt)); /* Error handler */ -/*static int nsp_eh_abort (Scsi_Cmnd *SCpnt);*/ -/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/ -static int nsp_eh_bus_reset (Scsi_Cmnd *SCpnt); -static int nsp_eh_host_reset (Scsi_Cmnd *SCpnt); +/*static int nsp_eh_abort (struct scsi_cmnd *SCpnt);*/ +/*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/ +static int nsp_eh_bus_reset (struct scsi_cmnd *SCpnt); +static int nsp_eh_host_reset (struct scsi_cmnd *SCpnt); static int nsp_bus_reset (nsp_hw_data *data); /* */ static int nsphw_init (nsp_hw_data *data); -static int nsphw_start_selection(Scsi_Cmnd *SCpnt); -static void nsp_start_timer (Scsi_Cmnd *SCpnt, int time); -static int nsp_fifo_count (Scsi_Cmnd *SCpnt); -static void nsp_pio_read (Scsi_Cmnd *SCpnt); -static void nsp_pio_write (Scsi_Cmnd *SCpnt); -static int nsp_nexus (Scsi_Cmnd *SCpnt); -static void nsp_scsi_done (Scsi_Cmnd *SCpnt); -static int nsp_analyze_sdtr (Scsi_Cmnd *SCpnt); -static int nsp_negate_signal (Scsi_Cmnd *SCpnt, unsigned char mask, char *str); -static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char mask); -static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase); -static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt); -static int nsp_reselected (Scsi_Cmnd *SCpnt); +static int nsphw_start_selection(struct scsi_cmnd *SCpnt); +static void nsp_start_timer (struct scsi_cmnd *SCpnt, int time); +static int nsp_fifo_count (struct scsi_cmnd *SCpnt); +static void nsp_pio_read (struct scsi_cmnd *SCpnt); +static void nsp_pio_write (struct scsi_cmnd *SCpnt); +static int nsp_nexus (struct scsi_cmnd *SCpnt); +static void nsp_scsi_done (struct scsi_cmnd *SCpnt); +static int nsp_analyze_sdtr (struct scsi_cmnd *SCpnt); +static int nsp_negate_signal (struct scsi_cmnd *SCpnt, + unsigned char mask, char *str); +static int nsp_expect_signal (struct scsi_cmnd *SCpnt, + unsigned char current_phase, + unsigned char mask); +static int nsp_xfer (struct scsi_cmnd *SCpnt, int phase); +static int nsp_dataphase_bypass (struct scsi_cmnd *SCpnt); +static int nsp_reselected (struct scsi_cmnd *SCpnt); static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); /* Interrupt handler */ @@ -355,8 +359,8 @@ static void __exit nsp_cs_exit(void); /* Debug */ #ifdef NSP_DEBUG -static void show_command (Scsi_Cmnd *SCpnt); -static void show_phase (Scsi_Cmnd *SCpnt); +static void show_command (struct scsi_cmnd *SCpnt); +static void show_phase (struct scsi_cmnd *SCpnt); static void show_busphase(unsigned char stat); static void show_message (nsp_hw_data *data); #else diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c index 62e5c60067f..2f75fe6e35a 100644 --- a/drivers/scsi/pcmcia/nsp_debug.c +++ b/drivers/scsi/pcmcia/nsp_debug.c @@ -138,12 +138,12 @@ static void print_commandk (unsigned char *command) printk("\n"); } -static void show_command(Scsi_Cmnd *SCpnt) +static void show_command(struct scsi_cmnd *SCpnt) { print_commandk(SCpnt->cmnd); } -static void show_phase(Scsi_Cmnd *SCpnt) +static void show_phase(struct scsi_cmnd *SCpnt) { int i = SCpnt->SCp.phase; diff --git a/drivers/scsi/pcmcia/nsp_message.c b/drivers/scsi/pcmcia/nsp_message.c index d7057737ff3..ef593b70d0f 100644 --- a/drivers/scsi/pcmcia/nsp_message.c +++ b/drivers/scsi/pcmcia/nsp_message.c @@ -8,7 +8,7 @@ /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */ -static void nsp_message_in(Scsi_Cmnd *SCpnt) +static void nsp_message_in(struct scsi_cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -50,7 +50,7 @@ static void nsp_message_in(Scsi_Cmnd *SCpnt) } -static void nsp_message_out(Scsi_Cmnd *SCpnt) +static void nsp_message_out(struct scsi_cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; int ret = 1; -- cgit From 9531c330f14c02d9f4eff7345071f485dc62dab1 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Tue, 10 Oct 2006 14:41:42 -0700 Subject: [SCSI] fc4: Conversion to struct scsi_cmnd in fc4 Changes the obsolete Scsi_Cmnd to struct scsi_cmnd in the Fibre Channel driver (fc4). Signed-off-by: Henrik Kretzschmar Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/fc4/fc.c | 28 +++++++++++++++------------- drivers/fc4/fcp_impl.h | 15 ++++++++------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 22d17474755..ca4e67a022d 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c @@ -70,9 +70,9 @@ #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) -#define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp))) +#define SC_FCMND(fcmnd) ((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp))) -static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int); +static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int); void fcp_queue_empty(fc_channel *); static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd) @@ -378,14 +378,14 @@ void fcp_register(fc_channel *fc, u8 type, int unregister) printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type); } -static void fcp_scsi_done(Scsi_Cmnd *SCpnt); +static void fcp_scsi_done(struct scsi_cmnd *SCpnt); static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch) { fcp_cmnd *fcmd; fcp_rsp *rsp; int host_status; - Scsi_Cmnd *SCpnt; + struct scsi_cmnd *SCpnt; int sense_len; int rsp_status; @@ -757,13 +757,14 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */ } -static void fcp_scsi_done (Scsi_Cmnd *SCpnt) +static void fcp_scsi_done(struct scsi_cmnd *SCpnt) { if (FCP_CMND(SCpnt)->done) FCP_CMND(SCpnt)->done(SCpnt); } -static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) +static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, + fcp_cmnd *fcmd, int prepare) { long i; fcp_cmd *cmd; @@ -837,7 +838,8 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i return 0; } -int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *)) +int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt, + void (* done)(struct scsi_cmnd *)) { fcp_cmnd *fcmd = FCP_CMND(SCpnt); fc_channel *fc = FC_SCMND(SCpnt); @@ -873,7 +875,7 @@ void fcp_queue_empty(fc_channel *fc) } } -int fcp_scsi_abort(Scsi_Cmnd *SCpnt) +int fcp_scsi_abort(struct scsi_cmnd *SCpnt) { /* Internal bookkeeping only. Lose 1 cmd_slots slot. */ fcp_cmnd *fcmd = FCP_CMND(SCpnt); @@ -910,7 +912,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt) } #if 0 -void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) +void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt) { fc_channel *fc = FC_SCMND(SCpnt); @@ -921,7 +923,7 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) #define FCP_RESET_TIMEOUT (2*HZ) -int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) +int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) { #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */ unsigned long flags; @@ -931,7 +933,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) DECLARE_MUTEX_LOCKED(sem); if (!fc->rst_pkt) { - fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); + fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); if (!fc->rst_pkt) return FAILED; fcmd = FCP_CMND(fc->rst_pkt); @@ -999,7 +1001,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) return SUCCESS; } -static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) +static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) { fc_channel *fc = FC_SCMND(SCpnt); fcp_cmnd *fcmd = FCP_CMND(SCpnt); @@ -1020,7 +1022,7 @@ static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) else return FAILED; } -int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) +int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) { unsigned long flags; int rc; diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h index c397c84bef6..1ac61330592 100644 --- a/drivers/fc4/fcp_impl.h +++ b/drivers/fc4/fcp_impl.h @@ -39,7 +39,7 @@ struct _fc_channel; typedef struct fcp_cmnd { struct fcp_cmnd *next; struct fcp_cmnd *prev; - void (*done)(Scsi_Cmnd *); + void (*done)(struct scsi_cmnd *); unsigned short proto; unsigned short token; unsigned int did; @@ -94,14 +94,14 @@ typedef struct _fc_channel { long *scsi_bitmap; long scsi_bitmap_end; int scsi_free; - int (*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); + int (*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); fcp_cmnd *scsi_que; char scsi_name[4]; fcp_cmnd **cmd_slots; int channels; int targets; long *ages; - Scsi_Cmnd *rst_pkt; + struct scsi_cmnd *rst_pkt; fcp_posmap *posmap; /* LOGIN stuff */ fcp_cmnd *login; @@ -155,9 +155,10 @@ int fc_do_prli(fc_channel *, unsigned char); for_each_fc_channel(fc) \ if (fc->state == FC_STATE_ONLINE) -int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); -int fcp_scsi_abort(Scsi_Cmnd *); -int fcp_scsi_dev_reset(Scsi_Cmnd *); -int fcp_scsi_host_reset(Scsi_Cmnd *); +int fcp_scsi_queuecommand(struct scsi_cmnd *, + void (* done) (struct scsi_cmnd *)); +int fcp_scsi_abort(struct scsi_cmnd *); +int fcp_scsi_dev_reset(struct scsi_cmnd *); +int fcp_scsi_host_reset(struct scsi_cmnd *); #endif /* !(_FCP_SCSI_H) */ -- cgit From 8d1a006049ff1c084d57fbea1106ecad3455bd27 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Thu, 12 Oct 2006 11:43:44 +0200 Subject: [SCSI] zfcp: initialize scsi_host_template.max_sectors with appropriate value Define ZFCP_MAX_SECTORS and initialize scsi_host_template.max_sectors with appropriate value. Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_def.h | 4 ++++ drivers/s390/scsi/zfcp_scsi.c | 1 + 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 8f882690994..74c0eac083e 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -107,6 +107,10 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ +#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) + /* max. number of (data buffer) SBALEs in largest SBAL chain + multiplied with number of sectors per 4k block */ + /* FIXME(tune): free space should be one max. SBAL chain plus what? */ #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - (ZFCP_MAX_SBALS_PER_REQ + 4)) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 4d2bc798132..452d96f92a1 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -58,6 +58,7 @@ struct zfcp_data zfcp_data = { .cmd_per_lun = 1, .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, + .max_sectors = ZFCP_MAX_SECTORS, }, .driver_version = ZFCP_VERSION, }; -- cgit From f1663ad5dbb801e03c4c99c24d698ad5dba9aaff Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 13 Oct 2006 09:33:37 -0700 Subject: [SCSI] qla2xxx: Check return value of sysfs_create_bin_file() usage. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 51 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ee75a71f3c6..285c8e8ff1a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -379,21 +379,37 @@ static struct bin_attribute sysfs_sfp_attr = { .read = qla2x00_sysfs_read_sfp, }; +static struct sysfs_entry { + char *name; + struct bin_attribute *attr; + int is4GBp_only; +} bin_file_entries[] = { + { "fw_dump", &sysfs_fw_dump_attr, }, + { "nvram", &sysfs_nvram_attr, }, + { "optrom", &sysfs_optrom_attr, }, + { "optrom_ctl", &sysfs_optrom_ctl_attr, }, + { "vpd", &sysfs_vpd_attr, 1 }, + { "sfp", &sysfs_sfp_attr, 1 }, + { 0 }, +}; + void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) { struct Scsi_Host *host = ha->host; + struct sysfs_entry *iter; + int ret; - sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); - sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); - sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); - sysfs_create_bin_file(&host->shost_gendev.kobj, - &sysfs_optrom_ctl_attr); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { - sysfs_create_bin_file(&host->shost_gendev.kobj, - &sysfs_vpd_attr); - sysfs_create_bin_file(&host->shost_gendev.kobj, - &sysfs_sfp_attr); + for (iter = bin_file_entries; iter->name; iter++) { + if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) + continue; + + ret = sysfs_create_bin_file(&host->shost_gendev.kobj, + iter->attr); + if (ret) + qla_printk(KERN_INFO, ha, + "Unable to create sysfs %s binary attribute " + "(%d).\n", iter->name, ret); } } @@ -401,17 +417,14 @@ void qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) { struct Scsi_Host *host = ha->host; + struct sysfs_entry *iter; + + for (iter = bin_file_entries; iter->name; iter++) { + if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) + continue; - sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); - sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); - sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); - sysfs_remove_bin_file(&host->shost_gendev.kobj, - &sysfs_optrom_ctl_attr); - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { - sysfs_remove_bin_file(&host->shost_gendev.kobj, - &sysfs_vpd_attr); sysfs_remove_bin_file(&host->shost_gendev.kobj, - &sysfs_sfp_attr); + iter->attr); } if (ha->beacon_blink_led == 1) -- cgit From 18c6c12759813c988bb05796d1b3352e98ae77de Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 13 Oct 2006 09:33:38 -0700 Subject: [SCSI] qla2xxx: Workaround D3 power-management issues. Early ISP2432 parts have a known hardware issue when coming out of a D3 hot state. This issue can result in a hung PCIe link. Recent firmwares contain a workaround whereby the stop-firmware mailbox command prevents the ISP from entering the D3 hot state. In order to ensure that the workaround succeeded the driver must verify that the stop-firmware mailbox command completes successfully. In the event of a failure, the driver attempts a shutdown-retry after resetting the ISP and re-executing firmware. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_init.c | 21 +++++++++++++++++++++ drivers/scsi/qla2xxx/qla_os.c | 6 +++--- 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index b51ce8f59cb..ca2f660a543 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -48,6 +48,7 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); +extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); /* * Global Data in qla_os.c source file. diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d5e0a124c4f..08cb5e3fb55 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3948,3 +3948,24 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) fail_fw_integrity: return QLA_FUNCTION_FAILED; } + +void +qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) +{ + int ret, retries; + + if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + return; + + ret = qla2x00_stop_firmware(ha); + for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { + qla2x00_reset_chip(ha); + if (qla2x00_chip_diag(ha) != QLA_SUCCESS) + continue; + if (qla2x00_setup_chip(ha) != QLA_SUCCESS) + continue; + qla_printk(KERN_INFO, ha, + "Attempting retry of stop-firmware command...\n"); + ret = qla2x00_stop_firmware(ha); + } +} diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 34b6eb71e45..54f561d9c7a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1712,8 +1712,10 @@ qla2x00_free_device(scsi_qla_host_t *ha) if (ha->eft) qla2x00_trace_control(ha, TC_DISABLE, 0, 0); + ha->flags.online = 0; + /* Stop currently executing firmware. */ - qla2x00_stop_firmware(ha); + qla2x00_try_to_stop_firmware(ha); /* turn-off interrupts on the card */ if (ha->interrupts_on) @@ -1721,8 +1723,6 @@ qla2x00_free_device(scsi_qla_host_t *ha) qla2x00_mem_free(ha); - ha->flags.online = 0; - /* Detach interrupts */ if (ha->host->irq) free_irq(ha->host->irq, ha); -- cgit From df7baa506c2db1c2d12abd6f05c43f911da55a2e Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 13 Oct 2006 09:33:39 -0700 Subject: [SCSI] qla2xxx: Correct QUEUE_FULL handling. - Drop queue-depths across all luns for a given fcport during TASK_SET_FULL statuses. - Ramp-up I/Os after throttling. - Consolidate completion-status handling of CS_QUEUE_FULL with CS_COMPLETE as ISP24xx firmware no longer reports CS_QUEUE_FULL. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 4 ++ drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_isr.c | 91 +++++++++++++++++++++++++++++++++++++----- drivers/scsi/qla2xxx/qla_os.c | 21 +++++++++- 4 files changed, 104 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index bab33f6d0bd..c4fc40f8e8c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1545,6 +1545,9 @@ typedef struct fc_port { spinlock_t rport_lock; struct fc_rport *rport, *drport; u32 supported_classes; + + unsigned long last_queue_full; + unsigned long last_ramp_up; } fc_port_t; /* @@ -2255,6 +2258,7 @@ typedef struct scsi_qla_host { uint16_t mgmt_svr_loop_id; uint32_t login_retry_count; + int max_q_depth; /* Fibre Channel Device List. */ struct list_head fcports; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index ca2f660a543..32ebeec45ff 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -62,6 +62,7 @@ extern int ql2xloginretrycount; extern int ql2xfdmienable; extern int ql2xallocfwdump; extern int ql2xextended_error_logging; +extern int ql2xqfullrampup; extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 626c7178a43..d3b6df4d55c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -6,6 +6,8 @@ */ #include "qla_def.h" +#include + static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); @@ -593,6 +595,67 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) } } +static void +qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) +{ + fc_port_t *fcport = data; + + if (fcport->ha->max_q_depth <= sdev->queue_depth) + return; + + if (sdev->ordered_tags) + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, + sdev->queue_depth + 1); + else + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, + sdev->queue_depth + 1); + + fcport->last_ramp_up = jiffies; + + DEBUG2(qla_printk(KERN_INFO, fcport->ha, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", + fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + +static void +qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) +{ + fc_port_t *fcport = data; + + if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) + return; + + DEBUG2(qla_printk(KERN_INFO, fcport->ha, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", + fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + +static inline void +qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) +{ + fc_port_t *fcport; + struct scsi_device *sdev; + + sdev = sp->cmd->device; + if (sdev->queue_depth >= ha->max_q_depth) + return; + + fcport = sp->fcport; + if (time_before(jiffies, + fcport->last_ramp_up + ql2xqfullrampup * HZ)) + return; + if (time_before(jiffies, + fcport->last_queue_full + ql2xqfullrampup * HZ)) + return; + + spin_unlock_irq(&ha->hardware_lock); + starget_for_each_device(sdev->sdev_target, fcport, + qla2x00_adjust_sdev_qdepth_up); + spin_lock_irq(&ha->hardware_lock); +} + /** * qla2x00_process_completed_request() - Process a Fast Post response. * @ha: SCSI driver HA context @@ -624,6 +687,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) /* Save ISP completion status */ sp->cmd->result = DID_OK << 16; + + qla2x00_ramp_up_queue_depth(ha, sp); qla2x00_sp_compl(ha, sp); } else { DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", @@ -823,6 +888,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) */ switch (comp_status) { case CS_COMPLETE: + case CS_QUEUE_FULL: if (scsi_status == 0) { cp->result = DID_OK << 16; break; @@ -849,6 +915,20 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) } cp->result = DID_OK << 16 | lscsi_status; + if (lscsi_status == SAM_STAT_TASK_SET_FULL) { + DEBUG2(printk(KERN_INFO + "scsi(%ld): QUEUE FULL status detected " + "0x%x-0x%x.\n", ha->host_no, comp_status, + scsi_status)); + + /* Adjust queue depth for all luns on the port. */ + fcport->last_queue_full = jiffies; + spin_unlock_irq(&ha->hardware_lock); + starget_for_each_device(cp->device->sdev_target, + fcport, qla2x00_adjust_sdev_qdepth_down); + spin_lock_irq(&ha->hardware_lock); + break; + } if (lscsi_status != SS_CHECK_CONDITION) break; @@ -1066,17 +1146,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) qla2x00_mark_device_lost(ha, fcport, 1, 1); break; - case CS_QUEUE_FULL: - DEBUG2(printk(KERN_INFO - "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n", - ha->host_no, comp_status, scsi_status)); - - /* SCSI Mid-Layer handles device queue full */ - - cp->result = DID_OK << 16 | lscsi_status; - - break; - default: DEBUG3(printk("scsi(%ld): Error detected (unknown status) " "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 54f561d9c7a..208607be78c 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -77,6 +77,19 @@ MODULE_PARM_DESC(ql2xfdmienable, "Enables FDMI registratons " "Default is 0 - no FDMI. 1 - perfom FDMI."); +#define MAX_Q_DEPTH 32 +static int ql2xmaxqdepth = MAX_Q_DEPTH; +module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(ql2xmaxqdepth, + "Maximum queue depth to report for target devices."); + +int ql2xqfullrampup = 120; +module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(ql2xqfullrampup, + "Number of seconds to wait to begin to ramp-up the queue " + "depth for a device after a queue-full condition has been " + "detected. Default is 120 seconds."); + /* * SCSI host template entry points */ @@ -1104,9 +1117,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev) struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) - scsi_activate_tcq(sdev, 32); + scsi_activate_tcq(sdev, ha->max_q_depth); else - scsi_deactivate_tcq(sdev, 32); + scsi_deactivate_tcq(sdev, ha->max_q_depth); rport->dev_loss_tmo = ha->port_down_retry_count + 5; @@ -1413,6 +1426,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->link_data_rate = PORT_SPEED_UNKNOWN; ha->optrom_size = OPTROM_SIZE_2300; + ha->max_q_depth = MAX_Q_DEPTH; + if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) + ha->max_q_depth = ql2xmaxqdepth; + /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; ha->isp_ops.reset_chip = qla2x00_reset_chip; -- cgit From 7c83a3ceb6d06e7cb908f5102687c9661e7d4d0a Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 13 Oct 2006 09:33:40 -0700 Subject: [SCSI] qla2xxx: Update version number to 8.01.07-k3. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index e57bf45a339..1fa0bce6b24 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k2" +#define QLA2XXX_VERSION "8.01.07-k3" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 -- cgit From 9c3121feef7e1fba86f74b2677e6f54e7153d149 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 13 Oct 2006 10:22:50 -0500 Subject: [SCSI] ibmvscsi: correctly reenable CRQ The "ibmvscsi: treat busy and error conditions separately" patch submitted by Dave Boutcher back in June incorrectly reenables the CRQ. The broken logic causes the adapter to get disabled if the CRQ connection happens to close temporarily. This patch "fixes that obviously wrong logic check" (Dave's words). Signed-off-by: Santiago Leon Signed-off-by: David Boutcher Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 669ea4fff16..fbc1d5c3b0a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1213,7 +1213,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, "ibmvscsi: Re-enabling adapter!\n"); purge_requests(hostdata, DID_REQUEUE); if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, - hostdata) == 0) || + hostdata)) || (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, -- cgit From 3fc2aef5227dda464560a3fdafc9f4c7ce10210f Mon Sep 17 00:00:00 2001 From: Sergey Kononenko Date: Sun, 15 Oct 2006 03:12:08 +0300 Subject: [SCSI] aic94xx: Supermicro motherboards support Add PCI id. Plus correct for possibly missing resistor that can cause FLASHEX to have the wrong value. Signed-off-by: Sergey Kononenko Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_hwi.h | 1 + drivers/scsi/aic94xx/aic94xx_init.c | 2 ++ drivers/scsi/aic94xx/aic94xx_sds.c | 4 ---- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index 14319d1d680..7b6aca02cf7 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h @@ -46,6 +46,7 @@ #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E +#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 99743ca29ca..a4cc432bbda 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -814,6 +814,8 @@ static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { 0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), 0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), + 0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), 0, 0, 2}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 83574b5b4e6..de7c04d4254 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c @@ -630,10 +630,6 @@ static int asd_flash_getid(struct asd_ha_struct *asd_ha) reg = asd_read_reg_dword(asd_ha, EXSICNFGR); - if (!(reg & FLASHEX)) { - ASD_DPRINTK("flash doesn't exist\n"); - return -ENOENT; - } if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, &asd_ha->hw_prof.flash.bar)) { asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", -- cgit From 031280f6e73d9177c93333c96e37eb05f2522faa Mon Sep 17 00:00:00 2001 From: Andrey Mirkin <(amirkin@sw.ru)> Date: Mon, 16 Oct 2006 12:08:43 +0400 Subject: [SCSI] megaraid_{mm,mbox}: 64-bit DMA capability fix It is known that 2 LSI Logic MegaRAID SATA RAID Controllers (150-4 and 150-6) don't support 64-bit DMA. Unfortunately currently this check is wrong and driver sets 64-bit DMA mode for these devices. Signed-off-by: Andrey Mirkin Acked-by: "Ju, Seokmann" Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_mbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index c0edb662d86..7bac86dda88 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -884,7 +884,7 @@ megaraid_init_mbox(adapter_t *adapter) if (((magic64 == HBA_SIGNATURE_64_BIT) && ((adapter->pdev->subsystem_device != - PCI_SUBSYS_ID_MEGARAID_SATA_150_6) || + PCI_SUBSYS_ID_MEGARAID_SATA_150_6) && (adapter->pdev->subsystem_device != PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && -- cgit From ed632da84c51a39fd9c982991e0f26120a035761 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 16 Oct 2006 10:06:27 -0500 Subject: [SCSI] add can_queue to host parameters Debugging TCQ issues has shown me this is a very useful parameter to be able to view. Add it to he host class parameters. Signed-off-by: James Bottomley --- drivers/scsi/scsi_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index e7fe565b96d..e1a91665d1c 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -192,6 +192,7 @@ static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost shost_rd_attr(unique_id, "%u\n"); shost_rd_attr(host_busy, "%hu\n"); shost_rd_attr(cmd_per_lun, "%hd\n"); +shost_rd_attr(can_queue, "%hd\n"); shost_rd_attr(sg_tablesize, "%hu\n"); shost_rd_attr(unchecked_isa_dma, "%d\n"); shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); @@ -200,6 +201,7 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { &class_device_attr_unique_id, &class_device_attr_host_busy, &class_device_attr_cmd_per_lun, + &class_device_attr_can_queue, &class_device_attr_sg_tablesize, &class_device_attr_unchecked_isa_dma, &class_device_attr_proc_name, -- cgit From 47bcd3546d5141e54f15e40a20dc01d7c5f5a473 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 16 Oct 2006 16:55:46 +0100 Subject: [SCSI] Switch fdomain to the pci_get API Doesn't make the hardware hot pluggable but does ensure the driver won't crash when another device is hot-unplugged at the wrong moment. Soon I propose to deprecate pci_find_device() and some of its friends. Signed-off-by: Alan Cox Signed-off-by: James Bottomley --- drivers/scsi/fdomain.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 41b05fc4538..2a964240cf4 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -387,6 +387,7 @@ static void __iomem * bios_mem; static int bios_major; static int bios_minor; static int PCI_bus; +static struct pci_dev *PCI_dev; static int Quantum; /* Quantum board variant */ static int interrupt_level; static volatile int in_command; @@ -812,9 +813,10 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ PCI_DEVICE_ID_FD_36C70 ); #endif - if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) + if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) return 0; - if (pci_enable_device(pdev)) return 0; + if (pci_enable_device(pdev)) + goto fail; #if DEBUG_DETECT printk( "scsi: TMC-3260 detect:" @@ -831,7 +833,7 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ pci_irq = pdev->irq; if (!request_region( pci_base, 0x10, "fdomain" )) - return 0; + goto fail; /* Now we have the I/O base address and interrupt from the PCI configuration registers. */ @@ -848,17 +850,22 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ if (!fdomain_is_valid_port(pci_base)) { printk(KERN_ERR "scsi: PCI card detected, but driver not loaded (invalid port)\n" ); release_region(pci_base, 0x10); - return 0; + goto fail; } /* Fill in a few global variables. Ugh. */ bios_major = bios_minor = -1; PCI_bus = 1; + PCI_dev = pdev; Quantum = 0; bios_base = 0; return 1; +fail: + pci_dev_put(pdev); + return 0; } + #endif struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) @@ -909,8 +916,7 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) if (setup_called) { printk(KERN_ERR "scsi: Bad LILO/INSMOD parameters?\n"); } - release_region(port_base, 0x10); - return NULL; + goto fail; } if (this_id) { @@ -942,8 +948,7 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) /* Log IRQ with kernel */ if (!interrupt_level) { printk(KERN_ERR "scsi: Card Detected, but driver not loaded (no IRQ)\n" ); - release_region(port_base, 0x10); - return NULL; + goto fail; } else { /* Register the IRQ with the kernel */ @@ -964,11 +969,14 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) printk(KERN_ERR " Send mail to faith@acm.org\n" ); } printk(KERN_ERR "scsi: Detected, but driver not loaded (IRQ)\n" ); - release_region(port_base, 0x10); - return NULL; + goto fail; } } return shpnt; +fail: + pci_dev_put(pdev); + release_region(port_base, 0x10); + return NULL; } static int fdomain_16x0_detect(struct scsi_host_template *tpnt) @@ -1714,6 +1722,8 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt) free_irq(shpnt->irq, shpnt); if (shpnt->io_port && shpnt->n_io_port) release_region(shpnt->io_port, shpnt->n_io_port); + if (PCI_bus) + pci_dev_put(PCI_dev); return 0; } -- cgit From 43a145a3440c5c5f24ff2888801e40e2242187e6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:38 -0400 Subject: [SCSI] iscsi class: fix slab corruption during restart The transport class recv mempools are causing slab corruption. We could hack around netlink's lack of mempool support like dm, but it is just too ulgy (dm's hack is ugly enough :) when you need to support broadcast. This patch removes the recv pools. We have not used them even when we were allocting 20 MB per session and the system only had 64 MBs. And we have no pools on the send side and have been ok there. When Peter's work gets merged we can use that since the network guys are in favor of that approach and are not going to add mempools everywhere. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 246 +++--------------------------------- 1 file changed, 17 insertions(+), 229 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 7b0019cccce..2d3baa99ca2 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -21,7 +21,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include #include #include #include @@ -149,30 +148,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, static struct sock *nls; static DEFINE_MUTEX(rx_queue_mutex); -struct mempool_zone { - mempool_t *pool; - atomic_t allocated; - int size; - int hiwat; - struct list_head freequeue; - spinlock_t freelock; -}; - -static struct mempool_zone *z_reply; - -/* - * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time - * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM - * so daemon will notice OOM on NETLINK tranposrt level and will - * be able to predict or change operational behavior - */ -#define Z_MAX_REPLY 8 -#define Z_HIWAT_REPLY 6 -#define Z_MAX_PDU 8 -#define Z_HIWAT_PDU 6 -#define Z_MAX_ERROR 16 -#define Z_HIWAT_ERROR 12 - static LIST_HEAD(sesslist); static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); @@ -414,59 +389,11 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) } EXPORT_SYMBOL_GPL(iscsi_destroy_session); -static void mempool_zone_destroy(struct mempool_zone *zp) -{ - mempool_destroy(zp->pool); - kfree(zp); -} - -static void* -mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) -{ - struct mempool_zone *zone = pool_data; - - return alloc_skb(zone->size, gfp_mask); -} - -static void -mempool_zone_free_skb(void *element, void *pool_data) -{ - kfree_skb(element); -} - -static struct mempool_zone * -mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) -{ - struct mempool_zone *zp; - - zp = kzalloc(sizeof(*zp), GFP_KERNEL); - if (!zp) - return NULL; - - zp->size = size; - zp->hiwat = hiwat; - INIT_LIST_HEAD(&zp->freequeue); - spin_lock_init(&zp->freelock); - atomic_set(&zp->allocated, 0); - - zp->pool = mempool_create(max, mempool_zone_alloc_skb, - mempool_zone_free_skb, zp); - if (!zp->pool) { - kfree(zp); - return NULL; - } - - return zp; -} - static void iscsi_conn_release(struct device *dev) { struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); struct device *parent = conn->dev.parent; - mempool_zone_destroy(conn->z_pdu); - mempool_zone_destroy(conn->z_error); - kfree(conn); put_device(parent); } @@ -476,31 +403,6 @@ static int iscsi_is_conn_dev(const struct device *dev) return dev->release == iscsi_conn_release; } -static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) -{ - conn->z_pdu = mempool_zone_init(Z_MAX_PDU, - NLMSG_SPACE(sizeof(struct iscsi_uevent) + - sizeof(struct iscsi_hdr) + - DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), - Z_HIWAT_PDU); - if (!conn->z_pdu) { - dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " - "pdu zone for new conn\n"); - return -ENOMEM; - } - - conn->z_error = mempool_zone_init(Z_MAX_ERROR, - NLMSG_SPACE(sizeof(struct iscsi_uevent)), - Z_HIWAT_ERROR); - if (!conn->z_error) { - dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " - "error zone for new conn\n"); - mempool_zone_destroy(conn->z_pdu); - return -ENOMEM; - } - return 0; -} - /** * iscsi_create_conn - create iscsi class connection * @session: iscsi cls session @@ -533,12 +435,9 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) conn->transport = transport; conn->cid = cid; - if (iscsi_create_event_pools(conn)) - goto free_conn; - /* this is released in the dev's release function */ if (!get_device(&session->dev)) - goto free_conn_pools; + goto free_conn; snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", session->sid, cid); @@ -555,8 +454,6 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) release_parent_ref: put_device(&session->dev); -free_conn_pools: - free_conn: kfree(conn); return NULL; @@ -599,81 +496,31 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt) return NULL; } -static inline struct list_head *skb_to_lh(struct sk_buff *skb) -{ - return (struct list_head *)&skb->cb; -} - -static void -mempool_zone_complete(struct mempool_zone *zone) -{ - unsigned long flags; - struct list_head *lh, *n; - - spin_lock_irqsave(&zone->freelock, flags); - list_for_each_safe(lh, n, &zone->freequeue) { - struct sk_buff *skb = (struct sk_buff *)((char *)lh - - offsetof(struct sk_buff, cb)); - if (!skb_shared(skb)) { - list_del(skb_to_lh(skb)); - mempool_free(skb, zone->pool); - atomic_dec(&zone->allocated); - } - } - spin_unlock_irqrestore(&zone->freelock, flags); -} - -static struct sk_buff* -mempool_zone_get_skb(struct mempool_zone *zone) -{ - struct sk_buff *skb; - - skb = mempool_alloc(zone->pool, GFP_ATOMIC); - if (skb) - atomic_inc(&zone->allocated); - return skb; -} - static int -iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp) +iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) { - unsigned long flags; int rc; - skb_get(skb); rc = netlink_broadcast(nls, skb, 0, 1, gfp); if (rc < 0) { - mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); return rc; } - spin_lock_irqsave(&zone->freelock, flags); - INIT_LIST_HEAD(skb_to_lh(skb)); - list_add(skb_to_lh(skb), &zone->freequeue); - spin_unlock_irqrestore(&zone->freelock, flags); return 0; } static int -iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) +iscsi_unicast_skb(struct sk_buff *skb, int pid) { - unsigned long flags; int rc; - skb_get(skb); rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); if (rc < 0) { - mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); return rc; } - spin_lock_irqsave(&zone->freelock, flags); - INIT_LIST_HEAD(skb_to_lh(skb)); - list_add(skb_to_lh(skb), &zone->freequeue); - spin_unlock_irqrestore(&zone->freelock, flags); - return 0; } @@ -692,9 +539,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, if (!priv) return -EINVAL; - mempool_zone_complete(conn->z_pdu); - - skb = mempool_zone_get_skb(conn->z_pdu); + skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " @@ -707,15 +552,13 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, memset(ev, 0, sizeof(*ev)); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_RECV_PDU; - if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) - ev->iferror = -ENOMEM; ev->r.recv_req.cid = conn->cid; ev->r.recv_req.sid = iscsi_conn_get_sid(conn); pdu = (char*)ev + sizeof(*ev); memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); - return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid); + return iscsi_unicast_skb(skb, priv->daemon_pid); } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); @@ -731,9 +574,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) if (!priv) return; - mempool_zone_complete(conn->z_error); - - skb = mempool_zone_get_skb(conn->z_error); + skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored " "conn error (%d)\n", error); @@ -744,13 +585,11 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ev = NLMSG_DATA(nlh); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_CONN_ERROR; - if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) - ev->iferror = -ENOMEM; ev->r.connerror.error = error; ev->r.connerror.cid = conn->cid; ev->r.connerror.sid = iscsi_conn_get_sid(conn); - iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC); + iscsi_broadcast_skb(skb, GFP_ATOMIC); dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", error); @@ -767,9 +606,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, int flags = multi ? NLM_F_MULTI : 0; int t = done ? NLMSG_DONE : type; - mempool_zone_complete(z_reply); - - skb = mempool_zone_get_skb(z_reply); + skb = alloc_skb(len, GFP_ATOMIC); /* * FIXME: * user is supposed to react on iferror == -ENOMEM; @@ -780,7 +617,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); nlh->nlmsg_flags = flags; memcpy(NLMSG_DATA(nlh), payload, size); - return iscsi_unicast_skb(z_reply, skb, pid); + return iscsi_unicast_skb(skb, pid); } static int @@ -810,9 +647,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) do { int actual_size; - mempool_zone_complete(conn->z_pdu); - - skbstat = mempool_zone_get_skb(conn->z_pdu); + skbstat = alloc_skb(len, GFP_ATOMIC); if (!skbstat) { dev_printk(KERN_ERR, &conn->dev, "iscsi: can not " "deliver stats: OOM\n"); @@ -825,8 +660,6 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) memset(evstat, 0, sizeof(*evstat)); evstat->transport_handle = iscsi_handle(conn->transport); evstat->type = nlh->nlmsg_type; - if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) - evstat->iferror = -ENOMEM; evstat->u.get_stats.cid = ev->u.get_stats.cid; evstat->u.get_stats.sid = @@ -845,7 +678,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) skb_trim(skbstat, NLMSG_ALIGN(actual_size)); nlhstat->nlmsg_len = actual_size; - err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid); + err = iscsi_unicast_skb(skbstat, priv->daemon_pid); } while (err < 0 && err != -ECONNREFUSED); return err; @@ -876,9 +709,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) session = iscsi_dev_to_session(conn->dev.parent); shost = iscsi_session_to_shost(session); - mempool_zone_complete(conn->z_pdu); - - skb = mempool_zone_get_skb(conn->z_pdu); + skb = alloc_skb(len, GFP_KERNEL); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event\n"); @@ -896,7 +727,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(skb, GFP_KERNEL); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session destruction event. Check iscsi daemon\n"); @@ -939,9 +770,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) session = iscsi_dev_to_session(conn->dev.parent); shost = iscsi_session_to_shost(session); - mempool_zone_complete(conn->z_pdu); - - skb = mempool_zone_get_skb(conn->z_pdu); + skb = alloc_skb(len, GFP_KERNEL); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event\n"); @@ -959,7 +788,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(skb, GFP_KERNEL); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event. Check iscsi daemon\n"); @@ -1278,9 +1107,6 @@ iscsi_if_rx(struct sock *sk, int len) err = iscsi_if_send_reply( NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); - if (atomic_read(&z_reply->allocated) >= - z_reply->hiwat) - ev->iferror = -ENOMEM; } while (err < 0 && err != -ECONNREFUSED); skb_pull(skb, rlen); } @@ -1584,32 +1410,6 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) } EXPORT_SYMBOL_GPL(iscsi_unregister_transport); -static int -iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr) -{ - struct netlink_notify *n = ptr; - - if (event == NETLINK_URELEASE && - n->protocol == NETLINK_ISCSI && n->pid) { - struct iscsi_cls_conn *conn; - unsigned long flags; - - mempool_zone_complete(z_reply); - spin_lock_irqsave(&connlock, flags); - list_for_each_entry(conn, &connlist, conn_list) { - mempool_zone_complete(conn->z_error); - mempool_zone_complete(conn->z_pdu); - } - spin_unlock_irqrestore(&connlock, flags); - } - - return NOTIFY_DONE; -} - -static struct notifier_block iscsi_nl_notifier = { - .notifier_call = iscsi_rcv_nl_event, -}; - static __init int iscsi_transport_init(void) { int err; @@ -1633,25 +1433,15 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_conn_class; - err = netlink_register_notifier(&iscsi_nl_notifier); - if (err) - goto unregister_session_class; - nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, THIS_MODULE); if (!nls) { err = -ENOBUFS; - goto unregister_notifier; + goto unregister_session_class; } - z_reply = mempool_zone_init(Z_MAX_REPLY, - NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY); - if (z_reply) - return 0; + return 0; - sock_release(nls->sk_socket); -unregister_notifier: - netlink_unregister_notifier(&iscsi_nl_notifier); unregister_session_class: transport_class_unregister(&iscsi_session_class); unregister_conn_class: @@ -1665,9 +1455,7 @@ unregister_transport_class: static void __exit iscsi_transport_exit(void) { - mempool_zone_destroy(z_reply); sock_release(nls->sk_socket); - netlink_unregister_notifier(&iscsi_nl_notifier); transport_class_unregister(&iscsi_connection_class); transport_class_unregister(&iscsi_session_class); transport_class_unregister(&iscsi_host_class); -- cgit From 98644047916c24258fb47c3dab2bed8a44f53b83 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:39 -0400 Subject: [SCSI] libiscsi: fix oops in connection create failure path If connection creation fails we end up calling list_del on a invalid struct. This then causes an oops. We are not acutally using the lists (old MCS code we thought might be useful elsewhere) so this patch just removes that code. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c542d0e95e6..1000fe93679 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -778,6 +778,10 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) } conn = session->leadconn; + if (!conn) { + reason = FAILURE_SESSION_FREED; + goto fault; + } if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*))) { @@ -1377,7 +1381,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, } spin_lock_init(&session->lock); - INIT_LIST_HEAD(&session->connections); /* initialize immediate command pool */ if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, @@ -1580,16 +1583,11 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) kfree(conn->persistent_address); __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, sizeof(void*)); - list_del(&conn->item); - if (list_empty(&session->connections)) + if (session->leadconn == conn) { session->leadconn = NULL; - if (session->leadconn && session->leadconn == conn) - session->leadconn = container_of(session->connections.next, - struct iscsi_conn, item); - - if (session->leadconn == NULL) /* no connections exits.. reset sequencing */ session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; + } spin_unlock_bh(&session->lock); kfifo_free(conn->immqueue); @@ -1777,32 +1775,12 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, int is_leading) { struct iscsi_session *session = class_to_transport_session(cls_session); - struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; + struct iscsi_conn *conn = cls_conn->dd_data; - /* lookup for existing connection */ spin_lock_bh(&session->lock); - list_for_each_entry(tmp, &session->connections, item) { - if (tmp == conn) { - if (conn->c_stage != ISCSI_CONN_STOPPED || - conn->stop_stage == STOP_CONN_TERM) { - printk(KERN_ERR "iscsi: can't bind " - "non-stopped connection (%d:%d)\n", - conn->c_stage, conn->stop_stage); - spin_unlock_bh(&session->lock); - return -EIO; - } - break; - } - } - if (tmp != conn) { - /* bind new iSCSI connection to session */ - conn->session = session; - list_add(&conn->item, &session->connections); - } - spin_unlock_bh(&session->lock); - if (is_leading) session->leadconn = conn; + spin_unlock_bh(&session->lock); /* * Unblock xmitworker(), Login Phase will pass through. -- cgit From cd529a46e17b43976d05c1e2ece2676ec7941cc8 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:40 -0400 Subject: [SCSI] libiscsi: fix missed iscsi_task_put in xmit error path from bhalevy@gmail.com: It looks like change 652 to libiscsi.c added some dead code around line 670 if (rc) { spin_unlock_bh(&conn->session->lock); goto again; } since 5 lines above we goto again if (rc). It looks like the previous if (rc) should go away if we want to put the ctask before breaking out of the while loop with "goto again" (see following patch). Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1000fe93679..e3a2ec253cf 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -661,8 +661,6 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) spin_unlock_bh(&conn->session->lock); rc = tt->xmit_cmd_task(conn, conn->ctask); - if (rc) - goto again; spin_lock_bh(&conn->session->lock); __iscsi_put_ctask(conn->ctask); -- cgit From 5831c737f724aa6a655a908d202221f079f30036 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:41 -0400 Subject: [SCSI] libiscsi: fix aen support We have been dropping the pdu. We should just send it to userspace and let it handle it. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index e3a2ec253cf..f5a9560b357 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -481,8 +481,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, break; case ISCSI_OP_ASYNC_EVENT: conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - /* we need sth like iscsi_async_event_rsp() */ - rc = ISCSI_ERR_BAD_OPCODE; + if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) + rc = ISCSI_ERR_CONN_FAILED; break; default: rc = ISCSI_ERR_BAD_OPCODE; -- cgit From b5072ea0910e5c8c79b8313e0ef70ca763983dbf Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:42 -0400 Subject: [SCSI] libiscsi: fix logout pdu processing According to the iscsi RFC, we cannot send other requests if we have sent a logout pdu. This patch enforces this requirement by blocking the session and suspending the send thread. Userspace decides if we restart the connection or if we just free everything. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f5a9560b357..2865ebd557e 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -578,6 +578,27 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); +static int iscsi_xmit_imm_task(struct iscsi_conn *conn) +{ + struct iscsi_hdr *hdr = conn->mtask->hdr; + int rc, was_logout = 0; + + if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) { + conn->session->state = ISCSI_STATE_IN_RECOVERY; + iscsi_block_session(session_to_cls(conn->session)); + was_logout = 1; + } + rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); + if (rc) + return rc; + + if (was_logout) { + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); + return -ENODATA; + } + return 0; +} + /** * iscsi_data_xmit - xmit any command into the scheduled connection * @conn: iscsi connection @@ -623,7 +644,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) conn->ctask = NULL; } if (conn->mtask) { - rc = tt->xmit_mgmt_task(conn, conn->mtask); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; /* done with this in-progress mtask */ @@ -638,7 +659,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = tt->xmit_mgmt_task(conn, conn->mtask); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; } -- cgit From cd00b7f5d814ba87b36371f122ce36ba4a88ba69 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 17 Oct 2006 09:32:06 -0400 Subject: [SCSI] qla1280 bus reset typo Fix typo in check of return value of qla1280_bus_reset() which would result in an adapter reset in addition to the bus reset. Signed-off-by: Jes Sorensen Signed-off-by: James Bottomley --- drivers/scsi/qla1280.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 2521d548dd5..16af5b79e58 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -931,11 +931,10 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) case BUS_RESET: if (qla1280_verbose) - printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " - "DEVICE RESET\n", ha->host_no, bus); - if (qla1280_bus_reset(ha, bus == 0)) + printk(KERN_INFO "qla1280(%ld:%d): Issued bus " + "reset.\n", ha->host_no, bus); + if (qla1280_bus_reset(ha, bus) == 0) result = SUCCESS; - break; case ADAPTER_RESET: -- cgit From 5a09e39810ae0465016c380962e12dd115779b87 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 20 Oct 2006 09:58:47 +0200 Subject: [SCSI] scsi_debug: support REPORT TARGET PORT GROUPS This patch adds support for REPORT TARGET PORT GROUPS. This is used eg for the multipathing priority callout to determine the path priority. With this patch multipath-tools can use the existing mpath_prio_alua callout to exercise the path priority grouping. Signed-off-by: Hannes Reinecke Signed-off-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/scsi_debug.c | 141 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9c0f35820e3..30ee3d72c02 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -52,7 +52,7 @@ #include "scsi_debug.h" #define SCSI_DEBUG_VERSION "1.80" -static const char * scsi_debug_version_date = "20060914"; +static const char * scsi_debug_version_date = "20061018"; /* Additional Sense Code (ASC) used */ #define NO_ADDITIONAL_SENSE 0x0 @@ -254,6 +254,8 @@ static int resp_requests(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); static int resp_start_stop(struct scsi_cmnd * scp, struct sdebug_dev_info * devip); +static int resp_report_tgtpgs(struct scsi_cmnd * scp, + struct sdebug_dev_info * devip); static int resp_readcap(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); static int resp_readcap16(struct scsi_cmnd * SCpnt, @@ -287,9 +289,9 @@ static void __init sdebug_build_parts(unsigned char * ramp); static void __init init_all_queued(void); static void stop_all_queued(void); static int stop_queued_cmnd(struct scsi_cmnd * cmnd); -static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, - int dev_id_num, const char * dev_id_str, - int dev_id_str_len); +static int inquiry_evpd_83(unsigned char * arr, int port_group_id, + int target_dev_id, int dev_id_num, + const char * dev_id_str, int dev_id_str_len); static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); static int do_create_driverfs_files(void); static void do_remove_driverfs_files(void); @@ -422,6 +424,15 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) } errsts = resp_readcap16(SCpnt, devip); break; + case MAINTENANCE_IN: + if (MI_REPORT_TARGET_PGS != cmd[1]) { + mk_sense_buffer(devip, ILLEGAL_REQUEST, + INVALID_OPCODE, 0); + errsts = check_condition_result; + break; + } + errsts = resp_report_tgtpgs(SCpnt, devip); + break; case READ_16: case READ_12: case READ_10: @@ -665,8 +676,9 @@ static const char * inq_vendor_id = "Linux "; static const char * inq_product_id = "scsi_debug "; static const char * inq_product_rev = "0004"; -static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, - int dev_id_num, const char * dev_id_str, +static int inquiry_evpd_83(unsigned char * arr, int port_group_id, + int target_dev_id, int dev_id_num, + const char * dev_id_str, int dev_id_str_len) { int num, port_a; @@ -720,6 +732,15 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, arr[num++] = (port_a >> 16) & 0xff; arr[num++] = (port_a >> 8) & 0xff; arr[num++] = port_a & 0xff; + /* NAA-5, Target port group identifier */ + arr[num++] = 0x61; /* proto=sas, binary */ + arr[num++] = 0x95; /* piv=1, target port group id */ + arr[num++] = 0x0; + arr[num++] = 0x4; + arr[num++] = 0; + arr[num++] = 0; + arr[num++] = (port_group_id >> 8) & 0xff; + arr[num++] = port_group_id & 0xff; /* NAA-5, Target device identifier */ arr[num++] = 0x61; /* proto=sas, binary */ arr[num++] = 0xa3; /* piv=1, target device, naa */ @@ -928,12 +949,12 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, struct sdebug_dev_info * devip) { unsigned char pq_pdt; - unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; + unsigned char * arr; unsigned char *cmd = (unsigned char *)scp->cmnd; - int alloc_len, n; + int alloc_len, n, ret; alloc_len = (cmd[3] << 8) + cmd[4]; - memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); + arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL); if (devip->wlun) pq_pdt = 0x1e; /* present, wlun */ else if (scsi_debug_no_lun_0 && (0 == devip->lun)) @@ -944,12 +965,15 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, if (0x2 & cmd[1]) { /* CMDDT bit set */ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + kfree(arr); return check_condition_result; } else if (0x1 & cmd[1]) { /* EVPD bit set */ - int lu_id_num, target_dev_id, len; + int lu_id_num, port_group_id, target_dev_id, len; char lu_id_str[6]; int host_no = devip->sdbg_host->shost->host_no; + port_group_id = (((host_no + 1) & 0x7f) << 8) + + (devip->channel & 0x7f); if (0 == scsi_debug_vpd_use_hostno) host_no = 0; lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + @@ -977,8 +1001,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, memcpy(&arr[4], lu_id_str, len); } else if (0x83 == cmd[2]) { /* device identification */ arr[1] = cmd[2]; /*sanity */ - arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, - lu_id_num, lu_id_str, len); + arr[3] = inquiry_evpd_83(&arr[4], port_group_id, + target_dev_id, lu_id_num, + lu_id_str, len); } else if (0x84 == cmd[2]) { /* Software interface ident. */ arr[1] = cmd[2]; /*sanity */ arr[3] = inquiry_evpd_84(&arr[4]); @@ -1012,17 +1037,22 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, /* Illegal request, invalid field in cdb */ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + kfree(arr); return check_condition_result; } len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); - return fill_from_dev_buffer(scp, arr, + ret = fill_from_dev_buffer(scp, arr, min(len, SDEBUG_MAX_INQ_ARR_SZ)); + kfree(arr); + return ret; } /* drops through here for a standard inquiry */ arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ arr[2] = scsi_debug_scsi_level; arr[3] = 2; /* response_data_format==2 */ arr[4] = SDEBUG_LONG_INQ_SZ - 5; + if (0 == scsi_debug_vpd_use_hostno) + arr[5] = 0x10; /* claim: implicit TGPS */ arr[6] = 0x10; /* claim: MultiP */ /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ arr[7] = 0xa; /* claim: LINKED + CMDQUE */ @@ -1039,8 +1069,10 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ } arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ - return fill_from_dev_buffer(scp, arr, + ret = fill_from_dev_buffer(scp, arr, min(alloc_len, SDEBUG_LONG_INQ_SZ)); + kfree(arr); + return ret; } static int resp_requests(struct scsi_cmnd * scp, @@ -1171,6 +1203,87 @@ static int resp_readcap16(struct scsi_cmnd * scp, min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); } +#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 + +static int resp_report_tgtpgs(struct scsi_cmnd * scp, + struct sdebug_dev_info * devip) +{ + unsigned char *cmd = (unsigned char *)scp->cmnd; + unsigned char * arr; + int host_no = devip->sdbg_host->shost->host_no; + int n, ret, alen, rlen; + int port_group_a, port_group_b, port_a, port_b; + + alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) + + cmd[9]); + + arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL); + /* + * EVPD page 0x88 states we have two ports, one + * real and a fake port with no device connected. + * So we create two port groups with one port each + * and set the group with port B to unavailable. + */ + port_a = 0x1; /* relative port A */ + port_b = 0x2; /* relative port B */ + port_group_a = (((host_no + 1) & 0x7f) << 8) + + (devip->channel & 0x7f); + port_group_b = (((host_no + 1) & 0x7f) << 8) + + (devip->channel & 0x7f) + 0x80; + + /* + * The asymmetric access state is cycled according to the host_id. + */ + n = 4; + if (0 == scsi_debug_vpd_use_hostno) { + arr[n++] = host_no % 3; /* Asymm access state */ + arr[n++] = 0x0F; /* claim: all states are supported */ + } else { + arr[n++] = 0x0; /* Active/Optimized path */ + arr[n++] = 0x01; /* claim: only support active/optimized paths */ + } + arr[n++] = (port_group_a >> 8) & 0xff; + arr[n++] = port_group_a & 0xff; + arr[n++] = 0; /* Reserved */ + arr[n++] = 0; /* Status code */ + arr[n++] = 0; /* Vendor unique */ + arr[n++] = 0x1; /* One port per group */ + arr[n++] = 0; /* Reserved */ + arr[n++] = 0; /* Reserved */ + arr[n++] = (port_a >> 8) & 0xff; + arr[n++] = port_a & 0xff; + arr[n++] = 3; /* Port unavailable */ + arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */ + arr[n++] = (port_group_b >> 8) & 0xff; + arr[n++] = port_group_b & 0xff; + arr[n++] = 0; /* Reserved */ + arr[n++] = 0; /* Status code */ + arr[n++] = 0; /* Vendor unique */ + arr[n++] = 0x1; /* One port per group */ + arr[n++] = 0; /* Reserved */ + arr[n++] = 0; /* Reserved */ + arr[n++] = (port_b >> 8) & 0xff; + arr[n++] = port_b & 0xff; + + rlen = n - 4; + arr[0] = (rlen >> 24) & 0xff; + arr[1] = (rlen >> 16) & 0xff; + arr[2] = (rlen >> 8) & 0xff; + arr[3] = rlen & 0xff; + + /* + * Return the smallest value of either + * - The allocated length + * - The constructed command length + * - The maximum array size + */ + rlen = min(alen,n); + ret = fill_from_dev_buffer(scp, arr, + min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); + kfree(arr); + return ret; +} + /* <> */ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) -- cgit From 6d07cb71fdacc710fd9816cddb5c2df0f7bd96b4 Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Fri, 20 Oct 2006 14:48:40 -0700 Subject: [SCSI] drivers/scsi: Handcrafted MIN/MAX macro removal Cleanups done to use min/max macros from kernel.h. Handcrafted MIN/MAX macros are changed to use macros in kernel.h [akpm@osdl.org: fix warning] Signed-off-by: Amol Lad Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx.h | 8 -------- drivers/scsi/aic7xxx/aic79xx_core.c | 22 +++++++++++----------- drivers/scsi/aic7xxx/aic79xx_osm.c | 7 ++++--- drivers/scsi/aic7xxx/aic7xxx.h | 8 -------- drivers/scsi/aic7xxx/aic7xxx_core.c | 18 +++++++++--------- drivers/scsi/aic7xxx/aic7xxx_osm.c | 4 ++-- 6 files changed, 26 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index df3346b5caf..c58ac6a8730 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -53,14 +53,6 @@ struct ahd_platform_data; struct scb_platform_data; /****************************** Useful Macros *********************************/ -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - #ifndef TRUE #define TRUE 1 #endif diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 653818d2f80..6adcf7989ce 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -2850,14 +2850,14 @@ ahd_devlimited_syncrate(struct ahd_softc *ahd, transinfo = &tinfo->goal; *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { - maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); + maxsync = max(maxsync, (u_int)AHD_SYNCRATE_ULTRA2); *ppr_options &= ~MSG_EXT_PPR_DT_REQ; } if (transinfo->period == 0) { *period = 0; *ppr_options = 0; } else { - *period = MAX(*period, transinfo->period); + *period = max(*period, (u_int)transinfo->period); ahd_find_syncrate(ahd, period, ppr_options, maxsync); } } @@ -2924,12 +2924,12 @@ ahd_validate_offset(struct ahd_softc *ahd, maxoffset = MAX_OFFSET_PACED; } else maxoffset = MAX_OFFSET_NON_PACED; - *offset = MIN(*offset, maxoffset); + *offset = min(*offset, maxoffset); if (tinfo != NULL) { if (role == ROLE_TARGET) - *offset = MIN(*offset, tinfo->user.offset); + *offset = min(*offset, (u_int)tinfo->user.offset); else - *offset = MIN(*offset, tinfo->goal.offset); + *offset = min(*offset, (u_int)tinfo->goal.offset); } } @@ -2955,9 +2955,9 @@ ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, } if (tinfo != NULL) { if (role == ROLE_TARGET) - *bus_width = MIN(tinfo->user.width, *bus_width); + *bus_width = min((u_int)tinfo->user.width, *bus_width); else - *bus_width = MIN(tinfo->goal.width, *bus_width); + *bus_width = min((u_int)tinfo->goal.width, *bus_width); } } @@ -6057,9 +6057,9 @@ ahd_alloc_scbs(struct ahd_softc *ahd) #endif } - newcount = MIN(scb_data->sense_left, scb_data->scbs_left); - newcount = MIN(newcount, scb_data->sgs_left); - newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); + newcount = min(scb_data->sense_left, scb_data->scbs_left); + newcount = min(newcount, scb_data->sgs_left); + newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata; u_int col_tag; @@ -8668,7 +8668,7 @@ ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) if (skip_addr > i) { int end_addr; - end_addr = MIN(address, skip_addr); + end_addr = min(address, skip_addr); address_offset += end_addr - i; i = skip_addr; } else { diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index d8d6687e20a..77ef4d9b0e5 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1814,9 +1814,9 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, u_int sense_offset; if (scb->flags & SCB_SENSE) { - sense_size = MIN(sizeof(struct scsi_sense_data) + sense_size = min(sizeof(struct scsi_sense_data) - ahd_get_sense_residual(scb), - sizeof(cmd->sense_buffer)); + (u_long)sizeof(cmd->sense_buffer)); sense_offset = 0; } else { /* @@ -1825,7 +1825,8 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, */ siu = (struct scsi_status_iu_header *) scb->sense_data; - sense_size = MIN(scsi_4btoul(siu->sense_length), + sense_size = min_t(size_t, + scsi_4btoul(siu->sense_length), sizeof(cmd->sense_buffer)); sense_offset = SIU_SENSE_OFFSET(siu); } diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index 62ff8c3dc2b..4850820816e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h @@ -54,14 +54,6 @@ struct scb_platform_data; struct seeprom_descriptor; /****************************** Useful Macros *********************************/ -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - #ifndef TRUE #define TRUE 1 #endif diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 93e4e40944b..46bd7bc2fa4 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1671,7 +1671,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, transinfo = &tinfo->goal; *ppr_options &= transinfo->ppr_options; if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { - maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2); + maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2); *ppr_options &= ~MSG_EXT_PPR_DT_REQ; } if (transinfo->period == 0) { @@ -1679,7 +1679,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, *ppr_options = 0; return (NULL); } - *period = MAX(*period, transinfo->period); + *period = max(*period, (u_int)transinfo->period); return (ahc_find_syncrate(ahc, period, ppr_options, maxsync)); } @@ -1804,12 +1804,12 @@ ahc_validate_offset(struct ahc_softc *ahc, else maxoffset = MAX_OFFSET_8BIT; } - *offset = MIN(*offset, maxoffset); + *offset = min(*offset, maxoffset); if (tinfo != NULL) { if (role == ROLE_TARGET) - *offset = MIN(*offset, tinfo->user.offset); + *offset = min(*offset, (u_int)tinfo->user.offset); else - *offset = MIN(*offset, tinfo->goal.offset); + *offset = min(*offset, (u_int)tinfo->goal.offset); } } @@ -1835,9 +1835,9 @@ ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo, } if (tinfo != NULL) { if (role == ROLE_TARGET) - *bus_width = MIN(tinfo->user.width, *bus_width); + *bus_width = min((u_int)tinfo->user.width, *bus_width); else - *bus_width = MIN(tinfo->goal.width, *bus_width); + *bus_width = min((u_int)tinfo->goal.width, *bus_width); } } @@ -4406,7 +4406,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc) physaddr = sg_map->sg_physaddr; newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg))); - newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); + newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata; #ifndef __linux__ @@ -6442,7 +6442,7 @@ ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts) if (skip_addr > i) { int end_addr; - end_addr = MIN(address, skip_addr); + end_addr = min(address, skip_addr); address_offset += end_addr - i; i = skip_addr; } else { diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index ad8578e9593..8eb1211a788 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1876,9 +1876,9 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, if (scb->flags & SCB_SENSE) { u_int sense_size; - sense_size = MIN(sizeof(struct scsi_sense_data) + sense_size = min(sizeof(struct scsi_sense_data) - ahc_get_sense_residual(scb), - sizeof(cmd->sense_buffer)); + (u_long)sizeof(cmd->sense_buffer)); memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb), sense_size); if (sense_size < sizeof(cmd->sense_buffer)) -- cgit From 289fe5b1f99c5e61ed32796cbed0a1ecc3589041 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 20 Oct 2006 14:47:57 -0700 Subject: [SCSI] aic7xxx: cleanups - make needlessly global code static - #if 0 the following unused global functions: - aic79xx_core.c: ahd_print_scb - aic79xx_core.c: ahd_suspend - aic79xx_core.c: ahd_resume - aic79xx_core.c: ahd_dump_scbs - aic79xx_osm.c: ahd_softc_comp Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Acked-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx.h | 53 ------- drivers/scsi/aic7xxx/aic79xx_core.c | 260 +++++++++++++++++++++------------ drivers/scsi/aic7xxx/aic79xx_inline.h | 30 ---- drivers/scsi/aic7xxx/aic79xx_osm.c | 2 +- drivers/scsi/aic7xxx/aic79xx_osm.h | 5 - drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 2 +- drivers/scsi/aic7xxx/aic79xx_pci.c | 7 +- drivers/scsi/aic7xxx/aic79xx_proc.c | 2 +- drivers/scsi/aic7xxx/aic7xxx.h | 2 - drivers/scsi/aic7xxx/aic7xxx_osm.c | 2 +- drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 - drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 2 +- drivers/scsi/aic7xxx/aic7xxx_pci.c | 4 +- 13 files changed, 175 insertions(+), 198 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index c58ac6a8730..b19a07cb2ab 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -964,8 +964,6 @@ int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, u_int start_addr, u_int count); -int ahd_wait_seeprom(struct ahd_softc *ahd); -int ahd_verify_vpd_cksum(struct vpd_config *vpd); int ahd_verify_cksum(struct seeprom_config *sc); int ahd_acquire_seeprom(struct ahd_softc *ahd); void ahd_release_seeprom(struct ahd_softc *ahd); @@ -1312,8 +1310,6 @@ struct ahd_pci_identity { char *name; ahd_device_setup_t *setup; }; -extern struct ahd_pci_identity ahd_pci_ident_table []; -extern const u_int ahd_num_pci_devs; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { @@ -1331,15 +1327,6 @@ extern const int ahd_num_aic7770_devs; /*************************** Function Declarations ****************************/ /******************************************************************************/ void ahd_reset_cmds_pending(struct ahd_softc *ahd); -u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); -void ahd_busy_tcl(struct ahd_softc *ahd, - u_int tcl, u_int busyid); -static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); -static __inline void -ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) -{ - ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); -} /***************************** PCI Front End *********************************/ struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); @@ -1348,7 +1335,6 @@ int ahd_pci_config(struct ahd_softc *, int ahd_pci_test_register_access(struct ahd_softc *); /************************** SCB and SCB queue management **********************/ -int ahd_probe_scbs(struct ahd_softc *); void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb); int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, @@ -1366,33 +1352,20 @@ int ahd_parse_vpddata(struct ahd_softc *ahd, int ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc); void ahd_intr_enable(struct ahd_softc *ahd, int enable); -void ahd_update_coalescing_values(struct ahd_softc *ahd, - u_int timer, - u_int maxcmds, - u_int mincmds); -void ahd_enable_coalescing(struct ahd_softc *ahd, - int enable); void ahd_pause_and_flushwork(struct ahd_softc *ahd); int ahd_suspend(struct ahd_softc *ahd); -int ahd_resume(struct ahd_softc *ahd); void ahd_set_unit(struct ahd_softc *, int); void ahd_set_name(struct ahd_softc *, char *); struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); -void ahd_alloc_scbs(struct ahd_softc *ahd); void ahd_free(struct ahd_softc *ahd); int ahd_reset(struct ahd_softc *ahd, int reinit); -void ahd_shutdown(void *arg); int ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value); int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value); -int ahd_wait_flexport(struct ahd_softc *ahd); /*************************** Interrupt Services *******************************/ -void ahd_pci_intr(struct ahd_softc *ahd); -void ahd_clear_intstat(struct ahd_softc *ahd); -void ahd_flush_qoutfifo(struct ahd_softc *ahd); void ahd_run_qoutfifo(struct ahd_softc *ahd); #ifdef AHD_TARGET_MODE void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); @@ -1401,7 +1374,6 @@ void ahd_handle_hwerrint(struct ahd_softc *ahd); void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); void ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat); -void ahd_clear_critical_section(struct ahd_softc *ahd); /***************************** Error Recovery *********************************/ typedef enum { @@ -1418,23 +1390,9 @@ int ahd_search_disc_list(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, int stop_on_first, int remove, int save_state); -void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); int ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset); -int ahd_abort_scbs(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status); -void ahd_restart(struct ahd_softc *ahd); -void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); -void ahd_handle_scb_status(struct ahd_softc *ahd, - struct scb *scb); -void ahd_handle_scsi_status(struct ahd_softc *ahd, - struct scb *scb); -void ahd_calc_residual(struct ahd_softc *ahd, - struct scb *scb); /*************************** Utility Functions ********************************/ -struct ahd_phase_table_entry* - ahd_lookup_phase_entry(int phase); void ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target, u_int lun, char channel, @@ -1442,14 +1400,6 @@ void ahd_compile_devinfo(struct ahd_devinfo *devinfo, /************************** Transfer Negotiation ******************************/ void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, u_int *ppr_options, u_int maxsync); -void ahd_validate_offset(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int period, u_int *offset, - int wide, role_t role); -void ahd_validate_width(struct ahd_softc *ahd, - struct ahd_initiator_tinfo *tinfo, - u_int *bus_width, - role_t role); /* * Negotiation types. These are used to qualify if we should renegotiate * even if our goal and current transport parameters are identical. @@ -1520,10 +1470,8 @@ extern uint32_t ahd_debug; #define AHD_SHOW_INT_COALESCING 0x10000 #define AHD_DEBUG_SEQUENCER 0x20000 #endif -void ahd_print_scb(struct scb *scb); void ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo); -void ahd_dump_sglist(struct scb *scb); void ahd_dump_card_state(struct ahd_softc *ahd); int ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, @@ -1532,5 +1480,4 @@ int ahd_print_register(ahd_reg_parse_entry_t *table, u_int value, u_int *cur_column, u_int wrap_point); -void ahd_dump_scbs(struct ahd_softc *ahd); #endif /* _AIC79XX_H_ */ diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 6adcf7989ce..7d53c6456d0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -52,7 +52,7 @@ /***************************** Lookup Tables **********************************/ -char *ahd_chip_names[] = +static char *ahd_chip_names[] = { "NONE", "aic7901", @@ -237,10 +237,33 @@ static int ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd); #endif +static int ahd_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +static void ahd_alloc_scbs(struct ahd_softc *ahd); +static void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, + u_int scbid); +static void ahd_calc_residual(struct ahd_softc *ahd, + struct scb *scb); +static void ahd_clear_critical_section(struct ahd_softc *ahd); +static void ahd_clear_intstat(struct ahd_softc *ahd); +static void ahd_enable_coalescing(struct ahd_softc *ahd, + int enable); +static u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); +static void ahd_freeze_devq(struct ahd_softc *ahd, + struct scb *scb); +static void ahd_handle_scb_status(struct ahd_softc *ahd, + struct scb *scb); +static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase); +static void ahd_shutdown(void *arg); +static void ahd_update_coalescing_values(struct ahd_softc *ahd, + u_int timer, + u_int maxcmds, + u_int mincmds); +static int ahd_verify_vpd_cksum(struct vpd_config *vpd); +static int ahd_wait_seeprom(struct ahd_softc *ahd); + /******************************** Private Inlines *****************************/ -static __inline void ahd_assert_atn(struct ahd_softc *ahd); -static __inline int ahd_currently_packetized(struct ahd_softc *ahd); -static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); static __inline void ahd_assert_atn(struct ahd_softc *ahd) @@ -294,11 +317,44 @@ ahd_set_active_fifo(struct ahd_softc *ahd) } } +static __inline void +ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); +} + +/* + * Determine whether the sequencer reported a residual + * for this SCB/transaction. + */ +static __inline void +ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_calc_residual(ahd, scb); +} + +static __inline void +ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_handle_scb_status(ahd, scb); + else + ahd_done(ahd, scb); +} + + /************************* Sequencer Execution Control ************************/ /* * Restart the sequencer program from address zero */ -void +static void ahd_restart(struct ahd_softc *ahd) { @@ -342,7 +398,7 @@ ahd_restart(struct ahd_softc *ahd) ahd_unpause(ahd); } -void +static void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) { ahd_mode_state saved_modes; @@ -366,7 +422,7 @@ ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) * Flush and completed commands that are sitting in the command * complete queues down on the chip but have yet to be dma'ed back up. */ -void +static void ahd_flush_qoutfifo(struct ahd_softc *ahd) { struct scb *scb; @@ -905,6 +961,51 @@ ahd_handle_hwerrint(struct ahd_softc *ahd) ahd_free(ahd); } +#ifdef AHD_DEBUG +static void +ahd_dump_sglist(struct scb *scb) +{ + int i; + + if (scb->sg_count > 0) { + if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg_list; + + sg_list = (struct ahd_dma64_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint64_t addr; + uint32_t len; + + addr = ahd_le64toh(sg_list[i].addr); + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (uint32_t)((addr >> 32) & 0xFFFFFFFF), + (uint32_t)(addr & 0xFFFFFFFF), + sg_list[i].len & AHD_SG_LEN_MASK, + (sg_list[i].len & AHD_DMA_LAST_SEG) + ? " Last" : ""); + } + } else { + struct ahd_dma_seg *sg_list; + + sg_list = (struct ahd_dma_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint32_t len; + + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (len & AHD_SG_HIGH_ADDR_MASK) >> 24, + ahd_le32toh(sg_list[i].addr), + len & AHD_SG_LEN_MASK, + len & AHD_DMA_LAST_SEG ? " Last" : ""); + } + } + } +} +#endif /* AHD_DEBUG */ + void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) { @@ -2523,7 +2624,7 @@ ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) } #define AHD_MAX_STEPS 2000 -void +static void ahd_clear_critical_section(struct ahd_softc *ahd) { ahd_mode_state saved_modes; @@ -2646,7 +2747,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) /* * Clear any pending interrupt status. */ -void +static void ahd_clear_intstat(struct ahd_softc *ahd) { AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), @@ -2677,6 +2778,8 @@ ahd_clear_intstat(struct ahd_softc *ahd) #ifdef AHD_DEBUG uint32_t ahd_debug = AHD_DEBUG_OPTS; #endif + +#if 0 void ahd_print_scb(struct scb *scb) { @@ -2701,49 +2804,7 @@ ahd_print_scb(struct scb *scb) SCB_GET_TAG(scb)); ahd_dump_sglist(scb); } - -void -ahd_dump_sglist(struct scb *scb) -{ - int i; - - if (scb->sg_count > 0) { - if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg_list; - - sg_list = (struct ahd_dma64_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint64_t addr; - uint32_t len; - - addr = ahd_le64toh(sg_list[i].addr); - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (uint32_t)((addr >> 32) & 0xFFFFFFFF), - (uint32_t)(addr & 0xFFFFFFFF), - sg_list[i].len & AHD_SG_LEN_MASK, - (sg_list[i].len & AHD_DMA_LAST_SEG) - ? " Last" : ""); - } - } else { - struct ahd_dma_seg *sg_list; - - sg_list = (struct ahd_dma_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint32_t len; - - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (len & AHD_SG_HIGH_ADDR_MASK) >> 24, - ahd_le32toh(sg_list[i].addr), - len & AHD_SG_LEN_MASK, - len & AHD_DMA_LAST_SEG ? " Last" : ""); - } - } - } -} +#endif /* 0 */ /************************* Transfer Negotiation *******************************/ /* @@ -2906,7 +2967,7 @@ ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, * Truncate the given synchronous offset to a value the * current adapter type and syncrate are capable of. */ -void +static void ahd_validate_offset(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, u_int period, u_int *offset, int wide, @@ -2937,7 +2998,7 @@ ahd_validate_offset(struct ahd_softc *ahd, * Truncate the given transfer width parameter to a value the * current adapter type is capable of. */ -void +static void ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, u_int *bus_width, role_t role) { @@ -3466,7 +3527,7 @@ ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) devinfo->target, devinfo->lun); } -struct ahd_phase_table_entry* +static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase) { struct ahd_phase_table_entry *entry; @@ -5351,7 +5412,7 @@ ahd_free(struct ahd_softc *ahd) return; } -void +static void ahd_shutdown(void *arg) { struct ahd_softc *ahd; @@ -5480,7 +5541,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit) /* * Determine the number of SCBs available on the controller */ -int +static int ahd_probe_scbs(struct ahd_softc *ahd) { int i; @@ -5929,7 +5990,7 @@ ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) ahd_platform_scb_free(ahd, scb); } -void +static void ahd_alloc_scbs(struct ahd_softc *ahd) { struct scb_data *scb_data; @@ -6982,7 +7043,7 @@ ahd_intr_enable(struct ahd_softc *ahd, int enable) ahd_outb(ahd, HCNTRL, hcntrl); } -void +static void ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, u_int mincmds) { @@ -7000,7 +7061,7 @@ ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds); } -void +static void ahd_enable_coalescing(struct ahd_softc *ahd, int enable) { @@ -7070,6 +7131,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) ahd->flags &= ~AHD_ALL_INTERRUPTS; } +#if 0 int ahd_suspend(struct ahd_softc *ahd) { @@ -7083,7 +7145,9 @@ ahd_suspend(struct ahd_softc *ahd) ahd_shutdown(ahd); return (0); } +#endif /* 0 */ +#if 0 int ahd_resume(struct ahd_softc *ahd) { @@ -7093,6 +7157,7 @@ ahd_resume(struct ahd_softc *ahd) ahd_restart(ahd); return (0); } +#endif /* 0 */ /************************** Busy Target Table *********************************/ /* @@ -7125,7 +7190,7 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) /* * Return the untagged transaction id for a given target/channel lun. */ -u_int +static u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) { u_int scbid; @@ -7138,7 +7203,7 @@ ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) return (scbid); } -void +static void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) { u_int scb_offset; @@ -7186,7 +7251,7 @@ ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, return match; } -void +static void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) { int target; @@ -7690,7 +7755,7 @@ ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer * is paused before it is called. */ -int +static int ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status) { @@ -8019,18 +8084,8 @@ ahd_stat_timer(void *arg) } /****************************** Status Processing *****************************/ -void -ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) -{ - if (scb->hscb->shared_data.istatus.scsi_status != 0) { - ahd_handle_scsi_status(ahd, scb); - } else { - ahd_calc_residual(ahd, scb); - ahd_done(ahd, scb); - } -} -void +static void ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) { struct hardware_scb *hscb; @@ -8238,10 +8293,21 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) } } +static void +ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) +{ + if (scb->hscb->shared_data.istatus.scsi_status != 0) { + ahd_handle_scsi_status(ahd, scb); + } else { + ahd_calc_residual(ahd, scb); + ahd_done(ahd, scb); + } +} + /* * Calculate the residual for a just completed SCB. */ -void +static void ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) { struct hardware_scb *hscb; @@ -9092,6 +9158,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) ahd_unpause(ahd); } +#if 0 void ahd_dump_scbs(struct ahd_softc *ahd) { @@ -9117,6 +9184,7 @@ ahd_dump_scbs(struct ahd_softc *ahd) ahd_set_scbptr(ahd, saved_scb_index); ahd_restore_modes(ahd, saved_modes); } +#endif /* 0 */ /**************************** Flexport Logic **********************************/ /* @@ -9219,7 +9287,7 @@ ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, /* * Wait ~100us for the serial eeprom to satisfy our request. */ -int +static int ahd_wait_seeprom(struct ahd_softc *ahd) { int cnt; @@ -9237,7 +9305,7 @@ ahd_wait_seeprom(struct ahd_softc *ahd) * Validate the two checksums in the per_channel * vital product data struct. */ -int +static int ahd_verify_vpd_cksum(struct vpd_config *vpd) { int i; @@ -9316,6 +9384,24 @@ ahd_release_seeprom(struct ahd_softc *ahd) /* Currently a no-op */ } +/* + * Wait at most 2 seconds for flexport arbitration to succeed. + */ +static int +ahd_wait_flexport(struct ahd_softc *ahd) +{ + int cnt; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + cnt = 1000000 * 2 / 5; + while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + int ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) { @@ -9357,24 +9443,6 @@ ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) return (0); } -/* - * Wait at most 2 seconds for flexport arbitration to succeed. - */ -int -ahd_wait_flexport(struct ahd_softc *ahd) -{ - int cnt; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - cnt = 1000000 * 2 / 5; - while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) - ahd_delay(5); - - if (cnt == 0) - return (ETIMEDOUT); - return (0); -} - /************************* Target Mode ****************************************/ #ifdef AHD_TARGET_MODE cam_status diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h index a3266e066c0..2ceb67f4af2 100644 --- a/drivers/scsi/aic7xxx/aic79xx_inline.h +++ b/drivers/scsi/aic7xxx/aic79xx_inline.h @@ -418,10 +418,6 @@ ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) } /*********************** Miscelaneous Support Functions ***********************/ -static __inline void ahd_complete_scb(struct ahd_softc *ahd, - struct scb *scb); -static __inline void ahd_update_residual(struct ahd_softc *ahd, - struct scb *scb); static __inline struct ahd_initiator_tinfo * ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, @@ -467,32 +463,6 @@ static __inline uint32_t ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb); -static __inline void -ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_handle_scb_status(ahd, scb); - else - ahd_done(ahd, scb); -} - -/* - * Determine whether the sequencer reported a residual - * for this SCB/transaction. - */ -static __inline void -ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_calc_residual(ahd, scb); -} - /* * Return pointers to the transfer negotiation information * for the specified our_id/remote_id pair. diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 77ef4d9b0e5..5e13046d845 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -293,7 +293,7 @@ static uint32_t aic79xx_seltime; * force all outstanding transactions to be serviced prior to a new * transaction. */ -uint32_t aic79xx_periodic_otag; +static uint32_t aic79xx_periodic_otag; /* Some storage boxes are using an LSI chip which has a bug making it * impossible to use aic79xx Rev B chip in 320 speeds. The following diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index fb3d4dd5441..3a67fc578d7 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -506,9 +506,6 @@ struct info_str { int pos; }; -void ahd_format_transinfo(struct info_str *info, - struct ahd_transinfo *tinfo); - /******************************** Locking *************************************/ static __inline void ahd_lockinit(struct ahd_softc *ahd) @@ -582,8 +579,6 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ -extern struct pci_driver aic79xx_pci_driver; - typedef enum { AHD_POWER_STATE_D0, diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 4b535420180..2001fe890e7 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -82,7 +82,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); -struct pci_driver aic79xx_pci_driver = { +static struct pci_driver aic79xx_pci_driver = { .name = "aic79xx", .probe = ahd_linux_pci_dev_probe, .remove = ahd_linux_pci_dev_remove, diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 14850f31aaf..c07735819cd 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c @@ -97,7 +97,7 @@ static ahd_device_setup_t ahd_aic7901A_setup; static ahd_device_setup_t ahd_aic7902_setup; static ahd_device_setup_t ahd_aic790X_setup; -struct ahd_pci_identity ahd_pci_ident_table [] = +static struct ahd_pci_identity ahd_pci_ident_table [] = { /* aic7901 based controllers */ { @@ -201,7 +201,7 @@ struct ahd_pci_identity ahd_pci_ident_table [] = } }; -const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); +static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); #define DEVCONFIG 0x40 #define PCIXINITPAT 0x0000E000ul @@ -245,6 +245,7 @@ static int ahd_check_extport(struct ahd_softc *ahd); static void ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control); static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); +static void ahd_pci_intr(struct ahd_softc *ahd); struct ahd_pci_identity * ahd_find_pci_device(ahd_dev_softc_t pci) @@ -757,7 +758,7 @@ static const char *pci_status_strings[] = "%s: Address or Write Phase Parity Error Detected in %s.\n" }; -void +static void ahd_pci_intr(struct ahd_softc *ahd) { uint8_t pci_status[8]; diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index c5f0ee59150..6b28bebcbca 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -136,7 +136,7 @@ copy_info(struct info_str *info, char *fmt, ...) return (len); } -void +static void ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) { u_int speed; diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index 4850820816e..5802f33324c 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h @@ -1127,8 +1127,6 @@ struct ahc_pci_identity { char *name; ahc_device_setup_t *setup; }; -extern struct ahc_pci_identity ahc_pci_ident_table[]; -extern const u_int ahc_num_pci_devs; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 8eb1211a788..ed85057152d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -328,7 +328,7 @@ static uint32_t aic7xxx_seltime; * force all outstanding transactions to be serviced prior to a new * transaction. */ -uint32_t aic7xxx_periodic_otag; +static uint32_t aic7xxx_periodic_otag; /* * Module information and settable options. diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index a87a4ce090d..a36b33868e0 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -533,8 +533,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) #define PCIR_SUBVEND_0 0x2c #define PCIR_SUBDEV_0 0x2e -extern struct pci_driver aic7xxx_pci_driver; - typedef enum { AHC_POWER_STATE_D0, diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index d20ca514e9f..ea5687df732 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -130,7 +130,7 @@ static struct pci_device_id ahc_linux_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); -struct pci_driver aic7xxx_pci_driver = { +static struct pci_driver aic7xxx_pci_driver = { .name = "aic7xxx", .probe = ahc_linux_pci_dev_probe, .remove = ahc_linux_pci_dev_remove, diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c index 63cab2d7455..09c8172c9e5 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -168,7 +168,7 @@ static ahc_device_setup_t ahc_aha394XX_setup; static ahc_device_setup_t ahc_aha494XX_setup; static ahc_device_setup_t ahc_aha398XX_setup; -struct ahc_pci_identity ahc_pci_ident_table [] = +static struct ahc_pci_identity ahc_pci_ident_table [] = { /* aic7850 based controllers */ { @@ -559,7 +559,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = } }; -const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); +static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); #define AHC_394X_SLOT_CHANNEL_A 4 #define AHC_394X_SLOT_CHANNEL_B 5 -- cgit From ca3c3323931ef925497a9ffcb61c5eebe55f8e2b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 20 Oct 2006 14:48:07 -0700 Subject: [SCSI] aic79xx: make ahd_set_tags() static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Acked-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx.h | 5 ----- drivers/scsi/aic7xxx/aic79xx_core.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index b19a07cb2ab..170a4344cbb 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -1428,11 +1428,6 @@ typedef enum { AHD_QUEUE_TAGGED } ahd_queue_alg; -void ahd_set_tags(struct ahd_softc *ahd, - struct scsi_cmnd *cmd, - struct ahd_devinfo *devinfo, - ahd_queue_alg alg); - /**************************** Target Mode *************************************/ #ifdef AHD_TARGET_MODE void ahd_send_lstate_events(struct ahd_softc *, diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 7d53c6456d0..4c2b5a81711 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -3271,7 +3271,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, /* * Update the current state of tagged queuing for a given target. */ -void +static void ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, struct ahd_devinfo *devinfo, ahd_queue_alg alg) { -- cgit From afc071e6281e4f2af4748b5ddc594334726a37cf Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 23 Oct 2006 21:47:13 -0700 Subject: [SCSI] lpfc: fix printk format warning Fix printk format warning: drivers/scsi/lpfc/lpfc_attr.c:597: warning: long long unsigned int format, uint64_t arg (arg 4) Signed-off-by: Randy Dunlap Acked-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 9496e87c135..2a4e02e7a39 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -594,7 +594,8 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn); + return snprintf(buf, PAGE_SIZE, "0x%llx\n", + (unsigned long long)phba->cfg_soft_wwpn); } -- cgit From 8883c1f182fa88d2b8e0adb6ae90a42f67e5353e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 23 Oct 2006 15:22:37 +0200 Subject: [SCSI] aic79xx: Fixup external device reset Whenever an external device is resetted we really have to take care to keep the channel in sync. Just notifying SCSI-ML and retry is not enough as we have to make sure the SCSI bus is not getting confused, either. So whenever we detect an external reset we rewrite the command to TUR, disable packetized command and notify the internal engine that an abort has happened. This way we trigger a proper bus reset sequence and all devices will be renegotiated properly. Kudos to Justin Gibbs and Luben Tuikov for this idea. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx_core.c | 66 +++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4c2b5a81711..07a86a30f67 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -1154,10 +1154,12 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) * If a target takes us into the command phase * assume that it has been externally reset and * has thus lost our previous packetized negotiation - * agreement. - * Revert to async/narrow transfers until we - * can renegotiate with the device and notify - * the OSM about the reset. + * agreement. Since we have not sent an identify + * message and may not have fully qualified the + * connection, we change our command to TUR, assert + * ATN and ABORT the task when we go to message in + * phase. The OSM will see the REQUEUE_REQUEST + * status and retry the command. */ scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); @@ -1184,7 +1186,28 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, /*ppr_options*/0, AHD_TRANS_ACTIVE, /*paused*/TRUE); - scb->flags |= SCB_EXTERNAL_RESET; + /* Hand-craft TUR command */ + ahd_outb(ahd, SCB_CDB_STORE, 0); + ahd_outb(ahd, SCB_CDB_STORE+1, 0); + ahd_outb(ahd, SCB_CDB_STORE+2, 0); + ahd_outb(ahd, SCB_CDB_STORE+3, 0); + ahd_outb(ahd, SCB_CDB_STORE+4, 0); + ahd_outb(ahd, SCB_CDB_STORE+5, 0); + ahd_outb(ahd, SCB_CDB_LEN, 6); + scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); + scb->hscb->control |= MK_MESSAGE; + ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); + /* + * The lun is 0, regardless of the SCB's lun + * as we have not sent an identify message. + */ + ahd_outb(ahd, SAVED_LUN, 0); + ahd_outb(ahd, SEQ_FLAGS, 0); + ahd_assert_atn(ahd); + scb->flags &= ~SCB_PACKETIZED; + scb->flags |= SCB_ABORT|SCB_EXTERNAL_RESET; ahd_freeze_devq(ahd, scb); ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); ahd_freeze_scb(scb); @@ -1620,8 +1643,10 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) /* * Ignore external resets after a bus reset. */ - if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) + if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) { + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); return; + } /* * Clear bus reset flag @@ -2301,6 +2326,22 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) if (sent_msg == MSG_ABORT_TAG) tag = SCB_GET_TAG(scb); + if ((scb->flags & SCB_EXTERNAL_RESET) != 0) { + /* + * This abort is in response to an + * unexpected switch to command phase + * for a packetized connection. Since + * the identify message was never sent, + * "saved lun" is 0. We really want to + * abort only the SCB that encountered + * this error, which could have a different + * lun. The SCB will be retried so the OS + * will see the UA after renegotiating to + * packetized. + */ + tag = SCB_GET_TAG(scb); + saved_lun = scb->hscb->lun; + } found = ahd_abort_scbs(ahd, target, 'A', saved_lun, tag, ROLE_INITIATOR, CAM_REQ_ABORTED); @@ -7984,6 +8025,11 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) ahd_clear_fifo(ahd, 0); ahd_clear_fifo(ahd, 1); + /* + * Clear SCSI interrupt status + */ + ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + /* * Reenable selections */ @@ -8017,10 +8063,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) } } #endif - /* Notify the XPT that a bus reset occurred */ - ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, AC_BUS_RESET); - /* * Revert to async/narrow transfers until we renegotiate. */ @@ -8042,6 +8084,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) } } + /* Notify the XPT that a bus reset occurred */ + ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, AC_BUS_RESET); + ahd_restart(ahd); return (found); -- cgit From 843822ad631889596d67716e6edbcde608aeba81 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 23 Oct 2006 15:24:23 +0200 Subject: [SCSI] aic79xx: set precompensation aic79xx has a special 'iocell' chip which handles the precompensation. If it's set via DV we should make sure to set the chip correctly, too. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx_osm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 5e13046d845..e7a32f8e1a5 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -2636,8 +2636,22 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp) pcomp ? "Enable" : "Disable"); #endif - if (pcomp) + if (pcomp) { + uint8_t precomp; + + if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) { + struct ahd_linux_iocell_opts *iocell_opts; + + iocell_opts = &aic79xx_iocell_info[ahd->unit]; + precomp = iocell_opts->precomp; + } else { + precomp = AIC79XX_DEFAULT_PRECOMP; + } ppr_options |= MSG_EXT_PPR_PCOMP_EN; + AHD_SET_PRECOMP(ahd, precomp); + } else { + AHD_SET_PRECOMP(ahd, 0); + } ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); -- cgit From 9080063f523b09af63234a21816c825133d48c44 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 23 Oct 2006 15:25:36 +0200 Subject: [SCSI] aic7xxx: Remove slave_destroy This is a cross-port from aic79xx; we still hit the occasional BUG_ON in slave_destroy. And again we don't really need the slave_destroy callback nor the ahc_linux_target structure at all. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx.h | 1 + drivers/scsi/aic7xxx/aic7xxx_core.c | 22 +++++++------ drivers/scsi/aic7xxx/aic7xxx_osm.c | 65 +++++++------------------------------ drivers/scsi/aic7xxx/aic7xxx_osm.h | 11 ++----- drivers/scsi/aic7xxx/aic7xxx_proc.c | 10 +++--- 5 files changed, 31 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index 5802f33324c..954c7c24501 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h @@ -1279,6 +1279,7 @@ typedef enum { } ahc_queue_alg; void ahc_set_tags(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo, ahc_queue_alg alg); diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 46bd7bc2fa4..50ef785224d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1986,7 +1986,7 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo->curr.ppr_options = ppr_options; ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + CAM_LUN_WILDCARD, AC_TRANSFER_NEG); if (bootverbose) { if (offset != 0) { printf("%s: target %d synchronous at %sMHz%s, " @@ -2056,7 +2056,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo->curr.width = width; ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); + CAM_LUN_WILDCARD, AC_TRANSFER_NEG); if (bootverbose) { printf("%s: target %d using %dbit transfers\n", ahc_name(ahc), devinfo->target, @@ -2074,12 +2074,14 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, * Update the current state of tagged queuing for a given target. */ void -ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, - ahc_queue_alg alg) +ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, ahc_queue_alg alg) { - ahc_platform_set_tags(ahc, devinfo, alg); + struct scsi_device *sdev = cmd->device; + + ahc_platform_set_tags(ahc, sdev, devinfo, alg); ahc_send_async(ahc, devinfo->channel, devinfo->target, - devinfo->lun, AC_TRANSFER_NEG, &alg); + devinfo->lun, AC_TRANSFER_NEG); } /* @@ -3489,7 +3491,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) printf("(%s:%c:%d:%d): refuses tagged commands. " "Performing non-tagged I/O\n", ahc_name(ahc), devinfo->channel, devinfo->target, devinfo->lun); - ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE); + ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE); mask = ~0x23; } else { printf("(%s:%c:%d:%d): refuses %s tagged commands. " @@ -3497,7 +3499,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) ahc_name(ahc), devinfo->channel, devinfo->target, devinfo->lun, tag_type == MSG_ORDERED_TASK ? "ordered" : "head of queue"); - ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC); + ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC); mask = ~0x03; } @@ -3763,7 +3765,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, if (status != CAM_SEL_TIMEOUT) ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); + CAM_LUN_WILDCARD, AC_SENT_BDR); if (message != NULL && (verbose_level <= bootverbose)) @@ -6018,7 +6020,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset) #endif /* Notify the XPT that a bus reset occurred */ ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); + CAM_LUN_WILDCARD, AC_BUS_RESET); /* * Revert to async/narrow transfers until we renegotiate. diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index ed85057152d..660f26e23a3 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -512,7 +512,6 @@ ahc_linux_target_alloc(struct scsi_target *starget) struct seeprom_config *sc = ahc->seep_config; unsigned long flags; struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget); - struct ahc_linux_target *targ = scsi_transport_target_data(starget); unsigned short scsirate; struct ahc_devinfo devinfo; struct ahc_initiator_tinfo *tinfo; @@ -533,7 +532,6 @@ ahc_linux_target_alloc(struct scsi_target *starget) BUG_ON(*ahc_targp != NULL); *ahc_targp = starget; - memset(targ, 0, sizeof(*targ)); if (sc) { int maxsync = AHC_SYNCRATE_DT; @@ -594,14 +592,11 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata); struct scsi_target *starget = sdev->sdev_target; - struct ahc_linux_target *targ = scsi_transport_target_data(starget); struct ahc_linux_device *dev; if (bootverbose) printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id); - BUG_ON(targ->sdev[sdev->lun] != NULL); - dev = scsi_transport_device_data(sdev); memset(dev, 0, sizeof(*dev)); @@ -618,8 +613,6 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) */ dev->maxtags = 0; - targ->sdev[sdev->lun] = sdev; - spi_period(starget) = 0; return 0; @@ -644,22 +637,6 @@ ahc_linux_slave_configure(struct scsi_device *sdev) return 0; } -static void -ahc_linux_slave_destroy(struct scsi_device *sdev) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev = scsi_transport_device_data(sdev); - struct ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); - - ahc = *((struct ahc_softc **)sdev->host->hostdata); - if (bootverbose) - printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id); - - BUG_ON(dev->active); - - targ->sdev[sdev->lun] = NULL; -} - #if defined(__i386__) /* * Return the disk geometry for the given SCSI device. @@ -782,7 +759,6 @@ struct scsi_host_template aic7xxx_driver_template = { .use_clustering = ENABLE_CLUSTERING, .slave_alloc = ahc_linux_slave_alloc, .slave_configure = ahc_linux_slave_configure, - .slave_destroy = ahc_linux_slave_destroy, .target_alloc = ahc_linux_target_alloc, .target_destroy = ahc_linux_target_destroy, }; @@ -1204,21 +1180,13 @@ void ahc_platform_free(struct ahc_softc *ahc) { struct scsi_target *starget; - int i, j; + int i; if (ahc->platform_data != NULL) { /* destroy all of the device and target objects */ for (i = 0; i < AHC_NUM_TARGETS; i++) { starget = ahc->platform_data->starget[i]; if (starget != NULL) { - for (j = 0; j < AHC_NUM_LUNS; j++) { - struct ahc_linux_target *targ = - scsi_transport_target_data(starget); - - if (targ->sdev[j] == NULL) - continue; - targ->sdev[j] = NULL; - } ahc->platform_data->starget[i] = NULL; } } @@ -1252,24 +1220,13 @@ ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) } void -ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, - ahc_queue_alg alg) +ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, + struct ahc_devinfo *devinfo, ahc_queue_alg alg) { - struct scsi_target *starget; - struct ahc_linux_target *targ; struct ahc_linux_device *dev; - struct scsi_device *sdev; - u_int target_offset; int was_queuing; int now_queuing; - target_offset = devinfo->target; - if (devinfo->channel != 'A') - target_offset += 8; - starget = ahc->platform_data->starget[target_offset]; - targ = scsi_transport_target_data(starget); - BUG_ON(targ == NULL); - sdev = targ->sdev[devinfo->lun]; if (sdev == NULL) return; dev = scsi_transport_device_data(sdev); @@ -1402,11 +1359,15 @@ ahc_linux_device_queue_depth(struct scsi_device *sdev) tags = ahc_linux_user_tagdepth(ahc, &devinfo); if (tags != 0 && sdev->tagged_supported != 0) { - ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED); + ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED); + ahc_send_async(ahc, devinfo.channel, devinfo.target, + devinfo.lun, AC_TRANSFER_NEG); ahc_print_devinfo(ahc, &devinfo); printf("Tagged Queuing enabled. Depth %d\n", tags); } else { - ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE); + ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE); + ahc_send_async(ahc, devinfo.channel, devinfo.target, + devinfo.lun, AC_TRANSFER_NEG); } } @@ -1630,7 +1591,7 @@ ahc_platform_flushwork(struct ahc_softc *ahc) void ahc_send_async(struct ahc_softc *ahc, char channel, - u_int target, u_int lun, ac_code code, void *arg) + u_int target, u_int lun, ac_code code) { switch (code) { case AC_TRANSFER_NEG: @@ -1947,7 +1908,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, } ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); ahc_set_scsi_status(scb, SCSI_STATUS_OK); - ahc_platform_set_tags(ahc, &devinfo, + ahc_platform_set_tags(ahc, sdev, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); break; @@ -1958,7 +1919,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, */ dev->openings = 1; ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); - ahc_platform_set_tags(ahc, &devinfo, + ahc_platform_set_tags(ahc, sdev, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); break; @@ -2600,8 +2561,6 @@ ahc_linux_init(void) if (!ahc_linux_transport_template) return -ENODEV; - scsi_transport_reserve_target(ahc_linux_transport_template, - sizeof(struct ahc_linux_target)); scsi_transport_reserve_device(ahc_linux_transport_template, sizeof(struct ahc_linux_device)); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index a36b33868e0..85ae5d836fa 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -256,7 +256,6 @@ typedef enum { AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ } ahc_linux_dev_flags; -struct ahc_linux_target; struct ahc_linux_device { /* * The number of transactions currently @@ -329,12 +328,6 @@ struct ahc_linux_device { #define AHC_OTAG_THRESH 500 }; -struct ahc_linux_target { - struct scsi_device *sdev[AHC_NUM_LUNS]; - struct ahc_transinfo last_tinfo; - struct ahc_softc *ahc; -}; - /********************* Definitions Required by the Core ***********************/ /* * Number of SG segments we require. So long as the S/G segments for @@ -822,7 +815,7 @@ ahc_freeze_scb(struct scb *scb) } } -void ahc_platform_set_tags(struct ahc_softc *ahc, +void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, struct ahc_devinfo *devinfo, ahc_queue_alg); int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, @@ -832,7 +825,7 @@ irqreturn_t void ahc_platform_flushwork(struct ahc_softc *ahc); void ahc_done(struct ahc_softc*, struct scb*); void ahc_send_async(struct ahc_softc *, char channel, - u_int target, u_int lun, ac_code, void *); + u_int target, u_int lun, ac_code); void ahc_print_path(struct ahc_softc *, struct scb *); void ahc_platform_dump_card_state(struct ahc_softc *ahc); diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 5914b4aa4a8..99e5443e753 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -182,7 +182,6 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, u_int our_id, char channel, u_int target_id, u_int target_offset) { - struct ahc_linux_target *targ; struct scsi_target *starget; struct ahc_initiator_tinfo *tinfo; struct ahc_tmode_tstate *tstate; @@ -198,7 +197,6 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, starget = ahc->platform_data->starget[target_offset]; if (!starget) return; - targ = scsi_transport_target_data(starget); copy_info(info, "\tGoal: "); ahc_format_transinfo(info, &tinfo->goal); @@ -208,7 +206,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, for (lun = 0; lun < AHC_NUM_LUNS; lun++) { struct scsi_device *sdev; - sdev = targ->sdev[lun]; + sdev = scsi_device_lookup_by_target(starget, lun); if (sdev == NULL) continue; @@ -383,11 +381,11 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, } copy_info(&info, "\n"); - max_targ = 15; + max_targ = 16; if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0) - max_targ = 7; + max_targ = 8; - for (i = 0; i <= max_targ; i++) { + for (i = 0; i < max_targ; i++) { u_int our_id; u_int target_id; char channel; -- cgit From d6b9ccbbeb625674891f797119f06512d27fc905 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 23 Oct 2006 15:26:37 +0200 Subject: [SCSI] aic79xx: Print out signalling This is a cross-port of a similar patch for aic7xxx; only it's a bit simpler here as we don't support HVD and all controller actually implement this register. I hope. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx_osm.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index e7a32f8e1a5..9bfcca5ede0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -2694,7 +2694,25 @@ static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold) ahd_unlock(ahd, &flags); } +static void ahd_linux_get_signalling(struct Scsi_Host *shost) +{ + struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; + unsigned long flags; + u8 mode; + ahd_lock(ahd, &flags); + ahd_pause(ahd); + mode = ahd_inb(ahd, SBLKCTL); + ahd_unpause(ahd); + ahd_unlock(ahd, &flags); + + if (mode & ENAB40) + spi_signalling(shost) = SPI_SIGNAL_LVD; + else if (mode & ENAB20) + spi_signalling(shost) = SPI_SIGNAL_SE; + else + spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; +} static struct spi_function_template ahd_linux_transport_functions = { .set_offset = ahd_linux_set_offset, @@ -2719,6 +2737,7 @@ static struct spi_function_template ahd_linux_transport_functions = { .show_pcomp_en = 1, .set_hold_mcs = ahd_linux_set_hold_mcs, .show_hold_mcs = 1, + .get_signalling = ahd_linux_get_signalling, }; static int __init -- cgit From 1fbece150a230d0ab447cfb2fc4df10fb89f0d8c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 1 Jul 2006 13:39:55 -0700 Subject: [PATCH] pcmcia: at91_cf update More correct AT91 CF wakeup logic ... only enable/disable the IRQ wakeup capability, not the IRQ itself. That way the we know that the IRQ will be disabled correctly, in suspend/resume logic instead of ARM IRQ code. Most of the pin multiplexing setup has moved to the devices.c setup code. Signed-off-by: David Brownell Signed-off-by: Andrew Victor Signed-off-by: Dominik Brodowski --- drivers/pcmcia/at91_cf.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 7f5df9a9f39..f8db6e342cb 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -241,12 +241,6 @@ static int __init at91_cf_probe(struct platform_device *pdev) csa = at91_sys_read(AT91_EBI_CSA); at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); - /* force poweron defaults for these pins ... */ - (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ - (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ - (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ - (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ - /* nWAIT is _not_ a default setting */ (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ @@ -322,6 +316,7 @@ fail1: if (board->irq_pin) free_irq(board->irq_pin, cf); fail0a: + device_init_wakeup(&pdev->dev, 0); free_irq(board->det_pin, cf); device_init_wakeup(&pdev->dev, 0); fail0: @@ -360,26 +355,20 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) struct at91_cf_data *board = cf->board; pcmcia_socket_dev_suspend(&pdev->dev, mesg); - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(&pdev->dev)) { enable_irq_wake(board->det_pin); - else { + if (board->irq_pin) + enable_irq_wake(board->irq_pin); + } else { disable_irq_wake(board->det_pin); - disable_irq(board->det_pin); + if (board->irq_pin) + disable_irq_wake(board->irq_pin); } - if (board->irq_pin) - disable_irq(board->irq_pin); return 0; } static int at91_cf_resume(struct platform_device *pdev) { - struct at91_cf_socket *cf = platform_get_drvdata(pdev); - struct at91_cf_data *board = cf->board; - - if (board->irq_pin) - enable_irq(board->irq_pin); - if (!device_may_wakeup(&pdev->dev)) - enable_irq(board->det_pin); pcmcia_socket_dev_resume(&pdev->dev); return 0; } -- cgit From 01918d16c837485ceba92d48fb734cf520e61144 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 2 Jul 2006 21:21:51 +0200 Subject: [PATCH] pcmcia: add more IDs to hostap_cs.c As a replacement for the broad manufactor/card ID match we commented out because of conflicts with pcnet_cs, add two product ID matches. Signed-off-by: Dominik Brodowski --- drivers/net/wireless/hostap/hostap_cs.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 686d895116d..f63909e4bc3 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -887,6 +887,13 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_PROD_ID123( "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", 0xc7b8df9d, 0x1700d087, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID123( + "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", + "Ver. 1.00", + 0x5cd01705, 0x4271660f, 0x9d08ee12), + PCMCIA_DEVICE_PROD_ID123( + "corega", "WL PCCL-11", "ISL37300P", + 0xa21501a, 0x59868926, 0xc9049a39), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); -- cgit From 4708b5faf7c53bb4128d34267bdfe4b8c74b488a Mon Sep 17 00:00:00 2001 From: Kaustav Majumdar Date: Fri, 20 Oct 2006 14:44:09 -0700 Subject: [PATCH] pcmcia: update alloc_io_space for conflict checking for multifunction PC card Some PCMCIA cards do not mention specific IO addresses in the CIS. In that case, inside the alloc_io_space function, conflicts are detected (the function returns 1) for the second function of a multifunction card unless the length of IO address range required is greater than 0x100. The following patch will remove this conflict checking for a PCMCIA function which had not mentioned any specific IO address to be mapped from. The patch is tested for Linux kernel 2.6.15.4 and works fine in the above case and is as suggested by Dave Hinds. Signed-off-by: Kaustav Majumdar Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 74cebd42403..b9201c2ec38 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -95,7 +95,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, * potential conflicts, just the most obvious ones. */ for (i = 0; i < MAX_IO_WIN; i++) - if ((s->io[i].res) && + if ((s->io[i].res) && *base && ((s->io[i].res->start & (align-1)) == *base)) return 1; for (i = 0; i < MAX_IO_WIN; i++) { -- cgit From ace7d4772cf056d9b13b51bd496a8be968774592 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 20 Oct 2006 14:44:12 -0700 Subject: [PATCH] pcmcia/ds: driver layer error checking Check driver layer return values in pcmcia/ds.c Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 74b3124e824..af392bfee5a 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1292,10 +1292,22 @@ struct bus_type pcmcia_bus_type = { static int __init init_pcmcia_bus(void) { + int ret; + spin_lock_init(&pcmcia_dev_list_lock); - bus_register(&pcmcia_bus_type); - class_interface_register(&pcmcia_bus_interface); + ret = bus_register(&pcmcia_bus_type); + if (ret < 0) { + printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); + return ret; + } + ret = class_interface_register(&pcmcia_bus_interface); + if (ret < 0) { + printk(KERN_WARNING + "pcmcia: class_interface_register error: %d\n", ret); + bus_unregister(&pcmcia_bus_type); + return ret; + } pcmcia_setup_ioctl(); -- cgit From f237de58b13bf65ba2f7fab896daacb92ae7ddef Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 20 Oct 2006 14:44:13 -0700 Subject: [PATCH] CONFIG_PM=n slim: drivers/pcmcia/* Remove some code which is unneeded if CONFIG_PM=n. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/i82092.c | 4 ++++ drivers/pcmcia/pd6729.c | 4 ++++ drivers/pcmcia/yenta_socket.c | 6 ++++-- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 82715f44895..d316d956f3b 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -41,6 +41,7 @@ static struct pci_device_id i82092aa_pci_ids[] = { }; MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); +#ifdef CONFIG_PM static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) { return pcmcia_socket_dev_suspend(&dev->dev, state); @@ -50,14 +51,17 @@ static int i82092aa_socket_resume (struct pci_dev *dev) { return pcmcia_socket_dev_resume(&dev->dev); } +#endif static struct pci_driver i82092aa_pci_drv = { .name = "i82092aa", .id_table = i82092aa_pci_ids, .probe = i82092aa_pci_probe, .remove = __devexit_p(i82092aa_pci_remove), +#ifdef CONFIG_PM .suspend = i82092aa_socket_suspend, .resume = i82092aa_socket_resume, +#endif }; diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index c83a0a6b158..a70f97fdbbd 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -755,6 +755,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev) kfree(socket); } +#ifdef CONFIG_PM static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) { return pcmcia_socket_dev_suspend(&dev->dev, state); @@ -764,6 +765,7 @@ static int pd6729_socket_resume(struct pci_dev *dev) { return pcmcia_socket_dev_resume(&dev->dev); } +#endif static struct pci_device_id pd6729_pci_ids[] = { { @@ -781,8 +783,10 @@ static struct pci_driver pd6729_pci_drv = { .id_table = pd6729_pci_ids, .probe = pd6729_pci_probe, .remove = __devexit_p(pd6729_pci_remove), +#ifdef CONFIG_PM .suspend = pd6729_socket_suspend, .resume = pd6729_socket_resume, +#endif }; static int pd6729_module_init(void) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 26229d9da76..9ced52ab7d1 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1213,7 +1213,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i return ret; } - +#ifdef CONFIG_PM static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) { struct yenta_socket *socket = pci_get_drvdata(dev); @@ -1262,7 +1262,7 @@ static int yenta_dev_resume (struct pci_dev *dev) return pcmcia_socket_dev_resume(&dev->dev); } - +#endif #define CB_ID(vend,dev,type) \ { \ @@ -1359,8 +1359,10 @@ static struct pci_driver yenta_cardbus_driver = { .id_table = yenta_table, .probe = yenta_probe, .remove = __devexit_p(yenta_close), +#ifdef CONFIG_PM .suspend = yenta_dev_suspend, .resume = yenta_dev_resume, +#endif }; -- cgit From f465ce176fb2f1778a04fc3fcb2b8aa564901419 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 20 Oct 2006 14:44:13 -0700 Subject: [PATCH] i82092: wire up errors from pci_register_driver() debugging goo removed to not leave assymetry in it after possible "leave" removal. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/i82092.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index d316d956f3b..c2ea07aa7a1 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -709,10 +709,7 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ static int i82092aa_module_init(void) { - enter("i82092aa_module_init"); - pci_register_driver(&i82092aa_pci_drv); - leave("i82092aa_module_init"); - return 0; + return pci_register_driver(&i82092aa_pci_drv); } static void i82092aa_module_exit(void) -- cgit From a230a6785dd5af84b8b043a64d8df8adc81f3724 Mon Sep 17 00:00:00 2001 From: Om Narasimhan Date: Fri, 20 Oct 2006 14:44:15 -0700 Subject: [PATCH] pcmcia: au1000_generic fix The previous code did something like, if (error) goto out_err; .... do { struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); out_err: flush_scheduled_work(); ops->hw_shutdown(skt); i--; } while (i > 0) ..... - On the error path, skt would not contain a valid value for the first iteration (skt is masked by uninitialized automatic skt) - Does not do hw_shutdown() for 0th element of PCMCIA_SOCKET Signed-off-by: Om Narasimhan Cc: "Yoichi Yuasa" Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/au1000_generic.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index d5dd0ce6553..5387de6216f 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -351,6 +351,7 @@ struct skt_dev_info { int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) { struct skt_dev_info *sinfo; + struct au1000_pcmcia_socket *skt; int ret, i; sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); @@ -365,7 +366,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, * Initialise the per-socket structure. */ for (i = 0; i < nr; i++) { - struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); + skt = PCMCIA_SOCKET(i); memset(skt, 0, sizeof(*skt)); skt->socket.resource_ops = &pccard_static_ops; @@ -438,17 +439,19 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, dev_set_drvdata(dev, sinfo); return 0; - do { - struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); + +out_err: + flush_scheduled_work(); + ops->hw_shutdown(skt); + while (i-- > 0) { + skt = PCMCIA_SOCKET(i); del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); -out_err: flush_scheduled_work(); ops->hw_shutdown(skt); - i--; - } while (i > 0); + } kfree(sinfo); out: return ret; -- cgit From 3efa9970bd0ac731302224ab9243693e91bc4bea Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Fri, 20 Oct 2006 14:44:18 -0700 Subject: [PATCH] ioremap balanced with iounmap for drivers/pcmcia ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Signed-off-by: Amol Lad Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/at91_cf.c | 3 ++- drivers/pcmcia/au1000_generic.c | 10 ++++++++++ drivers/pcmcia/m8xx_pcmcia.c | 12 ++++++++---- drivers/pcmcia/omap_cf.c | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index f8db6e342cb..3bcb7dc3299 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -310,9 +310,10 @@ static int __init at91_cf_probe(struct platform_device *pdev) return 0; fail2: - iounmap((void __iomem *) cf->socket.io_offset); release_mem_region(io->start, io->end + 1 - io->start); fail1: + if (cf->socket.io_offset) + iounmap((void __iomem *) cf->socket.io_offset); if (board->irq_pin) free_irq(board->irq_pin, cf); fail0a: diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 5387de6216f..551bde5d943 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -449,6 +449,16 @@ out_err: del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); flush_scheduled_work(); + if (i == 0) { + iounmap(skt->virt_io + (u32)mips_io_port_base); + skt->virt_io = NULL; + } +#ifndef CONFIG_MIPS_XXS1500 + else { + iounmap(skt->virt_io + (u32)mips_io_port_base); + skt->virt_io = NULL; + } +#endif ops->hw_shutdown(skt); } diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index e070a289676..3b72be88040 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -427,7 +427,7 @@ static int voltage_set(int slot, int vcc, int vpp) reg |= BCSR1_PCCVCC1; break; default: - return 1; + goto out_unmap; } switch(vpp) { @@ -438,15 +438,15 @@ static int voltage_set(int slot, int vcc, int vpp) if(vcc == vpp) reg |= BCSR1_PCCVPP1; else - return 1; + goto out_unmap; break; case 120: if ((vcc == 33) || (vcc == 50)) reg |= BCSR1_PCCVPP0; else - return 1; + goto out_unmap; default: - return 1; + goto out_unmap; } /* first, turn off all power */ @@ -457,6 +457,10 @@ static int voltage_set(int slot, int vcc, int vpp) iounmap(bcsr_io); return 0; + +out_unmap: + iounmap(bcsr_io); + return 1; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index c8e838c6976..06bf7f48836 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -309,9 +309,10 @@ static int __devinit omap_cf_probe(struct device *dev) return 0; fail2: - iounmap((void __iomem *) cf->socket.io_offset); release_mem_region(cf->phys_cf, SZ_8K); fail1: + if (cf->socket.io_offset) + iounmap((void __iomem *) cf->socket.io_offset); free_irq(irq, cf); fail0: kfree(cf); -- cgit From 26aaa3c202fb3bec8d6c6619122442d476f55658 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Fri, 20 Oct 2006 14:44:19 -0700 Subject: [PATCH] Export soc_common_drv_pcmcia_remove to allow modular PCMCIA. Allow a modular sa1100_cs. Signed-off-by: Jonathan McDowell Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/soc_common.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 3627e52e0c2..e433704e026 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -824,3 +824,4 @@ int soc_common_drv_pcmcia_remove(struct device *dev) return 0; } +EXPORT_SYMBOL(soc_common_drv_pcmcia_remove); -- cgit From 4deb7c1ed2b622b565c5330b475adc5a6cea30da Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 20 Oct 2006 14:44:23 -0700 Subject: [PATCH] PCMCIA: handle sysfs, PCI errors Handle sysfs and PCI errors correctly. Signed-off-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_ioctl.c | 11 ++++++++--- drivers/pcmcia/yenta_socket.c | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 9ad18e62658..310ede575ca 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -128,9 +128,12 @@ static int proc_read_drivers(char *buf, char **start, off_t pos, int count, int *eof, void *data) { char *p = buf; + int rc; - bus_for_each_drv(&pcmcia_bus_type, NULL, - (void *) &p, proc_read_drivers_callback); + rc = bus_for_each_drv(&pcmcia_bus_type, NULL, + (void *) &p, proc_read_drivers_callback); + if (rc < 0) + return rc; return (p - buf); } @@ -269,8 +272,10 @@ rescan: * Prevent this racing with a card insertion. */ mutex_lock(&s->skt_mutex); - bus_rescan_devices(&pcmcia_bus_type); + ret = bus_rescan_devices(&pcmcia_bus_type); mutex_unlock(&s->skt_mutex); + if (ret) + goto err_put_module; /* check whether the driver indeed matched. I don't care if this * is racy or not, because it can only happen on cardmgr access diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 9ced52ab7d1..da471bddc97 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1197,8 +1197,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ret = pcmcia_register_socket(&socket->socket); if (ret == 0) { /* Add the yenta register attributes */ - device_create_file(&dev->dev, &dev_attr_yenta_registers); - goto out; + ret = device_create_file(&dev->dev, &dev_attr_yenta_registers); + if (ret == 0) + goto out; + + /* error path... */ + pcmcia_unregister_socket(&socket->socket); } unmap: @@ -1248,12 +1252,18 @@ static int yenta_dev_resume (struct pci_dev *dev) struct yenta_socket *socket = pci_get_drvdata(dev); if (socket) { + int rc; + pci_set_power_state(dev, 0); /* FIXME: pci_restore_state needs to have a better interface */ pci_restore_state(dev); pci_write_config_dword(dev, 16*4, socket->saved_state[0]); pci_write_config_dword(dev, 17*4, socket->saved_state[1]); - pci_enable_device(dev); + + rc = pci_enable_device(dev); + if (rc) + return rc; + pci_set_master(dev); if (socket->type && socket->type->restore_state) -- cgit From f901b8c46fa9748b9d6836e9b158cf7be89447f1 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 25 Oct 2006 19:56:55 -0400 Subject: [PATCH] PCMCIA: fix __must_check warnings Fix the remaining __must_check warnings in the PCMCIA core. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index af392bfee5a..0f701921c13 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -717,6 +717,7 @@ static int pcmcia_requery(struct device *dev, void * _data) static void pcmcia_bus_rescan(struct pcmcia_socket *skt) { int no_devices=0; + int ret = 0; unsigned long flags; /* must be called with skt_mutex held */ @@ -729,7 +730,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) * missing resource information or other trouble, we need to * do this now. */ if (no_devices) { - int ret = pcmcia_card_add(skt); + ret = pcmcia_card_add(skt); if (ret) return; } @@ -741,7 +742,9 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) /* we re-scan all devices, not just the ones connected to this * socket. This does not matter, though. */ - bus_rescan_devices(&pcmcia_bus_type); + ret = bus_rescan_devices(&pcmcia_bus_type); + if (ret) + printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); } static inline int pcmcia_devmatch(struct pcmcia_device *dev, @@ -1001,6 +1004,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + int ret; if (!count) return -EINVAL; @@ -1009,7 +1013,10 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, p_dev->allow_func_id_match = 1; mutex_unlock(&p_dev->socket->skt_mutex); - bus_rescan_devices(&pcmcia_bus_type); + ret = bus_rescan_devices(&pcmcia_bus_type); + if (ret) + printk(KERN_INFO "pcmcia: bus_rescan_devices failed after " + "allowing func_id matches\n"); return count; } -- cgit From f5ef9d11fd255b30b455d18f8d721bc44cd1296b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 27 Oct 2006 01:03:31 -0700 Subject: [SPARC]: Fix bus_id[] string overflow. dp->path_component_name can be larger than ->bus_id[] so use a different naming scheme for this stuff. Noticed by Jurij Smakov. Signed-off-by: David S. Miller --- drivers/sbus/sbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index 935952ef88f..98fcbb3d556 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -61,11 +61,11 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde else sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; sdev->ofdev.dev.bus = &sbus_bus_type; - strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name); + sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); if (of_device_register(&sdev->ofdev) != 0) printk(KERN_DEBUG "sbus: device registration error for %s!\n", - sdev->ofdev.dev.bus_id); + dp->path_component_name); } static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) -- cgit From c2b1449bd1fd73103ed5ff1a28d8f7cbc8a01b52 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 27 Oct 2006 12:39:17 +0200 Subject: [S390] cio: css_probe_device() must be called enabled. Move css_probe_device() behind giving up the lock for the old subchannel in css_evaluate_known_subchannel() so we aren't disabled when we call it. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index a2dee5bf5a1..ad7f7e1c016 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -271,10 +271,6 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) /* Reset intparm to zeroes. */ sch->schib.pmcw.intparm = 0; cio_modify(sch); - - /* Probe if necessary. */ - if (action == UNREGISTER_PROBE) - ret = css_probe_device(sch->schid); break; case REPROBE: device_trigger_reprobe(sch); @@ -283,6 +279,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) break; } spin_unlock_irqrestore(&sch->lock, flags); + /* Probe if necessary. */ + if (action == UNREGISTER_PROBE) + ret = css_probe_device(sch->schid); return ret; } -- cgit From f3b017d8c9915cbaa8bab178dde1bd9dbbf5012c Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 27 Oct 2006 12:39:26 +0200 Subject: [S390] Improve AP bus device removal. Added a call to device_unregister() in ap_scan_bus() to actively remove unavailable AP bus devices with every bus scan. Previously devices were only removed in ap_queue_message() or __ap_poll_all(). Signed-off-by: Ralph Wuerthner Signed-off-by: Martin Schwidefsky --- drivers/s390/crypto/ap_bus.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index c5ccd20b110..79d89c36891 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -739,11 +739,16 @@ static void ap_scan_bus(void *data) dev = bus_find_device(&ap_bus_type, NULL, (void *)(unsigned long)qid, __ap_scan_bus); + rc = ap_query_queue(qid, &queue_depth, &device_type); + if (dev && rc) { + put_device(dev); + device_unregister(dev); + continue; + } if (dev) { put_device(dev); continue; } - rc = ap_query_queue(qid, &queue_depth, &device_type); if (rc) continue; rc = ap_init_queue(qid); -- cgit From 3c9da7ba049d11caccc219576a3a23404aa2fc50 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 27 Oct 2006 12:39:33 +0200 Subject: [S390] cio: Make ccw_device_register() static. ccw_device_register() is only called from io_subchannel_register() and io_subchannel_probe() and will never be called for possible non-io subchannels. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device.c | 3 +-- drivers/s390/cio/device.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 94bdd4d8a4c..39c98f94050 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -532,8 +532,7 @@ device_remove_files(struct device *dev) /* this is a simple abstraction for device_register that sets the * correct bus type and adds the bus specific files */ -int -ccw_device_register(struct ccw_device *cdev) +static int ccw_device_register(struct ccw_device *cdev) { struct device *dev = &cdev->dev; int ret; diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index c6140cc97a8..9233b5c0bcc 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h @@ -78,7 +78,6 @@ void io_subchannel_recog_done(struct ccw_device *cdev); int ccw_device_cancel_halt_clear(struct ccw_device *); -int ccw_device_register(struct ccw_device *); void ccw_device_do_unreg_rereg(void *); void ccw_device_call_sch_unregister(void *); -- cgit From 35ae61a0f43ebbabc3cb4345136ca529fc4d6700 Mon Sep 17 00:00:00 2001 From: MUNEDA Takahiro Date: Wed, 25 Oct 2006 11:44:57 -0700 Subject: acpiphp: fix latch status pci_hotplug.h says: * @latch_status: if the latch (if any) is open or closed (1/0) However, acpiphp returns opposite value. This patch fixes this issue. I tested this patch on my ia64 machine that has some apciphp based hotplug slots. Signed-off-by: MUNEDA Takahiro Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index c44311ac2fd..16167b01626 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -1807,8 +1807,8 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) /* - * latch closed: 1 - * latch open: 0 + * latch open: 1 + * latch closed: 0 */ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) { @@ -1816,7 +1816,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) sta = get_slot_status(slot); - return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0; + return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; } -- cgit From 6b5c76b8e2ff204fa8d7201acce461188873bf2b Mon Sep 17 00:00:00 2001 From: Eiichiro Oiwa Date: Mon, 23 Oct 2006 15:14:07 +0900 Subject: PCI: fix pci_fixup_video as it blows up on sparc64 This reverts much of the original pci_fixup_video change and makes it work for all arches that need it. fixed, and tested on x86, x86_64 and IA64 dig. Signed-off-by: Eiichiro Oiwa Acked-by: David Miller Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 46 ---------------------------------------------- drivers/pci/rom.c | 5 +++-- 2 files changed, 3 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e8a7f1b1b2b..687ab4a0c6c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1619,52 +1619,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); -/* - * Fixup to mark boot BIOS video selected by BIOS before it changes - * - * From information provided by "Jon Smirl" - * - * The standard boot ROM sequence for an x86 machine uses the BIOS - * to select an initial video card for boot display. This boot video - * card will have it's BIOS copied to C0000 in system RAM. - * IORESOURCE_ROM_SHADOW is used to associate the boot video - * card with this copy. On laptops this copy has to be used since - * the main ROM may be compressed or combined with another image. - * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW - * is marked here since the boot video device will be the only enabled - * video device at this point. - */ - -static void __devinit fixup_video(struct pci_dev *pdev) -{ - struct pci_dev *bridge; - struct pci_bus *bus; - u16 config; - - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return; - - /* Is VGA routed to us? */ - bus = pdev->bus; - while (bus) { - bridge = bus->self; - if (bridge) { - pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, - &config); - if (!(config & PCI_BRIDGE_CTL_VGA)) - return; - } - bus = bus->parent; - } - pci_read_config_word(pdev, PCI_COMMAND, &config); - if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { - pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; - printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video); - - static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { while (f < end) { diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 43e4a49f2cc..e1dcefc69bb 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -72,8 +72,9 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) int last_image; /* - * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control - * register is set for embedded VGA. + * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy + * memory map if the VGA enable bit of the Bridge Control register is + * set for embedded VGA. */ if (res->flags & IORESOURCE_ROM_SHADOW) { /* primary video rom always starts here */ -- cgit From 2449e06a5696b7af1c8a369b04c97f3b139cf3bb Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 20 Oct 2006 14:45:32 -0700 Subject: PCI: reset pci device state to unknown state for resume Considering below scenario: 1.Unload a PCI device's driver, the device ->current remains in PCI_D0. 2.Do suspend/resume circle. After that, BIOS puts the device to D3. 3.Reload the device driver. The calling pci_set_power_state in the driver can't change the state to D0, as set_power_state thinks the device is already in D0. A bug is reported at http://bugzilla.kernel.org/show_bug.cgi?id=6024 Pat attached a patch at http://marc.theaimsgroup.com/?l=linux-pci&m=114049761428561&w=2 for this issue, but it's lost. As pci_set_power_state can handle D3 -> D0 correctly (restore config space), I simplified Patrick's patch. Signed-off-by: Shaohua Li Cc: Patrick Mochel Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index b1c0c707d96..194f1d21d3d 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -264,6 +264,13 @@ static int pci_device_remove(struct device * dev) pci_dev->driver = NULL; } + /* + * If the device is still on, set the power state as "unknown", + * since it might change by the next time we load the driver. + */ + if (pci_dev->current_state == PCI_D0) + pci_dev->current_state = PCI_UNKNOWN; + /* * We would love to complain here if pci_dev->is_enabled is set, that * the driver should have called pci_disable_device(), but the @@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) suspend_report_result(drv->suspend, i); } else { pci_save_state(pci_dev); + /* + * mark its power state as "unknown", since we don't know if + * e.g. the BIOS will change its device state when we suspend. + */ + if (pci_dev->current_state == PCI_D0) + pci_dev->current_state = PCI_UNKNOWN; } return i; } -- cgit From 3560cc5ec3488b20d927f7160a21a0df1d1fda20 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Fri, 20 Oct 2006 14:45:36 -0700 Subject: PCI: Remove quirk_via_abnormal_poweroff My K8T800 mobo resumes fine from suspend to ram with and without patch applied against 2.6.18. quirk_via_abnormal_poweroff makes some boards not boot 2.6.18, so IMO patch should go to head, 2.6.18.2 and everywhere "ACPI: ACPICA 20060623" has been applied. Remove quirk_via_abnormal_poweroff Obsoleted by "ACPI: ACPICA 20060623": Implemented support for "ignored" bits in the ACPI registers. According to the ACPI specification, these bits should be preserved when writing the registers via a read/modify/write cycle. There are 3 bits preserved in this manner: PM1_CONTROL[0] (SCI_EN), PM1_CONTROL[9], and PM1_STATUS[11]. http://bugzilla.kernel.org/show_bug.cgi?id=3691 Signed-off-by: Karsten Wiese Cc: Bob Moore Cc: "Brown, Len" Acked-by: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 687ab4a0c6c..204b1c8e972 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -714,33 +714,6 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id ); -#ifdef CONFIG_ACPI_SLEEP - -/* - * Some VIA systems boot with the abnormal status flag set. This can cause - * the BIOS to re-POST the system on resume rather than passing control - * back to the OS. Clear the flag on boot - */ -static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev) -{ - u32 reg; - - acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, - ®); - - if (reg & 0x800) { - printk("Clearing abnormal poweroff flag\n"); - acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, - ACPI_REGISTER_PM1_STATUS, - (u16)0x800); - } -} - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff); - -#endif - /* * CardBus controllers have a legacy base address that enables them * to respond as i82365 pcmcia controllers. We don't want them to -- cgit From 735a7ffb739b6efeaeb1e720306ba308eaaeb20e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 27 Oct 2006 11:42:37 -0700 Subject: [PATCH] drivers: wait for threaded probes between initcall levels The multithreaded-probing code has a problem: after one initcall level (eg, core_initcall) has been processed, we will then start processing the next level (postcore_initcall) while the kernel threads which are handling core_initcall are still executing. This breaks the guarantees which the layered initcalls previously gave us. IOW, we want to be multithreaded _within_ an initcall level, but not between different levels. Fix that up by causing the probing code to wait for all outstanding probes at one level to complete before we start processing the next level. Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/dd.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index db01b95a47a..c5d6bb4290a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -70,6 +71,8 @@ struct stupid_thread_structure { }; static atomic_t probe_count = ATOMIC_INIT(0); +static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); + static int really_probe(void *void_data) { struct stupid_thread_structure *data = void_data; @@ -121,6 +124,7 @@ probe_failed: done: kfree(data); atomic_dec(&probe_count); + wake_up(&probe_waitqueue); return ret; } @@ -337,6 +341,32 @@ void driver_detach(struct device_driver * drv) } } +#ifdef CONFIG_PCI_MULTITHREAD_PROBE +static int __init wait_for_probes(void) +{ + DEFINE_WAIT(wait); + + printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, + atomic_read(&probe_count)); + if (!atomic_read(&probe_count)) + return 0; + while (atomic_read(&probe_count)) { + prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(&probe_count)) + schedule(); + } + finish_wait(&probe_waitqueue, &wait); + return 0; +} + +core_initcall_sync(wait_for_probes); +postcore_initcall_sync(wait_for_probes); +arch_initcall_sync(wait_for_probes); +subsys_initcall_sync(wait_for_probes); +fs_initcall_sync(wait_for_probes); +device_initcall_sync(wait_for_probes); +late_initcall_sync(wait_for_probes); +#endif EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_release_driver); -- cgit From efbfe96c5d839c367249bf1cd53249716450c0a2 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 27 Oct 2006 23:24:47 +0200 Subject: [PATCH] silence 'make xmldocs' warning by adding missing description of 'raw' in nand_base.c:1485 Add description of 'raw' in comments for drivers/mtd/nand/nand_base.c::nand_write_page_syndrome() so 'make xmldocs' will not spew a warning at us. Signed-off-by: Jesper Juhl Acked-by: Thomas Gleixner Signed-off-by: Linus Torvalds --- drivers/mtd/nand/nand_base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index baece61169f..41bfcae1fbf 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1479,6 +1479,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, * @buf: the data to write * @page: page number to write * @cached: cached programming + * @raw: use _raw version of write_page */ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int page, int cached, int raw) -- cgit From 2b6e845986347ef86729e8651908af3e8a8441f5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 28 Oct 2006 10:38:30 -0700 Subject: [PATCH] md: fix bug where spares don't always get rebuilt properly when they become live If save_raid_disk is >= 0, then the device could be a device that is already in sync that is being re-added. So we need to default this value to -1. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 7daa7b1e145..c40ce9f9cc9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2003,6 +2003,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi kobject_init(&rdev->kobj); rdev->desc_nr = -1; + rdev->saved_raid_disk = -1; rdev->flags = 0; rdev->data_offset = 0; rdev->sb_events = 0; -- cgit From 01ab5662f573fe3a6bcefa200f15ab3069cec8a3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 28 Oct 2006 10:38:30 -0700 Subject: [PATCH] md: simplify checking of available size when resizing an array When "mdadm --grow --size=xxx" is used to resize an array (use more or less of each device), we check the new siza against the available space in each device. We already have that number recorded in rdev->size, so calculating it is pointless (and wrong in one obscure case). Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index c40ce9f9cc9..50ab4a936e3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4045,11 +4045,8 @@ static int update_size(mddev_t *mddev, unsigned long size) return -EBUSY; ITERATE_RDEV(mddev,rdev,tmp) { sector_t avail; - if (rdev->sb_offset > rdev->data_offset) - avail = (rdev->sb_offset*2) - rdev->data_offset; - else - avail = get_capacity(rdev->bdev->bd_disk) - - rdev->data_offset; + avail = rdev->size * 2; + if (fit && (size == 0 || size > avail/2)) size = avail/2; if (avail < ((sector_t)size << 1)) -- cgit From 750a8f3e8f64654a584e54038c2c8db380813c79 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 28 Oct 2006 10:38:31 -0700 Subject: [PATCH] md: fix up maintenance of ->degraded in multipath A recent fix which made sure ->degraded was initialised properly exposed a second bug - ->degraded wasn't been updated when drives failed or were hot-added. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/multipath.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index a6260f0e3b9..14da37fee37 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -277,6 +277,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) set_bit(Faulty, &rdev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags); conf->working_disks--; + mddev->degraded++; printk(KERN_ALERT "multipath: IO failure on %s," " disabling IO path. \n Operation continuing" " on %d IO paths.\n", @@ -336,6 +337,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); conf->working_disks++; + mddev->degraded--; rdev->raid_disk = path; set_bit(In_sync, &rdev->flags); rcu_assign_pointer(p->rdev, rdev); -- cgit From 969b755aadf7bcf3df5991a127a103acd0145a52 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Oct 2006 10:38:32 -0700 Subject: [PATCH] md: fix printk format warnings, seen on powerpc64: drivers/md/raid1.c:1479: warning: long long unsigned int format, long unsigned int arg (arg 4) drivers/md/raid10.c:1475: warning: long long unsigned int format, long unsigned int arg (arg 4) Signed-off-by: Randy Dunlap Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 4 ++-- drivers/md/raid10.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index dc9d2def027..656fae912fe 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk, "raid1:%s: read error corrected " "(%d sectors at %llu on %s)\n", mdname(mddev), s, - (unsigned long long)sect + - rdev->data_offset, + (unsigned long long)(sect + + rdev->data_offset), bdevname(rdev->bdev, b)); } } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 74f17a9a6eb..7492d6033ac 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) "raid10:%s: read error corrected" " (%d sectors at %llu on %s)\n", mdname(mddev), s, - (unsigned long long)sect+ - rdev->data_offset, + (unsigned long long)(sect+ + rdev->data_offset), bdevname(rdev->bdev, b)); rdev_dec_pending(rdev, mddev); -- cgit From 760fe9ad1692361770bb56fa5c69cf6b3354858c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Oct 2006 10:38:39 -0700 Subject: [PATCH] ioc4: fix printk format warning Fix printk format warning: drivers/misc/ioc4.c:213: warning: long long int format, u64 arg (arg 3) Signed-off-by: Randy Dunlap Acked-by: Brent Casavant Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ioc4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 79354bbbbd6..b995a15b752 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -210,8 +210,8 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) do_div(ns, IOC4_EXTINT_COUNT_DIVISOR); printk(KERN_DEBUG - "IOC4 %s: PCI clock is %lld ns.\n", - pci_name(idd->idd_pdev), ns); + "IOC4 %s: PCI clock is %llu ns.\n", + pci_name(idd->idd_pdev), (unsigned long long)ns); } /* Remember results. We store the extint clock period rather -- cgit From 7b92aadfdae85ef837db343be38d4172115be72b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Oct 2006 10:38:40 -0700 Subject: [PATCH] cciss: fix printk format warning Fix printk format warnings: drivers/block/cciss.c:2000: warning: long long int format, long unsigned int arg (arg 2) drivers/block/cciss.c:2035: warning: long long int format, long unsigned int arg (arg 2) Signed-off-by: Randy Dunlap Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/cciss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index bc6602606fb..6ffe2b2bdac 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1992,8 +1992,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, *block_size = BLOCK_SIZE; } if (*total_size != (__u32) 0) - printk(KERN_INFO " blocks= %lld block_size= %d\n", - *total_size, *block_size); + printk(KERN_INFO " blocks= %llu block_size= %d\n", + (unsigned long long)*total_size, *block_size); kfree(buf); return; } @@ -2027,8 +2027,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, *total_size = 0; *block_size = BLOCK_SIZE; } - printk(KERN_INFO " blocks= %lld block_size= %d\n", - *total_size, *block_size); + printk(KERN_INFO " blocks= %llu block_size= %d\n", + (unsigned long long)*total_size, *block_size); kfree(buf); return; } -- cgit From eba6cd671427df295c10b54ee69cd5de419d38fe Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Oct 2006 10:38:55 -0700 Subject: [PATCH] move SYS_HYPERVISOR inside the Generic Driver menu Put SYS_HYPERVISOR inside the Generic Driver Config menu where it should be. Otherwise xconfig displays it as a dangling (lost) menu item under Device Drivers, all by itself (when all options are displayed). Signed-off-by: Randy Dunlap Cc: Cc: Martin Schwidefsky Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 0b4e2243693..1429f3a2629 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -37,8 +37,8 @@ config DEBUG_DRIVER If you are unsure about this, say N here. -endmenu - config SYS_HYPERVISOR bool default n + +endmenu -- cgit From c333526f489044be2b93085720eb898f0037b346 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 28 Oct 2006 10:38:57 -0700 Subject: [PATCH] JMB 368 PATA detection The Jmicron JMB368 is PATA only so has the PATA on function zero. Don't therefore skip function zero on this device when probing Signed-off-by: Alan Cox Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/generic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index ad418ce882c..e72ab36a549 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -247,8 +247,10 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi (!(PCI_FUNC(dev->devfn) & 1))) goto out; - if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1) - goto out; + if (dev->vendor == PCI_VENDOR_ID_JMICRON) { + if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1) + goto out; + } if (dev->vendor != PCI_VENDOR_ID_JMICRON) { pci_read_config_word(dev, PCI_COMMAND, &command); -- cgit From 84b5abe69ff600a559e1a1fa29f1edad707d4e2f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 28 Oct 2006 22:30:17 +0100 Subject: [ARM] Fix i2c-pxa slave mode support i2c-pxa times out when trying to enable slave mode due to an incorrect test. Also, check that i2c->slave is non-NULL before dereferencing it. Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pxa.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 81050d3c9b2..c95a6c15416 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -272,7 +272,8 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c) dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", __func__, (long)jiffies, ISR, ICR, IBMR); - if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD || + if ((ISR & (ISR_UB|ISR_IBB)) == 0 || + (ISR & ISR_SAD) != 0 || (ICR & ICR_SCLE) == 0) { if (i2c_debug > 1) dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); @@ -492,7 +493,10 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr) if (isr & ISR_BED) { /* what should we do here? */ } else { - int ret = i2c->slave->read(i2c->slave->data); + int ret = 0; + + if (i2c->slave != NULL) + ret = i2c->slave->read(i2c->slave->data); IDBR = ret; ICR |= ICR_TB; /* allow next byte */ -- cgit From 9468613b2bb0a386af563953b613efc6c77bd8c1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 28 Oct 2006 22:42:56 +0100 Subject: [ARM] Fix suspend oops caused by PXA2xx PCMCIA driver The PXA2xx PCMCIA driver was registering a device_driver with the platform_bus_type. Unfortunately, this causes data outside the device_driver structure to be dereferenced as if it were a platform_driver structure, causing an oops. Convert the PXA2xx core driver to use the proper platform_driver structure. Signed-off-by: Russell King --- drivers/pcmcia/pxa2xx_base.c | 41 +++++++++++++++++++++++++++++------------ drivers/pcmcia/pxa2xx_base.h | 2 +- drivers/pcmcia/pxa2xx_lubbock.c | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index b3518131ea0..dca9f8549b3 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -166,7 +166,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, } #endif -int pxa2xx_drv_pcmcia_probe(struct device *dev) +int __pxa2xx_drv_pcmcia_probe(struct device *dev) { int ret; struct pcmcia_low_level *ops; @@ -203,35 +203,52 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev) return ret; } -EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe); +EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe); -static int pxa2xx_drv_pcmcia_resume(struct device *dev) + +static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) +{ + return __pxa2xx_drv_pcmcia_probe(&dev->dev); +} + +static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) +{ + return soc_common_drv_pcmcia_remove(&dev->dev); +} + +static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state) +{ + return pcmcia_socket_dev_suspend(&dev->dev, state); +} + +static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) { - struct pcmcia_low_level *ops = dev->platform_data; + struct pcmcia_low_level *ops = dev->dev.platform_data; int nr = ops ? ops->nr : 0; MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); - return pcmcia_socket_dev_resume(dev); + return pcmcia_socket_dev_resume(&dev->dev); } -static struct device_driver pxa2xx_pcmcia_driver = { +static struct platform_driver pxa2xx_pcmcia_driver = { .probe = pxa2xx_drv_pcmcia_probe, - .remove = soc_common_drv_pcmcia_remove, - .suspend = pcmcia_socket_dev_suspend, + .remove = pxa2xx_drv_pcmcia_remove, + .suspend = pxa2xx_drv_pcmcia_suspend, .resume = pxa2xx_drv_pcmcia_resume, - .name = "pxa2xx-pcmcia", - .bus = &platform_bus_type, + .driver = { + .name = "pxa2xx-pcmcia", + }, }; static int __init pxa2xx_pcmcia_init(void) { - return driver_register(&pxa2xx_pcmcia_driver); + return platform_driver_register(&pxa2xx_pcmcia_driver); } static void __exit pxa2xx_pcmcia_exit(void) { - driver_unregister(&pxa2xx_pcmcia_driver); + platform_driver_unregister(&pxa2xx_pcmcia_driver); } fs_initcall(pxa2xx_pcmcia_init); diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index e46cff345d4..235d681652c 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h @@ -1,3 +1,3 @@ /* temporary measure */ -extern int pxa2xx_drv_pcmcia_probe(struct device *); +extern int __pxa2xx_drv_pcmcia_probe(struct device *); diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index fd1f691c7c2..a92f11143c4 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -260,7 +260,7 @@ int __init pcmcia_lubbock_init(struct sa1111_dev *sadev) lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); sadev->dev.platform_data = &lubbock_pcmcia_ops; - ret = pxa2xx_drv_pcmcia_probe(&sadev->dev); + ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); } return ret; -- cgit From 346f5c7ee7fa4ebee0e4c96415a7e59716bfa1d0 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 29 Oct 2006 19:52:49 +0100 Subject: ieee1394: ohci1394: revert fail on error in suspend Some errors during preparation for suspended state can be skipped with a warning instead of a failure of the whole suspend transition, notably an error in pci_set_power_state. Signed-off-by: Stefan Richter --- drivers/ieee1394/ohci1394.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index dea13525df8..6e8ea9110c4 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -3552,12 +3552,21 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) { int err; + printk(KERN_INFO "%s does not fully support suspend and resume yet\n", + OHCI1394_DRIVER_NAME); + err = pci_save_state(pdev); - if (err) - goto out; + if (err) { + printk(KERN_ERR "%s: pci_save_state failed with %d\n", + OHCI1394_DRIVER_NAME, err); + return err; + } err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); +#ifdef OHCI1394_DEBUG if (err) - goto out; + printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n", + OHCI1394_DRIVER_NAME, err); +#endif /* OHCI1394_DEBUG */ /* PowerMac suspend code comes last */ #ifdef CONFIG_PPC_PMAC @@ -3570,8 +3579,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); } #endif /* CONFIG_PPC_PMAC */ -out: - return err; + + return 0; } #endif /* CONFIG_PM */ -- cgit From 150ed8ed63b96d7f93ef7e6081797aa0df2b1abd Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 29 Oct 2006 03:43:19 +0900 Subject: [WATCHDOG] sc1200wdt.c pnp unregister fix. If no devices found or invalid parameter is specified, scl200wdt_pnp_driver is left unregistered. It breaks global list of pnp drivers. Signed-off-by: Akinobu Mita Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton --- drivers/char/watchdog/sc1200wdt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index d8d0f28e0ac..e3239833e4b 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c @@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void) if (io == -1) { printk(KERN_ERR PFX "io parameter must be specified\n"); ret = -EINVAL; - goto out_clean; + goto out_pnp; } #if defined CONFIG_PNP @@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void) if (!request_region(io, io_len, SC1200_MODULE_NAME)) { printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); ret = -EBUSY; - goto out_clean; + goto out_pnp; } ret = sc1200wdt_probe(); @@ -435,6 +435,11 @@ out_rbt: out_io: release_region(io, io_len); +out_pnp: +#if defined CONFIG_PNP + if (isapnp) + pnp_unregister_driver(&scl200wdt_pnp_driver); +#endif goto out_clean; } -- cgit From 209ad53bc19667a128d9c51beba873a5c62bff6e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 29 Oct 2006 17:31:49 -0800 Subject: Revert "r8169: mac address change support" This reverts commit a2b98a697fa4e7564f78905b83db122824916cf9. As per Guennadi Liakhovetski, the mac address change support code breaks some normal uses (_without_ any address changes), and until it's all sorted out, we're better off without it. Says Francois: "Go revert it. Despite what I claimed, I can not find a third-party confirmation by email that it works elsewhere. It would probably be enough to remove the call to __rtl8169_set_mac_addr() in rtl8169_hw_start() though." See also http://bugzilla.kernel.org/show_bug.cgi?id=6032 Cc: Guennadi Liakhovetski Acked-by: Francois Romieu Signed-off-by: Linus Torvalds --- drivers/net/r8169.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d132fe7d475..27f90b2139c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1397,41 +1397,6 @@ static void rtl8169_netpoll(struct net_device *dev) } #endif -static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr) -{ - unsigned int i, j; - - RTL_W8(Cfg9346, Cfg9346_Unlock); - for (i = 0; i < 2; i++) { - __le32 l = 0; - - for (j = 0; j < 4; j++) { - l <<= 8; - l |= dev->dev_addr[4*i + j]; - } - RTL_W32(MAC0 + 4*i, cpu_to_be32(l)); - } - RTL_W8(Cfg9346, Cfg9346_Lock); -} - -static int rtl8169_set_mac_addr(struct net_device *dev, void *p) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - - if (netif_running(dev)) { - spin_lock_irq(&tp->lock); - __rtl8169_set_mac_addr(dev, tp->mmio_addr); - spin_unlock_irq(&tp->lock); - } - return 0; -} - static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, void __iomem *ioaddr) { @@ -1681,7 +1646,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->stop = rtl8169_close; dev->tx_timeout = rtl8169_tx_timeout; dev->set_multicast_list = rtl8169_set_rx_mode; - dev->set_mac_address = rtl8169_set_mac_addr; dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; @@ -1929,8 +1893,6 @@ rtl8169_hw_start(struct net_device *dev) /* Enable all known interrupts by setting the interrupt mask. */ RTL_W16(IntrMask, rtl8169_intr_mask); - __rtl8169_set_mac_addr(dev, ioaddr); - netif_start_queue(dev); } -- cgit From 37af6560f7978c60791b5f3df17ce8b3e97f2d6e Mon Sep 17 00:00:00 2001 From: Christophe Saout Date: Mon, 30 Oct 2006 20:39:08 +0100 Subject: [PATCH] Fix dmsetup table output change Fix dm-crypt after the block cipher API changes to correctly return the backwards compatible cipher-chainmode[-ivmode] format for "dmsetup table". Signed-off-by: Christophe Saout Cc: Alasdair G Kergon Cc: Herbert Xu Signed-off-by: Linus Torvalds diff linux-2.6.19-rc3.orig/drivers/md/dm-crypt.c linux-2.6.19-rc3/drivers/md/dm-crypt.c --- drivers/md/dm-crypt.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index a625576fdee..08a40f4e4f6 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -915,8 +915,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen) { struct crypt_config *cc = (struct crypt_config *) ti->private; - const char *cipher; - const char *chainmode = NULL; unsigned int sz = 0; switch (type) { @@ -925,14 +923,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: - cipher = crypto_blkcipher_name(cc->tfm); - - chainmode = cc->chainmode; - if (cc->iv_mode) - DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode); + DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode, + cc->iv_mode); else - DMEMIT("%s-%s ", cipher, chainmode); + DMEMIT("%s-%s ", cc->cipher, cc->chainmode); if (cc->key_size > 0) { if ((maxlen - sz) < ((cc->key_size << 1) + 1)) -- cgit From a5a89bae0449634fdb7aa7cdb1c5ba154e4a789b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 29 Oct 2006 22:46:33 -0800 Subject: [PATCH] ioc4_serial: irq flags fix Use the correct type for the CPU flags. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/ioc4_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index ff4fa25f9fd..711bd151143 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -921,7 +921,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir) { struct ioc4_port *port = (struct ioc4_port *)arg; struct hooks *hooks = port->ip_hooks; - unsigned int flags; + unsigned long flags; spin_lock_irqsave(&port->ip_lock, flags); @@ -1834,7 +1834,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) struct ioc4_port *port = (struct ioc4_port *)arg; struct hooks *hooks = port->ip_hooks; unsigned int rx_high_rd_aborted = 0; - unsigned int flags; + unsigned long flags; struct uart_port *the_port; int loop_counter; -- cgit From 70812522b847bdb8fabee963191734f5fa3143f3 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 29 Oct 2006 22:46:35 -0800 Subject: [PATCH] isdn/gigaset: avoid cs->dev null pointer dereference When gigaset_initbcs() is called, cs->dev is not initialized yet. If dev_alloc_skb() failed in this function, NULL poinster dereference will happen at dev_warn(). Cc: Kai Germaschewski Cc: Hansjoerg Lipp Cc: Tilman Schmidt Acked-by: Karsten Keil Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/gigaset/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index aca165d43aa..d8d256daddd 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -616,7 +616,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - dev_warn(cs->dev, "could not allocate skb\n"); + gig_dbg(DEBUG_INIT, "could not allocate skb\n"); bcs->inputstate |= INS_skip_frame; } -- cgit From 7259f0d05d595b73ef312a082e628627c6414969 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 29 Oct 2006 22:46:36 -0800 Subject: [PATCH] lockdep: annotate DECLARE_WAIT_QUEUE_HEAD kernel: INFO: trying to register non-static key. kernel: the code is fine but needs lockdep annotation. kernel: turning off the locking correctness validator. kernel: [] show_trace_log_lvl+0x58/0x16a kernel: [] show_trace+0xd/0x10 kernel: [] dump_stack+0x19/0x1b kernel: [] __lock_acquire+0xf0/0x90d kernel: [] lock_acquire+0x4b/0x6b kernel: [] _spin_lock_irqsave+0x22/0x32 kernel: [] prepare_to_wait+0x17/0x4b kernel: [] lpfc_do_work+0xdd/0xcc2 [lpfc] kernel: [] kthread+0xc3/0xf2 kernel: [] kernel_thread_helper+0x5/0xb Another case of non-static lockdep keys; duplicate the paradigm set by DECLARE_COMPLETION_ONSTACK and introduce DECLARE_WAIT_QUEUE_HEAD_ONSTACK. Signed-off-by: Peter Zijlstra Cc: Greg KH Cc: Markus Lidel Acked-by: Ingo Molnar Cc: Arjan van de Ven Cc: James Bottomley Cc: Marcel Holtmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/bluetooth/bluecard_cs.c | 2 +- drivers/message/i2o/exec-osm.c | 2 +- drivers/scsi/dpt/dpti_i2o.h | 2 +- drivers/scsi/imm.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- drivers/scsi/ppa.c | 2 +- drivers/usb/net/usbnet.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 845b8680032..cbc07250b89 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -282,7 +282,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) clear_bit(ready_bit, &(info->tx_state)); if (bt_cb(skb)->pkt_type & 0x80) { - DECLARE_WAIT_QUEUE_HEAD(wq); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); DEFINE_WAIT(wait); unsigned char baud_reg; diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 01a5a702b03..a2350640384 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -124,7 +124,7 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, unsigned long timeout, struct i2o_dma *dma) { - DECLARE_WAIT_QUEUE_HEAD(wq); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; unsigned long flags; diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h index b3fa7ed71fa..5a49216fe4c 100644 --- a/drivers/scsi/dpt/dpti_i2o.h +++ b/drivers/scsi/dpt/dpti_i2o.h @@ -49,7 +49,7 @@ #include typedef wait_queue_head_t adpt_wait_queue_head_t; -#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait) +#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait) typedef wait_queue_t adpt_wait_queue_t; /* diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 2d95ac9c32c..e31f6122106 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1153,7 +1153,7 @@ static int __imm_attach(struct parport *pb) { struct Scsi_Host *host; imm_struct *dev; - DECLARE_WAIT_QUEUE_HEAD(waiting); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); DEFINE_WAIT(wait); int ports; int modes, ppb; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d586c3d3b0d..19c79a0549a 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -305,7 +305,7 @@ lpfc_do_work(void *p) { struct lpfc_hba *phba = p; int rc; - DECLARE_WAIT_QUEUE_HEAD(work_waitq); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq); set_user_nice(current, -20); phba->work_wait = &work_waitq; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 24a1779b9af..582f5ea4e84 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2983,7 +2983,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, struct lpfc_iocbq * prspiocbq, uint32_t timeout) { - DECLARE_WAIT_QUEUE_HEAD(done_q); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); long timeleft, timeout_req = 0; int retval = IOCB_SUCCESS; uint32_t creg_val; @@ -3061,7 +3061,7 @@ int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout) { - DECLARE_WAIT_QUEUE_HEAD(done_q); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); DECLARE_WAITQUEUE(wq_entry, current); uint32_t timeleft = 0; int retval; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index b0eba39f208..89a2a9f11e4 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -1012,7 +1012,7 @@ static LIST_HEAD(ppa_hosts); static int __ppa_attach(struct parport *pb) { struct Scsi_Host *host; - DECLARE_WAIT_QUEUE_HEAD(waiting); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); DEFINE_WAIT(wait); ppa_struct *dev; int ports; diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index cf3d20eb781..40873635d80 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net) { struct usbnet *dev = netdev_priv(net); int temp; - DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); netif_stop_queue (net); -- cgit From 2b52c9590d5ad2fb67b720ec12018dd2cf061480 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Sun, 29 Oct 2006 22:46:44 -0800 Subject: [PATCH] drivers/ide/pci/generic.c: add missing newline to the all-generic-ide message Signed-off-by: Sergey Vlasov Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index e72ab36a549..9f306880491 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -48,7 +48,7 @@ static int ide_generic_all; /* Set to claim all devices */ static int __init ide_generic_all_on(char *unused) { ide_generic_all = 1; - printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers."); + printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); return 1; } __setup("all-generic-ide", ide_generic_all_on); -- cgit From d458fd82c9bb536e4a582955e88554a02a92bf78 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Oct 2006 17:15:20 -0700 Subject: [NET] sealevel: uses arp_broken_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Wed, 25 Oct 2006 18:03:13 +0200 Toralf FĂśrster wrote: > WARNING: "arp_broken_ops" [drivers/net/wan/sealevel.ko] undefined! > make[1]: *** [__modpost] Error 1 > make: *** [modules] Error 2 > > Here's the config: ... > # CONFIG_INET is not set > CONFIG_SEALEVEL_4021=m Sealevel uses arp_broken_ops so it needs to depend on INET. Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/wan/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 58b7efbb075..b5d0d7fb647 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig @@ -127,7 +127,7 @@ config LANMEDIA # There is no way to detect a Sealevel board. Force it modular config SEALEVEL_4021 tristate "Sealevel Systems 4021 support" - depends on WAN && ISA && m && ISA_DMA_API + depends on WAN && ISA && m && ISA_DMA_API && INET help This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. -- cgit From c20e3945c761502b9d5d73ef0ff5f1a84b3a717e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 29 Oct 2006 16:14:55 -0800 Subject: [ETH1394]: Fix unaligned accesses. Several u64 objects are derefernced in situations where the pointer is not guarenteed to be aligned correctly. Use get_unaligned() as needed. Thanks to Will Simoneau for lots of testing and debugging help. Signed-off-by: David S. Miller Acked-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 8a7b8fab623..31e5cc49d61 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include "config_roms.h" @@ -491,7 +492,7 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) int i; struct eth1394_priv *priv = netdev_priv(dev); struct hpsb_host *host = priv->host; - u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3])); + u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3])); u16 maxpayload = 1 << (host->csr.max_rec + 1); int max_speed = IEEE1394_SPEED_MAX; @@ -514,8 +515,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) ETHER1394_GASP_OVERHEAD))); /* Set our hardware address while we're at it */ - *(u64*)dev->dev_addr = guid; - *(u64*)dev->broadcast = ~0x0ULL; + memcpy(dev->dev_addr, &guid, sizeof(u64)); + memset(dev->broadcast, 0xff, sizeof(u64)); } spin_unlock_irqrestore (&priv->lock, flags); @@ -894,6 +895,7 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, u16 maxpayload; struct eth1394_node_ref *node; struct eth1394_node_info *node_info; + __be64 guid; /* Sanity check. MacOSX seems to be sending us 131 in this * field (atleast on my Panther G5). Not sure why. */ @@ -902,8 +904,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); + guid = get_unaligned(&arp1394->s_uniq_id); node = eth1394_find_node_guid(&priv->ip_node_list, - be64_to_cpu(arp1394->s_uniq_id)); + be64_to_cpu(guid)); if (!node) { return 0; } @@ -931,10 +934,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, arp_ptr += arp->ar_pln; /* skip over sender IP addr */ if (arp->ar_op == htons(ARPOP_REQUEST)) - /* just set ARP req target unique ID to 0 */ - *((u64*)arp_ptr) = 0; + memset(arp_ptr, 0, sizeof(u64)); else - *((u64*)arp_ptr) = *((u64*)dev->dev_addr); + memcpy(arp_ptr, dev->dev_addr, sizeof(u64)); } /* Now add the ethernet header. */ @@ -1675,8 +1677,10 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) priv->bc_dgl++; } else { + __be64 guid = get_unaligned((u64 *)eth->h_dest); + node = eth1394_find_node_guid(&priv->ip_node_list, - be64_to_cpu(*(u64*)eth->h_dest)); + be64_to_cpu(guid)); if (!node) { ret = -EAGAIN; goto fail; -- cgit From 1aea7e00f6b83d32d359aeb8d670f1f7aaa88d55 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Tue, 31 Oct 2006 11:47:27 +0900 Subject: video: Fix include in hp680_bl. The hp6xx.h header moved location, causing the build to fail, fix it up. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- drivers/video/backlight/hp680_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index fe1488374f6..e3993213d10 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #define HP680_MAX_INTENSITY 255 -- cgit From 2e7a7426282bfa2d7dff6eddc5485af8c79a68f3 Mon Sep 17 00:00:00 2001 From: Erez Zilber Date: Sun, 22 Oct 2006 10:28:38 +0200 Subject: IB/iser: Start connection after enabling iSER When a connection is started (a new connection or a recovered one), iSER should prepare its resources for full-featured mode and only then notify the iSCSI layer that it is ready to start queueing commands. Signed-off-by: Erez Zilber Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index eb6f98d8228..9b2041e25d5 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -363,11 +363,11 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) struct iscsi_conn *conn = cls_conn->dd_data; int err; - err = iscsi_conn_start(cls_conn); + err = iser_conn_set_full_featured_mode(conn); if (err) return err; - return iser_conn_set_full_featured_mode(conn); + return iscsi_conn_start(cls_conn); } static struct iscsi_transport iscsi_iser_transport; -- cgit From 255d0c14b3757e8bd85add874e4dca4c3621b39e Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Tue, 24 Oct 2006 13:22:28 -0700 Subject: RDMA/cma: rdma_bind_addr() leaks a cma_dev reference count rdma_bind_addr() leaks a cma_dev reference count in failure case. Signed-off-by: Krishna Kumar Signed-off-by: Sean Hefty --- drivers/infiniband/core/cma.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 9ae4f3a67c7..d8ca3c1368b 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1762,22 +1762,29 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (!cma_any_addr(addr)) { ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); - if (!ret) { - mutex_lock(&lock); - ret = cma_acquire_dev(id_priv); - mutex_unlock(&lock); - } if (ret) - goto err; + goto err1; + + mutex_lock(&lock); + ret = cma_acquire_dev(id_priv); + mutex_unlock(&lock); + if (ret) + goto err1; } memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); ret = cma_get_port(id_priv); if (ret) - goto err; + goto err2; return 0; -err: +err2: + if (!cma_any_addr(addr)) { + mutex_lock(&lock); + cma_detach_from_dev(id_priv); + mutex_unlock(&lock); + } +err1: cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); return ret; } -- cgit From 04d03bc576f244bfa9692452aab83fa357ac0d57 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 25 Oct 2006 15:28:08 +1000 Subject: IB/ehca: Fix eHCA driver compilation for uniprocessor The eHCA driver does not compile for a uniprocessor configuration (CONFIG_SMP=n), due to H_SUCCESS and other symbols being undefined. This fixes it. Signed-off-by: Paul Mackerras Acked-by: Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_tools.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 809da3ef706..973c4b59154 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h @@ -63,6 +63,7 @@ #include #include #include +#include extern int ehca_debug_level; -- cgit From 8de94ce19dd3c6fc6e9d9658da11cf3d76841ee5 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 27 Oct 2006 17:28:35 -0500 Subject: IB/amso1100: Use dma_alloc_coherent() instead of kmalloc/dma_map_single The Ammasso driver needs to use dma_alloc_coherent() for allocating memory that will be used by the HW for dma. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/amso1100/c2_alloc.c | 13 ++++---- drivers/infiniband/hw/amso1100/c2_cq.c | 18 ++++------- drivers/infiniband/hw/amso1100/c2_rnic.c | 52 +++++++++++++------------------ 3 files changed, 33 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c index 028a60bbfca..0315f99e419 100644 --- a/drivers/infiniband/hw/amso1100/c2_alloc.c +++ b/drivers/infiniband/hw/amso1100/c2_alloc.c @@ -42,13 +42,14 @@ static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask, { int i; struct sp_chunk *new_head; + dma_addr_t dma_addr; - new_head = (struct sp_chunk *) __get_free_page(gfp_mask); + new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE, + &dma_addr, gfp_mask); if (new_head == NULL) return -ENOMEM; - new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head, - PAGE_SIZE, DMA_FROM_DEVICE); + new_head->dma_addr = dma_addr; pci_unmap_addr_set(new_head, mapping, new_head->dma_addr); new_head->next = NULL; @@ -80,10 +81,8 @@ void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root) while (root) { next = root->next; - dma_unmap_single(c2dev->ibdev.dma_device, - pci_unmap_addr(root, mapping), PAGE_SIZE, - DMA_FROM_DEVICE); - __free_page((struct page *) root); + dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root, + pci_unmap_addr(root, mapping)); root = next; } } diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c index 9d7bcc5ade9..05c9154d46f 100644 --- a/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/drivers/infiniband/hw/amso1100/c2_cq.c @@ -246,20 +246,17 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) { - - dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping), - mq->q_size * mq->msg_size, DMA_FROM_DEVICE); - free_pages((unsigned long) mq->msg_pool.host, - get_order(mq->q_size * mq->msg_size)); + dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size, + mq->msg_pool.host, pci_unmap_addr(mq, mapping)); } static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, int msg_size) { - unsigned long pool_start; + u8 *pool_start; - pool_start = __get_free_pages(GFP_KERNEL, - get_order(q_size * msg_size)); + pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, + &mq->host_dma, GFP_KERNEL); if (!pool_start) return -ENOMEM; @@ -267,13 +264,10 @@ static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, 0, /* index (currently unknown) */ q_size, msg_size, - (u8 *) pool_start, + pool_start, NULL, /* peer (currently unknown) */ C2_MQ_HOST_TARGET); - mq->host_dma = dma_map_single(c2dev->ibdev.dma_device, - (void *)pool_start, - q_size * msg_size, DMA_FROM_DEVICE); pci_unmap_addr_set(mq, mapping, mq->host_dma); return 0; diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 30409e17960..030238d335e 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -517,14 +517,12 @@ int c2_rnic_init(struct c2_dev *c2dev) /* Initialize the Verbs Reply Queue */ qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE)); msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE)); - q1_pages = kmalloc(qsize * msgsize, GFP_KERNEL); + q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, + &c2dev->rep_vq.host_dma, GFP_KERNEL); if (!q1_pages) { err = -ENOMEM; goto bail1; } - c2dev->rep_vq.host_dma = dma_map_single(c2dev->ibdev.dma_device, - (void *)q1_pages, qsize * msgsize, - DMA_FROM_DEVICE); pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma); pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages, (unsigned long long) c2dev->rep_vq.host_dma); @@ -540,14 +538,12 @@ int c2_rnic_init(struct c2_dev *c2dev) /* Initialize the Asynchronus Event Queue */ qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE)); msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE)); - q2_pages = kmalloc(qsize * msgsize, GFP_KERNEL); + q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, + &c2dev->aeq.host_dma, GFP_KERNEL); if (!q2_pages) { err = -ENOMEM; goto bail2; } - c2dev->aeq.host_dma = dma_map_single(c2dev->ibdev.dma_device, - (void *)q2_pages, qsize * msgsize, - DMA_FROM_DEVICE); pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages, (unsigned long long) c2dev->rep_vq.host_dma); @@ -597,17 +593,13 @@ int c2_rnic_init(struct c2_dev *c2dev) bail4: vq_term(c2dev); bail3: - dma_unmap_single(c2dev->ibdev.dma_device, - pci_unmap_addr(&c2dev->aeq, mapping), - c2dev->aeq.q_size * c2dev->aeq.msg_size, - DMA_FROM_DEVICE); - kfree(q2_pages); + dma_free_coherent(&c2dev->pcidev->dev, + c2dev->aeq.q_size * c2dev->aeq.msg_size, + q2_pages, pci_unmap_addr(&c2dev->aeq, mapping)); bail2: - dma_unmap_single(c2dev->ibdev.dma_device, - pci_unmap_addr(&c2dev->rep_vq, mapping), - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - DMA_FROM_DEVICE); - kfree(q1_pages); + dma_free_coherent(&c2dev->pcidev->dev, + c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, + q1_pages, pci_unmap_addr(&c2dev->rep_vq, mapping)); bail1: c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); bail0: @@ -640,19 +632,17 @@ void c2_rnic_term(struct c2_dev *c2dev) /* Free the verbs request allocator */ vq_term(c2dev); - /* Unmap and free the asynchronus event queue */ - dma_unmap_single(c2dev->ibdev.dma_device, - pci_unmap_addr(&c2dev->aeq, mapping), - c2dev->aeq.q_size * c2dev->aeq.msg_size, - DMA_FROM_DEVICE); - kfree(c2dev->aeq.msg_pool.host); - - /* Unmap and free the verbs reply queue */ - dma_unmap_single(c2dev->ibdev.dma_device, - pci_unmap_addr(&c2dev->rep_vq, mapping), - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - DMA_FROM_DEVICE); - kfree(c2dev->rep_vq.msg_pool.host); + /* Free the asynchronus event queue */ + dma_free_coherent(&c2dev->pcidev->dev, + c2dev->aeq.q_size * c2dev->aeq.msg_size, + c2dev->aeq.msg_pool.host, + pci_unmap_addr(&c2dev->aeq, mapping)); + + /* Free the verbs reply queue */ + dma_free_coherent(&c2dev->pcidev->dev, + c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, + c2dev->rep_vq.msg_pool.host, + pci_unmap_addr(&c2dev->rep_vq, mapping)); /* Free the MQ shared pointer pool */ c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); -- cgit From d7b748d63c908a0a85099ce546594192ae0926f6 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 30 Oct 2006 20:52:53 -0800 Subject: IB/amso1100: Fix incorrect pr_debug() pr_debug() was printing the wrong stuff. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/amso1100/c2_rnic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 030238d335e..21d9612a56c 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -545,8 +545,8 @@ int c2_rnic_init(struct c2_dev *c2dev) goto bail2; } pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); - pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages, - (unsigned long long) c2dev->rep_vq.host_dma); + pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q2_pages, + (unsigned long long) c2dev->aeq.host_dma); c2_mq_rep_init(&c2dev->aeq, 2, qsize, -- cgit From 0b26c88f29ad8bcf91a2ea8f25a36f2028ebabea Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Wed, 25 Oct 2006 12:54:20 +0200 Subject: IB/uverbs: Return sq_draining value in query_qp response Return the sq_draining value back to user space for query_qp instead of the en_sqd_async notify value, which is valid only for modify_qp. For query_qp, the draining status should returned. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b72c7f69ca9..743247ec065 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1214,7 +1214,7 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, resp.qp_access_flags = attr->qp_access_flags; resp.pkey_index = attr->pkey_index; resp.alt_pkey_index = attr->alt_pkey_index; - resp.en_sqd_async_notify = attr->en_sqd_async_notify; + resp.sq_draining = attr->sq_draining; resp.max_rd_atomic = attr->max_rd_atomic; resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; resp.min_rnr_timer = attr->min_rnr_timer; -- cgit From 80fc115d461031dc66bb7f31b8c84868e370fea6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 30 Oct 2006 20:41:11 -0800 Subject: [PATCH] SCSI: ISCSI build failure SCSI_QLA_ISCSI needs to depend on NET to prevent build (link) failures that are caused by selecting SCSI_ISCSI_ATTRS. Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- drivers/scsi/qla4xxx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig index 08a07f0b8d9..69cbff3f57c 100644 --- a/drivers/scsi/qla4xxx/Kconfig +++ b/drivers/scsi/qla4xxx/Kconfig @@ -1,6 +1,6 @@ config SCSI_QLA_ISCSI tristate "QLogic ISP4XXX host adapter family support" - depends on PCI && SCSI + depends on PCI && SCSI && NET select SCSI_ISCSI_ATTRS ---help--- This driver supports the QLogic 40xx (ISP4XXX) iSCSI host -- cgit From 68586b67ab1a2fd618f79e29a06f10ae886f4b46 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 30 Oct 2006 16:31:52 +0200 Subject: IB/mthca: Fix MAD extended header format for MAD_IFC firmware command Several fields in an incoming MAD extended info header were passed into the MAD_IFC firmware command at incorrect offsets (mostly off by 4 bytes). As the result, the HCA will fail to generate traps in which this info is needed (e.g. traps which include the GRH of the incoming packet), in violation of the IB spec. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_cmd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 99a94d71093..768df7265b8 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1820,11 +1820,11 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, #define MAD_IFC_BOX_SIZE 0x400 #define MAD_IFC_MY_QPN_OFFSET 0x100 -#define MAD_IFC_RQPN_OFFSET 0x104 -#define MAD_IFC_SL_OFFSET 0x108 -#define MAD_IFC_G_PATH_OFFSET 0x109 -#define MAD_IFC_RLID_OFFSET 0x10a -#define MAD_IFC_PKEY_OFFSET 0x10e +#define MAD_IFC_RQPN_OFFSET 0x108 +#define MAD_IFC_SL_OFFSET 0x10c +#define MAD_IFC_G_PATH_OFFSET 0x10d +#define MAD_IFC_RLID_OFFSET 0x10e +#define MAD_IFC_PKEY_OFFSET 0x112 #define MAD_IFC_GRH_OFFSET 0x140 inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); @@ -1862,7 +1862,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, val = in_wc->dlid_path_bits | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); - MTHCA_PUT(inbox, val, MAD_IFC_GRH_OFFSET); + MTHCA_PUT(inbox, val, MAD_IFC_G_PATH_OFFSET); MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET); MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); @@ -1870,7 +1870,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, if (in_grh) memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40); - op_modifier |= 0x10; + op_modifier |= 0x4; in_modifier |= in_wc->slid << 16; } -- cgit From c21e6d65f70d64b359a37545592f39e28074864e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 13:41:59 +0000 Subject: [MIPS] Sort out missuse of __init for prom_getcmdline() Signed-off-by: Ralf Baechle --- drivers/net/au1000_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 4873dc610d2..7db3c8af089 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -102,7 +102,7 @@ static void enable_mac(struct net_device *, int); // externs extern int get_ethernet_addr(char *ethernet_addr); extern void str2eaddr(unsigned char *ea, unsigned char *str); -extern char * __init prom_getcmdline(void); +extern char * prom_getcmdline(void); /* * Theory of operation -- cgit From 2d38caba5fd148976f54930782e8209fa45879a0 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 30 Oct 2006 19:52:31 +0100 Subject: [PATCH] ep93xx_eth: fix RX/TXstatus ring full handling Ray Lehtiniemi reported that an incoming UDP packet flood can lock up the ep93xx ethernet driver. Herbert Valerio Riedel noted that due to the way ep93xx_eth manages the RX/TXstatus rings, it cannot distinguish a full ring from an empty one, and correctly suggested that this was likely to be causing this lockup to occur. Instead of looking at the hardware's RX/TXstatus ring write pointers to determine when to stop reading from those rings, we should just check every individual RX/TXstatus descriptor's valid bit instead, since there is no other way to distinguish an empty ring from a full ring, and if there is a descriptor waiting, we take the hit of reading the descriptor from memory anyway. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/net/arm/ep93xx_eth.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 127561c782f..2fc8b2a1a02 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -193,12 +193,9 @@ static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) static int ep93xx_rx(struct net_device *dev, int *budget) { struct ep93xx_priv *ep = netdev_priv(dev); - int tail_offset; int rx_done; int processed; - tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; - rx_done = 0; processed = 0; while (*budget > 0) { @@ -211,28 +208,23 @@ static int ep93xx_rx(struct net_device *dev, int *budget) entry = ep->rx_pointer; rstat = ep->descs->rstat + entry; - if ((void *)rstat - (void *)ep->descs == tail_offset) { + + rstat0 = rstat->rstat0; + rstat1 = rstat->rstat1; + if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) { rx_done = 1; break; } - rstat0 = rstat->rstat0; - rstat1 = rstat->rstat1; rstat->rstat0 = 0; rstat->rstat1 = 0; - if (!(rstat0 & RSTAT0_RFP)) - printk(KERN_CRIT "ep93xx_rx: buffer not done " - " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOF)) printk(KERN_CRIT "ep93xx_rx: not end-of-frame " " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOB)) printk(KERN_CRIT "ep93xx_rx: not end-of-buffer " " %.8x %.8x\n", rstat0, rstat1); - if (!(rstat1 & RSTAT1_RFP)) - printk(KERN_CRIT "ep93xx_rx: buffer1 not done " - " %.8x %.8x\n", rstat0, rstat1); if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry) printk(KERN_CRIT "ep93xx_rx: entry mismatch " " %.8x %.8x\n", rstat0, rstat1); @@ -301,13 +293,8 @@ err: static int ep93xx_have_more_rx(struct ep93xx_priv *ep) { - struct ep93xx_rstat *rstat; - int tail_offset; - - rstat = ep->descs->rstat + ep->rx_pointer; - tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; - - return !((void *)rstat - (void *)ep->descs == tail_offset); + struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer; + return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP)); } static int ep93xx_poll(struct net_device *dev, int *budget) @@ -379,10 +366,8 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) static void ep93xx_tx_complete(struct net_device *dev) { struct ep93xx_priv *ep = netdev_priv(dev); - int tail_offset; int wake; - tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr; wake = 0; spin_lock(&ep->tx_pending_lock); @@ -393,15 +378,13 @@ static void ep93xx_tx_complete(struct net_device *dev) entry = ep->tx_clean_pointer; tstat = ep->descs->tstat + entry; - if ((void *)tstat - (void *)ep->descs == tail_offset) - break; tstat0 = tstat->tstat0; + if (!(tstat0 & TSTAT0_TXFP)) + break; + tstat->tstat0 = 0; - if (!(tstat0 & TSTAT0_TXFP)) - printk(KERN_CRIT "ep93xx_tx_complete: buffer not done " - " %.8x\n", tstat0); if (tstat0 & TSTAT0_FA) printk(KERN_CRIT "ep93xx_tx_complete: frame aborted " " %.8x\n", tstat0); -- cgit From 79c356f44b26da9fe357ed1a11e7faec4fd94e13 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 30 Oct 2006 19:52:54 +0100 Subject: [PATCH] ep93xx_eth: fix unlikely(x) > y test Fix unlikely(x) > y test in ep93xx_eth. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/net/arm/ep93xx_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 2fc8b2a1a02..90d77ec48fb 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -334,7 +334,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) struct ep93xx_priv *ep = netdev_priv(dev); int entry; - if (unlikely(skb->len) > MAX_PKT_SIZE) { + if (unlikely(skb->len > MAX_PKT_SIZE)) { ep->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; -- cgit From 06f0015ace46ce9d313ec02d6b13c47c8e795a6c Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 30 Oct 2006 19:54:08 +0100 Subject: [PATCH] ep93xx_eth: don't report RX errors Flooding the console with error messages for every RX FIFO overrun, checksum error and framing error isn't very sensible. Each of these errors can occur during normal operation, so stop printk'ing error messages for RX errors at all. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/net/arm/ep93xx_eth.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 90d77ec48fb..8ebd68e2af9 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -230,9 +230,6 @@ static int ep93xx_rx(struct net_device *dev, int *budget) " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_RWE)) { - printk(KERN_NOTICE "ep93xx_rx: receive error " - " %.8x %.8x\n", rstat0, rstat1); - ep->stats.rx_errors++; if (rstat0 & RSTAT0_OE) ep->stats.rx_fifo_errors++; -- cgit From 9d4df9e0fadfc84cd826e0f7e946691b4d7baee5 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 29 Oct 2006 03:52:14 +0900 Subject: [PATCH] tokenring: fix module_init error handling - Call platform_driver_unregister() before return when no cards found. (fixes data corruption when no cards found) - Check platform_device_register_simple() return value Cc: Jeff Garzik Cc: Mike Phillips Signed-off-by: Akinobu Mita drivers/net/tokenring/proteon.c | 9 +++++++-- drivers/net/tokenring/skisa.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/tokenring/proteon.c | 9 +++++++-- drivers/net/tokenring/skisa.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 4f756960db2..cb7dbb63c9d 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -370,6 +370,10 @@ static int __init proteon_init(void) dev->dma = dma[i]; pdev = platform_device_register_simple("proteon", i, NULL, 0); + if (IS_ERR(pdev)) { + free_netdev(dev); + continue; + } err = setup_card(dev, &pdev->dev); if (!err) { proteon_dev[i] = pdev; @@ -385,9 +389,10 @@ static int __init proteon_init(void) /* Probe for cards. */ if (num == 0) { printk(KERN_NOTICE "proteon.c: No cards found.\n"); - return (-ENODEV); + platform_driver_unregister(&proteon_driver); + return -ENODEV; } - return (0); + return 0; } static void __exit proteon_cleanup(void) diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index d6ba41cf311..33afea31d87 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c @@ -380,6 +380,10 @@ static int __init sk_isa_init(void) dev->dma = dma[i]; pdev = platform_device_register_simple("skisa", i, NULL, 0); + if (IS_ERR(pdev)) { + free_netdev(dev); + continue; + } err = setup_card(dev, &pdev->dev); if (!err) { sk_isa_dev[i] = pdev; @@ -395,9 +399,10 @@ static int __init sk_isa_init(void) /* Probe for cards. */ if (num == 0) { printk(KERN_NOTICE "skisa.c: No cards found.\n"); - return (-ENODEV); + platform_driver_unregister(&sk_isa_driver); + return -ENODEV; } - return (0); + return 0; } static void __exit sk_isa_cleanup(void) -- cgit From 09669585b5d0cfdebe28250d442693b3baac66a2 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 29 Oct 2006 03:47:12 +0900 Subject: [PATCH] n2: fix confusing error code modprobe n2 with no parameters or no such devices will get confusing error message. # modprobe n2 ... Kernel does not have module support This patch replaces return code from -ENOSYS to -EINVAL. Cc: Jeff Garzik Cc: Krzysztof Halasa Signed-off-by: Akinobu Mita drivers/net/wan/n2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) Signed-off-by: Jeff Garzik --- drivers/net/wan/n2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index dcf46add3ad..5c322dfb79f 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -500,7 +500,7 @@ static int __init n2_init(void) #ifdef MODULE printk(KERN_INFO "n2: no card initialized\n"); #endif - return -ENOSYS; /* no parameters specified, abort */ + return -EINVAL; /* no parameters specified, abort */ } printk(KERN_INFO "%s\n", version); @@ -538,11 +538,11 @@ static int __init n2_init(void) n2_run(io, irq, ram, valid[0], valid[1]); if (*hw == '\x0') - return first_card ? 0 : -ENOSYS; + return first_card ? 0 : -EINVAL; }while(*hw++ == ':'); printk(KERN_ERR "n2: invalid hardware parameters\n"); - return first_card ? 0 : -ENOSYS; + return first_card ? 0 : -EINVAL; } -- cgit From f479b322a0949d540b45aea645793058b0c50be5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 27 Oct 2006 10:22:10 -0700 Subject: [PATCH] sky2: not experimental The sky2 driver is no longer in experimental state. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e38846eb51f..28c17d1ca5c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2112,7 +2112,7 @@ config SKGE config SKY2 tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + depends on PCI select CRC32 ---help--- This driver supports Gigabit Ethernet adapters based on the @@ -2120,8 +2120,8 @@ config SKY2 Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/ 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 - This driver does not support the original Yukon chipset: a seperate - driver, skge, is provided for Yukon-based adapters. + There is companion driver for the older Marvell Yukon and + Genesis based adapters: skge. To compile this driver as a module, choose M here: the module will be called sky2. This is recommended. -- cgit From 1e7bed081968c42469bd02842b4190a115008221 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 26 Oct 2006 22:51:33 +0200 Subject: [PATCH] myri10ge: ServerWorks HT2000 PCI id is already defined in pci_ids.h No need to keep defining PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE in the driver code since it is now defined in pci_ids.h. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index fdbb0d7213b..806081b5973 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2416,7 +2416,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) * firmware image, and set tx.boundary to 4KB. */ -#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa -- cgit From 1e1675ccf758cbb4303ab052d58405cda6c745a7 Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Wed, 25 Oct 2006 13:11:42 +0200 Subject: [PATCH] ehea: kzalloc GFP_ATOMIC fix This patch fixes kzalloc parameters (GFP_ATOMIC instead of GFP_KERNEL) Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index eb7d44de59f..4538c99733f 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -586,8 +586,8 @@ int ehea_sense_port_attr(struct ehea_port *port) u64 hret; struct hcp_ehea_port_cb0 *cb0; - cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); - if (!cb0) { + cb0 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC); /* May be called via */ + if (!cb0) { /* ehea_neq_tasklet() */ ehea_error("no mem for cb0"); ret = -ENOMEM; goto out; @@ -765,8 +765,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { if (!netif_carrier_ok(port->netdev)) { - ret = ehea_sense_port_attr( - port); + ret = ehea_sense_port_attr(port); if (ret) { ehea_error("failed resensing port " "attributes"); @@ -1502,7 +1501,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) if ((enable && port->promisc) || (!enable && !port->promisc)) return; - cb7 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb7 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC); if (!cb7) { ehea_error("no mem for cb7"); goto out; @@ -1606,7 +1605,7 @@ static void ehea_add_multicast_entry(struct ehea_port* port, u8* mc_mac_addr) struct ehea_mc_list *ehea_mcl_entry; u64 hret; - ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_KERNEL); + ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); if (!ehea_mcl_entry) { ehea_error("no mem for mcl_entry"); return; -- cgit From 2ceaac755423cb93c1bb2f59ebd1a06f027ac095 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 30 Oct 2006 14:19:25 -0800 Subject: [PATCH] net s2io: return on NULL dev_alloc_skb() Checks for NULL dev_alloc_skb() and returns on true to avoid subsequent dereference. Cc: Jeff Garzik Cc: Christoph Hellwig Signed-off-by: David Rientjes Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a231ab7d28d..33569ec9dbf 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5985,6 +5985,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); + if (!(*skb)) { + DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", + dev->name); + return -ENOMEM; + } ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, @@ -6007,7 +6012,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; } else { *skb = dev_alloc_skb(size); - + if (!(*skb)) { + DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", + dev->name); + return -ENOMEM; + } ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); -- cgit From 798b6b19d7a4b6e1ea5340ec8b3b92811e05b81b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 22 Oct 2006 20:16:57 -0700 Subject: [PATCH] skge, sky2, et all. gplv2 only I don't want my code to downgraded to GPLv3 because of cut-n-pasted the comments. These files which I hold copyright on were started before it was clear what GPLv3 was going to be. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/irda/stir4200.c | 3 +-- drivers/net/skge.c | 3 +-- drivers/net/sky2.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index be8a66e702b..3b4c4787593 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -15,8 +15,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. +* the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/drivers/net/skge.c b/drivers/net/skge.c index e7e414928f8..b2949035f66 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -11,8 +11,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 95efdb5bbbe..53171f62b26 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -10,8 +10,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -- cgit From 0ca43235b34c92278fa903297acef37198ec3e26 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 18 Oct 2006 13:39:28 -0700 Subject: [PATCH] sky2: netpoll on dual port cards The sky2 driver uses a single NAPI poll routine for both ports on dual ported cards (because there is a single IRQ and status ring). Netpoll makes assumptions about the relationship between network device and NAPI that aren't correct on the second port, this will cause the port to never clear work. Most systems, just have single port, so not a big issue. The easy fix is just make the second port, not netpoll capable. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 53171f62b26..16616f5440d 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3238,7 +3238,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, dev->poll = sky2_poll; dev->weight = NAPI_WEIGHT; #ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = sky2_netpoll; + /* Network console (only works on port 0) + * because netpoll makes assumptions about NAPI + */ + if (port == 0) + dev->poll_controller = sky2_netpoll; #endif sky2 = netdev_priv(dev); -- cgit From cf0e812f0e90ee496af072b136e8bd02770387e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 27 Oct 2006 19:08:47 -0700 Subject: [PATCH] sata_sis: fix flags handling for the secondary port sis_init_one() modifies probe_ent->port_flags after allocating and initializing it using ata_pci_init_native_mode(). This makes port_flags for the secondary port (probe_ent->pinfo2->flags) go out of sync resulting in misdetection of device due to incorrectly initialized SCR access flag. This patch make probe_ent alloc/init happen after the final port flags value is determined. This is fragile but probe_ent and all the related mess are scheduled to go away soon for exactly this reason. We just need to hold everything together till then. This has been spotted and diagnosed and tested by Patrick McHardy. Signed-off-by: Tejun Heo Cc: Patric McHardy Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/sata_sis.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 0738f52463a..9d1235ba06b 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -240,7 +240,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_probe_ent *probe_ent = NULL; int rc; u32 genctl; - struct ata_port_info *ppi[2]; + struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; int pci_dev_busy = 0; u8 pmr; u8 port2_start; @@ -265,27 +265,20 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out_regions; - ppi[0] = ppi[1] = &sis_port_info; - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) { - rc = -ENOMEM; - goto err_out_regions; - } - /* check and see if the SCRs are in IO space or PCI cfg space */ pci_read_config_dword(pdev, SIS_GENCTL, &genctl); if ((genctl & GENCTL_IOMAPPED_SCR) == 0) - probe_ent->port_flags |= SIS_FLAG_CFGSCR; + pi.flags |= SIS_FLAG_CFGSCR; /* if hardware thinks SCRs are in IO space, but there are * no IO resources assigned, change to PCI cfg space. */ - if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) && + if ((!(pi.flags & SIS_FLAG_CFGSCR)) && ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { genctl &= ~GENCTL_IOMAPPED_SCR; pci_write_config_dword(pdev, SIS_GENCTL, genctl); - probe_ent->port_flags |= SIS_FLAG_CFGSCR; + pi.flags |= SIS_FLAG_CFGSCR; } pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -306,6 +299,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) port2_start = 0x20; } + probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); + if (!probe_ent) { + rc = -ENOMEM; + goto err_out_regions; + } + if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { probe_ent->port[0].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR); -- cgit From f833229c96c0bf53c05995e4bd58709d9e9edd67 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 31 Oct 2006 09:31:37 +0100 Subject: [PATCH] Add 0x7110 piix to ata_piix.c Hi Jeff, I tested the PATA support on my old VAIO notebook, and it failed to find my piix device: 00:07.1 Class 0101: 8086:7111 (rev 01) (prog-if 80 [Master]) Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 5250187ffce..4fad8d2382c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -169,6 +169,7 @@ static const struct pci_device_id piix_pci_tbl[] = { #ifdef ATA_ENABLE_PATA /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ + { 0x8086, 0x7110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, -- cgit From 6e42acc4115bc376b8523acbcba2b2b7cc27d016 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 27 Oct 2006 19:08:42 -0700 Subject: [PATCH] libata: unexport ata_dev_revalidate() ata_dev_revalidate() isn't used outside of libata core. Unexport it. Signed-off-by: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 - drivers/ata/libata.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 83728a9457a..a8fd0c3e59b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6122,7 +6122,6 @@ EXPORT_SYMBOL_GPL(ata_std_prereset); EXPORT_SYMBOL_GPL(ata_std_softreset); EXPORT_SYMBOL_GPL(sata_std_hardreset); EXPORT_SYMBOL_GPL(ata_std_postreset); -EXPORT_SYMBOL_GPL(ata_dev_revalidate); EXPORT_SYMBOL_GPL(ata_dev_classify); EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index a5ecb71390a..0ed263be652 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -53,6 +53,7 @@ extern unsigned ata_exec_internal(struct ata_device *dev, extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int post_reset, u16 *id); +extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); extern int ata_dev_configure(struct ata_device *dev, int print_info); extern int sata_down_spd_limit(struct ata_port *ap); extern int sata_set_spd_needed(struct ata_port *ap); -- cgit From c6446a4cdadaf411bafe1565e9fa7666f3c2fe95 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 9 Oct 2006 13:23:58 +0900 Subject: [PATCH] ata_piix: allow 01b MAP for both ICH6M and ICH7M ICH7M was separated from ICH6M to allow undocumented MAP value 01b which was spotted on an ASUS notebook. However, there is also notebooks with MAP value 01b on ICH6M. This patch re-merges ICH6M and ICH7M entries and allows MAP value 01b for both. This problem has been reported and initial patch provided by Jonathan Dieter. Signed-off-by: Tejun Heo Cc: Jonathan Dieter Cc: Tom Deblauwe Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 4fad8d2382c..8385387c49c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -126,8 +126,7 @@ enum { ich6_sata = 7, ich6_sata_ahci = 8, ich6m_sata_ahci = 9, - ich7m_sata_ahci = 10, - ich8_sata_ahci = 11, + ich8_sata_ahci = 10, /* constants for mapping table */ P0 = 0, /* port 0 */ @@ -228,7 +227,7 @@ static const struct pci_device_id piix_pci_tbl[] = { /* 82801GB/GR/GH (ICH7, identical to ICH6) */ { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ - { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci }, + { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, /* Enterprise Southbridge 2 (where's the datasheet?) */ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ @@ -400,23 +399,10 @@ static const struct piix_map_db ich6m_map_db = { .mask = 0x3, .port_enable = 0x5, .present_shift = 4, - .map = { - /* PM PS SM SS MAP */ - { P0, P2, RV, RV }, /* 00b */ - { RV, RV, RV, RV }, - { P0, P2, IDE, IDE }, /* 10b */ - { RV, RV, RV, RV }, - }, -}; - -static const struct piix_map_db ich7m_map_db = { - .mask = 0x3, - .port_enable = 0x5, - .present_shift = 4, /* Map 01b isn't specified in the doc but some notebooks use - * it anyway. ATM, the only case spotted carries subsystem ID - * 1025:0107. This is the only difference from ich6m. + * it anyway. MAP 01b have been spotted on both ICH6M and + * ICH7M. */ .map = { /* PM PS SM SS MAP */ @@ -446,7 +432,6 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich6_sata] = &ich6_map_db, [ich6_sata_ahci] = &ich6_map_db, [ich6m_sata_ahci] = &ich6m_map_db, - [ich7m_sata_ahci] = &ich7m_map_db, [ich8_sata_ahci] = &ich8_map_db, }; @@ -557,19 +542,7 @@ static struct ata_port_info piix_port_info[] = { .port_ops = &piix_sata_ops, }, - /* ich7m_sata_ahci: 10 */ - { - .sht = &piix_sht, - .flags = ATA_FLAG_SATA | - PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &piix_sata_ops, - }, - - /* ich8_sata_ahci: 11 */ + /* ich8_sata_ahci: 10 */ { .sht = &piix_sht, .flags = ATA_FLAG_SATA | -- cgit From 115e222d538e7838bffa0f76409acd9816a0ef32 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Tue, 24 Oct 2006 22:41:27 -0400 Subject: [PATCH] hostap_plx: fix CIS verification The length of the manfid CIS should be at least 4, and it's normally 4. It's incorrect to require it to be at least 5. This breaks support for most (if not all) cards. The right place to ensure that we don't access beyond the CIS buffer is to strengthen another check. Make sure that the next tuple begins at least at the CIS buffer end (in which case we stop processing) or before that. Reported by ph35sm@free.fr Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_plx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index 6dfa041be66..bc81b13a5a2 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -364,7 +364,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, pos = 0; while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) { - if (pos + cis[pos + 1] >= CIS_MAX_LEN) + if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN) goto cis_error; switch (cis[pos]) { @@ -391,7 +391,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, break; case CISTPL_MANFID: - if (cis[pos + 1] < 5) + if (cis[pos + 1] < 4) goto cis_error; manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); -- cgit From 81e171b95d2d06a64465a1e6ab1e2fb864ea2448 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 28 Oct 2006 17:52:34 -0500 Subject: [PATCH] bcm43xx: Fix low-traffic netdev watchdog TX timeouts This fixes a netdev watchdog timeout problem. The software needs to call netif_tx_disable before running the hardware calibration code. The problem condition can be shown by the following timegraph. |---5secs - ~10 jiffies time---|---|OOPS ^ ^ last real TX periodic work stops netif At OOPS, the following happens: The watchdog timer triggers, because the timeout of 5secs is over. The watchdog first checks for stopped TX. _Usually_ TX is only stopped from the TX handler to indicate a full TX queue. But this is different. We need to stop TX here, regardless of the TX queue state. So the watchdog recognizes the stopped device and assumes it is stopped due to full TX queues (Which is a _wrong_ assumption in this case). It then tests how far the last TX has been in the past. If it's more than 5secs (which is the case for low or no traffic), it will fire a TX timeout. Signed-off-by: Michael Buesch Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index a94c6d8826f..65edb56107f 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3163,9 +3163,11 @@ static int estimate_periodic_work_badness(unsigned int state) static void bcm43xx_periodic_work_handler(void *d) { struct bcm43xx_private *bcm = d; + struct net_device *net_dev = bcm->net_dev; unsigned long flags; u32 savedirqs = 0; int badness; + unsigned long orig_trans_start = 0; mutex_lock(&bcm->mutex); badness = estimate_periodic_work_badness(bcm->periodic_state); @@ -3173,7 +3175,18 @@ static void bcm43xx_periodic_work_handler(void *d) /* Periodic work will take a long time, so we want it to * be preemtible. */ - netif_tx_disable(bcm->net_dev); + + netif_tx_lock_bh(net_dev); + /* We must fake a started transmission here, as we are going to + * disable TX. If we wouldn't fake a TX, it would be possible to + * trigger the netdev watchdog, if the last real TX is already + * some time on the past (slightly less than 5secs) + */ + orig_trans_start = net_dev->trans_start; + net_dev->trans_start = jiffies; + netif_stop_queue(net_dev); + netif_tx_unlock_bh(net_dev); + spin_lock_irqsave(&bcm->irq_lock, flags); bcm43xx_mac_suspend(bcm); if (bcm43xx_using_pio(bcm)) @@ -3198,6 +3211,7 @@ static void bcm43xx_periodic_work_handler(void *d) bcm43xx_pio_thaw_txqueues(bcm); bcm43xx_mac_enable(bcm); netif_wake_queue(bcm->net_dev); + net_dev->trans_start = orig_trans_start; } mmiowb(); spin_unlock_irqrestore(&bcm->irq_lock, flags); -- cgit From df6d7c94b0c3ae6a1185c9e5fa8ee3368e4a5efb Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 17 Oct 2006 23:38:26 -0500 Subject: [PATCH] bcm43xx: fix unexpected LED control values in BCM4303 sprom The bcm43xx driver uses 4 locations in the devices sprom to determine the behavior of the leds. Certain defaults are assigned if all bits are set in those locations. On at least one BCM4303 chip, the sprom contains values other than the default, which executes an assertion placed in the default case of a following switch statement. This patch makes the leds on the above mentioned interface behave correctly. In addition, it limits the number of logged messages to 20 for the case of unexpected values in the sprom locations. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 7 ++++++- drivers/net/wireless/bcm43xx/bcm43xx_leds.h | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index 2ddbec6bf15..7d383a27b92 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -189,20 +189,24 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) case BCM43xx_LED_INACTIVE: continue; case BCM43xx_LED_OFF: + case BCM43xx_LED_BCM4303_3: break; case BCM43xx_LED_ON: turn_on = 1; break; case BCM43xx_LED_ACTIVITY: + case BCM43xx_LED_BCM4303_0: turn_on = activity; break; case BCM43xx_LED_RADIO_ALL: turn_on = radio->enabled; break; case BCM43xx_LED_RADIO_A: + case BCM43xx_LED_BCM4303_2: turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); break; case BCM43xx_LED_RADIO_B: + case BCM43xx_LED_BCM4303_1: turn_on = (radio->enabled && (phy->type == BCM43xx_PHYTYPE_B || phy->type == BCM43xx_PHYTYPE_G)); @@ -257,7 +261,8 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) continue; #endif /* CONFIG_BCM43XX_DEBUG */ default: - assert(0); + dprintkl(KERN_INFO PFX "Bad value in leds_update," + " led->behaviour: 0x%x\n", led->behaviour); }; if (led->activelow) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h index d3716cf3aeb..811e14a8119 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h @@ -46,6 +46,12 @@ enum { /* LED behaviour values */ BCM43xx_LED_TEST_BLINKSLOW, BCM43xx_LED_TEST_BLINKMEDIUM, BCM43xx_LED_TEST_BLINKFAST, + + /* Misc values for BCM4303 */ + BCM43xx_LED_BCM4303_0 = 0x2B, + BCM43xx_LED_BCM4303_1 = 0x78, + BCM43xx_LED_BCM4303_2 = 0x2E, + BCM43xx_LED_BCM4303_3 = 0x19, }; int bcm43xx_leds_init(struct bcm43xx_private *bcm); -- cgit From 441cbd8dace80545db2ac43175ac1c097d96f75c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 26 Oct 2006 15:38:10 +1000 Subject: [POWERPC] Fix various offb issues This patch fixes a few issues in offb: - A test was inverted causing the palette hack to never work (no device node was passed down to the init function) - Some cards seem to have their assigned-addresses property in a random order, thus we need to try using of_get_pci_address() first, which will fail if it's not a PCI device, and fallback to of_get_address() in that case. of_get_pci_address() properly parsees assigned-addresses to test the BAR number and thus will get it right whatever the order is. - Some cards (like GXT4500) provide a linebytes of 0xffffffff in the device-tree which does no good. This patch handles that by using the screen width when that happens. (Also fixes btext.c while at it). - Add detection of the GXT4500 in addition to the GXT2000 for the palette hacks (we use the same hack, palette is linear in register space at offset 0x6000). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/video/offb.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/video/offb.c b/drivers/video/offb.c index bad0e98fb3b..9a40bbecf76 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue)); break; case cmap_gxt2000: - out_le32((unsigned __iomem *) par->cmap_adr + regno, + out_le32(((unsigned __iomem *) par->cmap_adr) + regno, (red << 16 | green << 8 | blue)); break; } @@ -213,7 +213,7 @@ static int offb_blank(int blank, struct fb_info *info) out_le32(par->cmap_adr + 0xb4, 0); break; case cmap_gxt2000: - out_le32((unsigned __iomem *) par->cmap_adr + i, + out_le32(((unsigned __iomem *) par->cmap_adr) + i, 0); break; } @@ -226,13 +226,23 @@ static int offb_blank(int blank, struct fb_info *info) static void __iomem *offb_map_reg(struct device_node *np, int index, unsigned long offset, unsigned long size) { - struct resource r; - - if (of_address_to_resource(np, index, &r)) - return 0; - if ((r.start + offset + size) > r.end) - return 0; - return ioremap(r.start + offset, size); + const u32 *addrp; + u64 asize, taddr; + unsigned int flags; + + addrp = of_get_pci_address(np, index, &asize, &flags); + if (addrp == NULL) + addrp = of_get_address(np, index, &asize, &flags); + if (addrp == NULL) + return NULL; + if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) + return NULL; + if ((offset + size) > asize) + return NULL; + taddr = of_translate_address(np, addrp); + if (taddr == OF_BAD_ADDR) + return NULL; + return ioremap(taddr + offset, size); } static void __init offb_init_fb(const char *name, const char *full_name, @@ -289,7 +299,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, par->cmap_type = cmap_unknown; if (depth == 8) { - /* Palette hacks disabled for now */ if (dp && !strncmp(name, "ATY,Rage128", 11)) { par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); if (par->cmap_adr) @@ -313,7 +322,8 @@ static void __init offb_init_fb(const char *name, const char *full_name, ioremap(base + 0x7ff000, 0x1000) + 0xcc0; par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; - } else if (dp && device_is_compatible(dp, "pci1014,b7")) { + } else if (dp && (device_is_compatible(dp, "pci1014,b7") || + device_is_compatible(dp, "pci1014,21c"))) { par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); if (par->cmap_adr) par->cmap_type = cmap_gxt2000; @@ -433,7 +443,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) pp = get_property(dp, "linux,bootx-linebytes", &len); if (pp == NULL) pp = get_property(dp, "linebytes", &len); - if (pp && len == sizeof(u32)) + if (pp && len == sizeof(u32) && (*pp != 0xffffffffu)) pitch = *pp; else pitch = width * ((depth + 7) / 8); @@ -496,7 +506,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) offb_init_fb(no_real_node ? "bootx" : dp->name, no_real_node ? "display" : dp->full_name, width, height, depth, pitch, address, - no_real_node ? dp : NULL); + no_real_node ? NULL : dp); } } -- cgit From 1244a19cde42c268aa159d264fc2df072a3ff82f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 1 Nov 2006 17:19:18 +0900 Subject: [PATCH] ahci: fix status register check in ahci_softreset ahci_softreset() used to use ahci_tf_read() which reads D2H_REG area to check for the Status register. However, this area is zeroed on initialization and not set by initial signature FIS. Replace it with ahci_check_status(). This bug prevented CLO code from being activated whenever BSY and/or DRQ is set prior to softreset. This fix makes AHCI_FLAG_RESET_NEEDS_CLO flag redundant. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index cef2e70d64f..988f8bbd14f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -736,8 +736,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* check BUSY/DRQ, perform Command List Override if necessary */ - ahci_tf_read(ap, &tf); - if (tf.command & (ATA_BUSY | ATA_DRQ)) { + if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { rc = ahci_clo(ap); if (rc == -EOPNOTSUPP) { -- cgit From 8fc2d9cae99e47e236cb7b77015b9faf69a097cc Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Wed, 1 Nov 2006 05:23:11 -0500 Subject: [libata] sata_nv: Add PCI IDs Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 323b6071080..d65ebfd7c7b 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -117,10 +117,14 @@ static const struct pci_device_id nv_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, - { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, - { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, - { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, - { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, + { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */ { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, -- cgit From 732f74a46711c0724885703fb689c79139c84a3c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 1 Nov 2006 22:09:21 -0500 Subject: Revert "[PATCH] Add 0x7110 piix to ata_piix.c" This reverts commit f833229c96c0bf53c05995e4bd58709d9e9edd67: According to reviewers and the lspci data provided in commit message itself, PCI ID 0x7110 should not have been added to ata_piix. Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 8385387c49c..720174d628f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -168,7 +168,6 @@ static const struct pci_device_id piix_pci_tbl[] = { #ifdef ATA_ENABLE_PATA /* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */ /* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */ - { 0x8086, 0x7110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 }, { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, -- cgit From 7a118df3ea23820b9922a1b51cd2f24e464f4c17 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 31 Oct 2006 11:12:59 -0800 Subject: RDMA/addr: Use client registration to fix module unload race Require registration with ib_addr module to prevent caller from unloading while a callback is in progress. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/addr.c | 28 +++++++++++++++++++++++++++- drivers/infiniband/core/cma.c | 8 ++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 60d3fbdd216..e11187ecc93 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -47,6 +47,7 @@ struct addr_req { struct sockaddr src_addr; struct sockaddr dst_addr; struct rdma_dev_addr *addr; + struct rdma_addr_client *client; void *context; void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context); @@ -61,6 +62,26 @@ static LIST_HEAD(req_list); static DECLARE_WORK(work, process_req, NULL); static struct workqueue_struct *addr_wq; +void rdma_addr_register_client(struct rdma_addr_client *client) +{ + atomic_set(&client->refcount, 1); + init_completion(&client->comp); +} +EXPORT_SYMBOL(rdma_addr_register_client); + +static inline void put_client(struct rdma_addr_client *client) +{ + if (atomic_dec_and_test(&client->refcount)) + complete(&client->comp); +} + +void rdma_addr_unregister_client(struct rdma_addr_client *client) +{ + put_client(client); + wait_for_completion(&client->comp); +} +EXPORT_SYMBOL(rdma_addr_unregister_client); + int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, const unsigned char *dst_dev_addr) { @@ -229,6 +250,7 @@ static void process_req(void *data) list_del(&req->list); req->callback(req->status, &req->src_addr, req->addr, req->context); + put_client(req->client); kfree(req); } } @@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in, return ret; } -int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, +int rdma_resolve_ip(struct rdma_addr_client *client, + struct sockaddr *src_addr, struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context), @@ -285,6 +308,8 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, req->addr = addr; req->callback = callback; req->context = context; + req->client = client; + atomic_inc(&client->refcount); src_in = (struct sockaddr_in *) &req->src_addr; dst_in = (struct sockaddr_in *) &req->dst_addr; @@ -305,6 +330,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, break; default: ret = req->status; + atomic_dec(&client->refcount); kfree(req); break; } diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d8ca3c1368b..845090b0859 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -63,6 +63,7 @@ static struct ib_client cma_client = { }; static struct ib_sa_client sa_client; +static struct rdma_addr_client addr_client; static LIST_HEAD(dev_list); static LIST_HEAD(listen_any_list); static DEFINE_MUTEX(lock); @@ -1625,8 +1626,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, if (cma_any_addr(dst_addr)) ret = cma_resolve_loopback(id_priv); else - ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, - &id->route.addr.dev_addr, + ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, + dst_addr, &id->route.addr.dev_addr, timeout_ms, addr_handler, id_priv); if (ret) goto err; @@ -2217,6 +2218,7 @@ static int cma_init(void) return -ENOMEM; ib_sa_register_client(&sa_client); + rdma_addr_register_client(&addr_client); ret = ib_register_client(&cma_client); if (ret) @@ -2224,6 +2226,7 @@ static int cma_init(void) return 0; err: + rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); return ret; @@ -2232,6 +2235,7 @@ err: static void cma_cleanup(void) { ib_unregister_client(&cma_client); + rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); idr_destroy(&sdp_ps); -- cgit From 05e2867a7bcc76de37e103a97ed48ba6872db797 Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Thu, 2 Nov 2006 17:58:21 -0500 Subject: [libata] Add support for PATA controllers of MCP67 to pata_amd.c. Signed-off-by: Peer Chen Signed-off-by: Jeff Garzik --- drivers/ata/pata_amd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 29234c89711..5c47a9e0e0c 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -677,6 +677,8 @@ static const struct pci_device_id amd[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE), 8 }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE), 8 }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, { }, -- cgit From 895663cd92574367054e0eb604a7428852f359b8 Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Thu, 2 Nov 2006 17:59:46 -0500 Subject: [libata] Add support for AHCI controllers of MCP67. Signed-off-by: Peer Chen Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 988f8bbd14f..234197e57e9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -334,6 +334,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */ /* SiS */ { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ -- cgit From 6c8c21b9119cfe68a99825085014bba4f9c0c768 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sat, 14 Oct 2006 16:21:02 -0300 Subject: V4L/DVB (4752): DVB: Add DVB_FE_CUSTOMISE support for MT2060 Let the MT2060 be customized like most of the other DVB PLLs/front-ends. Also, add a missing dependency on I2C. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 12 ++++++------ drivers/media/dvb/frontends/Kconfig | 2 ++ drivers/media/dvb/frontends/mt2060.h | 8 ++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 2cc5caa26a0..a263b3f3c21 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -26,7 +26,7 @@ config DVB_USB_A800 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. @@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" depends on DVB_USB select DVB_DIB3000MB - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-B demodulator. @@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Support for USB2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-C/P demodulator. @@ -70,7 +70,7 @@ config DVB_USB_DIB0700 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB @@ -87,7 +87,7 @@ config DVB_USB_UMT_010 tristate "HanfTek UMT-010 DVB-T USB2.0 support" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. @@ -153,7 +153,7 @@ config DVB_USB_NOVA_T_USB2 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 + select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE help Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 080fa257a0b..aebb8d6f26f 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -276,6 +276,8 @@ config DVB_TDA826X config DVB_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" + depends on I2C + default m if DVB_FE_CUSTOMISE help A driver for the silicon IF tuner MT2060 from Microtune. diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h index 34a37c2b556..0a86eab3a95 100644 --- a/drivers/media/dvb/frontends/mt2060.h +++ b/drivers/media/dvb/frontends/mt2060.h @@ -30,6 +30,14 @@ struct mt2060_config { u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ }; +#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE)) extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); +#else +static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif // CONFIG_DVB_TUNER_MT2060 #endif -- cgit From ecba77f246011344f0b8f46eb25ae01ab4ae282d Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Fri, 27 Oct 2006 20:56:51 -0300 Subject: V4L/DVB (4785): Budget-ci: Change DEBIADDR_IR to a safer default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IR chip has no address decoding, so the IR data is always present in the high byte when doing a read from the saa7146 chip. This means that the DEBI address used is irrelevant to the IR decoding logic. DEBI addresses 0x1XXX are mapped to the registers on the CI module itself, but only the lowest two bits are actually used (see EN50221, section A.2.2.1), meaning that 0x1234 is equivalent to 0x1000 which maps to register 0 (the data register). A read from the data register is supposed to be preceded by a read from the size register, so some CI modules will be confused (the AlphaCrypt CAM will hang completely). The attached patch changes the address used when reading the IR data to use 0x4000 instead. This is the CI version address, which is a safer default, works with the AlphaCrypt CAM and matches the behaviour of the Windows driver (AFAIK). Signed-off-by: David Härdeman Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 2a2e9b40061..ac0cecb14dc 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -46,7 +46,14 @@ #include "bsbe1.h" #include "bsru6.h" -#define DEBIADDR_IR 0x1234 +/* + * Regarding DEBIADDR_IR: + * Some CI modules hang if random addresses are read. + * Using address 0x4000 for the IR read means that we + * use the same address as for CI version, which should + * be a safe default. + */ +#define DEBIADDR_IR 0x4000 #define DEBIADDR_CICONTROL 0x0000 #define DEBIADDR_CIVERSION 0x4000 #define DEBIADDR_IO 0x1000 -- cgit From c2625bff997f195e067ae11c9b0aa7217fb32991 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 29 Oct 2006 11:12:27 -0300 Subject: V4L/DVB (4786): Pvrusb2: use NULL instead of 0 Fix sparse NULL usage warnings: drivers/media/video/pvrusb2/pvrusb2-v4l2.c:714:14: warning: Using plain integer as NULL pointer drivers/media/video/pvrusb2/pvrusb2-v4l2.c:715:16: warning: Using plain integer as NULL pointer drivers/media/video/pvrusb2/pvrusb2-v4l2.c:1079:10: warning: Using plain integer as NULL pointer drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c:224:58: warning: Using plain integer as NULL pointer Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 2 +- drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index df8feac16ae..c80c26be6e4 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -221,7 +221,7 @@ static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) { int ret; - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); + ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL); pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); } diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 97e974d9b9c..bb40e908597 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -711,8 +711,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) dip->devbase.minor,pvr2_config_get_name(dip->config)); /* Paranoia */ - dip->v4lp = 0; - dip->stream = 0; + dip->v4lp = NULL; + dip->stream = NULL; /* Actual deallocation happens later when all internal references are gone. */ @@ -1076,7 +1076,7 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL); if (!vp->vdev) { kfree(vp); - return 0; + return NULL; } memset(vp->vdev,0,sizeof(*vp->vdev)); pvr2_channel_init(&vp->channel,mnp); -- cgit From 9e741b74afc975da51ec60c5a8147b2ebcf7e33a Mon Sep 17 00:00:00 2001 From: Raymond Mantchala Date: Mon, 30 Oct 2006 23:20:50 -0300 Subject: V4L/DVB (4787): Budget-ci: Inversion setting fixed for Technotrend 1500 T Technotrend 1500 T card have "inverted inversion". This patch fixes that. Many thanks to Martin Zwickel from Technotrend for his confirmation and correction proposal. Signed-off-by: Raymond Mantchala Signed-off-by: Perceval Anichini Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index ac0cecb14dc..cd5ec489af1 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1035,6 +1035,7 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) budget_ci->tuner_pll_address = 0x60; + philips_tdm1316l_config.invert = 1; budget_ci->budget.dvb_frontend = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { -- cgit From 588f98312c7fd1d86290583189d2eb24da70f752 Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Wed, 18 Oct 2006 17:30:42 -0300 Subject: V4L/DVB (4770): Fix mode switch of Compro Videomate T300 The board did not return to analog mode since the board specific "demod sleep" function was not called. Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-dvb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 1ba53b525ad..6b61d9b2fcb 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1147,6 +1147,8 @@ static int dvb_init(struct saa7134_dev *dev) &philips_europa_config, &dev->i2c_adap); if (dev->dvb.frontend) { + dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; + dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; -- cgit From 9bb6e2593ad4cb94944f547154baee64b4734598 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Fri, 27 Oct 2006 18:02:01 -0300 Subject: V4L/DVB (4784): [saa7146_i2c] short_delay mode fixed for fast machines TT DVB-C 2300 runs at 137 kHz I2C speed. short_delay mode did not work reliably on fast machines with that speed. Increased max loop count from 20 to 50. Moved dummy access out of the loop. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_i2c.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index d9953f7a8b6..5297a365c92 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -217,11 +217,9 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d } /* wait until we get a transfer done or error */ timeout = jiffies + HZ/100 + 1; /* 10ms */ + /* first read usually delivers bogus results... */ + saa7146_i2c_status(dev); while(1) { - /** - * first read usually delivers bogus results... - */ - saa7146_i2c_status(dev); status = saa7146_i2c_status(dev); if ((status & 0x3) != 1) break; @@ -232,10 +230,10 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); return -EIO; } - if ((++trial < 20) && short_delay) + if (++trial < 50 && short_delay) udelay(10); else - msleep(1); + msleep(1); } } -- cgit From c5dec9fb248e3318f30a26f9984b3b064053a77f Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sat, 14 Oct 2006 15:44:44 -0300 Subject: V4L/DVB (4751): Fix DBV_FE_CUSTOMISE for card drivers compiled into kernel When a front-end is disabled, card drivers that use it are compiled with a stub version of the front-end's attach function. This way they have no references to the front-end's code and don't need it to be loaded. If a card driver is compiled into the kernel, and a front-end is a module, then that front-end is effectively disabled wrt the card driver. In this case, the card driver should get the stub version. This was not happening. The stub vs real attach function selection is changed so that when the front-end is a module the real attach function is only used if the card driver is a module as well. This means a module front-end will be supported by card drivers that are modules and not supported by card drivers compiled into the kernel. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/bcm3510.h | 2 +- drivers/media/dvb/frontends/cx22700.h | 2 +- drivers/media/dvb/frontends/cx22702.h | 2 +- drivers/media/dvb/frontends/cx24110.h | 2 +- drivers/media/dvb/frontends/cx24123.h | 2 +- drivers/media/dvb/frontends/dib3000.h | 2 +- drivers/media/dvb/frontends/dib3000mc.h | 2 +- drivers/media/dvb/frontends/isl6421.h | 2 +- drivers/media/dvb/frontends/l64781.h | 2 +- drivers/media/dvb/frontends/lgdt330x.h | 2 +- drivers/media/dvb/frontends/lnbp21.h | 2 +- drivers/media/dvb/frontends/mt312.h | 2 +- drivers/media/dvb/frontends/mt352.h | 2 +- drivers/media/dvb/frontends/nxt200x.h | 2 +- drivers/media/dvb/frontends/nxt6000.h | 2 +- drivers/media/dvb/frontends/or51132.h | 2 +- drivers/media/dvb/frontends/or51211.h | 2 +- drivers/media/dvb/frontends/s5h1420.h | 2 +- drivers/media/dvb/frontends/sp8870.h | 2 +- drivers/media/dvb/frontends/sp887x.h | 2 +- drivers/media/dvb/frontends/stv0297.h | 2 +- drivers/media/dvb/frontends/stv0299.h | 2 +- drivers/media/dvb/frontends/tda10021.h | 2 +- drivers/media/dvb/frontends/tda1004x.h | 2 +- drivers/media/dvb/frontends/tda10086.h | 2 +- drivers/media/dvb/frontends/tda8083.h | 2 +- drivers/media/dvb/frontends/tda826x.h | 2 +- drivers/media/dvb/frontends/tua6100.h | 2 +- drivers/media/dvb/frontends/ves1820.h | 2 +- drivers/media/dvb/frontends/ves1x93.h | 2 +- drivers/media/dvb/frontends/zl10353.h | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h index 6dfa839a702..7e4f95e1734 100644 --- a/drivers/media/dvb/frontends/bcm3510.h +++ b/drivers/media/dvb/frontends/bcm3510.h @@ -34,7 +34,7 @@ struct bcm3510_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE) +#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE)) extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h index 10286cc29fb..7ac33690cdc 100644 --- a/drivers/media/dvb/frontends/cx22700.h +++ b/drivers/media/dvb/frontends/cx22700.h @@ -31,7 +31,7 @@ struct cx22700_config u8 demod_address; }; -#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE) +#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE)) extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index bc217ddf02c..9cd64da6ee4 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h @@ -41,7 +41,7 @@ struct cx22702_config u8 output_mode; }; -#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE) +#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index c9d5ae250eb..0ca3af4db51 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h @@ -41,7 +41,7 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { return r; } -#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE) +#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index 57a1dae1dc4..84f9e4f5c15 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/drivers/media/dvb/frontends/cx24123.h @@ -35,7 +35,7 @@ struct cx24123_config int lnb_polarity; }; -#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE) +#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index 0caac3f0f27..a6d3854a67b 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h @@ -41,7 +41,7 @@ struct dib_fe_xfer_ops int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); }; -#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE) +#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE)) extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); #else diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h index 0d6fdef7753..72d4757601d 100644 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ b/drivers/media/dvb/frontends/dib3000mc.h @@ -39,7 +39,7 @@ struct dib3000mc_config { #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 #define DEFAULT_DIB3000P_I2C_ADDRESS 24 -#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE) +#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); #else static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h index 1916e3eb2df..ea7f78a7d3c 100644 --- a/drivers/media/dvb/frontends/isl6421.h +++ b/drivers/media/dvb/frontends/isl6421.h @@ -39,7 +39,7 @@ #define ISL6421_ISEL1 0x20 #define ISL6421_DCL 0x40 -#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE) +#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE)) /* override_set and override_clear control which system register bits (above) to always set & clear */ extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear); diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h index 21ba4a23076..cd15f76ff28 100644 --- a/drivers/media/dvb/frontends/l64781.h +++ b/drivers/media/dvb/frontends/l64781.h @@ -31,7 +31,7 @@ struct l64781_config u8 demod_address; }; -#if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE) +#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE)) extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index 3f96b485584..995059004b1 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h @@ -52,7 +52,7 @@ struct lgdt330x_config int clock_polarity_flip; }; -#if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE) +#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE)) extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index 1fe1dd17931..68906acf7d6 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h @@ -39,7 +39,7 @@ #include -#if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE) +#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) /* override_set and override_clear control which system register bits (above) to always set & clear */ extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); #else diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index 7112fb4d58a..cf9a1505ad4 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h @@ -34,7 +34,7 @@ struct mt312_config u8 demod_address; }; -#if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE) +#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 0035c2e2d7c..e9964081fd8 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h @@ -51,7 +51,7 @@ struct mt352_config int (*demod_init)(struct dvb_frontend* fe); }; -#if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE) +#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE)) extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h index 2eb220e9806..28bc5591b31 100644 --- a/drivers/media/dvb/frontends/nxt200x.h +++ b/drivers/media/dvb/frontends/nxt200x.h @@ -45,7 +45,7 @@ struct nxt200x_config int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); }; -#if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE) +#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE)) extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h index 9397393a6bd..13d22518356 100644 --- a/drivers/media/dvb/frontends/nxt6000.h +++ b/drivers/media/dvb/frontends/nxt6000.h @@ -33,7 +33,7 @@ struct nxt6000_config u8 clock_inversion:1; }; -#if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE) +#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE)) extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h index 9718be4fb83..add24f0a743 100644 --- a/drivers/media/dvb/frontends/or51132.h +++ b/drivers/media/dvb/frontends/or51132.h @@ -34,7 +34,7 @@ struct or51132_config int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); }; -#if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE) +#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE)) extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h index 10a5419f9e0..8aad8402d61 100644 --- a/drivers/media/dvb/frontends/or51211.h +++ b/drivers/media/dvb/frontends/or51211.h @@ -37,7 +37,7 @@ struct or51211_config void (*sleep)(struct dvb_frontend * fe); }; -#if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE) +#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE)) extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h index efc54d7f3c5..1555870f722 100644 --- a/drivers/media/dvb/frontends/s5h1420.h +++ b/drivers/media/dvb/frontends/s5h1420.h @@ -34,7 +34,7 @@ struct s5h1420_config u8 invert:1; }; -#if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE) +#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h index 4cf27d3b10f..909cefe7139 100644 --- a/drivers/media/dvb/frontends/sp8870.h +++ b/drivers/media/dvb/frontends/sp8870.h @@ -35,7 +35,7 @@ struct sp8870_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) +#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE)) extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h index cab7ea644df..7ee78d7d916 100644 --- a/drivers/media/dvb/frontends/sp887x.h +++ b/drivers/media/dvb/frontends/sp887x.h @@ -17,7 +17,7 @@ struct sp887x_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE) +#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE)) extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h index 760b80db43a..69f4515df2b 100644 --- a/drivers/media/dvb/frontends/stv0297.h +++ b/drivers/media/dvb/frontends/stv0297.h @@ -42,7 +42,7 @@ struct stv0297_config u8 stop_during_read:1; }; -#if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE) +#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE)) extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 7ef25207081..33df9495908 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h @@ -89,7 +89,7 @@ struct stv0299_config int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); }; -#if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE) +#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h index d68ae20c841..e3da780108f 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda10021.h @@ -32,7 +32,7 @@ struct tda10021_config u8 demod_address; }; -#if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE) +#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, struct i2c_adapter* i2c, u8 pwm); #else diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index e28fca05734..605ad2dfc09 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h @@ -71,7 +71,7 @@ struct tda1004x_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE) +#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c); diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h index 18457adee30..ed584a8f4a8 100644 --- a/drivers/media/dvb/frontends/tda10086.h +++ b/drivers/media/dvb/frontends/tda10086.h @@ -35,7 +35,7 @@ struct tda10086_config u8 invert; }; -#if defined(CONFIG_DVB_TDA10086) || defined(CONFIG_DVB_TDA10086_MODULE) +#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h index aae15bdce6e..2d3307999f2 100644 --- a/drivers/media/dvb/frontends/tda8083.h +++ b/drivers/media/dvb/frontends/tda8083.h @@ -35,7 +35,7 @@ struct tda8083_config u8 demod_address; }; -#if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE) +#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h index 83998c00119..ad998119596 100644 --- a/drivers/media/dvb/frontends/tda826x.h +++ b/drivers/media/dvb/frontends/tda826x.h @@ -35,7 +35,7 @@ * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. * @return FE pointer on success, NULL on failure. */ -#if defined(CONFIG_DVB_TDA826X) || defined(CONFIG_DVB_TDA826X_MODULE) +#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough); diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h index 8f98033ffa7..03a665e7df6 100644 --- a/drivers/media/dvb/frontends/tua6100.h +++ b/drivers/media/dvb/frontends/tua6100.h @@ -34,7 +34,7 @@ #include #include "dvb_frontend.h" -#if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE) +#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE)) extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); #else static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h index f0c9dded39d..e4a2a324046 100644 --- a/drivers/media/dvb/frontends/ves1820.h +++ b/drivers/media/dvb/frontends/ves1820.h @@ -41,7 +41,7 @@ struct ves1820_config u8 selagc:1; }; -#if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE) +#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE)) extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, struct i2c_adapter* i2c, u8 pwm); #else diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h index 395fed39b28..d507f8966f8 100644 --- a/drivers/media/dvb/frontends/ves1x93.h +++ b/drivers/media/dvb/frontends/ves1x93.h @@ -40,7 +40,7 @@ struct ves1x93_config u8 invert_pwm:1; }; -#if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE) +#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE)) extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, struct i2c_adapter* i2c); #else diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 79a947215c4..0bc0109737f 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h @@ -36,7 +36,7 @@ struct zl10353_config int parallel_ts; }; -#if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE) +#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c); #else -- cgit From bb44c308ee37c14ab63251e27d6d8b4dc73a10a4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 27 Oct 2006 16:12:30 -0700 Subject: PCI: Let PCI_MULTITHREAD_PROBE depend on BROKEN PCI_MULTITHREAD_PROBE is an interesting feature, but in its current state it seems to be more of a trap for users who accidentally enable it. This patch lets PCI_MULTITHREAD_PROBE depend on BROKEN for 2.6.19. The intention is to get this patch reversed in -mm as soon as it's in Linus' tree, and reverse it for 2.6.20 or 2.6.21 after the fallout of in-kernel problems PCI_MULTITHREAD_PROBE causes got fixed. (akpm: I get enough bug reports already) Signed-off-by: Adrian Bunk Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index ecc50db8585..5f1b9f58070 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -19,7 +19,7 @@ config PCI_MSI config PCI_MULTITHREAD_PROBE bool "PCI Multi-threaded probe (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + depends on PCI && EXPERIMENTAL && BROKEN help Say Y here if you want the PCI core to spawn a new thread for every PCI device that is probed. This can cause a huge -- cgit From 90ac3c8124453fb355c10d3e1a27af5c0ab21099 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 9 Apr 2002 12:14:34 -0700 Subject: USB: add another sierra wireless device id As reported by Peter Kucmeroski and Jason Ganovsky. Cc: Peter Kucmeroski Cc: Jason Ganovsky Cc: Kevin Lloyd 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 ea16572d19f..69cc8fb4156 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ @@ -58,6 +59,7 @@ static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ -- cgit From bc724b98c5e782c2d6781428ed87768daa34921d Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Thu, 19 Oct 2006 00:11:17 -0700 Subject: USB: usb-storage: Unusual_dev update The protocol in this entry is needed for some versions of the device but not others. This adds the NEED_OVERRIDE flag to prevent it complaining to users who don't need it. Signed-off-by: Phil Dibowitz --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 37ed8e0f2dc..1e0d04f721f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1236,7 +1236,7 @@ UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, "Cowon Systems", "iAUDIO M5", US_SC_DEVICE, US_PR_BULK, NULL, - 0 ), + US_FL_NEED_OVERRIDE ), /* Submitted by Antoine Mairesse */ UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, -- cgit From 68717950e11eab8ff754b2721d23e9cb3a47b56f Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Thu, 19 Oct 2006 15:09:51 -0700 Subject: hid-core: big-endian fix fix Adam Kropelin had posted 32-bit fix in June 2005 about two weeks after I originally had posted my fixes for big endian support. Adam has a UPS device which reports LINEV using 32-bits. Added comments to describe the limitations of the code. extract() is the same version I posted earlier and tested in user space. Made similar changes to implement() routine. I've written (and will shortly post) a test for implement(). Code tested on C3600 (parisc) with USB keyboard/mouse attached. I've dropped test_implement.c and a few other user space test programs on http://iou.parisc-linux.org/~grundler/tests/ -rw-r--r-- 1 grundler grundler 1750 Oct 18 09:13 test_extract.c -rw-r--r-- 1 grundler grundler 561 Jan 25 2006 test_ffs.c -rw-r--r-- 1 grundler users 7175 Apr 8 2005 test_fls.c -rw-r--r-- 1 grundler grundler 206 Sep 1 15:52 test_gettimeofday.c -rw-r--r-- 1 grundler grundler 1886 Oct 19 09:20 test_implement.c -rw-r--r-- 1 grundler users 2707 Jun 4 2005 test_unaligned.c I would appreciate if someone else would look at the output of test_implement.c to make it does The Right Thing. Signed-off-by: Grant Grundler Cc: Matthew Wilcox Cc: Dmitry Torokhov Acked-By: Adam Kropelin Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 59 +++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 45f44fe33bf..6d42036c906 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -270,7 +270,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign * Read data value from item. */ -static __inline__ __u32 item_udata(struct hid_item *item) +static u32 item_udata(struct hid_item *item) { switch (item->size) { case 1: return item->data.u8; @@ -280,7 +280,7 @@ static __inline__ __u32 item_udata(struct hid_item *item) return 0; } -static __inline__ __s32 item_sdata(struct hid_item *item) +static s32 item_sdata(struct hid_item *item) { switch (item->size) { case 1: return item->data.s8; @@ -727,7 +727,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) * done by hand. */ -static __inline__ __s32 snto32(__u32 value, unsigned n) +static s32 snto32(__u32 value, unsigned n) { switch (n) { case 8: return ((__s8)value); @@ -741,9 +741,9 @@ static __inline__ __s32 snto32(__u32 value, unsigned n) * Convert a signed 32-bit integer to a signed n-bit integer. */ -static __inline__ __u32 s32ton(__s32 value, unsigned n) +static u32 s32ton(__s32 value, unsigned n) { - __s32 a = value >> (n - 1); + s32 a = value >> (n - 1); if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; return value & ((1 << n) - 1); @@ -751,30 +751,55 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n) /* * Extract/implement a data field from/to a little endian report (bit array). + * + * Code sort-of follows HID spec: + * http://www.usb.org/developers/devclass_docs/HID1_11.pdf + * + * While the USB HID spec allows unlimited length bit fields in "report + * descriptors", most devices never use more than 16 bits. + * One model of UPS is claimed to report "LINEV" as a 32-bit field. + * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) { - u32 x; + u64 x; + + WARN_ON(n > 32); report += offset >> 3; /* adjust byte index */ - offset &= 8 - 1; - x = get_unaligned((u32 *) report); - x = le32_to_cpu(x); - x = (x >> offset) & ((1 << n) - 1); - return x; + offset &= 7; /* now only need bit offset into one byte */ + x = get_unaligned((u64 *) report); + x = le64_to_cpu(x); + x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ + return (u32) x; } +/* + * "implement" : set bits in a little endian bit stream. + * Same concepts as "extract" (see comments above). + * The data mangled in the bit stream remains in little endian + * order the whole time. It make more sense to talk about + * endianness of register values by considering a register + * a "cached" copy of the little endiad bit stream. + */ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) { - u32 x; + u64 x; + u64 m = (1ULL << n) - 1; + + WARN_ON(n > 32); + + WARN_ON(value > m); + value &= m; report += offset >> 3; - offset &= 8 - 1; - x = get_unaligned((u32 *)report); - x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset)); - x |= cpu_to_le32(value << offset); - put_unaligned(x,(u32 *)report); + offset &= 7; + + x = get_unaligned((u64 *)report); + x &= cpu_to_le64(~(m << offset)); + x |= cpu_to_le64(((u64) value) << offset); + put_unaligned(x, (u64 *) report); } /* -- cgit From 78001e3d75c5d3ae1e8dc9875892b9461e4c8d4b Mon Sep 17 00:00:00 2001 From: Bjorn Schneider Date: Sat, 28 Oct 2006 12:42:04 +0200 Subject: USB: new VID/PID-combos for cp2101 3 new VID/PID combinations (registered with Silicon Laboratories Inc.) added for devices made by Lipowsky Industrie Elektronik GmbH all using the CP2102 usb-to-serial converter (Baby-JTAG, Baby-LIN, HARP-1). Signed-off-by: Bjorn Schneider Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp2101.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index bbf6532c26e..f95d42c0d16 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -64,6 +64,9 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ + { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ + { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ -- cgit From baafe37c6a58d4ddb8c2c62cd0f20340b4c66b35 Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Fri, 27 Oct 2006 18:59:24 +0200 Subject: USB: sierra: Fix id for Sierra Wireless MC8755 in new table The new version of sierra.c has introduced tables for the 1 port and 3 port variants. The device id i added in my last patch needs to be added to the 3 port table. Signed-off-by: Jan Luebbe Cc: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 69cc8fb4156..4b5097fa48d 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -62,6 +62,7 @@ static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ + { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { } -- cgit From d8fa59a8f6f7c9a1bc294154fd6805c6b247683d Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Fri, 27 Oct 2006 22:46:03 +0200 Subject: usbtouchscreen: use endpoint address from endpoint descriptor use the endpoint address from the endpoint descriptor instead of the hardcoding it to 0x81. at least some ITM based screen use a different address and don't work without this. Signed-off-by: Daniel Ritz Cc: Ralf Lehmann Cc: J.P. Delport Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/usbtouchscreen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 2902742895a..933ceddf3de 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c @@ -640,7 +640,7 @@ static int usbtouch_probe(struct usb_interface *intf, type->max_press, 0, 0); usb_fill_int_urb(usbtouch->irq, usbtouch->udev, - usb_rcvintpipe(usbtouch->udev, 0x81), + usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), usbtouch->data, type->rept_size, usbtouch_irq, usbtouch, endpoint->bInterval); -- cgit From 6c8df79f8c0f8d861ea25e6e104a29398d8398f4 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 28 Oct 2006 11:36:59 +0200 Subject: USB: failure in usblp's error path if urb submission fails due to a transient error here eg. ENOMEM , the driver is dead. This fixes it. Regards Oliver Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 809d465eb25..16353b661a0 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -722,6 +722,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t usblp->wcomplete = 0; err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); if (err) { + usblp->wcomplete = 1; if (err != -ENOMEM) count = -EIO; else -- cgit From 5a69ebe1e90d9e8d43131f08d344751cf42254c5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 28 Oct 2006 18:07:25 +0200 Subject: USB: usblp: fix system suspend for some systems this has been confirmed to fix suspend problems with usblp. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 16353b661a0..6303970e93c 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1203,8 +1203,6 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) down (&usblp->sem); /* we take no more IO */ usblp->sleeping = 1; - /* we wait for anything printing */ - wait_event (usblp->wait, usblp->wcomplete || !usblp->present); usblp_unlink_urbs(usblp); up (&usblp->sem); mutex_unlock (&usblp_mutex); -- cgit From 23b0d968c2c82c2574ca97148ce092eff4ab84a6 Mon Sep 17 00:00:00 2001 From: Naranjo Manuel Francisco Date: Fri, 27 Oct 2006 16:08:54 -0300 Subject: USB: HID: add blacklist AIRcable USB, little beautification This patch add AIRcable USBto USB-HID blacklist, makes some little changes things in the Kconfig to make AIRcable USB look as all the rest of drivers. And it removes the readme part that was on Documentation/usb/usb-serial.txt because it is not needed anymore. Signed-off-by: Naranjo Manuel Francisco --- drivers/usb/input/hid-core.c | 4 ++++ drivers/usb/serial/Kconfig | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 6d42036c906..6daf85c6eee 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1640,6 +1640,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_SUN 0x0430 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab +#define USB_VENDOR_ID_AIRCABLE 0x16CA +#define USB_DEVICE_ID_AIRCABLE1 0x1502 + /* * Alphabetically sorted blacklist by quirk type. */ @@ -1657,6 +1660,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 9a6ec1b5e3d..2a8dd4cc943 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -54,10 +54,10 @@ config USB_SERIAL_GENERIC properly. config USB_SERIAL_AIRCABLE - tristate "AIRcable USB Bluetooth Dongle Driver (EXPERIMENTAL)" + tristate "USB AIRcable Bluetooth Dongle Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL help - Say Y here if you want to use AIRcable USB Bluetoot Dongle. + Say Y here if you want to use USB AIRcable Bluetooth Dongle. To compile this driver as a module, choose M here: the module will be called aircable. -- cgit From 11bd44abbd204f580ea91e75c84e012988971012 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 1 Nov 2006 14:26:26 -0800 Subject: USB: fix compiler issues with newer gcc versions Remove complaint from newer GCCs; they don't like forward function declarations except in top-level contexts. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 66bff184a30..ba165aff9ea 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1188,6 +1188,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) #ifdef CONFIG_USB_OTG #include "otg_whitelist.h" +static int __usb_port_suspend(struct usb_device *, int port1); #endif /** @@ -1289,8 +1290,6 @@ int usb_new_device(struct usb_device *udev) * (Includes HNP test device.) */ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { - static int __usb_port_suspend(struct usb_device *, - int port1); err = __usb_port_suspend(udev, udev->bus->otg_port); if (err < 0) dev_dbg(&udev->dev, "HNP fail, %d\n", err); -- cgit From d518b2b48a9c11fc381b179709f5321bce1f3b39 Mon Sep 17 00:00:00 2001 From: Dominic Cerquetti Date: Fri, 20 Oct 2006 14:51:45 -0700 Subject: USB: xpad: additional USB id's added Adding additional USB vendor/product ID's for XBOX pads provided by the XBOX Linux team. Signed-off-by: Dominic Cerquetti Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/xpad.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 6a12a943b93..df97e5c803f 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -2,6 +2,10 @@ * X-Box gamepad - v0.0.6 * * Copyright (c) 2002 Marko Friedemann + * 2004 Oliver Schwartz , + * Steven Toth , + * Franz Lehner , + * Ivan Hawkes * 2005 Dominic Cerquetti * 2006 Adam Buchbinder * @@ -29,6 +33,7 @@ * - ITO Takayuki for providing essential xpad information on his website * - Vojtech Pavlik - iforce driver / input subsystem * - Greg Kroah-Hartman - usb-skeleton driver + * - XBOX Linux project - extra USB id's * * TODO: * - fine tune axes (especially trigger axes) @@ -54,6 +59,13 @@ * - fixed d-pad to axes mapping * * 2002-07-17 - 0.0.5 : simplified d-pad handling + * + * 2004-10-02 - 0.0.6 : DDR pad support + * - borrowed from the XBOX linux kernel + * - USB id's for commonly used dance pads are present + * - dance pads will map D-PAD to buttons, not axes + * - pass the module paramater 'dpad_to_buttons' to force + * the D-PAD to map to buttons if your pad is not detected */ #include @@ -90,8 +102,35 @@ static const struct xpad_device { { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, + { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, + { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, + { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, + { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, + { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, + { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, + { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, + { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, + { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, + { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, + { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, + { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } }; -- cgit From 9b823b43ff308c914530ec7fde5e2d79cb37b51a Mon Sep 17 00:00:00 2001 From: Jan Mate Date: Fri, 20 Oct 2006 14:51:44 -0700 Subject: USB Storage: unusual_devs.h entry for Sony Ericsson P990i USB Storage: this patch adds support for Sony Ericsson P990i Signed-off-by: Jan Mate Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1e0d04f721f..bc1ac07bf6c 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1313,6 +1313,13 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Jan Mate */ +UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, + "Sony Ericsson", + "P990i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. -- cgit From 18ee91fa9815fa3bb4e51cdcb8229bd0a0f11a70 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 2 Nov 2006 12:29:12 -0800 Subject: USB: use MII hooks only if CONFIG_MII is enabled Fix mcs7830 patch The recent mcs7830 update to make the MII support sharable goofed various pre-existing configurations in two ways: - it made the usbnet infrastructure reference MII symbols even when they're not needed in the kernel being built - it didn't enable MII along with the mcs7830 minidriver This patch fixes these two problems. However, there does seem to be a Kconfig reverse dependency bug in that MII gets wrongly enabled in some cases (like USBNET=y and USBNET_MII=n); I think I've noticed that same problem in other situations too. So the result can mean kernels being bloated by stuff that's needlessly enabled ... better than wrongly being disabled, but contributing to bloat. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/Kconfig | 8 ++++++- drivers/usb/net/usbnet.c | 58 ++++++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index 454a186b64a..e081836014a 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig @@ -92,8 +92,13 @@ config USB_RTL8150 To compile this driver as a module, choose M here: the module will be called rtl8150. +config USB_USBNET_MII + tristate + default n + config USB_USBNET tristate "Multi-purpose USB Networking Framework" + select MII if USBNET_MII != n ---help--- This driver supports several kinds of network links over USB, with "minidrivers" built around a common network driver core @@ -129,7 +134,7 @@ config USB_NET_AX8817X tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" depends on USB_USBNET && NET_ETHERNET select CRC32 - select MII + select USB_USBNET_MII default y help This option adds support for ASIX AX88xxx based USB 2.0 @@ -210,6 +215,7 @@ config USB_NET_PLUSB config USB_NET_MCS7830 tristate "MosChip MCS7830 based Ethernet adapters" depends on USB_USBNET + select USB_USBNET_MII help Choose this option if you're using a 10/100 Ethernet USB2 adapter based on the MosChip 7830 controller. This includes diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 40873635d80..760b5327b81 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -669,6 +669,9 @@ done: * they'll probably want to use this base set. */ +#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE) +#define HAVE_MII + int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd) { struct usbnet *dev = netdev_priv(net); @@ -699,20 +702,6 @@ int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) } EXPORT_SYMBOL_GPL(usbnet_set_settings); - -void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) -{ - struct usbnet *dev = netdev_priv(net); - - /* REVISIT don't always return "usbnet" */ - strncpy (info->driver, driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, - sizeof info->fw_version); - usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); -} -EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); - u32 usbnet_get_link (struct net_device *net) { struct usbnet *dev = netdev_priv(net); @@ -730,40 +719,57 @@ u32 usbnet_get_link (struct net_device *net) } EXPORT_SYMBOL_GPL(usbnet_get_link); -u32 usbnet_get_msglevel (struct net_device *net) +int usbnet_nway_reset(struct net_device *net) { struct usbnet *dev = netdev_priv(net); - return dev->msg_enable; + if (!dev->mii.mdio_write) + return -EOPNOTSUPP; + + return mii_nway_restart(&dev->mii); } -EXPORT_SYMBOL_GPL(usbnet_get_msglevel); +EXPORT_SYMBOL_GPL(usbnet_nway_reset); -void usbnet_set_msglevel (struct net_device *net, u32 level) +#endif /* HAVE_MII */ + +void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - dev->msg_enable = level; + /* REVISIT don't always return "usbnet" */ + strncpy (info->driver, driver_name, sizeof info->driver); + strncpy (info->version, DRIVER_VERSION, sizeof info->version); + strncpy (info->fw_version, dev->driver_info->description, + sizeof info->fw_version); + usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } -EXPORT_SYMBOL_GPL(usbnet_set_msglevel); +EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); -int usbnet_nway_reset(struct net_device *net) +u32 usbnet_get_msglevel (struct net_device *net) { struct usbnet *dev = netdev_priv(net); - if (!dev->mii.mdio_write) - return -EOPNOTSUPP; + return dev->msg_enable; +} +EXPORT_SYMBOL_GPL(usbnet_get_msglevel); - return mii_nway_restart(&dev->mii); +void usbnet_set_msglevel (struct net_device *net, u32 level) +{ + struct usbnet *dev = netdev_priv(net); + + dev->msg_enable = level; } -EXPORT_SYMBOL_GPL(usbnet_nway_reset); +EXPORT_SYMBOL_GPL(usbnet_set_msglevel); /* drivers may override default ethtool_ops in their bind() routine */ static struct ethtool_ops usbnet_ethtool_ops = { +#ifdef HAVE_MII .get_settings = usbnet_get_settings, .set_settings = usbnet_set_settings, - .get_drvinfo = usbnet_get_drvinfo, .get_link = usbnet_get_link, .nway_reset = usbnet_nway_reset, +#endif + .get_drvinfo = usbnet_get_drvinfo, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, }; -- cgit From 7870db4c7fa1b03fec133c4f4e67fdaa04c5ac15 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 2 Nov 2006 22:06:57 -0800 Subject: [PATCH] md: send online/offline uevents when an md array starts/stops This allows udev to do something intelligent when an array becomes available. Acked-by: Greg KH Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 50ab4a936e3..d1113560440 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3200,6 +3200,7 @@ static int do_md_run(mddev_t * mddev) mddev->changed = 1; md_new_event(mddev); + kobject_uevent(&mddev->gendisk->kobj, KOBJ_ONLINE); return 0; } @@ -3313,6 +3314,7 @@ static int do_md_stop(mddev_t * mddev, int mode) module_put(mddev->pers->owner); mddev->pers = NULL; + kobject_uevent(&mddev->gendisk->kobj, KOBJ_OFFLINE); if (mddev->ro) mddev->ro = 0; } -- cgit From 5d861d920a86523bbeb56c19b9906c3fb1b58048 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 2 Nov 2006 22:07:06 -0800 Subject: [PATCH] lkdtm: cleanup headers and module_param/MODULE_PARM_DESC Fix module_param/sysfs file permission typo. Clean up MODULE_PARM_DESC strings to avoid fancy (and incorrect) formatting. Fix header includes for lkdtm; add some needed ones, remove unused ones; and fix this gcc warning: drivers/misc/lkdtm.c:150: warning: 'struct buffer_head' declared inside parameter list drivers/misc/lkdtm.c:150: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Randy Dunlap Cc: Ankita Garg Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/lkdtm.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index bbdba7b37e1..46a9c35943b 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -44,12 +44,14 @@ */ #include +#include #include +#include #include -#include +#include #include -#include #include +#include #include #ifdef CONFIG_IDE @@ -116,16 +118,16 @@ static enum ctype cptype = NONE; static int count = DEFAULT_COUNT; module_param(recur_count, int, 0644); -MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\ - default is 10"); +MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ + "default is 10"); module_param(cpoint_name, charp, 0644); -MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed"); -module_param(cpoint_type, charp, 06444); -MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\ - hitting the crash point"); -module_param(cpoint_count, int, 06444); -MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \ - crash point is to be hit to trigger action"); +MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); +module_param(cpoint_type, charp, 0644); +MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ + "hitting the crash point"); +module_param(cpoint_count, int, 0644); +MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ + "crash point is to be hit to trigger action"); unsigned int jp_do_irq(unsigned int irq) { -- cgit From 77d6e1397a004c9376fed855e4164ca2b1dba2ed Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 2 Nov 2006 22:07:10 -0800 Subject: [PATCH] edac_mc: fix error handling Call sysdev_class_unregister() on failure in edac_sysfs_memctrl_setup() and decrease identation level for clear logic. Acked-by: Doug Thompson Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 4bde30bb3be..75e9e38330f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -230,34 +230,43 @@ static struct kobj_type ktype_memctrl = { */ static int edac_sysfs_memctrl_setup(void) { - int err=0; + int err = 0; debugf1("%s()\n", __func__); /* create the /sys/devices/system/edac directory */ err = sysdev_class_register(&edac_class); - if (!err) { - /* Init the MC's kobject */ - memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); - edac_memctrl_kobj.parent = &edac_class.kset.kobj; - edac_memctrl_kobj.ktype = &ktype_memctrl; + if (err) { + debugf1("%s() error=%d\n", __func__, err); + return err; + } - /* generate sysfs "..../edac/mc" */ - err = kobject_set_name(&edac_memctrl_kobj,"mc"); + /* Init the MC's kobject */ + memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); + edac_memctrl_kobj.parent = &edac_class.kset.kobj; + edac_memctrl_kobj.ktype = &ktype_memctrl; - if (!err) { - /* FIXME: maybe new sysdev_create_subdir() */ - err = kobject_register(&edac_memctrl_kobj); + /* generate sysfs "..../edac/mc" */ + err = kobject_set_name(&edac_memctrl_kobj,"mc"); - if (err) - debugf1("Failed to register '.../edac/mc'\n"); - else - debugf1("Registered '.../edac/mc' kobject\n"); - } - } else - debugf1("%s() error=%d\n", __func__, err); + if (err) + goto fail; + + /* FIXME: maybe new sysdev_create_subdir() */ + err = kobject_register(&edac_memctrl_kobj); + + if (err) { + debugf1("Failed to register '.../edac/mc'\n"); + goto fail; + } + debugf1("Registered '.../edac/mc' kobject\n"); + + return 0; + +fail: + sysdev_class_unregister(&edac_class); return err; } -- cgit From d13adb604693374c5fce47cd1a2017bcf3178eae Mon Sep 17 00:00:00 2001 From: Yvan Seth Date: Thu, 2 Nov 2006 22:07:13 -0800 Subject: [PATCH] ipmi_si_intf.c sets bad class_mask with PCI_DEVICE_CLASS Taken from http://bugzilla.kernel.org/show_bug.cgi?id=7439 It looks like device registration in drivers/char/ipmi/ipmi_si_intf.c was cleaned up and a small error was made when setting the class_mask. The fix is simple as the correct mask value is defined in the code but is not used. Acked-by: Corey Minyard Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e5cfb1fa47d..157fa81a264 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1867,7 +1867,7 @@ static int ipmi_pci_resume(struct pci_dev *pdev) static struct pci_device_id ipmi_pci_devices[] = { { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, - { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) } + { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } }; MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); -- cgit From d3e5a938e7ed718f6d191e8b6b176fcfeb88a294 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 2 Nov 2006 22:07:20 -0800 Subject: [PATCH] spi section fix WARNING: vmlinux - Section mismatch: reference to .init.text:spi_register_board_info from __ksymtab_gpl between '__ksymtab_spi_register_board_info' (at offset 0xc032f7d0) and '__ksymtab_spi_alloc_master' Fix this by removing the export. Acked-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 146298ad737..c3c0626f550 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -281,7 +281,6 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) up(&board_lock); return 0; } -EXPORT_SYMBOL_GPL(spi_register_board_info); /* FIXME someone should add support for a __setup("spi", ...) that * creates board info from kernel command lines -- cgit From 1f604c4bc078213aa1c4576efa0e8dad98522fa7 Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Thu, 2 Nov 2006 22:07:25 -0800 Subject: [PATCH] drivers/isdn/hysdn/hysdn_sched.c: sleep after taking spinlock fix spin_lock_irq{save,restore} is incorrectly called here (the function can sleep after acquring the lock). done the necessary corrections and removed unwanted cli/sti. Signed-off-by: Amol Lad Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hysdn/hysdn_sched.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 1fadf0133e9..18758772b74 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c @@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); - spin_lock_irqsave(&card->hysdn_lock, flags); while (card->async_busy) { - sti(); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg delayed"); msleep_interruptible(20); /* Timeout 20ms */ - if (!--cnt) { - spin_unlock_irqrestore(&card->hysdn_lock, flags); + if (!--cnt) return (-ERR_ASYNC_TIME); /* timed out */ - } - cli(); } /* wait for buffer to become free */ + spin_lock_irqsave(&card->hysdn_lock, flags); strcpy(card->async_data, line); card->async_len = strlen(line) + 1; card->async_channel = chan; @@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) /* now queue the task */ schedule_work(&card->irq_queue); - sti(); + spin_unlock_irqrestore(&card->hysdn_lock, flags); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg data queued"); cnt++; /* short delay */ - cli(); while (card->async_busy) { - sti(); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); msleep_interruptible(20); /* Timeout 20ms */ - if (!--cnt) { - spin_unlock_irqrestore(&card->hysdn_lock, flags); + if (!--cnt) return (-ERR_ASYNC_TIME); /* timed out */ - } - cli(); } /* wait for buffer to become free again */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); - if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg data send"); -- cgit From cda5e61a8e0b11826780b8e5a4155683f0557c8b Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Thu, 2 Nov 2006 22:07:27 -0800 Subject: [PATCH] IDE: Add the support of nvidia PATA controllers of MCP67 to amd74xx.c Add support for PATA controllers of MCP67 to amd74xx.c. Signed-off-by: Peer Chen Cc: Jeff Garzik Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/amd74xx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 2b0ea8b6608..753fe0e2145 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -75,6 +75,7 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, { 0 } }; @@ -491,7 +492,8 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), - /* 19 */ DECLARE_AMD_DEV("AMD5536"), + /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), + /* 20 */ DECLARE_AMD_DEV("AMD5536"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -530,7 +532,8 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); -- cgit From 36da4d869f23bc7d1a70a3185218cb626537845c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 3 Nov 2006 01:01:03 -0800 Subject: [TG3]: Fix 2nd ifup failure on 5752M. This fixes a bug reported in: http://bugzilla.kernel.org/show_bug.cgi?id=7438 tg3_close() turns off the PHY if WoL and ASF are both disabled. On the next tg3_open(), some devices such as the 5752M will not be brought up correctly without a PHY reset early in the reset sequence. The PHY clock is needed for some internal MAC blocks to function correctly. This problem is fixed by always resetting the PHY early in tg3_reset_hw() when it is called from tg3_open() or tg3_resume(). tg3_setup_phy() can then be called later in the sequence without the reset_phy parameter set to 1, since the PHY reset is already done. Update version to 3.68. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8e398499c04..8f059b7968b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.67" -#define DRV_MODULE_RELDATE "October 18, 2006" +#define DRV_MODULE_VERSION "3.68" +#define DRV_MODULE_RELDATE "November 02, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -6014,7 +6014,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tg3_abort_hw(tp, 1); } - if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy) + if (reset_phy) tg3_phy_reset(tp); err = tg3_chip_reset(tp); @@ -6574,7 +6574,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); } - err = tg3_setup_phy(tp, reset_phy); + err = tg3_setup_phy(tp, 0); if (err) return err; -- cgit From 1b5135d9b922fdcf46e1e7383167d93d42635fb4 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Fri, 3 Nov 2006 17:47:20 +0100 Subject: [PATCH] ehea: Nullpointer dereferencation fix Fix: Must check for nullpointer before dereferencing it - not afterwards. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_qmr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 3e1862326c8..161559315c0 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -209,11 +209,11 @@ int ehea_destroy_cq(struct ehea_cq *cq) { u64 adapter_handle, hret; - adapter_handle = cq->adapter->handle; - if (!cq) return 0; + adapter_handle = cq->adapter->handle; + /* deregister all previous registered pages */ hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); if (hret != H_SUCCESS) { -- cgit From 07fd06b3bc1589e44aefd02eb28700a51b3c9d12 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Fri, 3 Nov 2006 17:47:52 +0100 Subject: [PATCH] ehea: Removed redundant define Removed define H_CB_ALIGNMENT which is already defined in include/asm-powerpc/hvcall.h Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index b40724fc6b7..39ad9f73d1e 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0034" +#define DRV_VERSION "EHEA_0043" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) @@ -105,9 +105,6 @@ #define EHEA_BCMC_VLANID_ALL 0x01 #define EHEA_BCMC_VLANID_SINGLE 0x00 -/* Use this define to kmallocate pHYP control blocks */ -#define H_CB_ALIGNMENT 4096 - #define EHEA_CACHE_LINE 128 /* Memory Regions */ -- cgit From a1d261c561522151cb96c75f1dd1a51cf17665cf Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Fri, 3 Nov 2006 17:48:23 +0100 Subject: [PATCH] ehea: 64K page support fix This patch fixes 64k page support by using PAGE_MASK and appropriate pagesize defines in several places. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_ethtool.c | 2 +- drivers/net/ehea/ehea_main.c | 26 +++++++++++++------------- drivers/net/ehea/ehea_phyp.c | 2 +- drivers/net/ehea/ehea_phyp.h | 6 ++++-- drivers/net/ehea/ehea_qmr.c | 13 +++++++------ 5 files changed, 26 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 82eb2fb8c75..9f57c2e78ce 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -238,7 +238,7 @@ static void ehea_get_ethtool_stats(struct net_device *dev, data[i++] = port->port_res[0].swqe_refill_th; data[i++] = port->resets; - cb6 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb6) { ehea_error("no mem for cb6"); return; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 4538c99733f..6ad69610141 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -92,7 +92,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) memset(stats, 0, sizeof(*stats)); - cb2 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb2) { ehea_error("no mem for cb2"); goto out; @@ -586,8 +586,8 @@ int ehea_sense_port_attr(struct ehea_port *port) u64 hret; struct hcp_ehea_port_cb0 *cb0; - cb0 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC); /* May be called via */ - if (!cb0) { /* ehea_neq_tasklet() */ + cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC); /* May be called via */ + if (!cb0) { /* ehea_neq_tasklet() */ ehea_error("no mem for cb0"); ret = -ENOMEM; goto out; @@ -670,7 +670,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) u64 hret; int ret = 0; - cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb4) { ehea_error("no mem for cb4"); ret = -ENOMEM; @@ -985,7 +985,7 @@ static int ehea_configure_port(struct ehea_port *port) struct hcp_ehea_port_cb0 *cb0; ret = -ENOMEM; - cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb0) goto out; @@ -1443,7 +1443,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) goto out; } - cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb0) { ehea_error("no mem for cb0"); ret = -ENOMEM; @@ -1501,7 +1501,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) if ((enable && port->promisc) || (!enable && !port->promisc)) return; - cb7 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC); + cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC); if (!cb7) { ehea_error("no mem for cb7"); goto out; @@ -1870,7 +1870,7 @@ static void ehea_vlan_rx_register(struct net_device *dev, port->vgrp = grp; - cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1899,7 +1899,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1935,7 +1935,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) if (port->vgrp) port->vgrp->vlan_devices[vid] = NULL; - cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1968,7 +1968,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) u64 dummy64 = 0; struct hcp_modify_qp_cb0* cb0; - cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb0) { ret = -ENOMEM; goto out; @@ -2269,7 +2269,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) u64 hret; int ret; - cb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb) { ret = -ENOMEM; goto out; @@ -2340,7 +2340,7 @@ static int ehea_setup_single_port(struct ehea_port *port, goto out; /* Enable Jumbo frames */ - cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb4) { ehea_error("no mem for cb4"); } else { diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 0b51a8cea07..0cfc2bc1a27 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -506,7 +506,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, const u8 pagesize, const u8 queue_type, const u64 log_pageaddr, const u64 count) { - if ((count > 1) && (log_pageaddr & 0xfff)) { + if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { ehea_error("not on pageboundary"); return H_PARAMETER; } diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h index fa51e3b5bb0..919f94b7593 100644 --- a/drivers/net/ehea/ehea_phyp.h +++ b/drivers/net/ehea/ehea_phyp.h @@ -81,14 +81,16 @@ static inline u32 get_longbusy_msecs(int long_busy_ret_code) static inline void hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel, u64 paddr_user) { - epas->kernel.addr = ioremap(paddr_kernel, PAGE_SIZE); + /* To support 64k pages we must round to 64k page boundary */ + epas->kernel.addr = ioremap((paddr_kernel & PAGE_MASK), PAGE_SIZE) + + (paddr_kernel & ~PAGE_MASK); epas->user.addr = paddr_user; } static inline void hcp_epas_dtor(struct h_epas *epas) { if (epas->kernel.addr) - iounmap(epas->kernel.addr); + iounmap((void __iomem*)((u64)epas->kernel.addr & PAGE_MASK)); epas->user.addr = 0; epas->kernel.addr = 0; diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 161559315c0..72ef7bde334 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -512,7 +512,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) start = KERNELBASE; end = (u64)high_memory; - nr_pages = (end - start) / PAGE_SIZE; + nr_pages = (end - start) / EHEA_PAGESIZE; pt = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!pt) { @@ -538,9 +538,9 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) if (nr_pages > 1) { u64 num_pages = min(nr_pages, (u64)512); for (i = 0; i < num_pages; i++) - pt[i] = virt_to_abs((void*)(((u64)start) - + ((k++) * - PAGE_SIZE))); + pt[i] = virt_to_abs((void*)(((u64)start) + + ((k++) * + EHEA_PAGESIZE))); hret = ehea_h_register_rpage_mr(adapter->handle, adapter->mr.handle, 0, @@ -548,8 +548,9 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) num_pages); nr_pages -= num_pages; } else { - u64 abs_adr = virt_to_abs((void*)(((u64)start) - + (k * PAGE_SIZE))); + u64 abs_adr = virt_to_abs((void*)(((u64)start) + + (k * EHEA_PAGESIZE))); + hret = ehea_h_register_rpage_mr(adapter->handle, adapter->mr.handle, 0, 0, abs_adr,1); -- cgit From a81c52a81d6dbe6a36bce18112da04f20b175192 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 1 Nov 2006 21:18:58 -0800 Subject: [PATCH] Kconfig: remove redundant NETDEVICES depends drivers/net/Kconfig says: # All the following symbols are dependent on NETDEVICES - do not repeat # that for each of the symbols. so remove duplicate 'depends' uses of NETDEVICES. Signed-off-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 28c17d1ca5c..9cb3ca5806f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -486,7 +486,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM config MIPS_SIM_NET tristate "MIPS simulator Network device (EXPERIMENTAL)" - depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL + depends on MIPS_SIM && EXPERIMENTAL help The MIPSNET device is a simple Ethernet network device which is emulated by the MIPS Simulator. @@ -2467,7 +2467,7 @@ config ISERIES_VETH config RIONET tristate "RapidIO Ethernet over messaging driver support" - depends on NETDEVICES && RAPIDIO + depends on RAPIDIO config RIONET_TX_SIZE int "Number of outbound queue entries" -- cgit From 18a61e4adbc4dbe209e0d154df5cd37ce17dc314 Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Sun, 5 Nov 2006 23:52:07 -0800 Subject: [PATCH] Fix for LKDTM MEM_SWAPOUT crashpoint The MEM_SWAPOUT crashpoint in LKDTM could be broken as some compilers inline the call to shrink_page_list() and symbol lookup for this function name fails. Replacing it with the function shrink_inactive_list(), which is the only function calling shrink_page_list(). Signed-off-by: Ankita Garg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/lkdtm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 46a9c35943b..db9d7df75ae 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -157,8 +157,8 @@ void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) struct scan_control; -unsigned long jp_shrink_page_list(struct list_head *page_list, - struct scan_control *sc) +unsigned long jp_shrink_inactive_list(unsigned long max_scan, + struct zone *zone, struct scan_control *sc) { lkdtm_handler(); jprobe_return(); @@ -297,8 +297,8 @@ int lkdtm_module_init(void) lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; break; case MEM_SWAPOUT: - lkdtm.kp.symbol_name = "shrink_page_list"; - lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list; + lkdtm.kp.symbol_name = "shrink_inactive_list"; + lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list; break; case TIMERADD: lkdtm.kp.symbol_name = "hrtimer_start"; -- cgit From e5b9a335fd2180c6db1bcc4b24e83aff7481ebe3 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 5 Nov 2006 23:52:08 -0800 Subject: [PATCH] isdn/gigaset: convert warning message Make the failed-to-allocate-skb warning a non-debug message. Signed-off-by: Tilman Schmidt Cc: Hansjoerg Lipp Cc: Karsten Keil Cc: Kai Germaschewski Cc: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/gigaset/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index d8d256daddd..5800beeebb8 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -616,7 +616,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - gig_dbg(DEBUG_INIT, "could not allocate skb\n"); + warn("could not allocate skb\n"); bcs->inputstate |= INS_skip_frame; } -- cgit From e78181feb0b94fb6afeaef3b28d4f5df1b847c98 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 6 Nov 2006 23:17:20 +0100 Subject: [PATCH] b44: change comment about irq mask register Through some experimentation with the similarly built bcm43xx I came to the conclusion that if the hw/firmware sets a bit in the interrupt register, an interrupt will only be raised if that bit is included in the interrupt mask. Hence, the interrupt mask is more like an interrupt control mask. This patch changes the comment to reflect that. Signed-off-by: Johannes Berg Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 1ec217433b4..474a4e3438d 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -908,8 +908,9 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) istat = br32(bp, B44_ISTAT); imask = br32(bp, B44_IMASK); - /* ??? What the fuck is the purpose of the interrupt mask - * ??? register if we have to mask it out by hand anyways? + /* The interrupt mask register controls which interrupt bits + * will actually raise an interrupt to the CPU when set by hw/firmware, + * but doesn't mask off the bits. */ istat &= imask; if (istat) { -- cgit From edd106fc8ac1826dbe231b70ce0762db24133e5c Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 6 Nov 2006 08:57:12 -0800 Subject: [PATCH] e1000: Fix regression: garbled stats and irq allocation during swsusp e1000: Fix suspend/resume powerup and irq allocation From: Auke Kok After 7.0.33/2.6.16, e1000 suspend/resume left the user with an enabled device showing garbled statistics and undetermined irq allocation state, where `ifconfig eth0 down` would display `trying to free already freed irq`. Explicitly free and allocate irq as well as powerup the PHY during resume fixes when needed. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8d04752777a..726ec5e88ab 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4800,6 +4800,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if (adapter->hw.phy_type == e1000_phy_igp_3) e1000_phy_powerdown_workaround(&adapter->hw); + if (netif_running(netdev)) + e1000_free_irq(adapter); + /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ e1000_release_hw_control(adapter); @@ -4830,6 +4833,10 @@ e1000_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); + if (netif_running(netdev) && (err = e1000_request_irq(adapter))) + return err; + + e1000_power_up_phy(adapter); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); -- cgit From 3b6a792f6ace33584897d1af08630c9acc0ce221 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 6 Nov 2006 14:34:48 -0800 Subject: [NET]: kconfig, correct traffic shaper As Patrick McHardy suggested, Traffic Shaper is now obsolete and alternative to it is no longer CBQ, since its problems with virtual devices, alter Kconfig text to reflect this -- put a link to the traffic schedulers as a whole. Signed-off-by: Jiri Slaby Acked-by: Patrick McHardy Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9cb3ca5806f..6e863aa9894 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2833,7 +2833,7 @@ config NET_FC "SCSI generic support". config SHAPER - tristate "Traffic Shaper (EXPERIMENTAL)" + tristate "Traffic Shaper (OBSOLETE)" depends on EXPERIMENTAL ---help--- The traffic shaper is a virtual network device that allows you to @@ -2842,9 +2842,9 @@ config SHAPER these virtual devices. See for more information. - An alternative to this traffic shaper is the experimental - Class-Based Queuing (CBQ) scheduling support which you get if you - say Y to "QoS and/or fair queuing" above. + An alternative to this traffic shaper are traffic schedulers which + you'll get if you say Y to "QoS and/or fair queuing" in + "Networking options". To compile this driver as a module, choose M here: the module will be called shaper. If unsure, say N. -- cgit From af2c6a4aaa2253f1e29df8fb59a3d92174d30a33 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 7 Nov 2006 14:57:51 -0800 Subject: [TG3]: Fix array overrun in tg3_read_partno(). Use proper upper limits for the loops and check for all error conditions. The problem was noticed by Adrian Bunk. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8f059b7968b..06e4f77b098 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10212,7 +10212,7 @@ skip_phy_reset: static void __devinit tg3_read_partno(struct tg3 *tp) { unsigned char vpd_data[256]; - int i; + unsigned int i; u32 magic; if (tg3_nvram_read_swab(tp, 0x0, &magic)) @@ -10258,9 +10258,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) } /* Now parse and find the part number. */ - for (i = 0; i < 256; ) { + for (i = 0; i < 254; ) { unsigned char val = vpd_data[i]; - int block_end; + unsigned int block_end; if (val == 0x82 || val == 0x91) { i = (i + 3 + @@ -10276,21 +10276,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp) (vpd_data[i + 1] + (vpd_data[i + 2] << 8))); i += 3; - while (i < block_end) { + + if (block_end > 256) + goto out_not_found; + + while (i < (block_end - 2)) { if (vpd_data[i + 0] == 'P' && vpd_data[i + 1] == 'N') { int partno_len = vpd_data[i + 2]; - if (partno_len > 24) + i += 3; + if (partno_len > 24 || (partno_len + i) > 256) goto out_not_found; memcpy(tp->board_part_number, - &vpd_data[i + 3], - partno_len); + &vpd_data[i], partno_len); /* Success. */ return; } + i += 3 + vpd_data[i + 2]; } /* Part number not found. */ -- cgit From ecac598bcd1f151ee4760489bded625c147fb366 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 6 Nov 2006 09:45:31 -0600 Subject: [PATCH] bcm43xx: Drain TX status before starting IRQs Drain the Microcode TX-status-FIFO before we enable IRQs. This is required, because the FIFO may still have entries left from a previous run. Those would immediately fire after enabling IRQs and would lead to an oops in the DMA TXstatus handling code. Signed-off-by: Michael Buesch Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 65edb56107f..62c2ff8dfb9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -1463,6 +1463,23 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm) } } +static void drain_txstatus_queue(struct bcm43xx_private *bcm) +{ + u32 dummy; + + if (bcm->current_core->rev < 5) + return; + /* Read all entries from the microcode TXstatus FIFO + * and throw them away. + */ + while (1) { + dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0); + if (!dummy) + break; + dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1); + } +} + static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) { bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); @@ -3532,6 +3549,7 @@ int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm, bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); bcm43xx_security_init(bcm); + drain_txstatus_queue(bcm); ieee80211softmac_start(bcm->net_dev); /* Let's go! Be careful after enabling the IRQs. -- cgit From 3406118cd34762a7bf6b1a4f1095f9ea7576a354 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 6 Nov 2006 09:48:48 -0600 Subject: [PATCH] bcm43xx: Add error checking in bcm43xx_sprom_write() The Coverity checker noted that these "if (err)"'s couldn't ever be true. It seems the intention was to check the return values of the bcm43xx_pci_write_config32()'s? Signed-off-by: Adrian Bunk Signed-off-by: Larry Finger Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 62c2ff8dfb9..a1b783813d8 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -746,7 +746,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) if (err) goto err_ctlreg; spromctl |= 0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); if (err) goto err_ctlreg; /* We must burn lots of CPU cycles here, but that does not @@ -768,7 +768,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) mdelay(20); } spromctl &= ~0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); if (err) goto err_ctlreg; mdelay(500); -- cgit From 68ff6e8e0e203580ecb118319b5a3b53962edf5a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 8 Nov 2006 07:46:02 -0500 Subject: [libata] sata_via: fix obvious typo Spotted by Martin Devera. Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index f4455a1efe2..1c7f19aecc2 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -230,7 +230,7 @@ static int vt6420_prereset(struct ata_port *ap) int online; /* don't do any SCR stuff if we're not loading */ - if (!ATA_PFLAG_LOADING) + if (!(ap->pflags & ATA_PFLAG_LOADING)) goto skip_scr; /* Resume phy. This is the old resume sequence from -- cgit From bfc5ecdf48b529f6a2bd98ba26bfac39ca8cd8a5 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 8 Nov 2006 17:44:42 -0800 Subject: [PATCH] dm: fix find_device race There is a race between dev_create() and find_device(). If the mdptr has not yet been stored against a device, find_device() needs to behave as though no device was found. It already returns NULL, but there is a dm_put() missing: it must drop the reference dm_get_md() took. The bug was introduced by dm-fix-mapped-device-ref-counting.patch. It manifests itself if another dm ioctl attempts to reference a newly-created device while the device creation ioctl is still running. The consequence is that the device cannot be removed until the machine is rebooted. Certain udev configurations can lead to this happening. Signed-off-by: Alasdair G Kergon Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-ioctl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d13bb15a8a0..4510ad8f971 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -606,9 +606,14 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) return __get_name_cell(param->name); md = dm_get_md(huge_decode_dev(param->dev)); - if (md) - mdptr = dm_get_mdptr(md); + if (!md) + goto out; + mdptr = dm_get_mdptr(md); + if (!mdptr) + dm_put(md); + +out: return mdptr; } -- cgit From d287483d6d7a2d5b313aee155285f89b57d9cd4a Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 8 Nov 2006 17:44:43 -0800 Subject: [PATCH] dm: suspend: fix error path If the device is already suspended, just return the error and skip the code that would incorrectly wipe md->suspended_bdev. (This isn't currently a problem because existing code avoids calling this function if the device is already suspended.) Signed-off-by: Alasdair G Kergon Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b5764a86c8b..fc4f743f3b5 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1285,7 +1285,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs) down(&md->suspend_lock); if (dm_suspended(md)) - goto out; + goto out_unlock; map = dm_get_table(md); @@ -1361,6 +1361,8 @@ out: } dm_table_put(map); + +out_unlock: up(&md->suspend_lock); return r; } -- cgit From 5d55fdf94998db1df9ee7f1def8806bfd0e5ff73 Mon Sep 17 00:00:00 2001 From: Jonathan E Brassow Date: Wed, 8 Nov 2006 17:44:43 -0800 Subject: [PATCH] dm: multipath: fix rr_add_path order When adding paths to the round-robin path selector, their order gets inverted, which is not desirable. Fix by replacing list_add() with list_add_tail(). Signed-off-by: Jonathan E Brassow Signed-off-by: Alasdair G Kergon Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-round-robin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c index c5a16c55012..6f9fcd4db9b 100644 --- a/drivers/md/dm-round-robin.c +++ b/drivers/md/dm-round-robin.c @@ -136,7 +136,7 @@ static int rr_add_path(struct path_selector *ps, struct path *path, path->pscontext = pi; - list_add(&pi->list, &s->valid_paths); + list_add_tail(&pi->list, &s->valid_paths); return 0; } -- cgit From 33184048dc4f9d5550d3b6a88c8e0ff92033eb6e Mon Sep 17 00:00:00 2001 From: Jonathan E Brassow Date: Wed, 8 Nov 2006 17:44:44 -0800 Subject: [PATCH] dm: raid1: fix waiting for io on suspend All device-mapper targets must complete outstanding I/O before suspending. The mirror target generates I/O in its recovery phase and fails to wait for it. It needs to be tracked so we can ensure that it has completed before we suspend. [akpm@osdl.org: cleanup] Signed-off-by: Jonathan E Brassow Signed-off-by: Alasdair G Kergon Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-raid1.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 659224cb7c5..48a653b3f51 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -24,6 +24,7 @@ static struct workqueue_struct *_kmirrord_wq; static struct work_struct _kmirrord_work; +static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); static inline void wake(void) { @@ -83,6 +84,7 @@ struct region_hash { struct list_head *buckets; spinlock_t region_lock; + atomic_t recovery_in_flight; struct semaphore recovery_count; struct list_head clean_regions; struct list_head quiesced_regions; @@ -191,6 +193,7 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms, spin_lock_init(&rh->region_lock); sema_init(&rh->recovery_count, 0); + atomic_set(&rh->recovery_in_flight, 0); INIT_LIST_HEAD(&rh->clean_regions); INIT_LIST_HEAD(&rh->quiesced_regions); INIT_LIST_HEAD(&rh->recovered_regions); @@ -382,6 +385,8 @@ static void rh_update_states(struct region_hash *rh) rh->log->type->clear_region(rh->log, reg->key); rh->log->type->complete_resync_work(rh->log, reg->key, 1); dispatch_bios(rh->ms, ®->delayed_bios); + if (atomic_dec_and_test(&rh->recovery_in_flight)) + wake_up_all(&_kmirrord_recovery_stopped); up(&rh->recovery_count); mempool_free(reg, rh->region_pool); } @@ -502,11 +507,21 @@ static int __rh_recovery_prepare(struct region_hash *rh) static void rh_recovery_prepare(struct region_hash *rh) { - while (!down_trylock(&rh->recovery_count)) + /* Extra reference to avoid race with rh_stop_recovery */ + atomic_inc(&rh->recovery_in_flight); + + while (!down_trylock(&rh->recovery_count)) { + atomic_inc(&rh->recovery_in_flight); if (__rh_recovery_prepare(rh) <= 0) { + atomic_dec(&rh->recovery_in_flight); up(&rh->recovery_count); break; } + } + + /* Drop the extra reference */ + if (atomic_dec_and_test(&rh->recovery_in_flight)) + wake_up_all(&_kmirrord_recovery_stopped); } /* @@ -1177,6 +1192,11 @@ static void mirror_postsuspend(struct dm_target *ti) struct dirty_log *log = ms->rh.log; rh_stop_recovery(&ms->rh); + + /* Wait for all I/O we generated to complete */ + wait_event(_kmirrord_recovery_stopped, + !atomic_read(&ms->rh.recovery_in_flight)); + if (log->type->suspend && log->type->suspend(log)) /* FIXME: need better error handling */ DMWARN("log suspend failed"); -- cgit From b196872cd65a06ad65853c4513e0d0f24452d32e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 8 Nov 2006 17:44:45 -0800 Subject: [PATCH] drivers/telephony/ixj: fix an array overrun The Coverity checker noted that in drivers/telephony/ixj.c:ixj_build_filter_cadence(), filter_en[4] or filter_en[5] could be written to. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/telephony/ixj.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h index fbea4541c23..8d69bcdc29c 100644 --- a/drivers/telephony/ixj.h +++ b/drivers/telephony/ixj.h @@ -1295,7 +1295,7 @@ typedef struct { Proc_Info_Type Info_write; unsigned short frame_count; unsigned int filter_hist[4]; - unsigned char filter_en[4]; + unsigned char filter_en[6]; unsigned short proc_load; unsigned long framesread; unsigned long frameswritten; -- cgit From 2f4713036114dd13d1f4fe433b7f236250b65f5a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 8 Nov 2006 17:44:47 -0800 Subject: [PATCH] md: change ONLINE/OFFLINE events to a single CHANGE event It turns out that CHANGE is preferred to ONLINE/OFFLINE for various reasons (not least of which being that udev understands it already). So remove the recently added KOBJ_OFFLINE (no-one is likely to care anyway) and change the ONLINE to a CHANGE event Cc: Kay Sievers Signed-off-by: Neil Brown Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index d1113560440..ae50a2419cc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3200,7 +3200,7 @@ static int do_md_run(mddev_t * mddev) mddev->changed = 1; md_new_event(mddev); - kobject_uevent(&mddev->gendisk->kobj, KOBJ_ONLINE); + kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE); return 0; } @@ -3314,7 +3314,6 @@ static int do_md_stop(mddev_t * mddev, int mode) module_put(mddev->pers->owner); mddev->pers = NULL; - kobject_uevent(&mddev->gendisk->kobj, KOBJ_OFFLINE); if (mddev->ro) mddev->ro = 0; } -- cgit From 0692c6b1cf5537b190f90fb5903f1af89a41b0a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 8 Nov 2006 17:44:48 -0800 Subject: [PATCH] md: fix sizing problem with raid5-reshape and CONFIG_LBD=n I forgot to has the size-in-blocks to (loff_t) before shifting up to a size-in-bytes. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e14f4578072..69c3e201fa3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3659,7 +3659,7 @@ static void end_reshape(raid5_conf_t *conf) bdev = bdget_disk(conf->mddev->gendisk, 0); if (bdev) { mutex_lock(&bdev->bd_inode->i_mutex); - i_size_write(bdev->bd_inode, conf->mddev->array_size << 10); + i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10); mutex_unlock(&bdev->bd_inode->i_mutex); bdput(bdev); } -- cgit From 4b438a23fb05b6566393f9f0a3987ea3dcc1c0c4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Nov 2006 17:44:48 -0800 Subject: [PATCH] md: do not freeze md threads for suspend If there's a swap file on a software RAID, it should be possible to use this file for saving the swsusp's suspend image. Also, this file should be available to the memory management subsystem when memory is being freed before the suspend image is created. For the above reasons it seems that md_threads should not be frozen during the suspend and the appended patch makes this happen, but then there is the question if they don't cause any data to be written to disks after the suspend image has been created, provided that all filesystems are frozen at that time. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index ae50a2419cc..8cbf9c9df1c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4486,6 +4486,7 @@ static int md_thread(void * arg) * many dirty RAID5 blocks. */ + current->flags |= PF_NOFREEZE; allow_signal(SIGKILL); while (!kthread_should_stop()) { @@ -4502,7 +4503,6 @@ static int md_thread(void * arg) test_bit(THREAD_WAKEUP, &thread->flags) || kthread_should_stop(), thread->timeout); - try_to_freeze(); clear_bit(THREAD_WAKEUP, &thread->flags); -- cgit From f3ce6a0ead8c557e9acdc733addd23cbc206c7e3 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 8 Nov 2006 17:44:52 -0800 Subject: [PATCH] IPMI: Clean up the waiting message queue properly on unload A wrong function was being used to free a list; this fixes the problem. Otherwise, an oops at unload time was possible. But not likely, since you can't have any users when you unload the modules and it is very hard to get messages into this queue without users. Signed-off-by: Corey Minyard Cc: Patrick Schoeller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 34a4fd13fa8..e55a0d27672 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -376,13 +376,23 @@ static void free_recv_msg_list(struct list_head *q) } } +static void free_smi_msg_list(struct list_head *q) +{ + struct ipmi_smi_msg *msg, *msg2; + + list_for_each_entry_safe(msg, msg2, q, link) { + list_del(&msg->link); + ipmi_free_smi_msg(msg); + } +} + static void clean_up_interface_data(ipmi_smi_t intf) { int i; struct cmd_rcvr *rcvr, *rcvr2; struct list_head list; - free_recv_msg_list(&intf->waiting_msgs); + free_smi_msg_list(&intf->waiting_msgs); free_recv_msg_list(&intf->waiting_events); /* Wholesale remove all the entries from the list in the -- cgit From 46d52b09fa6a2d1e313cb75ca352d6f466e67bd1 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 8 Nov 2006 17:44:55 -0800 Subject: [PATCH] IPMI: retry messages on certain error returns Some more errors from the IPMI send message command are retryable, but are not being retried by the IPMI code. Make sure they get retried. Signed-off-by: Corey Minyard Cc: Frederic Lelievre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e55a0d27672..0b07ca1b71f 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -3242,7 +3242,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, report the error immediately. */ if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) - && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)) + && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) + && (msg->rsp[2] != IPMI_BUS_ERR) + && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) { int chan = msg->rsp[3] & 0xf; -- cgit From 64d9fe6973a9348e5211f3cc9f04b899329caeb4 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 8 Nov 2006 17:44:56 -0800 Subject: [PATCH] ipmi_si_intf.c: fix "&& 0xff" typos Signed-off-by: Alexey Dobriyan Acked-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 157fa81a264..abc5149e30e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1211,7 +1211,7 @@ static void intf_mem_outb(struct si_sm_io *io, unsigned int offset, static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) { return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) - && 0xff; + & 0xff; } static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, @@ -1223,7 +1223,7 @@ static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) { return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) - && 0xff; + & 0xff; } static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, @@ -1236,7 +1236,7 @@ static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset) { return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) - && 0xff; + & 0xff; } static void mem_outq(struct si_sm_io *io, unsigned int offset, -- cgit From ec68307cc5a8dc499e48693843bb42f6b6028458 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 8 Nov 2006 17:44:57 -0800 Subject: [PATCH] htirq: refactor so we only have one function that writes to the chip This refactoring actually optimizes the code a little by caching the value that we think the device is programmed with instead of reading it back from the hardware. Which simplifies the code a little and should speed things up a bit. This patch introduces the concept of a ht_irq_msg and modifies the architecture read/write routines to update this code. There is a minor consistency fix here as well as x86_64 forgot to initialize the htirq as masked. Signed-off-by: Eric W. Biederman Cc: Andi Kleen Acked-by: Bryan O'Sullivan Cc: Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/htirq.c | 72 ++++++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 0e27f2404a8..e346fe31f97 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -27,82 +27,55 @@ struct ht_irq_cfg { struct pci_dev *dev; unsigned pos; unsigned idx; + struct ht_irq_msg msg; }; -void write_ht_irq_low(unsigned int irq, u32 data) -{ - struct ht_irq_cfg *cfg = get_irq_data(irq); - unsigned long flags; - spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); - pci_write_config_dword(cfg->dev, cfg->pos + 4, data); - spin_unlock_irqrestore(&ht_irq_lock, flags); -} - -void write_ht_irq_high(unsigned int irq, u32 data) -{ - struct ht_irq_cfg *cfg = get_irq_data(irq); - unsigned long flags; - spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); - pci_write_config_dword(cfg->dev, cfg->pos + 4, data); - spin_unlock_irqrestore(&ht_irq_lock, flags); -} -u32 read_ht_irq_low(unsigned int irq) +void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) { struct ht_irq_cfg *cfg = get_irq_data(irq); unsigned long flags; - u32 data; spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); - pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); + if (cfg->msg.address_lo != msg->address_lo) { + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); + pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_lo); + } + if (cfg->msg.address_hi != msg->address_hi) { + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); + pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi); + } spin_unlock_irqrestore(&ht_irq_lock, flags); - return data; + cfg->msg = *msg; } -u32 read_ht_irq_high(unsigned int irq) +void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) { struct ht_irq_cfg *cfg = get_irq_data(irq); - unsigned long flags; - u32 data; - spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); - pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); - spin_unlock_irqrestore(&ht_irq_lock, flags); - return data; + *msg = cfg->msg; } void mask_ht_irq(unsigned int irq) { struct ht_irq_cfg *cfg; - unsigned long flags; - u32 data; + struct ht_irq_msg msg; cfg = get_irq_data(irq); - spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); - pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); - data |= 1; - pci_write_config_dword(cfg->dev, cfg->pos + 4, data); - spin_unlock_irqrestore(&ht_irq_lock, flags); + msg = cfg->msg; + msg.address_lo |= 1; + write_ht_irq_msg(irq, &msg); } void unmask_ht_irq(unsigned int irq) { struct ht_irq_cfg *cfg; - unsigned long flags; - u32 data; + struct ht_irq_msg msg; cfg = get_irq_data(irq); - spin_lock_irqsave(&ht_irq_lock, flags); - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); - pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); - data &= ~1; - pci_write_config_dword(cfg->dev, cfg->pos + 4, data); - spin_unlock_irqrestore(&ht_irq_lock, flags); + msg = cfg->msg; + msg.address_lo &= ~1; + write_ht_irq_msg(irq, &msg); } /** @@ -152,6 +125,9 @@ int ht_create_irq(struct pci_dev *dev, int idx) cfg->dev = dev; cfg->pos = pos; cfg->idx = 0x10 + (idx * 2); + /* Initialize msg to a value that will never match the first write. */ + cfg->msg.address_lo = 0xffffffff; + cfg->msg.address_hi = 0xffffffff; irq = create_irq(); if (irq < 0) { -- cgit From 43539c38cd8edb915d1f0e1f55dcb70638b4cc8e Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 8 Nov 2006 17:44:57 -0800 Subject: [PATCH] htirq: allow buggy drivers of buggy hardware to write the registers This patch adds a variant of ht_create_irq __ht_create_irq that takes an aditional parameter update that is a function that is called whenever we want to write to a drivers htirq configuration registers. This is needed to support the ipath_iba6110 because it's registers in the proper location are not actually conected to the hardware that controlls interrupt delivery. [bos@serpentine.com: fixes] Signed-off-by: Eric W. Biederman Cc: Andi Kleen Cc: Cc: Roland Dreier Signed-off-by: Bryan O'Sullivan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/htirq.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index e346fe31f97..0a8d1cce9fa 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -25,6 +25,8 @@ static DEFINE_SPINLOCK(ht_irq_lock); struct ht_irq_cfg { struct pci_dev *dev; + /* Update callback used to cope with buggy hardware */ + ht_irq_update_t *update; unsigned pos; unsigned idx; struct ht_irq_msg msg; @@ -44,6 +46,8 @@ void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi); } + if (cfg->update) + cfg->update(cfg->dev, irq, msg); spin_unlock_irqrestore(&ht_irq_lock, flags); cfg->msg = *msg; } @@ -79,16 +83,14 @@ void unmask_ht_irq(unsigned int irq) } /** - * ht_create_irq - create an irq and attach it to a device. + * __ht_create_irq - create an irq and attach it to a device. * @dev: The hypertransport device to find the irq capability on. * @idx: Which of the possible irqs to attach to. - * - * ht_create_irq is needs to be called for all hypertransport devices - * that generate irqs. + * @update: Function to be called when changing the htirq message * * The irq number of the new irq or a negative error value is returned. */ -int ht_create_irq(struct pci_dev *dev, int idx) +int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) { struct ht_irq_cfg *cfg; unsigned long flags; @@ -123,6 +125,7 @@ int ht_create_irq(struct pci_dev *dev, int idx) return -ENOMEM; cfg->dev = dev; + cfg->update = update; cfg->pos = pos; cfg->idx = 0x10 + (idx * 2); /* Initialize msg to a value that will never match the first write. */ @@ -144,6 +147,21 @@ int ht_create_irq(struct pci_dev *dev, int idx) return irq; } +/** + * ht_create_irq - create an irq and attach it to a device. + * @dev: The hypertransport device to find the irq capability on. + * @idx: Which of the possible irqs to attach to. + * + * ht_create_irq needs to be called for all hypertransport devices + * that generate irqs. + * + * The irq number of the new irq or a negative error value is returned. + */ +int ht_create_irq(struct pci_dev *dev, int idx) +{ + return __ht_create_irq(dev, idx, NULL); +} + /** * ht_destroy_irq - destroy an irq created with ht_create_irq * @@ -162,5 +180,6 @@ void ht_destroy_irq(unsigned int irq) kfree(cfg); } +EXPORT_SYMBOL(__ht_create_irq); EXPORT_SYMBOL(ht_create_irq); EXPORT_SYMBOL(ht_destroy_irq); -- cgit From 51f65ebccf55121832c265838f93949f898b12ff Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Wed, 8 Nov 2006 17:44:58 -0800 Subject: [PATCH] IB/ipath - program intconfig register using new HT irq hook Eric's changes to the htirq infrastructure require corresponding modifications to the ipath HT driver code so that interrupts are still delivered properly. Signed-off-by: Bryan O'Sullivan Cc: Eric W. Biederman Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/hw/ipath/ipath_driver.c | 17 ++-- drivers/infiniband/hw/ipath/ipath_iba6110.c | 117 ++++++++++++---------------- drivers/infiniband/hw/ipath/ipath_iba6120.c | 8 ++ drivers/infiniband/hw/ipath/ipath_intr.c | 10 +-- drivers/infiniband/hw/ipath/ipath_kernel.h | 4 + 5 files changed, 74 insertions(+), 82 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index b4ffaa7bcbb..09a13c1fc46 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -304,7 +304,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, } addr = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); - ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %x, vend %x/%x " + ipath_cdbg(VERBOSE, "regbase (0) %llx len %d pdev->irq %d, vend %x/%x " "driver_data %lx\n", addr, len, pdev->irq, ent->vendor, ent->device, ent->driver_data); @@ -467,15 +467,15 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, * check 0 irq after we return from chip-specific bus setup, since * that can affect this due to setup */ - if (!pdev->irq) + if (!dd->ipath_irq) ipath_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " "work\n"); else { - ret = request_irq(pdev->irq, ipath_intr, IRQF_SHARED, + ret = request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED, IPATH_DRV_NAME, dd); if (ret) { ipath_dev_err(dd, "Couldn't setup irq handler, " - "irq=%u: %d\n", pdev->irq, ret); + "irq=%d: %d\n", dd->ipath_irq, ret); goto bail_iounmap; } } @@ -637,11 +637,10 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev) * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs * for all versions of the driver, if they were allocated */ - if (pdev->irq) { - ipath_cdbg(VERBOSE, - "unit %u free_irq of irq %x\n", - dd->ipath_unit, pdev->irq); - free_irq(pdev->irq, dd); + if (dd->ipath_irq) { + ipath_cdbg(VERBOSE, "unit %u free irq %d\n", + dd->ipath_unit, dd->ipath_irq); + dd->ipath_f_free_irq(dd); } else ipath_dbg("irq is 0, not doing free_irq " "for unit %u\n", dd->ipath_unit); diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index 9e4e8d4c6e2..e57c7a351cb 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c @@ -38,6 +38,7 @@ #include #include +#include #include "ipath_kernel.h" #include "ipath_registers.h" @@ -913,49 +914,40 @@ static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, } } -static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, - int pos) +static int ipath_ht_intconfig(struct ipath_devdata *dd) { - u32 int_handler_addr_lower; - u32 int_handler_addr_upper; - u64 ihandler; - u32 intvec; + int ret; - /* use indirection register to get the intr handler */ - pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10); - pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower); - pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11); - pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper); + if (dd->ipath_intconfig) { + ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, + dd->ipath_intconfig); /* interrupt address */ + ret = 0; + } else { + ipath_dev_err(dd, "No interrupts enabled, couldn't setup " + "interrupt address\n"); + ret = -EINVAL; + } - ihandler = (u64) int_handler_addr_lower | - ((u64) int_handler_addr_upper << 32); + return ret; +} + +static void ipath_ht_irq_update(struct pci_dev *dev, int irq, + struct ht_irq_msg *msg) +{ + struct ipath_devdata *dd = pci_get_drvdata(dev); + u64 prev_intconfig = dd->ipath_intconfig; + + dd->ipath_intconfig = msg->address_lo; + dd->ipath_intconfig |= ((u64) msg->address_hi) << 32; /* - * kernels with CONFIG_PCI_MSI set the vector in the irq field of - * struct pci_device, so we use that to program the internal - * interrupt register (not config space) with that value. The BIOS - * must still have done the basic MSI setup. - */ - intvec = pdev->irq; - /* - * clear any vector bits there; normally not set but we'll overload - * this for some debug purposes (setting the HTC debug register - * value from software, rather than GPIOs), so it might be set on a - * driver reload. + * If the previous value of dd->ipath_intconfig is zero, we're + * getting configured for the first time, and must not program the + * intconfig register here (it will be programmed later, when the + * hardware is ready). Otherwise, we should. */ - ihandler &= ~0xff0000; - /* x86 vector goes in intrinfo[23:16] */ - ihandler |= intvec << 16; - ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, " - "interruptconfig %llx\n", int_handler_addr_lower, - int_handler_addr_upper, intvec, - (unsigned long long) ihandler); - - /* can't program yet, so save for interrupt setup */ - dd->ipath_intconfig = ihandler; - /* keep going, so we find link control stuff also */ - - return ihandler != 0; + if (prev_intconfig) + ipath_ht_intconfig(dd); } /** @@ -971,12 +963,19 @@ static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, static int ipath_setup_ht_config(struct ipath_devdata *dd, struct pci_dev *pdev) { - int pos, ret = 0; - int ihandler = 0; + int pos, ret; + + ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update); + if (ret < 0) { + ipath_dev_err(dd, "Couldn't create interrupt handler: " + "err %d\n", ret); + goto bail; + } + dd->ipath_irq = ret; + ret = 0; /* - * Read the capability info to find the interrupt info, and also - * handle clearing CRC errors in linkctrl register if necessary. We + * Handle clearing CRC errors in linkctrl register if necessary. We * do this early, before we ever enable errors or hardware errors, * mostly to avoid causing the chip to enter freeze mode. */ @@ -1000,17 +999,9 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, } if (!(cap_type & 0xE0)) slave_or_pri_blk(dd, pdev, pos, cap_type); - else if (cap_type == HT_INTR_DISC_CONFIG) - ihandler = set_int_handler(dd, pdev, pos); } while ((pos = pci_find_next_capability(pdev, pos, PCI_CAP_ID_HT))); - if (!ihandler) { - ipath_dev_err(dd, "Couldn't find interrupt handler in " - "config space\n"); - ret = -ENODEV; - } - bail: return ret; } @@ -1360,25 +1351,6 @@ static void ipath_ht_quiet_serdes(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); } -static int ipath_ht_intconfig(struct ipath_devdata *dd) -{ - int ret; - - if (!dd->ipath_intconfig) { - ipath_dev_err(dd, "No interrupts enabled, couldn't setup " - "interrupt address\n"); - ret = 1; - goto bail; - } - - ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, - dd->ipath_intconfig); /* interrupt address */ - ret = 0; - -bail: - return ret; -} - /** * ipath_pe_put_tid - write a TID in chip * @dd: the infinipath device @@ -1575,6 +1547,14 @@ static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase) return 0; } +static void ipath_ht_free_irq(struct ipath_devdata *dd) +{ + free_irq(dd->ipath_irq, dd); + ht_destroy_irq(dd->ipath_irq); + dd->ipath_irq = 0; + dd->ipath_intconfig = 0; +} + /** * ipath_init_iba6110_funcs - set up the chip-specific function pointers * @dd: the infinipath device @@ -1598,6 +1578,7 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd) dd->ipath_f_cleanup = ipath_setup_ht_cleanup; dd->ipath_f_setextled = ipath_setup_ht_setextled; dd->ipath_f_get_base_info = ipath_ht_get_base_info; + dd->ipath_f_free_irq = ipath_ht_free_irq; /* * initialize chip-specific variables diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index a72ab9de386..6af89683f71 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c @@ -851,6 +851,7 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, int pos, ret; dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ + dd->ipath_irq = pdev->irq; ret = pci_enable_msi(dd->pcidev); if (ret) ipath_dev_err(dd, "pci_enable_msi failed: %d, " @@ -1323,6 +1324,12 @@ done: return 0; } +static void ipath_pe_free_irq(struct ipath_devdata *dd) +{ + free_irq(dd->ipath_irq, dd); + dd->ipath_irq = 0; +} + /** * ipath_init_iba6120_funcs - set up the chip-specific function pointers * @dd: the infinipath device @@ -1349,6 +1356,7 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) dd->ipath_f_cleanup = ipath_setup_pe_cleanup; dd->ipath_f_setextled = ipath_setup_pe_setextled; dd->ipath_f_get_base_info = ipath_pe_get_base_info; + dd->ipath_f_free_irq = ipath_pe_free_irq; /* initialize chip-specific variables */ dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index d9079ee1203..5652a550d44 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c @@ -710,14 +710,14 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) * linuxbios development work, and it may happen in * the future again. */ - if (dd->pcidev && dd->pcidev->irq) { + if (dd->pcidev && dd->ipath_irq) { ipath_dev_err(dd, "Now %u unexpected " "interrupts, unregistering " "interrupt handler\n", *unexpectp); - ipath_dbg("free_irq of irq %x\n", - dd->pcidev->irq); - free_irq(dd->pcidev->irq, dd); + ipath_dbg("free_irq of irq %d\n", + dd->ipath_irq); + dd->ipath_f_free_irq(dd); } } if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { @@ -753,7 +753,7 @@ static void ipath_bad_regread(struct ipath_devdata *dd) if (allbits == 2) { ipath_dev_err(dd, "Still bad interrupt status, " "unregistering interrupt\n"); - free_irq(dd->pcidev->irq, dd); + dd->ipath_f_free_irq(dd); } else if (allbits > 2) { if ((allbits % 10000) == 0) printk("."); diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 06d5020a2f6..986b2125b8f 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -213,6 +213,8 @@ struct ipath_devdata { void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); /* fill out chip-specific fields */ int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); + /* free irq */ + void (*ipath_f_free_irq)(struct ipath_devdata *); struct ipath_ibdev *verbs_dev; struct timer_list verbs_timer; /* total dwords sent (summed from counter) */ @@ -328,6 +330,8 @@ struct ipath_devdata { /* so we can rewrite it after a chip reset */ u32 ipath_pcibar1; + /* interrupt number */ + int ipath_irq; /* HT/PCI Vendor ID (here for NodeInfo) */ u16 ipath_vendorid; /* HT/PCI Device ID (here for NodeInfo) */ -- cgit From 3f048109d9c4f8bb028ccb0d256ab65eb44f5988 Mon Sep 17 00:00:00 2001 From: "malahal@us.ibm.com" Date: Wed, 4 Oct 2006 17:28:37 -0700 Subject: [SCSI] aic94xx SCSI timeout fix The patch updates DDB0 in the aic94xx driver itself. It doesn't supply or use lldd_port_formed field. DDB0 is updated prior to posting notification to libsas layer. Signed-off-by: Malahal Naineni Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_hwi.c | 18 ++++++++++ drivers/scsi/aic94xx/aic94xx_hwi.h | 12 +++++++ drivers/scsi/aic94xx/aic94xx_init.c | 2 -- drivers/scsi/aic94xx/aic94xx_sas.h | 1 + drivers/scsi/aic94xx/aic94xx_scb.c | 72 +++++++++++++++++++++++++++++++++++++ drivers/scsi/aic94xx/aic94xx_seq.c | 5 ++- drivers/scsi/aic94xx/aic94xx_seq.h | 2 +- 7 files changed, 106 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 3c2d7a37993..af7e0113436 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy) return 0; } +static void asd_init_ports(struct asd_ha_struct *asd_ha) +{ + int i; + + spin_lock_init(&asd_ha->asd_ports_lock); + for (i = 0; i < ASD_MAX_PHYS; i++) { + struct asd_port *asd_port = &asd_ha->asd_ports[i]; + + memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE); + memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE); + asd_port->phy_mask = 0; + asd_port->num_phys = 0; + } +} + static int asd_init_phys(struct asd_ha_struct *asd_ha) { u8 i; @@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha) struct asd_phy *phy = &asd_ha->phys[i]; phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; + phy->asd_port = NULL; phy->sas_phy.enabled = 0; phy->sas_phy.id = i; @@ -658,6 +674,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) goto Out; } + asd_init_ports(asd_ha); + err = asd_init_scbs(asd_ha); if (err) { asd_printk("couldn't initialize scbs for %s\n", diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index 7b6aca02cf7..c6c3d18222f 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h @@ -193,6 +193,16 @@ struct asd_seq_data { struct asd_ascb **escb_arr; /* array of pointers to escbs */ }; +/* This is an internal port structure. These are used to get accurate + * phy_mask for updating DDB 0. + */ +struct asd_port { + u8 sas_addr[SAS_ADDR_SIZE]; + u8 attached_sas_addr[SAS_ADDR_SIZE]; + u32 phy_mask; + int num_phys; +}; + /* This is the Host Adapter structure. It describes the hardware * SAS adapter. */ @@ -211,6 +221,8 @@ struct asd_ha_struct { struct hw_profile hw_prof; struct asd_phy phys[ASD_MAX_PHYS]; + spinlock_t asd_ports_lock; + struct asd_port asd_ports[ASD_MAX_PHYS]; struct asd_sas_port ports[ASD_MAX_PHYS]; struct dma_pool *scb_pool; diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index a4cc432bbda..57c5ba4043f 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -786,8 +786,6 @@ static void asd_remove_driver_attrs(struct device_driver *driver) } static struct sas_domain_function_template aic94xx_transport_functions = { - .lldd_port_formed = asd_update_port_links, - .lldd_dev_found = asd_dev_found, .lldd_dev_gone = asd_dev_gone, diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index 64d23171234..9050e93bfd5 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h @@ -733,6 +733,7 @@ struct asd_phy { struct sas_identify_frame *identify_frame; struct asd_dma_tok *id_frm_tok; + struct asd_port *asd_port; u8 frame_rcvd[ASD_EDB_SIZE]; }; diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 7ee49b51b72..b15caf1c8fa 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -168,6 +168,70 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) } } +static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) +{ + int i; + struct asd_port *free_port = NULL; + struct asd_port *port; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + unsigned long flags; + + spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); + if (!phy->asd_port) { + for (i = 0; i < ASD_MAX_PHYS; i++) { + port = &asd_ha->asd_ports[i]; + + /* Check for wide port */ + if (port->num_phys > 0 && + memcmp(port->sas_addr, sas_phy->sas_addr, + SAS_ADDR_SIZE) == 0 && + memcmp(port->attached_sas_addr, + sas_phy->attached_sas_addr, + SAS_ADDR_SIZE) == 0) { + break; + } + + /* Find a free port */ + if (port->num_phys == 0 && free_port == NULL) { + free_port = port; + } + } + + /* Use a free port if this doesn't form a wide port */ + if (i >= ASD_MAX_PHYS) { + port = free_port; + BUG_ON(!port); + memcpy(port->sas_addr, sas_phy->sas_addr, + SAS_ADDR_SIZE); + memcpy(port->attached_sas_addr, + sas_phy->attached_sas_addr, + SAS_ADDR_SIZE); + } + port->num_phys++; + port->phy_mask |= (1U << sas_phy->id); + phy->asd_port = port; + } + ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", + __FUNCTION__, phy->asd_port->phy_mask, sas_phy->id); + asd_update_port_links(asd_ha, phy); + spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); +} + +static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) +{ + struct asd_port *port = phy->asd_port; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + unsigned long flags; + + spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); + if (port) { + port->num_phys--; + port->phy_mask &= ~(1U << sas_phy->id); + phy->asd_port = NULL; + } + spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); +} + static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, struct done_list_struct *dl, int edb_id, int phy_id) @@ -187,6 +251,7 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); asd_dump_frame_rcvd(phy, dl); + asd_form_port(ascb->ha, phy); sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); } @@ -197,6 +262,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, struct asd_ha_struct *asd_ha = ascb->ha; struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; + struct asd_phy *phy = &asd_ha->phys[phy_id]; u8 lr_error = dl->status_block[1]; u8 retries_left = dl->status_block[2]; @@ -221,6 +287,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, asd_turn_led(asd_ha, phy_id, 0); sas_phy_disconnected(sas_phy); + asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); if (retries_left == 0) { @@ -248,6 +315,8 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, unsigned long flags; struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; + struct asd_ha_struct *asd_ha = ascb->ha; + struct asd_phy *phy = &asd_ha->phys[phy_id]; u8 reg = dl->status_block[1]; u32 cont = dl->status_block[2] << ((reg & 3)*8); @@ -284,6 +353,7 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, phy_id); /* The sequencer disables all phys on that port. * We have to re-enable the phys ourselves. */ + asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); break; @@ -351,6 +421,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, u8 sb_opcode = dl->status_block[0]; int phy_id = sb_opcode & DL_PHY_MASK; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; + struct asd_phy *phy = &asd_ha->phys[phy_id]; if (edb > 6 || edb < 0) { ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", @@ -395,6 +466,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, asd_turn_led(asd_ha, phy_id, 0); /* the device is gone */ sas_phy_disconnected(sas_phy); + asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); break; case REQ_TASK_ABORT: diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 56e4b3ba6a0..845112539d0 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c @@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha) * port_map_by_links is also used as the conn_mask byte in the * initiator/target port DDB. */ -void asd_update_port_links(struct asd_sas_phy *sas_phy) +void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) { - struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha; - const u8 phy_mask = (u8) sas_phy->port->phy_mask; + const u8 phy_mask = (u8) phy->asd_port->phy_mask; u8 phy_is_up; u8 mask; int i, err; diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h index 42281c36153..9e715e5496a 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/drivers/scsi/aic94xx/aic94xx_seq.h @@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); int asd_init_seqs(struct asd_ha_struct *asd_ha); int asd_start_seqs(struct asd_ha_struct *asd_ha); -void asd_update_port_links(struct asd_sas_phy *phy); +void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy); #endif #endif -- cgit From 42961ee8fc4b05f5ca4d96ab34abd5149afe3541 Mon Sep 17 00:00:00 2001 From: "malahal@us.ibm.com" Date: Wed, 4 Oct 2006 17:34:03 -0700 Subject: [SCSI] aic94xx SCSI timeout fix: SMP retry fix. Updating DDB0 inside aic94xx driver itself caused SMP command timeout. I hit this SMP timeout problem twice but I am not able to reproduce it since then. Here is a fix that retries an SMP command. Signed-off-by: Malahal Naineni Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_expander.c | 84 +++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 30b8014bcc7..e34a9343549 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -71,55 +71,65 @@ static void smp_task_done(struct sas_task *task) static int smp_execute_task(struct domain_device *dev, void *req, int req_size, void *resp, int resp_size) { - int res; - struct sas_task *task = sas_alloc_task(GFP_KERNEL); + int res, retry; + struct sas_task *task = NULL; struct sas_internal *i = to_sas_internal(dev->port->ha->core.shost->transportt); - if (!task) - return -ENOMEM; - - task->dev = dev; - task->task_proto = dev->tproto; - sg_init_one(&task->smp_task.smp_req, req, req_size); - sg_init_one(&task->smp_task.smp_resp, resp, resp_size); + for (retry = 0; retry < 3; retry++) { + task = sas_alloc_task(GFP_KERNEL); + if (!task) + return -ENOMEM; - task->task_done = smp_task_done; + task->dev = dev; + task->task_proto = dev->tproto; + sg_init_one(&task->smp_task.smp_req, req, req_size); + sg_init_one(&task->smp_task.smp_resp, resp, resp_size); - task->timer.data = (unsigned long) task; - task->timer.function = smp_task_timedout; - task->timer.expires = jiffies + SMP_TIMEOUT*HZ; - add_timer(&task->timer); + task->task_done = smp_task_done; - res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); + task->timer.data = (unsigned long) task; + task->timer.function = smp_task_timedout; + task->timer.expires = jiffies + SMP_TIMEOUT*HZ; + add_timer(&task->timer); - if (res) { - del_timer(&task->timer); - SAS_DPRINTK("executing SMP task failed:%d\n", res); - goto ex_err; - } + res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); - wait_for_completion(&task->completion); - res = -ETASK; - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - SAS_DPRINTK("smp task timed out or aborted\n"); - i->dft->lldd_abort_task(task); - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - SAS_DPRINTK("SMP task aborted and not done\n"); + if (res) { + del_timer(&task->timer); + SAS_DPRINTK("executing SMP task failed:%d\n", res); goto ex_err; } + + wait_for_completion(&task->completion); + res = -ETASK; + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + SAS_DPRINTK("smp task timed out or aborted\n"); + i->dft->lldd_abort_task(task); + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + SAS_DPRINTK("SMP task aborted and not done\n"); + goto ex_err; + } + } + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAM_GOOD) { + res = 0; + break; + } else { + SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " + "status 0x%x\n", __FUNCTION__, + SAS_ADDR(dev->sas_addr), + task->task_status.resp, + task->task_status.stat); + sas_free_task(task); + task = NULL; + } } - if (task->task_status.resp == SAS_TASK_COMPLETE && - task->task_status.stat == SAM_GOOD) - res = 0; - else - SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " - "status 0x%x\n", __FUNCTION__, - SAS_ADDR(dev->sas_addr), - task->task_status.resp, - task->task_status.stat); ex_err: - sas_free_task(task); + BUG_ON(retry == 3 && task != NULL); + if (task != NULL) { + sas_free_task(task); + } return res; } -- cgit From 4039c30ef5d9189ff8dc72aaf610d1c933877e20 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 26 Oct 2006 18:01:06 -0700 Subject: [SCSI] 3ware 9000 add support for 9650SE Updates the 3ware 9000 driver: - Free irq handler in __twa_shutdown(). - Serialize reset code. - Add support for 9650SE controllers. Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/3w-9xxx.c | 141 +++++++++++++++++++++++++++++-------------------- drivers/scsi/3w-9xxx.h | 14 +++-- 2 files changed, 94 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 5f8c26cd66c..b091a0fc4eb 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -66,6 +66,9 @@ 2.26.02.006 - Fix 9550SX pchip reset timeout. Add big endian support. 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). + 2.26.02.008 - Free irq handler in __twa_shutdown(). + Serialize reset code. + Add support for 9650SE controllers. */ #include @@ -89,7 +92,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.007" +#define TW_DRIVER_VERSION "2.26.02.008" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -566,9 +569,9 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) goto out; } - tw_dev->working_srl = fw_on_ctlr_srl; - tw_dev->working_branch = fw_on_ctlr_branch; - tw_dev->working_build = fw_on_ctlr_build; + tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; + tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; + tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; /* Try base mode compatibility */ if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { @@ -590,10 +593,23 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) } goto out; } - tw_dev->working_srl = TW_BASE_FW_SRL; - tw_dev->working_branch = TW_BASE_FW_BRANCH; - tw_dev->working_build = TW_BASE_FW_BUILD; - } + tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; + tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; + tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; + } + + /* Load rest of compatibility struct */ + strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); + tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; + tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH; + tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD; + tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; + tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; + tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; + tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; + tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; + tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; + retval = 0; out: return retval; @@ -631,7 +647,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int goto out2; /* Check data buffer size */ - if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { + if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) { retval = TW_IOCTL_ERROR_OS_EINVAL; goto out2; } @@ -680,13 +696,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int /* Now wait for command to complete */ timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); - /* See if we reset while waiting for the ioctl to complete */ - if (test_bit(TW_IN_RESET, &tw_dev->flags)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - retval = TW_IOCTL_ERROR_OS_ERESTARTSYS; - goto out3; - } - /* We timed out, and didn't get an interrupt */ if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { /* Now we need to reset the board */ @@ -694,11 +703,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int tw_dev->host->host_no, TW_DRIVER, 0xc, cmd); retval = TW_IOCTL_ERROR_OS_EIO; - spin_lock_irqsave(tw_dev->host->host_lock, flags); - tw_dev->state[request_id] = TW_S_COMPLETED; - twa_free_request_id(tw_dev, request_id); - tw_dev->posted_request_count--; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); twa_reset_device_extension(tw_dev, 1); goto out3; } @@ -717,16 +721,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int tw_ioctl->driver_command.status = 0; /* Copy compatiblity struct into ioctl data buffer */ tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; - strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); - tw_compat_info->working_srl = tw_dev->working_srl; - tw_compat_info->working_branch = tw_dev->working_branch; - tw_compat_info->working_build = tw_dev->working_build; - tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL; - tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH; - tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD; - tw_compat_info->driver_srl_low = TW_BASE_FW_SRL; - tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH; - tw_compat_info->driver_build_low = TW_BASE_FW_BUILD; + memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); break; case TW_IOCTL_GET_LAST_EVENT: if (tw_dev->event_queue_wrapped) { @@ -895,7 +890,8 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) } if (status_reg_value & TW_STATUS_QUEUE_ERROR) { - TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); + if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); } @@ -939,10 +935,12 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) unsigned long before; int retval = 1; - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { + if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || + (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { before = jiffies; while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); + msleep(1); if (time_after(jiffies, before + HZ * 30)) goto out; } @@ -1214,6 +1212,10 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) handled = 1; + /* If we are resetting, bail */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) + goto twa_interrupt_bail; + /* Check controller for errors */ if (twa_check_bits(status_reg_value)) { if (twa_decode_bits(tw_dev, status_reg_value)) { @@ -1355,8 +1357,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { newcommand = &full_command_packet->command.newcommand; - newcommand->request_id__lunl = - TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); + newcommand->request_id__lunl = + cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); newcommand->sg_list[0].length = cpu_to_le32(length); newcommand->sgl_entries__lunh = @@ -1531,6 +1533,13 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, int retval = 1; command_que_value = tw_dev->command_packet_phys[request_id]; + + /* For 9650SE write low 4 bytes first */ + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + command_que_value += TW_COMMAND_OFFSET; + writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); + } + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); if (twa_check_bits(status_reg_value)) @@ -1557,13 +1566,17 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, TW_UNMASK_COMMAND_INTERRUPT(tw_dev); goto out; } else { - /* We successfully posted the command packet */ - if (sizeof(dma_addr_t) > 4) { - command_que_value += TW_COMMAND_OFFSET; - writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); - writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + /* Now write upper 4 bytes */ + writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); } else { - writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + if (sizeof(dma_addr_t) > 4) { + command_que_value += TW_COMMAND_OFFSET; + writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); + } else { + writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + } } tw_dev->state[request_id] = TW_S_POSTED; tw_dev->posted_request_count++; @@ -1620,14 +1633,9 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res goto out; TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); + clear_bit(TW_IN_RESET, &tw_dev->flags); + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - /* Wake up any ioctl that was pending before the reset */ - if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - } else { - tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - wake_up(&tw_dev->ioctl_wqueue); - } retval = 0; out: return retval; @@ -1736,6 +1744,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", TW_DRIVER, 0x2c, SCpnt->cmnd[0]); + /* Make sure we are not issuing an ioctl or resetting from ioctl */ + mutex_lock(&tw_dev->ioctl_lock); + /* Now reset the card and some of the device extension data */ if (twa_reset_device_extension(tw_dev, 0)) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); @@ -1744,6 +1755,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) retval = SUCCESS; out: + mutex_unlock(&tw_dev->ioctl_lock); return retval; } /* End twa_scsi_eh_reset() */ @@ -1753,8 +1765,14 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd int request_id, retval; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + /* If we are resetting due to timed out ioctl, report as busy */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) { + retval = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } + /* Check if this FW supports luns */ - if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { + if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { SCpnt->result = (DID_BAD_TARGET << 16); done(SCpnt); retval = 0; @@ -1960,6 +1978,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) /* Disable interrupts */ TW_DISABLE_INTERRUPTS(tw_dev); + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); /* Tell the card we are shutting down */ @@ -2091,21 +2112,25 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id /* Initialize the card */ if (twa_reset_sequence(tw_dev, 0)) - goto out_release_mem_region; + goto out_iounmap; /* Set host specific parameters */ - host->max_id = TW_MAX_UNITS; + if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) + host->max_id = TW_MAX_UNITS_9650SE; + else + host->max_id = TW_MAX_UNITS; + host->max_cmd_len = TW_MAX_CDB_LEN; /* Channels aren't supported by adapter */ - host->max_lun = TW_MAX_LUNS(tw_dev->working_srl); + host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); host->max_channel = 0; /* Register the card with the kernel SCSI layer */ retval = scsi_add_host(host, &pdev->dev); if (retval) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); - goto out_release_mem_region; + goto out_iounmap; } pci_set_drvdata(pdev, host); @@ -2145,6 +2170,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id out_remove_host: scsi_remove_host(host); +out_iounmap: + iounmap(tw_dev->base_addr); out_release_mem_region: pci_release_regions(pdev); out_free_device_extension: @@ -2170,12 +2197,12 @@ static void twa_remove(struct pci_dev *pdev) twa_major = -1; } - /* Free up the IRQ */ - free_irq(tw_dev->tw_pci_dev->irq, tw_dev); - /* Shutdown the card */ __twa_shutdown(tw_dev); + /* Free IO remapping */ + iounmap(tw_dev->base_addr); + /* Free up the mem region */ pci_release_regions(pdev); @@ -2193,6 +2220,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; MODULE_DEVICE_TABLE(pci, twa_pci_tbl); diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index e5685be96f4..7901517d451 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h @@ -289,7 +289,6 @@ static twa_message_type twa_error_table[] = { #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 /* PCI related defines */ -#define TW_NUMDEVICES 1 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 #define TW_PCI_CLEAR_PCI_ABORT 0x2000 @@ -335,6 +334,7 @@ static twa_message_type twa_error_table[] = { #define TW_ALIGNMENT_9000 4 /* 4 bytes */ #define TW_ALIGNMENT_9000_SGL 0x3 #define TW_MAX_UNITS 16 +#define TW_MAX_UNITS_9650SE 32 #define TW_INIT_MESSAGE_CREDITS 0x100 #define TW_INIT_COMMAND_PACKET_SIZE 0x3 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 @@ -354,7 +354,6 @@ static twa_message_type twa_error_table[] = { #define TW_MAX_RESPONSE_DRAIN 256 #define TW_MAX_AEN_DRAIN 40 #define TW_IN_RESET 2 -#define TW_IN_CHRDEV_IOCTL 3 #define TW_IN_ATTENTION_LOOP 4 #define TW_MAX_SECTORS 256 #define TW_AEN_WAIT_TIME 1000 @@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = { #ifndef PCI_DEVICE_ID_3WARE_9550SX #define PCI_DEVICE_ID_3WARE_9550SX 0x1003 #endif +#ifndef PCI_DEVICE_ID_3WARE_9650SE +#define PCI_DEVICE_ID_3WARE_9650SE 0x1004 +#endif /* Bitmask macros to eliminate bitfields */ @@ -442,6 +444,7 @@ static twa_message_type twa_error_table[] = { #define TW_CONTROL_REG_ADDR(x) (x->base_addr) #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) +#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20) #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) @@ -626,6 +629,9 @@ typedef struct TAG_TW_Compatibility_Info unsigned short driver_srl_low; unsigned short driver_branch_low; unsigned short driver_build_low; + unsigned short fw_on_ctlr_srl; + unsigned short fw_on_ctlr_branch; + unsigned short fw_on_ctlr_build; } TW_Compatibility_Info; #pragma pack() @@ -668,9 +674,7 @@ typedef struct TAG_TW_Device_Extension { wait_queue_head_t ioctl_wqueue; struct mutex ioctl_lock; char aen_clobber; - unsigned short working_srl; - unsigned short working_branch; - unsigned short working_build; + TW_Compatibility_Info tw_compat_info; } TW_Device_Extension; #endif /* _3W_9XXX_H */ -- cgit From 7ca63cb470f23a197f187afe936d4bf806197d6e Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Fri, 27 Oct 2006 17:47:49 -0400 Subject: [SCSI] sg: fix incorrect last scatg length For certain LLDs the sg driver can cause on oops when the transfer length is large and not a multiple of PAGE_SIZE. ChangeLog: - correct the length of the last scatter gather list element. - fix some printk()s that have the wrong function name. Signed-off-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/sg.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 3f8b9318856..81e3bc7b02a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20060920"; +static char *sg_version_date = "20061027"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, (int) cmnd[0], (int) hp->cmd_len)); if ((k = sg_start_req(srp))) { - SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k)); + SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k)); sg_finish_rem_req(srp); return k; /* probably out of space --> ENOMEM */ } if ((k = sg_write_xfer(srp))) { - SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n")); + SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n")); sg_finish_rem_req(srp); return k; } @@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, hp->dxfer_len, srp->data.k_use_sg, timeout, SG_DEFAULT_RETRIES, srp, sg_cmd_done, GFP_ATOMIC)) { - SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n")); + SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n")); /* * most likely out of mem, but could also be a bad map */ @@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid) sg_finish_rem_req(srp); srp = NULL; if (NULL == sfp->headrp) { - SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); + SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n")); if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ scsi_device_put(sdp->device); } @@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) POLL_HUP); } } - SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); + SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); if (NULL == sdp->headfp) { sg_dev_arr[k] = NULL; } } else { /* nothing active, simple case */ - SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); + SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); sg_dev_arr[k] = NULL; } sg_nr_dev--; @@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) } } sg->page = p; - sg->length = ret_sz; + sg->length = (ret_sz > num) ? num : ret_sz; - SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", - k, p, ret_sz)); + SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, " + "ret_sz=%d\n", k, num, ret_sz)); } /* end of for loop */ schp->k_use_sg = k; - SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz)); + SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, " + "rem_sz=%d\n", k, rem_sz)); schp->bufflen = blk_size; if (rem_sz > 0) /* must have failed */ @@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp) for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) { SCSI_LOG_TIMEOUT(5, printk( - "sg_remove_scat: k=%d, a=0x%p, len=%d\n", + "sg_remove_scat: k=%d, pg=0x%p, len=%d\n", k, sg->page, sg->length)); sg_page_free(sg->page, sg->length); } -- cgit From 25a122fd0d28b48782b9524a85895573e7ccf304 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Wed, 25 Oct 2006 09:37:41 +0300 Subject: MMC: Poll card status after rescanning cards Some broken cards seem to process CMD1 even in stand-by state. The result is that the card replies with ILLEGAL_COMMAND error for the next command sent after rescanning. Currently the next command is select card, which would return the error. But CMD7 does actually succeed and retries of the command will timeout. The workaround is to poll card status after CMD1 to clear the pending error. Signed-off-by: Timo Teras Signed-off-by: Pierre Ossman --- drivers/mmc/mmc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ee8863c123e..ec8168ac75b 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1178,14 +1178,29 @@ static void mmc_rescan(void *data) { struct mmc_host *host = data; struct list_head *l, *n; + unsigned char power_mode; mmc_claim_host(host); - if (host->ios.power_mode == MMC_POWER_ON) + /* + * Check for removed cards and newly inserted ones. We check for + * removed cards first so we can intelligently re-select the VDD. + */ + power_mode = host->ios.power_mode; + if (power_mode == MMC_POWER_ON) mmc_check_cards(host); mmc_setup(host); + /* + * Some broken cards process CMD1 even in stand-by state. There is + * no reply, but an ILLEGAL_COMMAND error is cached and returned + * after next command. We poll for card status here to clear any + * possibly pending error. + */ + if (power_mode == MMC_POWER_ON) + mmc_check_cards(host); + if (!list_empty(&host->cards)) { /* * (Re-)calculate the fastest clock rate which the -- cgit From 63ef731aa6a81e286de78dcc92241d123424ed39 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Thu, 2 Nov 2006 19:43:27 +0100 Subject: MMC: Do not set unsupported bits in OCR response The card might go to inactive state (according to specification), if there are unsupported bits set in the OCR. Signed-off-by: Timo Teras Signed-off-by: Pierre Ossman --- drivers/mmc/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ec8168ac75b..766bc54406e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -475,7 +475,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) if (bit) { bit -= 1; - ocr = 3 << bit; + ocr &= 3 << bit; host->ios.vdd = bit; mmc_set_ios(host); -- cgit From 7e28db5d8ff63b1cabc221c5cb84a5f45752f1c2 Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Tue, 7 Nov 2006 00:56:39 +0100 Subject: IB/ehca: Assure 4K alignment for firmware control blocks Assure 4K alignment for firmware control blocks in 64K page mode, because kzalloc()'s result address might not be 4K aligned if 64K pages are enabled. Thus, we introduce wrappers called ehca_{alloc,free}_fw_ctrlblock(), which use a slab cache for objects with 4K length and 4K alignment in order to alloc/free firmware control blocks in 64K page mode. In 4K page mode those wrappers just are defines of get_zeroed_page() and free_page(). Signed-off-by: Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_hca.c | 17 +++++----- drivers/infiniband/hw/ehca/ehca_irq.c | 17 +++++----- drivers/infiniband/hw/ehca/ehca_iverbs.h | 8 +++++ drivers/infiniband/hw/ehca/ehca_main.c | 56 +++++++++++++++++++++++++++----- drivers/infiniband/hw/ehca/ehca_mrmw.c | 8 ++--- drivers/infiniband/hw/ehca/ehca_qp.c | 10 +++--- 6 files changed, 81 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 5eae6ac4842..e1b618c5f68 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c @@ -40,6 +40,7 @@ */ #include "ehca_tools.h" +#include "ehca_iverbs.h" #include "hcp_if.h" int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) @@ -49,7 +50,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) ib_device); struct hipz_query_hca *rblock; - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -96,7 +97,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); query_device1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } @@ -109,7 +110,7 @@ int ehca_query_port(struct ib_device *ibdev, ib_device); struct hipz_query_port *rblock; - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -162,7 +163,7 @@ int ehca_query_port(struct ib_device *ibdev, props->active_speed = 0x1; query_port1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } @@ -178,7 +179,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) return -EINVAL; } - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -193,7 +194,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); query_pkey1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } @@ -211,7 +212,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, return -EINVAL; } - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -227,7 +228,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); query_gid1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 048cc443d1e..c3ea746e904 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -45,6 +45,7 @@ #include "ehca_tools.h" #include "hcp_if.h" #include "hipz_fns.h" +#include "ipz_pt_fn.h" #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) @@ -137,38 +138,36 @@ int ehca_error_data(struct ehca_shca *shca, void *data, u64 *rblock; unsigned long block_count; - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); ret = -ENOMEM; goto error_data1; } + /* rblock must be 4K aligned and should be 4K large */ ret = hipz_h_error_data(shca->ipz_hca_handle, resource, rblock, &block_count); - if (ret == H_R_STATE) { + if (ret == H_R_STATE) ehca_err(&shca->ib_device, "No error data is available: %lx.", resource); - } else if (ret == H_SUCCESS) { int length; length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); - if (length > PAGE_SIZE) - length = PAGE_SIZE; + if (length > EHCA_PAGESIZE) + length = EHCA_PAGESIZE; print_error_data(shca, data, rblock, length); - } - else { + } else ehca_err(&shca->ib_device, "Error data could not be fetched: %lx", resource); - } - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); error_data1: return ret; diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h index 319c39d47f3..3720e3032cc 100644 --- a/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h @@ -179,4 +179,12 @@ int ehca_mmap_register(u64 physical,void **mapped, int ehca_munmap(unsigned long addr, size_t len); +#ifdef CONFIG_PPC_64K_PAGES +void *ehca_alloc_fw_ctrlblock(void); +void ehca_free_fw_ctrlblock(void *ptr); +#else +#define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL)) +#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) +#endif + #endif diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 024d511c4b5..01f5aa9cb56 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -40,6 +40,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef CONFIG_PPC_64K_PAGES +#include +#endif #include "ehca_classes.h" #include "ehca_iverbs.h" #include "ehca_mrmw.h" @@ -49,7 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Christoph Raisch "); MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); -MODULE_VERSION("SVNEHCA_0017"); +MODULE_VERSION("SVNEHCA_0018"); int ehca_open_aqp1 = 0; int ehca_debug_level = 0; @@ -94,11 +97,31 @@ spinlock_t ehca_cq_idr_lock; DEFINE_IDR(ehca_qp_idr); DEFINE_IDR(ehca_cq_idr); + static struct list_head shca_list; /* list of all registered ehcas */ static spinlock_t shca_list_lock; static struct timer_list poll_eqs_timer; +#ifdef CONFIG_PPC_64K_PAGES +static struct kmem_cache *ctblk_cache = NULL; + +void *ehca_alloc_fw_ctrlblock(void) +{ + void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); + if (!ret) + ehca_gen_err("Out of memory for ctblk"); + return ret; +} + +void ehca_free_fw_ctrlblock(void *ptr) +{ + if (ptr) + kmem_cache_free(ctblk_cache, ptr); + +} +#endif + static int ehca_create_slab_caches(void) { int ret; @@ -133,6 +156,17 @@ static int ehca_create_slab_caches(void) goto create_slab_caches5; } +#ifdef CONFIG_PPC_64K_PAGES + ctblk_cache = kmem_cache_create("ehca_cache_ctblk", + EHCA_PAGESIZE, H_CB_ALIGNMENT, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!ctblk_cache) { + ehca_gen_err("Cannot create ctblk SLAB cache."); + ehca_cleanup_mrmw_cache(); + goto create_slab_caches5; + } +#endif return 0; create_slab_caches5: @@ -157,6 +191,10 @@ static void ehca_destroy_slab_caches(void) ehca_cleanup_qp_cache(); ehca_cleanup_cq_cache(); ehca_cleanup_pd_cache(); +#ifdef CONFIG_PPC_64K_PAGES + if (ctblk_cache) + kmem_cache_destroy(ctblk_cache); +#endif } #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) @@ -168,7 +206,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) u64 h_ret; struct hipz_query_hca *rblock; - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_gen_err("Cannot allocate rblock memory."); return -ENOMEM; @@ -211,7 +249,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) shca->sport[1].rate = IB_RATE_30_GBPS; num_ports1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } @@ -220,7 +258,7 @@ static int init_node_guid(struct ehca_shca *shca) int ret = 0; struct hipz_query_hca *rblock; - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + rblock = ehca_alloc_fw_ctrlblock(); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -235,7 +273,7 @@ static int init_node_guid(struct ehca_shca *shca) memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); init_node_guid1: - kfree(rblock); + ehca_free_fw_ctrlblock(rblock); return ret; } @@ -431,7 +469,7 @@ static ssize_t ehca_show_##name(struct device *dev, \ \ shca = dev->driver_data; \ \ - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \ + rblock = ehca_alloc_fw_ctrlblock(); \ if (!rblock) { \ dev_err(dev, "Can't allocate rblock memory."); \ return 0; \ @@ -439,12 +477,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ \ if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ dev_err(dev, "Can't query device properties"); \ - kfree(rblock); \ + ehca_free_fw_ctrlblock(rblock); \ return 0; \ } \ \ data = rblock->name; \ - kfree(rblock); \ + ehca_free_fw_ctrlblock(rblock); \ \ if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ return snprintf(buf, 256, "1\n"); \ @@ -752,7 +790,7 @@ int __init ehca_module_init(void) int ret; printk(KERN_INFO "eHCA Infiniband Device Driver " - "(Rel.: SVNEHCA_0017)\n"); + "(Rel.: SVNEHCA_0018)\n"); idr_init(&ehca_qp_idr); idr_init(&ehca_cq_idr); spin_lock_init(&ehca_qp_idr_lock); diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 5ca65441e1d..abce676c0ae 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -1013,7 +1013,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, u32 i; u64 *kpage; - kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + kpage = ehca_alloc_fw_ctrlblock(); if (!kpage) { ehca_err(&shca->ib_device, "kpage alloc failed"); ret = -ENOMEM; @@ -1092,7 +1092,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, ehca_reg_mr_rpages_exit1: - kfree(kpage); + ehca_free_fw_ctrlblock(kpage); ehca_reg_mr_rpages_exit0: if (ret) ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " @@ -1124,7 +1124,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, ehca_mrmw_map_acl(acl, &hipz_acl); ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); - kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + kpage = ehca_alloc_fw_ctrlblock(); if (!kpage) { ehca_err(&shca->ib_device, "kpage alloc failed"); ret = -ENOMEM; @@ -1181,7 +1181,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, } ehca_rereg_mr_rereg1_exit1: - kfree(kpage); + ehca_free_fw_ctrlblock(kpage); ehca_rereg_mr_rereg1_exit0: if ( ret && (ret != -EAGAIN) ) ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4394123cdbd..cf3e50ee2d0 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -811,8 +811,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, unsigned long spl_flags = 0; /* do query_qp to obtain current attr values */ - mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); - if (mqpcb == NULL) { + mqpcb = ehca_alloc_fw_ctrlblock(); + if (!mqpcb) { ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); return -ENOMEM; @@ -1225,7 +1225,7 @@ modify_qp_exit2: } modify_qp_exit1: - kfree(mqpcb); + ehca_free_fw_ctrlblock(mqpcb); return ret; } @@ -1277,7 +1277,7 @@ int ehca_query_qp(struct ib_qp *qp, return -EINVAL; } - qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL ); + qpcb = ehca_alloc_fw_ctrlblock(); if (!qpcb) { ehca_err(qp->device,"Out of memory for qpcb " "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); @@ -1401,7 +1401,7 @@ int ehca_query_qp(struct ib_qp *qp, ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); query_qp_exit1: - kfree(qpcb); + ehca_free_fw_ctrlblock(qpcb); return ret; } -- cgit From 534284a09b3f58cd92acd0652b7267ee142932ba Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Wed, 8 Nov 2006 15:58:31 -0600 Subject: [SCSI] iscsi: always release crypto Unconditionally free crypto state, as it is always allocated during TCP connection creation. Without this, crypto structures leak and crc32c module refcounts grow as connections are created and destroyed. Signed-off-by: Pete Wyckoff Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 0a9dbc59663..c0b8b33e935 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1816,21 +1816,14 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int digest = 0; - - if (conn->hdrdgst_en || conn->datadgst_en) - digest = 1; iscsi_tcp_release_conn(conn); iscsi_conn_teardown(cls_conn); - /* now free tcp_conn */ - if (digest) { - if (tcp_conn->tx_hash.tfm) - crypto_free_hash(tcp_conn->tx_hash.tfm); - if (tcp_conn->rx_hash.tfm) - crypto_free_hash(tcp_conn->rx_hash.tfm); - } + if (tcp_conn->tx_hash.tfm) + crypto_free_hash(tcp_conn->tx_hash.tfm); + if (tcp_conn->rx_hash.tfm) + crypto_free_hash(tcp_conn->rx_hash.tfm); kfree(tcp_conn); } -- cgit From d6e24d1c8a197cc9c2a1568224474f4b7af50803 Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Wed, 8 Nov 2006 15:58:32 -0600 Subject: [SCSI] iscsi: add newlines to debug messages Some messages from debug_scsi do not have trailing newlines, making console messages difficult to read. Fix that. Signed-off-by: Pete Wyckoff Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2865ebd557e..5d886218948 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -975,13 +975,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) if (session->state == ISCSI_STATE_TERMINATE) { failed: debug_scsi("failing host reset: session terminated " - "[CID %d age %d]", conn->id, session->age); + "[CID %d age %d]\n", conn->id, session->age); spin_unlock_bh(&session->lock); return FAILED; } if (sc->SCp.phase == session->age) { - debug_scsi("failing connection CID %d due to SCSI host reset", + debug_scsi("failing connection CID %d due to SCSI host reset\n", conn->id); fail_session = 1; } @@ -1054,7 +1054,8 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, NULL, 0); if (rc) { iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc); + debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt, + rc); return rc; } @@ -1071,7 +1072,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, conn->tmabort_timer.function = iscsi_tmabort_timedout; conn->tmabort_timer.data = (unsigned long)ctask; add_timer(&conn->tmabort_timer); - debug_scsi("abort set timeout [itt 0x%x]", ctask->itt); + debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); } spin_unlock_bh(&session->lock); mutex_unlock(&conn->xmitmutex); -- cgit From db37c505e5dfc1a26d6c82f1ce0c3ae06641c3e0 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 8 Nov 2006 15:58:33 -0600 Subject: [SCSI] iscsi_tcp: fix xmittask oops XMSTATE_SOL_HDR could be set when the xmit thread tests it, but there may not be anything on the r2tqueue yet. Move the XMSTATE_SOL_HDR set before the addition to the queue to make sure that when we pull something off it it is valid. This does not add locks around the xmstate test or make that a atmoic_t because this is a fast path and if it is set when we test it we can handle it there without the overhead. Later on we check the xmitqueue for all requests with the session lock so we will not miss it. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index c0b8b33e935..d0b139cccbb 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) iscsi_solicit_data_init(conn, ctask, r2t); tcp_ctask->exp_r2tsn = r2tsn + 1; - tcp_ctask->xmstate |= XMSTATE_SOL_HDR; __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); + tcp_ctask->xmstate |= XMSTATE_SOL_HDR; list_move_tail(&ctask->running, &conn->xmitqueue); scsi_queue_work(session->host, &conn->xmitwork); @@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn, if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - if (!tcp_ctask->r2t) + if (!tcp_ctask->r2t) { + spin_lock_bh(&session->lock); __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, sizeof(void*)); + spin_unlock_bh(&session->lock); + } send_hdr: r2t = tcp_ctask->r2t; dtask = &r2t->dtask; -- cgit From 82a0d7b5829ebd033b7f808c026ab43509913692 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 8 Nov 2006 15:58:34 -0600 Subject: [SCSI] iscsi class: update version Update version number Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 2d3baa99ca2..9b25124a989 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -33,7 +33,7 @@ #define ISCSI_SESSION_ATTRS 11 #define ISCSI_CONN_ATTRS 11 #define ISCSI_HOST_ATTRS 0 -#define ISCSI_TRANSPORT_VERSION "2.0-685" +#define ISCSI_TRANSPORT_VERSION "2.0-724" struct iscsi_internal { int daemon_pid; -- cgit From 107e716b3487df5e2940ebe3338d935306efc78b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 9 Nov 2006 21:45:09 +0100 Subject: [SCSI] gdth: Fix && typos Fix uses of "&&" where "&" was obviously intended instead. Signed-off-by: Jean Delvare Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 4bc14ad92e2..4c698a71f66 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) IStatus &= ~0x80; #ifdef INT_COAL if (coalesced) - ha->status = pcs->ext_status && 0xffff; + ha->status = pcs->ext_status & 0xffff; else #endif ha->status = gdth_readw(&dp6m_ptr->i960r.status); @@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (coalesced) { ha->info = pcs->info0; ha->info2 = pcs->info1; - ha->service = (pcs->ext_status >> 16) && 0xffff; + ha->service = (pcs->ext_status >> 16) & 0xffff; } else #endif { -- cgit From 05052f7f130b1232faeee1674a5bc41f67746cff Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 8 Nov 2006 19:56:37 -0800 Subject: [SCSI] psi240i.c: fix an array overrun Fix an array overrun spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/psi240i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index ac0419e2714..899e89d6fe6 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -328,7 +328,7 @@ static void Irq_Handler (int irq, void *dev_id) pinquiryData->AdditionalLength = 35 - 4; // Fill in vendor identification fields. - for ( z = 0; z < 20; z += 2 ) + for ( z = 0; z < 8; z += 2 ) { pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; -- cgit From 599540a85595bd5950354bd95f5ebf9c6e07c971 Mon Sep 17 00:00:00 2001 From: Kalle Pokki Date: Wed, 1 Nov 2006 09:52:41 +0200 Subject: [POWERPC] CPM_UART: Fix non-console transmit The SMC and SCC hardware transmitter is enabled at the wrong place. Simply writing twice to the non-console port, like $ echo asdf > /dev/ttyCPM1 $ echo asdf > /dev/ttyCPM1 puts the shell into endless uninterruptible sleep, since the transmitter is stopped after the first write, and is not enabled before the shutdown function of the second write. Thus the transmit buffers are never emptied. Signed-off-by: Kalle Pokki Signed-off-by: Vitaly Bordug Signed-off-by: Paul Mackerras --- drivers/serial/cpm_uart/cpm_uart_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 0abb544ae63..32fd8c83bd8 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -195,10 +195,8 @@ static void cpm_uart_start_tx(struct uart_port *port) if (cpm_uart_tx_pump(port) != 0) { if (IS_SMC(pinfo)) { smcp->smc_smcm |= SMCM_TX; - smcp->smc_smcmr |= SMCMR_TEN; } else { sccp->scc_sccm |= UART_SCCM_TX; - pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; } } } @@ -421,9 +419,10 @@ static int cpm_uart_startup(struct uart_port *port) /* Startup rx-int */ if (IS_SMC(pinfo)) { pinfo->smcp->smc_smcm |= SMCM_RX; - pinfo->smcp->smc_smcmr |= SMCMR_REN; + pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); } else { pinfo->sccp->scc_sccm |= UART_SCCM_RX; + pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); } if (!(pinfo->flags & FLAG_CONSOLE)) -- cgit From 0091cf5a6ae6e52fc95ceb53200975ef2c81c206 Mon Sep 17 00:00:00 2001 From: Kalle Pokki Date: Wed, 1 Nov 2006 15:08:13 +0200 Subject: [POWERPC] CPM_UART: Fix non-console initialisation The cpm_uart driver is initialised incorrectly, if there is a frame buffer console, and CONFIG_SERIAL_CPM_CONSOLE is defined. The driver fails to call cpm_uart_init_portdesc() and set_lineif() in this case. Signed-off-by: Kalle Pokki Signed-off-by: Vitaly Bordug Signed-off-by: Paul Mackerras --- drivers/serial/cpm_uart/cpm_uart.h | 2 +- drivers/serial/cpm_uart/cpm_uart_core.c | 11 ++++++----- drivers/serial/cpm_uart/cpm_uart_cpm1.c | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index a8f894c7819..69715e55650 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -88,7 +88,7 @@ extern struct uart_cpm_port cpm_uart_ports[UART_NR]; /* these are located in their respective files */ void cpm_line_cr_cmd(int line, int cmd); -int cpm_uart_init_portdesc(void); +int __init cpm_uart_init_portdesc(void); int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); void cpm_uart_freebuf(struct uart_cpm_port *pinfo); diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 32fd8c83bd8..7a3b97fdf8d 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1349,11 +1349,10 @@ static int cpm_uart_init(void) { pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); pr_info( "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); -#ifndef CONFIG_SERIAL_CPM_CONSOLE - ret = cpm_uart_init_portdesc(); - if (ret) - return ret; -#endif + + /* Don't run this again, if the console driver did it already */ + if (cpm_uart_nr == 0) + cpm_uart_init_portdesc(); cpm_reg.nr = cpm_uart_nr; ret = uart_register_driver(&cpm_reg); @@ -1365,6 +1364,8 @@ static int cpm_uart_init(void) { int con = cpm_uart_port_map[i]; cpm_uart_ports[con].port.line = i; cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; + if (cpm_uart_ports[con].set_lineif) + cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]); uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); } diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 95afc37297a..08e55fdc882 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -184,7 +184,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) } /* Setup any dynamic params in the uart desc */ -int cpm_uart_init_portdesc(void) +int __init cpm_uart_init_portdesc(void) { pr_debug("CPM uart[-]:init portdesc\n"); -- cgit From 0daa2303028a63dbd1b2e38f10854f0f7bf1ef9a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Nov 2006 19:51:01 -0800 Subject: [PATCH] bonding: lockdep annotation ============================================= [ INFO: possible recursive locking detected ] 2.6.17-1.2600.fc6 #1 Signed-off-by: Jeff Garzik --- drivers/net/bonding/bond_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c0bbddae4ec..17a461152d3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4692,6 +4692,8 @@ static int bond_check_params(struct bond_params *params) return 0; } +static struct lock_class_key bonding_netdev_xmit_lock_key; + /* Create a new bond based on the specified name and bonding parameters. * Caller must NOT hold rtnl_lock; we need to release it here before we * set up our sysfs entries. @@ -4727,6 +4729,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (res < 0) { goto out_bond; } + + lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key); + if (newbond) *newbond = bond_dev->priv; -- cgit From ace48ffb5d6c927c5a98048d93543e1cae0eebd0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 8 Nov 2006 19:51:03 -0800 Subject: [PATCH] com20020 build fix com20020.c needs to export functions if either of the ISA or PCI modules are built as loadable modules. Or they could always be exported. WARNING: "com20020_found" [drivers/net/arcnet/com20020-pci.ko] undefined! WARNING: "com20020_check" [drivers/net/arcnet/com20020-pci.ko] undefined! Signed-off-by: Randy Dunlap Cc: Toralf Forster Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/arcnet/com20020.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 0dc70c7b794..aa9dd8f1126 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -337,13 +337,16 @@ static void com20020_set_mc_list(struct net_device *dev) } } -#ifdef MODULE - +#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \ + defined(CONFIG_ARCNET_COM20020_ISA_MODULE) EXPORT_SYMBOL(com20020_check); EXPORT_SYMBOL(com20020_found); +#endif MODULE_LICENSE("GPL"); +#ifdef MODULE + int init_module(void) { BUGLVL(D_NORMAL) printk(VERSION); -- cgit From 92b1f905637bbd79fcd430a09737fd97061eb405 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 8 Nov 2006 19:49:15 -0800 Subject: [PATCH] drivers cris: return on NULL dev_alloc_skb() If the next descriptor array entry cannot be allocated by dev_alloc_skb(), return immediately so it is not dereferenced later. We cannot register the device with a partial descriptor list. Cc: Mikael Starvik Signed-off-by: David Rientjes Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/cris/eth_v10.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 966b563e42b..a03d781f6d0 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -509,6 +509,8 @@ etrax_ethernet_init(void) * does not share cacheline with any other data (to avoid cache bug) */ RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); + if (!RxDescList[i].skb) + return -ENOMEM; RxDescList[i].descr.ctrl = 0; RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE; RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]); -- cgit From d027c4dc7d6e35a4e43dbcc178f0bf3359814306 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 3 Nov 2006 07:14:32 -0300 Subject: V4L/DVB (4795): Tda826x: use correct max frequency sparse "defined twice" warning Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda826x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c index eeab26bd36e..34815b0b97e 100644 --- a/drivers/media/dvb/frontends/tda826x.c +++ b/drivers/media/dvb/frontends/tda826x.c @@ -121,7 +121,7 @@ static struct dvb_tuner_ops tda826x_tuner_ops = { .info = { .name = "Philips TDA826X", .frequency_min = 950000, - .frequency_min = 2175000 + .frequency_max = 2175000 }, .release = tda826x_release, .sleep = tda826x_sleep, -- cgit From ff97d93d6a311759db1b74b9b90dd6bcb8ce0aee Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Fri, 3 Nov 2006 10:45:52 -0300 Subject: V4L/DVB (4802): Cx88: fix remote control on WinFast 2000XP Expert fix remote control on WinFast 2000XP Expert by setting timing back to 1 ms, like it was in the original patch by Robert Reid. Signed-off-by: Hermann Pitton Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-input.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index ee48995a4ab..57e1c024a54 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -202,13 +202,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->sampling = 1; break; case CX88_BOARD_WINFAST_DTV2000H: - case CX88_BOARD_WINFAST2000XP_EXPERT: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; ir->mask_keyup = 0x100; ir->polling = 50; /* ms */ break; + case CX88_BOARD_WINFAST2000XP_EXPERT: + ir_codes = ir_codes_winfast; + ir->gpio_addr = MO_GP0_IO; + ir->mask_keycode = 0x8f8; + ir->mask_keyup = 0x100; + ir->polling = 1; /* ms */ + break; case CX88_BOARD_IODATA_GVBCTV7E: ir_codes = ir_codes_iodata_bctv7e; ir->gpio_addr = MO_GP0_IO; @@ -216,7 +222,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 5; /* ms */ break; - case CX88_BOARD_PROLINK_PLAYTVPVR: + case CX88_BOARD_PROLINK_PLAYTVPVR: case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: ir_codes = ir_codes_pixelview; ir->gpio_addr = MO_GP1_IO; -- cgit From ce48d5ecf3f52378064f317e0094b601508e9b3e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 5 Nov 2006 09:02:13 -0300 Subject: V4L/DVB (4804): Fix missing i2c dependency for saa7110 drivers/media/video/saa7110.c:112: undefined reference to `i2c_master_send' drivers/built-in.o: In function `saa7110_read': drivers/media/video/saa7110.c:130: undefined reference to `i2c_smbus_read_byte' drivers/media/video/saa7110.c:130: undefined reference to `i2c_smbus_read_byte' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fbe5b6168cc..bf267552941 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -186,7 +186,7 @@ config VIDEO_KS0127 config VIDEO_SAA7110 tristate "Philips SAA7110 video decoder" - depends on VIDEO_V4L1 + depends on VIDEO_V4L1 && I2C ---help--- Support for the Philips SAA7110 video decoders. -- cgit From 450efcfd2e1d941e302a8c89322fbfcef237be98 Mon Sep 17 00:00:00 2001 From: "pasky@ucw.cz" Date: Sun, 12 Nov 2006 14:22:32 -0300 Subject: V4L/DVB (4814): Remote support for Avermedia 777 I didn't test it personally since I don't have this card, but A16AR uses the same interface and that one certainly does work perfectly (see the next patch). This patch was originally sent in http://marc.theaimsgroup.com/?l=linux-video&m=114743413825375&w=2 https://www.redhat.com/mailman/private/video4linux-list/2006-May/msg00103.html but never got applied. This version has some trivial modifications and drops the weird gpio hack (it's not clear what practical purpose does it serve). Signed-off-by: Jose Alberto Reguero Signed-off-by: Petr Baudis Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 1 + drivers/media/video/saa7134/saa7134-input.c | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c9d8e3b9cc3..94324b3c34e 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3718,6 +3718,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: + case SAA7134_BOARD_AVERMEDIA_777: /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ff5991136f4..e8dcb6f9f8f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -194,6 +194,14 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; + case SAA7134_BOARD_AVERMEDIA_777: + ir_codes = ir_codes_avermedia; + mask_keycode = 0x02F200; + mask_keydown = 0x000400; + polling = 50; // ms + /* Without this we won't receive key up events */ + saa_setb(SAA7134_GPIO_GPMODE1, 0x1); + saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; -- cgit From 29e0f1a136d39c5683d998741911b769d0172d52 Mon Sep 17 00:00:00 2001 From: "pasky@ucw.cz" Date: Sun, 12 Nov 2006 14:23:32 -0300 Subject: V4L/DVB (4815): Remote support for Avermedia A16AR The remote as well as the GPIO interface is the same as what comes with 777. For an example of mplayer lirc configuration, see http://pasky.or.cz/~pasky/dev/v4l/lircrc Signed-off-by: Petr Baudis Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 2 +- drivers/media/video/saa7134/saa7134-input.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 94324b3c34e..1a402e45912 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3735,6 +3735,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_PROTEUS_2309: + case SAA7134_BOARD_AVERMEDIA_A16AR: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -3773,7 +3774,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); break; - case SAA7134_BOARD_AVERMEDIA_A16AR: case SAA7134_BOARD_AVERMEDIA_CARDBUS: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index e8dcb6f9f8f..7f62403b195 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -185,7 +185,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: - case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; mask_keydown = 0x000010; @@ -195,6 +194,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; case SAA7134_BOARD_AVERMEDIA_777: + case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = ir_codes_avermedia; mask_keycode = 0x02F200; mask_keydown = 0x000400; -- cgit From 0871a8849b80646074cd28b2b078c8e002e51282 Mon Sep 17 00:00:00 2001 From: "pasky@ucw.cz" Date: Sun, 12 Nov 2006 14:24:57 -0300 Subject: V4L/DVB (4816): Change tuner type for Avermedia A16AR This changes it from TDA8290 which is allegedly very unlikely to TD1316 which is allegedly very likely. I didn't get it to work with either, but expected that this got applied when Mauro sent it to me, so here it goes again; feel free to drop it to the floor. :-) Signed-off-by: Petr Baudis Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 1a402e45912..51f0cfdcb68 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2969,7 +2969,7 @@ struct saa7134_board saa7134_boards[] = { /* Petr Baudis */ .name = "AVerMedia TV Hybrid A16AR", .audio_clock = 0x187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, /* untested */ + .tuner_type = TUNER_PHILIPS_TD1316, /* untested */ .radio_type = TUNER_TEA5767, /* untested */ .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, -- cgit From fef4fa1475db6a53237e29451c88c15167d69cc4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 9 Nov 2006 17:25:28 -0300 Subject: V4L/DVB (4817): Fix uses of "&&" where "&" was intended Fix uses of "&&" where "&" was intended in bttv-cards.c and tveeprom.c Signed-off-by: Jean Delvare Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-cards.c | 2 +- drivers/media/video/tveeprom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index a84903e0d81..21ebe8f1381 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -4001,7 +4001,7 @@ static void __devinit init_PXC200(struct bttv *btv) * - sleep 1ms * - write 0x0E * read from GPIO_DATA into buf (uint_32) - * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 ) + * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 ) * error. ERROR_CPLD_Check_Failed. */ /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index e6baaee038b..6b9ef731b83 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -468,7 +468,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, (eeprom_data[i+6] << 8) + (eeprom_data[i+7] << 16); - if ( (eeprom_data[i + 8] && 0xf0) && + if ( (eeprom_data[i + 8] & 0xf0) && (tvee->serial_number < 0xffffff) ) { tvee->MAC_address[0] = 0x00; tvee->MAC_address[1] = 0x0D; -- cgit From 6f36fbb242442184d314e305199bb9a449be4f67 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 9 Nov 2006 17:36:44 -0300 Subject: V4L/DVB (4818): Flexcop-usb: fix debug printk .. fix debug printk. Why, oh why, one would want to do (u16 & 0xff) << 8 and print it with %02x format? Acked-by: Patrick Boettcher Signed-off-by: Alexey Dobriyan Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 2853ea1bdaf..87fb75f0d1c 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c @@ -246,7 +246,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, wIndex = (chipaddr << 8 ) | addr; deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, - ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8); + wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); len = usb_control_msg(fc_usb->udev,pipe, req, -- cgit From d67afe5ed00070de0965bfc98de5f6ed3a80a73e Mon Sep 17 00:00:00 2001 From: David Miller Date: Fri, 10 Nov 2006 12:27:48 -0800 Subject: [PATCH] pci: don't try to remove sysfs files before they are setup. The PCI sysfs attributes are created after the initial PCI bus scan. With the addition of more return value checking and assertions in the device and sysfs layers we now can get dumps like this on sparc64: [ 20.135032] Call Trace: [ 20.135042] [0000000000537f88] pci_remove_bus_device+0x30/0xc0 [ 20.135076] [000000000078f890] pci_fill_in_pbm_cookies+0x98/0x440 [ 20.135109] [000000000042e828] sabre_scan_bus+0x230/0x400 [ 20.135139] [000000000078c710] pcibios_init+0x58/0xa0 [ 20.135159] [0000000000416f14] init+0x9c/0x2e0 [ 20.135190] [0000000000417a50] kernel_thread+0x38/0x60 [ 20.135211] [0000000000417170] rest_init+0x18/0x40 [ 20.135514] PCI0(PBMB): Bus running at 33MHz It's triggering because removal of the "config" PCI sysfs file for the device fails. On sparc64, after probing the device, we'll delete the PCI device via pci_remove_bus_device() if we cannot find the firmware device tree node corresponding to it. This is fine, but at this point the sysfs files for the PCI device won't be setup yet. So we should not try to do anything in pci_remove_sysfs_dev_files() if pci_sysfs_init() has not run yet. Signed-off-by: David S. Miller Acked-by: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/pci-sysfs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a1d2e979b17..f952bfea48a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -642,6 +642,9 @@ err: */ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { + if (!sysfs_initialized) + return; + if (pdev->cfg_size < 4096) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); else -- cgit From 1a4b0fc503ff4149f5915be4aeb179b9453cf485 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Nov 2006 12:27:49 -0800 Subject: [PATCH] mspec driver build fix Fix MSPEC driver to build for non SN2 enabled configs as the driver should work in cached and uncached modes (no fetchop) on these systems. In addition make MSPEC select IA64_UNCACHED_ALLOCATOR, which is required for it and move it to arch/ia64/Kconfig to avoid warnings on non ia64 architectures running allmodconfig. Once the Kconfig code is fixed, we can move it back. Signed-off-by: Jes Sorensen Cc: Fernando Luis Vzquez Cao Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/Kconfig | 8 -------- drivers/char/mspec.c | 8 +++++++- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 39a9f8cc641..2af12fc4511 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -409,14 +409,6 @@ config SGI_MBCS If you have an SGI Altix with an attached SABrick say Y or M here, otherwise say N. -config MSPEC - tristate "Memory special operations driver" - depends on IA64 - help - If you have an ia64 and you want to enable memory special - operations support (formerly known as fetchop), say Y here, - otherwise say N. - source "drivers/serial/Kconfig" config UNIX98_PTYS diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 5c0dec39cf6..235e8922611 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -72,7 +72,11 @@ enum { MSPEC_UNCACHED }; +#ifdef CONFIG_SGI_SN static int is_sn2; +#else +#define is_sn2 0 +#endif /* * One of these structures is allocated when an mspec region is mmaped. The @@ -211,7 +215,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) if (vdata->type == MSPEC_FETCHOP) paddr = TO_AMO(maddr); else - paddr = __pa(TO_CAC(maddr)); + paddr = maddr & ~__IA64_UNCACHED_OFFSET; pfn = paddr >> PAGE_SHIFT; @@ -335,6 +339,7 @@ mspec_init(void) * The fetchop device only works on SN2 hardware, uncached and cached * memory drivers should both be valid on all ia64 hardware */ +#ifdef CONFIG_SGI_SN if (ia64_platform_is("sn2")) { is_sn2 = 1; if (is_shub2()) { @@ -363,6 +368,7 @@ mspec_init(void) goto free_scratch_pages; } } +#endif ret = misc_register(&cached_miscdev); if (ret) { printk(KERN_ERR "%s: failed to register device %i\n", -- cgit From 7947d2cc2c2e01125a393de83862d02b621999fe Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 10 Nov 2006 12:27:50 -0800 Subject: [PATCH] IPMI: Fix more && typos Fix improper use of "&&" when "&" was intended. Signed-off-by: Jean Delvare Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 0b07ca1b71f..a41b8df2407 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1854,7 +1854,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev, struct bmc_device *bmc = dev_get_drvdata(dev); return snprintf(buf, 10, "%u\n", - bmc->id.device_revision && 0x80 >> 7); + (bmc->id.device_revision & 0x80) >> 7); } static ssize_t revision_show(struct device *dev, struct device_attribute *attr, @@ -1863,7 +1863,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, struct bmc_device *bmc = dev_get_drvdata(dev); return snprintf(buf, 20, "%u\n", - bmc->id.device_revision && 0x0F); + bmc->id.device_revision & 0x0F); } static ssize_t firmware_rev_show(struct device *dev, -- cgit From e40c67597eac7a0b0e676867517b01a5a57f7b4b Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Fri, 10 Nov 2006 12:27:52 -0800 Subject: [PATCH] Patch for nvidia divide by zero error for 7600 pci-express card The following patch resolves the divide by zero error I encountered on my system: http://marc.10east.com/?l=linux-fbdev-devel&m=116058257024413&w=2 I accomplished this by merging what I thought was appropriate from: http://webcvs.freedesktop.org/xorg/driver/xf86-video-nv/src/ Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nv_hw.c | 12 +++++++++--- drivers/video/nvidia/nv_setup.c | 18 +++++++++++++++++- drivers/video/nvidia/nv_type.h | 1 + drivers/video/nvidia/nvidia.c | 24 ++++++++++++------------ 4 files changed, 39 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index 9ed640d3572..ea426115c6f 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk, if (par->Architecture >= NV_ARCH_40) { pll = NV_RD32(par->PMC, 0x4020); - P = (pll >> 16) & 0x03; + P = (pll >> 16) & 0x07; pll = NV_RD32(par->PMC, 0x4024); M = pll & 0xFF; N = (pll >> 8) & 0xFF; - MB = (pll >> 16) & 0xFF; - NB = (pll >> 24) & 0xFF; + if (((par->Chipset & 0xfff0) == 0x0290) || + ((par->Chipset & 0xfff0) == 0x0390)) { + MB = 1; + NB = 1; + } else { + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; + } *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; pll = NV_RD32(par->PMC, 0x4000); diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index a18a9aebf05..61dc46fecf2 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c @@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info) case 0x0186: case 0x0187: case 0x018D: + case 0x0228: case 0x0286: case 0x028C: case 0x0316: @@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info) case 0x034C: case 0x0160: case 0x0166: + case 0x0169: + case 0x016B: + case 0x016C: + case 0x016D: case 0x00C8: case 0x00CC: case 0x0144: @@ -639,12 +644,23 @@ int NVCommonSetup(struct fb_info *info) par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; - printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); + printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); } if (monA) info->monspecs = *monA; + if (!par->FlatPanel || !par->twoHeads) + par->FPDither = 0; + + par->LVDS = 0; + if (par->FlatPanel && par->twoHeads) { + NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); + if (par->PRAMDAC0[0x08b4] & 1) + par->LVDS = 1; + printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); + } + kfree(edidA); kfree(edidB); done: diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h index acdc2669340..86e65dea60d 100644 --- a/drivers/video/nvidia/nv_type.h +++ b/drivers/video/nvidia/nv_type.h @@ -129,6 +129,7 @@ struct nvidia_par { int fpHeight; int PanelTweak; int paneltweak; + int LVDS; int pm_state; u32 crtcSync_read; u32 fpSyncs; diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index eb24107bcc8..538e947610e 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1160,20 +1160,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) case 0x0340: /* GeForceFX 5700 */ arch = NV_ARCH_30; break; - case 0x0040: - case 0x00C0: - case 0x0120: + case 0x0040: /* GeForce 6800 */ + case 0x00C0: /* GeForce 6800 */ + case 0x0120: /* GeForce 6800 */ case 0x0130: - case 0x0140: - case 0x0160: - case 0x01D0: - case 0x0090: - case 0x0210: - case 0x0220: + case 0x0140: /* GeForce 6600 */ + case 0x0160: /* GeForce 6200 */ + case 0x01D0: /* GeForce 7200, 7300, 7400 */ + case 0x0090: /* GeForce 7800 */ + case 0x0210: /* GeForce 6800 */ + case 0x0220: /* GeForce 6200 */ case 0x0230: - case 0x0240: - case 0x0290: - case 0x0390: + case 0x0240: /* GeForce 6100 */ + case 0x0290: /* GeForce 7900 */ + case 0x0390: /* GeForce 7600 */ arch = NV_ARCH_40; break; case 0x0020: /* TNT, TNT2 */ -- cgit From 09123d230a294cd3b860f4ea042235b988277f0a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 10 Nov 2006 12:27:57 -0800 Subject: [PATCH] SCSI core: always store >= 36 bytes of INQUIRY data This patch (as810c) copies a minimum of 36 bytes of INQUIRY data, even if the device claims that not all of them are valid. Often badly behaved devices put plausible data in the Vendor, Product, and Revision strings but set the Additional Length byte to a small value. Using potentially valid data is certainly better than allocating a short buffer and then reading beyond the end of it, which is what we do now. Signed-off-by: Alan Stern Cc: James Bottomley Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/scsi_scan.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index fd9e281c3bf..94a274645f6 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -631,12 +631,22 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, * scanning run at their own risk, or supply a user level program * that can correctly scan. */ - sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC); - if (sdev->inquiry == NULL) { + + /* + * Copy at least 36 bytes of INQUIRY data, so that we don't + * dereference unallocated memory when accessing the Vendor, + * Product, and Revision strings. Badly behaved devices may set + * the INQUIRY Additional Length byte to a small value, indicating + * these strings are invalid, but often they contain plausible data + * nonetheless. It doesn't matter if the device sent < 36 bytes + * total, since scsi_probe_lun() initializes inq_result with 0s. + */ + sdev->inquiry = kmemdup(inq_result, + max_t(size_t, sdev->inquiry_len, 36), + GFP_ATOMIC); + if (sdev->inquiry == NULL) return SCSI_SCAN_NO_RESPONSE; - } - memcpy(sdev->inquiry, inq_result, sdev->inquiry_len); sdev->vendor = (char *) (sdev->inquiry + 8); sdev->model = (char *) (sdev->inquiry + 16); sdev->rev = (char *) (sdev->inquiry + 32); -- cgit From c58121143f87930621c1a6fa9683b6862f2b42c9 Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Sun, 5 Nov 2006 21:42:56 +0100 Subject: IB/ehca: Use named constant for max mtu Define and use a constant EHCA_MAX_MTU instead hardcoded value. Signed-off-by: Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_av.c | 5 ++--- drivers/infiniband/hw/ehca/hipz_hw.h | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c index 3bac197f901..214e2fdddee 100644 --- a/drivers/infiniband/hw/ehca/ehca_av.c +++ b/drivers/infiniband/hw/ehca/ehca_av.c @@ -118,8 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) } memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); } - /* for the time being we use a hard coded PMTU of 2048 Bytes */ - av->av.pmtu = 4; + av->av.pmtu = EHCA_MAX_MTU; /* dgid comes in grh.word_3 */ memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, @@ -193,7 +192,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); } - new_ehca_av.pmtu = 4; /* see also comment in create_ah() */ + new_ehca_av.pmtu = EHCA_MAX_MTU; memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, sizeof(ah_attr->grh.dgid)); diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h index 3fc92b031c5..fad91368dc5 100644 --- a/drivers/infiniband/hw/ehca/hipz_hw.h +++ b/drivers/infiniband/hw/ehca/hipz_hw.h @@ -45,6 +45,8 @@ #include "ehca_tools.h" +#define EHCA_MAX_MTU 4 + /* QP Table Entry Memory Map */ struct hipz_qptemm { u64 qpx_hcr; -- cgit From f2c238a0c5e155acd49752c5fb93fb8d8534232b Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Sun, 5 Nov 2006 21:42:20 +0100 Subject: IB/ehca: Activate scaling code by default Change ehca's Kconfig to activates scaling code as default. After several measurements we saw that this feature prevents dropped packets (UD) in stress situation. Thus, enabling it helps to improve ehca's bandwidth through IPoIB. Signed-off-by: Hoang-Nam Nguyen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig index 922389b6439..727b10d8968 100644 --- a/drivers/infiniband/hw/ehca/Kconfig +++ b/drivers/infiniband/hw/ehca/Kconfig @@ -10,6 +10,7 @@ config INFINIBAND_EHCA config INFINIBAND_EHCA_SCALING bool "Scaling support (EXPERIMENTAL)" depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL + default y ---help--- eHCA scaling support schedules the CQ callbacks to different CPUs. -- cgit From 2ffcab6ae44b02679229ca1852526d0a6e062dd2 Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Wed, 8 Nov 2006 14:23:22 -0600 Subject: RDMA/amso1100: Fix unitialized pseudo_netdev accessed in c2_register_device Rework some load-time error handling: c2_register_device() leaked when it failed, and the function that called it didn't check the return code. Signed-off-by: Tom Tucker Signed-off-by: Roland Dreier --- drivers/infiniband/hw/amso1100/c2.c | 3 ++- drivers/infiniband/hw/amso1100/c2_provider.c | 39 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 9e7bd94b958..27fe242ed43 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c @@ -1155,7 +1155,8 @@ static int __devinit c2_probe(struct pci_dev *pcidev, goto bail10; } - c2_register_device(c2dev); + if (c2_register_device(c2dev)) + goto bail10; return 0; diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index da98d9f7142..fef97275291 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -757,20 +757,17 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) int c2_register_device(struct c2_dev *dev) { - int ret; + int ret = -ENOMEM; int i; /* Register pseudo network device */ dev->pseudo_netdev = c2_pseudo_netdev_init(dev); - if (dev->pseudo_netdev) { - ret = register_netdev(dev->pseudo_netdev); - if (ret) { - printk(KERN_ERR PFX - "Unable to register netdev, ret = %d\n", ret); - free_netdev(dev->pseudo_netdev); - return ret; - } - } + if (!dev->pseudo_netdev) + goto out3; + + ret = register_netdev(dev->pseudo_netdev); + if (ret) + goto out2; pr_debug("%s:%u\n", __FUNCTION__, __LINE__); strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); @@ -848,21 +845,25 @@ int c2_register_device(struct c2_dev *dev) ret = ib_register_device(&dev->ibdev); if (ret) - return ret; + goto out1; for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { ret = class_device_create_file(&dev->ibdev.class_dev, c2_class_attributes[i]); - if (ret) { - unregister_netdev(dev->pseudo_netdev); - free_netdev(dev->pseudo_netdev); - ib_unregister_device(&dev->ibdev); - return ret; - } + if (ret) + goto out0; } + goto out3; - pr_debug("%s:%u\n", __FUNCTION__, __LINE__); - return 0; +out0: + ib_unregister_device(&dev->ibdev); +out1: + unregister_netdev(dev->pseudo_netdev); +out2: + free_netdev(dev->pseudo_netdev); +out3: + pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret); + return ret; } void c2_unregister_device(struct c2_dev *dev) -- cgit From b26c791e9ca3365616d40836000285931ca033d0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 9 Nov 2006 21:02:26 +0100 Subject: RDMA/amso1100: Fix && typo Fix the AMSO1100 firmware version computation, which was broken due to "&&" being used where "&" should have. Signed-off-by: Jean Delvare Signed-off-by: Roland Dreier --- drivers/infiniband/hw/amso1100/c2_rnic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 21d9612a56c..623dc95f91d 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -157,8 +157,8 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props) props->fw_ver = ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | - ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) | - (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF); + ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) | + (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF); memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); props->max_mr_size = 0xFFFFFFFF; props->page_size_cap = ~(C2_MIN_PAGESIZE-1); -- cgit From 39798695b4bcc7b145f8910ca56195808d3a7637 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 13 Nov 2006 09:38:07 -0800 Subject: IB/mad: Fix race between cancel and receive completion When ib_cancel_mad() is called, it puts the canceled send on a list and schedules a "flushed" callback from process context. However, this leaves a window where a receive completion could be processed before the send is fully flushed. This is fine, except that ib_find_send_mad() will find the MAD and return it to the receive processing, which results in the sender getting both a successful receive and a "flushed" send completion for the same request. Understandably, this confuses the sender, which is expecting only one of these two callbacks, and leads to grief such as a use-after-free in IPoIB. Fix this by changing ib_find_send_mad() to return a send struct only if the status is still successful (and not "flushed"). The search of the send_list already had this check, so this patch just adds the same check to the search of the wait_list. Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 493f4c65c7a..a72bcea46ff 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, */ (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || rcv_has_same_gid(mad_agent_priv, wr, wc))) - return wr; + return (wr->status == IB_WC_SUCCESS) ? wr : NULL; } /* -- cgit From b71567312976305cc1ce7e9b71e7378c8bfcb40f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 13 Nov 2006 18:05:02 +0100 Subject: [PATCH] ide-cd: only set rq->errors SCSI style for block pc requests We should only set ->errors to CHECK_CONDITION and so on for requests that use this field in the SCSI manner. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- 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 bddfebdf91d..88214943d00 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -724,7 +724,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * if we have an error, pass back CHECK_CONDITION as the * scsi status byte */ - if (!rq->errors) + if (blk_pc_request(rq) && !rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; /* Check for tray open. */ -- cgit From 4dd7406e9c7e7a5422425ef699780463490b8745 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 13 Nov 2006 09:50:11 -0800 Subject: [dvb saa7134] Fix missing 'break' for avermedia card case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 450efcfd2e1d941e302a8c89322fbfcef237be98 broke Avermedia 777 support. Added obvious missing "break" statement. Cc: José Suárez Cc: Michael Krufky Cc: Mauro Carvalho Chehab Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa7134-input.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 7f62403b195..dee83552e68 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -202,6 +202,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) /* Without this we won't receive key up events */ saa_setb(SAA7134_GPIO_GPMODE1, 0x1); saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); + break; case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; -- cgit From b5bf24b94c65536d3cc2bf9039ab05b3967f7b7f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 8 Nov 2006 16:18:26 +0000 Subject: [PATCH] hpt37x: Check the enablebits Helps for PATA but SATA bridged devices lie and always set all the bits so will need the error handling fixes from Tejun. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 7350443948c..fce3fcdc7e7 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.5" +#define DRV_VERSION "0.5.1" struct hpt_clock { u8 xfer_speed; @@ -453,7 +453,13 @@ static int hpt37x_pre_reset(struct ata_port *ap) { u8 scr2, ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - + static const struct pci_bits hpt37x_enable_bits[] = { + { 0x50, 1, 0x04, 0x04 }, + { 0x54, 1, 0x04, 0x04 } + }; + if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) + return -ENOENT; + pci_read_config_byte(pdev, 0x5B, &scr2); pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); /* Cable register now active */ @@ -488,10 +494,17 @@ static void hpt37x_error_handler(struct ata_port *ap) static int hpt374_pre_reset(struct ata_port *ap) { + static const struct pci_bits hpt37x_enable_bits[] = { + { 0x50, 1, 0x04, 0x04 }, + { 0x54, 1, 0x04, 0x04 } + }; u16 mcr3, mcr6; u8 ata66; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); + + if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) + return -ENOENT; + /* Do the extra channel work */ pci_read_config_word(pdev, 0x52, &mcr3); pci_read_config_word(pdev, 0x56, &mcr6); -- cgit From 3f9dd27a22ff79b6b6c4eccd19e4063bff0ddc7e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 10 Nov 2006 22:52:46 +0300 Subject: [PATCH] pata_artop: fix "& (1 >>" typo Signed-off-by: Alexey Dobriyan Signed-off-by: Jeff Garzik --- drivers/ata/pata_artop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 690828eb522..96a098020a8 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -92,7 +92,7 @@ static int artop6260_pre_reset(struct ata_port *ap) return -ENOENT; pci_read_config_byte(pdev, 0x49, &tmp); - if (tmp & (1 >> ap->port_no)) + if (tmp & (1 << ap->port_no)) ap->cbl = ATA_CBL_PATA40; else ap->cbl = ATA_CBL_PATA80; -- cgit From 253b92ecbd3d2e9f5a79fc7632c89ac74bff16c4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 14 Nov 2006 09:55:41 -0500 Subject: libata: fix double-completion on error A curious thing happens, however, when ata_qc_new_init fails to get an ata_queued_cmd: First, ata_qc_new_init handles the failure like this: cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1); done(cmd); Then, we return to ata_scsi_translate and do this: err_mem: cmd->result = (DID_ERROR << 16); done(cmd); It appears to me that first we set a status code indicating that we're ok but the device queue is full and finish the command, but then we blow away that status code and replace it with an error flag and finish the command a second time! That does not seem to be desirable behavior since we merely want the I/O to wait until a command slot frees up, not send errors up the block layer. In the err_mem case, we should simply exit out of ata_scsi_translate instead. Signed-off-by: Darrick J. Wong Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7af2a4ba499..5c1fc467fc7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1612,9 +1612,9 @@ early_finish: err_did: ata_qc_free(qc); -err_mem: cmd->result = (DID_ERROR << 16); done(cmd); +err_mem: DPRINTK("EXIT - internal\n"); return 0; -- cgit From d8f7975159f35846754d3845c9701b612c5c0624 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 14 Nov 2006 02:03:26 -0800 Subject: [PATCH] revert "PCI: quirk for IBM Dock II cardbus controllers" Fix http://bugzilla.kernel.org/show_bug.cgi?id=7264 We need to target this quirk a little more tightly, using the T20 DMI string. Cc: Pavel Kysilka Acked-by: Kristen Carlson Accardi Cc: Greg Kroah-Hartman Cc: Dominik Brodowski Cc: Daniel Ritz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 204b1c8e972..5b448381169 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1460,33 +1460,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); -/* - * Fixup the cardbus bridges on the IBM Dock II docking station - */ -static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev) -{ - u32 val; - - /* - * tie the 2 interrupt pins to INTA, and configure the - * multifunction routing register to handle this. - */ - if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) && - (dev->subsystem_device == 0x0148)) { - printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge " - "applying quirk\n"); - pci_read_config_dword(dev, 0x8c, &val); - val = ((val & 0xffffff00) | 0x1002); - pci_write_config_dword(dev, 0x8c, val); - pci_read_config_dword(dev, 0x80, &val); - val = ((val & 0x00ffff00) | 0x2864c077); - pci_write_config_dword(dev, 0x80, val); - } -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, - quirk_ibm_dock2_cardbus); - static void __devinit quirk_netmos(struct pci_dev *dev) { unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; -- cgit From 6a34b57bec41c95f1e38f700cd9b81324baaffc7 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Tue, 14 Nov 2006 02:03:28 -0800 Subject: [PATCH] drivers/ide: stray bracket Stray bracket in debug code. Signed-off-by: Nicolas Kaiser Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/legacy/hd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index b1d5291531b..45ed03591cd 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -459,7 +459,7 @@ ok_to_read: #ifdef DEBUG printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", req->rq_disk->disk_name, req->sector, req->nr_sectors, - req->buffer+512)); + req->buffer+512); #endif if (req->current_nr_sectors <= 0) end_request(req, 1); -- cgit From d6e89cb6cd3a10eb203914093642f580c20476d4 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 14 Nov 2006 02:03:30 -0800 Subject: [PATCH] nvidiafb: fix unreachable code in nv10GetConfig Fix binary/logical operator typo which leads to unreachable code. Noticed while looking at other issues; I don't have the relevant hardware to test this. Signed-off-by: Nathan Lynch Cc: "Antonino A. Daplas" Acked-by: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nv_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index 61dc46fecf2..eab3e282a4d 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c @@ -262,7 +262,7 @@ static void nv10GetConfig(struct nvidia_par *par) #endif dev = pci_find_slot(0, 1); - if ((par->Chipset && 0xffff) == 0x01a0) { + if ((par->Chipset & 0xffff) == 0x01a0) { int amt = 0; pci_read_config_dword(dev, 0x7c, &amt); -- cgit From a4625085445b86951d8482c0cdd6d52719f7c323 Mon Sep 17 00:00:00 2001 From: Brian King Date: Mon, 13 Nov 2006 16:32:36 -0600 Subject: [PATCH] libata: Convert from module_init to subsys_initcall When building a monolithic kernel, the load order of drivers does not work for SAS libata users, resulting in a kernel oops. Convert libata to use subsys_initcall instead of module_init, which ensures that libata gets loaded before any LLDD. This is the same thing that scsi core does to solve the problem. The load order problem was observed on ipr SAS adapters and should exist for other SAS users as well. Signed-off-by: Brian King Acked-by: Jeff Garzik Signed-off-by: Linus Torvalds --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a8fd0c3e59b..915a55a6cc1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5957,7 +5957,7 @@ static void __exit ata_exit(void) destroy_workqueue(ata_aux_wq); } -module_init(ata_init); +subsys_initcall(ata_init); module_exit(ata_exit); static unsigned long ratelimit_time; -- cgit From b369c2cfa47bc0ad495a95fe9a17c9888781d615 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 14 Nov 2006 12:36:03 +0100 Subject: [PATCH] cciss: fix iostat cciss needs to call disk_stat_add() for iostat to work. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- drivers/block/cciss.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6ffe2b2bdac..4105c3bf347 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1300,6 +1300,12 @@ static void cciss_softirq_done(struct request *rq) complete_buffers(rq->bio, rq->errors); + if (blk_fs_request(rq)) { + const int rw = rq_data_dir(rq); + + disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); + } + #ifdef CCISS_DEBUG printk("Done with %p\n", rq); #endif /* CCISS_DEBUG */ -- cgit From 1f794b6082a5ff88f7c48d1634056026acf806f4 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 14 Nov 2006 12:36:45 +0100 Subject: [PATCH] cpqarray: fix iostat cpqarray needs to call disk_stat_add() for iostat to work. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- drivers/block/cpqarray.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 570d2f04932..d5f519ebbc0 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -998,6 +998,7 @@ static inline void complete_buffers(struct bio *bio, int ok) */ static inline void complete_command(cmdlist_t *cmd, int timeout) { + struct request *rq = cmd->rq; int ok=1; int i, ddir; @@ -1029,12 +1030,18 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, cmd->req.sg[i].size, ddir); - complete_buffers(cmd->rq->bio, ok); + complete_buffers(rq->bio, ok); - add_disk_randomness(cmd->rq->rq_disk); + if (blk_fs_request(rq)) { + const int rw = rq_data_dir(rq); - DBGPX(printk("Done with %p\n", cmd->rq);); - end_that_request_last(cmd->rq, ok ? 1 : -EIO); + disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); + } + + add_disk_randomness(rq->rq_disk); + + DBGPX(printk("Done with %p\n", rq);); + end_that_request_last(rq, ok ? 1 : -EIO); } /* -- cgit From c387fd85f84b9d89a75596325d8d6a0f730baf64 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 15 Nov 2006 00:30:17 +0100 Subject: [PATCH] Char: isicom, fix close bug port is dereferenced even if it is NULL. Dereference it _after_ the check if (!port)... Thanks Eric for reporting this. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=7527 Signed-off-by: Jiri Slaby Signed-off-by: Linus Torvalds --- drivers/char/isicom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index e9e9bf31c36..58c955e390b 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -1062,11 +1062,12 @@ static void isicom_shutdown_port(struct isi_port *port) static void isicom_close(struct tty_struct *tty, struct file *filp) { struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; + struct isi_board *card; unsigned long flags; if (!port) return; + card = port->card; if (isicom_paranoia_check(port, tty->name, "isicom_close")) return; -- cgit From d31e817183a4c1ee2e5fc0635ac075381f5c4419 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 16 Nov 2006 14:00:57 +1100 Subject: [PATCH] powerpc: windfarm shall request it's sub modules The windfarm code, in it's current incarnation, uses request_module() to load the various submodules it needs for a given platform so that only the main platform control module needs to be modprobed. However, it was missing various bits. This fixes it. In the future, we'll use some hotplug mecanisms to try to get all of this auto-loaded on the platforms where it matters but that isn't ready yet. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- drivers/macintosh/windfarm_pm112.c | 11 +++++++++++ drivers/macintosh/windfarm_pm81.c | 1 + drivers/macintosh/windfarm_pm91.c | 1 + 3 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index fa4b13f8936..b3fbb45bc90 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -685,6 +685,17 @@ static int __init wf_pm112_init(void) ++nr_cores; printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); + +#ifdef MODULE + request_module("windfarm_smu_controls"); + request_module("windfarm_smu_sensors"); + request_module("windfarm_smu_sat"); + request_module("windfarm_lm75_sensor"); + request_module("windfarm_max6690_sensor"); + request_module("windfarm_cpufreq_clamp"); + +#endif /* MODULE */ + platform_driver_register(&wf_pm112_driver); return 0; } diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index 2a944851b8e..f24fa734046 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -788,6 +788,7 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); + request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ platform_driver_register(&wf_smu_driver); diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 9961a67b4f8..26eee69ebe6 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -719,6 +719,7 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); + request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ platform_driver_register(&wf_smu_driver); -- cgit From 0ccead1869444891ae6b41f2c5fc8498521c908e Mon Sep 17 00:00:00 2001 From: Gary Zambrano Date: Tue, 14 Nov 2006 16:34:00 -0800 Subject: [TG3]: Increase 5906 firmware poll time. Newer 5906 bootcode needs about 7ms to finish resetting so the poll firmware loop was changed to maximum 20ms. Signed-off-by: Gary Zambrano Signed-off-by: Michael Chan Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/tg3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 06e4f77b098..6e86866bd3f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4728,10 +4728,11 @@ static int tg3_poll_fw(struct tg3 *tp) u32 val; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - for (i = 0; i < 400; i++) { + /* Wait up to 20ms for init done. */ + for (i = 0; i < 200; i++) { if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) return 0; - udelay(10); + udelay(100); } return -ENODEV; } -- cgit From c7835a77c86422d276b0d1a4c70924d933014c13 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 15 Nov 2006 21:14:42 -0800 Subject: [TG3]: Disable TSO on 5906 if CLKREQ is enabled. Due to hardware errata, TSO must be disabled if the PCI Express clock request is enabled on 5906. The chip may hang when transmitting TSO frames if CLKREQ is enabled. Update version to 3.69. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6e86866bd3f..1dbdd6bb587 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.68" -#define DRV_MODULE_RELDATE "November 02, 2006" +#define DRV_MODULE_VERSION "3.69" +#define DRV_MODULE_RELDATE "November 15, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -10366,7 +10366,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u32 pci_state_reg, grc_misc_cfg; u32 val; u16 pci_cmd; - int err; + int err, pcie_cap; /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. @@ -10541,8 +10541,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; - if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) + pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); + if (pcie_cap != 0) { tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u16 lnkctl; + + pci_read_config_word(tp->pdev, + pcie_cap + PCI_EXP_LNKCTL, + &lnkctl); + if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) + tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; + } + } /* If we have an AMD 762 or VIA K8T800 chipset, write * reordering to the mailbox registers done by the host @@ -11809,6 +11820,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { -- cgit From b48f5457b4e9d64d9c1117a4ece247d98b4db49f Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Thu, 16 Nov 2006 01:19:08 -0800 Subject: [PATCH] ipmi: use platform_device_add() instead of platform_device_register() to register device allocated dynamically I got below warning when running 2.6.19-rc5-mm1 on my ia64 machine. WARNING at lib/kobject.c:172 kobject_init() Call Trace: [] show_stack+0x40/0xa0 sp=e0000002ff9f7bc0 bsp=e0000002ff9f0d10 [] dump_stack+0x30/0x60 sp=e0000002ff9f7d90 bsp=e0000002ff9f0cf8 [] kobject_init+0x90/0x160 sp=e0000002ff9f7d90 bsp=e0000002ff9f0cd0 [] device_initialize+0x40/0x1c0 sp=e0000002ff9f7da0 bsp=e0000002ff9f0cb0 [] platform_device_register+0x20/0x60 sp=e0000002ff9f7dd0 bsp=e0000002ff9f0c90 [] try_smi_init+0xbc0/0x11e0 sp=e0000002ff9f7dd0 bsp=e0000002ff9f0c50 [] init_ipmi_si+0xaa0/0x12e0 sp=e0000002ff9f7de0 bsp=e0000002ff9f0bd8 [] init+0x350/0x780 sp=e0000002ff9f7e00 bsp=e0000002ff9f0ba8 [] kernel_thread_helper+0x30/0x60 sp=e0000002ff9f7e30 bsp=e0000002ff9f0b80 [] start_kernel_thread+0x20/0x40 sp=e0000002ff9f7e30 bsp=e0000002ff9f0b80 WARNING at lib/kobject.c:172 kobject_init() Call Trace: [] show_stack+0x40/0xa0 sp=e0000002ff9f7b40 bsp=e0000002ff9f0db0 [] dump_stack+0x30/0x60 sp=e0000002ff9f7d10 bsp=e0000002ff9f0d98 [] kobject_init+0x90/0x160 sp=e0000002ff9f7d10 bsp=e0000002ff9f0d70 [] device_initialize+0x40/0x1c0 sp=e0000002ff9f7d20 bsp=e0000002ff9f0d50 [] platform_device_register+0x20/0x60 sp=e0000002ff9f7d50 bsp=e0000002ff9f0d30 [] ipmi_register_smi+0xcc0/0x18e0 sp=e0000002ff9f7d50 bsp=e0000002ff9f0c90 [] try_smi_init+0xc60/0x11e0 sp=e0000002ff9f7dd0 bsp=e0000002ff9f0c50 [] init_ipmi_si+0xaa0/0x12e0 sp=e0000002ff9f7de0 bsp=e0000002ff9f0bd8 [] init+0x350/0x780 sp=e0000002ff9f7e00 bsp=e0000002ff9f0ba8 [] kernel_thread_helper+0x30/0x60 sp=e0000002ff9f7e30 bsp=e0000002ff9f0b80 [] start_kernel_thread+0x20/0x40 sp=e0000002ff9f7e30 bsp=e0000002ff9f0b80 The root cause is the device struct is initialized twice. If the device is allocated dynamically by platform_device_alloc, platform_device_alloc will initialize struct device, then, platform_device_add should be used to register the device. The difference between platform_device_register and platform_device_add is platform_device_register will initiate the device while platform_device_add won't. Signed-off-by: Zhang Yanmin Cc: Corey Minyard Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index a41b8df2407..c47add8e47d 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2118,7 +2118,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) dev_set_drvdata(&bmc->dev->dev, bmc); kref_init(&bmc->refcount); - rv = platform_device_register(bmc->dev); + rv = platform_device_add(bmc->dev); mutex_unlock(&ipmidriver_mutex); if (rv) { printk(KERN_ERR diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index abc5149e30e..bb1fac104fd 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2346,7 +2346,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->dev = &new_smi->pdev->dev; new_smi->dev->driver = &ipmi_driver; - rv = platform_device_register(new_smi->pdev); + rv = platform_device_add(new_smi->pdev); if (rv) { printk(KERN_ERR "ipmi_si_intf:" -- cgit From 84a763e3d1a47fa9308b8817f265e936e5f1000a Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Thu, 16 Nov 2006 01:19:11 -0800 Subject: [PATCH] pnx4008: rename driver Make the drivers' names less generic to avoid possible confusion in future, as was requested by Russell King. Signed-off-by: Vitaly Wool Acked-by: James Simmons Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pnx4008/pnxrgbfb.c | 2 +- drivers/video/pnx4008/sdum.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c index 7d9453c91a4..bf36b68856d 100644 --- a/drivers/video/pnx4008/pnxrgbfb.c +++ b/drivers/video/pnx4008/pnxrgbfb.c @@ -191,7 +191,7 @@ err: static struct platform_driver rgbfb_driver = { .driver = { - .name = "rgbfb", + .name = "pnx4008-rgbfb", }, .probe = rgbfb_probe, .remove = rgbfb_remove, diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c index 51f0ecc2a51..d23bf0d659b 100644 --- a/drivers/video/pnx4008/sdum.c +++ b/drivers/video/pnx4008/sdum.c @@ -848,7 +848,7 @@ static int sdum_remove(struct platform_device *pdev) static struct platform_driver sdum_driver = { .driver = { - .name = "sdum", + .name = "pnx4008-sdum", }, .probe = sdum_probe, .remove = sdum_remove, -- cgit From 3b9c10dc59eaaef23e5a47110c20fb554f7dba28 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Thu, 16 Nov 2006 01:19:14 -0800 Subject: [PATCH] pnx4008:fix NULL dereference in rgbfb Fix possible NULL dereference in pnxrgbfb. Signed-off-by: Vitaly Wool Cc: James Simmons Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pnx4008/pnxrgbfb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c index bf36b68856d..f29e66e2d77 100644 --- a/drivers/video/pnx4008/pnxrgbfb.c +++ b/drivers/video/pnx4008/pnxrgbfb.c @@ -154,7 +154,8 @@ static int __devinit rgbfb_probe(struct platform_device *pdev) goto err1; } - if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor")) + if (!fb_get_options("pnxrgbfb", &option) && option && + !strcmp(option, "nocursor")) rgbfb_ops.fb_cursor = no_cursor; info->node = -1; -- cgit From 3b46f0396c76a61526dec57a782a061c197ac337 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 16 Nov 2006 01:19:17 -0800 Subject: [PATCH] set default video mode on PowerBook Wallstreet Finally add the third PowerBook Wallstreet 233MHz model to the list of known display resolutions. Without this change, a 640x480 video mode is used. A workaround so far was to boot with 'video=atyfb:vmode:14' Signed-off-by: Olaf Hering Cc: Benjamin Herrenschmidt Cc: "Antonino A. Daplas" Cc: Solomon Peachy Cc: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/atyfb_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index b77b3092392..e815b354c09 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -406,7 +406,7 @@ static struct { { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, - { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 }, { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, -- cgit From e757bef270e21453bf507df200e2fb477c076da6 Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Thu, 16 Nov 2006 01:19:19 -0800 Subject: [PATCH] IB/ipath - fix driver build for platforms with PCI, but not HT The PCI Express and Hypertransport chip-specific source files should only be built when the kernel has the capability of actually compiling them. This fixes the driver build on, for example, ia64. Signed-off-by: Bryan O'Sullivan Cc: "Eric W. Biederman" Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/hw/ipath/Kconfig | 2 +- drivers/infiniband/hw/ipath/Makefile | 5 +++-- drivers/infiniband/hw/ipath/ipath_driver.c | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig index 574a678e7fd..5ca471ac654 100644 --- a/drivers/infiniband/hw/ipath/Kconfig +++ b/drivers/infiniband/hw/ipath/Kconfig @@ -1,6 +1,6 @@ config INFINIBAND_IPATH tristate "QLogic InfiniPath Driver" - depends on PCI_MSI && 64BIT && INFINIBAND + depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND ---help--- This is a driver for QLogic InfiniPath host channel adapters, including InfiniBand verbs support. This driver allows these diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile index 5e29cb0095e..7dc10551cf1 100644 --- a/drivers/infiniband/hw/ipath/Makefile +++ b/drivers/infiniband/hw/ipath/Makefile @@ -10,8 +10,6 @@ ib_ipath-y := \ ipath_eeprom.o \ ipath_file_ops.o \ ipath_fs.o \ - ipath_iba6110.o \ - ipath_iba6120.o \ ipath_init_chip.o \ ipath_intr.o \ ipath_keys.o \ @@ -31,5 +29,8 @@ ib_ipath-y := \ ipath_verbs_mcast.o \ ipath_verbs.o +ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o +ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o + ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 09a13c1fc46..1aeddb48e35 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -390,12 +390,16 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, /* setup the chip-specific functions, as early as possible. */ switch (ent->device) { +#ifdef CONFIG_HT_IRQ case PCI_DEVICE_ID_INFINIPATH_HT: ipath_init_iba6110_funcs(dd); break; +#endif +#ifdef CONFIG_PCI_MSI case PCI_DEVICE_ID_INFINIPATH_PE800: ipath_init_iba6120_funcs(dd); break; +#endif default: ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " "failing\n", ent->device); -- cgit From 4c1b6d18bf2fdeb5ac725126c6928aaa98c8e22f Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Thu, 16 Nov 2006 01:19:21 -0800 Subject: [PATCH] parport: fix compilation failure Fix compilation failure. Signed-off-by: Arnaud Giersch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/parport_ip32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c index e3e19277030..ec44efdbb84 100644 --- a/drivers/parport/parport_ip32.c +++ b/drivers/parport/parport_ip32.c @@ -780,7 +780,7 @@ static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id) enum parport_ip32_irq_mode irq_mode = priv->irq_mode; switch (irq_mode) { case PARPORT_IP32_IRQ_FWD: - parport_generic_irq(irq, p, regs); + parport_generic_irq(irq, p); break; case PARPORT_IP32_IRQ_HERE: parport_ip32_wakeup(p); -- cgit From 6897083abfb0156b533ab8ac42c47f68c550ca9e Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 16 Nov 2006 01:19:25 -0800 Subject: [PATCH] dell_rbu: fix error check platform_device_register_simple() returns error code as pointer when it fails. The return value should be checked by IS_ERR(). Cc: Abhay Salunke Signed-off-by: Akinobu Mita Cc: Matt Domsch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dell_rbu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 08b16179844..fc702e40bd4 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -705,17 +705,16 @@ static struct bin_attribute rbu_packet_size_attr = { static int __init dcdrbu_init(void) { - int rc = 0; + int rc; spin_lock_init(&rbu_data.lock); init_packet_head(); - rbu_device = - platform_device_register_simple("dell_rbu", -1, NULL, 0); - if (!rbu_device) { + rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); + if (IS_ERR(rbu_device)) { printk(KERN_ERR "dell_rbu:%s:platform_device_register_simple " "failed\n", __FUNCTION__); - return -EIO; + return PTR_ERR(rbu_device); } rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); -- cgit From 097b8457dafe7efc22201b4062e2d1e82e494067 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Nov 2006 01:19:31 -0800 Subject: [PATCH] scsi: clear garbage after CDBs on SG_IO ATAPI devices transfer fixed number of bytes for CDBs (12 or 16). Some ATAPI devices choke when shorter CDB is used and the left bytes contain garbage. Block SG_IO cleared left bytes but SCSI SG_IO didn't. This patch makes SCSI SG_IO clear it and simplify CDB clearing in block SG_IO. Signed-off-by: Tejun Heo Cc: Mathieu Fluhr Cc: James Bottomley Cc: Douglas Gilbert Acked-by: Jens Axboe Cc: Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/scsi_lib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d2c02df12fd..3ac4890ce08 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -410,6 +410,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, goto free_req; req->cmd_len = cmd_len; + memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ memcpy(req->cmd, cmd, req->cmd_len); req->sense = sioc->sense; req->sense_len = 0; -- cgit From 073ae841d6a5098f7c6e17fc1f329350d950d1ce Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 16 Nov 2006 10:59:12 +0200 Subject: IPoIB: Clear high octet in QP number IPoIB assumes that high (reserved) octet in the hardware address is 0, and copies it into the QPN. This violates RFC 4391 (which requires that the high 8 bits are ignored on receive), and will result in an invalid QPN being used when interoperating with IPoIB connected mode. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 1eaf00e9862..85522daeb94 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -49,6 +49,8 @@ #include +#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff) + MODULE_AUTHOR("Roland Dreier"); MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); MODULE_LICENSE("Dual BSD/GPL"); @@ -520,8 +522,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, sizeof(union ib_gid)); - ipoib_send(dev, skb, path->ah, - be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha)); } else { neigh->ah = NULL; __skb_queue_tail(&neigh->queue, skb); @@ -599,8 +600,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, ipoib_dbg(priv, "Send unicast ARP to %04x\n", be16_to_cpu(path->pathrec.dlid)); - ipoib_send(dev, skb, path->ah, - be32_to_cpup((__be32 *) phdr->hwaddr)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); } else if ((path->query || !path_rec_start(dev, path)) && skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { /* put pseudoheader back on for next time */ @@ -661,8 +661,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) goto out; } - ipoib_send(dev, skb, neigh->ah, - be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); + ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha)); goto out; } @@ -694,7 +693,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) IPOIB_GID_FMT "\n", skb->dst ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), - be32_to_cpup((__be32 *) phdr->hwaddr), + IPOIB_QPN(phdr->hwaddr), IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); dev_kfree_skb_any(skb); ++priv->stats.tx_dropped; @@ -777,7 +776,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) ipoib_dbg(priv, "neigh_destructor for %06x " IPOIB_GID_FMT "\n", - be32_to_cpup((__be32 *) n->ha), + IPOIB_QPN(n->ha), IPOIB_GID_RAW_ARG(n->ha + 4)); spin_lock_irqsave(&priv->lock, flags); -- cgit From 3da2495c0a92723d58cacaaff48dc60a29ddaae6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 14 Nov 2006 16:28:01 -0500 Subject: OHCI: disallow autostop when wakeup is not available This patch (as822) prevents the OHCI autostop mechanism from kicking in if the root hub is not able or not allowed to issue wakeup requests. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 6f113596af6..da09e7930c1 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -422,7 +422,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ohci->autostop = 0; ohci->next_statechange = jiffies + STATECHANGE_DELAY; - } else if (time_after_eq (jiffies, + } else if (device_may_wakeup(&hcd->self.root_hub->dev) + && time_after_eq(jiffies, ohci->next_statechange) && !ohci->ed_rm_list && !(ohci->hc_control & -- cgit From 40c36092f75ae2026e35feb4f85caa143b64423a Mon Sep 17 00:00:00 2001 From: Kjell Myksvoll Date: Sun, 22 Oct 2006 23:26:42 +0200 Subject: USB: ftdi_sio: adds vendor/product id for a RFID construction kit Adds the vendor and prodcut id for a RFID construction kit from the Elektor Electronics magazine, september 2006. From: Kjell Myksvoll Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bd76b4c11fc..c971d787379 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -511,6 +511,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, + { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f0edb87d2dd..30921f558ee 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -174,10 +174,16 @@ */ #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ +/* + * FTDI USB UART chips used in construction projects from the + * Elektor Electronics magazine (http://elektor-electronics.co.uk) + */ +#define ELEKTOR_VID 0x0C7D +#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ + /* * DSS-20 Sync Station for Sony Ericsson P800 */ - #define FTDI_DSS20_PID 0xFC82 /* -- cgit From fad14a0da885714c8610982045a6d04a4886865e Mon Sep 17 00:00:00 2001 From: Frank Sievertsen Date: Fri, 20 Oct 2006 09:43:53 +0200 Subject: USB: ftdi driver pid for dmx-interfaces Please add a usb pid to the ftdi_sio driver. The pid is used by dmx4all dmx-interfaces (for stage lighting). The interfaces are using the usb-id 0403:c850. I added the id to the driver and it works perfectly. I added a patch for linux 2.6.18.1, too. From: Frank Sievertsen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c971d787379..c186b4e73c7 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -311,6 +311,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 30921f558ee..bae117d359a 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -55,6 +55,9 @@ /* iPlus device */ #define FTDI_IPLUS_PID 0xD070 /* Product Id */ +/* DMX4ALL DMX Interfaces */ +#define FTDI_DMX4ALL 0xC850 + /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -- cgit From 51b5bce8c253b82d4789161cc3b0c74bee313bb1 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Thu, 2 Nov 2006 23:14:10 -0800 Subject: USB: Fix UCR-61S2B unusual_dev entry Recently this entry's bcd scope was narrowed so as not to falsly apply to bcd's other than 0x0110. But while it breaks those of a larger bcd, it is still needed for those of a smaller bcd - so this changes the lower bcd limit to 0x0000. Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index bc1ac07bf6c..e87fb538b74 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1323,8 +1323,10 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. + * Devices with bcd > 110 seem to not need it while those + * with bcd < 110 appear to need it. */ -UNUSUAL_DEV( 0x1019, 0x0c55, 0x0110, 0x0110, +UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, "Desknote", "UCR-61S2B", US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, -- cgit From 583ceada075597a5b6acab1140d61ac81586a2a6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Oct 2006 12:04:22 -0400 Subject: USB: OHCI: fix root-hub resume bug When a suspended OHCI controller sees a port's status change, it sets both the Root-Hub-Status-Change and the Resume-Detect bits in the Interrupt Status register. Processing both these bits, the driver tries to resume the root hub twice! This patch (as807) fixes the bug by ignoring RD if RHSC is set. It also prints a slightly more informative log message when a remote-wakeup event occurs. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 25 +++++++++++++++---------- drivers/usb/host/ohci-hub.c | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9be6b303e78..ea4714e557e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -715,13 +715,6 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) return IRQ_NOTMINE; } - if (ints & OHCI_INTR_RHSC) { - ohci_vdbg (ohci, "rhsc\n"); - ohci->next_statechange = jiffies + STATECHANGE_DELAY; - ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); - usb_hcd_poll_rh_status(hcd); - } - if (ints & OHCI_INTR_UE) { disable (ohci); ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); @@ -731,9 +724,21 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) ohci_usb_reset (ohci); } - if (ints & OHCI_INTR_RD) { - ohci_vdbg (ohci, "resume detect\n"); - ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); + if (ints & OHCI_INTR_RHSC) { + ohci_vdbg(ohci, "rhsc\n"); + ohci->next_statechange = jiffies + STATECHANGE_DELAY; + ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, + ®s->intrstatus); + usb_hcd_poll_rh_status(hcd); + } + + /* For connect and disconnect events, we expect the controller + * to turn on RHSC along with RD. But for remote wakeup events + * this might not happen. + */ + else if (ints & OHCI_INTR_RD) { + ohci_vdbg(ohci, "resume detect\n"); + ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus); hcd->poll_rh = 1; if (ohci->autostop) { spin_lock (&ohci->lock); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index da09e7930c1..6995ea36f2e 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -169,7 +169,8 @@ __acquires(ohci->lock) break; case OHCI_USB_RESUME: /* HCFS changes sometime after INTR_RD */ - ohci_info (ohci, "wakeup\n"); + ohci_info(ohci, "%swakeup\n", + autostopped ? "auto-" : ""); break; case OHCI_USB_OPER: /* this can happen after resuming a swsusp snapshot */ -- cgit From bb7eef6eea53633a8a49f014fd27c08f7d5fda1a Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 8 Nov 2006 19:58:07 -0800 Subject: USB: correct keymapping on Powerbook built-in USB ISO keyboards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit similar to the version in adbhid_input_register(): The '<>' key and the '^°' key on a german keyboard is swapped. Provide correct keys to userland, external USB keyboards will not work correctly when the 'badmap'/'goodmap' workarounds from xkeyboard-config are used. It is expected that distributions drop the badmap/goodmap part from keycodes/macintosh in the xkeyboard-config package. This is probably 2.6.18.x material, if major distros settle on 2.6.18. Signed-off-by: Olaf Hering Cc: Dmitry Torokhov Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 4 ++-- drivers/usb/input/hid-input.c | 17 +++++++++++++++++ drivers/usb/input/hid.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 6daf85c6eee..8fde85c4905 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1797,10 +1797,10 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9a808a3b4d3..68e7ebb978a 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -121,6 +121,12 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { { } }; +static struct hidinput_key_translation powerbook_iso_keyboard[] = { + { KEY_GRAVE, KEY_102ND }, + { KEY_102ND, KEY_GRAVE }, + { } +}; + static int usbhid_pb_fnmode = 1; module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); MODULE_PARM_DESC(pb_fnmode, @@ -195,6 +201,14 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, } } + if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { + trans = find_translation(powerbook_iso_keyboard, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + return 0; } @@ -210,6 +224,9 @@ static void hidinput_pb_setup(struct input_dev *input) for (trans = powerbook_numlock_keys; trans->from; trans++) set_bit(trans->to, input->keybit); + + for (trans = powerbook_iso_keyboard; trans->from; trans++) + set_bit(trans->to, input->keybit); } #else static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 9b50effef75..0e76e6dcac3 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -260,6 +260,7 @@ struct hid_item { #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 #define HID_QUIRK_INVERT_HWHEEL 0x00004000 +#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 /* * This is the global environment of the parser. This information is -- cgit From a3878f11ed29c50b7da1336adcac089e9c741fc2 Mon Sep 17 00:00:00 2001 From: Jan Mate Date: Wed, 8 Nov 2006 19:58:04 -0800 Subject: USB Storage: unusual_devs.h entry for Sony Ericsson P990i USB Storage: this patch adds support for Sony Ericsson P990i Signed-off-by: Jan Mate Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index e87fb538b74..cc701e88d38 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1320,6 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Jan Mate */ +UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, + "Sony Ericsson", + "P990i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. -- cgit From a7dc4eeac8f18de5fc6bea1a0f46e67f42b83509 Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Sun, 12 Nov 2006 11:22:42 +0100 Subject: USB: hid-core: Add quirk for new Apple keyboard/trackpad The new Core2 Duo MacBook Pro have a new keyboard+trackpad device. The following patch adds the needed HID quirk for the Fn key. Signed-off-by: Julien BLACHE Signed-off-by: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 8fde85c4905..6d08a3bcc95 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1802,6 +1802,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x021B, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, -- cgit From 70708f2c2a3c164e9aa80345919a22c838b3b314 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Mon, 6 Nov 2006 16:33:07 +0300 Subject: usb-storage: Remove duplicated unusual_devs.h entries for Sony Ericsson P990i For some reason the unusual_devs.h entry for Sony Ericsson P990i had three identical copies in a wrong place in the file in addition to the correct entry. Signed-off-by: Sergey Vlasov Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index cc701e88d38..efb047f431e 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1306,27 +1306,6 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), -/* Reported by Jan Mate */ -UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, - "Sony Ericsson", - "P990i", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Reported by Jan Mate */ -UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, - "Sony Ericsson", - "P990i", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Reported by Jan Mate */ -UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, - "Sony Ericsson", - "P990i", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. -- cgit From 6ab16a9029b0b26c23a4806d90ca76be6d6beae3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 7 Nov 2006 10:16:25 +0100 Subject: USB: Fixed outdated usb_get_device_descriptor() documentation usb_get_device_descriptor() used to convert several descriptor fields to host CPU's byte order. Now that it doesn't convert them anymore, update the documentation to reflect this. Signed-off-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fccd1952bad..7729c074488 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -828,10 +828,7 @@ char *usb_cache_string(struct usb_device *udev, int index) * Context: !in_interrupt () * * Updates the copy of the device descriptor stored in the device structure, - * which dedicates space for this purpose. Note that several fields are - * converted to the host CPU's byte order: the USB version (bcdUSB), and - * vendors product and version fields (idVendor, idProduct, and bcdDevice). - * That lets device drivers compare against non-byteswapped constants. + * which dedicates space for this purpose. * * Not exported, only for use by the core. If drivers really want to read * the device descriptor directly, they can call usb_get_descriptor() with -- cgit From 0029908ba9661ef26f7020309966aae23c2027b8 Mon Sep 17 00:00:00 2001 From: Alex Sanks Date: Sun, 29 Oct 2006 16:38:31 -0800 Subject: USB: ipaq: Add HTC Modem Support Adds support for HTC Smart Phones in modem mode (as opposed to sync mode). Loads and works with pppd on my T-Mobile SDA. Signed-off-by: Alex Sanks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 6238aff1e77..d72cf8bc7f7 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -320,6 +320,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ + { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */ { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */ -- cgit From 5a3fcf5c7f035de8e2b28d144d67b7bebac8a723 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Tue, 7 Nov 2006 00:31:51 +0100 Subject: USB: auerswald possible memleak fix fix possible memory leak in auerbuf_setup(). Regards, Mariusz Kozlowski Signed-off-by: Mariusz Kozlowski Signed-off-by: Wolfgang Muees Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/auerswald.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 0be9d62d62a..e4971d6aaaf 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -780,7 +780,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned bl_fail:/* not enough memory. Free allocated elements */ dbg ("auerbuf_setup: no more memory"); - kfree(bep); + auerbuf_free(bep); auerbuf_free_buffers (bcp); return -ENOMEM; } -- cgit From e45413eb708c1cf21082764457692c8eeac0ca97 Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Thu, 5 Oct 2006 14:26:02 +0400 Subject: W1: ioremap balanced with iounmap ioremap must be balanced with iounmap in error path. Please consider for 2.6.19. Signed-off-by: Amol Lad Signed-off-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/matrox_w1.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 2788b8ca9bb..6f9d880ab2e 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -215,6 +215,8 @@ static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_devi return 0; err_out_free_device: + if (dev->virt_addr) + iounmap(dev->virt_addr); kfree(dev); return err; -- cgit From d355c3c23ce56ab83e41f2bfb30d02fb90618530 Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Mon, 13 Nov 2006 09:15:20 +0100 Subject: aoe: Add forgotten NULL at end of attribute list in aoeblk.c This caused the system to stall when the aoe module was loaded. The error was introduced in commit 4ca5224f3ea4779054d96e885ca9b3980801ce13 Signed-off-by: Dennis Stosberg Signed-off-by: Greg Kroah-Hartman --- drivers/block/aoe/aoeblk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index d433f27e0ce..aa25f8b09fe 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -68,6 +68,7 @@ static struct attribute *aoe_attrs[] = { &disk_attr_mac.attr, &disk_attr_netif.attr, &disk_attr_fwver.attr, + NULL }; static const struct attribute_group attr_group = { -- cgit From 4f71c5de19c27f2198105d3b26b398494d5c353b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 17 Nov 2006 15:35:00 +1100 Subject: [PATCH] Fix radeon DDC regression When radeonfb was changed to use the new "generic" ddc, a bit of code initializing the GPIO lines was lost, causing it to not work if the firmware didn't configure them properly, which seems to happen on some cards. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- drivers/video/aty/radeon_i2c.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 67675452009..869725a13c2 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -139,7 +139,13 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid) { - u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); + u32 reg = rinfo->i2c[conn-1].ddc_reg; + u8 *edid; + + OUTREG(reg, INREG(reg) & + ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); + + edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); if (out_edid) *out_edid = edid; -- cgit From 4be703906cffd5902028d20626e636ba21fb0b61 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 16 Nov 2006 22:18:28 -0800 Subject: Fix generic fb_ddc i2c edid probe msg Benh points out that the msgs[0].flags entry never got initialized, and since it's an automatic stack allocation, it could have any random value, which is bad. Rewrite the initializer to explicitly initialize all fields of the small i2c_msg structure array we generate. Just to keep it all obvious, let's handle msgs[1].buf in the same initializer while we're at it, instead of initializing that one separately later. Signed-off-by: Linus Torvalds --- drivers/video/fb_ddc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c index 3aa6ebf68f1..f836137a0ed 100644 --- a/drivers/video/fb_ddc.c +++ b/drivers/video/fb_ddc.c @@ -20,26 +20,26 @@ static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) { unsigned char start = 0x0; + unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); struct i2c_msg msgs[] = { { .addr = DDC_ADDR, + .flags = 0, .len = 1, .buf = &start, }, { .addr = DDC_ADDR, .flags = I2C_M_RD, .len = EDID_LENGTH, + .buf = buf, } }; - unsigned char *buf; - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); if (!buf) { dev_warn(&adapter->dev, "unable to allocate memory for EDID " "block.\n"); return NULL; } - msgs[1].buf = buf; if (i2c_transfer(adapter, msgs, 2) == 2) return buf; -- cgit From 1d08811d0c05cd54a778f45588ec22eee027ff89 Mon Sep 17 00:00:00 2001 From: Jan-Benedict Glaw Date: Fri, 17 Nov 2006 10:32:04 +0100 Subject: lkkbd: Remove my old snail-mail address I moved to a different town and my old snail-mail address is invalid now. Also, there's no need at all to have any address like that in the sources, so remove it completely. Signed-off-by: Jan-Benedict Glaw --- drivers/input/keyboard/lkkbd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 708d5a1bc3d..979b93e33da 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -59,11 +59,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can do so either by - * email or by paper mail: - * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.), - * Germany. */ #include -- cgit From b976fe19acc565e5137e6f12af7b6633a23e6b7c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Nov 2006 19:31:09 -0800 Subject: Revert "ACPI: created a dedicated workqueue for notify() execution" This reverts commit 37605a6900f6b4d886d995751fcfeef88c4e462c. Again. This same bug has now been introduced twice: it was done earlier by commit b8d35192c55fb055792ff0641408eaaec7c88988, only to be reverted last time in commit 72945b2b90a5554975b8f72673ab7139d232a121. We must NOT try to queue up notify handlers to another thread than the normal ACPI execution thread, because the notifications on some systems seem to just keep on accumulating until we run out of memory and/or threads. Keeping events within the one deferred execution thread automatically throttles the events properly. At least the Compaq N620c will lock up completely on the first thermal event without this patch reverted. Cc: David Brownell Cc: Len Brown Cc: Alexey Starikovskiy Signed-off-by: Linus Torvalds --- drivers/acpi/osl.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index c84286cbbe2..068fe4f100b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -73,7 +73,6 @@ static unsigned int acpi_irq_irq; static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; -static struct workqueue_struct *kacpi_notify_wq; acpi_status acpi_os_initialize(void) { @@ -92,9 +91,8 @@ acpi_status acpi_os_initialize1(void) return AE_NULL_ENTRY; } kacpid_wq = create_singlethread_workqueue("kacpid"); - kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); BUG_ON(!kacpid_wq); - BUG_ON(!kacpi_notify_wq); + return AE_OK; } @@ -106,7 +104,6 @@ acpi_status acpi_os_terminate(void) } destroy_workqueue(kacpid_wq); - destroy_workqueue(kacpi_notify_wq); return AE_OK; } @@ -569,7 +566,10 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ static void acpi_os_execute_deferred(void *context) { - struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context; + struct acpi_os_dpc *dpc = NULL; + + + dpc = (struct acpi_os_dpc *)context; if (!dpc) { printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); return; @@ -604,12 +604,14 @@ acpi_status acpi_os_execute(acpi_execute_type type, struct acpi_os_dpc *dpc; struct work_struct *task; + ACPI_FUNCTION_TRACE("os_queue_for_execution"); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); if (!function) - return AE_BAD_PARAMETER; + return_ACPI_STATUS(AE_BAD_PARAMETER); /* * Allocate/initialize DPC structure. Note that this memory will be @@ -622,20 +624,26 @@ acpi_status acpi_os_execute(acpi_execute_type type, * from the same memory. */ - dpc = kmalloc(sizeof(struct acpi_os_dpc) + - sizeof(struct work_struct), GFP_ATOMIC); + dpc = + kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), + GFP_ATOMIC); if (!dpc) - return AE_NO_MEMORY; + return_ACPI_STATUS(AE_NO_MEMORY); + dpc->function = function; dpc->context = context; + task = (void *)(dpc + 1); INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); - if (!queue_work((type == OSL_NOTIFY_HANDLER)? - kacpi_notify_wq : kacpid_wq, task)) { - status = AE_ERROR; + + if (!queue_work(kacpid_wq, task)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Call to queue_work() failed.\n")); kfree(dpc); + status = AE_ERROR; } - return status; + + return_ACPI_STATUS(status); } EXPORT_SYMBOL(acpi_os_execute); -- cgit From dfbc9e9d33adb1ac9910dd7f8ceb911947039a52 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Sat, 18 Nov 2006 22:19:34 -0800 Subject: [PATCH] pcmcia: fix 'rmmod pcmcia' with unbound devices Having unbound PCMCIA devices: doing a 'find /sys' after a 'rmmod pcmcia' gives an oops because the pcmcia_device is not unregisterd from the driver core. fixes bugzilla #7481 Signed-off-by: Daniel Ritz Dominik Brodowski Cc: Pavol Gono Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pcmcia/ds.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0f701921c13..a20d84d707d 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1271,6 +1271,9 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev, socket->pcmcia_state.dead = 1; pccard_register_pcmcia(socket, NULL); + /* unregister any unbound devices */ + pcmcia_card_remove(socket, NULL); + pcmcia_put_socket(socket); return; -- cgit From a6cd2d94e1072a5756b5e5ab647d3223cba7e555 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 18 Nov 2006 22:19:36 -0800 Subject: [PATCH] i2c-ixp4xx: fix ") != 0))" typo i2c_bit_add_bus() returns -E; -E != 0 => err = 1 probe fails with positive error code Signed-off-by: Alexey Dobriyan Cc: Deepak Saxena Acked-by: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/i2c/busses/i2c-ixp4xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 1ce01fb0ac0..05fffb9415a 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -137,7 +137,8 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) gpio_line_set(gpio->scl_pin, 0); gpio_line_set(gpio->sda_pin, 0); - if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { + err = i2c_bit_add_bus(&drv_data->adapter); + if (err != 0) printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); kfree(drv_data); -- cgit From ffb3d1348605816de10d4e57281e02f606508b6c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 18 Nov 2006 22:19:39 -0800 Subject: [PATCH] scx200_acb: handle PCI errors Signed-off-by: Jeff Garzik Signed-off-by: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/i2c/busses/scx200_acb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 32aab0d34ee..714bae78095 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -494,11 +494,12 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, iface->pdev = pdev; iface->bar = bar; - pci_enable_device_bars(iface->pdev, 1 << iface->bar); + rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); + if (rc) + goto errout_free; rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); - - if (rc != 0) { + if (rc) { printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", iface->bar); goto errout_free; -- cgit From f0c69c4ee796a2d2277c3a000e24f29a25a00060 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 18 Nov 2006 22:19:41 -0800 Subject: [PATCH] ftape: fix printk format warnings Fix printk format warnings: drivers/char/ftape/zftape/zftape-buffers.c:87: warning: format '%d' expects type 'int', but argument 3 has type 'size_t' drivers/char/ftape/zftape/zftape-buffers.c:104: warning: format '%d' expects type 'int', but argument 3 has type 'size_t' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ftape/zftape/zftape-buffers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c index da06f138334..7ebce2ec789 100644 --- a/drivers/char/ftape/zftape/zftape-buffers.c +++ b/drivers/char/ftape/zftape/zftape-buffers.c @@ -85,7 +85,7 @@ int zft_vmalloc_once(void *new, size_t size) peak_memory = used_memory; } TRACE_ABORT(0, ft_t_noise, - "allocated buffer @ %p, %d bytes", *(void **)new, size); + "allocated buffer @ %p, %zd bytes", *(void **)new, size); } int zft_vmalloc_always(void *new, size_t size) { @@ -101,7 +101,7 @@ void zft_vfree(void *old, size_t size) if (*(void **)old) { vfree(*(void **)old); used_memory -= size; - TRACE(ft_t_noise, "released buffer @ %p, %d bytes", + TRACE(ft_t_noise, "released buffer @ %p, %zd bytes", *(void **)old, size); *(void **)old = NULL; } -- cgit From 49a1cd00b599d12c3f397e5a32f81f6e2aab0d74 Mon Sep 17 00:00:00 2001 From: Toralf Foerster Date: Sat, 18 Nov 2006 22:19:41 -0800 Subject: [PATCH] fix build error for HISAX_NETJET Fix a build error for the enter:now PCI card. Signed-off-by: Toralf Foerster Acked-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index eb57a988e04..cfd2718a490 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -344,7 +344,7 @@ config HISAX_HFC_SX config HISAX_ENTERNOW_PCI bool "Formula-n enter:now PCI card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the Formula-n enter:now PCI ISDN card. -- cgit From b3438f8266cb1f5010085ac47d7ad6a36a212164 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 20 Nov 2006 11:47:18 -0800 Subject: Add "pure_initcall" for static variable initialization This is a quick hack to overcome the fact that SRCU currently does not allow static initializers, and we need to sometimes initialize those things before any other initializers (even "core" ones) can do so. Currently we don't allow this at all for modules, and the only user that needs is right now is cpufreq. As reported by Thomas Gleixner: "Commit b4dfdbb3c707474a2254c5b4d7e62be31a4b7da9 ("[PATCH] cpufreq: make the transition_notifier chain use SRCU breaks cpu frequency notification users, which register the callback > on core_init level." Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Arjan van de Ven Cc: Andrew Morton , Signed-off-by: Linus Torvalds --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 86e69b7f912..dd0c2623e27 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -59,7 +59,7 @@ static int __init init_cpufreq_transition_notifier_list(void) srcu_init_notifier_head(&cpufreq_transition_notifier_list); return 0; } -core_initcall(init_cpufreq_transition_notifier_list); +pure_initcall(init_cpufreq_transition_notifier_list); static LIST_HEAD(cpufreq_governor_list); static DEFINE_MUTEX (cpufreq_governor_mutex); -- cgit From 3f5a6ca31c334011fd929501a078424c0d3f71be Mon Sep 17 00:00:00 2001 From: Bryan O'Sullivan Date: Mon, 20 Nov 2006 10:54:34 -0800 Subject: IB/ipath: Depend on CONFIG_NET ipath uses skb functions and won't build without CONFIG_NET. Spotted by Randy Dunlap. Signed-off-by: Bryan O'Sullivan Acked-by: Randy Dunlap Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ipath/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig index 5ca471ac654..90c14543677 100644 --- a/drivers/infiniband/hw/ipath/Kconfig +++ b/drivers/infiniband/hw/ipath/Kconfig @@ -1,6 +1,6 @@ config INFINIBAND_IPATH tristate "QLogic InfiniPath Driver" - depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND + depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND && NET ---help--- This is a driver for QLogic InfiniPath host channel adapters, including InfiniBand verbs support. This driver allows these -- cgit From 6af6e1efb161ffe36e718b1fd58385710879af7c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 21 Nov 2006 16:58:59 -0500 Subject: [PATCH] Fix CPU_FREQ_GOV_ONDEMAND=y compile error The ONDEMAND governor needs FREQ_TABLE Signed-off-by: Mattia Dongili Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- drivers/cpufreq/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 2cc71b66231..491779af8d5 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -107,6 +107,7 @@ config CPU_FREQ_GOV_USERSPACE config CPU_FREQ_GOV_ONDEMAND tristate "'ondemand' cpufreq policy governor" + select CPU_FREQ_TABLE help 'ondemand' - This driver adds a dynamic cpufreq policy governor. The governor does a periodic polling and -- cgit From 12862086f24d7382b24379bbcbe0dadf12ca5945 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Tue, 21 Nov 2006 17:44:31 -0800 Subject: [TG3]: Add missing unlock in tg3_open() error path. Sparse noticed a locking imbalance in tg3_open(). This patch adds an unlock to one of the error paths, so that tg3_open() always exits without the lock held. Signed-off-by: Ira W. Snyder Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1dbdd6bb587..c20bb998e0e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6979,8 +6979,10 @@ static int tg3_open(struct net_device *dev) tg3_full_lock(tp, 0); err = tg3_set_power_state(tp, PCI_D0); - if (err) + if (err) { + tg3_full_unlock(tp); return err; + } tg3_disable_ints(tp); tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; -- cgit From 7d915a38985d2826acbdc9dc9cca8a93e23e5278 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 22 Nov 2006 09:37:54 -0800 Subject: [AGP] Fix intel 965 AGP memory mapping function This introduces a i965-specific "mask_memory()" function that knows about the extended physical addresses that the i965 supports. This allows us to correctly map in physical memory in the >4GB range into the GTT. Also simplify/clean-up the i965 case for the aperture sizing by just returning the fixed 512kB size from "fetch_size()". We don't really care that not all of the aperture may be visible - the only thing that cares about the aperture size is the Intel "stolen memory" calculation, which depends on the fixed size. Cc: Keith Packard Cc: Eric Anholt Cc: Dave Jones Signed-off-by: Linus Torvalds --- drivers/char/agp/intel-agp.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index d1ede7db5a1..aceece71a85 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -387,11 +387,7 @@ static void intel_i830_init_gtt_entries(void) /* We obtain the size of the GTT, which is also stored (for some * reason) at the top of stolen memory. Then we add 4KB to that * for the video BIOS popup, which is also stored in there. */ - - if (IS_I965) - size = 512 + 4; - else - size = agp_bridge->driver->fetch_size() + 4; + size = agp_bridge->driver->fetch_size() + 4; if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { @@ -805,6 +801,26 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) return 0; } + +/* + * The i965 supports 36-bit physical addresses, but to keep + * the format of the GTT the same, the bits that don't fit + * in a 32-bit word are shifted down to bits 4..7. + * + * Gcc is smart enough to notice that "(addr >> 28) & 0xf0" + * is always zero on 32-bit architectures, so no need to make + * this conditional. + */ +static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, + unsigned long addr, int type) +{ + /* Shift high bits down */ + addr |= (addr >> 28) & 0xf0; + + /* Type checking must be done elsewhere */ + return addr | bridge->driver->masks[type].mask; +} + static int intel_i965_fetch_size(void) { struct aper_size_info_fixed *values; @@ -832,7 +848,8 @@ static int intel_i965_fetch_size(void) agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset); - return values[offset].size; + /* The i965 GTT is always sized as if it had a 512kB aperture size */ + return 512; } /* The intel i965 automatically initializes the agp aperture during POST. @@ -1584,7 +1601,7 @@ static struct agp_bridge_driver intel_i965_driver = { .fetch_size = intel_i965_fetch_size, .cleanup = intel_i915_cleanup, .tlb_flush = intel_i810_tlbflush, - .mask_memory = intel_i810_mask_memory, + .mask_memory = intel_i965_mask_memory, .masks = intel_i810_masks, .agp_enable = intel_i810_agp_enable, .cache_flush = global_cache_flush, -- cgit From 66c669baa7d70b8d135da67f36c8dba12cea71b8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 22 Nov 2006 14:55:29 -0800 Subject: [AGP] Allocate AGP pages with GFP_DMA32 by default Not all graphic page remappers support physical addresses over the 4GB mark for remapping, so while some do (the AMD64 GART always did, and I just fixed the i965 to do so properly), we're safest off just forcing GFP_DMA32 allocations to make sure graphics pages get allocated in the low 32-bit address space by default. AGP sub-drivers that really care, and can do better, could just choose to implement their own allocator (or we could add another "64-bit safe" default allocator for their use), but quite frankly, you're not likely to care in practice. So for now, this trivial change means that we won't be allocating pages that we can't map correctly by mistake on x86-64. [ On traditional 32-bit x86, this could never happen, because GFP_KERNEL would never allocate any highmem memory anyway ] Acked-by: Andi Kleen Acked-by: Dave Jones Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Linus Torvalds --- drivers/char/agp/generic.c | 2 +- drivers/char/agp/intel-agp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c3920016168..5ff457b41ef 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -1054,7 +1054,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) { struct page * page; - page = alloc_page(GFP_KERNEL); + page = alloc_page(GFP_KERNEL | GFP_DMA32); if (page == NULL) return NULL; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index aceece71a85..555b3a8ab49 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -169,7 +169,7 @@ static void *i8xx_alloc_pages(void) { struct page * page; - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); if (page == NULL) return NULL; -- cgit From 0916bd3ebb7cefdd0f432e8491abe24f4b5a101e Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 22 Nov 2006 20:42:01 -0500 Subject: [PATCH] Correct bound checking from the value returned from _PPC method. processor_perflib.c::acpi_processor_ppc_notifier() check if the value returned by the processor's _PPC method is 0 and return failed if so. This is wrong since 0 indicate that the bios think the processor can go to the highest frequency. This patch for example fix the HP NX 6125 to allow its highest frequency to be available. Signed-off-by: Bruno Ducrot Cc: "Pallipadi, Venkatesh" Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- drivers/acpi/processor_perflib.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 7ba5e49ab30..6fd174a3714 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -83,10 +83,8 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, goto out; ppc = (unsigned int)pr->performance_platform_limit; - if (!ppc) - goto out; - if (ppc > pr->performance->state_count) + if (ppc >= pr->performance->state_count) goto out; cpufreq_verify_within_limits(policy, 0, -- cgit From 0b1082efb92eedb28e982cfae526267ebdcf5622 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 23 Nov 2006 13:28:50 +0100 Subject: [PATCH] Fix i2c-ixp4xx compile (missing brace) Fix recent i2c-ixp4xx compilation breakage. Sorry for overlooking it. Signed-off-by: Jean Delvare Signed-off-by: Linus Torvalds --- drivers/i2c/busses/i2c-ixp4xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 05fffb9415a..68fe863f9d5 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -138,7 +138,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) gpio_line_set(gpio->sda_pin, 0); err = i2c_bit_add_bus(&drv_data->adapter); - if (err != 0) + if (err) { printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); kfree(drv_data); -- cgit From 8e4d9dcb4205dd43c4297168022ed0c6874fb918 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Sat, 25 Nov 2006 11:09:17 -0800 Subject: [PATCH] fix "pcmcia: fix 'rmmod pcmcia' with unbound devices" Add required locking to dfbc9e9d33adb1ac9910dd7f8ceb911947039a52 Signed-off-by: Daniel Ritz Cc: Dominik Brodowski Cc: Pavol Gono Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pcmcia/ds.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index a20d84d707d..21d83a895b2 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1272,7 +1272,9 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev, pccard_register_pcmcia(socket, NULL); /* unregister any unbound devices */ + mutex_lock(&socket->skt_mutex); pcmcia_card_remove(socket, NULL); + mutex_unlock(&socket->skt_mutex); pcmcia_put_socket(socket); -- cgit From 2601a46474db2dcbc08ee690e56f08a10abe65cb Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 25 Nov 2006 11:09:27 -0800 Subject: [PATCH] rtc framework handles periodic irqs The RTC framework has an irq_set_freq() method that should be used to manage the periodic IRQ frequency, but the current ioctl logic doesn't know how to do that. This patch teaches it how. This means that drivers implementing irq_set_freq() will automatically support RTC_IRQP_{READ,SET} ioctls; that logic doesn't need duplication within the driver. [akpm@osdl.org: export rtc_irq_set_freq] Signed-off-by: David Brownell Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/interface.c | 1 + drivers/rtc/rtc-dev.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 579cd667b16..4783ec68fb3 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -265,3 +265,4 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int } return err; } +EXPORT_SYMBOL_GPL(rtc_irq_set_freq); diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 583789c66cd..3109865e8d7 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -214,7 +214,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, struct rtc_wkalrm alarm; void __user *uarg = (void __user *) arg; - /* check that the calles has appropriate permissions + /* check that the calling task has appropriate permissions * for certain ioctls. doing this check here is useful * to avoid duplicate code in each driver. */ @@ -299,6 +299,17 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, err = rtc_set_time(class_dev, &tm); break; + + case RTC_IRQP_READ: + if (ops->irq_set_freq) + err = put_user(rtc->irq_freq, (unsigned long *) arg); + break; + + case RTC_IRQP_SET: + if (ops->irq_set_freq) + err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg); + break; + #if 0 case RTC_EPOCH_SET: #ifndef rtc_epoch -- cgit From d728b1e69fd5829ec2ab2434381e5a268d4f684a Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 25 Nov 2006 11:09:28 -0800 Subject: [PATCH] rtc class locking bugfixes I got a lockdep warning when running "rtctest" so I though it'd be good to see what was up. - The warning was for rtc->irq_task_lock, gotten from rtc_update_irq() by irq handlerss ... but in a handful of other cases, grabbed without blocking IRQs. - Some callers to rtc_update_irq() were not ensuring IRQs were blocked, yet the routine expects that; make sure all callers block IRQs. It would appear that RTC API tests haven't been part of anyone's kernel regression test suite recently, at least not with lockdep running. Signed-off-by: David Brownell Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/interface.c | 15 +++++++++++---- drivers/rtc/rtc-at91.c | 3 ++- drivers/rtc/rtc-dev.c | 12 +++++++----- drivers/rtc/rtc-ds1553.c | 3 ++- drivers/rtc/rtc-test.c | 2 ++ 5 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 4783ec68fb3..6f11f6dfdd9 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -145,6 +145,13 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) } EXPORT_SYMBOL_GPL(rtc_set_alarm); +/** + * rtc_update_irq - report RTC periodic, alarm, and/or update irqs + * @class_dev: the rtc's class device + * @num: how many irqs are being reported (usually one) + * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF + * Context: in_interrupt(), irqs blocked + */ void rtc_update_irq(struct class_device *class_dev, unsigned long num, unsigned long events) { @@ -201,12 +208,12 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) if (task == NULL || task->func == NULL) return -EINVAL; - spin_lock(&rtc->irq_task_lock); + spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task == NULL) { rtc->irq_task = task; retval = 0; } - spin_unlock(&rtc->irq_task_lock); + spin_unlock_irq(&rtc->irq_task_lock); return retval; } @@ -216,10 +223,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) { struct rtc_device *rtc = to_rtc_device(class_dev); - spin_lock(&rtc->irq_task_lock); + spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task == task) rtc->irq_task = NULL; - spin_unlock(&rtc->irq_task_lock); + spin_unlock_irq(&rtc->irq_task_lock); } EXPORT_SYMBOL_GPL(rtc_irq_unregister); diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c index bd61e99540a..5c8addcaf1f 100644 --- a/drivers/rtc/rtc-at91.c +++ b/drivers/rtc/rtc-at91.c @@ -292,7 +292,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) AT91_RTC_CALEV); ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, - IRQF_SHARED, "at91_rtc", pdev); + IRQF_DISABLED | IRQF_SHARED, + "at91_rtc", pdev); if (ret) { printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", AT91_ID_SYS); diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 3109865e8d7..814b9e1873f 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -61,7 +61,9 @@ static void rtc_uie_task(void *data) int err; err = rtc_read_time(&rtc->class_dev, &tm); - spin_lock_irq(&rtc->irq_lock); + + local_irq_disable(); + spin_lock(&rtc->irq_lock); if (rtc->stop_uie_polling || err) { rtc->uie_task_active = 0; } else if (rtc->oldsecs != tm.tm_sec) { @@ -74,11 +76,11 @@ static void rtc_uie_task(void *data) } else if (schedule_work(&rtc->uie_task) == 0) { rtc->uie_task_active = 0; } - spin_unlock_irq(&rtc->irq_lock); + spin_unlock(&rtc->irq_lock); if (num) rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); + local_irq_enable(); } - static void rtc_uie_timer(unsigned long data) { struct rtc_device *rtc = (struct rtc_device *)data; @@ -238,10 +240,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, /* avoid conflicting IRQ users */ if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { - spin_lock(&rtc->irq_task_lock); + spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task) err = -EBUSY; - spin_unlock(&rtc->irq_task_lock); + spin_unlock_irq(&rtc->irq_task_lock); if (err < 0) return err; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 78552e6e76a..001eb1123a6 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -340,7 +340,8 @@ static int __init ds1553_rtc_probe(struct platform_device *pdev) if (pdata->irq >= 0) { writeb(0, ioaddr + RTC_INTERRUPTS); - if (request_irq(pdata->irq, ds1553_rtc_interrupt, IRQF_SHARED, + if (request_irq(pdata->irq, ds1553_rtc_interrupt, + IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = -1; diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index bc4bd24508a..6ef9c62d503 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -99,6 +99,7 @@ static ssize_t test_irq_store(struct device *dev, struct rtc_device *rtc = platform_get_drvdata(plat_dev); retval = count; + local_irq_disable(); if (strncmp(buf, "tick", 4) == 0) rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); else if (strncmp(buf, "alarm", 5) == 0) @@ -107,6 +108,7 @@ static ssize_t test_irq_store(struct device *dev, rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); else retval = -EINVAL; + local_irq_enable(); return retval; } -- cgit From 17ad78e59a0334d64c3a37f964b15ab9918313c7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 25 Nov 2006 11:09:29 -0800 Subject: [PATCH] drivers/rtc/rtc-rs5c372.c: fix a NULL dereference The correct order is: NULL check before dereference This was a guaranteed NULL dereference with debugging enabled since rs5c372_sysfs_show_osc() does actually pass NULL... Spotted by the Coverity checker. Signed-off-by: Adrian Bunk Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-rs5c372.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 2a86632580f..a44fe4efa21 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -126,13 +126,13 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) return -EIO; } - dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); - if (osc) *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; - if (trim) + if (trim) { *trim = buf & RS5C372_TRIM_MASK; + dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); + } return 0; } -- cgit From 82189b9807e05ea8d1f69de5bf92eaf244a0eb12 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Sat, 25 Nov 2006 11:09:30 -0800 Subject: [PATCH] Fix device_attribute memory leak in device_del dev->devt_attr is allocated in device_add() but it is never freed in device_del() in the drivers/base/core.c file (reported by kmemleak). Signed-off-by: Catalin Marinas Acked-by: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 68ad11af22b..002fde46d38 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -591,8 +591,10 @@ void device_del(struct device * dev) if (parent) klist_del(&dev->knode_parent); - if (dev->devt_attr) + if (dev->devt_attr) { device_remove_file(dev, dev->devt_attr); + kfree(dev->devt_attr); + } if (dev->class) { sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); -- cgit From a1b26c32af51d0fd82754bc06b495dd03c2f2d58 Mon Sep 17 00:00:00 2001 From: Jeremy Higdon Date: Sat, 25 Nov 2006 11:09:33 -0800 Subject: [PATCH] sgiioc4: Disable module unload This patch removes a module_exit function that sgiioc4 should not have had. It seems that the IDE layer doesn't support submodule unloading. sgiioc4 was the only driver in drivers/ide/pci that had an exit function. After an unload, the devices would stay around and the next attempt to reference would crash... Signed-off-by: Jeremy Higdon Acked-by: "Bartlomiej Zolnierkiewicz" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ide/pci/sgiioc4.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 244f7eb7006..cfad09accf5 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -768,14 +768,7 @@ ioc4_ide_init(void) return ioc4_register_submodule(&ioc4_ide_submodule); } -static void __devexit -ioc4_ide_exit(void) -{ - ioc4_unregister_submodule(&ioc4_ide_submodule); -} - late_initcall(ioc4_ide_init); /* Call only after IDE init is done */ -module_exit(ioc4_ide_exit); MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon"); MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card"); -- cgit From 5e66b0b5f187c811419ff10cfb5668c028a64d57 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 25 Nov 2006 11:09:35 -0800 Subject: [PATCH] tlclk: fix platform_device_register_simple() error check The return value of platform_device_register_simple() should be checked by IS_ERR(). This patch also fix misc_register() error case. Because misc_register() returns error code. Cc: Sebastien Bouchard Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tlclk.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 2444a0e24b3..244d30a03fe 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -792,15 +792,14 @@ static int __init tlclk_init(void) ret = misc_register(&tlclk_miscdev); if (ret < 0) { printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret); - ret = -EBUSY; goto out3; } tlclk_device = platform_device_register_simple("telco_clock", -1, NULL, 0); - if (!tlclk_device) { + if (IS_ERR(tlclk_device)) { printk(KERN_ERR "tlclk: platform_device_register failed.\n"); - ret = -EBUSY; + ret = PTR_ERR(tlclk_device); goto out4; } -- cgit From 9dce447a542d8b4bedf13d6a4c4fc6737240372e Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 25 Nov 2006 11:09:38 -0800 Subject: [PATCH] usb: ati remote memleak fix This is a bug. When checking for ati_remote->outbuf we free freeing ati_remote->inbuf so we end up freeing ati_remote->inbuf twice. Also the checks for 'ati_remote->inbuf != NULL' and 'ati_remote->outbuf != NULL' are redundant as usb_buffer_free() does this. Signed-off-by: Mariusz Kozlowski Acked-by: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/input/ati_remote.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index f659f3028ad..787b847d38c 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c @@ -636,13 +636,11 @@ static void ati_remote_free_buffers(struct ati_remote *ati_remote) if (ati_remote->out_urb) usb_free_urb(ati_remote->out_urb); - if (ati_remote->inbuf) - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->inbuf, ati_remote->inbuf_dma); + usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, + ati_remote->inbuf, ati_remote->inbuf_dma); - if (ati_remote->outbuf) - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->inbuf, ati_remote->outbuf_dma); + usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, + ati_remote->outbuf, ati_remote->outbuf_dma); } static void ati_remote_input_init(struct ati_remote *ati_remote) -- cgit From 95f6134e175fd69ab3f088f7a09adbd3fd3548e1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 23 Nov 2006 11:48:28 -0800 Subject: [6PACK]: Masking bug in 6pack driver. Looks like a broken masking to me, binary not is used where bitwise not was intended. Signed-off-by: Jean Delvare Signed-off-by: Ralf Baechle Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 86b3bb9bec2..92420f007b9 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -914,7 +914,7 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd) printk(KERN_DEBUG "6pack: protocol violation\n"); else sp->status = 0; - cmd &= !SIXP_RX_DCD_MASK; + cmd &= ~SIXP_RX_DCD_MASK; } sp->status = cmd & SIXP_PRIO_DATA_MASK; } else { /* output watchdog char if idle */ -- cgit From c4e46b9567669eb5e1182d4b12c2d889ce27da64 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Thu, 16 Nov 2006 18:31:04 -0300 Subject: V4L/DVB (4831): Fix tuning on older budget DVBS cards. Fixes to DISEQC on these cards inadvertently broke normal tone/voltage signalling. This restores the necessary function. Signed-off-by: Andrew de Quincey Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index e58f0391e9d..e28617bd564 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -382,6 +382,7 @@ static void frontend_init(struct budget *budget) if (budget->dvb_frontend) { budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; + budget->dvb_frontend->ops.set_tone = budget_set_tone; break; } break; -- cgit From bc495b66d048d64a9b8aeb49ca8405f4687ca123 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 19 Nov 2006 02:15:37 -0300 Subject: V4L/DVB (4840): Budget: diseqc_method module parameter for cards with subsystem-id 13c2:1003 New module parameter diseqc_method for cards with subsystem-id 13c2:1003. - 0: unreliable method, can be used by all board revisions (default) - 1: reliable method, works for newer board layouts only The parameter has no effect for cards with other subsystem-ids. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index e28617bd564..56f1c80defc 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -46,6 +46,10 @@ #include "lnbp21.h" #include "bsru6.h" +static int diseqc_method; +module_param(diseqc_method, int, 0444); +MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); + static void Set22K (struct budget *budget, int state) { struct saa7146_dev *dev=budget->dev; @@ -382,7 +386,11 @@ static void frontend_init(struct budget *budget) if (budget->dvb_frontend) { budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { + budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; + budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; + budget->dvb_frontend->ops.set_tone = budget_set_tone; + } break; } break; -- cgit From 30d9464c76743160612e7de0b2f5f656c78915d3 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Thu, 16 Nov 2006 22:12:40 -0300 Subject: V4L/DVB (4832): Fix uninitialised variable in dvb_frontend_swzigzag Spotted by coverity/Adrian Bunk. Signed-off-by: Andrew de Quincey Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 53304e6991a..a2ab2eebfc6 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -348,7 +348,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { - fe_status_t s; + fe_status_t s = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; /* if we've got no parameters, just keep idling */ -- cgit From a5bbc7d94cf1dcb2100eeaf68791a401ad7ce54d Mon Sep 17 00:00:00 2001 From: Ira Snyder Date: Mon, 20 Nov 2006 07:20:48 -0300 Subject: V4L/DVB (4849): Add missing spin_unlock to saa6588 decoder driver Sparse noticed a lock imbalance in read_from_buf(). Further inspection shows that the lock should not be held when the function exits. This adds a spin_unlock_irqrestore(), so that every exit path of the read_from_buf() function is consistent. The unlock was missing on an error path. Signed-off-by: Ira W. Snyder Signed-off-by: Hans J. Koch Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa6588.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index a81285ca7d5..7b9859c3301 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c @@ -212,8 +212,10 @@ static void read_from_buf(struct saa6588 *s, struct rds_command *a) if (rd_blocks > s->block_count) rd_blocks = s->block_count; - if (!rd_blocks) + if (!rd_blocks) { + spin_unlock_irqrestore(&s->lock, flags); return; + } for (i = 0; i < rd_blocks; i++) { if (block_to_user_buf(s, buf_ptr)) { -- cgit From 5718bbd2d92b9c2aa2f5700e4d3ed9d72f72f47e Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Tue, 21 Nov 2006 08:13:59 -0300 Subject: V4L/DVB (4865): Fix: Slot 0 not NULL on disconnecting SN9C10x PC Camera The patch fix bug 5748. Signed-off-by: Luca Risolia Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/et61x251/et61x251_core.c | 3 +-- drivers/media/video/sn9c102/sn9c102_core.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index f786ab11d2c..86e353b26b5 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -1182,8 +1182,6 @@ static void et61x251_release_resources(struct et61x251_device* cam) video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); - usb_put_dev(cam->usbdev); - mutex_unlock(&et61x251_sysfs_lock); kfree(cam->control_buffer); @@ -1275,6 +1273,7 @@ static int et61x251_release(struct inode* inode, struct file* filp) if (cam->state & DEV_DISCONNECTED) { et61x251_release_resources(cam); + usb_put_dev(cam->usbdev); mutex_unlock(&cam->dev_mutex); kfree(cam); return 0; diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index a4702d3c2ac..42fb60d985b 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -1462,8 +1462,6 @@ static void sn9c102_release_resources(struct sn9c102_device* cam) video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); - usb_put_dev(cam->usbdev); - mutex_unlock(&sn9c102_sysfs_lock); kfree(cam->control_buffer); @@ -1555,6 +1553,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp) if (cam->state & DEV_DISCONNECTED) { sn9c102_release_resources(cam); + usb_put_dev(cam->usbdev); mutex_unlock(&cam->dev_mutex); kfree(cam); return 0; -- cgit From f7668162a366d1ce0fe84122d11108e13a8ce950 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 25 Nov 2006 09:40:28 -0300 Subject: V4L/DVB (4885): Improve saa711x check The old code would accept any device on the same i2c address as the saa711x chips as an saa711x. However, this fails with saa717x chips, which use that same address and so are misdetected as a saa7111. Now check whether the chip is really a saa711x model. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7115.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index c5719f7bd1a..f28398dd9d9 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1464,8 +1464,6 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver_saa711x; snprintf(client->name, sizeof(client->name) - 1, "saa7115"); - v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1); - for (i=0;i<0x0f;i++) { saa711x_write(client, 0, i); name[i] = (saa711x_read(client, 0) &0x0f) +'0'; @@ -1477,6 +1475,13 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) saa711x_write(client, 0, 5); chip_id = saa711x_read(client, 0) & 0x0f; + /* Check whether this chip is part of the saa711x series */ + if (memcmp(name, "1f711", 5)) { + v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n", + address << 1, name); + return 0; + } + snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name); -- cgit From 221a09d5c4cb8384d9be74db60f37a5752675255 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 18:01:21 -0300 Subject: V4L/DVB (4874): Fix oops on symbol rate==0 The tda10086 causes an oops (divide by zero) if a zero symbol rate is used; this prevents this. Signed-off-by: Andrew de Quincey Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10086.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c index 7456b0b9976..4c27a2d90a3 100644 --- a/drivers/media/dvb/frontends/tda10086.c +++ b/drivers/media/dvb/frontends/tda10086.c @@ -441,6 +441,10 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa dprintk ("%s\n", __FUNCTION__); + // check for invalid symbol rate + if (fe_params->u.qpsk.symbol_rate < 500000) + return -EINVAL; + // calculate the updated frequency (note: we convert from Hz->kHz) tmp64 = tda10086_read_byte(state, 0x52); tmp64 |= (tda10086_read_byte(state, 0x51) << 8); -- cgit From c31f571d9f42fa2e89148811730fe3dc64943a6e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Nov 2006 12:39:43 +0900 Subject: [PATCH] libata: don't schedule EH on wcache on/off if old EH Do not schedule EH for revalidation on wcache on/off if old EH. Old EH cannot handle it and will result in WARN_ON()'s and oops. This closes bug #7412. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 5c1fc467fc7..22643c0d9a5 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1451,6 +1451,7 @@ nothing_to_do: static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) { + struct ata_port *ap = qc->ap; struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; int need_sense = (qc->err_mask != 0); @@ -1459,11 +1460,12 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE * cache */ - if (!need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && + if (ap->ops->error_handler && + !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && ((qc->tf.feature == SETFEATURES_WC_ON) || (qc->tf.feature == SETFEATURES_WC_OFF))) { - qc->ap->eh_info.action |= ATA_EH_REVALIDATE; - ata_port_schedule_eh(qc->ap); + ap->eh_info.action |= ATA_EH_REVALIDATE; + ata_port_schedule_eh(ap); } /* For ATA pass thru (SAT) commands, generate a sense block if @@ -1490,8 +1492,8 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } } - if (need_sense && !qc->ap->ops->error_handler) - ata_dump_status(qc->ap->id, &qc->result_tf); + if (need_sense && !ap->ops->error_handler) + ata_dump_status(ap->id, &qc->result_tf); qc->scsidone(cmd); -- cgit From f33d625f40e3b803c4cdea3219abb96cabf5ea03 Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Tue, 21 Nov 2006 16:55:58 -0800 Subject: [PATCH] ahci: AHCI mode SATA patch for Intel ICH9 This patch adds the Intel ICH9 AHCI controller DID's for SATA support. Signed-off-by: Jason Gaston Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 234197e57e9..f510e1196dc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -314,6 +314,17 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ + { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ + { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ /* JMicron */ { PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */ -- cgit From 08475a1920aa7acc535324d6991b830fa7625bd8 Mon Sep 17 00:00:00 2001 From: Brian King Date: Mon, 20 Nov 2006 13:51:56 -0600 Subject: [PATCH] libata: Fixup ata_sas_queuecmd to handle __ata_scsi_queuecmd failure Fixes ata_sas_queuecmd to properly handle a failure from __ata_scsi_queuecmd. Signed-off-by: Brian King Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 22643c0d9a5..47ea111d5ac 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3347,20 +3347,23 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); * @ap: ATA port to which the command is being sent * * RETURNS: - * Zero. + * Return value from __ata_scsi_queuecmd() if @cmd can be queued, + * 0 otherwise. */ int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), struct ata_port *ap) { + int rc = 0; + ata_scsi_dump_cdb(ap, cmd); if (likely(ata_scsi_dev_enabled(ap->device))) - __ata_scsi_queuecmd(cmd, done, ap->device); + rc = __ata_scsi_queuecmd(cmd, done, ap->device); else { cmd->result = (DID_BAD_TARGET << 16); done(cmd); } - return 0; + return rc; } EXPORT_SYMBOL_GPL(ata_sas_queuecmd); -- cgit From 967bf623e9f5eecfb056b1ba7e0efd74a21c9c3a Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 28 Nov 2006 23:11:52 +0000 Subject: [PATCH] Fix Intel/Sharp command set erase suspend bug When we sleep and wait for a suspended operation to be resumed, go back and check until it's ready -- don't just continue after the first time we're woken. This can cause file system corruption. Signed-off-by: Joakim Tjernlund Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- drivers/mtd/chips/cfi_cmdset_0001.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 7ea49a0d5ec..296159ec518 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1087,7 +1087,7 @@ static int inval_cache_and_wait_for_operation( } spin_lock(chip->mutex); - if (chip->state != chip_state) { + while (chip->state != chip_state) { /* Someone's suspended the operation: sleep */ DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_UNINTERRUPTIBLE); -- cgit From 315917d23fdd20a0f4ff99b9228de5840d9d276c Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 29 Nov 2006 22:21:33 +0100 Subject: [PATCH] r8169: Fix iteration variable sign This changes the type of variable "i" in rtl8169_init_one() from "unsigned int" to "int". "i" is checked for < 0 later, which can never happen for "unsigned". This results in broken error handling. Signed-off-by: Michael Buesch Signed-off-by: Francois Romieu Signed-off-by: Linus Torvalds --- 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 27f90b2139c..b977ed85ff3 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1473,8 +1473,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct rtl8169_private *tp; struct net_device *dev; void __iomem *ioaddr; - unsigned int i, pm_cap; - int rc; + unsigned int pm_cap; + int i, rc; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", -- cgit