From 66a10506d632051e1153e2555f4b2c820d427f64 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 13 Feb 2008 15:55:38 +0900 Subject: [MTD] [OneNAND] Fix unlock all in Double Density Package (DDP) Signed-off-by: Kyungmin Park Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 8d7d21be1541..15a62db656de 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -2052,7 +2052,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) * * Check lock status */ -static void onenand_check_lock_status(struct onenand_chip *this) +static int onenand_check_lock_status(struct onenand_chip *this) { unsigned int value, block, status; unsigned int end; @@ -2070,9 +2070,13 @@ static void onenand_check_lock_status(struct onenand_chip *this) /* Check lock status */ status = this->read_word(this->base + ONENAND_REG_WP_STATUS); - if (!(status & ONENAND_WP_US)) + if (!(status & ONENAND_WP_US)) { printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); + return 0; + } } + + return 1; } /** @@ -2081,9 +2085,11 @@ static void onenand_check_lock_status(struct onenand_chip *this) * * Unlock all blocks */ -static int onenand_unlock_all(struct mtd_info *mtd) +static void onenand_unlock_all(struct mtd_info *mtd) { struct onenand_chip *this = mtd->priv; + loff_t ofs = 0; + size_t len = this->chipsize; if (this->options & ONENAND_HAS_UNLOCK_ALL) { /* Set start block address */ @@ -2099,23 +2105,19 @@ static int onenand_unlock_all(struct mtd_info *mtd) & ONENAND_CTRL_ONGO) continue; + /* Check lock status */ + if (onenand_check_lock_status(this)) + return; + /* Workaround for all block unlock in DDP */ if (ONENAND_IS_DDP(this)) { - /* 1st block on another chip */ - loff_t ofs = this->chipsize >> 1; - size_t len = mtd->erasesize; - - onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); + /* All blocks on another chip */ + ofs = this->chipsize >> 1; + len = this->chipsize >> 1; } - - onenand_check_lock_status(this); - - return 0; } - onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK); - - return 0; + onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); } #ifdef CONFIG_MTD_ONENAND_OTP -- cgit v1.2.2 From 3797fec17193e05dee9666b990d6c84e16b188b3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Apr 2008 00:41:00 -0400 Subject: Input: remove private member from input_dev structure Everyone should be using input_{get|set}_drvdata() by now. Alias them to dev_{get|set}_drvdata() and remove ->private. Signed-off-by: Dmitry Torokhov --- drivers/input/input-polldev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 490918a5d192..0d3ce7a50fb1 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c @@ -73,7 +73,7 @@ static void input_polled_device_work(struct work_struct *work) static int input_open_polled_device(struct input_dev *input) { - struct input_polled_dev *dev = input->private; + struct input_polled_dev *dev = input_get_drvdata(input); int error; error = input_polldev_start_workqueue(); @@ -91,7 +91,7 @@ static int input_open_polled_device(struct input_dev *input) static void input_close_polled_device(struct input_dev *input) { - struct input_polled_dev *dev = input->private; + struct input_polled_dev *dev = input_get_drvdata(input); cancel_delayed_work_sync(&dev->work); input_polldev_stop_workqueue(); @@ -151,10 +151,10 @@ int input_register_polled_device(struct input_polled_dev *dev) { struct input_dev *input = dev->input; + input_set_drvdata(input, dev); INIT_DELAYED_WORK(&dev->work, input_polled_device_work); if (!dev->poll_interval) dev->poll_interval = 500; - input->private = dev; input->open = input_open_polled_device; input->close = input_close_polled_device; -- cgit v1.2.2 From e6cdd15629a5a99d805fa3cbf0f5174bcfc685bb Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 2 Apr 2008 00:42:42 -0400 Subject: Input: locomokbd - add 'off' button support for Sharp Collie/Poodle Enables the Sharp Zaurus Collie and Poodle devices to be turned off by pressing the "Cancel" button for a few seconds (as designed by Sharp). Additional small cleanups: - removal of unused #defines and variables - add missing __devinit/__devexit/__devinitconst annotations - reorganized copyright notice Signed-off-by: Helge Deller Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/locomokbd.c | 73 +++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 5a0ca18d6755..9caed30f3bbb 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -1,14 +1,12 @@ /* - * Copyright (c) 2005 John Lenz + * LoCoMo keyboard driver for Linux-based ARM PDAs: + * - SHARP Zaurus Collie (SL-5500) + * - SHARP Zaurus Poodle (SL-5600) * + * Copyright (c) 2005 John Lenz * Based on from xtkbd.c - */ - -/* - * LoCoMo keyboard driver for Linux/ARM - */ - -/* + * + * * 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 @@ -47,7 +45,8 @@ MODULE_LICENSE("GPL"); #define KEY_CONTACT KEY_F18 #define KEY_CENTER KEY_F15 -static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { +static const unsigned char +locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ @@ -67,22 +66,21 @@ static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { #define KB_COLS 8 #define KB_ROWMASK(r) (1 << (r)) #define SCANCODE(c,r) ( ((c)<<4) + (r) + 1 ) -#define NR_SCANCODES 128 #define KB_DELAY 8 #define SCAN_INTERVAL (HZ/10) -#define LOCOMOKBD_PRESSED 1 struct locomokbd { unsigned char keycode[LOCOMOKBD_NUMKEYS]; struct input_dev *input; char phys[32]; - struct locomo_dev *ldev; unsigned long base; spinlock_t lock; struct timer_list timer; + unsigned long suspend_jiffies; + unsigned int count_cancel; }; /* helper functions for reading the keyboard matrix */ @@ -128,7 +126,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col) /* Scan the hardware keyboard and push any changes up through the input layer */ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) { - unsigned int row, col, rowd, scancode; + unsigned int row, col, rowd; unsigned long flags; unsigned int num_pressed; unsigned long membase = locomokbd->base; @@ -145,13 +143,33 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) rowd = ~locomo_readl(membase + LOCOMO_KIB); for (row = 0; row < KB_ROWS; row++) { + unsigned int scancode, pressed, key; + scancode = SCANCODE(col, row); - if (rowd & KB_ROWMASK(row)) { - num_pressed += 1; - input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1); - } else { - input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0); - } + pressed = rowd & KB_ROWMASK(row); + key = locomokbd->keycode[scancode]; + + input_report_key(locomokbd->input, key, pressed); + if (likely(!pressed)) + continue; + + num_pressed++; + + /* The "Cancel/ESC" key is labeled "On/Off" on + * Collie and Poodle and should suspend the device + * if it was pressed for more than a second. */ + if (unlikely(key == KEY_ESC)) { + if (!time_after(jiffies, + locomokbd->suspend_jiffies + HZ)) + continue; + if (locomokbd->count_cancel++ + != (HZ/SCAN_INTERVAL + 1)) + continue; + input_event(locomokbd->input, EV_PWR, + KEY_SUSPEND, 1); + locomokbd->suspend_jiffies = jiffies; + } else + locomokbd->count_cancel = 0; } locomokbd_reset_col(membase, col); } @@ -162,6 +180,8 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) /* if any keys are pressed, enable the timer */ if (num_pressed) mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL); + else + locomokbd->count_cancel = 0; spin_unlock_irqrestore(&locomokbd->lock, flags); } @@ -186,10 +206,11 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) static void locomokbd_timer_callback(unsigned long data) { struct locomokbd *locomokbd = (struct locomokbd *) data; + locomokbd_scankeyboard(locomokbd); } -static int locomokbd_probe(struct locomo_dev *dev) +static int __devinit locomokbd_probe(struct locomo_dev *dev) { struct locomokbd *locomokbd; struct input_dev *input_dev; @@ -211,7 +232,6 @@ static int locomokbd_probe(struct locomo_dev *dev) goto err_free_mem; } - locomokbd->ldev = dev; locomo_set_drvdata(dev, locomokbd); locomokbd->base = (unsigned long) dev->mapbase; @@ -222,6 +242,8 @@ static int locomokbd_probe(struct locomo_dev *dev) locomokbd->timer.function = locomokbd_timer_callback; locomokbd->timer.data = (unsigned long) locomokbd; + locomokbd->suspend_jiffies = jiffies; + locomokbd->input = input_dev; strcpy(locomokbd->phys, "locomokbd/input0"); @@ -233,9 +255,10 @@ static int locomokbd_probe(struct locomo_dev *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | + BIT_MASK(EV_PWR); input_dev->keycode = locomokbd->keycode; - input_dev->keycodesize = sizeof(unsigned char); + input_dev->keycodesize = sizeof(locomokbd_keycode[0]); input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); @@ -268,7 +291,7 @@ static int locomokbd_probe(struct locomo_dev *dev) return err; } -static int locomokbd_remove(struct locomo_dev *dev) +static int __devexit locomokbd_remove(struct locomo_dev *dev) { struct locomokbd *locomokbd = locomo_get_drvdata(dev); @@ -292,7 +315,7 @@ static struct locomo_driver keyboard_driver = { }, .devid = LOCOMO_DEVID_KEYBOARD, .probe = locomokbd_probe, - .remove = locomokbd_remove, + .remove = __devexit_p(locomokbd_remove), }; static int __init locomokbd_init(void) -- cgit v1.2.2 From 7c6d0ee14cb7a4cfad4864dc196256da5749bc0c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 2 Apr 2008 00:43:01 -0400 Subject: Input: ads7846 - simplify support of external vREF (and ads7843) This updates the ads7846 driver to handle external vREF (required on boards using ads7843 chips) without module parameters, and also removes a needless variable with its associated bogus gcc warning. Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 57a1c28bf122..a571aa965da0 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -87,6 +87,7 @@ struct ads7846 { #endif u16 model; + u16 vref_mv; u16 vref_delay_usecs; u16 x_plate_ohms; u16 pressure_max; @@ -184,9 +185,6 @@ struct ads7846 { * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; * ads7846 lets that pin be unconnected, to use internal vREF. */ -static unsigned vREF_mV; -module_param(vREF_mV, uint, 0); -MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts"); struct ser_req { u8 ref_on; @@ -213,7 +211,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) struct ads7846 *ts = dev_get_drvdata(dev); struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); int status; - int uninitialized_var(sample); int use_internal; if (!req) @@ -270,13 +267,13 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) if (status == 0) { /* on-wire is a must-ignore bit, a BE12 value, then padding */ - sample = be16_to_cpu(req->sample); - sample = sample >> 3; - sample &= 0x0fff; + status = be16_to_cpu(req->sample); + status = status >> 3; + status &= 0x0fff; } kfree(req); - return status ? status : sample; + return status; } #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) @@ -317,7 +314,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) unsigned retval = v; /* external resistors may scale vAUX into 0..vREF */ - retval *= vREF_mV; + retval *= ts->vref_mv; retval = retval >> 12; return retval; } @@ -375,14 +372,14 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) /* hwmon sensors need a reference voltage */ switch (ts->model) { case 7846: - if (!vREF_mV) { + if (!ts->vref_mv) { dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); - vREF_mV = 2500; + ts->vref_mv = 2500; } break; case 7845: case 7843: - if (!vREF_mV) { + if (!ts->vref_mv) { dev_warn(&spi->dev, "external vREF for ADS%d not specified\n", ts->model); @@ -875,6 +872,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->spi = spi; ts->input = input_dev; + ts->vref_mv = pdata->vref_mv; hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ts->timer.function = ads7846_timer; -- cgit v1.2.2 From febf1dff119ef27ee22a54d40f284d2454f00d8d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Apr 2008 00:51:09 -0400 Subject: Input: add support for WM97xx familty touchscreens Add support for the touchscreen controllers provided by Wolfson Microelectronics WM97xx series chips in both polled and streaming modes. These drivers have been maintained out of tree since 2003. During that time the driver the primary maintainer was Liam Girdwood and a number of people have made contributions including Dmitry Baryshkov, Stanley Cai, Rodolfo Giometti, Russell King, Marc Kleine-Budde, Ian Molton, Vincent Sanders, Andrew Zabolotny, Graeme Gregory, Mike Arthur and myself. Apologies to anyone I have omitted. Signed-off-by: Liam Girdwood Signed-off-by: Graeme Gregory Signed-off-by: Mike Arthur Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 14 + drivers/input/touchscreen/Makefile | 3 + drivers/input/touchscreen/wm97xx-core.c | 789 ++++++++++++++++++++++++++++++++ 3 files changed, 806 insertions(+) create mode 100644 drivers/input/touchscreen/wm97xx-core.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 90e8e92dfe47..a95a87cd1d59 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -185,6 +185,20 @@ config TOUCHSCREEN_UCB1400 To compile this driver as a module, choose M here: the module will be called ucb1400_ts. +config TOUCHSCREEN_WM97XX + tristate "Support for WM97xx AC97 touchscreen controllers" + depends on AC97_BUS + help + Say Y here if you have a Wolfson Microelectronics WM97xx + touchscreen connected to your system. Note that this option + only enables core driver, you will also need to select + support for appropriate chip below. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called wm97xx-ts. + config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 35d4097df35a..b4e7b5dbf649 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -4,6 +4,8 @@ # Each configuration option enables a list of files. +wm97xx-ts-y := wm97xx-core.o + obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o @@ -19,3 +21,4 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o +obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c new file mode 100644 index 000000000000..2910999e05a0 --- /dev/null +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -0,0 +1,789 @@ +/* + * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712 + * and WM9713 AC97 Codecs. + * + * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton + * Andrew Zabolotny + * Russell King + * + * 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. + * + * Notes: + * + * Features: + * - supports WM9705, WM9712, WM9713 + * - polling mode + * - continuous mode (arch-dependent) + * - adjustable rpu/dpp settings + * - adjustable pressure current + * - adjustable sample settle delay + * - 4 and 5 wire touchscreens (5 wire is WM9712 only) + * - pen down detection + * - battery monitor + * - sample AUX adcs + * - power management + * - codec GPIO + * - codec event notification + * Todo + * - Support for async sampling control for noisy LCDs. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TS_NAME "wm97xx" +#define WM_CORE_VERSION "1.00" +#define DEFAULT_PRESSURE 0xb0c0 + + +/* + * Touchscreen absolute values + * + * These parameters are used to help the input layer discard out of + * range readings and reduce jitter etc. + * + * o min, max:- indicate the min and max values your touch screen returns + * o fuzz:- use a higher number to reduce jitter + * + * The default values correspond to Mainstone II in QVGA mode + * + * Please read + * Documentation/input/input-programming.txt for more details. + */ + +static int abs_x[3] = {350, 3900, 5}; +module_param_array(abs_x, int, NULL, 0); +MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz"); + +static int abs_y[3] = {320, 3750, 40}; +module_param_array(abs_y, int, NULL, 0); +MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz"); + +static int abs_p[3] = {0, 150, 4}; +module_param_array(abs_p, int, NULL, 0); +MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz"); + +/* + * wm97xx IO access, all IO locking done by AC97 layer + */ +int wm97xx_reg_read(struct wm97xx *wm, u16 reg) +{ + if (wm->ac97) + return wm->ac97->bus->ops->read(wm->ac97, reg); + else + return -1; +} +EXPORT_SYMBOL_GPL(wm97xx_reg_read); + +void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val) +{ + /* cache digitiser registers */ + if (reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3) + wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val; + + /* cache gpio regs */ + if (reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE) + wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val; + + /* wm9713 irq reg */ + if (reg == 0x5a) + wm->misc = val; + + if (wm->ac97) + wm->ac97->bus->ops->write(wm->ac97, reg, val); +} +EXPORT_SYMBOL_GPL(wm97xx_reg_write); + +/** + * wm97xx_read_aux_adc - Read the aux adc. + * @wm: wm97xx device. + * @adcsel: codec ADC to be read + * + * Reads the selected AUX ADC. + */ + +int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) +{ + int power_adc = 0, auxval; + u16 power = 0; + + /* get codec */ + mutex_lock(&wm->codec_mutex); + + /* When the touchscreen is not in use, we may have to power up + * the AUX ADC before we can use sample the AUX inputs-> + */ + if (wm->id == WM9713_ID2 && + (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) { + power_adc = 1; + wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff); + } + + /* Prepare the codec for AUX reading */ + wm->codec->aux_prepare(wm); + + /* Turn polling mode on to read AUX ADC */ + wm->pen_probably_down = 1; + wm->codec->poll_sample(wm, adcsel, &auxval); + + if (power_adc) + wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); + + wm->codec->dig_restore(wm); + + wm->pen_probably_down = 0; + + mutex_unlock(&wm->codec_mutex); + return auxval & 0xfff; +} +EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); + +/** + * wm97xx_get_gpio - Get the status of a codec GPIO. + * @wm: wm97xx device. + * @gpio: gpio + * + * Get the status of a codec GPIO pin + */ + +enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio) +{ + u16 status; + enum wm97xx_gpio_status ret; + + mutex_lock(&wm->codec_mutex); + status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); + + if (status & gpio) + ret = WM97XX_GPIO_HIGH; + else + ret = WM97XX_GPIO_LOW; + + mutex_unlock(&wm->codec_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(wm97xx_get_gpio); + +/** + * wm97xx_set_gpio - Set the status of a codec GPIO. + * @wm: wm97xx device. + * @gpio: gpio + * + * + * Set the status of a codec GPIO pin + */ + +void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, + enum wm97xx_gpio_status status) +{ + u16 reg; + + mutex_lock(&wm->codec_mutex); + reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS); + + if (status & WM97XX_GPIO_HIGH) + reg |= gpio; + else + reg &= ~gpio; + + if (wm->id == WM9712_ID2) + wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1); + else + wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg); + mutex_unlock(&wm->codec_mutex); +} +EXPORT_SYMBOL_GPL(wm97xx_set_gpio); + +/* + * Codec GPIO pin configuration, this sets pin direction, polarity, + * stickyness and wake up. + */ +void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir, + enum wm97xx_gpio_pol pol, enum wm97xx_gpio_sticky sticky, + enum wm97xx_gpio_wake wake) +{ + u16 reg; + + mutex_lock(&wm->codec_mutex); + reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); + + if (pol == WM97XX_GPIO_POL_HIGH) + reg |= gpio; + else + reg &= ~gpio; + + wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg); + reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY); + + if (sticky == WM97XX_GPIO_STICKY) + reg |= gpio; + else + reg &= ~gpio; + + wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg); + reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); + + if (wake == WM97XX_GPIO_WAKE) + reg |= gpio; + else + reg &= ~gpio; + + wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg); + reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); + + if (dir == WM97XX_GPIO_IN) + reg |= gpio; + else + reg &= ~gpio; + + wm97xx_reg_write(wm, AC97_GPIO_CFG, reg); + mutex_unlock(&wm->codec_mutex); +} +EXPORT_SYMBOL_GPL(wm97xx_config_gpio); + +/* + * Handle a pen down interrupt. + */ +static void wm97xx_pen_irq_worker(struct work_struct *work) +{ + struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work); + int pen_was_down = wm->pen_is_down; + + /* do we need to enable the touch panel reader */ + if (wm->id == WM9705_ID2) { + if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) & + WM97XX_PEN_DOWN) + wm->pen_is_down = 1; + else + wm->pen_is_down = 0; + } else { + u16 status, pol; + mutex_lock(&wm->codec_mutex); + status = wm97xx_reg_read(wm, AC97_GPIO_STATUS); + pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); + + if (WM97XX_GPIO_13 & pol & status) { + wm->pen_is_down = 1; + wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol & + ~WM97XX_GPIO_13); + } else { + wm->pen_is_down = 0; + wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol | + WM97XX_GPIO_13); + } + + if (wm->id == WM9712_ID2) + wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status & + ~WM97XX_GPIO_13) << 1); + else + wm97xx_reg_write(wm, AC97_GPIO_STATUS, status & + ~WM97XX_GPIO_13); + mutex_unlock(&wm->codec_mutex); + } + + /* If the system is not using continuous mode or it provides a + * pen down operation then we need to schedule polls while the + * pen is down. Otherwise the machine driver is responsible + * for scheduling reads. + */ + if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { + if (wm->pen_is_down && !pen_was_down) { + /* Data is not availiable immediately on pen down */ + queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); + } + + /* Let ts_reader report the pen up for debounce. */ + if (!wm->pen_is_down && pen_was_down) + wm->pen_is_down = 1; + } + + if (!wm->pen_is_down && wm->mach_ops->acc_enabled) + wm->mach_ops->acc_pen_up(wm); + + wm->mach_ops->irq_enable(wm, 1); +} + +/* + * Codec PENDOWN irq handler + * + * We have to disable the codec interrupt in the handler because it + * can take upto 1ms to clear the interrupt source. We schedule a task + * in a work queue to do the actual interaction with the chip (it + * doesn't matter if we end up reenqueing it before it is executed + * since we don't touch the chip until it has run). The interrupt is + * then enabled again in the slow handler when the source has been + * cleared. + */ +static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) +{ + struct wm97xx *wm = dev_id; + + wm->mach_ops->irq_enable(wm, 0); + queue_work(wm->ts_workq, &wm->pen_event_work); + + return IRQ_HANDLED; +} + +/* + * initialise pen IRQ handler and workqueue + */ +static int wm97xx_init_pen_irq(struct wm97xx *wm) +{ + u16 reg; + + /* If an interrupt is supplied an IRQ enable operation must also be + * provided. */ + BUG_ON(!wm->mach_ops->irq_enable); + + if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, + "wm97xx-pen", wm)) { + dev_err(wm->dev, + "Failed to register pen down interrupt, polling"); + wm->pen_irq = 0; + return -EINVAL; + } + + /* Configure GPIO as interrupt source on WM971x */ + if (wm->id != WM9705_ID2) { + BUG_ON(!wm->mach_ops->irq_gpio); + reg = wm97xx_reg_read(wm, AC97_MISC_AFE); + wm97xx_reg_write(wm, AC97_MISC_AFE, + reg & ~(wm->mach_ops->irq_gpio)); + reg = wm97xx_reg_read(wm, 0x5a); + wm97xx_reg_write(wm, 0x5a, reg & ~0x0001); + } + + return 0; +} + +static int wm97xx_read_samples(struct wm97xx *wm) +{ + struct wm97xx_data data; + int rc; + + mutex_lock(&wm->codec_mutex); + + if (wm->mach_ops && wm->mach_ops->acc_enabled) + rc = wm->mach_ops->acc_pen_down(wm); + else + rc = wm->codec->poll_touch(wm, &data); + + if (rc & RC_PENUP) { + if (wm->pen_is_down) { + wm->pen_is_down = 0; + dev_dbg(wm->dev, "pen up\n"); + input_report_abs(wm->input_dev, ABS_PRESSURE, 0); + input_sync(wm->input_dev); + } else if (!(rc & RC_AGAIN)) { + /* We need high frequency updates only while + * pen is down, the user never will be able to + * touch screen faster than a few times per + * second... On the other hand, when the user + * is actively working with the touchscreen we + * don't want to lose the quick response. So we + * will slowly increase sleep time after the + * pen is up and quicky restore it to ~one task + * switch when pen is down again. + */ + if (wm->ts_reader_interval < HZ / 10) + wm->ts_reader_interval++; + } + + } else if (rc & RC_VALID) { + dev_dbg(wm->dev, + "pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n", + data.x >> 12, data.x & 0xfff, data.y >> 12, + data.y & 0xfff, data.p >> 12, data.p & 0xfff); + input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); + input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); + input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); + input_sync(wm->input_dev); + wm->pen_is_down = 1; + wm->ts_reader_interval = wm->ts_reader_min_interval; + } else if (rc & RC_PENDOWN) { + dev_dbg(wm->dev, "pen down\n"); + wm->pen_is_down = 1; + wm->ts_reader_interval = wm->ts_reader_min_interval; + } + + mutex_unlock(&wm->codec_mutex); + return rc; +} + +/* +* The touchscreen sample reader. +*/ +static void wm97xx_ts_reader(struct work_struct *work) +{ + int rc; + struct wm97xx *wm = container_of(work, struct wm97xx, ts_reader.work); + + BUG_ON(!wm->codec); + + do { + rc = wm97xx_read_samples(wm); + } while (rc & RC_AGAIN); + + if (wm->pen_is_down || !wm->pen_irq) + queue_delayed_work(wm->ts_workq, &wm->ts_reader, + wm->ts_reader_interval); +} + +/** + * wm97xx_ts_input_open - Open the touch screen input device. + * @idev: Input device to be opened. + * + * Called by the input sub system to open a wm97xx touchscreen device. + * Starts the touchscreen thread and touch digitiser. + */ +static int wm97xx_ts_input_open(struct input_dev *idev) +{ + struct wm97xx *wm = input_get_drvdata(idev); + + wm->ts_workq = create_singlethread_workqueue("kwm97xx"); + if (wm->ts_workq == NULL) { + dev_err(wm->dev, + "Failed to create workqueue\n"); + return -EINVAL; + } + + /* start digitiser */ + if (wm->mach_ops && wm->mach_ops->acc_enabled) + wm->codec->acc_enable(wm, 1); + wm->codec->dig_enable(wm, 1); + + INIT_DELAYED_WORK(&wm->ts_reader, wm97xx_ts_reader); + INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker); + + wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1; + if (wm->ts_reader_min_interval < 1) + wm->ts_reader_min_interval = 1; + wm->ts_reader_interval = wm->ts_reader_min_interval; + + wm->pen_is_down = 0; + if (wm->pen_irq) + wm97xx_init_pen_irq(wm); + else + dev_err(wm->dev, "No IRQ specified\n"); + + /* If we either don't have an interrupt for pen down events or + * failed to acquire it then we need to poll. + */ + if (wm->pen_irq == 0) + queue_delayed_work(wm->ts_workq, &wm->ts_reader, + wm->ts_reader_interval); + + return 0; +} + +/** + * wm97xx_ts_input_close - Close the touch screen input device. + * @idev: Input device to be closed. + * + * Called by the input sub system to close a wm97xx touchscreen + * device. Kills the touchscreen thread and stops the touch + * digitiser. + */ + +static void wm97xx_ts_input_close(struct input_dev *idev) +{ + struct wm97xx *wm = input_get_drvdata(idev); + u16 reg; + + if (wm->pen_irq) { + /* Return the interrupt to GPIO usage (disabling it) */ + if (wm->id != WM9705_ID2) { + BUG_ON(!wm->mach_ops->irq_gpio); + reg = wm97xx_reg_read(wm, AC97_MISC_AFE); + wm97xx_reg_write(wm, AC97_MISC_AFE, + reg | wm->mach_ops->irq_gpio); + } + + free_irq(wm->pen_irq, wm); + } + + wm->pen_is_down = 0; + + /* Balance out interrupt disables/enables */ + if (cancel_work_sync(&wm->pen_event_work)) + wm->mach_ops->irq_enable(wm, 1); + + /* ts_reader rearms itself so we need to explicitly stop it + * before we destroy the workqueue. + */ + cancel_delayed_work_sync(&wm->ts_reader); + + destroy_workqueue(wm->ts_workq); + + /* stop digitiser */ + wm->codec->dig_enable(wm, 0); + if (wm->mach_ops && wm->mach_ops->acc_enabled) + wm->codec->acc_enable(wm, 0); +} + +static int wm97xx_probe(struct device *dev) +{ + struct wm97xx *wm; + int ret = 0, id = 0; + + wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); + if (!wm) + return -ENOMEM; + mutex_init(&wm->codec_mutex); + + wm->dev = dev; + dev->driver_data = wm; + wm->ac97 = to_ac97_t(dev); + + /* check that we have a supported codec */ + id = wm97xx_reg_read(wm, AC97_VENDOR_ID1); + if (id != WM97XX_ID1) { + dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id); + ret = -ENODEV; + goto alloc_err; + } + + wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2); + + dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff); + + switch (wm->id & 0xff) { +#ifdef CONFIG_TOUCHSCREEN_WM9705 + case 0x05: + wm->codec = &wm9705_codec; + break; +#endif +#ifdef CONFIG_TOUCHSCREEN_WM9712 + case 0x12: + wm->codec = &wm9712_codec; + break; +#endif +#ifdef CONFIG_TOUCHSCREEN_WM9713 + case 0x13: + wm->codec = &wm9713_codec; + break; +#endif + default: + dev_err(wm->dev, "Support for wm97%02x not compiled in.\n", + wm->id & 0xff); + ret = -ENODEV; + goto alloc_err; + } + + wm->input_dev = input_allocate_device(); + if (wm->input_dev == NULL) { + ret = -ENOMEM; + goto alloc_err; + } + + /* set up touch configuration */ + wm->input_dev->name = "wm97xx touchscreen"; + wm->input_dev->open = wm97xx_ts_input_open; + wm->input_dev->close = wm97xx_ts_input_close; + set_bit(EV_ABS, wm->input_dev->evbit); + set_bit(ABS_X, wm->input_dev->absbit); + set_bit(ABS_Y, wm->input_dev->absbit); + set_bit(ABS_PRESSURE, wm->input_dev->absbit); + input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1], + abs_x[2], 0); + input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1], + abs_y[2], 0); + input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], + abs_p[2], 0); + input_set_drvdata(wm->input_dev, wm); + wm->input_dev->dev.parent = dev; + ret = input_register_device(wm->input_dev); + if (ret < 0) + goto dev_alloc_err; + + /* set up physical characteristics */ + wm->codec->phy_init(wm); + + /* load gpio cache */ + wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG); + wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); + wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY); + wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); + wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS); + wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); + + /* register our battery device */ + wm->battery_dev = platform_device_alloc("wm97xx-battery", -1); + if (!wm->battery_dev) { + ret = -ENOMEM; + goto batt_err; + } + platform_set_drvdata(wm->battery_dev, wm); + wm->battery_dev->dev.parent = dev; + ret = platform_device_add(wm->battery_dev); + if (ret < 0) + goto batt_reg_err; + + /* register our extended touch device (for machine specific + * extensions) */ + wm->touch_dev = platform_device_alloc("wm97xx-touch", -1); + if (!wm->touch_dev) { + ret = -ENOMEM; + goto touch_err; + } + platform_set_drvdata(wm->touch_dev, wm); + wm->touch_dev->dev.parent = dev; + ret = platform_device_add(wm->touch_dev); + if (ret < 0) + goto touch_reg_err; + + return ret; + + touch_reg_err: + platform_device_put(wm->touch_dev); + touch_err: + platform_device_unregister(wm->battery_dev); + wm->battery_dev = NULL; + batt_reg_err: + platform_device_put(wm->battery_dev); + batt_err: + input_unregister_device(wm->input_dev); + wm->input_dev = NULL; + dev_alloc_err: + input_free_device(wm->input_dev); + alloc_err: + kfree(wm); + + return ret; +} + +static int wm97xx_remove(struct device *dev) +{ + struct wm97xx *wm = dev_get_drvdata(dev); + + platform_device_unregister(wm->battery_dev); + platform_device_unregister(wm->touch_dev); + input_unregister_device(wm->input_dev); + kfree(wm); + + return 0; +} + +#ifdef CONFIG_PM +static int wm97xx_suspend(struct device *dev, pm_message_t state) +{ + struct wm97xx *wm = dev_get_drvdata(dev); + + if (wm->input_dev->users) + cancel_delayed_work_sync(&wm->ts_reader); + + return 0; +} + +static int wm97xx_resume(struct device *dev) +{ + struct wm97xx *wm = dev_get_drvdata(dev); + + /* restore digitiser and gpios */ + if (wm->id == WM9713_ID2) { + wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]); + wm97xx_reg_write(wm, 0x5a, wm->misc); + if (wm->input_dev->users) { + u16 reg; + reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff; + wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg); + } + } + + wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]); + + wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]); + wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]); + wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]); + wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]); + wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]); + wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]); + + if (wm->input_dev->users && !wm->pen_irq) { + wm->ts_reader_interval = wm->ts_reader_min_interval; + queue_delayed_work(wm->ts_workq, &wm->ts_reader, + wm->ts_reader_interval); + } + + return 0; +} + +#else +#define wm97xx_suspend NULL +#define wm97xx_resume NULL +#endif + +/* + * Machine specific operations + */ +int wm97xx_register_mach_ops(struct wm97xx *wm, + struct wm97xx_mach_ops *mach_ops) +{ + mutex_lock(&wm->codec_mutex); + if (wm->mach_ops) { + mutex_unlock(&wm->codec_mutex); + return -EINVAL; + } + wm->mach_ops = mach_ops; + mutex_unlock(&wm->codec_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops); + +void wm97xx_unregister_mach_ops(struct wm97xx *wm) +{ + mutex_lock(&wm->codec_mutex); + wm->mach_ops = NULL; + mutex_unlock(&wm->codec_mutex); +} +EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); + +static struct device_driver wm97xx_driver = { + .name = "ac97", + .bus = &ac97_bus_type, + .owner = THIS_MODULE, + .probe = wm97xx_probe, + .remove = wm97xx_remove, + .suspend = wm97xx_suspend, + .resume = wm97xx_resume, +}; + +static int __init wm97xx_init(void) +{ + return driver_register(&wm97xx_driver); +} + +static void __exit wm97xx_exit(void) +{ + driver_unregister(&wm97xx_driver); +} + +module_init(wm97xx_init); +module_exit(wm97xx_exit); + +/* Module information */ +MODULE_AUTHOR("Liam Girdwood "); +MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 9448cefc6689aa51f1cd1cfe8b701dc94789c7ee Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Apr 2008 00:51:21 -0400 Subject: Input: WM97xx - add chip driver for WM9705 touchscreen Signed-off-by: Liam Girdwood Signed-off-by: Graeme Gregory Signed-off-by: Mike Arthur Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/wm9705.c | 353 +++++++++++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 drivers/input/touchscreen/wm9705.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index a95a87cd1d59..4939a96d12b9 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -199,6 +199,15 @@ config TOUCHSCREEN_WM97XX To compile this driver as a module, choose M here: the module will be called wm97xx-ts. +config TOUCHSCREEN_WM9705 + bool "WM9705 Touchscreen interface support" + depends on TOUCHSCREEN_WM97XX + help + Say Y here if you have a Wolfson Microelectronics WM9705 + touchscreen controller connected to your system. + + If unsure, say N. + config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index b4e7b5dbf649..5829a435efd1 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o +wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c new file mode 100644 index 000000000000..978e1a13ffc7 --- /dev/null +++ b/drivers/input/touchscreen/wm9705.c @@ -0,0 +1,353 @@ +/* + * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec. + * + * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton + * Andrew Zabolotny + * Russell King + * + * 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 + +#define TS_NAME "wm97xx" +#define WM9705_VERSION "1.00" +#define DEFAULT_PRESSURE 0xb0c0 + +/* + * Module parameters + */ + +/* + * Set current used for pressure measurement. + * + * Set pil = 2 to use 400uA + * pil = 1 to use 200uA and + * pil = 0 to disable pressure measurement. + * + * This is used to increase the range of values returned by the adc + * when measureing touchpanel pressure. + */ +static int pil; +module_param(pil, int, 0); +MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); + +/* + * Set threshold for pressure measurement. + * + * Pen down pressure below threshold is ignored. + */ +static int pressure = DEFAULT_PRESSURE & 0xfff; +module_param(pressure, int, 0); +MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); + +/* + * Set adc sample delay. + * + * For accurate touchpanel measurements, some settling time may be + * required between the switch matrix applying a voltage across the + * touchpanel plate and the ADC sampling the signal. + * + * This delay can be set by setting delay = n, where n is the array + * position of the delay in the array delay_table below. + * Long delays > 1ms are supported for completeness, but are not + * recommended. + */ +static int delay = 4; +module_param(delay, int, 0); +MODULE_PARM_DESC(delay, "Set adc sample delay."); + +/* + * Pen detect comparator threshold. + * + * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold + * i.e. 1 = Vmid/15 threshold + * 15 = Vmid/1 threshold + * + * Adjust this value if you are having problems with pen detect not + * detecting any down events. + */ +static int pdd = 8; +module_param(pdd, int, 0); +MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold"); + +/* + * Set adc mask function. + * + * Sources of glitch noise, such as signals driving an LCD display, may feed + * through to the touch screen plates and affect measurement accuracy. In + * order to minimise this, a signal may be applied to the MASK pin to delay or + * synchronise the sampling. + * + * 0 = No delay or sync + * 1 = High on pin stops conversions + * 2 = Edge triggered, edge on pin delays conversion by delay param (above) + * 3 = Edge triggered, edge on pin starts conversion after delay param + */ +static int mask; +module_param(mask, int, 0); +MODULE_PARM_DESC(mask, "Set adc mask function."); + +/* + * ADC sample delay times in uS + */ +static const int delay_table[] = { + 21, /* 1 AC97 Link frames */ + 42, /* 2 */ + 84, /* 4 */ + 167, /* 8 */ + 333, /* 16 */ + 667, /* 32 */ + 1000, /* 48 */ + 1333, /* 64 */ + 2000, /* 96 */ + 2667, /* 128 */ + 3333, /* 160 */ + 4000, /* 192 */ + 4667, /* 224 */ + 5333, /* 256 */ + 6000, /* 288 */ + 0 /* No delay, switch matrix always on */ +}; + +/* + * Delay after issuing a POLL command. + * + * The delay is 3 AC97 link frames + the touchpanel settling delay + */ +static inline void poll_delay(int d) +{ + udelay(3 * AC97_LINK_FRAME + delay_table[d]); +} + +/* + * set up the physical settings of the WM9705 + */ +static void wm9705_phy_init(struct wm97xx *wm) +{ + u16 dig1 = 0, dig2 = WM97XX_RPR; + + /* + * mute VIDEO and AUX as they share X and Y touchscreen + * inputs on the WM9705 + */ + wm97xx_reg_write(wm, AC97_AUX, 0x8000); + wm97xx_reg_write(wm, AC97_VIDEO, 0x8000); + + /* touchpanel pressure current*/ + if (pil == 2) { + dig2 |= WM9705_PIL; + dev_dbg(wm->dev, + "setting pressure measurement current to 400uA."); + } else if (pil) + dev_dbg(wm->dev, + "setting pressure measurement current to 200uA."); + if (!pil) + pressure = 0; + + /* polling mode sample settling delay */ + if (delay != 4) { + if (delay < 0 || delay > 15) { + dev_dbg(wm->dev, "supplied delay out of range."); + delay = 4; + } + } + dig1 &= 0xff0f; + dig1 |= WM97XX_DELAY(delay); + dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", + delay_table[delay]); + + /* WM9705 pdd */ + dig2 |= (pdd & 0x000f); + dev_dbg(wm->dev, "setting pdd to Vmid/%d", 1 - (pdd & 0x000f)); + + /* mask */ + dig2 |= ((mask & 0x3) << 4); + + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); +} + +static void wm9705_dig_enable(struct wm97xx *wm, int enable) +{ + if (enable) { + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, + wm->dig[2] | WM97XX_PRP_DET_DIG); + wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ + } else + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, + wm->dig[2] & ~WM97XX_PRP_DET_DIG); +} + +static void wm9705_aux_prepare(struct wm97xx *wm) +{ + memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); +} + +static void wm9705_dig_restore(struct wm97xx *wm) +{ + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); +} + +static inline int is_pden(struct wm97xx *wm) +{ + return wm->dig[2] & WM9705_PDEN; +} + +/* + * Read a sample from the WM9705 adc in polling mode. + */ +static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) +{ + int timeout = 5 * delay; + + if (!wm->pen_probably_down) { + u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(data & WM97XX_PEN_DOWN)) + return RC_PENUP; + wm->pen_probably_down = 1; + } + + /* set up digitiser */ + if (adcsel & 0x8000) + adcsel = ((adcsel & 0x7fff) + 3) << 12; + + if (wm->mach_ops && wm->mach_ops->pre_sample) + wm->mach_ops->pre_sample(adcsel); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, + adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); + + /* wait 3 AC97 time slots + delay for conversion */ + poll_delay(delay); + + /* wait for POLL to go low */ + while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) + && timeout) { + udelay(AC97_LINK_FRAME); + timeout--; + } + + if (timeout == 0) { + /* If PDEN is set, we can get a timeout when pen goes up */ + if (is_pden(wm)) + wm->pen_probably_down = 0; + else + dev_dbg(wm->dev, "adc sample timeout"); + return RC_PENUP; + } + + *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (wm->mach_ops && wm->mach_ops->post_sample) + wm->mach_ops->post_sample(adcsel); + + /* check we have correct sample */ + if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { + dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, + *sample & WM97XX_ADCSEL_MASK); + return RC_PENUP; + } + + if (!(*sample & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } + + return RC_VALID; +} + +/* + * Sample the WM9705 touchscreen in polling mode + */ +static int wm9705_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) +{ + int rc; + + rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); + if (rc != RC_VALID) + return rc; + rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); + if (rc != RC_VALID) + return rc; + if (pil) { + rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p); + if (rc != RC_VALID) + return rc; + } else + data->p = DEFAULT_PRESSURE; + + return RC_VALID; +} + +/* + * Enable WM9705 continuous mode, i.e. touch data is streamed across + * an AC97 slot + */ +static int wm9705_acc_enable(struct wm97xx *wm, int enable) +{ + u16 dig1, dig2; + int ret = 0; + + dig1 = wm->dig[1]; + dig2 = wm->dig[2]; + + if (enable) { + /* continous mode */ + if (wm->mach_ops->acc_startup && + (ret = wm->mach_ops->acc_startup(wm)) < 0) + return ret; + dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | + WM97XX_DELAY_MASK | WM97XX_SLT_MASK); + dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | + WM97XX_DELAY(delay) | + WM97XX_SLT(wm->acc_slot) | + WM97XX_RATE(wm->acc_rate); + if (pil) + dig1 |= WM97XX_ADCSEL_PRES; + dig2 |= WM9705_PDEN; + } else { + dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); + dig2 &= ~WM9705_PDEN; + if (wm->mach_ops->acc_shutdown) + wm->mach_ops->acc_shutdown(wm); + } + + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); + + return ret; +} + +struct wm97xx_codec_drv wm9705_codec = { + .id = WM9705_ID2, + .name = "wm9705", + .poll_sample = wm9705_poll_sample, + .poll_touch = wm9705_poll_touch, + .acc_enable = wm9705_acc_enable, + .phy_init = wm9705_phy_init, + .dig_enable = wm9705_dig_enable, + .dig_restore = wm9705_dig_restore, + .aux_prepare = wm9705_aux_prepare, +}; +EXPORT_SYMBOL_GPL(wm9705_codec); + +/* Module information */ +MODULE_AUTHOR("Liam Girdwood "); +MODULE_DESCRIPTION("WM9705 Touch Screen Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From de22b9ef1020ffdb9e1ed6f4686e2e62eaeb0958 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Apr 2008 00:51:26 -0400 Subject: Input: WM97xx - add chip driver for WM9712 touchscreen Signed-off-by: Liam Girdwood Signed-off-by: Graeme Gregory Signed-off-by: Mike Arthur Signed-off-by: Mark Brown Signed-off-by: Lars Munch Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/wm9712.c | 462 +++++++++++++++++++++++++++++++++++++ 3 files changed, 472 insertions(+) create mode 100644 drivers/input/touchscreen/wm9712.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4939a96d12b9..240e441c118a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -208,6 +208,15 @@ config TOUCHSCREEN_WM9705 If unsure, say N. +config TOUCHSCREEN_WM9712 + bool "WM9712 Touchscreen interface support" + depends on TOUCHSCREEN_WM97XX + help + Say Y here if you have a Wolfson Microelectronics WM9712 + touchscreen controller connected to your system. + + If unsure, say N. + config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 5829a435efd1..eb57f66e57f3 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o +wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c new file mode 100644 index 000000000000..0b6e4cfa6a21 --- /dev/null +++ b/drivers/input/touchscreen/wm9712.c @@ -0,0 +1,462 @@ +/* + * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. + * + * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton + * Andrew Zabolotny + * Russell King + * + * 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 + +#define TS_NAME "wm97xx" +#define WM9712_VERSION "1.00" +#define DEFAULT_PRESSURE 0xb0c0 + +/* + * Module parameters + */ + +/* + * Set internal pull up for pen detect. + * + * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) + * i.e. pull up resistance = 64k Ohms / rpu. + * + * Adjust this value if you are having problems with pen detect not + * detecting any down event. + */ +static int rpu = 8; +module_param(rpu, int, 0); +MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); + +/* + * Set current used for pressure measurement. + * + * Set pil = 2 to use 400uA + * pil = 1 to use 200uA and + * pil = 0 to disable pressure measurement. + * + * This is used to increase the range of values returned by the adc + * when measureing touchpanel pressure. + */ +static int pil; +module_param(pil, int, 0); +MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); + +/* + * Set threshold for pressure measurement. + * + * Pen down pressure below threshold is ignored. + */ +static int pressure = DEFAULT_PRESSURE & 0xfff; +module_param(pressure, int, 0); +MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); + +/* + * Set adc sample delay. + * + * For accurate touchpanel measurements, some settling time may be + * required between the switch matrix applying a voltage across the + * touchpanel plate and the ADC sampling the signal. + * + * This delay can be set by setting delay = n, where n is the array + * position of the delay in the array delay_table below. + * Long delays > 1ms are supported for completeness, but are not + * recommended. + */ +static int delay = 3; +module_param(delay, int, 0); +MODULE_PARM_DESC(delay, "Set adc sample delay."); + +/* + * Set five_wire = 1 to use a 5 wire touchscreen. + * + * NOTE: Five wire mode does not allow for readback of pressure. + */ +static int five_wire; +module_param(five_wire, int, 0); +MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen."); + +/* + * Set adc mask function. + * + * Sources of glitch noise, such as signals driving an LCD display, may feed + * through to the touch screen plates and affect measurement accuracy. In + * order to minimise this, a signal may be applied to the MASK pin to delay or + * synchronise the sampling. + * + * 0 = No delay or sync + * 1 = High on pin stops conversions + * 2 = Edge triggered, edge on pin delays conversion by delay param (above) + * 3 = Edge triggered, edge on pin starts conversion after delay param + */ +static int mask; +module_param(mask, int, 0); +MODULE_PARM_DESC(mask, "Set adc mask function."); + +/* + * Coordinate Polling Enable. + * + * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together + * for every poll. + */ +static int coord; +module_param(coord, int, 0); +MODULE_PARM_DESC(coord, "Polling coordinate mode"); + +/* + * ADC sample delay times in uS + */ +static const int delay_table[] = { + 21, /* 1 AC97 Link frames */ + 42, /* 2 */ + 84, /* 4 */ + 167, /* 8 */ + 333, /* 16 */ + 667, /* 32 */ + 1000, /* 48 */ + 1333, /* 64 */ + 2000, /* 96 */ + 2667, /* 128 */ + 3333, /* 160 */ + 4000, /* 192 */ + 4667, /* 224 */ + 5333, /* 256 */ + 6000, /* 288 */ + 0 /* No delay, switch matrix always on */ +}; + +/* + * Delay after issuing a POLL command. + * + * The delay is 3 AC97 link frames + the touchpanel settling delay + */ +static inline void poll_delay(int d) +{ + udelay(3 * AC97_LINK_FRAME + delay_table[d]); +} + +/* + * set up the physical settings of the WM9712 + */ +static void wm9712_phy_init(struct wm97xx *wm) +{ + u16 dig1 = 0; + u16 dig2 = WM97XX_RPR | WM9712_RPU(1); + + /* WM9712 rpu */ + if (rpu) { + dig2 &= 0xffc0; + dig2 |= WM9712_RPU(rpu); + dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms", + 64000 / rpu); + } + + /* touchpanel pressure current*/ + if (pil == 2) { + dig2 |= WM9712_PIL; + dev_dbg(wm->dev, + "setting pressure measurement current to 400uA."); + } else if (pil) + dev_dbg(wm->dev, + "setting pressure measurement current to 200uA."); + if (!pil) + pressure = 0; + + /* WM9712 five wire */ + if (five_wire) { + dig2 |= WM9712_45W; + dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); + } + + /* polling mode sample settling delay */ + if (delay < 0 || delay > 15) { + dev_dbg(wm->dev, "supplied delay out of range."); + delay = 4; + } + dig1 &= 0xff0f; + dig1 |= WM97XX_DELAY(delay); + dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.", + delay_table[delay]); + + /* mask */ + dig2 |= ((mask & 0x3) << 6); + if (mask) { + u16 reg; + /* Set GPIO4 as Mask Pin*/ + reg = wm97xx_reg_read(wm, AC97_MISC_AFE); + wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4); + reg = wm97xx_reg_read(wm, AC97_GPIO_CFG); + wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4); + } + + /* wait - coord mode */ + if (coord) + dig2 |= WM9712_WAIT; + + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); +} + +static void wm9712_dig_enable(struct wm97xx *wm, int enable) +{ + u16 dig2 = wm->dig[2]; + + if (enable) { + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, + dig2 | WM97XX_PRP_DET_DIG); + wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ + } else + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, + dig2 & ~WM97XX_PRP_DET_DIG); +} + +static void wm9712_aux_prepare(struct wm97xx *wm) +{ + memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG); +} + +static void wm9712_dig_restore(struct wm97xx *wm) +{ + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]); +} + +static inline int is_pden(struct wm97xx *wm) +{ + return wm->dig[2] & WM9712_PDEN; +} + +/* + * Read a sample from the WM9712 adc in polling mode. + */ +static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) +{ + int timeout = 5 * delay; + + if (!wm->pen_probably_down) { + u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(data & WM97XX_PEN_DOWN)) + return RC_PENUP; + wm->pen_probably_down = 1; + } + + /* set up digitiser */ + if (adcsel & 0x8000) + adcsel = ((adcsel & 0x7fff) + 3) << 12; + + if (wm->mach_ops && wm->mach_ops->pre_sample) + wm->mach_ops->pre_sample(adcsel); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, + adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); + + /* wait 3 AC97 time slots + delay for conversion */ + poll_delay(delay); + + /* wait for POLL to go low */ + while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) + && timeout) { + udelay(AC97_LINK_FRAME); + timeout--; + } + + if (timeout <= 0) { + /* If PDEN is set, we can get a timeout when pen goes up */ + if (is_pden(wm)) + wm->pen_probably_down = 0; + else + dev_dbg(wm->dev, "adc sample timeout"); + return RC_PENUP; + } + + *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (wm->mach_ops && wm->mach_ops->post_sample) + wm->mach_ops->post_sample(adcsel); + + /* check we have correct sample */ + if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { + dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, + *sample & WM97XX_ADCSEL_MASK); + return RC_PENUP; + } + + if (!(*sample & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } + + return RC_VALID; +} + +/* + * Read a coord from the WM9712 adc in polling mode. + */ +static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) +{ + int timeout = 5 * delay; + + if (!wm->pen_probably_down) { + u16 data_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(data_rd & WM97XX_PEN_DOWN)) + return RC_PENUP; + wm->pen_probably_down = 1; + } + + /* set up digitiser */ + if (wm->mach_ops && wm->mach_ops->pre_sample) + wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); + + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, + WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay)); + + /* wait 3 AC97 time slots + delay for conversion and read x */ + poll_delay(delay); + data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + /* wait for POLL to go low */ + while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL) + && timeout) { + udelay(AC97_LINK_FRAME); + timeout--; + } + + if (timeout <= 0) { + /* If PDEN is set, we can get a timeout when pen goes up */ + if (is_pden(wm)) + wm->pen_probably_down = 0; + else + dev_dbg(wm->dev, "adc sample timeout"); + return RC_PENUP; + } + + /* read back y data */ + data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (pil) + data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + else + data->p = DEFAULT_PRESSURE; + + if (wm->mach_ops && wm->mach_ops->post_sample) + wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); + + /* check we have correct sample */ + if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) + goto err; + if (pil && !(data->p & WM97XX_ADCSEL_PRES)) + goto err; + + if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } + return RC_VALID; +err: + return 0; +} + +/* + * Sample the WM9712 touchscreen in polling mode + */ +static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) +{ + int rc; + + if (coord) { + rc = wm9712_poll_coord(wm, data); + if (rc != RC_VALID) + return rc; + } else { + rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); + if (rc != RC_VALID) + return rc; + + rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); + if (rc != RC_VALID) + return rc; + + if (pil && !five_wire) { + rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, + &data->p); + if (rc != RC_VALID) + return rc; + } else + data->p = DEFAULT_PRESSURE; + } + return RC_VALID; +} + +/* + * Enable WM9712 continuous mode, i.e. touch data is streamed across + * an AC97 slot + */ +static int wm9712_acc_enable(struct wm97xx *wm, int enable) +{ + u16 dig1, dig2; + int ret = 0; + + dig1 = wm->dig[1]; + dig2 = wm->dig[2]; + + if (enable) { + /* continous mode */ + if (wm->mach_ops->acc_startup) { + ret = wm->mach_ops->acc_startup(wm); + if (ret < 0) + return ret; + } + dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK | + WM97XX_DELAY_MASK | WM97XX_SLT_MASK); + dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN | + WM97XX_DELAY(delay) | + WM97XX_SLT(wm->acc_slot) | + WM97XX_RATE(wm->acc_rate); + if (pil) + dig1 |= WM97XX_ADCSEL_PRES; + dig2 |= WM9712_PDEN; + } else { + dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN); + dig2 &= ~WM9712_PDEN; + if (wm->mach_ops->acc_shutdown) + wm->mach_ops->acc_shutdown(wm); + } + + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1); + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2); + + return 0; +} + +struct wm97xx_codec_drv wm9712_codec = { + .id = WM9712_ID2, + .name = "wm9712", + .poll_sample = wm9712_poll_sample, + .poll_touch = wm9712_poll_touch, + .acc_enable = wm9712_acc_enable, + .phy_init = wm9712_phy_init, + .dig_enable = wm9712_dig_enable, + .dig_restore = wm9712_dig_restore, + .aux_prepare = wm9712_aux_prepare, +}; +EXPORT_SYMBOL_GPL(wm9712_codec); + +/* Module information */ +MODULE_AUTHOR("Liam Girdwood "); +MODULE_DESCRIPTION("WM9712 Touch Screen Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From dca98e91fb83a43fc430893f349fd8248fa0ba38 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Apr 2008 00:51:30 -0400 Subject: Input: WM97xx - add chip driver for WM97123 touchscreen Signed-off-by: Liam Girdwood Signed-off-by: Graeme Gregory Signed-off-by: Mike Arthur Signed-off-by: Mark Brown Signed-off-by: Lars Munch Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/wm9713.c | 460 +++++++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 drivers/input/touchscreen/wm9713.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 240e441c118a..f6e8dad9726b 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -217,6 +217,15 @@ config TOUCHSCREEN_WM9712 If unsure, say N. +config TOUCHSCREEN_WM9713 + bool "WM9713 Touchscreen interface support" + depends on TOUCHSCREEN_WM97XX + help + Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen + controller connected to your system. + + If unsure, say N. + config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index eb57f66e57f3..f1bc82941cc6 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o +wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c new file mode 100644 index 000000000000..01278bd7e65c --- /dev/null +++ b/drivers/input/touchscreen/wm9713.c @@ -0,0 +1,460 @@ +/* + * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec. + * + * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton + * Andrew Zabolotny + * Russell King + * + * 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 + +#define TS_NAME "wm97xx" +#define WM9713_VERSION "1.00" +#define DEFAULT_PRESSURE 0xb0c0 + +/* + * Module parameters + */ + +/* + * Set internal pull up for pen detect. + * + * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive) + * i.e. pull up resistance = 64k Ohms / rpu. + * + * Adjust this value if you are having problems with pen detect not + * detecting any down event. + */ +static int rpu = 8; +module_param(rpu, int, 0); +MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); + +/* + * Set current used for pressure measurement. + * + * Set pil = 2 to use 400uA + * pil = 1 to use 200uA and + * pil = 0 to disable pressure measurement. + * + * This is used to increase the range of values returned by the adc + * when measureing touchpanel pressure. + */ +static int pil; +module_param(pil, int, 0); +MODULE_PARM_DESC(pil, "Set current used for pressure measurement."); + +/* + * Set threshold for pressure measurement. + * + * Pen down pressure below threshold is ignored. + */ +static int pressure = DEFAULT_PRESSURE & 0xfff; +module_param(pressure, int, 0); +MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement."); + +/* + * Set adc sample delay. + * + * For accurate touchpanel measurements, some settling time may be + * required between the switch matrix applying a voltage across the + * touchpanel plate and the ADC sampling the signal. + * + * This delay can be set by setting delay = n, where n is the array + * position of the delay in the array delay_table below. + * Long delays > 1ms are supported for completeness, but are not + * recommended. + */ +static int delay = 4; +module_param(delay, int, 0); +MODULE_PARM_DESC(delay, "Set adc sample delay."); + +/* + * Set adc mask function. + * + * Sources of glitch noise, such as signals driving an LCD display, may feed + * through to the touch screen plates and affect measurement accuracy. In + * order to minimise this, a signal may be applied to the MASK pin to delay or + * synchronise the sampling. + * + * 0 = No delay or sync + * 1 = High on pin stops conversions + * 2 = Edge triggered, edge on pin delays conversion by delay param (above) + * 3 = Edge triggered, edge on pin starts conversion after delay param + */ +static int mask; +module_param(mask, int, 0); +MODULE_PARM_DESC(mask, "Set adc mask function."); + +/* + * Coordinate Polling Enable. + * + * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together + * for every poll. + */ +static int coord; +module_param(coord, int, 0); +MODULE_PARM_DESC(coord, "Polling coordinate mode"); + +/* + * ADC sample delay times in uS + */ +static const int delay_table[] = { + 21, /* 1 AC97 Link frames */ + 42, /* 2 */ + 84, /* 4 */ + 167, /* 8 */ + 333, /* 16 */ + 667, /* 32 */ + 1000, /* 48 */ + 1333, /* 64 */ + 2000, /* 96 */ + 2667, /* 128 */ + 3333, /* 160 */ + 4000, /* 192 */ + 4667, /* 224 */ + 5333, /* 256 */ + 6000, /* 288 */ + 0 /* No delay, switch matrix always on */ +}; + +/* + * Delay after issuing a POLL command. + * + * The delay is 3 AC97 link frames + the touchpanel settling delay + */ +static inline void poll_delay(int d) +{ + udelay(3 * AC97_LINK_FRAME + delay_table[d]); +} + +/* + * set up the physical settings of the WM9713 + */ +static void wm9713_phy_init(struct wm97xx *wm) +{ + u16 dig1 = 0, dig2, dig3; + + /* default values */ + dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5); + dig3 = WM9712_RPU(1); + + /* rpu */ + if (rpu) { + dig3 &= 0xffc0; + dig3 |= WM9712_RPU(rpu); + dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n", + 64000 / rpu); + } + + /* touchpanel pressure */ + if (pil == 2) { + dig3 |= WM9712_PIL; + dev_info(wm->dev, + "setting pressure measurement current to 400uA."); + } else if (pil) + dev_info(wm->dev, + "setting pressure measurement current to 200uA."); + if (!pil) + pressure = 0; + + /* sample settling delay */ + if (delay < 0 || delay > 15) { + dev_info(wm->dev, "supplied delay out of range."); + delay = 4; + dev_info(wm->dev, "setting adc sample delay to %d u Secs.", + delay_table[delay]); + } + dig2 &= 0xff0f; + dig2 |= WM97XX_DELAY(delay); + + /* mask */ + dig3 |= ((mask & 0x3) << 4); + if (coord) + dig3 |= WM9713_WAIT; + + wm->misc = wm97xx_reg_read(wm, 0x5a); + + wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); + wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); + wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0); +} + +static void wm9713_dig_enable(struct wm97xx *wm, int enable) +{ + u16 val; + + if (enable) { + val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); + wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] | + WM97XX_PRP_DET_DIG); + wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */ + } else { + wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] & + ~WM97XX_PRP_DET_DIG); + val = wm97xx_reg_read(wm, AC97_EXTENDED_MID); + wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000); + } +} + +static void wm9713_dig_restore(struct wm97xx *wm) +{ + wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]); + wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]); +} + +static void wm9713_aux_prepare(struct wm97xx *wm) +{ + memcpy(wm->dig_save, wm->dig, sizeof(wm->dig)); + wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0); + wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG); +} + +static inline int is_pden(struct wm97xx *wm) +{ + return wm->dig[2] & WM9713_PDEN; +} + +/* + * Read a sample from the WM9713 adc in polling mode. + */ +static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) +{ + u16 dig1; + int timeout = 5 * delay; + + if (!wm->pen_probably_down) { + u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(data & WM97XX_PEN_DOWN)) + return RC_PENUP; + wm->pen_probably_down = 1; + } + + /* set up digitiser */ + if (adcsel & 0x8000) + adcsel = 1 << ((adcsel & 0x7fff) + 3); + + dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); + dig1 &= ~WM9713_ADCSEL_MASK; + + if (wm->mach_ops && wm->mach_ops->pre_sample) + wm->mach_ops->pre_sample(adcsel); + wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL); + + /* wait 3 AC97 time slots + delay for conversion */ + poll_delay(delay); + + /* wait for POLL to go low */ + while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) && + timeout) { + udelay(AC97_LINK_FRAME); + timeout--; + } + + if (timeout <= 0) { + /* If PDEN is set, we can get a timeout when pen goes up */ + if (is_pden(wm)) + wm->pen_probably_down = 0; + else + dev_dbg(wm->dev, "adc sample timeout"); + return RC_PENUP; + } + + *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (wm->mach_ops && wm->mach_ops->post_sample) + wm->mach_ops->post_sample(adcsel); + + /* check we have correct sample */ + if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) { + dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, + *sample & WM97XX_ADCSRC_MASK); + return RC_PENUP; + } + + if (!(*sample & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } + + return RC_VALID; +} + +/* + * Read a coordinate from the WM9713 adc in polling mode. + */ +static int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data) +{ + u16 dig1; + int timeout = 5 * delay; + + if (!wm->pen_probably_down) { + u16 val = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (!(val & WM97XX_PEN_DOWN)) + return RC_PENUP; + wm->pen_probably_down = 1; + } + + /* set up digitiser */ + dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); + dig1 &= ~WM9713_ADCSEL_MASK; + if (pil) + dig1 |= WM9713_ADCSEL_PRES; + + if (wm->mach_ops && wm->mach_ops->pre_sample) + wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); + wm97xx_reg_write(wm, AC97_WM9713_DIG1, + dig1 | WM9713_POLL | WM9713_COO); + + /* wait 3 AC97 time slots + delay for conversion */ + poll_delay(delay); + data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + /* wait for POLL to go low */ + while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) + && timeout) { + udelay(AC97_LINK_FRAME); + timeout--; + } + + if (timeout <= 0) { + /* If PDEN is set, we can get a timeout when pen goes up */ + if (is_pden(wm)) + wm->pen_probably_down = 0; + else + dev_dbg(wm->dev, "adc sample timeout"); + return RC_PENUP; + } + + /* read back data */ + data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + if (pil) + data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + else + data->p = DEFAULT_PRESSURE; + + if (wm->mach_ops && wm->mach_ops->post_sample) + wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y); + + /* check we have correct sample */ + if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y)) + goto err; + if (pil && !(data->p & WM97XX_ADCSEL_PRES)) + goto err; + + if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) { + wm->pen_probably_down = 0; + return RC_PENUP; + } + return RC_VALID; +err: + return 0; +} + +/* + * Sample the WM9713 touchscreen in polling mode + */ +static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) +{ + int rc; + + if (coord) { + rc = wm9713_poll_coord(wm, data); + if (rc != RC_VALID) + return rc; + } else { + rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); + if (rc != RC_VALID) + return rc; + rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); + if (rc != RC_VALID) + return rc; + if (pil) { + rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, + &data->p); + if (rc != RC_VALID) + return rc; + } else + data->p = DEFAULT_PRESSURE; + } + return RC_VALID; +} + +/* + * Enable WM9713 continuous mode, i.e. touch data is streamed across + * an AC97 slot + */ +static int wm9713_acc_enable(struct wm97xx *wm, int enable) +{ + u16 dig1, dig2, dig3; + int ret = 0; + + dig1 = wm->dig[0]; + dig2 = wm->dig[1]; + dig3 = wm->dig[2]; + + if (enable) { + /* continous mode */ + if (wm->mach_ops->acc_startup && + (ret = wm->mach_ops->acc_startup(wm)) < 0) + return ret; + + dig1 &= ~WM9713_ADCSEL_MASK; + dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X | + WM9713_ADCSEL_Y; + if (pil) + dig1 |= WM9713_ADCSEL_PRES; + dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK | + WM97XX_CM_RATE_MASK); + dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) | + WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate); + dig3 |= WM9713_PDEN; + } else { + dig1 &= ~(WM9713_CTC | WM9713_COO); + dig2 &= ~WM97XX_SLEN; + dig3 &= ~WM9713_PDEN; + if (wm->mach_ops->acc_shutdown) + wm->mach_ops->acc_shutdown(wm); + } + + wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1); + wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2); + wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3); + + return ret; +} + +struct wm97xx_codec_drv wm9713_codec = { + .id = WM9713_ID2, + .name = "wm9713", + .poll_sample = wm9713_poll_sample, + .poll_touch = wm9713_poll_touch, + .acc_enable = wm9713_acc_enable, + .phy_init = wm9713_phy_init, + .dig_enable = wm9713_dig_enable, + .dig_restore = wm9713_dig_restore, + .aux_prepare = wm9713_aux_prepare, +}; +EXPORT_SYMBOL_GPL(wm9713_codec); + +/* Module information */ +MODULE_AUTHOR("Liam Girdwood "); +MODULE_DESCRIPTION("WM9713 Touch Screen Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 4db8a5f21e5149e09949516eef98b78b68880075 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Apr 2008 00:51:46 -0400 Subject: Input: WM97xx - add support for streaming mode on Mainstone Signed-off-by: Liam Girdwood Signed-off-by: Graeme Gregory Signed-off-by: Mike Arthur Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 12 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/mainstone-wm97xx.c | 302 +++++++++++++++++++++++++++ 3 files changed, 315 insertions(+) create mode 100644 drivers/input/touchscreen/mainstone-wm97xx.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index f6e8dad9726b..565ec711c2ee 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -226,6 +226,18 @@ config TOUCHSCREEN_WM9713 If unsure, say N. +config TOUCHSCREEN_WM97XX_MAINSTONE + tristate "WM97xx Mainstone accelerated touch" + depends on TOUCHSCREEN_WM97XX && ARCH_PXA + help + Say Y here for support for streaming mode with WM97xx touchscreens + on Mainstone systems. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called mainstone-wm97xx. + config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index f1bc82941cc6..3c096d75651d 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o +obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c new file mode 100644 index 000000000000..a79f029b91c0 --- /dev/null +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -0,0 +1,302 @@ +/* + * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for + * Wolfson WM97xx AC97 Codecs. + * + * Copyright 2004, 2007 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton + * Andrew Zabolotny + * + * 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. + * + * Notes: + * This is a wm97xx extended touch driver to capture touch + * data in a continuous manner on the Intel XScale archictecture + * + * Features: + * - codecs supported:- WM9705, WM9712, WM9713 + * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION "0.13" + +struct continuous { + u16 id; /* codec id */ + u8 code; /* continuous code */ + u8 reads; /* number of coord reads per read cycle */ + u32 speed; /* number of coords per second */ +}; + +#define WM_READS(sp) ((sp / HZ) + 1) + +static const struct continuous cinfo[] = { + {WM9705_ID2, 0, WM_READS(94), 94}, + {WM9705_ID2, 1, WM_READS(188), 188}, + {WM9705_ID2, 2, WM_READS(375), 375}, + {WM9705_ID2, 3, WM_READS(750), 750}, + {WM9712_ID2, 0, WM_READS(94), 94}, + {WM9712_ID2, 1, WM_READS(188), 188}, + {WM9712_ID2, 2, WM_READS(375), 375}, + {WM9712_ID2, 3, WM_READS(750), 750}, + {WM9713_ID2, 0, WM_READS(94), 94}, + {WM9713_ID2, 1, WM_READS(120), 120}, + {WM9713_ID2, 2, WM_READS(154), 154}, + {WM9713_ID2, 3, WM_READS(188), 188}, +}; + +/* continuous speed index */ +static int sp_idx; +static u16 last, tries; + +/* + * Pen sampling frequency (Hz) in continuous mode. + */ +static int cont_rate = 200; +module_param(cont_rate, int, 0); +MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); + +/* + * Pen down detection. + * + * This driver can either poll or use an interrupt to indicate a pen down + * event. If the irq request fails then it will fall back to polling mode. + */ +static int pen_int; +module_param(pen_int, int, 0); +MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)"); + +/* + * Pressure readback. + * + * Set to 1 to read back pen down pressure + */ +static int pressure; +module_param(pressure, int, 0); +MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); + +/* + * AC97 touch data slot. + * + * Touch screen readback data ac97 slot + */ +static int ac97_touch_slot = 5; +module_param(ac97_touch_slot, int, 0); +MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); + + +/* flush AC97 slot 5 FIFO on pxa machines */ +#ifdef CONFIG_PXA27x +static void wm97xx_acc_pen_up(struct wm97xx *wm) +{ + schedule_timeout_uninterruptible(1); + + while (MISR & (1 << 2)) + MODR; +} +#else +static void wm97xx_acc_pen_up(struct wm97xx *wm) +{ + int count = 16; + schedule_timeout_uninterruptible(1); + + while (count < 16) { + MODR; + count--; + } +} +#endif + +static int wm97xx_acc_pen_down(struct wm97xx *wm) +{ + u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; + int reads = 0; + + /* When the AC97 queue has been drained we need to allow time + * to buffer up samples otherwise we end up spinning polling + * for samples. The controller can't have a suitably low + * threashold set to use the notifications it gives. + */ + schedule_timeout_uninterruptible(1); + + if (tries > 5) { + tries = 0; + return RC_PENUP; + } + + x = MODR; + if (x == last) { + tries++; + return RC_AGAIN; + } + last = x; + do { + if (reads) + x = MODR; + y = MODR; + if (pressure) + p = MODR; + + /* are samples valid */ + if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || + (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || + (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES) + goto up; + + /* coordinate is good */ + tries = 0; + input_report_abs(wm->input_dev, ABS_X, x & 0xfff); + input_report_abs(wm->input_dev, ABS_Y, y & 0xfff); + input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff); + input_sync(wm->input_dev); + reads++; + } while (reads < cinfo[sp_idx].reads); +up: + return RC_PENDOWN | RC_AGAIN; +} + +static int wm97xx_acc_startup(struct wm97xx *wm) +{ + int idx = 0; + + /* check we have a codec */ + if (wm->ac97 == NULL) + return -ENODEV; + + /* Go you big red fire engine */ + for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { + if (wm->id != cinfo[idx].id) + continue; + sp_idx = idx; + if (cont_rate <= cinfo[idx].speed) + break; + } + wm->acc_rate = cinfo[sp_idx].code; + wm->acc_slot = ac97_touch_slot; + dev_info(wm->dev, + "mainstone accelerated touchscreen driver, %d samples/sec\n", + cinfo[sp_idx].speed); + + /* codec specific irq config */ + if (pen_int) { + switch (wm->id) { + case WM9705_ID2: + wm->pen_irq = IRQ_GPIO(4); + set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE); + break; + case WM9712_ID2: + case WM9713_ID2: + /* enable pen down interrupt */ + /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */ + wm->pen_irq = MAINSTONE_AC97_IRQ; + wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, + WM97XX_GPIO_POL_HIGH, + WM97XX_GPIO_STICKY, + WM97XX_GPIO_WAKE); + wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT, + WM97XX_GPIO_POL_HIGH, + WM97XX_GPIO_NOTSTICKY, + WM97XX_GPIO_NOWAKE); + break; + default: + dev_err(wm->dev, + "pen down irq not supported on this device\n"); + pen_int = 0; + break; + } + } + + return 0; +} + +static void wm97xx_acc_shutdown(struct wm97xx *wm) +{ + /* codec specific deconfig */ + if (pen_int) { + switch (wm->id & 0xffff) { + case WM9705_ID2: + wm->pen_irq = 0; + break; + case WM9712_ID2: + case WM9713_ID2: + /* disable interrupt */ + wm->pen_irq = 0; + break; + } + } +} + +static void wm97xx_irq_enable(struct wm97xx *wm, int enable) +{ + if (enable) + enable_irq(wm->pen_irq); + else + disable_irq(wm->pen_irq); +} + +static struct wm97xx_mach_ops mainstone_mach_ops = { + .acc_enabled = 1, + .acc_pen_up = wm97xx_acc_pen_up, + .acc_pen_down = wm97xx_acc_pen_down, + .acc_startup = wm97xx_acc_startup, + .acc_shutdown = wm97xx_acc_shutdown, + .irq_enable = wm97xx_irq_enable, + .irq_gpio = WM97XX_GPIO_2, +}; + +static int mainstone_wm97xx_probe(struct platform_device *pdev) +{ + struct wm97xx *wm = platform_get_drvdata(pdev); + + return wm97xx_register_mach_ops(wm, &mainstone_mach_ops); +} + +static int mainstone_wm97xx_remove(struct platform_device *pdev) +{ + struct wm97xx *wm = platform_get_drvdata(pdev); + + wm97xx_unregister_mach_ops(wm); + return 0; +} + +static struct platform_driver mainstone_wm97xx_driver = { + .probe = mainstone_wm97xx_probe, + .remove = mainstone_wm97xx_remove, + .driver = { + .name = "wm97xx-touch", + }, +}; + +static int __init mainstone_wm97xx_init(void) +{ + return platform_driver_register(&mainstone_wm97xx_driver); +} + +static void __exit mainstone_wm97xx_exit(void) +{ + platform_driver_unregister(&mainstone_wm97xx_driver); +} + +module_init(mainstone_wm97xx_init); +module_exit(mainstone_wm97xx_exit); + +/* Module information */ +MODULE_AUTHOR("Liam Girdwood "); +MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From f23c1d7579211c801494c7a8d6fca12905f7949f Mon Sep 17 00:00:00 2001 From: Tobias Mueller Date: Wed, 2 Apr 2008 10:02:06 -0400 Subject: Input: appletouch - add product IDs for the 4th generation MacBooks Signed-off-by: Tobias Mueller Acked-by: Johannes Berg Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/appletouch.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index b4423a471f02..8dd3942f3022 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -62,6 +62,10 @@ #define GEYSER4_ISO_PRODUCT_ID 0x021B #define GEYSER4_JIS_PRODUCT_ID 0x021C +#define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229 +#define GEYSER4_HF_ISO_PRODUCT_ID 0x022A +#define GEYSER4_HF_JIS_PRODUCT_ID 0x022B + #define ATP_DEVICE(prod) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ @@ -93,6 +97,10 @@ static struct usb_device_id atp_table [] = { { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, + { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) }, + { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) }, + { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) }, + /* Terminating entry */ { } }; @@ -217,7 +225,10 @@ static inline int atp_is_geyser_3(struct atp *dev) (productId == GEYSER3_JIS_PRODUCT_ID) || (productId == GEYSER4_ANSI_PRODUCT_ID) || (productId == GEYSER4_ISO_PRODUCT_ID) || - (productId == GEYSER4_JIS_PRODUCT_ID); + (productId == GEYSER4_JIS_PRODUCT_ID) || + (productId == GEYSER4_HF_ANSI_PRODUCT_ID) || + (productId == GEYSER4_HF_ISO_PRODUCT_ID) || + (productId == GEYSER4_HF_JIS_PRODUCT_ID); } /* -- cgit v1.2.2 From 5550fbaeb3cc88fe2982e9b5351073173d733f30 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Apr 2008 11:22:51 -0400 Subject: Input: tosakbd - fix suspend Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tosakbd.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 3884d1e3f070..a247006757de 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c @@ -52,7 +52,7 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_ struct tosakbd { unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; struct input_dev *input; - + int suspended; spinlock_t lock; /* protect kbd scanning */ struct timer_list timer; }; @@ -133,6 +133,9 @@ static void tosakbd_scankeyboard(struct platform_device *dev) spin_lock_irqsave(&tosakbd->lock, flags); + if (tosakbd->suspended) + goto out; + for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { /* * Discharge the output driver capacitatance @@ -174,6 +177,7 @@ static void tosakbd_scankeyboard(struct platform_device *dev) if (num_pressed) mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); + out: spin_unlock_irqrestore(&tosakbd->lock, flags); } @@ -200,6 +204,7 @@ static irqreturn_t tosakbd_interrupt(int irq, void *__dev) static void tosakbd_timer_callback(unsigned long __dev) { struct platform_device *dev = (struct platform_device *)__dev; + tosakbd_scankeyboard(dev); } @@ -207,6 +212,13 @@ static void tosakbd_timer_callback(unsigned long __dev) static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) { struct tosakbd *tosakbd = platform_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&tosakbd->lock, flags); + PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT); + PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); + tosakbd->suspended = 1; + spin_unlock_irqrestore(&tosakbd->lock, flags); del_timer_sync(&tosakbd->timer); @@ -215,6 +227,9 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) static int tosakbd_resume(struct platform_device *dev) { + struct tosakbd *tosakbd = platform_get_drvdata(dev); + + tosakbd->suspended = 0; tosakbd_scankeyboard(dev); return 0; @@ -365,8 +380,8 @@ fail: return error; } -static int __devexit tosakbd_remove(struct platform_device *dev) { - +static int __devexit tosakbd_remove(struct platform_device *dev) +{ int i; struct tosakbd *tosakbd = platform_get_drvdata(dev); -- cgit v1.2.2 From 8a0f83eacc1bb8899094b17483de95ddf2d8fcc6 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:17:52 -0400 Subject: Input: xpad - match xbox 360 devices with interface info Match Xbox 360 controllers using the interface info, i.e. interface class 255 (Vendor specific), subclass 93 and protocol 1, instead of specifying the device ids individually. As the class is vendor-specific, we have to still match against vendor id as well, though. Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 0380597249bb..8804ad30dae2 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -91,6 +91,7 @@ #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 +#define XTYPE_UNKNOWN 2 static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -138,7 +139,7 @@ static const struct xpad_device { { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } + { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } }; static const signed short xpad_btn[] = { @@ -173,12 +174,20 @@ static const signed short xpad_abs_pad[] = { -1 /* terminating entry */ }; -/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only - * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, - * but we need only one of them. */ +/* Xbox 360 has a vendor-specific class, so we cannot match it with only + * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we + * match against vendor id as well. Also, some Xbox 360 devices have multiple + * interface protocols, we only need protocol 1. */ +#define XPAD_XBOX360_VENDOR(vend) \ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ + .idVendor = (vend), \ + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ + .bInterfaceSubClass = 93, \ + .bInterfaceProtocol = 1 + static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ - { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ + { XPAD_XBOX360_VENDOR(0x045e) }, /* Microsoft X-Box 360 controllers */ { } }; @@ -645,6 +654,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = dpad_to_buttons; + if (xpad->xtype == XTYPE_UNKNOWN) + xpad->xtype = (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC); xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); -- cgit v1.2.2 From a0979923d7c34c9c60d0ee8a533f9502dcfbd42b Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:18:10 -0400 Subject: Input: xpad - fix dpad handling of unknown devices For devices not specifically listed in xpad.c, xpad->dpad_mapping is initially set to MAP_DPAD_UNKNOWN. In xpad_probe() it gets changed to either MAP_DPAD_TO_BUTTONS or MAP_DPAD_TO_AXES, depending on the module parameter dpad_to_buttons. However, MAP_DPAD_UNKNOWN is defined as -1, while the field is u8. This results in actual value of 255, causing the MAP_DPAD_UNKNOWN check in xpad_probe() to fail. Fix that by defining MAP_DPAD_UNKNOWN as 2 instead. Also, setting module parameter dpad_to_buttons to 1 should obviously map dpad to buttons, while the default behaviour (0) should be to map dpad to axes. However, dpad_to_buttons is directly assigned to xpad->dpad_mapping, and as MAP_DPAD_TO_BUTTONS is 0, the actual behaviour is reversed. Fix that by negating dpad_to_buttons in assignment. Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 8804ad30dae2..6288c4f6e3a3 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -87,7 +87,7 @@ but we map them to axes when possible to simplify things */ #define MAP_DPAD_TO_BUTTONS 0 #define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN -1 +#define MAP_DPAD_UNKNOWN 2 #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 @@ -653,7 +653,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->dpad_mapping = xpad_device[i].dpad_mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) - xpad->dpad_mapping = dpad_to_buttons; + xpad->dpad_mapping = !dpad_to_buttons; if (xpad->xtype == XTYPE_UNKNOWN) xpad->xtype = (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC); xpad->dev = input_dev; -- cgit v1.2.2 From 97f09cb53da583cefc1ce2930de8f64b52cfc54b Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:18:23 -0400 Subject: Input: xpad - fix inverted Y and RY axes The commit ae91d10aab2762f81733e9194cb56eff99c8d808 inverted Y and RY axes on xbox360 so that up is positive and down is negative. This is wrong, as axes on game controllers have up as negative per convention. Also, even xpad itself reports HAT0X with up as negative. Fix that by inverting them again. Also, according to http://bugzilla.kernel.org/show_bug.cgi?id=10337 the original xbox controllers also have the Y and RY axes inverted. Fix that by inverting them as well. Cc: Brian Magnuson Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 6288c4f6e3a3..316d98755440 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -236,13 +236,13 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 12))); input_report_abs(dev, ABS_Y, - (__s16) le16_to_cpup((__le16 *)(data + 14))); + ~(__s16) le16_to_cpup((__le16 *)(data + 14))); /* right stick */ input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 16))); input_report_abs(dev, ABS_RY, - (__s16) le16_to_cpup((__le16 *)(data + 18))); + ~(__s16) le16_to_cpup((__le16 *)(data + 18))); /* triggers left/right */ input_report_abs(dev, ABS_Z, data[10]); @@ -330,13 +330,13 @@ static void xpad360_process_packet(struct usb_xpad *xpad, input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 6))); input_report_abs(dev, ABS_Y, - (__s16) le16_to_cpup((__le16 *)(data + 8))); + ~(__s16) le16_to_cpup((__le16 *)(data + 8))); /* right stick */ input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 10))); input_report_abs(dev, ABS_RY, - (__s16) le16_to_cpup((__le16 *)(data + 12))); + ~(__s16) le16_to_cpup((__le16 *)(data + 12))); /* triggers left/right */ input_report_abs(dev, ABS_Z, data[4]); -- cgit v1.2.2 From 8a7ae2a890852b133342a6d72f84b0dac1bc8e8e Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:18:35 -0400 Subject: Input: xpad - add more xbox 360 controller ids Add Mad Catz and 0x0e6f xbox360 controllers which are already found in xpad_device[] table in xpad.c into the vendor id list. Also add Logitech into the vendor list for Logitech Chillstream gamepads. Also add the RedOctane Guitar Hero X-plorer. Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 316d98755440..89524954ab46 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -110,6 +110,7 @@ static const struct xpad_device { { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, @@ -136,6 +137,7 @@ static const struct xpad_device { { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, @@ -188,6 +190,10 @@ static const signed short xpad_abs_pad[] = { static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ { XPAD_XBOX360_VENDOR(0x045e) }, /* Microsoft X-Box 360 controllers */ + { XPAD_XBOX360_VENDOR(0x046d) }, /* Logitech X-Box 360 style controllers */ + { XPAD_XBOX360_VENDOR(0x0738) }, /* Mad Catz X-Box 360 controllers */ + { XPAD_XBOX360_VENDOR(0x0e6f) }, /* 0x0e6f X-Box 360 controllers */ + { XPAD_XBOX360_VENDOR(0x1430) }, /* RedOctane X-Box 360 controllers */ { } }; -- cgit v1.2.2 From fc55e95214f1e8384e48cff88279d16507fa5358 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:18:44 -0400 Subject: Input: xpad - do not report nonexistent buttons for xbox360 The buttons BTN_C and BTN_Z are only used in the original xbox controller, not in xbox360 controller. Therefore only add them to keybit when the controller is a non-360 one. Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 89524954ab46..b48f7051bf30 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -144,12 +144,19 @@ static const struct xpad_device { { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } }; -static const signed short xpad_btn[] = { - BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ +/* buttons shared with xbox and xbox360 */ +static const signed short xpad_common_btn[] = { + BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ -1 /* terminating entry */ }; +/* original xbox controllers only */ +static const signed short xpad_btn[] = { + BTN_C, BTN_Z, /* "analog" buttons */ + -1 /* terminating entry */ +}; + /* only used if MAP_DPAD_TO_BUTTONS */ static const signed short xpad_btn_pad[] = { BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ @@ -679,11 +686,14 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); /* set up buttons */ - for (i = 0; xpad_btn[i] >= 0; i++) - set_bit(xpad_btn[i], input_dev->keybit); + for (i = 0; xpad_common_btn[i] >= 0; i++) + set_bit(xpad_common_btn[i], input_dev->keybit); if (xpad->xtype == XTYPE_XBOX360) for (i = 0; xpad360_btn[i] >= 0; i++) set_bit(xpad360_btn[i], input_dev->keybit); + else + for (i = 0; xpad_btn[i] >= 0; i++) + set_bit(xpad_btn[i], input_dev->keybit); if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) for (i = 0; xpad_btn_pad[i] >= 0; i++) set_bit(xpad_btn_pad[i], input_dev->keybit); -- cgit v1.2.2 From cfbe20106fa00e89c1fb2c74dbff0ba80e0e539d Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:18:57 -0400 Subject: Input: xpad - enable force feedback on xbox 360 controllers only Commit 4994cd8dadcf9d484ab3ec19f3c7c7a4e5353c1c introduced a regression which causes xpad to report force feedback cababilities for non-360 controllers too, even while there is no actual support for those. Fix that by adding a check for XTYPE_XBOX360 to xpad_init_ff(). Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index b48f7051bf30..fd801135eebb 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -499,6 +499,9 @@ static int xpad_play_effect(struct input_dev *dev, void *data, static int xpad_init_ff(struct usb_xpad *xpad) { + if (xpad->xtype != XTYPE_XBOX360) + return 0; + input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); -- cgit v1.2.2 From bf8cb3141884138c2e4a2ecb56300ece6e8020a2 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Thu, 3 Apr 2008 16:19:10 -0400 Subject: Input: xpad - drop obsolete driver versioning The driver version numbers and changelog have not been updated in a long while to reflect actual changes. Remove the version number and add a notice that later changes can be tracked in SCM. Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fd801135eebb..7188eec53cc6 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1,5 +1,5 @@ /* - * X-Box gamepad - v0.0.6 + * X-Box gamepad driver * * Copyright (c) 2002 Marko Friedemann * 2004 Oliver Schwartz , @@ -68,6 +68,8 @@ * - 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 + * + * Later changes can be tracked in SCM. */ #include @@ -77,7 +79,6 @@ #include #include -#define DRIVER_VERSION "v0.0.6" #define DRIVER_AUTHOR "Marko Friedemann " #define DRIVER_DESC "X-Box pad driver" @@ -771,7 +772,7 @@ static int __init usb_xpad_init(void) { int result = usb_register(&xpad_driver); if (result == 0) - info(DRIVER_DESC ":" DRIVER_VERSION); + info(DRIVER_DESC); return result; } -- cgit v1.2.2 From 99de0912be6f384fc31c8e8e7ba0850d0d670385 Mon Sep 17 00:00:00 2001 From: Brian Magnuson Date: Thu, 3 Apr 2008 16:19:23 -0400 Subject: Input: xpad - add support for wireless xbox360 controllers Signed-off-by: Brian Magnuson Signed-off-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 164 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 7188eec53cc6..ebf8303d6f56 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -92,7 +92,8 @@ #define XTYPE_XBOX 0 #define XTYPE_XBOX360 1 -#define XTYPE_UNKNOWN 2 +#define XTYPE_XBOX360W 2 +#define XTYPE_UNKNOWN 3 static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -109,6 +110,7 @@ static const struct xpad_device { { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, @@ -186,22 +188,25 @@ static const signed short xpad_abs_pad[] = { /* Xbox 360 has a vendor-specific class, so we cannot match it with only * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we - * match against vendor id as well. Also, some Xbox 360 devices have multiple - * interface protocols, we only need protocol 1. */ -#define XPAD_XBOX360_VENDOR(vend) \ + * match against vendor id as well. Wired Xbox 360 devices have protocol 1, + * wireless controllers have protocol 129. */ +#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ .idVendor = (vend), \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ .bInterfaceSubClass = 93, \ - .bInterfaceProtocol = 1 + .bInterfaceProtocol = (pr) +#define XPAD_XBOX360_VENDOR(vend) \ + { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ + { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ - { XPAD_XBOX360_VENDOR(0x045e) }, /* Microsoft X-Box 360 controllers */ - { XPAD_XBOX360_VENDOR(0x046d) }, /* Logitech X-Box 360 style controllers */ - { XPAD_XBOX360_VENDOR(0x0738) }, /* Mad Catz X-Box 360 controllers */ - { XPAD_XBOX360_VENDOR(0x0e6f) }, /* 0x0e6f X-Box 360 controllers */ - { XPAD_XBOX360_VENDOR(0x1430) }, /* RedOctane X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ + XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ { } }; @@ -211,10 +216,15 @@ struct usb_xpad { struct input_dev *dev; /* input device interface */ struct usb_device *udev; /* usb device */ + int pad_present; + struct urb *irq_in; /* urb for interrupt in report */ unsigned char *idata; /* input data */ dma_addr_t idata_dma; + struct urb *bulk_out; + unsigned char *bdata; + #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) struct urb *irq_out; /* urb for interrupt out report */ unsigned char *odata; /* output data */ @@ -359,6 +369,39 @@ static void xpad360_process_packet(struct usb_xpad *xpad, input_sync(dev); } +/* + * xpad360w_process_packet + * + * Completes a request by converting the data into events for the + * input subsystem. It is version for xbox 360 wireless controller. + * + * Byte.Bit + * 00.1 - Status change: The controller or headset has connected/disconnected + * Bits 01.7 and 01.6 are valid + * 01.7 - Controller present + * 01.6 - Headset present + * 01.1 - Pad state (Bytes 4+) valid + * + */ + +static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +{ + /* Presence change */ + if (data[0] & 0x08) { + if (data[1] & 0x80) { + xpad->pad_present = 1; + usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); + } else + xpad->pad_present = 0; + } + + /* Valid pad data */ + if (!(data[1] & 0x1)) + return; + + xpad360_process_packet(xpad, cmd, &data[4]); +} + static void xpad_irq_in(struct urb *urb) { struct usb_xpad *xpad = urb->context; @@ -381,10 +424,16 @@ static void xpad_irq_in(struct urb *urb) goto exit; } - if (xpad->xtype == XTYPE_XBOX360) + switch (xpad->xtype) { + case XTYPE_XBOX360: xpad360_process_packet(xpad, 0, xpad->idata); - else + break; + case XTYPE_XBOX360W: + xpad360w_process_packet(xpad, 0, xpad->idata); + break; + default: xpad_process_packet(xpad, 0, xpad->idata); + } exit: retval = usb_submit_urb (urb, GFP_ATOMIC); @@ -422,6 +471,23 @@ exit: __FUNCTION__, retval); } +static void xpad_bulk_out(struct urb *urb) +{ + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + break; + default: + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + } +} + static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; @@ -600,6 +666,10 @@ static int xpad_open(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); + /* URB was submitted in probe */ + if(xpad->xtype == XTYPE_XBOX360W) + return 0; + xpad->irq_in->dev = xpad->udev; if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; @@ -611,7 +681,8 @@ static void xpad_close(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); - usb_kill_urb(xpad->irq_in); + if(xpad->xtype != XTYPE_XBOX360W) + usb_kill_urb(xpad->irq_in); xpad_stop_output(xpad); } @@ -671,8 +742,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = !dpad_to_buttons; - if (xpad->xtype == XTYPE_UNKNOWN) - xpad->xtype = (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC); + if (xpad->xtype == XTYPE_UNKNOWN) { + if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { + if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) + xpad->xtype = XTYPE_XBOX360W; + else + xpad->xtype = XTYPE_XBOX360; + } else + xpad->xtype = XTYPE_XBOX; + } xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); @@ -692,7 +770,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id /* set up buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) set_bit(xpad_common_btn[i], input_dev->keybit); - if (xpad->xtype == XTYPE_XBOX360) + if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) for (i = 0; xpad360_btn[i] >= 0; i++) set_bit(xpad360_btn[i], input_dev->keybit); else @@ -734,8 +812,57 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail4; usb_set_intfdata(intf, xpad); + + /* + * Submit the int URB immediatly rather than waiting for open + * because we get status messages from the device whether + * or not any controllers are attached. In fact, it's + * exactly the message that a controller has arrived that + * we're waiting for. + */ + if (xpad->xtype == XTYPE_XBOX360W) { + xpad->irq_in->dev = xpad->udev; + error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); + if (error) + goto fail4; + + /* + * Setup the message to set the LEDs on the + * controller when it shows up + */ + xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); + if(!xpad->bulk_out) + goto fail5; + + xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); + if(!xpad->bdata) + goto fail6; + + xpad->bdata[2] = 0x08; + switch (intf->cur_altsetting->desc.bInterfaceNumber) { + case 0: + xpad->bdata[3] = 0x42; + break; + case 2: + xpad->bdata[3] = 0x43; + break; + case 4: + xpad->bdata[3] = 0x44; + break; + case 6: + xpad->bdata[3] = 0x45; + } + + ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; + usb_fill_bulk_urb(xpad->bulk_out, udev, + usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), + xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); + } + return 0; + fail6: usb_free_urb(xpad->bulk_out); + fail5: usb_kill_urb(xpad->irq_in); fail4: usb_free_urb(xpad->irq_in); fail3: xpad_deinit_output(xpad); fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); @@ -754,6 +881,11 @@ static void xpad_disconnect(struct usb_interface *intf) xpad_led_disconnect(xpad); input_unregister_device(xpad->dev); xpad_deinit_output(xpad); + if (xpad->xtype == XTYPE_XBOX360W) { + usb_kill_urb(xpad->bulk_out); + usb_free_urb(xpad->bulk_out); + usb_kill_urb(xpad->irq_in); + } usb_free_urb(xpad->irq_in); usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); -- cgit v1.2.2 From 6eae9b0acdb6f03ed87ef882760e0ef8f440dc1a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Apr 2008 16:19:33 -0400 Subject: Input: xpad - don't use GFP_ATOMIC GFP_ATOMIC should not be used when GFP_KERNEL can be used. Signed-off-by: Oliver Neukum Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index ebf8303d6f56..d4d289e75dc2 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -497,7 +497,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) return 0; xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, - GFP_ATOMIC, &xpad->odata_dma ); + GFP_KERNEL, &xpad->odata_dma); if (!xpad->odata) goto fail1; @@ -729,7 +729,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail1; xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, - GFP_ATOMIC, &xpad->idata_dma); + GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) goto fail1; -- cgit v1.2.2 From 76d057ce5a48034c97f604a0a25a87093e072c71 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 4 Apr 2008 15:31:47 -0400 Subject: Input: usbtouchscreen - don't use DMA on stack DMA on the stack is not allowed. The buffer must be kmalloced. Signed-off-by: Oliver Neukum Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 31 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 63f9664a066f..3a0a8ca57076 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -396,9 +396,12 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) { struct usb_device *dev = usbtouch->udev; - int ret; - unsigned char buf[2]; + int ret = -ENOMEM; + unsigned char *buf; + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + goto err_nobuf; /* reset */ buf[0] = buf[1] = 0xFF; ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), @@ -406,9 +409,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); if (ret < 0) - return ret; - if (buf[0] != 0x06 || buf[1] != 0x00) - return -ENODEV; + goto err_out; + if (buf[0] != 0x06 || buf[1] != 0x00) { + ret = -ENODEV; + goto err_out; + } /* set coordinate output rate */ buf[0] = buf[1] = 0xFF; @@ -417,20 +422,22 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); if (ret < 0) - return ret; + goto err_out; if ((buf[0] != 0x06 || buf[1] != 0x00) && - (buf[0] != 0x15 || buf[1] != 0x01)) - return -ENODEV; + (buf[0] != 0x15 || buf[1] != 0x01)) { + ret = -ENODEV; + goto err_out; + } /* start sending data */ ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), TSC10_CMD_DATA1, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (ret < 0) - return ret; - - return 0; +err_out: + kfree(buf); +err_nobuf: + return ret; } -- cgit v1.2.2 From 0beb4f6f294b0f2dde07fa9da9c00abd4f9c8b50 Mon Sep 17 00:00:00 2001 From: Karl Dahlke Date: Tue, 15 Apr 2008 01:30:32 -0400 Subject: Input: put ledstate in the keyboard notifier Led state should be part of the key event, like shiftstate, and not grabbed asynchronously after the fact. [samuel.thibault@ens-lyon.org: various fixes] Signed-off-by: Samuel Thibault Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 4dbd3425e928..59608e341385 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1237,6 +1237,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) } param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + param.ledstate = kbd->ledflagstate; key_map = key_maps[shift_final]; if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { @@ -1285,6 +1286,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) (*k_handler[type])(vc, keysym & 0xff, !down); + param.ledstate = kbd->ledflagstate; atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); if (type != KT_SLOCK) -- cgit v1.2.2 From 9f9439e92a7fb057d31a19636b99e43306192756 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Tue, 15 Apr 2008 01:30:47 -0400 Subject: Input: add PS/2 serio driver for AVR32 devices Add support for the PSIF peripheral on AVR32 AP7 devices. It is implemented as a serio driver and will behave like a serio 8042 device. The driver has been tested with a Dell keyboard capable of running on 3.3 volts and a Logitech mouse on the STK1000 + STK1002 starter kit. The Logitech mouse was hacked by cutting the cord and using a bi-directional voltage converter to get the required 5 volt I/O level. For more information about the PSIF module, see the datasheet for AT32AP700X at http://www.atmel.com/dyn/products/datasheets.asp?family_id=682 Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Dmitry Torokhov --- drivers/input/serio/Kconfig | 10 ++ drivers/input/serio/Makefile | 1 + drivers/input/serio/at32psif.c | 375 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 386 insertions(+) create mode 100644 drivers/input/serio/at32psif.c (limited to 'drivers') diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index b88569e21d60..ec4b6610f730 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -88,6 +88,16 @@ config SERIO_RPCKBD To compile this driver as a module, choose M here: the module will be called rpckbd. +config SERIO_AT32PSIF + tristate "AVR32 PSIF PS/2 keyboard and mouse controller" + depends on AVR32 + help + Say Y here if you want to use the PSIF peripheral on AVR32 devices + and connect a PS/2 keyboard and/or mouse to it. + + To compile this driver as a module, choose M here: the module will + be called at32psif. + config SERIO_AMBAKMI tristate "AMBA KMI keyboard controller" depends on ARM_AMBA diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 4155197867a3..38b886887cbc 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o +obj-$(CONFIG_SERIO_AT32PSIF) += at32psif.o obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o obj-$(CONFIG_HP_SDC) += hp_sdc.o diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c new file mode 100644 index 000000000000..c267588f7308 --- /dev/null +++ b/drivers/input/serio/at32psif.c @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2007 Atmel Corporation + * + * Driver for the AT32AP700X PS/2 controller (PSIF). + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PSIF register offsets */ +#define PSIF_CR 0x00 +#define PSIF_RHR 0x04 +#define PSIF_THR 0x08 +#define PSIF_SR 0x10 +#define PSIF_IER 0x14 +#define PSIF_IDR 0x18 +#define PSIF_IMR 0x1c +#define PSIF_PSR 0x24 + +/* Bitfields in control register. */ +#define PSIF_CR_RXDIS_OFFSET 1 +#define PSIF_CR_RXDIS_SIZE 1 +#define PSIF_CR_RXEN_OFFSET 0 +#define PSIF_CR_RXEN_SIZE 1 +#define PSIF_CR_SWRST_OFFSET 15 +#define PSIF_CR_SWRST_SIZE 1 +#define PSIF_CR_TXDIS_OFFSET 9 +#define PSIF_CR_TXDIS_SIZE 1 +#define PSIF_CR_TXEN_OFFSET 8 +#define PSIF_CR_TXEN_SIZE 1 + +/* Bitfields in interrupt disable, enable, mask and status register. */ +#define PSIF_NACK_OFFSET 8 +#define PSIF_NACK_SIZE 1 +#define PSIF_OVRUN_OFFSET 5 +#define PSIF_OVRUN_SIZE 1 +#define PSIF_PARITY_OFFSET 9 +#define PSIF_PARITY_SIZE 1 +#define PSIF_RXRDY_OFFSET 4 +#define PSIF_RXRDY_SIZE 1 +#define PSIF_TXEMPTY_OFFSET 1 +#define PSIF_TXEMPTY_SIZE 1 +#define PSIF_TXRDY_OFFSET 0 +#define PSIF_TXRDY_SIZE 1 + +/* Bitfields in prescale register. */ +#define PSIF_PSR_PRSCV_OFFSET 0 +#define PSIF_PSR_PRSCV_SIZE 12 + +/* Bitfields in receive hold register. */ +#define PSIF_RHR_RXDATA_OFFSET 0 +#define PSIF_RHR_RXDATA_SIZE 8 + +/* Bitfields in transmit hold register. */ +#define PSIF_THR_TXDATA_OFFSET 0 +#define PSIF_THR_TXDATA_SIZE 8 + +/* Bit manipulation macros */ +#define PSIF_BIT(name) \ + (1 << PSIF_##name##_OFFSET) + +#define PSIF_BF(name, value) \ + (((value) & ((1 << PSIF_##name##_SIZE) - 1)) \ + << PSIF_##name##_OFFSET) + +#define PSIF_BFEXT(name, value) \ + (((value) >> PSIF_##name##_OFFSET) \ + & ((1 << PSIF_##name##_SIZE) - 1)) + +#define PSIF_BFINS(name, value, old) \ + (((old) & ~(((1 << PSIF_##name##_SIZE) - 1) \ + << PSIF_##name##_OFFSET)) \ + | PSIF_BF(name, value)) + +/* Register access macros */ +#define psif_readl(port, reg) \ + __raw_readl((port)->regs + PSIF_##reg) + +#define psif_writel(port, reg, value) \ + __raw_writel((value), (port)->regs + PSIF_##reg) + +struct psif { + struct platform_device *pdev; + struct clk *pclk; + struct serio *io; + void __iomem *regs; + unsigned int irq; + unsigned int open; + /* Prevent concurrent writes to PSIF THR. */ + spinlock_t lock; +}; + +static irqreturn_t psif_interrupt(int irq, void *_ptr) +{ + struct psif *psif = _ptr; + int retval = IRQ_NONE; + unsigned int io_flags = 0; + unsigned long status; + + status = psif_readl(psif, SR); + + if (status & PSIF_BIT(RXRDY)) { + unsigned char val = (unsigned char) psif_readl(psif, RHR); + + if (status & PSIF_BIT(PARITY)) + io_flags |= SERIO_PARITY; + if (status & PSIF_BIT(OVRUN)) + dev_err(&psif->pdev->dev, "overrun read error\n"); + + serio_interrupt(psif->io, val, io_flags); + + retval = IRQ_HANDLED; + } + + return retval; +} + +static int psif_write(struct serio *io, unsigned char val) +{ + struct psif *psif = io->port_data; + unsigned long flags; + int timeout = 10; + int retval = 0; + + spin_lock_irqsave(&psif->lock, flags); + + while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) + msleep(10); + + if (timeout >= 0) { + psif_writel(psif, THR, val); + } else { + dev_dbg(&psif->pdev->dev, "timeout writing to THR\n"); + retval = -EBUSY; + } + + spin_unlock_irqrestore(&psif->lock, flags); + + return retval; +} + +static int psif_open(struct serio *io) +{ + struct psif *psif = io->port_data; + int retval; + + retval = clk_enable(psif->pclk); + if (retval) + goto out; + + psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); + psif_writel(psif, IER, PSIF_BIT(RXRDY)); + + psif->open = 1; +out: + return retval; +} + +static void psif_close(struct serio *io) +{ + struct psif *psif = io->port_data; + + psif->open = 0; + + psif_writel(psif, IDR, ~0UL); + psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); + + clk_disable(psif->pclk); +} + +static void psif_set_prescaler(struct psif *psif) +{ + unsigned long prscv; + unsigned long rate = clk_get_rate(psif->pclk); + + /* PRSCV = Pulse length (100 us) * PSIF module frequency. */ + prscv = 100 * (rate / 1000000UL); + + if (prscv > ((1<pdev->dev, "pclk too fast, " + "prescaler set to max\n"); + } + + clk_enable(psif->pclk); + psif_writel(psif, PSR, prscv); + clk_disable(psif->pclk); +} + +static int __init psif_probe(struct platform_device *pdev) +{ + struct resource *regs; + struct psif *psif; + struct serio *io; + struct clk *pclk; + int irq; + int ret; + + psif = kzalloc(sizeof(struct psif), GFP_KERNEL); + if (!psif) { + dev_dbg(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto out; + } + psif->pdev = pdev; + + io = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!io) { + dev_dbg(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto out_free_psif; + } + psif->io = io; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_dbg(&pdev->dev, "no mmio resources defined\n"); + ret = -ENOMEM; + goto out_free_io; + } + + psif->regs = ioremap(regs->start, regs->end - regs->start + 1); + if (!psif->regs) { + ret = -ENOMEM; + dev_dbg(&pdev->dev, "could not map I/O memory\n"); + goto out_free_io; + } + + pclk = clk_get(&pdev->dev, "pclk"); + if (IS_ERR(pclk)) { + dev_dbg(&pdev->dev, "could not get peripheral clock\n"); + ret = PTR_ERR(pclk); + goto out_iounmap; + } + psif->pclk = pclk; + + /* Reset the PSIF to enter at a known state. */ + ret = clk_enable(pclk); + if (ret) { + dev_dbg(&pdev->dev, "could not enable pclk\n"); + goto out_put_clk; + } + psif_writel(psif, CR, PSIF_BIT(CR_SWRST)); + clk_disable(pclk); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_dbg(&pdev->dev, "could not get irq\n"); + ret = -ENXIO; + goto out_put_clk; + } + ret = request_irq(irq, psif_interrupt, IRQF_SHARED, "at32psif", psif); + if (ret) { + dev_dbg(&pdev->dev, "could not request irq %d\n", irq); + goto out_put_clk; + } + psif->irq = irq; + + io->id.type = SERIO_8042; + io->write = psif_write; + io->open = psif_open; + io->close = psif_close; + snprintf(io->name, sizeof(io->name), "AVR32 PS/2 port%d", pdev->id); + snprintf(io->phys, sizeof(io->phys), "at32psif/serio%d", pdev->id); + io->port_data = psif; + io->dev.parent = &pdev->dev; + + psif_set_prescaler(psif); + + spin_lock_init(&psif->lock); + serio_register_port(psif->io); + platform_set_drvdata(pdev, psif); + + dev_info(&pdev->dev, "Atmel AVR32 PSIF PS/2 driver on 0x%08x irq %d\n", + (int)psif->regs, psif->irq); + + return 0; + +out_put_clk: + clk_put(psif->pclk); +out_iounmap: + iounmap(psif->regs); +out_free_io: + kfree(io); +out_free_psif: + kfree(psif); +out: + return ret; +} + +static int __exit psif_remove(struct platform_device *pdev) +{ + struct psif *psif = platform_get_drvdata(pdev); + + psif_writel(psif, IDR, ~0UL); + psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); + + serio_unregister_port(psif->io); + iounmap(psif->regs); + free_irq(psif->irq, psif); + clk_put(psif->pclk); + kfree(psif); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM +static int psif_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct psif *psif = platform_get_drvdata(pdev); + + if (psif->open) { + psif_writel(psif, CR, PSIF_BIT(CR_RXDIS) | PSIF_BIT(CR_TXDIS)); + clk_disable(psif->pclk); + } + + return 0; +} + +static int psif_resume(struct platform_device *pdev) +{ + struct psif *psif = platform_get_drvdata(pdev); + + if (psif->open) { + clk_enable(psif->pclk); + psif_set_prescaler(psif); + psif_writel(psif, CR, PSIF_BIT(CR_RXEN) | PSIF_BIT(CR_TXEN)); + } + + return 0; +} +#else +#define psif_suspend NULL +#define psif_resume NULL +#endif + +static struct platform_driver psif_driver = { + .remove = __exit_p(psif_remove), + .driver = { + .name = "atmel_psif", + }, + .suspend = psif_suspend, + .resume = psif_resume, +}; + +static int __init psif_init(void) +{ + return platform_driver_probe(&psif_driver, psif_probe); +} + +static void __exit psif_exit(void) +{ + platform_driver_unregister(&psif_driver); +} + +module_init(psif_init); +module_exit(psif_exit); + +MODULE_AUTHOR("Hans-Christian Egtvedt "); +MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 1164ec1ae43770db6ea5450c6cac0761b11d6d1d Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 15 Apr 2008 01:31:13 -0400 Subject: Input: gpio_keys - irq handling cleanup Cleanup IRQ handling in gpio_keys: bail after handling the IRQ, and report IRQ_NONE if we never handle it. Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 6a9ca4bdcb74..a54dc15f9005 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -43,10 +43,11 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) input_event(input, type, button->code, !!state); input_sync(input); + return IRQ_HANDLED; } } - return IRQ_HANDLED; + return IRQ_NONE; } static int __devinit gpio_keys_probe(struct platform_device *pdev) -- cgit v1.2.2 From da3e4c885e5ebbccc8181f53d8ae74c4c22d506f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 15 Apr 2008 01:31:33 -0400 Subject: Input: omap-keypad - fix build warning Fix the following build warning: drivers/input/keyboard/omap-keypad.c: In function 'omap_kp_probe': drivers/input/keyboard/omap-keypad.c:418: warning: 'row_idx' is used uninitialized in this function drivers/input/keyboard/omap-keypad.c:421: warning: 'col_idx' is used uninitialized in this function These variables are useful when cpu_is_omap24xx(), and otherwise just for useless cleanup. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/omap-keypad.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index babc913d5492..eec328167f8d 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -352,6 +352,9 @@ static int __init omap_kp_probe(struct platform_device *pdev) } omap_set_gpio_direction(row_gpios[row_idx], 1); } + } else { + col_idx = 0; + row_idx = 0; } setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); @@ -415,10 +418,10 @@ err4: err3: device_remove_file(&pdev->dev, &dev_attr_enable); err2: - for (i = row_idx-1; i >=0; i--) + for (i = row_idx - 1; i >=0; i--) omap_free_gpio(row_gpios[i]); err1: - for (i = col_idx-1; i >=0; i--) + for (i = col_idx - 1; i >=0; i--) omap_free_gpio(col_gpios[i]); kfree(omap_kp); -- cgit v1.2.2 From 04021e4e401d7ac2051839dd5b00a701c9119dd9 Mon Sep 17 00:00:00 2001 From: Michael Gruber Date: Tue, 15 Apr 2008 01:31:47 -0400 Subject: Input: xpad - set proper buffer length for outgoing requests The messages for led/rumble are exactly 3 and 8 bytes respectively. Hence set up the transfer_buffer_length accordingly. Signed-off-by: Michael Gruber Acked-by: Anssi Hannula Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d4d289e75dc2..52ddb04644ab 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -558,6 +558,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, xpad->odata[5] = 0x00; xpad->odata[6] = 0x00; xpad->odata[7] = 0x00; + xpad->irq_out->transfer_buffer_length = 8; usb_submit_urb(xpad->irq_out, GFP_KERNEL); } @@ -594,6 +595,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command) xpad->odata[0] = 0x01; xpad->odata[1] = 0x03; xpad->odata[2] = command; + xpad->irq_out->transfer_buffer_length = 3; usb_submit_urb(xpad->irq_out, GFP_KERNEL); mutex_unlock(&xpad->odata_mutex); } -- cgit v1.2.2 From e722409445fbe718f09f6d5e03d0ae84cf0954d0 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 15 Apr 2008 01:31:57 -0400 Subject: Input: wacom - implement suspend and autosuspend This implements suspend and autosuspend support for wacom devices. It works by using the usb last busy functionality triggered in the completion callback. Signed-off-by: Oliver Neukum Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom.h | 3 ++ drivers/input/tablet/wacom_sys.c | 76 ++++++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index acf9830698cb..706619d06f71 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -101,8 +101,11 @@ struct wacom { dma_addr_t data_dma; struct input_dev *dev; struct usb_device *usbdev; + struct usb_interface *intf; struct urb *irq; struct wacom_wac * wacom_wac; + struct mutex lock; + int open:1; char phys[32]; }; diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 41caaef8e2d7..71cc0c140790 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -70,6 +70,7 @@ static void wacom_sys_irq(struct urb *urb) input_sync(get_input_dev(&wcombo)); exit: + usb_mark_last_busy(wacom->usbdev); retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", @@ -124,10 +125,25 @@ static int wacom_open(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + mutex_lock(&wacom->lock); + wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq, GFP_KERNEL)) + + if (usb_autopm_get_interface(wacom->intf) < 0) { + mutex_unlock(&wacom->lock); return -EIO; + } + + if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { + usb_autopm_put_interface(wacom->intf); + mutex_unlock(&wacom->lock); + return -EIO; + } + + wacom->open = 1; + wacom->intf->needs_remote_wakeup = 1; + mutex_unlock(&wacom->lock); return 0; } @@ -135,7 +151,11 @@ static void wacom_close(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + mutex_lock(&wacom->lock); usb_kill_urb(wacom->irq); + wacom->open = 0; + wacom->intf->needs_remote_wakeup = 0; + mutex_unlock(&wacom->lock); } void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) @@ -243,6 +263,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->usbdev = dev; wacom->dev = input_dev; + wacom->intf = intf; + mutex_init(&wacom->lock); usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); @@ -304,23 +326,57 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i static void wacom_disconnect(struct usb_interface *intf) { - struct wacom *wacom = usb_get_intfdata (intf); + struct wacom *wacom = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - if (wacom) { - usb_kill_urb(wacom->irq); - input_unregister_device(wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); - kfree(wacom); - } + + usb_kill_urb(wacom->irq); + input_unregister_device(wacom->dev); + usb_free_urb(wacom->irq); + usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); + kfree(wacom->wacom_wac); + kfree(wacom); +} + +static int wacom_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct wacom *wacom = usb_get_intfdata(intf); + + mutex_lock(&wacom->lock); + usb_kill_urb(wacom->irq); + mutex_unlock(&wacom->lock); + + return 0; +} + +static int wacom_resume(struct usb_interface *intf) +{ + struct wacom *wacom = usb_get_intfdata(intf); + int rv; + + mutex_lock(&wacom->lock); + if (wacom->open) + rv = usb_submit_urb(wacom->irq, GFP_NOIO); + else + rv = 0; + mutex_unlock(&wacom->lock); + + return rv; +} + +static int wacom_reset_resume(struct usb_interface *intf) +{ + return wacom_resume(intf); } static struct usb_driver wacom_driver = { .name = "wacom", .probe = wacom_probe, .disconnect = wacom_disconnect, + .suspend = wacom_suspend, + .resume = wacom_resume, + .reset_resume = wacom_reset_resume, + .supports_autosuspend = 1, }; static int __init wacom_init(void) -- cgit v1.2.2 From a32bcc45b9e9d8021b5936c45dc3f8db7a044466 Mon Sep 17 00:00:00 2001 From: Guryanov Dmitry Date: Mon, 10 Mar 2008 03:08:58 -0700 Subject: Input: aiptek - add support for Genius G-PEN 560 tablet USBHID driver only supports relative mode with this tablet so let aiptek module handle it. Signed-off-by: Dmitry Guryanov Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/hid/usbhid/hid-quirks.c | 4 ++++ drivers/input/tablet/Kconfig | 10 +++++----- drivers/input/tablet/aiptek.c | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index e29a057cbea2..17b2f49675d8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -405,6 +405,9 @@ #define USB_VENDOR_ID_YEALINK 0x6993 #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 +#define USB_VENDOR_ID_KYE 0x0458 +#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 + /* * Alphabetically sorted blacklist by quirk type. */ @@ -703,6 +706,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560, HID_QUIRK_IGNORE }, { 0, 0 } }; diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index d371c0bdc0bd..effb49ea24aa 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig @@ -25,14 +25,14 @@ config TABLET_USB_ACECAD module will be called acecad. config TABLET_USB_AIPTEK - tristate "Aiptek 6000U/8000U tablet support (USB)" + tristate "Aiptek 6000U/8000U and Genius G_PEN tablet support (USB)" depends on USB_ARCH_HAS_HCD select USB help - Say Y here if you want to use the USB version of the Aiptek 6000U - or Aiptek 8000U tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. + Say Y here if you want to use the USB version of the Aiptek 6000U, + Aiptek 8000U or Genius G-PEN 560 tablet. Make sure to say Y to + "Mouse support" (CONFIG_INPUT_MOUSEDEV) and/or "Event interface + support" (CONFIG_INPUT_EVDEV) as well. To compile this driver as a module, choose M here: the module will be called aiptek. diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 94683f58c9e1..1d759f6f8076 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -184,6 +184,7 @@ */ #define USB_VENDOR_ID_AIPTEK 0x08ca +#define USB_VENDOR_ID_KYE 0x0458 #define USB_REQ_GET_REPORT 0x01 #define USB_REQ_SET_REPORT 0x09 @@ -832,6 +833,7 @@ static const struct usb_device_id aiptek_ids[] = { {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)}, {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)}, {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)}, + {USB_DEVICE(USB_VENDOR_ID_KYE, 0x5003)}, {} }; -- cgit v1.2.2 From 3e24e2b5ae03394d9510530f9dd973050fd18730 Mon Sep 17 00:00:00 2001 From: Martin Kebert Date: Mon, 10 Mar 2008 13:40:36 +0100 Subject: Input: add Zhen Hua driver This is a driver for Zhen Hua PPM-4CH RC transmitter (commonly used in cheap Ready To Fly RC helicopters by Walkera) which using "Zhen Hua 5-byte protocol" for using them as a four axis joystick via serial port. Transmitter connected to serial port (19200 8N1) sending periodically 5 bytes where first byte is for synchronization and next four bytes are values of axis. Signed-off-by: Martin Kebert Signed-off-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/Kconfig | 12 ++ drivers/input/joystick/Makefile | 1 + drivers/input/joystick/zhenhua.c | 243 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 drivers/input/joystick/zhenhua.c (limited to 'drivers') diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 7c662ee594a3..be5c14a5a0a4 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -193,6 +193,18 @@ config JOYSTICK_TWIDJOY To compile this driver as a module, choose M here: the module will be called twidjoy. +config JOYSTICK_ZHENHUA + tristate "5-byte Zhenhua RC transmitter" + select SERIO + help + Say Y here if you have a Zhen Hua PPM-4CH transmitter which is + supplied with a ready to fly micro electric indoor helicopters + such as EasyCopter, Lama, MiniCopter, DragonFly or Jabo and want + to use it via serial cable as a joystick. + + To compile this driver as a module, choose M here: the + module will be called zhenhua. + config JOYSTICK_DB9 tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads" depends on PARPORT diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index e855abb0cc51..868b746e757a 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile @@ -27,5 +27,6 @@ obj-$(CONFIG_JOYSTICK_TURBOGRAFX) += turbografx.o obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o +obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c new file mode 100644 index 000000000000..b5853125c898 --- /dev/null +++ b/drivers/input/joystick/zhenhua.c @@ -0,0 +1,243 @@ +/* + * derived from "twidjoy.c" + * + * Copyright (c) 2008 Martin Kebert + * Copyright (c) 2001 Arndt Schoenewald + * Copyright (c) 2000-2001 Vojtech Pavlik + * Copyright (c) 2000 Mark Fletcher + * + */ + +/* + * Driver to use 4CH RC transmitter using Zhen Hua 5-byte protocol (Walkera Lama, + * EasyCopter etc.) as a joystick under Linux. + * + * RC transmitters using Zhen Hua 5-byte protocol are cheap four channels + * transmitters for control a RC planes or RC helicopters with possibility to + * connect on a serial port. + * Data coming from transmitter is in this order: + * 1. byte = synchronisation byte + * 2. byte = X axis + * 3. byte = Y axis + * 4. byte = RZ axis + * 5. byte = Z axis + * (and this is repeated) + * + * For questions or feedback regarding this driver module please contact: + * Martin Kebert - but I am not a C-programmer nor kernel + * coder :-( + */ + +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "RC transmitter with 5-byte Zhen Hua protocol joystick driver" + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/* + * Constants. + */ + +#define ZHENHUA_MAX_LENGTH 5 + +/* + * Zhen Hua data. + */ + +struct zhenhua { + struct input_dev *dev; + int idx; + unsigned char data[ZHENHUA_MAX_LENGTH]; + char phys[32]; +}; + + +/* bits in all incoming bytes needs to be "reversed" */ +static int zhenhua_bitreverse(int x) +{ + x = ((x & 0xaa) >> 1) | ((x & 0x55) << 1); + x = ((x & 0xcc) >> 2) | ((x & 0x33) << 2); + x = ((x & 0xf0) >> 4) | ((x & 0x0f) << 4); + return x; +} + +/* + * zhenhua_process_packet() decodes packets the driver receives from the + * RC transmitter. It updates the data accordingly. + */ + +static void zhenhua_process_packet(struct zhenhua *zhenhua) +{ + struct input_dev *dev = zhenhua->dev; + unsigned char *data = zhenhua->data; + + input_report_abs(dev, ABS_Y, data[1]); + input_report_abs(dev, ABS_X, data[2]); + input_report_abs(dev, ABS_RZ, data[3]); + input_report_abs(dev, ABS_Z, data[4]); + + input_sync(dev); +} + +/* + * zhenhua_interrupt() is called by the low level driver when characters + * are ready for us. We then buffer them for further processing, or call the + * packet processing routine. + */ + +static irqreturn_t zhenhua_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +{ + struct zhenhua *zhenhua = serio_get_drvdata(serio); + + /* All Zhen Hua packets are 5 bytes. The fact that the first byte + * is allways 0xf7 and all others are in range 0x32 - 0xc8 (50-200) + * can be used to check and regain sync. */ + + if (data == 0xef) + zhenhua->idx = 0; /* this byte starts a new packet */ + else if (zhenhua->idx == 0) + return IRQ_HANDLED; /* wrong MSB -- ignore this byte */ + + if (zhenhua->idx < ZHENHUA_MAX_LENGTH) + zhenhua->data[zhenhua->idx++] = zhenhua_bitreverse(data); + + if (zhenhua->idx == ZHENHUA_MAX_LENGTH) { + zhenhua_process_packet(zhenhua); + zhenhua->idx = 0; + } + + return IRQ_HANDLED; +} + +/* + * zhenhua_disconnect() is the opposite of zhenhua_connect() + */ + +static void zhenhua_disconnect(struct serio *serio) +{ + struct zhenhua *zhenhua = serio_get_drvdata(serio); + + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_unregister_device(zhenhua->dev); + kfree(zhenhua); +} + +/* + * zhenhua_connect() is the routine that is called when someone adds a + * new serio device. It looks for the Twiddler, and if found, registers + * it as an input device. + */ + +static int zhenhua_connect(struct serio *serio, struct serio_driver *drv) +{ + struct zhenhua *zhenhua; + struct input_dev *input_dev; + int err = -ENOMEM; + + zhenhua = kzalloc(sizeof(struct zhenhua), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!zhenhua || !input_dev) + goto fail1; + + zhenhua->dev = input_dev; + snprintf(zhenhua->phys, sizeof(zhenhua->phys), "%s/input0", serio->phys); + + input_dev->name = "Zhen Hua 5-byte device"; + input_dev->phys = zhenhua->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_ZHENHUA; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; + + input_dev->evbit[0] = BIT(EV_ABS); + input_set_abs_params(input_dev, ABS_X, 50, 200, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 50, 200, 0, 0); + input_set_abs_params(input_dev, ABS_Z, 50, 200, 0, 0); + input_set_abs_params(input_dev, ABS_RZ, 50, 200, 0, 0); + + serio_set_drvdata(serio, zhenhua); + + err = serio_open(serio, drv); + if (err) + goto fail2; + + err = input_register_device(zhenhua->dev); + if (err) + goto fail3; + + return 0; + + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); + kfree(zhenhua); + return err; +} + +/* + * The serio driver structure. + */ + +static struct serio_device_id zhenhua_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_ZHENHUA, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, zhenhua_serio_ids); + +static struct serio_driver zhenhua_drv = { + .driver = { + .name = "zhenhua", + }, + .description = DRIVER_DESC, + .id_table = zhenhua_serio_ids, + .interrupt = zhenhua_interrupt, + .connect = zhenhua_connect, + .disconnect = zhenhua_disconnect, +}; + +/* + * The functions for inserting/removing us as a module. + */ + +static int __init zhenhua_init(void) +{ + return serio_register_driver(&zhenhua_drv); +} + +static void __exit zhenhua_exit(void) +{ + serio_unregister_driver(&zhenhua_drv); +} + +module_init(zhenhua_init); +module_exit(zhenhua_exit); -- cgit v1.2.2 From a4f0fcdfb2397e81d22446bb364dc190bf16b25a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 12 Feb 2008 13:26:31 +0200 Subject: UBI: be verbose when debuggin is enabled Make I/O function to be always verbose when about CRC errors and magic number errors when I/O debugging is enabled. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 2 ++ drivers/mtd/ubi/io.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 51c40b17f1ec..718740a63eb3 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -99,8 +99,10 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); #ifdef CONFIG_MTD_UBI_DEBUG_MSG_BLD /* Initialization and build messages */ #define dbg_bld(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) +#define UBI_IO_DEBUG 1 #else #define dbg_bld(fmt, ...) ({}) +#define UBI_IO_DEBUG 0 #endif #ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index db3efdef2433..4ac11df7b048 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -631,6 +631,8 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, dbg_io("read EC header from PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + if (UBI_IO_DEBUG) + verbose = 1; err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); if (err) { @@ -904,6 +906,8 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, dbg_io("read VID header from PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + if (UBI_IO_DEBUG) + verbose = 1; p = (char *)vid_hdr - ubi->vid_hdr_shift; err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, -- cgit v1.2.2 From 92a74f1c1c9ca4d8009bfdea1c5febb7c0674f15 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sat, 16 Feb 2008 15:42:52 +0200 Subject: UBI: make ubi-header.h local The new trend in linux is not to store headers which define on-media format in the include/ directory, but instead, store them locally. This is because these headers "do not define any kernel<->userspace interface". Do so for UBI as well. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi-media.h | 372 ++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/ubi.h | 3 +- 2 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 drivers/mtd/ubi/ubi-media.h (limited to 'drivers') diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h new file mode 100644 index 000000000000..c3185d9fd048 --- /dev/null +++ b/drivers/mtd/ubi/ubi-media.h @@ -0,0 +1,372 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (Битюцкий Ðртём) + * Thomas Gleixner + * Frank Haverkamp + * Oliver Lohmann + * Andreas Arnez + */ + +/* + * This file defines the layout of UBI headers and all the other UBI on-flash + * data structures. + */ + +#ifndef __UBI_MEDIA_H__ +#define __UBI_MEDIA_H__ + +#include + +/* The version of UBI images supported by this implementation */ +#define UBI_VERSION 1 + +/* The highest erase counter value supported by this implementation */ +#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF + +/* The initial CRC32 value used when calculating CRC checksums */ +#define UBI_CRC32_INIT 0xFFFFFFFFU + +/* Erase counter header magic number (ASCII "UBI#") */ +#define UBI_EC_HDR_MAGIC 0x55424923 +/* Volume identifier header magic number (ASCII "UBI!") */ +#define UBI_VID_HDR_MAGIC 0x55424921 + +/* + * Volume type constants used in the volume identifier header. + * + * @UBI_VID_DYNAMIC: dynamic volume + * @UBI_VID_STATIC: static volume + */ +enum { + UBI_VID_DYNAMIC = 1, + UBI_VID_STATIC = 2 +}; + +/* + * Volume flags used in the volume table record. + * + * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume + * + * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume + * table. UBI automatically re-sizes the volume which has this flag and makes + * the volume to be of largest possible size. This means that if after the + * initialization UBI finds out that there are available physical eraseblocks + * present on the device, it automatically appends all of them to the volume + * (the physical eraseblocks reserved for bad eraseblocks handling and other + * reserved physical eraseblocks are not taken). So, if there is a volume with + * the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical + * eraseblocks will be zero after UBI is loaded, because all of them will be + * reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared + * after the volume had been initialized. + * + * The auto-resize feature is useful for device production purposes. For + * example, different NAND flash chips may have different amount of initial bad + * eraseblocks, depending of particular chip instance. Manufacturers of NAND + * chips usually guarantee that the amount of initial bad eraseblocks does not + * exceed certain percent, e.g. 2%. When one creates an UBI image which will be + * flashed to the end devices in production, he does not know the exact amount + * of good physical eraseblocks the NAND chip on the device will have, but this + * number is required to calculate the volume sized and put them to the volume + * table of the UBI image. In this case, one of the volumes (e.g., the one + * which will store the root file system) is marked as "auto-resizable", and + * UBI will adjust its size on the first boot if needed. + * + * Note, first UBI reserves some amount of physical eraseblocks for bad + * eraseblock handling, and then re-sizes the volume, not vice-versa. This + * means that the pool of reserved physical eraseblocks will always be present. + */ +enum { + UBI_VTBL_AUTORESIZE_FLG = 0x01, +}; + +/* + * Compatibility constants used by internal volumes. + * + * @UBI_COMPAT_DELETE: delete this internal volume before anything is written + * to the flash + * @UBI_COMPAT_RO: attach this device in read-only mode + * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its + * physical eraseblocks, don't allow the wear-leveling unit to move them + * @UBI_COMPAT_REJECT: reject this UBI image + */ +enum { + UBI_COMPAT_DELETE = 1, + UBI_COMPAT_RO = 2, + UBI_COMPAT_PRESERVE = 4, + UBI_COMPAT_REJECT = 5 +}; + +/* Sizes of UBI headers */ +#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) +#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) + +/* Sizes of UBI headers without the ending CRC */ +#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32)) +#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32)) + +/** + * struct ubi_ec_hdr - UBI erase counter header. + * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) + * @version: version of UBI implementation which is supposed to accept this + * UBI image + * @padding1: reserved for future, zeroes + * @ec: the erase counter + * @vid_hdr_offset: where the VID header starts + * @data_offset: where the user data start + * @padding2: reserved for future, zeroes + * @hdr_crc: erase counter header CRC checksum + * + * The erase counter header takes 64 bytes and has a plenty of unused space for + * future usage. The unused fields are zeroed. The @version field is used to + * indicate the version of UBI implementation which is supposed to be able to + * work with this UBI image. If @version is greater then the current UBI + * version, the image is rejected. This may be useful in future if something + * is changed radically. This field is duplicated in the volume identifier + * header. + * + * The @vid_hdr_offset and @data_offset fields contain the offset of the the + * volume identifier header and user data, relative to the beginning of the + * physical eraseblock. These values have to be the same for all physical + * eraseblocks. + */ +struct ubi_ec_hdr { + __be32 magic; + __u8 version; + __u8 padding1[3]; + __be64 ec; /* Warning: the current limit is 31-bit anyway! */ + __be32 vid_hdr_offset; + __be32 data_offset; + __u8 padding2[36]; + __be32 hdr_crc; +} __attribute__ ((packed)); + +/** + * struct ubi_vid_hdr - on-flash UBI volume identifier header. + * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) + * @version: UBI implementation version which is supposed to accept this UBI + * image (%UBI_VERSION) + * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @copy_flag: if this logical eraseblock was copied from another physical + * eraseblock (for wear-leveling reasons) + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @vol_id: ID of this volume + * @lnum: logical eraseblock number + * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be + * removed, kept only for not breaking older UBI users) + * @data_size: how many bytes of data this logical eraseblock contains + * @used_ebs: total number of used logical eraseblocks in this volume + * @data_pad: how many bytes at the end of this physical eraseblock are not + * used + * @data_crc: CRC checksum of the data stored in this logical eraseblock + * @padding1: reserved for future, zeroes + * @sqnum: sequence number + * @padding2: reserved for future, zeroes + * @hdr_crc: volume identifier header CRC checksum + * + * The @sqnum is the value of the global sequence counter at the time when this + * VID header was created. The global sequence counter is incremented each time + * UBI writes a new VID header to the flash, i.e. when it maps a logical + * eraseblock to a new physical eraseblock. The global sequence counter is an + * unsigned 64-bit integer and we assume it never overflows. The @sqnum + * (sequence number) is used to distinguish between older and newer versions of + * logical eraseblocks. + * + * There are 2 situations when there may be more then one physical eraseblock + * corresponding to the same logical eraseblock, i.e., having the same @vol_id + * and @lnum values in the volume identifier header. Suppose we have a logical + * eraseblock L and it is mapped to the physical eraseblock P. + * + * 1. Because UBI may erase physical eraseblocks asynchronously, the following + * situation is possible: L is asynchronously erased, so P is scheduled for + * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, + * so P1 is written to, then an unclean reboot happens. Result - there are 2 + * physical eraseblocks P and P1 corresponding to the same logical eraseblock + * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the + * flash. + * + * 2. From time to time UBI moves logical eraseblocks to other physical + * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P + * to P1, and an unclean reboot happens before P is physically erased, there + * are two physical eraseblocks P and P1 corresponding to L and UBI has to + * select one of them when the flash is attached. The @sqnum field says which + * PEB is the original (obviously P will have lower @sqnum) and the copy. But + * it is not enough to select the physical eraseblock with the higher sequence + * number, because the unclean reboot could have happen in the middle of the + * copying process, so the data in P is corrupted. It is also not enough to + * just select the physical eraseblock with lower sequence number, because the + * data there may be old (consider a case if more data was added to P1 after + * the copying). Moreover, the unclean reboot may happen when the erasure of P + * was just started, so it result in unstable P, which is "mostly" OK, but + * still has unstable bits. + * + * UBI uses the @copy_flag field to indicate that this logical eraseblock is a + * copy. UBI also calculates data CRC when the data is moved and stores it at + * the @data_crc field of the copy (P1). So when UBI needs to pick one physical + * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is + * examined. If it is cleared, the situation* is simple and the newer one is + * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC + * checksum is correct, this physical eraseblock is selected (P1). Otherwise + * the older one (P) is selected. + * + * Note, there is an obsolete @leb_ver field which was used instead of @sqnum + * in the past. But it is not used anymore and we keep it in order to be able + * to deal with old UBI images. It will be removed at some point. + * + * There are 2 sorts of volumes in UBI: user volumes and internal volumes. + * Internal volumes are not seen from outside and are used for various internal + * UBI purposes. In this implementation there is only one internal volume - the + * layout volume. Internal volumes are the main mechanism of UBI extensions. + * For example, in future one may introduce a journal internal volume. Internal + * volumes have their own reserved range of IDs. + * + * The @compat field is only used for internal volumes and contains the "degree + * of their compatibility". It is always zero for user volumes. This field + * provides a mechanism to introduce UBI extensions and to be still compatible + * with older UBI binaries. For example, if someone introduced a journal in + * future, he would probably use %UBI_COMPAT_DELETE compatibility for the + * journal volume. And in this case, older UBI binaries, which know nothing + * about the journal volume, would just delete this volume and work perfectly + * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image + * - it just ignores the Ext3fs journal. + * + * The @data_crc field contains the CRC checksum of the contents of the logical + * eraseblock if this is a static volume. In case of dynamic volumes, it does + * not contain the CRC checksum as a rule. The only exception is when the + * data of the physical eraseblock was moved by the wear-leveling unit, then + * the wear-leveling unit calculates the data CRC and stores it in the + * @data_crc field. And of course, the @copy_flag is %in this case. + * + * The @data_size field is used only for static volumes because UBI has to know + * how many bytes of data are stored in this eraseblock. For dynamic volumes, + * this field usually contains zero. The only exception is when the data of the + * physical eraseblock was moved to another physical eraseblock for + * wear-leveling reasons. In this case, UBI calculates CRC checksum of the + * contents and uses both @data_crc and @data_size fields. In this case, the + * @data_size field contains data size. + * + * The @used_ebs field is used only for static volumes and indicates how many + * eraseblocks the data of the volume takes. For dynamic volumes this field is + * not used and always contains zero. + * + * The @data_pad is calculated when volumes are created using the alignment + * parameter. So, effectively, the @data_pad field reduces the size of logical + * eraseblocks of this volume. This is very handy when one uses block-oriented + * software (say, cramfs) on top of the UBI volume. + */ +struct ubi_vid_hdr { + __be32 magic; + __u8 version; + __u8 vol_type; + __u8 copy_flag; + __u8 compat; + __be32 vol_id; + __be32 lnum; + __be32 leb_ver; /* obsolete, to be removed, don't use */ + __be32 data_size; + __be32 used_ebs; + __be32 data_pad; + __be32 data_crc; + __u8 padding1[4]; + __be64 sqnum; + __u8 padding2[12]; + __be32 hdr_crc; +} __attribute__ ((packed)); + +/* Internal UBI volumes count */ +#define UBI_INT_VOL_COUNT 1 + +/* + * Starting ID of internal volumes. There is reserved room for 4096 internal + * volumes. + */ +#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) + +/* The layout volume contains the volume table */ + +#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START +#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC +#define UBI_LAYOUT_VOLUME_ALIGN 1 +#define UBI_LAYOUT_VOLUME_EBS 2 +#define UBI_LAYOUT_VOLUME_NAME "layout volume" +#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT + +/* The maximum number of volumes per one UBI device */ +#define UBI_MAX_VOLUMES 128 + +/* The maximum volume name length */ +#define UBI_VOL_NAME_MAX 127 + +/* Size of the volume table record */ +#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) + +/* Size of the volume table record without the ending CRC */ +#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32)) + +/** + * struct ubi_vtbl_record - a record in the volume table. + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @upd_marker: if volume update was started but not finished + * @name_len: volume name length + * @name: the volume name + * @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG) + * @padding: reserved, zeroes + * @crc: a CRC32 checksum of the record + * + * The volume table records are stored in the volume table, which is stored in + * the layout volume. The layout volume consists of 2 logical eraseblock, each + * of which contains a copy of the volume table (i.e., the volume table is + * duplicated). The volume table is an array of &struct ubi_vtbl_record + * objects indexed by the volume ID. + * + * If the size of the logical eraseblock is large enough to fit + * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES + * records. Otherwise, it contains as many records as it can fit (i.e., size of + * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). + * + * The @upd_marker flag is used to implement volume update. It is set to %1 + * before update and set to %0 after the update. So if the update operation was + * interrupted, UBI knows that the volume is corrupted. + * + * The @alignment field is specified when the volume is created and cannot be + * later changed. It may be useful, for example, when a block-oriented file + * system works on top of UBI. The @data_pad field is calculated using the + * logical eraseblock size and @alignment. The alignment must be multiple to the + * minimal flash I/O unit. If @alignment is 1, all the available space of + * the physical eraseblocks is used. + * + * Empty records contain all zeroes and the CRC checksum of those zeroes. + */ +struct ubi_vtbl_record { + __be32 reserved_pebs; + __be32 alignment; + __be32 data_pad; + __u8 vol_type; + __u8 upd_marker; + __be16 name_len; + __u8 name[UBI_VOL_NAME_MAX+1]; + __u8 flags; + __u8 padding[23]; + __be32 crc; +} __attribute__ ((packed)); + +#endif /* !__UBI_MEDIA_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index a548c1d28fa8..28de80fcde55 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -37,10 +37,9 @@ #include #include #include - -#include #include +#include "ubi-media.h" #include "scan.h" #include "debug.h" -- cgit v1.2.2 From c4506092c1773211b71a75bd557c02b090c82b66 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 12 Feb 2008 16:36:41 +0200 Subject: UBI: fix error printing Use existing ubi_err() as the rest of the code does. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 275960462970..1e0e4e689d3e 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -950,8 +950,7 @@ static int __init ubi_init(void) BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); if (mtd_devs > UBI_MAX_DEVICES) { - printk(KERN_ERR "UBI error: too many MTD devices, " - "maximum is %d\n", UBI_MAX_DEVICES); + ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES); return -EINVAL; } @@ -959,25 +958,25 @@ static int __init ubi_init(void) ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); if (IS_ERR(ubi_class)) { err = PTR_ERR(ubi_class); - printk(KERN_ERR "UBI error: cannot create UBI class\n"); + ubi_err("cannot create UBI class"); goto out; } err = class_create_file(ubi_class, &ubi_version); if (err) { - printk(KERN_ERR "UBI error: cannot create sysfs file\n"); + ubi_err("cannot create sysfs file"); goto out_class; } err = misc_register(&ubi_ctrl_cdev); if (err) { - printk(KERN_ERR "UBI error: cannot register device\n"); + ubi_err("cannot register device"); goto out_version; } ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", - sizeof(struct ubi_wl_entry), - 0, 0, NULL); + sizeof(struct ubi_wl_entry), + 0, 0, NULL); if (!ubi_wl_entry_slab) goto out_dev_unreg; @@ -1000,8 +999,7 @@ static int __init ubi_init(void) mutex_unlock(&ubi_devices_mutex); if (err < 0) { put_mtd_device(mtd); - printk(KERN_ERR "UBI error: cannot attach mtd%d\n", - mtd->index); + ubi_err("cannot attach mtd%d", mtd->index); goto out_detach; } } @@ -1023,7 +1021,7 @@ out_version: out_class: class_destroy(ubi_class); out: - printk(KERN_ERR "UBI error: cannot initialize UBI, error %d\n", err); + ubi_err("UBI error: cannot initialize UBI, error %d", err); return err; } module_init(ubi_init); -- cgit v1.2.2 From 6e0c84e37e809e79313043385148020ceb760496 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 27 Mar 2008 17:18:45 +0200 Subject: UBI: improve Kconfig documentation Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index b9daf159a4a7..3f063108e95f 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -24,8 +24,13 @@ config MTD_UBI_WL_THRESHOLD erase counter value and the lowest erase counter value of eraseblocks of UBI devices. When this threshold is exceeded, UBI starts performing wear leveling by means of moving data from eraseblock with low erase - counter to eraseblocks with high erase counter. Leave the default - value if unsure. + counter to eraseblocks with high erase counter. + + The default value should be OK for SLC NAND flashes, NOR flashes and + other flashes which have eraseblock life-cycle 100000 or more. + However, in case of MLC NAND flashes which typically have eraseblock + life-cycle less then 10000, the threshold should be lessened (e.g., + to 128 or 256, although it does not have to be power of 2). config MTD_UBI_BEB_RESERVE int "Percentage of reserved eraseblocks for bad eraseblocks handling" -- cgit v1.2.2 From cbd8a9d2cd6f576ca41022599341bbd8be1b0b27 Mon Sep 17 00:00:00 2001 From: Jan Altenberg Date: Fri, 28 Mar 2008 16:13:53 +0100 Subject: UBI: initialize static volumes with vol->used_bytes I came across a problem which seems to be present since: commit 941dfb07ed91451b1c58626a0d258dfdf468b593 UBI: set correct gluebi device size ubi_create_gluebi() leaves mtd->size = 0 for static volumes. So even existing static volumes are initialized with a size of 0. Signed-off-by: Jan Altenberg Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/gluebi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index d397219238d3..e909b390069a 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -291,11 +291,12 @@ int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol) /* * In case of dynamic volume, MTD device size is just volume size. In * case of a static volume the size is equivalent to the amount of data - * bytes, which is zero at this moment and will be changed after volume - * update. + * bytes. */ if (vol->vol_type == UBI_DYNAMIC_VOLUME) mtd->size = vol->usable_leb_size * vol->reserved_pebs; + else + mtd->size = vol->used_bytes; if (add_mtd_device(mtd)) { ubi_err("cannot not add MTD device\n"); -- cgit v1.2.2 From d808fbe5b404854374917bd0d1db937a0a524665 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Apr 2008 09:24:39 -0400 Subject: Input: wm97xx-core - only schedule interrupt handler if not already scheduled As well as clarifying the fact that the driver can cope if a second interrupt occurs before the IRQ work is scheduled this also ensures that calls to the machine irq_enable() are balanced, making that easier to implement. Normally this is redundant due to the interrupt disabling but some unusal board configurations can trigger it. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm97xx-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 2910999e05a0..e27b1e060b33 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -328,18 +328,18 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) * * We have to disable the codec interrupt in the handler because it * can take upto 1ms to clear the interrupt source. We schedule a task - * in a work queue to do the actual interaction with the chip (it - * doesn't matter if we end up reenqueing it before it is executed - * since we don't touch the chip until it has run). The interrupt is - * then enabled again in the slow handler when the source has been - * cleared. + * in a work queue to do the actual interaction with the chip. The + * interrupt is then enabled again in the slow handler when the source + * has been cleared. */ static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) { struct wm97xx *wm = dev_id; - wm->mach_ops->irq_enable(wm, 0); - queue_work(wm->ts_workq, &wm->pen_event_work); + if (!work_pending(&wm->pen_event_work)) { + wm->mach_ops->irq_enable(wm, 0); + queue_work(wm->ts_workq, &wm->pen_event_work); + } return IRQ_HANDLED; } -- cgit v1.2.2 From db7c10e708b9bdd1618c034591d27c33cb341222 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Apr 2008 09:24:48 -0400 Subject: Input: wm97xx-core - use IRQF_SAMPLE_RANDOM The touchscreen interrupt is driven by human input which can reasonably be used to provide entropy. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm97xx-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index e27b1e060b33..fec07c28281a 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -355,7 +355,8 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm) * provided. */ BUG_ON(!wm->mach_ops->irq_enable); - if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, + if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, "wm97xx-pen", wm)) { dev_err(wm->dev, "Failed to register pen down interrupt, polling"); -- cgit v1.2.2 From 34d278534db050b93d79175d59a32a70ac25f9b5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Apr 2008 09:24:58 -0400 Subject: Input: wm97xx-core - support use as a wakeup source The WM97xx touch screen controllers can be used to generate a wakeup event when the system is suspended. Provide a new core API call wm97xx_set_suspend_mode() allowing machine drivers to enable this. If no suspend_mode is provided then the touch panel will be powered down when the system is suspended. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm97xx-core.c | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index fec07c28281a..e9c7ea46b6e3 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -261,6 +261,23 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir, } EXPORT_SYMBOL_GPL(wm97xx_config_gpio); +/* + * Configure the WM97XX_PRP value to use while system is suspended. + * If a value other than 0 is set then WM97xx pen detection will be + * left enabled in the configured mode while the system is in suspend, + * the device has users and suspend has not been disabled via the + * wakeup sysfs entries. + * + * @wm: WM97xx device to configure + * @mode: WM97XX_PRP value to configure while suspended + */ +void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode) +{ + wm->suspend_mode = mode; + device_init_wakeup(&wm->input_dev->dev, mode != 0); +} +EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode); + /* * Handle a pen down interrupt. */ @@ -689,10 +706,32 @@ static int wm97xx_remove(struct device *dev) static int wm97xx_suspend(struct device *dev, pm_message_t state) { struct wm97xx *wm = dev_get_drvdata(dev); + u16 reg; + int suspend_mode; + + if (device_may_wakeup(&wm->input_dev->dev)) + suspend_mode = wm->suspend_mode; + else + suspend_mode = 0; if (wm->input_dev->users) cancel_delayed_work_sync(&wm->ts_reader); + /* Power down the digitiser (bypassing the cache for resume) */ + reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2); + reg &= ~WM97XX_PRP_DET_DIG; + if (wm->input_dev->users) + reg |= suspend_mode; + wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg); + + /* WM9713 has an additional power bit - turn it off if there + * are no users or if suspend mode is zero. */ + if (wm->id == WM9713_ID2 && + (!wm->input_dev->users || !suspend_mode)) { + reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000; + wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg); + } + return 0; } -- cgit v1.2.2 From 4bc1dca4b0eb4dfbf100895bfc1256f21e3c901a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sat, 19 Apr 2008 20:44:31 +0300 Subject: UBI: fix mean EC calculation (a + b) / (c + d) != a / c + b / d. The old code errornously assumed this incorrect formuld. Instead, just sum all erase counters in a 64-bit variable and divide to the number of EBs at the end. Thanks to Adrian Hunter for pointing this out. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 41 ++++++++--------------------------------- drivers/mtd/ubi/scan.h | 2 +- 2 files changed, 9 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 05aa3e7daba1..96d410e106ab 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -42,6 +42,7 @@ #include #include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID @@ -91,27 +92,6 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, return 0; } -/** - * commit_to_mean_value - commit intermediate results to the final mean erase - * counter value. - * @si: scanning information - * - * This is a helper function which calculates partial mean erase counter mean - * value and adds it to the resulting mean value. As we can work only in - * integer arithmetic and we want to calculate the mean value of erase counter - * accurately, we first sum erase counter values in @si->ec_sum variable and - * count these components in @si->ec_count. If this temporary @si->ec_sum is - * going to overflow, we calculate the partial mean value - * (@si->ec_sum/@si->ec_count) and add it to @si->mean_ec. - */ -static void commit_to_mean_value(struct ubi_scan_info *si) -{ - si->ec_sum /= si->ec_count; - if (si->ec_sum % si->ec_count >= si->ec_count / 2) - si->mean_ec += 1; - si->mean_ec += si->ec_sum; -} - /** * validate_vid_hdr - check that volume identifier header is correct and * consistent. @@ -901,15 +881,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum adjust_mean_ec: if (!ec_corr) { - if (si->ec_sum + ec < ec) { - commit_to_mean_value(si); - si->ec_sum = 0; - si->ec_count = 0; - } else { - si->ec_sum += ec; - si->ec_count += 1; - } - + si->ec_sum += ec; + si->ec_count += 1; if (ec > si->max_ec) si->max_ec = ec; if (ec < si->min_ec) @@ -965,9 +938,11 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) dbg_msg("scanning is finished"); - /* Finish mean erase counter calculations */ - if (si->ec_count) - commit_to_mean_value(si); + /* Calculate mean erase counter */ + if (si->ec_count) { + do_div(si->ec_sum, si->ec_count); + si->mean_ec = si->ec_sum; + } if (si->is_empty) ubi_msg("empty MTD device detected"); diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 46d444af471a..966b9b682a42 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -124,7 +124,7 @@ struct ubi_scan_info { int max_ec; unsigned long long max_sqnum; int mean_ec; - int ec_sum; + uint64_t ec_sum; int ec_count; }; -- cgit v1.2.2 From 434b825e1fc9ef7971fc962734278ffbab36a1ab Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 20 Apr 2008 18:00:33 +0300 Subject: UBI: print media information earlier Print information about logicale eraseblock size, sub-page size and so on at early stage, befor an attempt to attach the MTD device was made. This is more convenient to do so because the attempt to attach may fail, and the information is never printed then. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 1e0e4e689d3e..e8578ca422ff 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -606,8 +606,16 @@ static int io_init(struct ubi_device *ubi) ubi->ro_mode = 1; } - dbg_msg("leb_size %d", ubi->leb_size); - dbg_msg("ro_mode %d", ubi->ro_mode); + ubi_msg("physical eraseblock size: %d bytes (%d KiB)", + ubi->peb_size, ubi->peb_size >> 10); + ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); + ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); + if (ubi->hdrs_min_io_size != ubi->min_io_size) + ubi_msg("sub-page size: %d", + ubi->hdrs_min_io_size); + ubi_msg("VID header offset: %d (aligned %d)", + ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); + ubi_msg("data offset: %d", ubi->leb_start); /* * Note, ideally, we have to initialize ubi->bad_peb_count here. But @@ -804,15 +812,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); ubi_msg("MTD device name: \"%s\"", mtd->name); ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); - ubi_msg("physical eraseblock size: %d bytes (%d KiB)", - ubi->peb_size, ubi->peb_size >> 10); - ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); ubi_msg("number of good PEBs: %d", ubi->good_peb_count); ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); - ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); - ubi_msg("VID header offset: %d (aligned %d)", - ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); - ubi_msg("data offset: %d", ubi->leb_start); ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); -- cgit v1.2.2 From 41bdf96006132db8ca6ad40d0189454fe620993a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 18 Apr 2008 13:44:10 -0700 Subject: [MTD] [MAPS] Document MTD_PHYSMAP module name in kconfig Help out users by telling them the module name in the Kconfig help when using the MTD_PHYSMAP option. Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/maps/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 12c253664eb2..1bd69aa9e22a 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -21,6 +21,9 @@ config MTD_PHYSMAP particular board as well as the bus width, either statically with config options or at run-time. + To compile this driver as a module, choose M here: the + module will be called physmap. + config MTD_PHYSMAP_START hex "Physical start address of flash mapping" depends on MTD_PHYSMAP -- cgit v1.2.2 From 7903cbabcb90a7d485e67062400481c321090a4f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 18 Apr 2008 13:44:11 -0700 Subject: [MTD] mtdoops.c: make struct oops_cxt static again struct oops_cxt needlessly became global. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/mtdoops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index d3cf05012b46..5a680e1e61f1 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -35,7 +35,7 @@ #define OOPS_PAGE_SIZE 4096 -struct mtdoops_context { +static struct mtdoops_context { int mtd_index; struct work_struct work_erase; struct work_struct work_write; -- cgit v1.2.2 From ec12cc74e998fa39e8d707d2deb3116f9838308a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 18 Apr 2008 13:44:12 -0700 Subject: [MTD] [NAND] mtd/nand/cs553x_nand.c:part_probes[] static Make the needlessly global part_probes[] static. Signed-off-by: Adrian Bunk Acked-by: Mart Raudsepp Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/nand/cs553x_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 8dab69657b19..3370a800fd36 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -279,7 +279,7 @@ static int is_geode(void) #ifdef CONFIG_MTD_PARTITIONS -const char *part_probes[] = { "cmdlinepart", NULL }; +static const char *part_probes[] = { "cmdlinepart", NULL }; #endif -- cgit v1.2.2 From 0bc88c59cc2f031a38ad5902d5764497549217c5 Mon Sep 17 00:00:00 2001 From: Stephane Chazelas Date: Fri, 18 Apr 2008 13:44:15 -0700 Subject: [MTD] block2mtd: logging typo fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address a number of small issues mainly regarding the output made by this driver to dmesg: - Some of the blkmtd's had not been changed to block2mtd which caused display problem - the parse_err() macro was displaying "block2mtd: " twice Signed-off-by: Stéphane Chazelas Acked-by: Jörn Engel Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/devices/block2mtd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index ad1880c67518..519d942e7940 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -305,7 +305,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) } list_add(&dev->list, &blkmtd_device_list); INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, - dev->mtd.name + strlen("blkmtd: "), + dev->mtd.name + strlen("block2mtd: "), dev->mtd.erasesize >> 10, dev->mtd.erasesize); return dev; @@ -366,9 +366,9 @@ static inline void kill_final_newline(char *str) } -#define parse_err(fmt, args...) do { \ - ERROR("block2mtd: " fmt "\n", ## args); \ - return 0; \ +#define parse_err(fmt, args...) do { \ + ERROR(fmt, ## args); \ + return 0; \ } while (0) #ifndef MODULE @@ -473,7 +473,7 @@ static void __devexit block2mtd_exit(void) block2mtd_sync(&dev->mtd); del_mtd_device(&dev->mtd); INFO("mtd%d: [%s] removed", dev->mtd.index, - dev->mtd.name + strlen("blkmtd: ")); + dev->mtd.name + strlen("block2mtd: ")); list_del(&dev->list); block2mtd_free_device(dev); } -- cgit v1.2.2 From 30d6a24eb8fdba2c6240bfec0eec4c8f2f058a1b Mon Sep 17 00:00:00 2001 From: Gordon Farquharson Date: Fri, 18 Apr 2008 13:44:18 -0700 Subject: [MTD] [JEDEC] add support for the ST M29W400DB flash chip Add support for the ST M29W400DB flash chip. which is used on the GLAN Tank NAS. Signed-off-by: Gordon Farquharson Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/chips/jedec_probe.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 4be51a86a85c..8a00de506664 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -132,6 +132,8 @@ #define M29F800AB 0x0058 #define M29W800DT 0x00D7 #define M29W800DB 0x005B +#define M29W400DT 0x00EE +#define M29W400DB 0x00EF #define M29W160DT 0x22C4 #define M29W160DB 0x2249 #define M29W040B 0x00E3 @@ -1456,6 +1458,36 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x08000,1), ERASEINFO(0x10000,15) } + }, { + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W400DT, + .name = "ST M29W400DT", + .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, + .uaddr = MTD_UADDR_0x0AAA_0x0555, + .dev_size = SIZE_512KiB, + .cmd_set = P_ID_AMD_STD, + .nr_regions = 4, + .regions = { + ERASEINFO(0x04000,7), + ERASEINFO(0x02000,1), + ERASEINFO(0x08000,2), + ERASEINFO(0x10000,1) + } + }, { + .mfr_id = MANUFACTURER_ST, + .dev_id = M29W400DB, + .name = "ST M29W400DB", + .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, + .uaddr = MTD_UADDR_0x0AAA_0x0555, + .dev_size = SIZE_512KiB, + .cmd_set = P_ID_AMD_STD, + .nr_regions = 4, + .regions = { + ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,7) + } }, { .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ .dev_id = M29W160DT, -- cgit v1.2.2 From 35d086b143e52f43a70c85ab86c054cbf1c4ff26 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 22 Apr 2008 12:25:26 +0100 Subject: [MTD] [JEDEC] Fix whitespace noise in chip table Signed-off-by: David Woodhouse --- drivers/mtd/chips/jedec_probe.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 8a00de506664..880a2fd734ff 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1115,7 +1115,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,8), } - }, { + }, { .mfr_id = MANUFACTURER_MACRONIX, .dev_id = MX29F016, .name = "Macronix MX29F016", @@ -1127,7 +1127,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,32), } - }, { + }, { .mfr_id = MANUFACTURER_MACRONIX, .dev_id = MX29F004T, .name = "Macronix MX29F004T", @@ -1142,7 +1142,7 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x02000,2), ERASEINFO(0x04000,1), } - }, { + }, { .mfr_id = MANUFACTURER_MACRONIX, .dev_id = MX29F004B, .name = "Macronix MX29F004B", @@ -1220,7 +1220,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x40000,16), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF512, .name = "SST 39LF512", @@ -1232,7 +1232,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x01000,16), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF010, .name = "SST 39LF010", @@ -1244,7 +1244,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x01000,32), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST29EE020, .name = "SST 29EE020", @@ -1278,7 +1278,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x01000,64), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF040, .name = "SST 39LF040", @@ -1290,7 +1290,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x01000,128), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39SF010A, .name = "SST 39SF010A", @@ -1302,7 +1302,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x01000,32), } - }, { + }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39SF020A, .name = "SST 39SF020A", @@ -1428,7 +1428,7 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x08000,1), ERASEINFO(0x10000,15), } - }, { + }, { .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ .dev_id = M29W800DT, .name = "ST M29W800DT", @@ -1518,7 +1518,7 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x08000,1), ERASEINFO(0x10000,31) } - }, { + }, { .mfr_id = MANUFACTURER_ST, .dev_id = M29W040B, .name = "ST M29W040B", @@ -1530,7 +1530,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,8), } - }, { + }, { .mfr_id = MANUFACTURER_ST, .dev_id = M50FW040, .name = "ST M50FW040", @@ -1542,7 +1542,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,8), } - }, { + }, { .mfr_id = MANUFACTURER_ST, .dev_id = M50FW080, .name = "ST M50FW080", @@ -1554,7 +1554,7 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO(0x10000,16), } - }, { + }, { .mfr_id = MANUFACTURER_ST, .dev_id = M50FW016, .name = "ST M50FW016", -- cgit v1.2.2 From cb53b3b99992b6c548d56cdf47bc710640ee2ee1 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 18 Apr 2008 13:44:19 -0700 Subject: [MTD] replace remaining __FUNCTION__ occurrences __FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 12 ++++++------ drivers/mtd/chips/cfi_cmdset_0020.c | 12 ++++++------ drivers/mtd/devices/lart.c | 16 ++++++++-------- drivers/mtd/devices/m25p80.c | 8 ++++---- drivers/mtd/maps/bast-flash.c | 4 ++-- drivers/mtd/maps/pcmciamtd.c | 2 +- drivers/mtd/maps/pmcmsp-flash.c | 2 +- drivers/mtd/maps/tqm8xxl.c | 6 +++--- drivers/mtd/ubi/debug.h | 2 +- drivers/mtd/ubi/ubi.h | 4 ++-- 10 files changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 0080452531d6..81b7767a665a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -384,7 +384,7 @@ read_pri_intelext(struct map_info *map, __u16 adr) if (extp_size > 4096) { printk(KERN_ERR "%s: cfi_pri_intelext is too fat\n", - __FUNCTION__); + __func__); return NULL; } goto again; @@ -641,7 +641,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, if ((1 << partshift) < mtd->erasesize) { printk( KERN_ERR "%s: bad number of hw partitions (%d)\n", - __FUNCTION__, numparts); + __func__, numparts); return -EINVAL; } @@ -2013,7 +2013,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len) #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", - __FUNCTION__, ofs, len); + __func__, ofs, len); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, ofs, len, NULL); #endif @@ -2023,7 +2023,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len) #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status after, ret=%d\n", - __FUNCTION__, ret); + __func__, ret); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, ofs, len, NULL); #endif @@ -2037,7 +2037,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", - __FUNCTION__, ofs, len); + __func__, ofs, len); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, ofs, len, NULL); #endif @@ -2047,7 +2047,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) #ifdef DEBUG_LOCK_BITS printk(KERN_DEBUG "%s: lock status after, ret=%d\n", - __FUNCTION__, ret); + __func__, ret); cfi_varsize_frob(mtd, do_printlockstatus_oneblock, ofs, len, NULL); #endif diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 492e2ab27420..669caebba451 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -445,7 +445,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, retry: #ifdef DEBUG_CFI_FEATURES - printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); + printk("%s: chip->state[%d]\n", __func__, chip->state); #endif spin_lock_bh(chip->mutex); @@ -463,7 +463,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; #ifdef DEBUG_CFI_FEATURES - printk("%s: 1 status[%x]\n", __FUNCTION__, map_read(map, cmd_adr)); + printk("%s: 1 status[%x]\n", __func__, map_read(map, cmd_adr)); #endif case FL_STATUS: @@ -591,7 +591,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, /* check for errors: 'lock bit', 'VPP', 'dead cell'/'unerased cell' or 'incorrect cmd' -- saw */ if (map_word_bitsset(map, status, CMD(0x3a))) { #ifdef DEBUG_CFI_FEATURES - printk("%s: 2 status[%lx]\n", __FUNCTION__, status.x[0]); + printk("%s: 2 status[%lx]\n", __func__, status.x[0]); #endif /* clear status */ map_write(map, CMD(0x50), cmd_adr); @@ -625,9 +625,9 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, ofs = to - (chipnum << cfi->chipshift); #ifdef DEBUG_CFI_FEATURES - printk("%s: map_bankwidth(map)[%x]\n", __FUNCTION__, map_bankwidth(map)); - printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); - printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); + printk("%s: map_bankwidth(map)[%x]\n", __func__, map_bankwidth(map)); + printk("%s: chipnum[%x] wbufsize[%x]\n", __func__, chipnum, wbufsize); + printk("%s: ofs[%x] len[%x]\n", __func__, ofs, len); #endif /* Write buffer is worth it only if more than one word to write... */ diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 99fd210feaec..1d324e5c412d 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -275,7 +275,7 @@ static __u8 read8 (__u32 offset) { volatile __u8 *data = (__u8 *) (FLASH_OFFSET + offset); #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n",__FUNCTION__,offset,*data); + printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n", __func__, offset, *data); #endif return (*data); } @@ -284,7 +284,7 @@ static __u32 read32 (__u32 offset) { volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n",__FUNCTION__,offset,*data); + printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n", __func__, offset, *data); #endif return (*data); } @@ -294,7 +294,7 @@ static void write32 (__u32 x,__u32 offset) volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); *data = x; #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,*data); + printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, *data); #endif } @@ -337,7 +337,7 @@ static inline int erase_block (__u32 offset) __u32 status; #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x\n",__FUNCTION__,offset); + printk (KERN_DEBUG "%s(): 0x%.8x\n", __func__, offset); #endif /* erase and confirm */ @@ -371,7 +371,7 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) int i,first; #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); + printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); #endif /* sanity checks */ @@ -442,7 +442,7 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf) { #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,len); + printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); #endif /* sanity checks */ @@ -488,7 +488,7 @@ static inline int write_dword (__u32 offset,__u32 x) __u32 status; #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,x); + printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, x); #endif /* setup writing */ @@ -524,7 +524,7 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen int i,n; #ifdef LART_DEBUG - printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len); + printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); #endif *retlen = 0; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 98df5bcc02f3..60408c955a13 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -151,7 +151,7 @@ static int wait_till_ready(struct m25p *flash) static int erase_sector(struct m25p *flash, u32 offset) { DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n", - flash->spi->dev.bus_id, __FUNCTION__, + flash->spi->dev.bus_id, __func__, flash->mtd.erasesize / 1024, offset); /* Wait until finished previous write command. */ @@ -188,7 +188,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) u32 addr,len; DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n", - flash->spi->dev.bus_id, __FUNCTION__, "at", + flash->spi->dev.bus_id, __func__, "at", (u32)instr->addr, instr->len); /* sanity checks */ @@ -240,7 +240,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, struct spi_message m; DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", - flash->spi->dev.bus_id, __FUNCTION__, "from", + flash->spi->dev.bus_id, __func__, "from", (u32)from, len); /* sanity checks */ @@ -308,7 +308,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, struct spi_message m; DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", - flash->spi->dev.bus_id, __FUNCTION__, "to", + flash->spi->dev.bus_id, __func__, "to", (u32)to, len); if (retlen) diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c index fc3b2672d1e2..59fea2a89804 100644 --- a/drivers/mtd/maps/bast-flash.c +++ b/drivers/mtd/maps/bast-flash.c @@ -137,7 +137,7 @@ static int bast_flash_probe(struct platform_device *pdev) if (info->map.size > AREA_MAXSIZE) info->map.size = AREA_MAXSIZE; - pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, + pr_debug("%s: area %08lx, size %ld\n", __func__, info->map.phys, info->map.size); info->area = request_mem_region(res->start, info->map.size, @@ -149,7 +149,7 @@ static int bast_flash_probe(struct platform_device *pdev) } info->map.virt = ioremap(res->start, info->map.size); - pr_debug("%s: virt at %08x\n", __FUNCTION__, (int)info->map.virt); + pr_debug("%s: virt at %08x\n", __func__, (int)info->map.virt); if (info->map.virt == 0) { printk(KERN_ERR PFX "failed to ioremap() region\n"); diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index eaeb56a4070a..1912d968718b 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -33,7 +33,7 @@ MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy"); #undef DEBUG #define DEBUG(n, format, arg...) \ if (n <= debug) { \ - printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ + printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ } #else diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c index 02bde8c982ec..f43ba2815cbb 100644 --- a/drivers/mtd/maps/pmcmsp-flash.c +++ b/drivers/mtd/maps/pmcmsp-flash.c @@ -46,7 +46,7 @@ static struct mtd_partition **msp_parts; static struct map_info *msp_maps; static int fcnt; -#define DEBUG_MARKER printk(KERN_NOTICE "%s[%d]\n",__FUNCTION__,__LINE__) +#define DEBUG_MARKER printk(KERN_NOTICE "%s[%d]\n", __func__, __LINE__) int __init init_msp_flash(void) { diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 37e4ded9b600..521734057314 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c @@ -124,7 +124,7 @@ int __init init_tqm_mtd(void) //request maximum flash size address space start_scan_addr = ioremap(flash_addr, flash_size); if (!start_scan_addr) { - printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr); + printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __func__, flash_addr); return -EIO; } @@ -132,7 +132,7 @@ int __init init_tqm_mtd(void) if(mtd_size >= flash_size) break; - printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); + printk(KERN_INFO "%s: chip probing count %d\n", __func__, idx); map_banks[idx] = kzalloc(sizeof(struct map_info), GFP_KERNEL); if(map_banks[idx] == NULL) { @@ -178,7 +178,7 @@ int __init init_tqm_mtd(void) mtd_size += mtd_banks[idx]->size; num_banks++; - printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, + printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __func__, num_banks, mtd_banks[idx]->name, mtd_banks[idx]->size); } } diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 51c40b17f1ec..8ac7d87dc85b 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -41,7 +41,7 @@ /* Generic debugging message */ #define dbg_msg(fmt, ...) \ printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ - current->pid, __FUNCTION__, ##__VA_ARGS__) + current->pid, __func__, ##__VA_ARGS__) #define ubi_dbg_dump_stack() dump_stack() diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index a548c1d28fa8..8f095cb87108 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -54,10 +54,10 @@ #define ubi_msg(fmt, ...) printk(KERN_NOTICE "UBI: " fmt "\n", ##__VA_ARGS__) /* UBI warning messages */ #define ubi_warn(fmt, ...) printk(KERN_WARNING "UBI warning: %s: " fmt "\n", \ - __FUNCTION__, ##__VA_ARGS__) + __func__, ##__VA_ARGS__) /* UBI error messages */ #define ubi_err(fmt, ...) printk(KERN_ERR "UBI error: %s: " fmt "\n", \ - __FUNCTION__, ##__VA_ARGS__) + __func__, ##__VA_ARGS__) /* Lowest number PEBs reserved for bad PEB handling */ #define MIN_RESEVED_PEBS 2 -- cgit v1.2.2 From c27e9b80bee039cfefa51c7af08b01eaab3dfb61 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Fri, 18 Apr 2008 13:44:24 -0700 Subject: [MTD] [NAND] fix possible Ooops in rfc_from4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I found this while I was looking how the rs_lib is working. The rs_decoder is initialized _after_ the nand core code read the BBT table and _after_ the partition table has been added. The driver has a private BBT description which is in located in flash data so we Ooops if there is a bit flip _or_ if a bit flips while reading the partition table. This patch moves the initialization of the rs_lib before the first possible access by nand core. Signed-off-by: Sebastian Siewior Cc: Thomas Gleixner Cc: Jörn Engel Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/nand/rtc_from4.c | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 0f6ac250f434..26f88215bc47 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c @@ -478,6 +478,7 @@ static int __init rtc_from4_init(void) struct nand_chip *this; unsigned short bcr1, bcr2, wcr2; int i; + int ret; /* Allocate memory for MTD device structure and private data */ rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); @@ -537,6 +538,22 @@ static int __init rtc_from4_init(void) this->ecc.hwctl = rtc_from4_enable_hwecc; this->ecc.calculate = rtc_from4_calculate_ecc; this->ecc.correct = rtc_from4_correct_data; + + /* We could create the decoder on demand, if memory is a concern. + * This way we have it handy, if an error happens + * + * Symbolsize is 10 (bits) + * Primitve polynomial is x^10+x^3+1 + * first consecutive root is 0 + * primitve element to generate roots = 1 + * generator polinomial degree = 6 + */ + rs_decoder = init_rs(10, 0x409, 0, 1, 6); + if (!rs_decoder) { + printk(KERN_ERR "Could not create a RS decoder\n"); + ret = -ENOMEM; + goto err_1; + } #else printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); @@ -549,8 +566,8 @@ static int __init rtc_from4_init(void) /* Scan to find existence of the device */ if (nand_scan(rtc_from4_mtd, RTC_FROM4_MAX_CHIPS)) { - kfree(rtc_from4_mtd); - return -ENXIO; + ret = -ENXIO; + goto err_2; } /* Perform 'device recovery' for each chip in case there was a power loss. */ @@ -566,28 +583,19 @@ static int __init rtc_from4_init(void) #endif /* Register the partitions */ - add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); + ret = add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); + if (ret) + goto err_3; -#ifdef RTC_FROM4_HWECC - /* We could create the decoder on demand, if memory is a concern. - * This way we have it handy, if an error happens - * - * Symbolsize is 10 (bits) - * Primitve polynomial is x^10+x^3+1 - * first consecutive root is 0 - * primitve element to generate roots = 1 - * generator polinomial degree = 6 - */ - rs_decoder = init_rs(10, 0x409, 0, 1, 6); - if (!rs_decoder) { - printk(KERN_ERR "Could not create a RS decoder\n"); - nand_release(rtc_from4_mtd); - kfree(rtc_from4_mtd); - return -ENOMEM; - } -#endif /* Return happy */ return 0; +err_3: + nand_release(rtc_from4_mtd); +err_2: + free_rs(rs_decoder); +err_1: + kfree(rtc_from4_mtd); + return ret; } module_init(rtc_from4_init); -- cgit v1.2.2 From 41d867c9ac852ce17069f8ae680f25877be97942 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:44:26 -0700 Subject: [MTD] [MAPS] fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable MTD mapping platform drivers, to re-enable auto loading. NOTE oddness with physmap ... it's a legacy driver in some configs, which means it can't always support hotplugging. (Not that most of these mapping drivers would often be used as modules...) [dbrownell@users.sourceforge.net: bugfix, more drivers, registration fixes] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/maps/bast-flash.c | 1 + drivers/mtd/maps/integrator-flash.c | 2 ++ drivers/mtd/maps/ixp2000.c | 3 ++- drivers/mtd/maps/ixp4xx.c | 2 ++ drivers/mtd/maps/omap_nor.c | 3 ++- drivers/mtd/maps/physmap.c | 8 ++++++++ drivers/mtd/maps/plat-ram.c | 3 +++ drivers/mtd/maps/sa1100-flash.c | 2 ++ 8 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c index 59fea2a89804..1f492062f8ca 100644 --- a/drivers/mtd/maps/bast-flash.c +++ b/drivers/mtd/maps/bast-flash.c @@ -223,3 +223,4 @@ module_exit(bast_flash_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks "); MODULE_DESCRIPTION("BAST MTD Map driver"); +MODULE_ALIAS("platform:bast-nor"); diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index 6946d802e6f6..325c8880c437 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c @@ -190,6 +190,7 @@ static struct platform_driver armflash_driver = { .remove = armflash_remove, .driver = { .name = "armflash", + .owner = THIS_MODULE, }, }; @@ -209,3 +210,4 @@ module_exit(armflash_exit); MODULE_AUTHOR("ARM Ltd"); MODULE_DESCRIPTION("ARM Integrator CFI map driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:armflash"); diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index c26488a1793a..c8396b8574c4 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c @@ -253,6 +253,7 @@ static struct platform_driver ixp2000_flash_driver = { .remove = ixp2000_flash_remove, .driver = { .name = "IXP2000-Flash", + .owner = THIS_MODULE, }, }; @@ -270,4 +271,4 @@ module_init(ixp2000_flash_init); module_exit(ixp2000_flash_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Deepak Saxena "); - +MODULE_ALIAS("platform:IXP2000-Flash"); diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 7a828e3e6446..01f19a4714b5 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c @@ -275,6 +275,7 @@ static struct platform_driver ixp4xx_flash_driver = { .remove = ixp4xx_flash_remove, .driver = { .name = "IXP4XX-Flash", + .owner = THIS_MODULE, }, }; @@ -295,3 +296,4 @@ module_exit(ixp4xx_flash_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); MODULE_AUTHOR("Deepak Saxena"); +MODULE_ALIAS("platform:IXP4XX-Flash"); diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index e8d9ae535673..676248ff4a75 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c @@ -156,6 +156,7 @@ static struct platform_driver omapflash_driver = { .remove = __devexit_p(omapflash_remove), .driver = { .name = "omapflash", + .owner = THIS_MODULE, }, }; @@ -174,4 +175,4 @@ module_exit(omapflash_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards"); - +MODULE_ALIAS("platform:omapflash"); diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index bc4649a17b9d..183255fcfdcb 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -242,6 +242,7 @@ static struct platform_driver physmap_flash_driver = { .shutdown = physmap_flash_shutdown, .driver = { .name = "physmap-flash", + .owner = THIS_MODULE, }, }; @@ -319,3 +320,10 @@ module_exit(physmap_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("Generic configurable MTD map driver"); + +/* legacy platform drivers can't hotplug or coldplg */ +#ifndef PHYSMAP_COMPAT +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:physmap-flash"); +#endif + diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 894c0b271289..7160e0eb09af 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -251,6 +251,9 @@ static int platram_probe(struct platform_device *pdev) /* device driver info */ +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:mtd-ram"); + static struct platform_driver platram_driver = { .probe = platram_probe, .remove = platram_remove, diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index f904e6bd02e0..c7d5a52a2d55 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -456,6 +456,7 @@ static struct platform_driver sa1100_mtd_driver = { .shutdown = sa1100_mtd_shutdown, .driver = { .name = "flash", + .owner = THIS_MODULE, }, }; @@ -475,3 +476,4 @@ module_exit(sa1100_mtd_exit); MODULE_AUTHOR("Nicolas Pitre"); MODULE_DESCRIPTION("SA1100 CFI map driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:flash"); -- cgit v1.2.2 From 1ff184225b15930ea118ac2130f074c741d34f08 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:44:27 -0700 Subject: [MTD] [NAND] fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable MTD NAND platform drivers, to re-enable auto loading. NOTE: at91_nand for some reason disallows modular builds. I'm assuming that's just an oversight that will be fixed. [dbrownell@users.sourceforge.net: minor fix] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/nand/at91_nand.c | 1 + drivers/mtd/nand/bf5xx_nand.c | 1 + drivers/mtd/nand/ndfc.c | 2 ++ drivers/mtd/nand/orion_nand.c | 1 + drivers/mtd/nand/plat_nand.c | 1 + drivers/mtd/nand/s3c2410.c | 3 +++ 6 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index c9fb2acf4056..7ea1a74a52b7 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -234,3 +234,4 @@ module_exit(at91_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rick Bronson"); MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200"); +MODULE_ALIAS("platform:at91_nand"); diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 747042ab094a..1fbc24ca5836 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -803,3 +803,4 @@ module_exit(bf5xx_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESC); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 1c0e89f00e8d..955959eb02d4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -317,3 +317,5 @@ module_exit(ndfc_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Thomas Gleixner "); MODULE_DESCRIPTION("Platform driver for NDFC"); +MODULE_ALIAS("platform:ndfc-chip"); +MODULE_ALIAS("platform:ndfc-nand"); diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index ec5ad28b237e..59e05a1c50cf 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -169,3 +169,4 @@ module_exit(orion_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Tzachi Perelstein"); MODULE_DESCRIPTION("NAND glue for Orion platforms"); +MODULE_ALIAS("platform:orion_nand"); diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index f6d5c2adc4fd..0fdb93ebc2fa 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -150,3 +150,4 @@ module_exit(plat_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Vitaly Wool"); MODULE_DESCRIPTION("Simple generic NAND driver"); +MODULE_ALIAS("platform:gen_nand"); diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 9260ad947524..f3fa1be22ddf 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -927,3 +927,6 @@ module_exit(s3c2410_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks "); MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); +MODULE_ALIAS("platform:s3c2410-nand"); +MODULE_ALIAS("platform:s3c2412-nand"); +MODULE_ALIAS("platform:s3c2440-nand"); -- cgit v1.2.2 From 52f8301437a0ba744265e0549ee7239eb85426fc Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 30 Mar 2008 21:59:37 +0900 Subject: [MTD] [NAND] at91_nand: Make part_probes[] static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The part_probes[] should be static. Signed-off-by: Atsushi Nemoto Acked-by: Jörn Engel Signed-off-by: David Woodhouse --- drivers/mtd/nand/at91_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index 7ea1a74a52b7..463632ed794c 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -83,7 +83,7 @@ static void at91_nand_disable(struct at91_nand_host *host) } #ifdef CONFIG_MTD_PARTITIONS -const char *part_probes[] = { "cmdlinepart", NULL }; +static const char *part_probes[] = { "cmdlinepart", NULL }; #endif /* -- cgit v1.2.2 From f72561cf6c9d0671da57902bc2ffee03b074227a Mon Sep 17 00:00:00 2001 From: Mark Hindley Date: Mon, 31 Mar 2008 14:25:03 +0100 Subject: [MTD] Correct phram module param description Signed-off-by: Mark Hindley Signed-off-by: David Woodhouse --- drivers/mtd/devices/phram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 180298b92a7a..5f960182da95 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -282,7 +282,7 @@ static int phram_setup(const char *val, struct kernel_param *kp) } module_param_call(phram, phram_setup, NULL, NULL, 000); -MODULE_PARM_DESC(phram,"Memory region to map. \"map=,,\""); +MODULE_PARM_DESC(phram, "Memory region to map. \"phram=,,\""); static int __init init_phram(void) -- cgit v1.2.2 From 576506645df01f3c1a9c2c9064201aa0ba4cb0ea Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 4 Apr 2008 17:06:05 -0500 Subject: [MTD] [NAND] fsl_elbc_nand: Fix SEQIN handling for large pages. Previously, a READ command was erroneously issued rather than SEQIN. Signed-off-by: Scott Wood Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsl_elbc_nand.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 378b7aa63812..b9f9f22cd860 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -346,19 +346,20 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, ctrl->column = column; ctrl->oob = 0; - fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) | - (NAND_CMD_SEQIN << FCR_CMD2_SHIFT); - if (priv->page_size) { + fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) | + (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT); + out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | (FIR_OP_CA << FIR_OP1_SHIFT) | (FIR_OP_PA << FIR_OP2_SHIFT) | (FIR_OP_WB << FIR_OP3_SHIFT) | (FIR_OP_CW1 << FIR_OP4_SHIFT)); - - fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; } else { + fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) | + (NAND_CMD_SEQIN << FCR_CMD2_SHIFT); + out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | (FIR_OP_CM2 << FIR_OP1_SHIFT) | -- cgit v1.2.2 From 950bcb2582ebeddb66a8e9349eaedf7ba69e195b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:19:46 +0300 Subject: [MTD] mtd/ofpart.c: add MODULE_LICENSE This patch adds the missing MODULE_LICENSE("GPL"). Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/ofpart.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index f86e06934cd8..4f80c2fd89af 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -72,3 +72,5 @@ int __devinit of_mtd_parse_partitions(struct device *dev, return nr_parts; } EXPORT_SYMBOL(of_mtd_parse_partitions); + +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From a8e8aa25694f1781fafee4ee8e8f393e4b979b36 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:19:58 +0300 Subject: [MTD] proper prototypes for inftl_{read,write}_oob() This patch adds proper prototypes for inftl_{read,write}_oob() in include/linux/mtd/inftl.h Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/inftlmount.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index b8917beeb650..c551d2f0779c 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -41,11 +41,6 @@ char inftlmountrev[]="$Revision: 1.18 $"; -extern int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf); -extern int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf); - /* * find_boot_record: Find the INFTL Media Header and its Spare copy which * contains the various device information of the INFTL partition and -- cgit v1.2.2 From 51ee83df6151a3e618e65236e304e00ac8d95607 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:00 +0300 Subject: [MTD] proper prototypes for nftl_{read,write}_oob() This patch adds proper prototypes for nftl_{read,write}_oob() in include/linux/mtd/nftl.h Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/nftlmount.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c index 0513cbc8834d..345e6eff89ce 100644 --- a/drivers/mtd/nftlmount.c +++ b/drivers/mtd/nftlmount.c @@ -33,11 +33,6 @@ char nftlmountrev[]="$Revision: 1.41 $"; -extern int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf); -extern int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf); - /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the * various device information of the NFTL partition and Bad Unit Table. Update * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] -- cgit v1.2.2 From 456d9fc92eb8635d53e8facc57764464b8759173 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:02 +0300 Subject: [MTD] mtdram.c should #include Every file should include the headers containing the externs for its global functions (in this case for mtdram_init_device()). Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/devices/mtdram.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index e427c82d5f4c..bf485ff49457 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -17,6 +17,7 @@ #include #include #include +#include static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE; -- cgit v1.2.2 From ed262c4f5cb8291668c27c88a022bd7628f067a4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:04 +0300 Subject: [MTD] cmdlinepart.c: don't compare pointers with 0 Sparse spotted that 0 was compared to pointers. While I was at it, I also moved the assignments out of the if's. Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/cmdlinepart.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index b44292abd9f7..3e090436396d 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -119,7 +119,8 @@ static struct mtd_partition * newpart(char *s, char *p; name = ++s; - if ((p = strchr(name, delim)) == 0) + p = strchr(name, delim); + if (!p) { printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim); return NULL; @@ -159,9 +160,10 @@ static struct mtd_partition * newpart(char *s, return NULL; } /* more partitions follow, parse them */ - if ((parts = newpart(s + 1, &s, num_parts, - this_part + 1, &extra_mem, extra_mem_size)) == 0) - return NULL; + parts = newpart(s + 1, &s, num_parts, this_part + 1, + &extra_mem, extra_mem_size); + if (!parts) + return NULL; } else { /* this is the last partition: allocate space for all */ -- cgit v1.2.2 From 5ce45d50056e20aca50f19229d8a7e003569ad26 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:24 +0300 Subject: [MTD] ftl.c: make code static This patch makes the following needlessly global code static: - ftl_freepart() - struct ftl_tr Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/ftl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index c815d0f38577..4a79b187b568 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -136,8 +136,6 @@ typedef struct partition_t { #endif } partition_t; -void ftl_freepart(partition_t *part); - /* Partition state flags */ #define FTL_FORMATTED 0x01 @@ -1014,7 +1012,7 @@ static int ftl_writesect(struct mtd_blktrans_dev *dev, /*====================================================================*/ -void ftl_freepart(partition_t *part) +static void ftl_freepart(partition_t *part) { vfree(part->VirtualBlockMap); part->VirtualBlockMap = NULL; @@ -1069,7 +1067,7 @@ static void ftl_remove_dev(struct mtd_blktrans_dev *dev) kfree(dev); } -struct mtd_blktrans_ops ftl_tr = { +static struct mtd_blktrans_ops ftl_tr = { .name = "ftl", .major = FTL_MAJOR, .part_bits = PART_BITS, -- cgit v1.2.2 From eb8e31831a603f285ee9e6ffc59d5366e0ff8a8e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:30 +0300 Subject: [MTD] [NOR] cfi_cmdset_0020.c: make a function static This patch makes the needlessly global cfi_staa_erase_varsize() static. Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0020.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 669caebba451..1b720cc571f3 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -893,7 +893,8 @@ retry: return ret; } -int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) +static int cfi_staa_erase_varsize(struct mtd_info *mtd, + struct erase_info *instr) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; unsigned long adr, len; -- cgit v1.2.2 From 607d1cb1042657177bf72247eeb85c0d8416bd51 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:38 +0300 Subject: [MTD] [OneNAND] proper onenand_bbt_read_oob() prototype This patch adds a proper prototype for onenand_bbt_read_oob() in include/linux/mtd/onenand.h Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_bbt.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index aecdd50a1781..2f53b51c6805 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -17,9 +17,6 @@ #include #include -extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, - struct mtd_oob_ops *ops); - /** * check_short_pattern - [GENERIC] check if a pattern is in the buffer * @param buf the buffer to search -- cgit v1.2.2 From 7fe9296c80e9a4ee51b43fbfbceb5143751a9d5c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Apr 2008 17:20:40 +0300 Subject: [MTD] make struct rfd_ftl_tr static This patch makes the needlessly global struct rfd_ftl_tr static. Signed-off-by: Adrian Bunk Signed-off-by: David Woodhouse --- drivers/mtd/rfd_ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index 823fba4e6d2f..c84e45465499 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -823,7 +823,7 @@ static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev) kfree(part); } -struct mtd_blktrans_ops rfd_ftl_tr = { +static struct mtd_blktrans_ops rfd_ftl_tr = { .name = "rfd", .major = RFD_FTL_MAJOR, .part_bits = PART_BITS, -- cgit v1.2.2 From c3f08b353519ee9c64308837199a9fcf83e863da Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Wed, 16 Jan 2008 15:45:20 +0100 Subject: [MTD] [MAPS] add support for Nvidia MCP55 to ck804xrom This patch extends the existing MAPS driver for the Nvidia CK804 chipset (ck804xrom.c) to also work on the Nvidia MCP55 chipset. As both chipsets are rather similar, suporting them both with the same driver is easy. Signed-off-by: Carl-Daniel Hailfinger Signed-off-by: David Woodhouse --- drivers/mtd/maps/ck804xrom.c | 89 ++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 688ef495888a..59d8fb49270a 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -28,6 +28,9 @@ #define ROM_PROBE_STEP_SIZE (64*1024) +#define DEV_CK804 1 +#define DEV_MCP55 2 + struct ck804xrom_window { void __iomem *virt; unsigned long phys; @@ -45,8 +48,9 @@ struct ck804xrom_map_info { char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; }; - -/* The 2 bits controlling the window size are often set to allow reading +/* + * The following applies to ck804 only: + * The 2 bits controlling the window size are often set to allow reading * the BIOS, but too small to allow writing, since the lock registers are * 4MiB lower in the address space than the data. * @@ -58,10 +62,17 @@ struct ck804xrom_map_info { * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a * 64KiB window. * + * The following applies to mcp55 only: + * The 15 bits controlling the window size are distributed as follows: + * byte @0x88: bit 0..7 + * byte @0x8c: bit 8..15 + * word @0x90: bit 16..30 + * If all bits are enabled, we have a 16? MiB window + * Please set win_size_bits to 0x7fffffff if you actually want to do something */ static uint win_size_bits = 0; module_param(win_size_bits, uint, 0); -MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS."); +MODULE_PARM_DESC(win_size_bits, "ROM window size bits override, normally set by BIOS."); static struct ck804xrom_window ck804xrom_window = { .maps = LIST_HEAD_INIT(ck804xrom_window.maps), @@ -102,10 +113,11 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window) static int __devinit ck804xrom_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; u8 byte; + u16 word; struct ck804xrom_window *window = &ck804xrom_window; struct ck804xrom_map_info *map = NULL; unsigned long map_top; @@ -113,26 +125,42 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev, /* Remember the pci dev I find the window in */ window->pdev = pci_dev_get(pdev); - /* Enable the selected rom window. This is often incorrectly - * set up by the BIOS, and the 4MiB offset for the lock registers - * requires the full 5MiB of window space. - * - * This 'write, then read' approach leaves the bits for - * other uses of the hardware info. - */ - pci_read_config_byte(pdev, 0x88, &byte); - pci_write_config_byte(pdev, 0x88, byte | win_size_bits ); - - - /* Assume the rom window is properly setup, and find it's size */ - pci_read_config_byte(pdev, 0x88, &byte); - - if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) - window->phys = 0xffb00000; /* 5MiB */ - else if ((byte & (1<<7)) == (1<<7)) - window->phys = 0xffc00000; /* 4MiB */ - else - window->phys = 0xffff0000; /* 64KiB */ + switch (ent->driver_data) { + case DEV_CK804: + /* Enable the selected rom window. This is often incorrectly + * set up by the BIOS, and the 4MiB offset for the lock registers + * requires the full 5MiB of window space. + * + * This 'write, then read' approach leaves the bits for + * other uses of the hardware info. + */ + pci_read_config_byte(pdev, 0x88, &byte); + pci_write_config_byte(pdev, 0x88, byte | win_size_bits ); + + /* Assume the rom window is properly setup, and find it's size */ + pci_read_config_byte(pdev, 0x88, &byte); + + if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) + window->phys = 0xffb00000; /* 5MiB */ + else if ((byte & (1<<7)) == (1<<7)) + window->phys = 0xffc00000; /* 4MiB */ + else + window->phys = 0xffff0000; /* 64KiB */ + break; + + case DEV_MCP55: + pci_read_config_byte(pdev, 0x88, &byte); + pci_write_config_byte(pdev, 0x88, byte | (win_size_bits & 0xff)); + + pci_read_config_byte(pdev, 0x8c, &byte); + pci_write_config_byte(pdev, 0x8c, byte | ((win_size_bits & 0xff00) >> 8)); + + pci_read_config_word(pdev, 0x90, &word); + pci_write_config_word(pdev, 0x90, word | ((win_size_bits & 0x7fff0000) >> 16)); + + window->phys = 0xff000000; /* 16MiB, hardcoded for now */ + break; + } window->size = 0xffffffffUL - window->phys + 1UL; @@ -303,8 +331,15 @@ static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) } static struct pci_device_id ck804xrom_pci_tbl[] = { - { PCI_VENDOR_ID_NVIDIA, 0x0051, - PCI_ANY_ID, PCI_ANY_ID, }, /* nvidia ck804 */ + { PCI_VENDOR_ID_NVIDIA, 0x0051, PCI_ANY_ID, PCI_ANY_ID, DEV_CK804 }, + { PCI_VENDOR_ID_NVIDIA, 0x0360, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0361, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0362, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0363, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0364, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0365, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0366, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, + { PCI_VENDOR_ID_NVIDIA, 0x0367, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, { 0, } }; @@ -332,7 +367,7 @@ static int __init init_ck804xrom(void) break; } if (pdev) { - retVal = ck804xrom_init_one(pdev, &ck804xrom_pci_tbl[0]); + retVal = ck804xrom_init_one(pdev, id); pci_dev_put(pdev); return retVal; } -- cgit v1.2.2 From b0d06afb60741c19e103ffd60927f68e17c9d199 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 14 Feb 2008 17:00:10 +0100 Subject: [MTD] cmdlinepart: Missing partition info is not an error Return 0 partitions instead of -EINVAL on no mtdpart= argument in kernel cmdline or missing partition info for device. Signed-off-by: Peter Korsgaard Acked-by: Stefan Roese Signed-off-by: David Woodhouse --- drivers/mtd/cmdlinepart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 3e090436396d..e472a0e9de9d 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -310,9 +310,6 @@ static int parse_cmdline_partitions(struct mtd_info *master, struct cmdline_mtd_partition *part; char *mtd_id = master->name; - if(!cmdline) - return -EINVAL; - /* parse command line */ if (!cmdline_parsed) mtdpart_setup_real(cmdline); @@ -343,7 +340,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, return part->num_parts; } } - return -EINVAL; + return 0; } -- cgit v1.2.2 From 8e2537e4cb4e80b7032372a42069899b90a06e90 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 14 Feb 2008 16:50:25 +0100 Subject: [MTD] fix minor typo in the MTD map driver for SHARP SL series Signed-off-by: David Woodhouse --- drivers/mtd/maps/sharpsl-flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c index 12fe53c0d2fc..917dc778f24e 100644 --- a/drivers/mtd/maps/sharpsl-flash.c +++ b/drivers/mtd/maps/sharpsl-flash.c @@ -92,7 +92,7 @@ int __init init_sharpsl(void) parts = sharpsl_partitions; nb_parts = ARRAY_SIZE(sharpsl_partitions); - printk(KERN_NOTICE "Using %s partision definition\n", part_type); + printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); return 0; -- cgit v1.2.2 From b73d7e4381311bea024bf7cedcba3dcf20f63aab Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Sat, 16 Feb 2008 18:14:35 +0100 Subject: [MTD] [OneNAND] unlikely(x) || unlikely(y) => unlikely(x || y) Acked-By: Kyungmin Park Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 15a62db656de..56255c85d97b 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1336,7 +1336,7 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, } /* Reject writes, which are not page aligned */ - if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { + if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "onenand_panic_write: Attempt to write not page aligned data\n"); return -EINVAL; } @@ -1466,7 +1466,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, } /* Reject writes, which are not page aligned */ - if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { + if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n"); return -EINVAL; } -- cgit v1.2.2 From fe69af002e26ca39824f626459c16d642607b573 Mon Sep 17 00:00:00 2001 From: eric miao Date: Thu, 14 Feb 2008 15:48:23 +0800 Subject: [MTD] [NAND] support for pxa3xx This is preliminary since: 1. It supports only _one_ chip select at the moment. As there is no existing platforms available using two chip selects of the NAND controller, it shall really not include code for supporting the 2nd chip select for now, as such code cannot be verified. 2. It resorts to the default and simpliest memory based badblock table 3. Only limited types of nand flash are currently supported. Most PXA3xx processors come with on-chip NAND flash dies, so there isn't much flexibility for other types of NAND. 4. The NAND controller should be configured to detect the device's ID, thus making it difficult to use nand_scan_ident() to assist the detection process (though it's not impossible) TODO: fix all the above limitations of cuz :-) Signed-off-by: eric miao Cc: Sergey Podstavin Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 7 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/pxa3xx_nand.c | 1249 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1257 insertions(+) create mode 100644 drivers/mtd/nand/pxa3xx_nand.c (limited to 'drivers') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 959fb86cda01..180fc7be1826 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -279,6 +279,13 @@ config MTD_NAND_AT91 Enables support for NAND Flash / Smart Media Card interface on Atmel AT91 processors. +config MTD_NAND_PXA3xx + bool "Support for NAND flash devices on PXA3xx" + depends on MTD_NAND && PXA3xx + help + This enables the driver for the NAND flash device found on + PXA3xx processors + config MTD_NAND_CM_X270 tristate "Support for NAND Flash on CM-X270 modules" depends on MTD_NAND && MACH_ARMCORE diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 80d575eeee96..54a332bda3da 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o +obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o obj-$(CONFIG_MTD_ALAUDA) += alauda.o obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c new file mode 100644 index 000000000000..138e219c2304 --- /dev/null +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -0,0 +1,1249 @@ +/* + * drivers/mtd/nand/pxa3xx_nand.c + * + * Copyright © 2005 Intel Corporation + * Copyright © 2006 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define CHIP_DELAY_TIMEOUT (2 * HZ/10) + +/* registers and bit definitions */ +#define NDCR (0x00) /* Control register */ +#define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */ +#define NDTR1CS0 (0x0C) /* Timing Parameter 1 for CS0 */ +#define NDSR (0x14) /* Status Register */ +#define NDPCR (0x18) /* Page Count Register */ +#define NDBDR0 (0x1C) /* Bad Block Register 0 */ +#define NDBDR1 (0x20) /* Bad Block Register 1 */ +#define NDDB (0x40) /* Data Buffer */ +#define NDCB0 (0x48) /* Command Buffer0 */ +#define NDCB1 (0x4C) /* Command Buffer1 */ +#define NDCB2 (0x50) /* Command Buffer2 */ + +#define NDCR_SPARE_EN (0x1 << 31) +#define NDCR_ECC_EN (0x1 << 30) +#define NDCR_DMA_EN (0x1 << 29) +#define NDCR_ND_RUN (0x1 << 28) +#define NDCR_DWIDTH_C (0x1 << 27) +#define NDCR_DWIDTH_M (0x1 << 26) +#define NDCR_PAGE_SZ (0x1 << 24) +#define NDCR_NCSX (0x1 << 23) +#define NDCR_ND_MODE (0x3 << 21) +#define NDCR_NAND_MODE (0x0) +#define NDCR_CLR_PG_CNT (0x1 << 20) +#define NDCR_CLR_ECC (0x1 << 19) +#define NDCR_RD_ID_CNT_MASK (0x7 << 16) +#define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK) + +#define NDCR_RA_START (0x1 << 15) +#define NDCR_PG_PER_BLK (0x1 << 14) +#define NDCR_ND_ARB_EN (0x1 << 12) + +#define NDSR_MASK (0xfff) +#define NDSR_RDY (0x1 << 11) +#define NDSR_CS0_PAGED (0x1 << 10) +#define NDSR_CS1_PAGED (0x1 << 9) +#define NDSR_CS0_CMDD (0x1 << 8) +#define NDSR_CS1_CMDD (0x1 << 7) +#define NDSR_CS0_BBD (0x1 << 6) +#define NDSR_CS1_BBD (0x1 << 5) +#define NDSR_DBERR (0x1 << 4) +#define NDSR_SBERR (0x1 << 3) +#define NDSR_WRDREQ (0x1 << 2) +#define NDSR_RDDREQ (0x1 << 1) +#define NDSR_WRCMDREQ (0x1) + +#define NDCB0_AUTO_RS (0x1 << 25) +#define NDCB0_CSEL (0x1 << 24) +#define NDCB0_CMD_TYPE_MASK (0x7 << 21) +#define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK) +#define NDCB0_NC (0x1 << 20) +#define NDCB0_DBC (0x1 << 19) +#define NDCB0_ADDR_CYC_MASK (0x7 << 16) +#define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK) +#define NDCB0_CMD2_MASK (0xff << 8) +#define NDCB0_CMD1_MASK (0xff) +#define NDCB0_ADDR_CYC_SHIFT (16) + +/* dma-able I/O address for the NAND data and commands */ +#define NDCB0_DMA_ADDR (0x43100048) +#define NDDB_DMA_ADDR (0x43100040) + +/* macros for registers read/write */ +#define nand_writel(info, off, val) \ + __raw_writel((val), (info)->mmio_base + (off)) + +#define nand_readl(info, off) \ + __raw_readl((info)->mmio_base + (off)) + +/* error code and state */ +enum { + ERR_NONE = 0, + ERR_DMABUSERR = -1, + ERR_SENDCMD = -2, + ERR_DBERR = -3, + ERR_BBERR = -4, +}; + +enum { + STATE_READY = 0, + STATE_CMD_HANDLE, + STATE_DMA_READING, + STATE_DMA_WRITING, + STATE_DMA_DONE, + STATE_PIO_READING, + STATE_PIO_WRITING, +}; + +struct pxa3xx_nand_timing { + unsigned int tCH; /* Enable signal hold time */ + unsigned int tCS; /* Enable signal setup time */ + unsigned int tWH; /* ND_nWE high duration */ + unsigned int tWP; /* ND_nWE pulse time */ + unsigned int tRH; /* ND_nRE high duration */ + unsigned int tRP; /* ND_nRE pulse width */ + unsigned int tR; /* ND_nWE high to ND_nRE low for read */ + unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ + unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ +}; + +struct pxa3xx_nand_cmdset { + uint16_t read1; + uint16_t read2; + uint16_t program; + uint16_t read_status; + uint16_t read_id; + uint16_t erase; + uint16_t reset; + uint16_t lock; + uint16_t unlock; + uint16_t lock_status; +}; + +struct pxa3xx_nand_flash { + struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ + struct pxa3xx_nand_cmdset *cmdset; + + uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */ + uint32_t page_size; /* Page size in bytes (PAGE_SZ) */ + uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */ + uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */ + uint32_t num_blocks; /* Number of physical blocks in Flash */ + uint32_t chip_id; + + /* NOTE: these are automatically calculated, do not define */ + size_t oob_size; + size_t read_id_bytes; + + unsigned int col_addr_cycles; + unsigned int row_addr_cycles; +}; + +struct pxa3xx_nand_info { + struct nand_chip nand_chip; + + struct platform_device *pdev; + struct pxa3xx_nand_flash *flash_info; + + struct clk *clk; + void __iomem *mmio_base; + + unsigned int buf_start; + unsigned int buf_count; + + /* DMA information */ + int drcmr_dat; + int drcmr_cmd; + + unsigned char *data_buff; + dma_addr_t data_buff_phys; + size_t data_buff_size; + int data_dma_ch; + struct pxa_dma_desc *data_desc; + dma_addr_t data_desc_addr; + + uint32_t reg_ndcr; + + /* saved column/page_addr during CMD_SEQIN */ + int seqin_column; + int seqin_page_addr; + + /* relate to the command */ + unsigned int state; + + int use_ecc; /* use HW ECC ? */ + int use_dma; /* use DMA ? */ + + size_t data_size; /* data size in FIFO */ + int retcode; + struct completion cmd_complete; + + /* generated NDCBx register values */ + uint32_t ndcb0; + uint32_t ndcb1; + uint32_t ndcb2; +}; + +static int use_dma = 1; +module_param(use_dma, bool, 0444); +MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); + +static struct pxa3xx_nand_cmdset smallpage_cmdset = { + .read1 = 0x0000, + .read2 = 0x0050, + .program = 0x1080, + .read_status = 0x0070, + .read_id = 0x0090, + .erase = 0xD060, + .reset = 0x00FF, + .lock = 0x002A, + .unlock = 0x2423, + .lock_status = 0x007A, +}; + +static struct pxa3xx_nand_cmdset largepage_cmdset = { + .read1 = 0x3000, + .read2 = 0x0050, + .program = 0x1080, + .read_status = 0x0070, + .read_id = 0x0090, + .erase = 0xD060, + .reset = 0x00FF, + .lock = 0x002A, + .unlock = 0x2423, + .lock_status = 0x007A, +}; + +static struct pxa3xx_nand_timing samsung512MbX16_timing = { + .tCH = 10, + .tCS = 0, + .tWH = 20, + .tWP = 40, + .tRH = 30, + .tRP = 40, + .tR = 11123, + .tWHR = 110, + .tAR = 10, +}; + +static struct pxa3xx_nand_flash samsung512MbX16 = { + .timing = &samsung512MbX16_timing, + .cmdset = &smallpage_cmdset, + .page_per_block = 32, + .page_size = 512, + .flash_width = 16, + .dfc_width = 16, + .num_blocks = 4096, + .chip_id = 0x46ec, +}; + +static struct pxa3xx_nand_timing micron_timing = { + .tCH = 10, + .tCS = 25, + .tWH = 15, + .tWP = 25, + .tRH = 15, + .tRP = 25, + .tR = 25000, + .tWHR = 60, + .tAR = 10, +}; + +static struct pxa3xx_nand_flash micron1GbX8 = { + .timing = µn_timing, + .cmdset = &largepage_cmdset, + .page_per_block = 64, + .page_size = 2048, + .flash_width = 8, + .dfc_width = 8, + .num_blocks = 1024, + .chip_id = 0xa12c, +}; + +static struct pxa3xx_nand_flash micron1GbX16 = { + .timing = µn_timing, + .cmdset = &largepage_cmdset, + .page_per_block = 64, + .page_size = 2048, + .flash_width = 16, + .dfc_width = 16, + .num_blocks = 1024, + .chip_id = 0xb12c, +}; + +static struct pxa3xx_nand_flash *builtin_flash_types[] = { + &samsung512MbX16, + µn1GbX8, + µn1GbX16, +}; + +#define NDTR0_tCH(c) (min((c), 7) << 19) +#define NDTR0_tCS(c) (min((c), 7) << 16) +#define NDTR0_tWH(c) (min((c), 7) << 11) +#define NDTR0_tWP(c) (min((c), 7) << 8) +#define NDTR0_tRH(c) (min((c), 7) << 3) +#define NDTR0_tRP(c) (min((c), 7) << 0) + +#define NDTR1_tR(c) (min((c), 65535) << 16) +#define NDTR1_tWHR(c) (min((c), 15) << 4) +#define NDTR1_tAR(c) (min((c), 15) << 0) + +/* convert nano-seconds to nand flash controller clock cycles */ +#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) + 1) + +static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, + struct pxa3xx_nand_timing *t) +{ + unsigned long nand_clk = clk_get_rate(info->clk); + uint32_t ndtr0, ndtr1; + + ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) | + NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) | + NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) | + NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) | + NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) | + NDTR0_tRP(ns2cycle(t->tRP, nand_clk)); + + ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) | + NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | + NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); + + nand_writel(info, NDTR0CS0, ndtr0); + nand_writel(info, NDTR1CS0, ndtr1); +} + +#define WAIT_EVENT_TIMEOUT 10 + +static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event) +{ + int timeout = WAIT_EVENT_TIMEOUT; + uint32_t ndsr; + + while (timeout--) { + ndsr = nand_readl(info, NDSR) & NDSR_MASK; + if (ndsr & event) { + nand_writel(info, NDSR, ndsr); + return 0; + } + udelay(10); + } + + return -ETIMEDOUT; +} + +static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, + uint16_t cmd, int column, int page_addr) +{ + struct pxa3xx_nand_flash *f = info->flash_info; + struct pxa3xx_nand_cmdset *cmdset = f->cmdset; + + /* calculate data size */ + switch (f->page_size) { + case 2048: + info->data_size = (info->use_ecc) ? 2088 : 2112; + break; + case 512: + info->data_size = (info->use_ecc) ? 520 : 528; + break; + default: + return -EINVAL; + } + + /* generate values for NDCBx registers */ + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb1 = 0; + info->ndcb2 = 0; + info->ndcb0 |= NDCB0_ADDR_CYC(f->row_addr_cycles + f->col_addr_cycles); + + if (f->col_addr_cycles == 2) { + /* large block, 2 cycles for column address + * row address starts from 3rd cycle + */ + info->ndcb1 |= (page_addr << 16) | (column & 0xffff); + if (f->row_addr_cycles == 3) + info->ndcb2 = (page_addr >> 16) & 0xff; + } else + /* small block, 1 cycles for column address + * row address starts from 2nd cycle + */ + info->ndcb1 = (page_addr << 8) | (column & 0xff); + + if (cmd == cmdset->program) + info->ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS; + + return 0; +} + +static int prepare_erase_cmd(struct pxa3xx_nand_info *info, + uint16_t cmd, int page_addr) +{ + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS | NDCB0_ADDR_CYC(3); + info->ndcb1 = page_addr; + info->ndcb2 = 0; + return 0; +} + +static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd) +{ + struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset; + + info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); + info->ndcb1 = 0; + info->ndcb2 = 0; + + if (cmd == cmdset->read_id) { + info->ndcb0 |= NDCB0_CMD_TYPE(3); + info->data_size = 8; + } else if (cmd == cmdset->read_status) { + info->ndcb0 |= NDCB0_CMD_TYPE(4); + info->data_size = 8; + } else if (cmd == cmdset->reset || cmd == cmdset->lock || + cmd == cmdset->unlock) { + info->ndcb0 |= NDCB0_CMD_TYPE(5); + } else + return -EINVAL; + + return 0; +} + +static void enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) +{ + uint32_t ndcr; + + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~int_mask); +} + +static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) +{ + uint32_t ndcr; + + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr | int_mask); +} + +/* NOTE: it is a must to set ND_RUN firstly, then write command buffer + * otherwise, it does not work + */ +static int write_cmd(struct pxa3xx_nand_info *info) +{ + uint32_t ndcr; + + /* clear status bits and run */ + nand_writel(info, NDSR, NDSR_MASK); + + ndcr = info->reg_ndcr; + + ndcr |= info->use_ecc ? NDCR_ECC_EN : 0; + ndcr |= info->use_dma ? NDCR_DMA_EN : 0; + ndcr |= NDCR_ND_RUN; + + nand_writel(info, NDCR, ndcr); + + if (wait_for_event(info, NDSR_WRCMDREQ)) { + printk(KERN_ERR "timed out writing command\n"); + return -ETIMEDOUT; + } + + nand_writel(info, NDCB0, info->ndcb0); + nand_writel(info, NDCB0, info->ndcb1); + nand_writel(info, NDCB0, info->ndcb2); + return 0; +} + +static int handle_data_pio(struct pxa3xx_nand_info *info) +{ + int ret, timeout = CHIP_DELAY_TIMEOUT; + + switch (info->state) { + case STATE_PIO_WRITING: + __raw_writesl(info->mmio_base + NDDB, info->data_buff, + info->data_size << 2); + + enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + + ret = wait_for_completion_timeout(&info->cmd_complete, timeout); + if (!ret) { + printk(KERN_ERR "program command time out\n"); + return -1; + } + break; + case STATE_PIO_READING: + __raw_readsl(info->mmio_base + NDDB, info->data_buff, + info->data_size << 2); + break; + default: + printk(KERN_ERR "%s: invalid state %d\n", __FUNCTION__, + info->state); + return -EINVAL; + } + + info->state = STATE_READY; + return 0; +} + +static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) +{ + struct pxa_dma_desc *desc = info->data_desc; + int dma_len = ALIGN(info->data_size, 32); + + desc->ddadr = DDADR_STOP; + desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len; + + if (dir_out) { + desc->dsadr = info->data_buff_phys; + desc->dtadr = NDDB_DMA_ADDR; + desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG; + } else { + desc->dtadr = info->data_buff_phys; + desc->dsadr = NDDB_DMA_ADDR; + desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC; + } + + DRCMR(info->drcmr_dat) = DRCMR_MAPVLD | info->data_dma_ch; + DDADR(info->data_dma_ch) = info->data_desc_addr; + DCSR(info->data_dma_ch) |= DCSR_RUN; +} + +static void pxa3xx_nand_data_dma_irq(int channel, void *data) +{ + struct pxa3xx_nand_info *info = data; + uint32_t dcsr; + + dcsr = DCSR(channel); + DCSR(channel) = dcsr; + + if (dcsr & DCSR_BUSERR) { + info->retcode = ERR_DMABUSERR; + complete(&info->cmd_complete); + } + + if (info->state == STATE_DMA_WRITING) { + info->state = STATE_DMA_DONE; + enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + } else { + info->state = STATE_READY; + complete(&info->cmd_complete); + } +} + +static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) +{ + struct pxa3xx_nand_info *info = devid; + unsigned int status; + + status = nand_readl(info, NDSR); + + if (status & (NDSR_RDDREQ | NDSR_DBERR)) { + if (status & NDSR_DBERR) + info->retcode = ERR_DBERR; + + disable_int(info, NDSR_RDDREQ | NDSR_DBERR); + + if (info->use_dma) { + info->state = STATE_DMA_READING; + start_data_dma(info, 0); + } else { + info->state = STATE_PIO_READING; + complete(&info->cmd_complete); + } + } else if (status & NDSR_WRDREQ) { + disable_int(info, NDSR_WRDREQ); + if (info->use_dma) { + info->state = STATE_DMA_WRITING; + start_data_dma(info, 1); + } else { + info->state = STATE_PIO_WRITING; + complete(&info->cmd_complete); + } + } else if (status & (NDSR_CS0_BBD | NDSR_CS0_CMDD)) { + if (status & NDSR_CS0_BBD) + info->retcode = ERR_BBERR; + + disable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + info->state = STATE_READY; + complete(&info->cmd_complete); + } + nand_writel(info, NDSR, status); + return IRQ_HANDLED; +} + +static int pxa3xx_nand_do_cmd(struct pxa3xx_nand_info *info, uint32_t event) +{ + uint32_t ndcr; + int ret, timeout = CHIP_DELAY_TIMEOUT; + + if (write_cmd(info)) { + info->retcode = ERR_SENDCMD; + goto fail_stop; + } + + info->state = STATE_CMD_HANDLE; + + enable_int(info, event); + + ret = wait_for_completion_timeout(&info->cmd_complete, timeout); + if (!ret) { + printk(KERN_ERR "command execution timed out\n"); + info->retcode = ERR_SENDCMD; + goto fail_stop; + } + + if (info->use_dma == 0 && info->data_size > 0) + if (handle_data_pio(info)) + goto fail_stop; + + return 0; + +fail_stop: + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); + udelay(10); + return -ETIMEDOUT; +} + +static int pxa3xx_nand_dev_ready(struct mtd_info *mtd) +{ + struct pxa3xx_nand_info *info = mtd->priv; + return (nand_readl(info, NDSR) & NDSR_RDY) ? 1 : 0; +} + +static inline int is_buf_blank(uint8_t *buf, size_t len) +{ + for (; len > 0; len--) + if (*buf++ != 0xff) + return 0; + return 1; +} + +static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, + int column, int page_addr ) +{ + struct pxa3xx_nand_info *info = mtd->priv; + struct pxa3xx_nand_flash * flash_info = info->flash_info; + struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset; + int ret; + + info->use_dma = (use_dma) ? 1 : 0; + info->use_ecc = 0; + info->data_size = 0; + info->state = STATE_READY; + + init_completion(&info->cmd_complete); + + switch (command) { + case NAND_CMD_READOOB: + /* disable HW ECC to get all the OOB data */ + info->buf_count = mtd->writesize + mtd->oobsize; + info->buf_start = mtd->writesize + column; + + if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) + break; + + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR); + + /* We only are OOB, so if the data has error, does not matter */ + if (info->retcode == ERR_DBERR) + info->retcode = ERR_NONE; + break; + + case NAND_CMD_READ0: + info->use_ecc = 1; + info->retcode = ERR_NONE; + info->buf_start = column; + info->buf_count = mtd->writesize + mtd->oobsize; + memset(info->data_buff, 0xFF, info->buf_count); + + if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) + break; + + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR); + + if (info->retcode == ERR_DBERR) { + /* for blank page (all 0xff), HW will calculate its ECC as + * 0, which is different from the ECC information within + * OOB, ignore such double bit errors + */ + if (is_buf_blank(info->data_buff, mtd->writesize)) + info->retcode = ERR_NONE; + } + break; + case NAND_CMD_SEQIN: + info->buf_start = column; + info->buf_count = mtd->writesize + mtd->oobsize; + memset(info->data_buff, 0xff, info->buf_count); + + /* save column/page_addr for next CMD_PAGEPROG */ + info->seqin_column = column; + info->seqin_page_addr = page_addr; + break; + case NAND_CMD_PAGEPROG: + info->use_ecc = (info->seqin_column >= mtd->writesize) ? 0 : 1; + + if (prepare_read_prog_cmd(info, cmdset->program, + info->seqin_column, info->seqin_page_addr)) + break; + + pxa3xx_nand_do_cmd(info, NDSR_WRDREQ); + break; + case NAND_CMD_ERASE1: + if (prepare_erase_cmd(info, cmdset->erase, page_addr)) + break; + + pxa3xx_nand_do_cmd(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); + break; + case NAND_CMD_ERASE2: + break; + case NAND_CMD_READID: + case NAND_CMD_STATUS: + info->use_dma = 0; /* force PIO read */ + info->buf_start = 0; + info->buf_count = (command == NAND_CMD_READID) ? + flash_info->read_id_bytes : 1; + + if (prepare_other_cmd(info, (command == NAND_CMD_READID) ? + cmdset->read_id : cmdset->read_status)) + break; + + pxa3xx_nand_do_cmd(info, NDSR_RDDREQ); + break; + case NAND_CMD_RESET: + if (prepare_other_cmd(info, cmdset->reset)) + break; + + ret = pxa3xx_nand_do_cmd(info, NDSR_CS0_CMDD); + if (ret == 0) { + int timeout = 2; + uint32_t ndcr; + + while (timeout--) { + if (nand_readl(info, NDSR) & NDSR_RDY) + break; + msleep(10); + } + + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); + } + break; + default: + printk(KERN_ERR "non-supported command.\n"); + break; + } + + if (info->retcode == ERR_DBERR) { + printk(KERN_ERR "double bit error @ page %08x\n", page_addr); + info->retcode = ERR_NONE; + } +} + +static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) +{ + struct pxa3xx_nand_info *info = mtd->priv; + char retval = 0xFF; + + if (info->buf_start < info->buf_count) + /* Has just send a new command? */ + retval = info->data_buff[info->buf_start++]; + + return retval; +} + +static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) +{ + struct pxa3xx_nand_info *info = mtd->priv; + u16 retval = 0xFFFF; + + if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) { + retval = *((u16 *)(info->data_buff+info->buf_start)); + info->buf_start += 2; + } + return retval; +} + +static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct pxa3xx_nand_info *info = mtd->priv; + int real_len = min_t(size_t, len, info->buf_count - info->buf_start); + + memcpy(buf, info->data_buff + info->buf_start, real_len); + info->buf_start += real_len; +} + +static void pxa3xx_nand_write_buf(struct mtd_info *mtd, + const uint8_t *buf, int len) +{ + struct pxa3xx_nand_info *info = mtd->priv; + int real_len = min_t(size_t, len, info->buf_count - info->buf_start); + + memcpy(info->data_buff + info->buf_start, buf, real_len); + info->buf_start += real_len; +} + +static int pxa3xx_nand_verify_buf(struct mtd_info *mtd, + const uint8_t *buf, int len) +{ + return 0; +} + +static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) +{ + return; +} + +static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) +{ + struct pxa3xx_nand_info *info = mtd->priv; + + /* pxa3xx_nand_send_command has waited for command complete */ + if (this->state == FL_WRITING || this->state == FL_ERASING) { + if (info->retcode == ERR_NONE) + return 0; + else { + /* + * any error make it return 0x01 which will tell + * the caller the erase and write fail + */ + return 0x01; + } + } + + return 0; +} + +static void pxa3xx_nand_ecc_hwctl(struct mtd_info *mtd, int mode) +{ + return; +} + +static int pxa3xx_nand_ecc_calculate(struct mtd_info *mtd, + const uint8_t *dat, uint8_t *ecc_code) +{ + return 0; +} + +static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd, + uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) +{ + struct pxa3xx_nand_info *info = mtd->priv; + /* + * Any error include ERR_SEND_CMD, ERR_DBERR, ERR_BUSERR, we + * consider it as a ecc error which will tell the caller the + * read fail We have distinguish all the errors, but the + * nand_read_ecc only check this function return value + */ + if (info->retcode != ERR_NONE) + return -1; + + return 0; +} + +static int __readid(struct pxa3xx_nand_info *info, uint32_t *id) +{ + struct pxa3xx_nand_flash *f = info->flash_info; + struct pxa3xx_nand_cmdset *cmdset = f->cmdset; + uint32_t ndcr; + uint8_t id_buff[8]; + + if (prepare_other_cmd(info, cmdset->read_id)) { + printk(KERN_ERR "failed to prepare command\n"); + return -EINVAL; + } + + /* Send command */ + if (write_cmd(info)) + goto fail_timeout; + + /* Wait for CMDDM(command done successfully) */ + if (wait_for_event(info, NDSR_RDDREQ)) + goto fail_timeout; + + __raw_readsl(info->mmio_base + NDDB, id_buff, 2); + *id = id_buff[0] | (id_buff[1] << 8); + return 0; + +fail_timeout: + ndcr = nand_readl(info, NDCR); + nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN); + udelay(10); + return -ETIMEDOUT; +} + +static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, + struct pxa3xx_nand_flash *f) +{ + struct platform_device *pdev = info->pdev; + struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; + uint32_t ndcr = 0x00000FFF; /* disable all interrupts */ + + if (f->page_size != 2048 && f->page_size != 512) + return -EINVAL; + + if (f->flash_width != 16 && f->flash_width != 8) + return -EINVAL; + + /* calculate flash information */ + f->oob_size = (f->page_size == 2048) ? 64 : 16; + f->read_id_bytes = (f->page_size == 2048) ? 4 : 2; + + /* calculate addressing information */ + f->col_addr_cycles = (f->page_size == 2048) ? 2 : 1; + + if (f->num_blocks * f->page_per_block > 65536) + f->row_addr_cycles = 3; + else + f->row_addr_cycles = 2; + + ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; + ndcr |= (f->col_addr_cycles == 2) ? NDCR_RA_START : 0; + ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0; + ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0; + ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0; + ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0; + + ndcr |= NDCR_RD_ID_CNT(f->read_id_bytes); + ndcr |= NDCR_SPARE_EN; /* enable spare by default */ + + info->reg_ndcr = ndcr; + + pxa3xx_nand_set_timing(info, f->timing); + info->flash_info = f; + return 0; +} + +static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info) +{ + struct pxa3xx_nand_flash *f; + uint32_t id; + int i; + + for (i = 0; i < ARRAY_SIZE(builtin_flash_types); i++) { + + f = builtin_flash_types[i]; + + if (pxa3xx_nand_config_flash(info, f)) + continue; + + if (__readid(info, &id)) + continue; + + if (id == f->chip_id) + return 0; + } + + return -ENODEV; +} + +/* the maximum possible buffer size for large page with OOB data + * is: 2048 + 64 = 2112 bytes, allocate a page here for both the + * data buffer and the DMA descriptor + */ +#define MAX_BUFF_SIZE PAGE_SIZE + +static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) +{ + struct platform_device *pdev = info->pdev; + int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc); + + if (use_dma == 0) { + info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL); + if (info->data_buff == NULL) + return -ENOMEM; + return 0; + } + + info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE, + &info->data_buff_phys, GFP_KERNEL); + if (info->data_buff == NULL) { + dev_err(&pdev->dev, "failed to allocate dma buffer\n"); + return -ENOMEM; + } + + info->data_buff_size = MAX_BUFF_SIZE; + info->data_desc = (void *)info->data_buff + data_desc_offset; + info->data_desc_addr = info->data_buff_phys + data_desc_offset; + + info->data_dma_ch = pxa_request_dma("nand-data", DMA_PRIO_LOW, + pxa3xx_nand_data_dma_irq, info); + if (info->data_dma_ch < 0) { + dev_err(&pdev->dev, "failed to request data dma\n"); + dma_free_coherent(&pdev->dev, info->data_buff_size, + info->data_buff, info->data_buff_phys); + return info->data_dma_ch; + } + + return 0; +} + +static struct nand_ecclayout hw_smallpage_ecclayout = { + .eccbytes = 6, + .eccpos = {8, 9, 10, 11, 12, 13 }, + .oobfree = { {2, 6} } +}; + +static struct nand_ecclayout hw_largepage_ecclayout = { + .eccbytes = 24, + .eccpos = { + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { {2, 38} } +}; + +static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, + struct pxa3xx_nand_info *info) +{ + struct pxa3xx_nand_flash *f = info->flash_info; + struct nand_chip *this = &info->nand_chip; + + this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0; + + this->waitfunc = pxa3xx_nand_waitfunc; + this->select_chip = pxa3xx_nand_select_chip; + this->dev_ready = pxa3xx_nand_dev_ready; + this->cmdfunc = pxa3xx_nand_cmdfunc; + this->read_word = pxa3xx_nand_read_word; + this->read_byte = pxa3xx_nand_read_byte; + this->read_buf = pxa3xx_nand_read_buf; + this->write_buf = pxa3xx_nand_write_buf; + this->verify_buf = pxa3xx_nand_verify_buf; + + this->ecc.mode = NAND_ECC_HW; + this->ecc.hwctl = pxa3xx_nand_ecc_hwctl; + this->ecc.calculate = pxa3xx_nand_ecc_calculate; + this->ecc.correct = pxa3xx_nand_ecc_correct; + this->ecc.size = f->page_size; + + if (f->page_size == 2048) + this->ecc.layout = &hw_largepage_ecclayout; + else + this->ecc.layout = &hw_smallpage_ecclayout; + + this->chip_delay= 25; +} + +static int pxa3xx_nand_probe(struct platform_device *pdev) +{ + struct pxa3xx_nand_platform_data *pdata; + struct pxa3xx_nand_info *info; + struct nand_chip *this; + struct mtd_info *mtd; + struct resource *r; + int ret = 0, irq; + + pdata = pdev->dev.platform_data; + + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data defined\n"); + return -ENODEV; + } + + mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), + GFP_KERNEL); + if (mtd == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + info = (struct pxa3xx_nand_info *)(&mtd[1]); + info->pdev = pdev; + + this = &info->nand_chip; + mtd->priv = info; + + info->clk = clk_get(&pdev->dev, "NANDCLK"); + if (IS_ERR(info->clk)) { + dev_err(&pdev->dev, "failed to get nand clock\n"); + ret = PTR_ERR(info->clk); + goto fail_free_mtd; + } + clk_enable(info->clk); + + r = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no resource defined for data DMA\n"); + ret = -ENXIO; + goto fail_put_clk; + } + info->drcmr_dat = r->start; + + r = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (r == NULL) { + dev_err(&pdev->dev, "no resource defined for command DMA\n"); + ret = -ENXIO; + goto fail_put_clk; + } + info->drcmr_cmd = r->start; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no IRQ resource defined\n"); + ret = -ENXIO; + goto fail_put_clk; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no IO memory resource defined\n"); + ret = -ENODEV; + goto fail_put_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto fail_put_clk; + } + + info->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (info->mmio_base == NULL) { + dev_err(&pdev->dev, "ioremap() failed\n"); + ret = -ENODEV; + goto fail_free_res; + } + + ret = pxa3xx_nand_init_buff(info); + if (ret) + goto fail_free_io; + + ret = request_irq(IRQ_NAND, pxa3xx_nand_irq, IRQF_DISABLED, + pdev->name, info); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request IRQ\n"); + goto fail_free_buf; + } + + ret = pxa3xx_nand_detect_flash(info); + if (ret) { + dev_err(&pdev->dev, "failed to detect flash\n"); + ret = -ENODEV; + goto fail_free_irq; + } + + pxa3xx_nand_init_mtd(mtd, info); + + platform_set_drvdata(pdev, mtd); + + if (nand_scan(mtd, 1)) { + dev_err(&pdev->dev, "failed to scan nand\n"); + ret = -ENXIO; + goto fail_free_irq; + } + + return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); + +fail_free_irq: + free_irq(IRQ_NAND, info); +fail_free_buf: + if (use_dma) { + pxa_free_dma(info->data_dma_ch); + dma_free_coherent(&pdev->dev, info->data_buff_size, + info->data_buff, info->data_buff_phys); + } else + kfree(info->data_buff); +fail_free_io: + iounmap(info->mmio_base); +fail_free_res: + release_mem_region(r->start, r->end - r->start + 1); +fail_put_clk: + clk_disable(info->clk); + clk_put(info->clk); +fail_free_mtd: + kfree(mtd); + return ret; +} + +static int pxa3xx_nand_remove(struct platform_device *pdev) +{ + struct mtd_info *mtd = platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; + + platform_set_drvdata(pdev, NULL); + + del_mtd_device(mtd); + del_mtd_partitions(mtd); + free_irq(IRQ_NAND, info); + if (use_dma) { + pxa_free_dma(info->data_dma_ch); + dma_free_writecombine(&pdev->dev, info->data_buff_size, + info->data_buff, info->data_buff_phys); + } else + kfree(info->data_buff); + kfree(mtd); + return 0; +} + +#ifdef CONFIG_PM +static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; + + if (info->state != STATE_READY) { + dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); + return -EAGAIN; + } + + return 0; +} + +static int pxa3xx_nand_resume(struct platform_device *pdev) +{ + struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev); + struct pxa3xx_nand_info *info = mtd->priv; + + clk_enable(info->clk); + + return pxa3xx_nand_config_flash(info); +} +#else +#define pxa3xx_nand_suspend NULL +#define pxa3xx_nand_resume NULL +#endif + +static struct platform_driver pxa3xx_nand_driver = { + .driver = { + .name = "pxa3xx-nand", + }, + .probe = pxa3xx_nand_probe, + .remove = pxa3xx_nand_remove, + .suspend = pxa3xx_nand_suspend, + .resume = pxa3xx_nand_resume, +}; + +static int __init pxa3xx_nand_init(void) +{ + return platform_driver_register(&pxa3xx_nand_driver); +} +module_init(pxa3xx_nand_init); + +static void __exit pxa3xx_nand_exit(void) +{ + platform_driver_unregister(&pxa3xx_nand_driver); +} +module_exit(pxa3xx_nand_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PXA3xx NAND controller driver"); -- cgit v1.2.2 From ca5c23c3b8882d61bf19b7685f2244501902869f Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Wed, 27 Feb 2008 01:42:39 +0200 Subject: [MTD] XIP: Use generic xip_iprefetch() instead of asm volatile (...) Untested, but shouldn't break anything... Makes MTD_XIP arch independent. I guess this is why xip_iprefetch() was made for. Signed-off-by: Paulius Zaleckas Acked-by: Nicolas Pitre Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 4 ++-- drivers/mtd/chips/cfi_cmdset_0002.c | 4 ++-- drivers/mtd/chips/cfi_probe.c | 2 +- drivers/mtd/chips/cfi_util.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 81b7767a665a..eb0e30824ddb 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1071,10 +1071,10 @@ static int __xipram xip_wait_for_operation( chip->state = newstate; map_write(map, CMD(0xff), adr); (void) map_read(map, adr); - asm volatile (".rep 8; nop; .endr"); + xip_iprefetch(); local_irq_enable(); spin_unlock(chip->mutex); - asm volatile (".rep 8; nop; .endr"); + xip_iprefetch(); cond_resched(); /* diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 458d477614d6..5cd657322bc4 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -723,10 +723,10 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip, chip->erase_suspended = 1; map_write(map, CMD(0xf0), adr); (void) map_read(map, adr); - asm volatile (".rep 8; nop; .endr"); + xip_iprefetch(); local_irq_enable(); spin_unlock(chip->mutex); - asm volatile (".rep 8; nop; .endr"); + xip_iprefetch(); cond_resched(); /* diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index f651b6ef1c5d..b03d43ef9108 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -39,7 +39,7 @@ struct mtd_info *cfi_probe(struct map_info *map); #define xip_allowed(base, map) \ do { \ (void) map_read(map, base); \ - asm volatile (".rep 8; nop; .endr"); \ + xip_iprefetch(); \ local_irq_enable(); \ } while (0) diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 2e51496c248e..72e0022a47bf 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -65,7 +65,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n #ifdef CONFIG_MTD_XIP (void) map_read(map, base); - asm volatile (".rep 8; nop; .endr"); + xip_iprefetch(); local_irq_enable(); #endif -- cgit v1.2.2 From 757570063a350ee3875c42a6338d29ee09f5af07 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 3 Mar 2008 18:30:24 +0100 Subject: [MTD] [MAPS] Extend plat-ram to support a supplied probe type This enhances plat-ram to take a map_probes argument in the platform_data structure which allow plat-ram to support any direct-mapped device that MTD supports (jedec, cfi, amd ..) A few items are also fixed: - Don't panic if probes is 0 - Actually use the partition list that is passed in Signed-off-by: Florian Fainelli Signed-off-by: Jason Gunthorpe Signed-off-by: David Woodhouse --- drivers/mtd/maps/plat-ram.c | 47 ++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 7160e0eb09af..f0b10ca05029 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -47,6 +47,7 @@ struct platram_info { struct mtd_info *mtd; struct map_info map; struct mtd_partition *partitions; + bool free_partitions; struct resource *area; struct platdata_mtd_ram *pdata; }; @@ -98,7 +99,8 @@ static int platram_remove(struct platform_device *pdev) #ifdef CONFIG_MTD_PARTITIONS if (info->partitions) { del_mtd_partitions(info->mtd); - kfree(info->partitions); + if (info->free_partitions) + kfree(info->partitions); } #endif del_mtd_device(info->mtd); @@ -176,7 +178,8 @@ static int platram_probe(struct platform_device *pdev) info->map.phys = res->start; info->map.size = (res->end - res->start) + 1; - info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pdev->name; + info->map.name = pdata->mapname != NULL ? + (char *)pdata->mapname : (char *)pdev->name; info->map.bankwidth = pdata->bankwidth; /* register our usage of the memory area */ @@ -203,9 +206,19 @@ static int platram_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "initialised map, probing for mtd\n"); - /* probe for the right mtd map driver */ + /* probe for the right mtd map driver + * supplied by the platform_data struct */ + + if (pdata->map_probes != 0) { + const char **map_probes = pdata->map_probes; + + for ( ; !info->mtd && *map_probes; map_probes++) + info->mtd = do_map_probe(*map_probes , &info->map); + } + /* fallback to map_ram */ + else + info->mtd = do_map_probe("map_ram", &info->map); - info->mtd = do_map_probe("map_ram" , &info->map); if (info->mtd == NULL) { dev_err(&pdev->dev, "failed to probe for map_ram\n"); err = -ENOMEM; @@ -220,19 +233,21 @@ static int platram_probe(struct platform_device *pdev) * to add this device whole */ #ifdef CONFIG_MTD_PARTITIONS - if (pdata->nr_partitions > 0) { - const char **probes = { NULL }; - - if (pdata->probes) - probes = (const char **)pdata->probes; - - err = parse_mtd_partitions(info->mtd, probes, + if (!pdata->nr_partitions) { + /* try to probe using the supplied probe type */ + if (pdata->probes) { + err = parse_mtd_partitions(info->mtd, pdata->probes, &info->partitions, 0); - if (err > 0) { - err = add_mtd_partitions(info->mtd, info->partitions, - err); + info->free_partitions = 1; + if (err > 0) + err = add_mtd_partitions(info->mtd, + info->partitions, err); } } + /* use the static mapping */ + else + err = add_mtd_partitions(info->mtd, pdata->partitions, + pdata->nr_partitions); #endif /* CONFIG_MTD_PARTITIONS */ if (add_mtd_device(info->mtd)) { @@ -240,7 +255,9 @@ static int platram_probe(struct platform_device *pdev) err = -ENOMEM; } - dev_info(&pdev->dev, "registered mtd device\n"); + if (!err) + dev_info(&pdev->dev, "registered mtd device\n"); + return err; exit_free: -- cgit v1.2.2 From 1b0a062be7fccfbf0218a81c98c0e4d380ee23f5 Mon Sep 17 00:00:00 2001 From: Andrei Dolnikov Date: Mon, 3 Mar 2008 21:01:21 +0300 Subject: [MTD] [NOR] Add JEDEC support for the SST 36VF3203 flash chip Add support for the SST 36VF3203 flash chip. It is used on Emerson KSI8560 board. Signed-off-by: Andrei Dolnikov Signed-off-by: David Woodhouse --- drivers/mtd/chips/jedec_probe.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 880a2fd734ff..aa07575eb288 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -162,6 +162,7 @@ #define SST49LF030A 0x001C #define SST49LF040A 0x0051 #define SST49LF080A 0x005B +#define SST36VF3203 0x7354 /* Toshiba */ #define TC58FVT160 0x00C2 @@ -1413,6 +1414,18 @@ static const struct amd_flash_info jedec_table[] = { ERASEINFO(0x1000,256), ERASEINFO(0x1000,256) } + }, { + .mfr_id = MANUFACTURER_SST, + .dev_id = SST36VF3203, + .name = "SST 36VF3203", + .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, + .uaddr = MTD_UADDR_0x0AAA_0x0555, + .dev_size = SIZE_4MiB, + .cmd_set = P_ID_AMD_STD, + .nr_regions = 1, + .regions = { + ERASEINFO(0x10000,64), + } }, { .mfr_id = MANUFACTURER_ST, .dev_id = M29F800AB, -- cgit v1.2.2 From a1c06ee11f0b83e372c958b165338f579d17e3d4 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 22 Apr 2008 20:39:43 +0100 Subject: [MTD] [NAND] Fix checkpatch errors in pxa3xx_nand Signed-off-by: David Woodhouse --- drivers/mtd/nand/pxa3xx_nand.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 138e219c2304..fceb468ccdec 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -494,7 +494,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) info->data_size << 2); break; default: - printk(KERN_ERR "%s: invalid state %d\n", __FUNCTION__, + printk(KERN_ERR "%s: invalid state %d\n", __func__, info->state); return -EINVAL; } @@ -638,10 +638,10 @@ static inline int is_buf_blank(uint8_t *buf, size_t len) } static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, - int column, int page_addr ) + int column, int page_addr) { struct pxa3xx_nand_info *info = mtd->priv; - struct pxa3xx_nand_flash * flash_info = info->flash_info; + struct pxa3xx_nand_flash *flash_info = info->flash_info; struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset; int ret; @@ -1040,7 +1040,7 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, else this->ecc.layout = &hw_smallpage_ecclayout; - this->chip_delay= 25; + this->chip_delay = 25; } static int pxa3xx_nand_probe(struct platform_device *pdev) @@ -1054,17 +1054,17 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; - if (pdata == NULL) { + if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -ENODEV; } mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), GFP_KERNEL); - if (mtd == NULL) { + if (!mtd) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; - } + } info = (struct pxa3xx_nand_info *)(&mtd[1]); info->pdev = pdev; -- cgit v1.2.2 From 5c249c5a57dce2b47f1fb92093201b3a7013cb57 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 11 Mar 2008 22:33:13 +0300 Subject: [MTD] [NAND] FSL UPM NAND driver This is very simple driver, NAND is connected through localbus, and User-Programmable Machine is doing various adjustments to speak NAND. No special efforts needed to do read and write cycles, though to control ALE and CLE phases, we ask UPM to generate exact pre-programmed signals on the localbus lines. Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 8 ++ drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/fsl_upm.c | 291 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 drivers/mtd/nand/fsl_upm.c (limited to 'drivers') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 180fc7be1826..dcbb0decd465 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -337,4 +337,12 @@ config MTD_NAND_FSL_ELBC Enabling this option will enable you to use this to control external NAND devices. +config MTD_NAND_FSL_UPM + tristate "Support for NAND on Freescale UPM" + depends on MTD_NAND && OF_GPIO && (PPC_83xx || PPC_85xx) + select FSL_LBC + help + Enables support for NAND Flash chips wired onto Freescale PowerPC + processor localbus with User-Programmable Machine support. + endif # MTD_NAND diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 54a332bda3da..a6e74a46992a 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -33,5 +33,6 @@ obj-$(CONFIG_MTD_ALAUDA) += alauda.o obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o +obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o nand-objs := nand_base.o nand_bbt.o diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c new file mode 100644 index 000000000000..1ebfd87f00b4 --- /dev/null +++ b/drivers/mtd/nand/fsl_upm.c @@ -0,0 +1,291 @@ +/* + * Freescale UPM NAND driver. + * + * Copyright © 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * 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 + +struct fsl_upm_nand { + struct device *dev; + struct mtd_info mtd; + struct nand_chip chip; + int last_ctrl; +#ifdef CONFIG_MTD_PARTITIONS + struct mtd_partition *parts; +#endif + + struct fsl_upm upm; + uint8_t upm_addr_offset; + uint8_t upm_cmd_offset; + void __iomem *io_base; + int rnb_gpio; + const uint32_t *wait_pattern; + const uint32_t *wait_write; + int chip_delay; +}; + +#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) + +static int fun_chip_ready(struct mtd_info *mtd) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); + + if (gpio_get_value(fun->rnb_gpio)) + return 1; + + dev_vdbg(fun->dev, "busy\n"); + return 0; +} + +static void fun_wait_rnb(struct fsl_upm_nand *fun) +{ + int cnt = 1000000; + + if (fun->rnb_gpio >= 0) { + while (--cnt && !fun_chip_ready(&fun->mtd)) + cpu_relax(); + } + + if (!cnt) + dev_err(fun->dev, "tired waiting for RNB\n"); +} + +static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); + + if (!(ctrl & fun->last_ctrl)) { + fsl_upm_end_pattern(&fun->upm); + + if (cmd == NAND_CMD_NONE) + return; + + fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE); + } + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_ALE) + fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); + else if (ctrl & NAND_CLE) + fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); + } + + fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); + + if (fun->wait_pattern) + fun_wait_rnb(fun); +} + +static uint8_t fun_read_byte(struct mtd_info *mtd) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); + + return in_8(fun->chip.IO_ADDR_R); +} + +static void fun_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); + int i; + + for (i = 0; i < len; i++) + buf[i] = in_8(fun->chip.IO_ADDR_R); +} + +static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); + int i; + + for (i = 0; i < len; i++) { + out_8(fun->chip.IO_ADDR_W, buf[i]); + if (fun->wait_write) + fun_wait_rnb(fun); + } +} + +static int __devinit fun_chip_init(struct fsl_upm_nand *fun) +{ + int ret; +#ifdef CONFIG_MTD_PARTITIONS + static const char *part_types[] = { "cmdlinepart", NULL, }; +#endif + + fun->chip.IO_ADDR_R = fun->io_base; + fun->chip.IO_ADDR_W = fun->io_base; + fun->chip.cmd_ctrl = fun_cmd_ctrl; + fun->chip.chip_delay = fun->chip_delay; + fun->chip.read_byte = fun_read_byte; + fun->chip.read_buf = fun_read_buf; + fun->chip.write_buf = fun_write_buf; + fun->chip.ecc.mode = NAND_ECC_SOFT; + + if (fun->rnb_gpio >= 0) + fun->chip.dev_ready = fun_chip_ready; + + fun->mtd.priv = &fun->chip; + fun->mtd.owner = THIS_MODULE; + + ret = nand_scan(&fun->mtd, 1); + if (ret) + return ret; + + fun->mtd.name = fun->dev->bus_id; + +#ifdef CONFIG_MTD_PARTITIONS + ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); + if (ret > 0) + return add_mtd_partitions(&fun->mtd, fun->parts, ret); +#endif + return add_mtd_device(&fun->mtd); +} + +static int __devinit fun_probe(struct of_device *ofdev, + const struct of_device_id *ofid) +{ + struct fsl_upm_nand *fun; + struct resource io_res; + const uint32_t *prop; + int ret; + int size; + + fun = kzalloc(sizeof(*fun), GFP_KERNEL); + if (!fun) + return -ENOMEM; + + ret = of_address_to_resource(ofdev->node, 0, &io_res); + if (ret) { + dev_err(&ofdev->dev, "can't get IO base\n"); + goto err1; + } + + ret = fsl_upm_find(io_res.start, &fun->upm); + if (ret) { + dev_err(&ofdev->dev, "can't find UPM\n"); + goto err1; + } + + prop = of_get_property(ofdev->node, "fsl,upm-addr-offset", &size); + if (!prop || size != sizeof(uint32_t)) { + dev_err(&ofdev->dev, "can't get UPM address offset\n"); + ret = -EINVAL; + goto err2; + } + fun->upm_addr_offset = *prop; + + prop = of_get_property(ofdev->node, "fsl,upm-cmd-offset", &size); + if (!prop || size != sizeof(uint32_t)) { + dev_err(&ofdev->dev, "can't get UPM command offset\n"); + ret = -EINVAL; + goto err2; + } + fun->upm_cmd_offset = *prop; + + fun->rnb_gpio = of_get_gpio(ofdev->node, 0); + if (fun->rnb_gpio >= 0) { + ret = gpio_request(fun->rnb_gpio, ofdev->dev.bus_id); + if (ret) { + dev_err(&ofdev->dev, "can't request RNB gpio\n"); + goto err2; + } + gpio_direction_input(fun->rnb_gpio); + } else if (fun->rnb_gpio == -EINVAL) { + dev_err(&ofdev->dev, "specified RNB gpio is invalid\n"); + goto err2; + } + + fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, + io_res.end - io_res.start + 1); + if (!fun->io_base) { + ret = -ENOMEM; + goto err2; + } + + fun->dev = &ofdev->dev; + fun->last_ctrl = NAND_CLE; + fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern", + NULL); + fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL); + + prop = of_get_property(ofdev->node, "chip-delay", NULL); + if (prop) + fun->chip_delay = *prop; + else + fun->chip_delay = 50; + + ret = fun_chip_init(fun); + if (ret) + goto err2; + + dev_set_drvdata(&ofdev->dev, fun); + + return 0; +err2: + if (fun->rnb_gpio >= 0) + gpio_free(fun->rnb_gpio); +err1: + kfree(fun); + + return ret; +} + +static int __devexit fun_remove(struct of_device *ofdev) +{ + struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); + + nand_release(&fun->mtd); + + if (fun->rnb_gpio >= 0) + gpio_free(fun->rnb_gpio); + + kfree(fun); + + return 0; +} + +static struct of_device_id of_fun_match[] = { + { .compatible = "fsl,upm-nand" }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_fun_match); + +static struct of_platform_driver of_fun_driver = { + .name = "fsl,upm-nand", + .match_table = of_fun_match, + .probe = fun_probe, + .remove = __devexit_p(fun_remove), +}; + +static int __init fun_module_init(void) +{ + return of_register_platform_driver(&of_fun_driver); +} +module_init(fun_module_init); + +static void __exit fun_module_exit(void) +{ + of_unregister_platform_driver(&of_fun_driver); +} +module_exit(fun_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Anton Vorontsov "); +MODULE_DESCRIPTION("Driver for NAND chips working through Freescale " + "LocalBus User-Programmable Machine"); -- cgit v1.2.2 From f0797881d59ab93d7d92c55411e0573977d909d4 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Wed, 12 Mar 2008 02:25:06 +0100 Subject: [MTD] AR7 mtd partition map Signed-off-by: Matteo Croce Signed-off-by: Felix Fietkau Signed-off-by: Eugene Konev Signed-off-by: David Woodhouse --- drivers/mtd/Kconfig | 6 +++ drivers/mtd/Makefile | 1 + drivers/mtd/ar7part.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 drivers/mtd/ar7part.c (limited to 'drivers') diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index e8503341e3b1..eed06d068fd1 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -158,6 +158,12 @@ config MTD_OF_PARTS the partition map from the children of the flash node, as described in Documentation/powerpc/booting-without-of.txt. +config MTD_AR7_PARTS + tristate "TI AR7 partitioning support" + depends on MTD_PARTITIONS + ---help--- + TI AR7 partitioning support + comment "User Modules And Translation Layers" config MTD_CHAR diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 538e33d11d46..4b77335715f0 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o # 'Users' - code which presents functionality to userspace. diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c new file mode 100644 index 000000000000..7722608d5a83 --- /dev/null +++ b/drivers/mtd/ar7part.c @@ -0,0 +1,146 @@ +/* + * Copyright © 2007 Eugene Konev + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * TI AR7 flash partition table. + * Based on ar7 map by Felix Fietkau + * + */ + +#include +#include + +#include +#include +#include +#include + +#define AR7_PARTS 4 +#define ROOT_OFFSET 0xe0000 + +#define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) +#define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) + +struct ar7_bin_rec { + unsigned int checksum; + unsigned int length; + unsigned int address; +}; + +static struct mtd_partition ar7_parts[AR7_PARTS]; + +static int create_mtd_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long origin) +{ + struct ar7_bin_rec header; + unsigned int offset, len; + unsigned int pre_size = master->erasesize, post_size = 0; + unsigned int root_offset = ROOT_OFFSET; + + int retries = 10; + + ar7_parts[0].name = "loader"; + ar7_parts[0].offset = 0; + ar7_parts[0].size = master->erasesize; + ar7_parts[0].mask_flags = MTD_WRITEABLE; + + ar7_parts[1].name = "config"; + ar7_parts[1].offset = 0; + ar7_parts[1].size = master->erasesize; + ar7_parts[1].mask_flags = 0; + + do { /* Try 10 blocks starting from master->erasesize */ + offset = pre_size; + master->read(master, offset, + sizeof(header), &len, (u8 *)&header); + if (!strncmp((char *)&header, "TIENV0.8", 8)) + ar7_parts[1].offset = pre_size; + if (header.checksum == LOADER_MAGIC1) + break; + if (header.checksum == LOADER_MAGIC2) + break; + pre_size += master->erasesize; + } while (retries--); + + pre_size = offset; + + if (!ar7_parts[1].offset) { + ar7_parts[1].offset = master->size - master->erasesize; + post_size = master->erasesize; + } + + switch (header.checksum) { + case LOADER_MAGIC1: + while (header.length) { + offset += sizeof(header) + header.length; + master->read(master, offset, sizeof(header), + &len, (u8 *)&header); + } + root_offset = offset + sizeof(header) + 4; + break; + case LOADER_MAGIC2: + while (header.length) { + offset += sizeof(header) + header.length; + master->read(master, offset, sizeof(header), + &len, (u8 *)&header); + } + root_offset = offset + sizeof(header) + 4 + 0xff; + root_offset &= ~(u32)0xff; + break; + default: + printk(KERN_WARNING "Unknown magic: %08x\n", header.checksum); + break; + } + + master->read(master, root_offset, + sizeof(header), &len, (u8 *)&header); + if (header.checksum != SQUASHFS_MAGIC) { + root_offset += master->erasesize - 1; + root_offset &= ~(master->erasesize - 1); + } + + ar7_parts[2].name = "linux"; + ar7_parts[2].offset = pre_size; + ar7_parts[2].size = master->size - pre_size - post_size; + ar7_parts[2].mask_flags = 0; + + ar7_parts[3].name = "rootfs"; + ar7_parts[3].offset = root_offset; + ar7_parts[3].size = master->size - root_offset - post_size; + ar7_parts[3].mask_flags = 0; + + *pparts = ar7_parts; + return AR7_PARTS; +} + +static struct mtd_part_parser ar7_parser = { + .owner = THIS_MODULE, + .parse_fn = create_mtd_partitions, + .name = "ar7part", +}; + +static int __init ar7_parser_init(void) +{ + return register_mtd_parser(&ar7_parser); +} + +module_init(ar7_parser_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR( "Felix Fietkau , " + "Eugene Konev "); +MODULE_DESCRIPTION("MTD partitioning for TI AR7"); -- cgit v1.2.2 From 9ebed3e60f9991e980e6c38b0edbdf9c8ff2ff6d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 18 Mar 2008 19:34:03 +0300 Subject: [MTD] [NAND] fsl_elbc_nand: fix mtd name Currently fsl_elbc_nand doesn't initialize mtd->name, and this causes nand_get_flash_type() to assign name that is equal to chip type, like this: root@b1:~# cat /proc/mtd dev: size erasesize name mtd0: 00800000 00010000 "fe000000.flash" mtd1: 02000000 00004000 "NAND 32MiB 3,3V 8-bit" mtd0 is physmap_of flash (normal name), and mtd1 is fsl_elbc_nand. Despite inconsistency, with mtd name like this specifying paritions from the kernel command line becomes a torture (though, I didn't tried and not sure if mtdparts= can handle spaces at all). Plus, this causes real bugs when multiple fsl_elbc_nand chips registered. With this patch applied fsl_elbc_nand chip will have proper name: root@b1:~# cat /proc/mtd dev: size erasesize name mtd0: 00800000 00010000 "fe000000.flash" mtd1: 02000000 00004000 "e0600000.flash" p.s. We can't use priv->dev->bus_id as in physmap_of, because fsl_elbc_nand pretends to be a localbus controller, so its bus_id is "address.localbus", which is incorrect and thus will also not work for multiple chips. Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsl_elbc_nand.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index b9f9f22cd860..cb12b67ce5ef 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -780,6 +780,8 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) nand_release(&priv->mtd); + kfree(priv->mtd.name); + if (priv->vbase) iounmap(priv->vbase); @@ -840,6 +842,12 @@ static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, goto err; } + priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", res.start); + if (!priv->mtd.name) { + ret = -ENOMEM; + goto err; + } + ret = fsl_elbc_chip_init(priv); if (ret) goto err; -- cgit v1.2.2 From 1938de46cb7e108120ffbf5155678a2a5e05b377 Mon Sep 17 00:00:00 2001 From: Mike Hench Date: Wed, 19 Mar 2008 12:40:15 -0500 Subject: [MTD] [NAND] corrected MPC8313 NAND fixes Fix a race condition in fsl_elbc_run_command Fix incorrect usage of clearbits32 that bashed option register Remove work around for bashed register Signed-off-by: Mike Hench Acked-by: Scott Wood Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsl_elbc_nand.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index cb12b67ce5ef..919c192b8f27 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -184,11 +184,11 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) in_be32(&lbc->fbar), in_be32(&lbc->fpar), in_be32(&lbc->fbcr), priv->bank); + ctrl->irq_status = 0; /* execute special operation */ out_be32(&lbc->lsor, priv->bank); /* wait for FCM complete flag or timeout */ - ctrl->irq_status = 0; wait_event_timeout(ctrl->irq_wait, ctrl->irq_status, FCM_TIMEOUT_MSECS * HZ/1000); ctrl->status = ctrl->irq_status; @@ -667,7 +667,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) /* adjust Option Register and ECC to match Flash page size */ if (mtd->writesize == 512) { priv->page_size = 0; - clrbits32(&lbc->bank[priv->bank].or, ~OR_FCM_PGS); + clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); } else if (mtd->writesize == 2048) { priv->page_size = 1; setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); @@ -688,11 +688,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) return -1; } - /* The default u-boot configuration on MPC8313ERDB causes errors; - * more delay is needed. This should be safe for other boards - * as well. - */ - setbits32(&lbc->bank[priv->bank].or, 0x70); return 0; } -- cgit v1.2.2 From 93919d384df98eba02bebd417ecb2f481b3bdcb8 Mon Sep 17 00:00:00 2001 From: Hamish Moffatt Date: Fri, 28 Mar 2008 15:00:00 +1100 Subject: [MTD] [NAND] plat_nand: set mtd->name This patch sets mtd->name to the platform bus ID in the plat_nand driver, so that you can specify partitions readily with mtdparts=. Currently it relies on nand_base filling in the name from the device, which results in names like "NAND 256MiB 3,3V 8-bit", that you can't use with cmdlineparts. Signed-off-by: Hamish Moffatt Signed-off-by: David Woodhouse --- drivers/mtd/nand/plat_nand.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 0fdb93ebc2fa..f674c5427b17 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -54,6 +54,7 @@ static int __init plat_nand_probe(struct platform_device *pdev) data->chip.priv = &data; data->mtd.priv = &data->chip; data->mtd.owner = THIS_MODULE; + data->mtd.name = pdev->dev.bus_id; data->chip.IO_ADDR_R = data->io_base; data->chip.IO_ADDR_W = data->io_base; -- cgit v1.2.2 From 0ff6631be150702ed4c92b46b77941affee866ba Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 28 Mar 2008 22:10:54 +0300 Subject: [MTD] [NAND] fsl_elbc_nand: workaround for hangs during nand write Using current driver elbc sometimes hangs during nand write. Reading back last byte helps though (thanks to Scott Wood for the idea). Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsl_elbc_nand.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 919c192b8f27..4b69aacdf5ca 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -481,7 +481,7 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) struct fsl_elbc_ctrl *ctrl = priv->ctrl; unsigned int bufsize = mtd->writesize + mtd->oobsize; - if (len < 0) { + if (len <= 0) { dev_err(ctrl->dev, "write_buf of %d bytes", len); ctrl->status = 0; return; @@ -496,6 +496,15 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) } memcpy_toio(&ctrl->addr[ctrl->index], buf, len); + /* + * This is workaround for the weird elbc hangs during nand write, + * Scott Wood says: "...perhaps difference in how long it takes a + * write to make it through the localbus compared to a write to IMMR + * is causing problems, and sync isn't helping for some reason." + * Reading back the last byte helps though. + */ + in_8(&ctrl->addr[ctrl->index] + len - 1); + ctrl->index += len; } -- cgit v1.2.2 From fecb8865def541ff38f59ef3caf0cbd09f4fc9fd Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sun, 30 Mar 2008 21:19:29 -0700 Subject: [MTD] [NOR] Read extended device ID from AMD/Spansion CFI flash chips AMD/Spansion use a device id of 0x7e to indicate an extended device is present at offset 0xe and 0xf in the query data. I've verified with Spansion that all their chips (mfr == 0x01) with an id of 0x7e use it to indicate an extended id is present. What's more, there are no chips with a NON-extended id that is the same as a different chip's extended id. In other words, when the extended ID is present, one can replace the normal id with the extended id without losing any information. Which is what I've done. Signed-off-by: Trent Piepho Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_probe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index b03d43ef9108..a4463a91ce31 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -232,6 +232,11 @@ static int __xipram cfi_chip_setup(struct map_info *map, cfi->mfr = cfi_read_query16(map, base); cfi->id = cfi_read_query16(map, base + ofs_factor); + /* Get AMD/Spansion extended JEDEC ID */ + if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e) + cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 | + cfi_read_query(map, base + 0xf * ofs_factor); + /* Put it back into Read Mode */ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); /* ... even if it's an Intel chip */ -- cgit v1.2.2 From 70b072550a59e787b46030ab104ac64e25fcc732 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sun, 30 Mar 2008 21:19:30 -0700 Subject: [MTD] [NOR] Fixup for incorrect CFI data in Spansion S29GL064/32N flash chips This is a known erratum confirmed by Spansion. I have an errata document, but I can't find a link to it anywhere on their site to include here. Some of the S29GL064N chips report 64 sectors when they should report 128, and some of S29GL032N chips report 127 sectors when they should report 63. Note that when the chip dies are fixed by Spansion, they will still have the same id. The fix is done in such a way that it won't affect corrected chips. The fixups use the extended id made available by a previous patch. Without that, virtually all newer AMD/Spansion chips will have the same ID (0x227e) and it's not possible to apply the fixup to the correct chips. Signed-off-by: Trent Piepho Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0002.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5cd657322bc4..f7fcc6389533 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -220,6 +220,28 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param) mtd->flags |= MTD_POWERUP_LOCK; } +static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + if ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0x003f) { + cfi->cfiq->EraseRegionInfo[0] |= 0x0040; + pr_warning("%s: Bad S29GL064N CFI data, adjust from 64 to 128 sectors\n", mtd->name); + } +} + +static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + if ((cfi->cfiq->EraseRegionInfo[1] & 0xffff) == 0x007e) { + cfi->cfiq->EraseRegionInfo[1] &= ~0x0040; + pr_warning("%s: Bad S29GL032N CFI data, adjust from 127 to 63 sectors\n", mtd->name); + } +} + static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, #ifdef AMD_BOOTLOC_BUG @@ -231,6 +253,10 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, + { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, }, + { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, + { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, + { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, #endif -- cgit v1.2.2 From f1ebe4eba40e0ee862767893277d1b1a1e4cc85f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 7 Apr 2008 12:29:23 -0700 Subject: [MTD] [MAPS] omap_nor section fixes Minor tweaks to omap_nor ... as with most platform drivers, its probe and remove logic can (and should!) safely vanish in most configs. Signed-off-by: David Brownell Signed-off-by: David Woodhouse --- drivers/mtd/maps/omap_nor.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index 676248ff4a75..240b0e2d095d 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c @@ -70,7 +70,7 @@ static void omap_set_vpp(struct map_info *map, int enable) } } -static int __devinit omapflash_probe(struct platform_device *pdev) +static int __init omapflash_probe(struct platform_device *pdev) { int err; struct omapflash_info *info; @@ -130,7 +130,7 @@ out_free_info: return err; } -static int __devexit omapflash_remove(struct platform_device *pdev) +static int __exit omapflash_remove(struct platform_device *pdev) { struct omapflash_info *info = platform_get_drvdata(pdev); @@ -152,8 +152,7 @@ static int __devexit omapflash_remove(struct platform_device *pdev) } static struct platform_driver omapflash_driver = { - .probe = omapflash_probe, - .remove = __devexit_p(omapflash_remove), + .remove = __exit_p(omapflash_remove), .driver = { .name = "omapflash", .owner = THIS_MODULE, @@ -162,7 +161,7 @@ static struct platform_driver omapflash_driver = { static int __init omapflash_init(void) { - return platform_driver_register(&omapflash_driver); + return platform_driver_probe(&omapflash_driver, omapflash_probe); } static void __exit omapflash_exit(void) -- cgit v1.2.2 From 67e5a28b35254bbbcd5bfce61ef646709e059bbf Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 14 Apr 2008 09:39:39 +0300 Subject: [MTD] [OneNAND] Allow for controller errors when reading A power loss while writing can result in a page becoming unreadable. When the device is mounted again, reading that page gives controller errors. Upper level software like JFFS2 treat -EIO as fatal, refusing to mount at all. That means it is necessary to treat the error as an ECC error to allow recovery. Note that typically in this case, the eraseblock can still be erased and rewritten i.e. it has not become a bad block. Signed-off-by: Adrian Hunter Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 56255c85d97b..5d7965f7e9ce 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -329,6 +329,21 @@ static int onenand_wait(struct mtd_info *mtd, int state) printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); if (ctrl & ONENAND_CTRL_LOCK) printk(KERN_ERR "onenand_wait: it's locked error.\n"); + if (state == FL_READING) { + /* + * A power loss while writing can result in a page + * becoming unreadable. When the device is mounted + * again, reading that page gives controller errors. + * Upper level software like JFFS2 treat -EIO as fatal, + * refusing to mount at all. That means it is necessary + * to treat the error as an ECC error to allow recovery. + * Note that typically in this case, the eraseblock can + * still be erased and rewritten i.e. it has not become + * a bad block. + */ + mtd->ecc_stats.failed++; + return -EBADMSG; + } return -EIO; } -- cgit v1.2.2 From 0916083210039bf3d186a87522cc806dc21b7097 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:18 +0100 Subject: [MTD] [NAND] S3C2410 Fix previous nFCE suspend save patch Commit 03680b1e00d146df718c8a4eac34438566b70c85 incorrectly was assuming S3C2410_NFCONF was being used to select the NAND chip. Fix this error by ising the sel_reg. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index f3fa1be22ddf..8557c68dbb42 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -119,8 +119,7 @@ struct s3c2410_nand_info { void __iomem *sel_reg; int sel_bit; int mtd_count; - - unsigned long save_nfconf; + unsigned long save_sel; enum s3c_cpu_type cpu_type; }; @@ -810,15 +809,14 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) struct s3c2410_nand_info *info = platform_get_drvdata(dev); if (info) { - info->save_nfconf = readl(info->regs + S3C2410_NFCONF); + info->save_sel = readl(info->sel_reg); /* For the moment, we must ensure nFCE is high during * the time we are suspended. This really should be * handled by suspending the MTDs we are using, but * that is currently not the case. */ - writel(info->save_nfconf | info->sel_bit, - info->regs + S3C2410_NFCONF); + writel(info->save_sel | info->sel_bit, info->sel_reg); if (!allow_clk_stop(info)) clk_disable(info->clk); @@ -830,7 +828,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) static int s3c24xx_nand_resume(struct platform_device *dev) { struct s3c2410_nand_info *info = platform_get_drvdata(dev); - unsigned long nfconf; + unsigned long sel; if (info) { clk_enable(info->clk); @@ -838,10 +836,10 @@ static int s3c24xx_nand_resume(struct platform_device *dev) /* Restore the state of the nFCE line. */ - nfconf = readl(info->regs + S3C2410_NFCONF); - nfconf &= ~info->sel_bit; - nfconf |= info->save_nfconf & info->sel_bit; - writel(nfconf, info->regs + S3C2410_NFCONF); + sel = readl(info->sel_reg); + sel &= ~info->sel_bit; + sel |= info->save_sel & info->sel_bit; + writel(sel, info->sel_reg); if (allow_clk_stop(info)) clk_disable(info->clk); -- cgit v1.2.2 From 71d54f3855b4ca98559e8782350336ec2433cc24 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:19 +0100 Subject: [MTD] [NAND] S3C2410 Large page NAND support This adds support for using large page NAND devices with the S3C24XX NAND controller. This also adds the file Documentation/arm/Samsung-S3C24XX/NAND.txt to describe the differences. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 8557c68dbb42..15397e0f3965 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -472,7 +472,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u ecc_code[1] = ecc >> 8; ecc_code[2] = ecc >> 16; - pr_debug("%s: returning ecc %06lx\n", __func__, ecc); + pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff); return 0; } @@ -643,9 +643,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.correct = s3c2410_nand_correct_data; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = 512; - chip->ecc.bytes = 3; - chip->ecc.layout = &nand_hw_eccoob; switch (info->cpu_type) { case TYPE_S3C2410: @@ -669,6 +666,34 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, } } +/* s3c2410_nand_update_chip + * + * post-probe chip update, to change any items, such as the + * layout for large page nand + */ + +static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, + struct s3c2410_nand_mtd *nmtd) +{ + struct nand_chip *chip = &nmtd->chip; + + printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift); + + if (hardware_ecc) { + /* change the behaviour depending on wether we are using + * the large or small page nand device */ + + if (chip->page_shift > 10) { + chip->ecc.size = 256; + chip->ecc.bytes = 3; + } else { + chip->ecc.size = 512; + chip->ecc.bytes = 3; + chip->ecc.layout = &nand_hw_eccoob; + } + } +} + /* s3c2410_nand_probe * * called by device layer when it finds a device matching @@ -775,9 +800,12 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, s3c2410_nand_init_chip(info, nmtd, sets); - nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1); + nmtd->scan_res = nand_scan_ident(&nmtd->mtd, + (sets) ? sets->nr_chips : 1); if (nmtd->scan_res == 0) { + s3c2410_nand_update_chip(info, nmtd); + nand_scan_tail(&nmtd->mtd); s3c2410_nand_add_partition(info, nmtd, sets); } -- cgit v1.2.2 From c45c6c68333c04de84c21a4b869f36a96f642779 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:20 +0100 Subject: [MTD] [NAND] S3C2410 Allow unset ecc to be ignored for ecc correction If a block's ecc field is all 0xff, then ignore the ECC correction. This is for systems where some of the blocks, such as the initial cramfs are written without ECC and need to be loaded on start. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 15397e0f3965..35401f7b9302 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -357,6 +357,14 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, if (diff0 == 0 && diff1 == 0 && diff2 == 0) return 0; /* ECC is ok */ + /* sometimes people do not think about using the ECC, so check + * to see if we have an 0xff,0xff,0xff read ECC and then ignore + * the error, on the assumption that this is an un-eccd page. + */ + if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && read_ecc[2] == 0xff + && info->platform->ignore_unset_ecc) + return 0; + /* Can we correct this ECC (ie, one row and column change). * Note, this is similar to the 256 error code on smartmedia */ -- cgit v1.2.2 From 1c21ab67b7d3c9a1296019939e0efb69350487cf Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:21 +0100 Subject: [MTD] [NAND] S3C2410 Allow ECC layout to be passed through platform data Add support for the ECC layout to be passed via the platform data specified by the board. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 35401f7b9302..ccacc40e64ee 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -672,6 +672,9 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, } else { chip->ecc.mode = NAND_ECC_SOFT; } + + if (set->ecc_layout != NULL) + chip->ecc.layout = set->ecc_layout; } /* s3c2410_nand_update_chip -- cgit v1.2.2 From 37e5ffa3f15bd9a8b133ab13e9bef833b5eb33d4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 15 Apr 2008 11:36:22 +0100 Subject: [MTD] [NAND] S3C2410 Allow ECC disable to be specified by the board Add support to disable ECC checking for a given chip when passed by the board via the platform data. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/s3c2410.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index ccacc40e64ee..b34a460ab679 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -675,6 +675,9 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, if (set->ecc_layout != NULL) chip->ecc.layout = set->ecc_layout; + + if (set->disable_ecc) + chip->ecc.mode = NAND_ECC_NONE; } /* s3c2410_nand_update_chip -- cgit v1.2.2 From ed8165c75e3dd0b2e51b92a858cabe29ba00c9cb Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 14 Apr 2008 14:58:58 +0100 Subject: [MTD] [NAND] Verify probe by retrying to checking the results match With modern systems using bus-hold instead of bus pull-up, it can often lead to erroneous reporting of NAND devices where there are none. Do a double probe to ensure that the result we got the first time is repeatable, and if it is not then return that there is no chip there. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7acb1a0e7409..ba1bdf787323 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2229,6 +2229,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, { struct nand_flash_dev *type = NULL; int i, dev_id, maf_idx; + int tmp_id, tmp_manf; /* Select the device */ chip->select_chip(mtd, 0); @@ -2240,6 +2241,26 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, *maf_id = chip->read_byte(mtd); dev_id = chip->read_byte(mtd); + /* Try again to make sure, as some systems the bus-hold or other + * interface concerns can cause random data which looks like a + * possibly credible NAND flash to appear. If the two results do + * not match, ignore the device completely. + */ + + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); + + /* Read manufacturer and device IDs */ + + tmp_manf = chip->read_byte(mtd); + tmp_id = chip->read_byte(mtd); + + if (tmp_manf != *maf_id || tmp_id != dev_id) { + printk(KERN_INFO "%s: second ID read did not match " + "%02x,%02x against %02x,%02x\n", __func__, + *maf_id, dev_id, tmp_manf, tmp_id); + return ERR_PTR(-ENODEV); + } + /* Lookup the flash id */ for (i = 0; nand_flash_ids[i].name != NULL; i++) { if (dev_id == nand_flash_ids[i].id) { -- cgit v1.2.2 From fe224668dff97dd8899bd559d1608cc9285db67b Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Wed, 23 Apr 2008 01:40:52 +0200 Subject: [MTD] [NOR] Fix Intel CFI driver for collie flash collie seems to contain LH28F640BF flash chips. According to http://sharp-world.com/products/device/flash/pdf/*FUM00701*@E.pdf (page 83) if they have 0x51 of Extended Query Table (number of hardware partitions) set to zero, they have a single fixed partition. This patch makes those chips work. Signed-off-by: Thomas Kunze Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index eb0e30824ddb..e812df607a5c 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -619,6 +619,9 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, sizeof(struct cfi_intelext_blockinfo); } + if (!numparts) + numparts = 1; + /* Programming Region info */ if (extp->MinorVersion >= '4') { struct cfi_intelext_programming_regioninfo *prinfo; -- cgit v1.2.2 From 986ee0139a91ab8b6b07d29d7a112c8033b5f8e0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 23 Apr 2008 09:39:49 +0100 Subject: [MTD] Clean up AR7 partition map support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/mtd/ar7part.c: In function ‘create_mtd_partitions’: drivers/mtd/ar7part.c:69: warning: passing argument 4 of ‘master->read’ from incompatible pointer type drivers/mtd/ar7part.c:91: warning: passing argument 4 of ‘master->read’ from incompatible pointer type drivers/mtd/ar7part.c:99: warning: passing argument 4 of ‘master->read’ from incompatible pointer type drivers/mtd/ar7part.c:110: warning: passing argument 4 of ‘master->read’ from incompatible pointer type drivers/mtd/ar7part.c:111: error: ‘SQUASHFS_MAGIC’ undeclared (first use in this function) drivers/mtd/ar7part.c:111: error: (Each undeclared identifier is reported only once drivers/mtd/ar7part.c:111: error: for each function it appears in.) Signed-off-by: David Woodhouse --- drivers/mtd/ar7part.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 7722608d5a83..ecf170b55c32 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -34,6 +34,10 @@ #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) +#ifndef SQUASHFS_MAGIC +#define SQUASHFS_MAGIC 0x73717368 +#endif + struct ar7_bin_rec { unsigned int checksum; unsigned int length; @@ -47,7 +51,8 @@ static int create_mtd_partitions(struct mtd_info *master, unsigned long origin) { struct ar7_bin_rec header; - unsigned int offset, len; + unsigned int offset; + size_t len; unsigned int pre_size = master->erasesize, post_size = 0; unsigned int root_offset = ROOT_OFFSET; @@ -66,7 +71,7 @@ static int create_mtd_partitions(struct mtd_info *master, do { /* Try 10 blocks starting from master->erasesize */ offset = pre_size; master->read(master, offset, - sizeof(header), &len, (u8 *)&header); + sizeof(header), &len, (uint8_t *)&header); if (!strncmp((char *)&header, "TIENV0.8", 8)) ar7_parts[1].offset = pre_size; if (header.checksum == LOADER_MAGIC1) @@ -88,7 +93,7 @@ static int create_mtd_partitions(struct mtd_info *master, while (header.length) { offset += sizeof(header) + header.length; master->read(master, offset, sizeof(header), - &len, (u8 *)&header); + &len, (uint8_t *)&header); } root_offset = offset + sizeof(header) + 4; break; @@ -96,10 +101,10 @@ static int create_mtd_partitions(struct mtd_info *master, while (header.length) { offset += sizeof(header) + header.length; master->read(master, offset, sizeof(header), - &len, (u8 *)&header); + &len, (uint8_t *)&header); } root_offset = offset + sizeof(header) + 4 + 0xff; - root_offset &= ~(u32)0xff; + root_offset &= ~(uint32_t)0xff; break; default: printk(KERN_WARNING "Unknown magic: %08x\n", header.checksum); -- cgit v1.2.2 From 697fa9721cbc54ce1604dae09d1be6bb918567f6 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 23 Apr 2008 13:43:21 +0300 Subject: UBI: add a message UBI scan takes quite a time on some systems, so it is nice to print a message that we started attaching an MTD device. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/ubi/build.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index e8578ca422ff..961416ac0616 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -763,8 +763,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) mutex_init(&ubi->volumes_mutex); spin_lock_init(&ubi->volumes_lock); - dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", - mtd->index, ubi_num, vid_hdr_offset); + ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); err = io_init(ubi); if (err) -- cgit v1.2.2 From 77f5492c43adb4eb351fa0d163136877e8b2ed92 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Wed, 23 Apr 2008 19:51:14 +0200 Subject: [MTD] [NAND] Hardware ECC controller on at91sam9263 / at91sam9260 This is a patch to use the hardware ECC controller of the AT91SAM9260 and AT91SAM9263 for the AT91 nand. On AT91 NAND, there's now a choice between ECC soft, ECC hard or no ECC (for debug). It has been tested on AT91SAM9263 with 8 bits large and small page NAND. Signed-off-by: Richard Genoud Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 41 +++++ drivers/mtd/nand/at91_nand.c | 361 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 397 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index dcbb0decd465..5076faf9ca66 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -278,6 +278,47 @@ config MTD_NAND_AT91 help Enables support for NAND Flash / Smart Media Card interface on Atmel AT91 processors. +choice + prompt "ECC management for NAND Flash / SmartMedia on AT91" + depends on MTD_NAND_AT91 + +config MTD_NAND_AT91_ECC_HW + bool "Hardware ECC" + depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 + help + Uses hardware ECC provided by the at91sam9260/at91sam9263 chip + instead of software ECC. + The hardware ECC controller is capable of single bit error + correction and 2-bit random detection per page. + + NB : hardware and software ECC schemes are incompatible. + If you switch from one to another, you'll have to erase your + mtd partition. + + If unsure, say Y + +config MTD_NAND_AT91_ECC_SOFT + bool "Software ECC" + help + Uses software ECC. + + NB : hardware and software ECC schemes are incompatible. + If you switch from one to another, you'll have to erase your + mtd partition. + +config MTD_NAND_AT91_ECC_NONE + bool "No ECC (testing only, DANGEROUS)" + depends on DEBUG_KERNEL + help + No ECC will be used. + It's not a good idea and it should be reserved for testing + purpose only. + + If unsure, say N + + endchoice + +endchoice config MTD_NAND_PXA3xx bool "Support for NAND flash devices on PXA3xx" diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index 463632ed794c..c3eb203a2ad0 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -9,6 +9,15 @@ * Derived from drivers/mtd/spia.c * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) * + * + * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 + * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007 + * + * Derived from Das U-Boot source code + * (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c) + * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas + * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -29,11 +38,59 @@ #include #include +#ifdef CONFIG_MTD_NAND_AT91_ECC_HW +#define hard_ecc 1 +#else +#define hard_ecc 0 +#endif + +#ifdef CONFIG_MTD_NAND_AT91_ECC_NONE +#define no_ecc 1 +#else +#define no_ecc 0 +#endif + +/* Register access macros */ +#define ecc_readl(add, reg) \ + __raw_readl(add + AT91_ECC_##reg) +#define ecc_writel(add, reg, value) \ + __raw_writel((value), add + AT91_ECC_##reg) + +#include /* AT91SAM9260/3 ECC registers */ + +/* oob layout for large page size + * bad block info is on bytes 0 and 1 + * the bytes have to be consecutives to avoid + * several NAND_CMD_RNDOUT during read + */ +static struct nand_ecclayout at91_oobinfo_large = { + .eccbytes = 4, + .eccpos = {60, 61, 62, 63}, + .oobfree = { + {2, 58} + }, +}; + +/* oob layout for small page size + * bad block info is on bytes 4 and 5 + * the bytes have to be consecutives to avoid + * several NAND_CMD_RNDOUT during read + */ +static struct nand_ecclayout at91_oobinfo_small = { + .eccbytes = 4, + .eccpos = {0, 1, 2, 3}, + .oobfree = { + {6, 10} + }, +}; + struct at91_nand_host { struct nand_chip nand_chip; struct mtd_info mtd; void __iomem *io_base; struct at91_nand_data *board; + struct device *dev; + void __iomem *ecc; }; /* @@ -82,6 +139,215 @@ static void at91_nand_disable(struct at91_nand_host *host) at91_set_gpio_value(host->board->enable_pin, 1); } +/* + * write oob for small pages + */ +static int at91_nand_write_oob_512(struct mtd_info *mtd, + struct nand_chip *chip, int page) +{ + int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; + int eccsize = chip->ecc.size, length = mtd->oobsize; + int len, pos, status = 0; + const uint8_t *bufpoi = chip->oob_poi; + + pos = eccsize + chunk; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); + len = min_t(int, length, chunk); + chip->write_buf(mtd, bufpoi, len); + bufpoi += len; + length -= len; + if (length > 0) + chip->write_buf(mtd, bufpoi, length); + + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + status = chip->waitfunc(mtd, chip); + + return status & NAND_STATUS_FAIL ? -EIO : 0; + +} + +/* + * read oob for small pages + */ +static int at91_nand_read_oob_512(struct mtd_info *mtd, + struct nand_chip *chip, int page, int sndcmd) +{ + if (sndcmd) { + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + sndcmd = 0; + } + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + return sndcmd; +} + +/* + * Calculate HW ECC + * + * function called after a write + * + * mtd: MTD block structure + * dat: raw data (unused) + * ecc_code: buffer for ECC + */ +static int at91_nand_calculate(struct mtd_info *mtd, + const u_char *dat, unsigned char *ecc_code) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + uint32_t *eccpos = nand_chip->ecc.layout->eccpos; + unsigned int ecc_value; + + /* get the first 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, PR) & AT91_ECC_PARITY; + + ecc_code[eccpos[0]] = ecc_value & 0xFF; + ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; + + /* get the last 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; + + ecc_code[eccpos[2]] = ecc_value & 0xFF; + ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; + + return 0; +} + +/* + * HW ECC read page function + * + * mtd: mtd info structure + * chip: nand chip info structure + * buf: buffer to store read data + */ +static int at91_nand_read_page(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf) +{ + int eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + uint32_t *eccpos = chip->ecc.layout->eccpos; + uint8_t *p = buf; + uint8_t *oob = chip->oob_poi; + uint8_t *ecc_pos; + int stat; + + /* read the page */ + chip->read_buf(mtd, p, eccsize); + + /* move to ECC position if needed */ + if (eccpos[0] != 0) { + /* This only works on large pages + * because the ECC controller waits for + * NAND_CMD_RNDOUTSTART after the + * NAND_CMD_RNDOUT. + * anyway, for small pages, the eccpos[0] == 0 + */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, + mtd->writesize + eccpos[0], -1); + } + + /* the ECC controller needs to read the ECC just after the data */ + ecc_pos = oob + eccpos[0]; + chip->read_buf(mtd, ecc_pos, eccbytes); + + /* check if there's an error */ + stat = chip->ecc.correct(mtd, p, oob, NULL); + + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + + /* get back to oob start (end of page) */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); + + /* read the oob */ + chip->read_buf(mtd, oob, mtd->oobsize); + + return 0; +} + +/* + * HW ECC Correction + * + * function called after a read + * + * mtd: MTD block structure + * dat: raw data read from the chip + * read_ecc: ECC from the chip (unused) + * isnull: unused + * + * Detect and correct a 1 bit error for a page + */ +static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *isnull) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + unsigned int ecc_status; + unsigned int ecc_word, ecc_bit; + + /* get the status from the Status Register */ + ecc_status = ecc_readl(host->ecc, SR); + + /* if there's no error */ + if (likely(!(ecc_status & AT91_ECC_RECERR))) + return 0; + + /* get error bit offset (4 bits) */ + ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; + /* get word address (12 bits) */ + ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; + ecc_word >>= 4; + + /* if there are multiple errors */ + if (ecc_status & AT91_ECC_MULERR) { + /* check if it is a freshly erased block + * (filled with 0xff) */ + if ((ecc_bit == AT91_ECC_BITADDR) + && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { + /* the block has just been erased, return OK */ + return 0; + } + /* it doesn't seems to be a freshly + * erased block. + * We can't correct so many errors */ + dev_dbg(host->dev, "at91_nand : multiple errors detected." + " Unable to correct.\n"); + return -EIO; + } + + /* if there's a single bit error : we can correct it */ + if (ecc_status & AT91_ECC_ECCERR) { + /* there's nothing much to do here. + * the bit error is on the ECC itself. + */ + dev_dbg(host->dev, "at91_nand : one bit error on ECC code." + " Nothing to correct\n"); + return 0; + } + + dev_dbg(host->dev, "at91_nand : one bit error on data." + " (word offset in the page :" + " 0x%x bit offset : 0x%x)\n", + ecc_word, ecc_bit); + /* correct the error */ + if (nand_chip->options & NAND_BUSWIDTH_16) { + /* 16 bits words */ + ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit); + } else { + /* 8 bits words */ + dat[ecc_word] ^= (1 << ecc_bit); + } + dev_dbg(host->dev, "at91_nand : error corrected\n"); + return 1; +} + +/* + * Enable HW ECC : unsused + */ +static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } + #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "cmdlinepart", NULL }; #endif @@ -94,6 +360,8 @@ static int __init at91_nand_probe(struct platform_device *pdev) struct at91_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; + struct resource *regs; + struct resource *mem; int res; #ifdef CONFIG_MTD_PARTITIONS @@ -108,8 +376,13 @@ static int __init at91_nand_probe(struct platform_device *pdev) return -ENOMEM; } - host->io_base = ioremap(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); + return -ENXIO; + } + + host->io_base = ioremap(mem->start, mem->end - mem->start + 1); if (host->io_base == NULL) { printk(KERN_ERR "at91_nand: ioremap failed\n"); kfree(host); @@ -119,6 +392,7 @@ static int __init at91_nand_probe(struct platform_device *pdev) mtd = &host->mtd; nand_chip = &host->nand_chip; host->board = pdev->dev.platform_data; + host->dev = &pdev->dev; nand_chip->priv = host; /* link the private data structures */ mtd->priv = nand_chip; @@ -132,7 +406,32 @@ static int __init at91_nand_probe(struct platform_device *pdev) if (host->board->rdy_pin) nand_chip->dev_ready = at91_nand_device_ready; + regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!regs && hard_ecc) { + printk(KERN_ERR "at91_nand: can't get I/O resource " + "regs\nFalling back on software ECC\n"); + } + nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ + if (no_ecc) + nand_chip->ecc.mode = NAND_ECC_NONE; + if (hard_ecc && regs) { + host->ecc = ioremap(regs->start, regs->end - regs->start + 1); + if (host->ecc == NULL) { + printk(KERN_ERR "at91_nand: ioremap failed\n"); + res = -EIO; + goto err_ecc_ioremap; + } + nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; + nand_chip->ecc.calculate = at91_nand_calculate; + nand_chip->ecc.correct = at91_nand_correct; + nand_chip->ecc.hwctl = at91_nand_hwctl; + nand_chip->ecc.read_page = at91_nand_read_page; + nand_chip->ecc.bytes = 4; + nand_chip->ecc.prepad = 0; + nand_chip->ecc.postpad = 0; + } + nand_chip->chip_delay = 20; /* 20us command delay time */ if (host->board->bus_width_16) /* 16-bit bus width */ @@ -149,8 +448,53 @@ static int __init at91_nand_probe(struct platform_device *pdev) } } - /* Scan to find existance of the device */ - if (nand_scan(mtd, 1)) { + /* first scan to find the device and get the page size */ + if (nand_scan_ident(mtd, 1)) { + res = -ENXIO; + goto out; + } + + if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { + /* ECC is calculated for the whole page (1 step) */ + nand_chip->ecc.size = mtd->writesize; + + /* set ECC page size and oob layout */ + switch (mtd->writesize) { + case 512: + nand_chip->ecc.layout = &at91_oobinfo_small; + nand_chip->ecc.read_oob = at91_nand_read_oob_512; + nand_chip->ecc.write_oob = at91_nand_write_oob_512; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); + break; + case 1024: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); + break; + case 2048: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); + break; + case 4096: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); + break; + default: + /* page size not handled by HW ECC */ + /* switching back to soft ECC */ + nand_chip->ecc.mode = NAND_ECC_SOFT; + nand_chip->ecc.calculate = NULL; + nand_chip->ecc.correct = NULL; + nand_chip->ecc.hwctl = NULL; + nand_chip->ecc.read_page = NULL; + nand_chip->ecc.postpad = 0; + nand_chip->ecc.prepad = 0; + nand_chip->ecc.bytes = 0; + break; + } + } + + /* second phase scan */ + if (nand_scan_tail(mtd)) { res = -ENXIO; goto out; } @@ -179,9 +523,15 @@ static int __init at91_nand_probe(struct platform_device *pdev) if (!res) return res; +#ifdef CONFIG_MTD_PARTITIONS release: +#endif nand_release(mtd); + out: + iounmap(host->ecc); + +err_ecc_ioremap: at91_nand_disable(host); platform_set_drvdata(pdev, NULL); iounmap(host->io_base); @@ -202,6 +552,7 @@ static int __devexit at91_nand_remove(struct platform_device *pdev) at91_nand_disable(host); iounmap(host->io_base); + iounmap(host->ecc); kfree(host); return 0; @@ -233,5 +584,5 @@ module_exit(at91_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rick Bronson"); -MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200"); +MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200 / AT91SAM9"); MODULE_ALIAS("platform:at91_nand"); -- cgit v1.2.2 From 23386fe572028ca0f9249fb3c71ed31b54cf1665 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:33:53 -0700 Subject: [POWERPC] macintosh/windfarm: Fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable "macintosh" platform drivers, to re-enable auto loading. [dbrownell@users.sourceforge.net: registration fixes] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/macintosh/windfarm_pm112.c | 3 ++- drivers/macintosh/windfarm_pm81.c | 4 ++-- drivers/macintosh/windfarm_pm91.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index b3fbb45bc90a..73d695dc9e50 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -668,7 +668,7 @@ static struct platform_driver wf_pm112_driver = { .remove = __devexit_p(wf_pm112_remove), .driver = { .name = "windfarm", - .bus = &platform_bus_type, + .owner = THIS_MODULE, }, }; @@ -711,3 +711,4 @@ module_exit(wf_pm112_exit); MODULE_AUTHOR("Paul Mackerras "); MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:windfarm"); diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index f24fa734046a..abbe206474f5 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -770,7 +770,7 @@ static struct platform_driver wf_smu_driver = { .remove = __devexit_p(wf_smu_remove), .driver = { .name = "windfarm", - .bus = &platform_bus_type, + .owner = THIS_MODULE, }, }; @@ -810,4 +810,4 @@ module_exit(wf_smu_exit); MODULE_AUTHOR("Benjamin Herrenschmidt "); MODULE_DESCRIPTION("Thermal control logic for iMac G5"); MODULE_LICENSE("GPL"); - +MODULE_ALIAS("platform:windfarm"); diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 26eee69ebe6d..764c525b2117 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -702,7 +702,7 @@ static struct platform_driver wf_smu_driver = { .remove = __devexit_p(wf_smu_remove), .driver = { .name = "windfarm", - .bus = &platform_bus_type, + .owner = THIS_MODULE, }, }; @@ -742,3 +742,4 @@ MODULE_AUTHOR("Benjamin Herrenschmidt "); MODULE_DESCRIPTION("Thermal control logic for PowerMac9,1"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:windfarm"); -- cgit v1.2.2 From 1d32e21889b96e594e8b63b193bf7d2a51ab93ec Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 10 Apr 2008 07:01:53 +1000 Subject: [POWERPC] PS3: Fix gelic net module dependency The PS3 gelic network driver depends on the wake-on-lan support provided by the PS3 sys manager driver. Add that dependency to the GELIC_NET Kconfig option. Prevents these build errors: ps3_gelic_net.c:1277: undefined reference to `.ps3_sys_manager_get_wol' ps3_gelic_net.c:1337: undefined reference to `.ps3_sys_manager_set_wol' CC: Masakazu Mokuno CC: Jeff Garzik Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2399a3796f6e..d46d9498040c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2278,6 +2278,7 @@ config TSI108_ETH config GELIC_NET tristate "PS3 Gigabit Ethernet driver" depends on PPC_PS3 + select PS3_SYS_MANAGER help This driver supports the network device on the PS3 game console. This driver has built-in support for Ethernet. -- cgit v1.2.2 From 138decf83f6a973951ce7faf39094d964de7853a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 23 Apr 2008 19:51:34 +1000 Subject: [POWERPC] drivers/of/of_i2c.c: Add MODULE_LICENSE After commit 585468e5d5962660867c269e26f0a4b89a599473 ([POWERPC] i2c: Fix build breakage introduced by OF helpers) drivers/of/of_i2c.c needs a MODULE_LICENSE. Signed-off-by: Adrian Bunk Signed-off-by: Paul Mackerras --- drivers/of/of_i2c.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 631689171159..715a44471617 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -13,6 +13,7 @@ #include #include +#include struct i2c_driver_device { char *of_device; @@ -113,3 +114,5 @@ void of_register_i2c_devices(struct i2c_adapter *adap, } } EXPORT_SYMBOL(of_register_i2c_devices); + +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 2fd53e02be9a73cc49d69e0ff8860daa7b5bf8ab Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 23 Apr 2008 19:51:38 +1000 Subject: [POWERPC] char/xilinx_hwicap/ section fix This patch fixes the following build error: <-- snip --> ... CC [M] drivers/char/xilinx_hwicap/xilinx_hwicap.o ... /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/char/xilinx_hwicap/xilinx_hwicap.c:806: error: hwicap_of_match causes a section type conflict /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/char/xilinx_hwicap/xilinx_hwicap.c:806: error: hwicap_of_match causes a section type conflict make[4]: *** [drivers/char/xilinx_hwicap/xilinx_hwicap.o] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Paul Mackerras --- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 016f90567a52..dfe6907ae15b 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -803,7 +803,7 @@ static int __devexit hwicap_of_remove(struct of_device *op) } /* Match table for of_platform binding */ -static const struct of_device_id __devinit hwicap_of_match[] = { +static const struct of_device_id __devinitconst hwicap_of_match[] = { { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, {}, -- cgit v1.2.2 From 81e329cdddd63d66e2b3c3dc51d429ba074cdbb8 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 10 Mar 2008 13:43:05 +0100 Subject: Input: fix ordering in joystick Makefile Make entries in drivers/input/joystick/Makefile properly alphabetically ordered. Signed-off-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index 868b746e757a..fdbf8c4c2876 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_JOYSTICK_GF2K) += gf2k.o obj-$(CONFIG_JOYSTICK_GRIP) += grip.o obj-$(CONFIG_JOYSTICK_GRIP_MP) += grip_mp.o obj-$(CONFIG_JOYSTICK_GUILLEMOT) += guillemot.o +obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o @@ -29,4 +30,3 @@ obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o -obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ -- cgit v1.2.2 From b39b04403bba4f807ee6e57ae2f4407187588fcd Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 17 Apr 2008 09:28:25 -0400 Subject: Input: drivers/char/keyboard.c - use time_after The functions time_before, time_before_eq, time_after, and time_after_eq are more robust for comparing jiffies against other values. Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 59608e341385..45806d27579a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -42,6 +42,7 @@ #include #include #include +#include extern void ctrl_alt_del(void); @@ -928,7 +929,8 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) if (up_flag) { if (brl_timeout) { if (!committing || - jiffies - releasestart > (brl_timeout * HZ) / 1000) { + time_after(jiffies, + releasestart + msecs_to_jiffies(brl_timeout))) { committing = pressed; releasestart = jiffies; } -- cgit v1.2.2 From d7b5247bbcfba2bc96d4b3dec9086a4f1a31363b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 00:24:42 -0400 Subject: Input: add MODULE_ALIAS() to hotpluggable platform modules Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable "input" platform drivers, to re-enable auto loading. [dbrownell@users.sourceforge.net: more drivers, registration fixes] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/aaed2000_kbd.c | 4 ++++ drivers/input/keyboard/bf54x-keys.c | 2 ++ drivers/input/keyboard/corgikbd.c | 2 ++ drivers/input/keyboard/gpio_keys.c | 2 ++ drivers/input/keyboard/jornada680_kbd.c | 2 ++ drivers/input/keyboard/jornada720_kbd.c | 4 ++++ drivers/input/keyboard/omap-keypad.c | 2 ++ drivers/input/keyboard/pxa27x_keypad.c | 4 ++++ drivers/input/keyboard/spitzkbd.c | 1 + drivers/input/keyboard/tosakbd.c | 2 ++ drivers/input/misc/cobalt_btns.c | 3 +++ drivers/input/mouse/gpio_mouse.c | 4 ++++ drivers/input/serio/rpckbd.c | 2 ++ drivers/input/touchscreen/corgi_ts.c | 2 ++ drivers/input/touchscreen/jornada720_ts.c | 4 ++++ 15 files changed, 40 insertions(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index 72abc196ce66..a293e8b3f508 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c @@ -156,11 +156,15 @@ static int __devexit aaedkbd_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:aaed2000-keyboard"); + static struct platform_driver aaedkbd_driver = { .probe = aaedkbd_probe, .remove = __devexit_p(aaedkbd_remove), .driver = { .name = "aaed2000-keyboard", + .owner = THIS_MODULE, }, }; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 05e3494cf8b8..d87ac3322a6d 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -359,6 +359,7 @@ struct platform_driver bfin_kpad_device_driver = { .remove = __devexit_p(bfin_kpad_remove), .driver = { .name = DRV_NAME, + .owner = THIS_MODULE, } }; @@ -378,3 +379,4 @@ module_exit(bfin_kpad_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Keypad driver for BF54x Processors"); +MODULE_ALIAS("platform:bf54x-keys"); diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 790fed368aae..5187c0c7a222 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -392,6 +392,7 @@ static struct platform_driver corgikbd_driver = { .resume = corgikbd_resume, .driver = { .name = "corgi-keyboard", + .owner = THIS_MODULE, }, }; @@ -411,3 +412,4 @@ module_exit(corgikbd_exit); MODULE_AUTHOR("Richard Purdie "); MODULE_DESCRIPTION("Corgi Keyboard Driver"); MODULE_LICENSE("GPLv2"); +MODULE_ALIAS("platform:corgi-keyboard"); diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index a54dc15f9005..bbd00c3fe98c 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -214,6 +214,7 @@ struct platform_driver gpio_keys_device_driver = { .resume = gpio_keys_resume, .driver = { .name = "gpio-keys", + .owner = THIS_MODULE, } }; @@ -233,3 +234,4 @@ module_exit(gpio_keys_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Phil Blundell "); MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); +MODULE_ALIAS("platform:gpio-keys"); diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index a23633a2e1b4..9387da343f97 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -254,6 +254,7 @@ static int __devexit jornada680kbd_remove(struct platform_device *pdev) static struct platform_driver jornada680kbd_driver = { .driver = { .name = "jornada680_kbd", + .owner = THIS_MODULE, }, .probe = jornada680kbd_probe, .remove = __devexit_p(jornada680kbd_remove), @@ -275,3 +276,4 @@ module_exit(jornada680kbd_exit); MODULE_AUTHOR("Kristoffer Ericson "); MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); MODULE_LICENSE("GPLv2"); +MODULE_ALIAS("platform:jornada680_kbd"); diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 986f93cfc6b8..a1164a0c7736 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c @@ -162,9 +162,13 @@ static int __devexit jornada720_kbd_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:jornada720_kbd"); + static struct platform_driver jornada720_kbd_driver = { .driver = { .name = "jornada720_kbd", + .owner = THIS_MODULE, }, .probe = jornada720_kbd_probe, .remove = __devexit_p(jornada720_kbd_remove), diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index eec328167f8d..10afd2068068 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -467,6 +467,7 @@ static struct platform_driver omap_kp_driver = { .resume = omap_kp_resume, .driver = { .name = "omap-keypad", + .owner = THIS_MODULE, }, }; @@ -487,3 +488,4 @@ module_exit(omap_kp_exit); MODULE_AUTHOR("Timo Teräs"); MODULE_DESCRIPTION("OMAP Keypad Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:omap-keypad"); diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 4e651c11c1da..3dea0c5077a9 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -545,6 +545,9 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:pxa27x-keypad"); + static struct platform_driver pxa27x_keypad_driver = { .probe = pxa27x_keypad_probe, .remove = __devexit_p(pxa27x_keypad_remove), @@ -552,6 +555,7 @@ static struct platform_driver pxa27x_keypad_driver = { .resume = pxa27x_keypad_resume, .driver = { .name = "pxa27x-keypad", + .owner = THIS_MODULE, }, }; diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 1d59a2dc3c17..92102f9e4b8b 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -494,3 +494,4 @@ module_exit(spitzkbd_exit); MODULE_AUTHOR("Richard Purdie "); MODULE_DESCRIPTION("Spitz Keyboard Driver"); MODULE_LICENSE("GPLv2"); +MODULE_ALIAS("platform:spitz-keyboard"); diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index a247006757de..94e444b4ee15 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c @@ -409,6 +409,7 @@ static struct platform_driver tosakbd_driver = { .resume = tosakbd_resume, .driver = { .name = "tosa-keyboard", + .owner = THIS_MODULE, }, }; @@ -428,3 +429,4 @@ module_exit(tosakbd_exit); MODULE_AUTHOR("Dirk Opfer "); MODULE_DESCRIPTION("Tosa Keyboard Driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tosa-keyboard"); diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 5511ef006a66..6a1f48b76e32 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -148,6 +148,9 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:Cobalt buttons"); + static struct platform_driver cobalt_buttons_driver = { .probe = cobalt_buttons_probe, .remove = __devexit_p(cobalt_buttons_remove), diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 0936d6ba015c..339290184871 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c @@ -171,10 +171,14 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:gpio_mouse"); + struct platform_driver gpio_mouse_device_driver = { .remove = __devexit_p(gpio_mouse_remove), .driver = { .name = "gpio_mouse", + .owner = THIS_MODULE, } }; diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 49f84315cb32..34c59d9c6205 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -45,6 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik, Russell King"); MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:kart"); static int rpckbd_write(struct serio *port, unsigned char val) { @@ -140,6 +141,7 @@ static struct platform_driver rpckbd_driver = { .remove = __devexit_p(rpckbd_remove), .driver = { .name = "kart", + .owner = THIS_MODULE, }, }; diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 99d92f5c93d6..765e964b7969 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -361,6 +361,7 @@ static struct platform_driver corgits_driver = { .resume = corgits_resume, .driver = { .name = "corgi-ts", + .owner = THIS_MODULE, }, }; @@ -380,3 +381,4 @@ module_exit(corgits_exit); MODULE_AUTHOR("Richard Purdie "); MODULE_DESCRIPTION("Corgi TouchScreen Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:corgi-ts"); diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index 42a1c9a1940e..742242111bf1 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -160,11 +160,15 @@ static int __devexit jornada720_ts_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:jornada_ts"); + static struct platform_driver jornada720_ts_driver = { .probe = jornada720_ts_probe, .remove = __devexit_p(jornada720_ts_remove), .driver = { .name = "jornada_ts", + .owner = THIS_MODULE, }, }; -- cgit v1.2.2 From d0478d0ad7a58f36afa03e57afe14955c2943466 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 18 Apr 2008 00:25:00 -0400 Subject: Input: bf54x-keys - add infrastructure for keypad wakeups Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/bf54x-keys.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index d87ac3322a6d..54ed8e2e1c02 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -312,6 +312,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) bfin_write_KPAD_CTL(bfin_read_KPAD_CTL() | KPAD_EN); + device_init_wakeup(&pdev->dev, 1); + printk(KERN_ERR DRV_NAME ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq); @@ -354,13 +356,40 @@ static int __devexit bfin_kpad_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); + + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(bf54x_kpad->irq); + + return 0; +} + +static int bfin_kpad_resume(struct platform_device *pdev) +{ + struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); + + if (device_may_wakeup(&pdev->dev)) + disable_irq_wake(bf54x_kpad->irq); + + return 0; +} +#else +# define bfin_kpad_suspend NULL +# define bfin_kpad_resume NULL +#endif + struct platform_driver bfin_kpad_device_driver = { - .probe = bfin_kpad_probe, - .remove = __devexit_p(bfin_kpad_remove), .driver = { .name = DRV_NAME, .owner = THIS_MODULE, - } + }, + .probe = bfin_kpad_probe, + .remove = __devexit_p(bfin_kpad_remove), + .suspend = bfin_kpad_suspend, + .resume = bfin_kpad_resume, }; static int __init bfin_kpad_init(void) -- cgit v1.2.2 From 8c6deb9c8fd29feaeae3aae500608beac777ea9e Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 18 Apr 2008 00:25:18 -0400 Subject: Input: i8042 - fix incorrect usage of strncpy and strncat Fix incorrect length argument for strncpy and strncat by replacing them with strlcpy and strlcat Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 60931aceb828..5ece9f56babc 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -370,10 +370,10 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * if (pnp_irq_valid(dev,0)) i8042_pnp_kbd_irq = pnp_irq(dev, 0); - strncpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); + strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); if (strlen(pnp_dev_name(dev))) { - strncat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); - strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); + strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); + strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); } i8042_pnp_kbd_devices++; @@ -391,10 +391,10 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * if (pnp_irq_valid(dev, 0)) i8042_pnp_aux_irq = pnp_irq(dev, 0); - strncpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); + strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); if (strlen(pnp_dev_name(dev))) { - strncat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); - strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); + strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); + strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); } i8042_pnp_aux_devices++; -- cgit v1.2.2 From 8fd76c4506817a93718fab0d6b3a55b9becc9f2c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 18 Apr 2008 00:25:38 -0400 Subject: Input: mac_hid - add lockdep annotation to emumousebtn The mouse button emulation calls input device methods from an input device. This causes funny lock nesting which is harmless as each device has its own locks. Give the nesting device its own lock classes so that lockdep will not consider them the same. Signed-off-by: Peter Zijlstra Signed-off-by: Dmitry Torokhov --- drivers/macintosh/mac_hid.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 89302309da92..f972ff377b63 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -103,6 +103,9 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) return 0; } +static struct lock_class_key emumousebtn_event_class; +static struct lock_class_key emumousebtn_mutex_class; + static int emumousebtn_input_register(void) { int ret; @@ -111,6 +114,9 @@ static int emumousebtn_input_register(void) if (!emumousebtn) return -ENOMEM; + lockdep_set_class(emumousebtn->event_lock, &emumousebtn_event_class); + lockdep_set_class(emumousebtn->mutex, &emumousebtn_mutex_class); + emumousebtn->name = "Macintosh mouse button emulation"; emumousebtn->id.bustype = BUS_ADB; emumousebtn->id.vendor = 0x0001; -- cgit v1.2.2 From a22b4b2f408f7958ffb3a9e62defc5168db1e15e Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Mon, 21 Apr 2008 10:00:46 -0400 Subject: Input: at32psif - update MODULE_AUTHOR with new email Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Dmitry Torokhov --- drivers/input/serio/at32psif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index c267588f7308..41fda8c67b1e 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -370,6 +370,6 @@ static void __exit psif_exit(void) module_init(psif_init); module_exit(psif_exit); -MODULE_AUTHOR("Hans-Christian Egtvedt "); +MODULE_AUTHOR("Hans-Christian Egtvedt "); MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 48bdce4a2e0b1d3be6ed6da14d25adfe9385d2dc Mon Sep 17 00:00:00 2001 From: Vernon Sauder Date: Mon, 21 Apr 2008 12:13:21 -0400 Subject: Input: ucb1400_ts - IRQ probe fix The UCB1400 driver IRQ probe code fails to find an interrupt if all the interrupts in the range 0-31 are nonprobe-able. This patch removes the check of the return value so interrupts above 31 can be detected. Tested on InHand Fingertip4 PXA270 board. Signed-off-by: Vernon Sauder Acked-by: Nicolas Pitre Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ucb1400_ts.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 607f9933aa1f..bce018e45bce 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -427,10 +427,6 @@ static int ucb1400_detect_irq(struct ucb1400 *ucb) unsigned long mask, timeout; mask = probe_irq_on(); - if (!mask) { - probe_irq_off(mask); - return -EBUSY; - } /* Enable the ADC interrupt. */ ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); -- cgit v1.2.2 From b912b5e2cfb35c02c9c79d3f6e31753f3be4dd83 Mon Sep 17 00:00:00 2001 From: John Linn Date: Thu, 3 Apr 2008 10:22:19 +1100 Subject: [POWERPC] Xilinx: of_serial support for Xilinx uart 16550. The Xilinx 16550 uart core is not a standard 16550 because it uses word-based addressing rather than byte-based addressing. With additional properties it is compatible with the open firmware 'ns16550' compatible binding. This code updates the of_serial driver to handle the reg-offset and reg-shift properties to enable this core to be used. Signed-off-by: John Linn Acked-by: Arnd Bergmann Signed-off-by: Josh Boyer --- drivers/serial/of_serial.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 8aacfb78deab..25029c7570b6 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -31,7 +31,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, struct resource resource; struct device_node *np = ofdev->node; const unsigned int *clk, *spd; - int ret; + const u32 *prop; + int ret, prop_size; memset(port, 0, sizeof *port); spd = of_get_property(np, "current-speed", NULL); @@ -49,6 +50,17 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, spin_lock_init(&port->lock); port->mapbase = resource.start; + + /* Check for shifted address mapping */ + prop = of_get_property(np, "reg-offset", &prop_size); + if (prop && (prop_size == sizeof(u32))) + port->mapbase += *prop; + + /* Check for registers offset within the devices address range */ + prop = of_get_property(np, "reg-shift", &prop_size); + if (prop && (prop_size == sizeof(u32))) + port->regshift = *prop; + port->irq = irq_of_parse_and_map(np, 0); port->iotype = UPIO_MEM; port->type = type; -- cgit v1.2.2 From ae531c26c5c2a28ca1b35a75b39b3b256850f2c8 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Thu, 24 Apr 2008 23:40:47 +0200 Subject: x86: introduce /dev/mem restrictions with a config option This patch introduces a restriction on /dev/mem: Only non-memory can be read or written unless the newly introduced config option is set. The X server needs access to /dev/mem for the PCI space, but it doesn't need access to memory; both the file permissions and SELinux permissions of /dev/mem just make X effectively super-super powerful. With the exception of the BIOS area, there's just no valid app that uses /dev/mem on actual memory. Other popular users of /dev/mem are rootkits and the like. (note: mmap access of memory via /dev/mem was already not allowed since a really long time) People who want to use /dev/mem for kernel debugging can enable the config option. The restrictions of this patch have been in the Fedora and RHEL kernels for at least 4 years without any problems. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/char/mem.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 20070b7c573d..dcf6e31970a1 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -108,6 +108,30 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) } #endif +#ifdef CONFIG_NONPROMISC_DEVMEM +static inline int range_is_allowed(unsigned long from, unsigned long to) +{ + unsigned long cursor; + + cursor = from >> PAGE_SHIFT; + while ((cursor << PAGE_SHIFT) < to) { + if (!devmem_is_allowed(cursor)) { + printk(KERN_INFO "Program %s tried to read /dev/mem " + "between %lx->%lx.\n", + current->comm, from, to); + return 0; + } + cursor++; + } + return 1; +} +#else +static inline int range_is_allowed(unsigned long from, unsigned long to) +{ + return 1; +} +#endif + /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. @@ -157,6 +181,8 @@ static ssize_t read_mem(struct file * file, char __user * buf, */ ptr = xlate_dev_mem_ptr(p); + if (!range_is_allowed(p, p+count)) + return -EPERM; if (copy_to_user(buf, ptr, sz)) return -EFAULT; buf += sz; @@ -214,6 +240,8 @@ static ssize_t write_mem(struct file * file, const char __user * buf, */ ptr = xlate_dev_mem_ptr(p); + if (!range_is_allowed(p, p+sz)) + return -EPERM; copied = copy_from_user(ptr, buf, sz); if (copied) { written += sz - copied; -- cgit v1.2.2 From e2beb3eae627211b67e456c53f946cede2ac10d7 Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Thu, 6 Mar 2008 23:01:47 -0800 Subject: devmem: add range_is_allowed() check to mmap of /dev/mem Earlier patch that introduced CONFIG_NONPROMISC_DEVMEM, did the range_is_allowed() check only for read and write. Add range_is_allowed() check to mmap of /dev/mem as well. Changes the paramaters of range_is_allowed() to pfn and size to handle more than 32 bits of physical address on 32 bit arch cleanly. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Ingo Molnar --- drivers/char/mem.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index dcf6e31970a1..964ff3b1cff4 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -109,24 +109,26 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) #endif #ifdef CONFIG_NONPROMISC_DEVMEM -static inline int range_is_allowed(unsigned long from, unsigned long to) +static inline int range_is_allowed(unsigned long pfn, unsigned long size) { - unsigned long cursor; + u64 from = ((u64)pfn) << PAGE_SHIFT; + u64 to = from + size; + u64 cursor = from; - cursor = from >> PAGE_SHIFT; - while ((cursor << PAGE_SHIFT) < to) { - if (!devmem_is_allowed(cursor)) { - printk(KERN_INFO "Program %s tried to read /dev/mem " - "between %lx->%lx.\n", + while (cursor < to) { + if (!devmem_is_allowed(pfn)) { + printk(KERN_INFO + "Program %s tried to access /dev/mem between %Lx->%Lx.\n", current->comm, from, to); return 0; } - cursor++; + cursor += PAGE_SIZE; + pfn++; } return 1; } #else -static inline int range_is_allowed(unsigned long from, unsigned long to) +static inline int range_is_allowed(unsigned long pfn, unsigned long size) { return 1; } @@ -181,7 +183,7 @@ static ssize_t read_mem(struct file * file, char __user * buf, */ ptr = xlate_dev_mem_ptr(p); - if (!range_is_allowed(p, p+count)) + if (!range_is_allowed(p >> PAGE_SHIFT, count)) return -EPERM; if (copy_to_user(buf, ptr, sz)) return -EFAULT; @@ -240,7 +242,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, */ ptr = xlate_dev_mem_ptr(p); - if (!range_is_allowed(p, p+sz)) + if (!range_is_allowed(p >> PAGE_SHIFT, sz)) return -EPERM; copied = copy_from_user(ptr, buf, sz); if (copied) { @@ -309,6 +311,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) if (!private_mapping_ok(vma)) return -ENOSYS; + if (!range_is_allowed(vma->vm_pgoff, size)) + return -EPERM; + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, size, vma->vm_page_prot); -- cgit v1.2.2 From e045fb2a988a9a1964059b0d33dbaf18d12f925f Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Tue, 18 Mar 2008 17:00:15 -0700 Subject: x86: PAT avoid aliasing in /dev/mem read/write Add xlate and unxlate around /dev/mem read/write. This sets up the mapping that can be used for /dev/mem read and write without aliasing worries. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar --- drivers/char/mem.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 964ff3b1cff4..83495885ada0 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -134,6 +134,10 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) } #endif +void __attribute__((weak)) unxlate_dev_mem_ptr(unsigned long phys, void *addr) +{ +} + /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. @@ -176,17 +180,25 @@ static ssize_t read_mem(struct file * file, char __user * buf, sz = min_t(unsigned long, sz, count); + if (!range_is_allowed(p >> PAGE_SHIFT, count)) + return -EPERM; + /* * On ia64 if a page has been mapped somewhere as * uncached, then it must also be accessed uncached * by the kernel or data corruption may occur */ ptr = xlate_dev_mem_ptr(p); + if (!ptr) + return -EFAULT; - if (!range_is_allowed(p >> PAGE_SHIFT, count)) - return -EPERM; - if (copy_to_user(buf, ptr, sz)) + if (copy_to_user(buf, ptr, sz)) { + unxlate_dev_mem_ptr(p, ptr); return -EFAULT; + } + + unxlate_dev_mem_ptr(p, ptr); + buf += sz; p += sz; count -= sz; @@ -235,22 +247,32 @@ static ssize_t write_mem(struct file * file, const char __user * buf, sz = min_t(unsigned long, sz, count); + if (!range_is_allowed(p >> PAGE_SHIFT, sz)) + return -EPERM; + /* * On ia64 if a page has been mapped somewhere as * uncached, then it must also be accessed uncached * by the kernel or data corruption may occur */ ptr = xlate_dev_mem_ptr(p); + if (!ptr) { + if (written) + break; + return -EFAULT; + } - if (!range_is_allowed(p >> PAGE_SHIFT, sz)) - return -EPERM; copied = copy_from_user(ptr, buf, sz); if (copied) { written += sz - copied; + unxlate_dev_mem_ptr(p, ptr); if (written) break; return -EFAULT; } + + unxlate_dev_mem_ptr(p, ptr); + buf += sz; p += sz; count -= sz; -- cgit v1.2.2 From f0970c13b6a5b01189aeb196ebb573cf87d95839 Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Tue, 18 Mar 2008 17:00:20 -0700 Subject: x86: PAT phys_mem_access_prot_allowed for dev/mem mmap Introduce phys_mem_access_prot_allowed(), which checks whether the mapping is possible, without any conflicts and returns success or failure based on that. phys_mem_access_prot() by itself does not allow failure case. This ability to return error is needed for PAT where we may have aliasing conflicts. x86 setup __HAVE_PHYS_MEM_ACCESS_PROT and move x86 specific code out of /dev/mem into arch specific area. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar --- drivers/char/mem.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 83495885ada0..56b2fb4fbc93 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -41,36 +41,7 @@ */ static inline int uncached_access(struct file *file, unsigned long addr) { -#if defined(__i386__) && !defined(__arch_um__) - /* - * On the PPro and successors, the MTRRs are used to set - * memory types for physical addresses outside main memory, - * so blindly setting PCD or PWT on those pages is wrong. - * For Pentiums and earlier, the surround logic should disable - * caching for the high addresses through the KEN pin, but - * we maintain the tradition of paranoia in this code. - */ - if (file->f_flags & O_SYNC) - return 1; - return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) || - test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) || - test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) || - test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) ) - && addr >= __pa(high_memory); -#elif defined(__x86_64__) && !defined(__arch_um__) - /* - * This is broken because it can generate memory type aliases, - * which can cause cache corruptions - * But it is only available for root and we have to be bug-to-bug - * compatible with i386. - */ - if (file->f_flags & O_SYNC) - return 1; - /* same behaviour as i386. PAT always set to cached and MTRRs control the - caching behaviour. - Hopefully a full PAT implementation will fix that soon. */ - return 0; -#elif defined(CONFIG_IA64) +#if defined(CONFIG_IA64) /* * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. */ @@ -283,6 +254,12 @@ static ssize_t write_mem(struct file * file, const char __user * buf, return written; } +int __attribute__((weak)) phys_mem_access_prot_allowed(struct file *file, + unsigned long pfn, unsigned long size, pgprot_t *vma_prot) +{ + return 1; +} + #ifndef __HAVE_PHYS_MEM_ACCESS_PROT static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) @@ -336,6 +313,10 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) if (!range_is_allowed(vma->vm_pgoff, size)) return -EPERM; + if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size, + &vma->vm_page_prot)) + return -EINVAL; + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, size, vma->vm_page_prot); -- cgit v1.2.2 From e7f260a276f2c9184fe753732d834b1f6fbe9f17 Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Tue, 18 Mar 2008 17:00:21 -0700 Subject: x86: PAT use reserve free memtype in mmap of /dev/mem Use reserve_memtype and free_memtype wrappers for /dev/mem mmaps. The memtype is slightly complicated here, given that we have to support existing X mappings. We fallback on UC_MINUS for that. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar --- drivers/char/mem.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 56b2fb4fbc93..e83623ead441 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -300,6 +300,35 @@ static inline int private_mapping_ok(struct vm_area_struct *vma) } #endif +void __attribute__((weak)) +map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) +{ + /* nothing. architectures can override. */ +} + +void __attribute__((weak)) +unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) +{ + /* nothing. architectures can override. */ +} + +static void mmap_mem_open(struct vm_area_struct *vma) +{ + map_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} + +static void mmap_mem_close(struct vm_area_struct *vma) +{ + unmap_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} + +static struct vm_operations_struct mmap_mem_ops = { + .open = mmap_mem_open, + .close = mmap_mem_close +}; + static int mmap_mem(struct file * file, struct vm_area_struct * vma) { size_t size = vma->vm_end - vma->vm_start; @@ -321,13 +350,17 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) size, vma->vm_page_prot); + vma->vm_ops = &mmap_mem_ops; + /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, - vma->vm_page_prot)) + vma->vm_page_prot)) { + unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot); return -EAGAIN; + } return 0; } -- cgit v1.2.2 From 87e27cf6288c6bf089ed34a72213d9ad16e82d84 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:53:52 -0700 Subject: xen: add missing definitions for xen grant table which ia64/xen needs Add xen handles realted definitions for grant table which ia64/xen needs. Pointer argumsnts for ia64/xen hypercall are passed in pseudo physical address (guest physical address) so that it is required to convert guest kernel virtual address into pseudo physical address right before issuing hypercall. The xen guest handle represents such arguments. Define necessary handles and helper functions. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/grant-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index d85dc6d41c2a..d4a89b3d694f 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -470,7 +470,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) setup.dom = DOMID_SELF; setup.nr_frames = nr_gframes; - setup.frame_list = frames; + set_xen_guest_handle(setup.frame_list, frames); rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); if (rc == -ENOSYS) { -- cgit v1.2.2 From af711cda4f94b5fddcdc5eb4134387ae026e3171 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:53:54 -0700 Subject: xen: move features.c from arch/x86/xen/features.c to drivers/xen ia64/xen also uses it too. Move it into common place so that ia64/xen can share the code. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/Makefile | 2 +- drivers/xen/features.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 drivers/xen/features.c (limited to 'drivers') diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 56592f0d6cef..609fdda90a34 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,2 +1,2 @@ -obj-y += grant-table.o +obj-y += grant-table.o features.o obj-y += xenbus/ diff --git a/drivers/xen/features.c b/drivers/xen/features.c new file mode 100644 index 000000000000..0707714e40d6 --- /dev/null +++ b/drivers/xen/features.c @@ -0,0 +1,29 @@ +/****************************************************************************** + * features.c + * + * Xen feature flags. + * + * Copyright (c) 2006, Ian Campbell, XenSource Inc. + */ +#include +#include +#include +#include +#include + +u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly; +EXPORT_SYMBOL_GPL(xen_features); + +void xen_setup_features(void) +{ + struct xen_feature_info fi; + int i, j; + + for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) { + fi.submap_idx = i; + if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) + break; + for (j = 0; j < 32; j++) + xen_features[i * 32 + j] = !!(fi.submap & 1< Date: Wed, 2 Apr 2008 10:53:55 -0700 Subject: xen: move events.c to drivers/xen for IA64/Xen support move arch/x86/xen/events.c undedr drivers/xen to share codes with x86 and ia64. And minor adjustment to compile. ia64/xen also uses events.c Signed-off-by: Yaozu (Eddie) Dong Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/Makefile | 2 +- drivers/xen/events.c | 657 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 658 insertions(+), 1 deletion(-) create mode 100644 drivers/xen/events.c (limited to 'drivers') diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 609fdda90a34..823ce788b14b 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,2 +1,2 @@ -obj-y += grant-table.o features.o +obj-y += grant-table.o features.o events.o obj-y += xenbus/ diff --git a/drivers/xen/events.c b/drivers/xen/events.c new file mode 100644 index 000000000000..c50d499b1e6f --- /dev/null +++ b/drivers/xen/events.c @@ -0,0 +1,657 @@ +/* + * Xen event channels + * + * Xen models interrupts with abstract event channels. Because each + * domain gets 1024 event channels, but NR_IRQ is not that large, we + * must dynamically map irqs<->event channels. The event channels + * interface with the rest of the kernel by defining a xen interrupt + * chip. When an event is recieved, it is mapped to an irq and sent + * through the normal interrupt processing path. + * + * There are four kinds of events which can be mapped to an event + * channel: + * + * 1. Inter-domain notifications. This includes all the virtual + * device events, since they're driven by front-ends in another domain + * (typically dom0). + * 2. VIRQs, typically used for timers. These are per-cpu events. + * 3. IPIs. + * 4. Hardware interrupts. Not supported at present. + * + * Jeremy Fitzhardinge , XenSource Inc, 2007 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * This lock protects updates to the following mapping and reference-count + * arrays. The lock does not need to be acquired to read the mapping tables. + */ +static DEFINE_SPINLOCK(irq_mapping_update_lock); + +/* IRQ <-> VIRQ mapping. */ +static DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1}; + +/* IRQ <-> IPI mapping */ +static DEFINE_PER_CPU(int, ipi_to_irq[XEN_NR_IPIS]) = {[0 ... XEN_NR_IPIS-1] = -1}; + +/* Packed IRQ information: binding type, sub-type index, and event channel. */ +struct packed_irq +{ + unsigned short evtchn; + unsigned char index; + unsigned char type; +}; + +static struct packed_irq irq_info[NR_IRQS]; + +/* Binding types. */ +enum { + IRQT_UNBOUND, + IRQT_PIRQ, + IRQT_VIRQ, + IRQT_IPI, + IRQT_EVTCHN +}; + +/* Convenient shorthand for packed representation of an unbound IRQ. */ +#define IRQ_UNBOUND mk_irq_info(IRQT_UNBOUND, 0, 0) + +static int evtchn_to_irq[NR_EVENT_CHANNELS] = { + [0 ... NR_EVENT_CHANNELS-1] = -1 +}; +static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG]; +static u8 cpu_evtchn[NR_EVENT_CHANNELS]; + +/* Reference counts for bindings to IRQs. */ +static int irq_bindcount[NR_IRQS]; + +/* Xen will never allocate port zero for any purpose. */ +#define VALID_EVTCHN(chn) ((chn) != 0) + +/* + * Force a proper event-channel callback from Xen after clearing the + * callback mask. We do this in a very simple manner, by making a call + * down into Xen. The pending flag will be checked by Xen on return. + */ +void force_evtchn_callback(void) +{ + (void)HYPERVISOR_xen_version(0, NULL); +} +EXPORT_SYMBOL_GPL(force_evtchn_callback); + +static struct irq_chip xen_dynamic_chip; + +/* Constructor for packed IRQ information. */ +static inline struct packed_irq mk_irq_info(u32 type, u32 index, u32 evtchn) +{ + return (struct packed_irq) { evtchn, index, type }; +} + +/* + * Accessors for packed IRQ information. + */ +static inline unsigned int evtchn_from_irq(int irq) +{ + return irq_info[irq].evtchn; +} + +static inline unsigned int index_from_irq(int irq) +{ + return irq_info[irq].index; +} + +static inline unsigned int type_from_irq(int irq) +{ + return irq_info[irq].type; +} + +static inline unsigned long active_evtchns(unsigned int cpu, + struct shared_info *sh, + unsigned int idx) +{ + return (sh->evtchn_pending[idx] & + cpu_evtchn_mask[cpu][idx] & + ~sh->evtchn_mask[idx]); +} + +static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ + int irq = evtchn_to_irq[chn]; + + BUG_ON(irq == -1); +#ifdef CONFIG_SMP + irq_desc[irq].affinity = cpumask_of_cpu(cpu); +#endif + + __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); + __set_bit(chn, cpu_evtchn_mask[cpu]); + + cpu_evtchn[chn] = cpu; +} + +static void init_evtchn_cpu_bindings(void) +{ +#ifdef CONFIG_SMP + int i; + /* By default all event channels notify CPU#0. */ + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].affinity = cpumask_of_cpu(0); +#endif + + memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); + memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0])); +} + +static inline unsigned int cpu_from_evtchn(unsigned int evtchn) +{ + return cpu_evtchn[evtchn]; +} + +static inline void clear_evtchn(int port) +{ + struct shared_info *s = HYPERVISOR_shared_info; + sync_clear_bit(port, &s->evtchn_pending[0]); +} + +static inline void set_evtchn(int port) +{ + struct shared_info *s = HYPERVISOR_shared_info; + sync_set_bit(port, &s->evtchn_pending[0]); +} + + +/** + * notify_remote_via_irq - send event to remote end of event channel via irq + * @irq: irq of event channel to send event to + * + * Unlike notify_remote_via_evtchn(), this is safe to use across + * save/restore. Notifications on a broken connection are silently + * dropped. + */ +void notify_remote_via_irq(int irq) +{ + int evtchn = evtchn_from_irq(irq); + + if (VALID_EVTCHN(evtchn)) + notify_remote_via_evtchn(evtchn); +} +EXPORT_SYMBOL_GPL(notify_remote_via_irq); + +static void mask_evtchn(int port) +{ + struct shared_info *s = HYPERVISOR_shared_info; + sync_set_bit(port, &s->evtchn_mask[0]); +} + +static void unmask_evtchn(int port) +{ + struct shared_info *s = HYPERVISOR_shared_info; + unsigned int cpu = get_cpu(); + + BUG_ON(!irqs_disabled()); + + /* Slow path (hypercall) if this is a non-local port. */ + if (unlikely(cpu != cpu_from_evtchn(port))) { + struct evtchn_unmask unmask = { .port = port }; + (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask); + } else { + struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu); + + sync_clear_bit(port, &s->evtchn_mask[0]); + + /* + * The following is basically the equivalent of + * 'hw_resend_irq'. Just like a real IO-APIC we 'lose + * the interrupt edge' if the channel is masked. + */ + if (sync_test_bit(port, &s->evtchn_pending[0]) && + !sync_test_and_set_bit(port / BITS_PER_LONG, + &vcpu_info->evtchn_pending_sel)) + vcpu_info->evtchn_upcall_pending = 1; + } + + put_cpu(); +} + +static int find_unbound_irq(void) +{ + int irq; + + /* Only allocate from dynirq range */ + for (irq = 0; irq < NR_IRQS; irq++) + if (irq_bindcount[irq] == 0) + break; + + if (irq == NR_IRQS) + panic("No available IRQ to bind to: increase NR_IRQS!\n"); + + return irq; +} + +int bind_evtchn_to_irq(unsigned int evtchn) +{ + int irq; + + spin_lock(&irq_mapping_update_lock); + + irq = evtchn_to_irq[evtchn]; + + if (irq == -1) { + irq = find_unbound_irq(); + + dynamic_irq_init(irq); + set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, + handle_level_irq, "event"); + + evtchn_to_irq[evtchn] = irq; + irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn); + } + + irq_bindcount[irq]++; + + spin_unlock(&irq_mapping_update_lock); + + return irq; +} +EXPORT_SYMBOL_GPL(bind_evtchn_to_irq); + +static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) +{ + struct evtchn_bind_ipi bind_ipi; + int evtchn, irq; + + spin_lock(&irq_mapping_update_lock); + + irq = per_cpu(ipi_to_irq, cpu)[ipi]; + if (irq == -1) { + irq = find_unbound_irq(); + if (irq < 0) + goto out; + + dynamic_irq_init(irq); + set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, + handle_level_irq, "ipi"); + + bind_ipi.vcpu = cpu; + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, + &bind_ipi) != 0) + BUG(); + evtchn = bind_ipi.port; + + evtchn_to_irq[evtchn] = irq; + irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn); + + per_cpu(ipi_to_irq, cpu)[ipi] = irq; + + bind_evtchn_to_cpu(evtchn, cpu); + } + + irq_bindcount[irq]++; + + out: + spin_unlock(&irq_mapping_update_lock); + return irq; +} + + +static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) +{ + struct evtchn_bind_virq bind_virq; + int evtchn, irq; + + spin_lock(&irq_mapping_update_lock); + + irq = per_cpu(virq_to_irq, cpu)[virq]; + + if (irq == -1) { + bind_virq.virq = virq; + bind_virq.vcpu = cpu; + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, + &bind_virq) != 0) + BUG(); + evtchn = bind_virq.port; + + irq = find_unbound_irq(); + + dynamic_irq_init(irq); + set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, + handle_level_irq, "virq"); + + evtchn_to_irq[evtchn] = irq; + irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn); + + per_cpu(virq_to_irq, cpu)[virq] = irq; + + bind_evtchn_to_cpu(evtchn, cpu); + } + + irq_bindcount[irq]++; + + spin_unlock(&irq_mapping_update_lock); + + return irq; +} + +static void unbind_from_irq(unsigned int irq) +{ + struct evtchn_close close; + int evtchn = evtchn_from_irq(irq); + + spin_lock(&irq_mapping_update_lock); + + if (VALID_EVTCHN(evtchn) && (--irq_bindcount[irq] == 0)) { + close.port = evtchn; + if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) + BUG(); + + switch (type_from_irq(irq)) { + case IRQT_VIRQ: + per_cpu(virq_to_irq, cpu_from_evtchn(evtchn)) + [index_from_irq(irq)] = -1; + break; + default: + break; + } + + /* Closed ports are implicitly re-bound to VCPU0. */ + bind_evtchn_to_cpu(evtchn, 0); + + evtchn_to_irq[evtchn] = -1; + irq_info[irq] = IRQ_UNBOUND; + + dynamic_irq_init(irq); + } + + spin_unlock(&irq_mapping_update_lock); +} + +int bind_evtchn_to_irqhandler(unsigned int evtchn, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, void *dev_id) +{ + unsigned int irq; + int retval; + + irq = bind_evtchn_to_irq(evtchn); + retval = request_irq(irq, handler, irqflags, devname, dev_id); + if (retval != 0) { + unbind_from_irq(irq); + return retval; + } + + return irq; +} +EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler); + +int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, + irq_handler_t handler, + unsigned long irqflags, const char *devname, void *dev_id) +{ + unsigned int irq; + int retval; + + irq = bind_virq_to_irq(virq, cpu); + retval = request_irq(irq, handler, irqflags, devname, dev_id); + if (retval != 0) { + unbind_from_irq(irq); + return retval; + } + + return irq; +} +EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler); + +int bind_ipi_to_irqhandler(enum ipi_vector ipi, + unsigned int cpu, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_id) +{ + int irq, retval; + + irq = bind_ipi_to_irq(ipi, cpu); + if (irq < 0) + return irq; + + retval = request_irq(irq, handler, irqflags, devname, dev_id); + if (retval != 0) { + unbind_from_irq(irq); + return retval; + } + + return irq; +} + +void unbind_from_irqhandler(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); + unbind_from_irq(irq); +} +EXPORT_SYMBOL_GPL(unbind_from_irqhandler); + +void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) +{ + int irq = per_cpu(ipi_to_irq, cpu)[vector]; + BUG_ON(irq < 0); + notify_remote_via_irq(irq); +} + +irqreturn_t xen_debug_interrupt(int irq, void *dev_id) +{ + struct shared_info *sh = HYPERVISOR_shared_info; + int cpu = smp_processor_id(); + int i; + unsigned long flags; + static DEFINE_SPINLOCK(debug_lock); + + spin_lock_irqsave(&debug_lock, flags); + + printk("vcpu %d\n ", cpu); + + for_each_online_cpu(i) { + struct vcpu_info *v = per_cpu(xen_vcpu, i); + printk("%d: masked=%d pending=%d event_sel %08lx\n ", i, + (get_irq_regs() && i == cpu) ? !(get_irq_regs()->flags & X86_EFLAGS_IF) : v->evtchn_upcall_mask, + v->evtchn_upcall_pending, + v->evtchn_pending_sel); + } + printk("pending:\n "); + for(i = ARRAY_SIZE(sh->evtchn_pending)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_pending[i], + i % 8 == 0 ? "\n " : " "); + printk("\nmasks:\n "); + for(i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_mask[i], + i % 8 == 0 ? "\n " : " "); + + printk("\nunmasked:\n "); + for(i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_pending[i] & ~sh->evtchn_mask[i], + i % 8 == 0 ? "\n " : " "); + + printk("\npending list:\n"); + for(i = 0; i < NR_EVENT_CHANNELS; i++) { + if (sync_test_bit(i, sh->evtchn_pending)) { + printk(" %d: event %d -> irq %d\n", + cpu_evtchn[i], i, + evtchn_to_irq[i]); + } + } + + spin_unlock_irqrestore(&debug_lock, flags); + + return IRQ_HANDLED; +} + + +/* + * Search the CPUs pending events bitmasks. For each one found, map + * the event number to an irq, and feed it into do_IRQ() for + * handling. + * + * Xen uses a two-level bitmap to speed searching. The first level is + * a bitset of words which contain pending event bits. The second + * level is a bitset of pending events themselves. + */ +void xen_evtchn_do_upcall(struct pt_regs *regs) +{ + int cpu = get_cpu(); + struct shared_info *s = HYPERVISOR_shared_info; + struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu); + static DEFINE_PER_CPU(unsigned, nesting_count); + unsigned count; + + do { + unsigned long pending_words; + + vcpu_info->evtchn_upcall_pending = 0; + + if (__get_cpu_var(nesting_count)++) + goto out; + + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); + while (pending_words != 0) { + unsigned long pending_bits; + int word_idx = __ffs(pending_words); + pending_words &= ~(1UL << word_idx); + + while ((pending_bits = active_evtchns(cpu, s, word_idx)) != 0) { + int bit_idx = __ffs(pending_bits); + int port = (word_idx * BITS_PER_LONG) + bit_idx; + int irq = evtchn_to_irq[port]; + + if (irq != -1) { + regs->orig_ax = ~irq; + do_IRQ(regs); + } + } + } + + BUG_ON(!irqs_disabled()); + + count = __get_cpu_var(nesting_count); + __get_cpu_var(nesting_count) = 0; + } while(count != 1); + +out: + put_cpu(); +} + +/* Rebind an evtchn so that it gets delivered to a specific cpu */ +static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu) +{ + struct evtchn_bind_vcpu bind_vcpu; + int evtchn = evtchn_from_irq(irq); + + if (!VALID_EVTCHN(evtchn)) + return; + + /* Send future instances of this interrupt to other vcpu. */ + bind_vcpu.port = evtchn; + bind_vcpu.vcpu = tcpu; + + /* + * If this fails, it usually just indicates that we're dealing with a + * virq or IPI channel, which don't actually need to be rebound. Ignore + * it, but don't do the xenlinux-level rebind in that case. + */ + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + bind_evtchn_to_cpu(evtchn, tcpu); +} + + +static void set_affinity_irq(unsigned irq, cpumask_t dest) +{ + unsigned tcpu = first_cpu(dest); + rebind_irq_to_cpu(irq, tcpu); +} + +static void enable_dynirq(unsigned int irq) +{ + int evtchn = evtchn_from_irq(irq); + + if (VALID_EVTCHN(evtchn)) + unmask_evtchn(evtchn); +} + +static void disable_dynirq(unsigned int irq) +{ + int evtchn = evtchn_from_irq(irq); + + if (VALID_EVTCHN(evtchn)) + mask_evtchn(evtchn); +} + +static void ack_dynirq(unsigned int irq) +{ + int evtchn = evtchn_from_irq(irq); + + move_native_irq(irq); + + if (VALID_EVTCHN(evtchn)) + clear_evtchn(evtchn); +} + +static int retrigger_dynirq(unsigned int irq) +{ + int evtchn = evtchn_from_irq(irq); + struct shared_info *sh = HYPERVISOR_shared_info; + int ret = 0; + + if (VALID_EVTCHN(evtchn)) { + int masked; + + masked = sync_test_and_set_bit(evtchn, sh->evtchn_mask); + sync_set_bit(evtchn, sh->evtchn_pending); + if (!masked) + unmask_evtchn(evtchn); + ret = 1; + } + + return ret; +} + +static struct irq_chip xen_dynamic_chip __read_mostly = { + .name = "xen-dyn", + .mask = disable_dynirq, + .unmask = enable_dynirq, + .ack = ack_dynirq, + .set_affinity = set_affinity_irq, + .retrigger = retrigger_dynirq, +}; + +void __init xen_init_IRQ(void) +{ + int i; + + init_evtchn_cpu_bindings(); + + /* No event channels are 'live' right now. */ + for (i = 0; i < NR_EVENT_CHANNELS; i++) + mask_evtchn(i); + + /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ + for (i = 0; i < NR_IRQS; i++) + irq_bindcount[i] = 0; + + irq_ctx_init(smp_processor_id()); +} -- cgit v1.2.2 From e849c3e9e0b786619c451d89ef0c47ac9a28fbc1 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:53:56 -0700 Subject: Xen: make events.c portable for ia64/xen support Remove x86 dependency in drivers/xen/events.c for ia64/xen support introducing include/asm/xen/events.h. Introduce xen_irqs_disabled() to hide regs->flags Introduce xen_do_IRQ() to hide regs->orig_ax. make enum ipi_vector definition arch specific. ia64/xen needs four vectors. Add one rmb() because on ia64 xchg() isn't barrier. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/events.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c50d499b1e6f..2396b4492f70 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -469,7 +469,7 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) for_each_online_cpu(i) { struct vcpu_info *v = per_cpu(xen_vcpu, i); printk("%d: masked=%d pending=%d event_sel %08lx\n ", i, - (get_irq_regs() && i == cpu) ? !(get_irq_regs()->flags & X86_EFLAGS_IF) : v->evtchn_upcall_mask, + (get_irq_regs() && i == cpu) ? xen_irqs_disabled(get_irq_regs()) : v->evtchn_upcall_mask, v->evtchn_upcall_pending, v->evtchn_pending_sel); } @@ -527,7 +527,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) if (__get_cpu_var(nesting_count)++) goto out; - /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ +#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ + /* Clear master flag /before/ clearing selector flag. */ + rmb(); +#endif pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); while (pending_words != 0) { unsigned long pending_bits; @@ -539,10 +542,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) int port = (word_idx * BITS_PER_LONG) + bit_idx; int irq = evtchn_to_irq[port]; - if (irq != -1) { - regs->orig_ax = ~irq; - do_IRQ(regs); - } + if (irq != -1) + xen_do_IRQ(irq, regs); } } -- cgit v1.2.2 From 642e0c882cd5369429c833d97e4804c8be473e8a Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:53:57 -0700 Subject: xen: add resend_irq_on_evtchn() definition into events.c Define resend_irq_on_evtchn() which ia64/xen uses. Although it isn't used by current x86/xen code, it's arch generic so that put it into common code. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/events.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 2396b4492f70..4f0f22b020ea 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -586,6 +586,22 @@ static void set_affinity_irq(unsigned irq, cpumask_t dest) rebind_irq_to_cpu(irq, tcpu); } +int resend_irq_on_evtchn(unsigned int irq) +{ + int masked, evtchn = evtchn_from_irq(irq); + struct shared_info *s = HYPERVISOR_shared_info; + + if (!VALID_EVTCHN(evtchn)) + return 1; + + masked = sync_test_and_set_bit(evtchn, s->evtchn_mask); + sync_set_bit(evtchn, s->evtchn_pending); + if (!masked) + unmask_evtchn(evtchn); + + return 1; +} + static void enable_dynirq(unsigned int irq) { int evtchn = evtchn_from_irq(irq); -- cgit v1.2.2 From 5f0ababbf49f12330effab932a18055a50f4c0a1 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:53:59 -0700 Subject: xen: replace callers of alloc_vm_area()/free_vm_area() with xen_ prefixed one Don't use alloc_vm_area()/free_vm_area() directly, instead define xen_alloc_vm_area()/xen_free_vm_area() and use them. alloc_vm_area()/free_vm_area() are used to allocate/free area which are for grant table mapping. Xen/x86 grant table is based on virtual address so that alloc_vm_area()/free_vm_area() are suitable. On the other hand Xen/ia64 (and Xen/powerpc) grant table is based on pseudo physical address (guest physical address) so that allocation should be done differently. The original version of xenified Linux/IA64 have its own allocate_vm_area()/free_vm_area() definitions which don't allocate vm area contradictory to those names. Now vanilla Linux already has its definitions so that it's impossible to have IA64 definitions of allocate_vm_area()/free_vm_area(). Instead introduce xen_allocate_vm_area()/xen_free_vm_area() and use them. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/grant-table.c | 2 +- drivers/xen/xenbus/xenbus_client.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index d4a89b3d694f..3e02808c4055 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -482,7 +482,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) if (shared == NULL) { struct vm_struct *area; - area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); + area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); BUG_ON(area == NULL); shared = area->addr; } diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 9fd2f70ab46d..0f86b0ff7879 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -399,7 +399,7 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr) *vaddr = NULL; - area = alloc_vm_area(PAGE_SIZE); + area = xen_alloc_vm_area(PAGE_SIZE); if (!area) return -ENOMEM; @@ -409,7 +409,7 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr) BUG(); if (op.status != GNTST_okay) { - free_vm_area(area); + xen_free_vm_area(area); xenbus_dev_fatal(dev, op.status, "mapping in shared page %d from domain %d", gnt_ref, dev->otherend_id); @@ -508,7 +508,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) BUG(); if (op.status == GNTST_okay) - free_vm_area(area); + xen_free_vm_area(area); else xenbus_dev_error(dev, op.status, "unmapping page at handle %d error %d", -- cgit v1.2.2 From 8d3d2106c19f4e69f208f59fe484ca113fbb48b3 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:54:00 -0700 Subject: xen: make grant table arch portable split out x86 specific part from grant-table.c and allow ia64/xen specific initialization. ia64/xen grant table is based on pseudo physical address (guest physical address) unlike x86/xen. On ia64 init_mm doesn't map identity straight mapped area. ia64/xen specific grant table initialization is necessary. Signed-off-by: Isaku Yamahata Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/grant-table.c | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 3e02808c4055..52b6b41b909d 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -439,24 +439,6 @@ static inline unsigned int max_nr_grant_frames(void) return xen_max; } -static int map_pte_fn(pte_t *pte, struct page *pmd_page, - unsigned long addr, void *data) -{ - unsigned long **frames = (unsigned long **)data; - - set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL)); - (*frames)++; - return 0; -} - -static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, - unsigned long addr, void *data) -{ - - set_pte_at(&init_mm, addr, pte, __pte(0)); - return 0; -} - static int gnttab_map(unsigned int start_idx, unsigned int end_idx) { struct gnttab_setup_table setup; @@ -480,17 +462,9 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) BUG_ON(rc || setup.status); - if (shared == NULL) { - struct vm_struct *area; - area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); - BUG_ON(area == NULL); - shared = area->addr; - } - rc = apply_to_page_range(&init_mm, (unsigned long)shared, - PAGE_SIZE * nr_gframes, - map_pte_fn, &frames); + rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(), + &shared); BUG_ON(rc); - frames -= nr_gframes; /* adjust after map_pte_fn() */ kfree(frames); @@ -506,10 +480,7 @@ static int gnttab_resume(void) static int gnttab_suspend(void) { - apply_to_page_range(&init_mm, (unsigned long)shared, - PAGE_SIZE * nr_grant_frames, - unmap_pte_fn, NULL); - + arch_gnttab_unmap_shared(shared, nr_grant_frames); return 0; } -- cgit v1.2.2 From b15993fcc1bf15f717fb4414b32e4a11534dfdc4 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 2 Apr 2008 10:54:01 -0700 Subject: xen: import arch generic part of xencomm On xen/ia64 and xen/powerpc hypercall arguments are passed by pseudo physical address (guest physical address) so that it's necessary to convert from virtual address into pseudo physical address. The frame work is called xencomm. Import arch generic part of xencomm. Signed-off-by: Isaku Yamahata Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/xen/Makefile | 1 + drivers/xen/xencomm.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 drivers/xen/xencomm.c (limited to 'drivers') diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 823ce788b14b..43f014cfb458 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,2 +1,3 @@ obj-y += grant-table.o features.o events.o obj-y += xenbus/ +obj-$(CONFIG_XEN_XENCOMM) += xencomm.o diff --git a/drivers/xen/xencomm.c b/drivers/xen/xencomm.c new file mode 100644 index 000000000000..797cb4e31f07 --- /dev/null +++ b/drivers/xen/xencomm.c @@ -0,0 +1,232 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) IBM Corp. 2006 + * + * Authors: Hollis Blanchard + */ + +#include +#include +#include +#include +#include +#ifdef __ia64__ +#include /* for is_kern_addr() */ +#endif + +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include +#endif + +static int xencomm_init(struct xencomm_desc *desc, + void *buffer, unsigned long bytes) +{ + unsigned long recorded = 0; + int i = 0; + + while ((recorded < bytes) && (i < desc->nr_addrs)) { + unsigned long vaddr = (unsigned long)buffer + recorded; + unsigned long paddr; + int offset; + int chunksz; + + offset = vaddr % PAGE_SIZE; /* handle partial pages */ + chunksz = min(PAGE_SIZE - offset, bytes - recorded); + + paddr = xencomm_vtop(vaddr); + if (paddr == ~0UL) { + printk(KERN_DEBUG "%s: couldn't translate vaddr %lx\n", + __func__, vaddr); + return -EINVAL; + } + + desc->address[i++] = paddr; + recorded += chunksz; + } + + if (recorded < bytes) { + printk(KERN_DEBUG + "%s: could only translate %ld of %ld bytes\n", + __func__, recorded, bytes); + return -ENOSPC; + } + + /* mark remaining addresses invalid (just for safety) */ + while (i < desc->nr_addrs) + desc->address[i++] = XENCOMM_INVALID; + + desc->magic = XENCOMM_MAGIC; + + return 0; +} + +static struct xencomm_desc *xencomm_alloc(gfp_t gfp_mask, + void *buffer, unsigned long bytes) +{ + struct xencomm_desc *desc; + unsigned long buffer_ulong = (unsigned long)buffer; + unsigned long start = buffer_ulong & PAGE_MASK; + unsigned long end = (buffer_ulong + bytes) | ~PAGE_MASK; + unsigned long nr_addrs = (end - start + 1) >> PAGE_SHIFT; + unsigned long size = sizeof(*desc) + + sizeof(desc->address[0]) * nr_addrs; + + /* + * slab allocator returns at least sizeof(void*) aligned pointer. + * When sizeof(*desc) > sizeof(void*), struct xencomm_desc might + * cross page boundary. + */ + if (sizeof(*desc) > sizeof(void *)) { + unsigned long order = get_order(size); + desc = (struct xencomm_desc *)__get_free_pages(gfp_mask, + order); + if (desc == NULL) + return NULL; + + desc->nr_addrs = + ((PAGE_SIZE << order) - sizeof(struct xencomm_desc)) / + sizeof(*desc->address); + } else { + desc = kmalloc(size, gfp_mask); + if (desc == NULL) + return NULL; + + desc->nr_addrs = nr_addrs; + } + return desc; +} + +void xencomm_free(struct xencomm_handle *desc) +{ + if (desc && !((ulong)desc & XENCOMM_INLINE_FLAG)) { + struct xencomm_desc *desc__ = (struct xencomm_desc *)desc; + if (sizeof(*desc__) > sizeof(void *)) { + unsigned long size = sizeof(*desc__) + + sizeof(desc__->address[0]) * desc__->nr_addrs; + unsigned long order = get_order(size); + free_pages((unsigned long)__va(desc), order); + } else + kfree(__va(desc)); + } +} + +static int xencomm_create(void *buffer, unsigned long bytes, + struct xencomm_desc **ret, gfp_t gfp_mask) +{ + struct xencomm_desc *desc; + int rc; + + pr_debug("%s: %p[%ld]\n", __func__, buffer, bytes); + + if (bytes == 0) { + /* don't create a descriptor; Xen recognizes NULL. */ + BUG_ON(buffer != NULL); + *ret = NULL; + return 0; + } + + BUG_ON(buffer == NULL); /* 'bytes' is non-zero */ + + desc = xencomm_alloc(gfp_mask, buffer, bytes); + if (!desc) { + printk(KERN_DEBUG "%s failure\n", "xencomm_alloc"); + return -ENOMEM; + } + + rc = xencomm_init(desc, buffer, bytes); + if (rc) { + printk(KERN_DEBUG "%s failure: %d\n", "xencomm_init", rc); + xencomm_free((struct xencomm_handle *)__pa(desc)); + return rc; + } + + *ret = desc; + return 0; +} + +/* check if memory address is within VMALLOC region */ +static int is_phys_contiguous(unsigned long addr) +{ + if (!is_kernel_addr(addr)) + return 0; + + return (addr < VMALLOC_START) || (addr >= VMALLOC_END); +} + +static struct xencomm_handle *xencomm_create_inline(void *ptr) +{ + unsigned long paddr; + + BUG_ON(!is_phys_contiguous((unsigned long)ptr)); + + paddr = (unsigned long)xencomm_pa(ptr); + BUG_ON(paddr & XENCOMM_INLINE_FLAG); + return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG); +} + +/* "mini" routine, for stack-based communications: */ +static int xencomm_create_mini(void *buffer, + unsigned long bytes, struct xencomm_mini *xc_desc, + struct xencomm_desc **ret) +{ + int rc = 0; + struct xencomm_desc *desc; + BUG_ON(((unsigned long)xc_desc) % sizeof(*xc_desc) != 0); + + desc = (void *)xc_desc; + + desc->nr_addrs = XENCOMM_MINI_ADDRS; + + rc = xencomm_init(desc, buffer, bytes); + if (!rc) + *ret = desc; + + return rc; +} + +struct xencomm_handle *xencomm_map(void *ptr, unsigned long bytes) +{ + int rc; + struct xencomm_desc *desc; + + if (is_phys_contiguous((unsigned long)ptr)) + return xencomm_create_inline(ptr); + + rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL); + + if (rc || desc == NULL) + return NULL; + + return xencomm_pa(desc); +} + +struct xencomm_handle *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, + struct xencomm_mini *xc_desc) +{ + int rc; + struct xencomm_desc *desc = NULL; + + if (is_phys_contiguous((unsigned long)ptr)) + return xencomm_create_inline(ptr); + + rc = xencomm_create_mini(ptr, bytes, xc_desc, + &desc); + + if (rc) + return NULL; + + return xencomm_pa(desc); +} -- cgit v1.2.2 From 3e334239d89d4a71610be5a3e8432464d421d9ec Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 2 Apr 2008 10:54:02 -0700 Subject: xen: Make xen-blkfront write its protocol ABI to xenstore Frontends are expected to write their protocol ABI to xenstore. Since the protocol ABI defaults to the backend's native ABI, things work fine without that as long as the frontend's native ABI is identical to the backend's native ABI. This is not the case for xen-blkfront running 32-on-64, because its ABI differs between 32 and 64 bit, and thus needs this fix. Based on http://xenbits.xensource.com/xen-unstable.hg?rev/c545932a18f3 and http://xenbits.xensource.com/xen-unstable.hg?rev/ffe52263b430 by Gerd Hoffmann Signed-off-by: Markus Armbruster Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/block/xen-blkfront.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9c6f3f99208d..2e7c81e3f36a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -47,6 +47,7 @@ #include #include +#include #include @@ -614,6 +615,12 @@ again: message = "writing event-channel"; goto abort_transaction; } + err = xenbus_printf(xbt, dev->nodename, "protocol", "%s", + XEN_IO_PROTO_ABI_NATIVE); + if (err) { + message = "writing protocol"; + goto abort_transaction; + } err = xenbus_transaction_end(xbt, 0); if (err) { -- cgit v1.2.2 From 53f0e8afcb0d57cfaff06b89eb8b5302f167577e Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 Apr 2008 10:54:03 -0700 Subject: xen/blkfront: use bdget_disk info->dev is never initialized to anything, so bdget(info->dev) is meaningless. Get rid of info->dev, and use bdget_disk on the gendisk. Signed-off-by: Jeremy Fitzhardinge Cc: Al Viro Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/block/xen-blkfront.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2e7c81e3f36a..4497ff84f64a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -75,7 +75,6 @@ static struct block_device_operations xlvbd_block_fops; struct blkfront_info { struct xenbus_device *xbdev; - dev_t dev; struct gendisk *gd; int vdevice; blkif_vdev_t handle; @@ -903,7 +902,7 @@ static void backend_changed(struct xenbus_device *dev, break; case XenbusStateClosing: - bd = bdget(info->dev); + bd = bdget_disk(info->gd, 0); if (bd == NULL) xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); -- cgit v1.2.2 From 1d78d7055629e3f6300d6b8d7028259ee2bffc0e Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Wed, 2 Apr 2008 10:54:04 -0700 Subject: xen blkfront: Delay wait for block devices until after the disk is added When the xen block frontend driver is built as a module the module load is only synchronous up to the point where the frontend and the backend become connected rather than when the disk is added. This means that there can be a race on boot between loading the module and loading the dm-* modules and doing the scan for LVM physical volumes (all in the initrd). In the failure case the disk is not present until after the scan for physical volumes is complete. Taken from: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/11483a00c017 Signed-off-by: Christian Limpach Signed-off-by: Mark McLoughlin Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/block/xen-blkfront.c | 11 +++++++++++ drivers/xen/xenbus/xenbus_probe.c | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4497ff84f64a..dfe61afe676a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -88,6 +88,7 @@ struct blkfront_info struct blk_shadow shadow[BLK_RING_SIZE]; unsigned long shadow_free; int feature_barrier; + int is_ready; /** * The number of people holding this device open. We won't allow a @@ -839,6 +840,8 @@ static void blkfront_connect(struct blkfront_info *info) spin_unlock_irq(&blkif_io_lock); add_disk(info->gd); + + info->is_ready = 1; } /** @@ -931,6 +934,13 @@ static int blkfront_remove(struct xenbus_device *dev) return 0; } +static int blkfront_is_ready(struct xenbus_device *dev) +{ + struct blkfront_info *info = dev->dev.driver_data; + + return info->is_ready; +} + static int blkif_open(struct inode *inode, struct file *filep) { struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; @@ -977,6 +987,7 @@ static struct xenbus_driver blkfront = { .remove = blkfront_remove, .resume = blkfront_resume, .otherend_changed = backend_changed, + .is_ready = blkfront_is_ready, }; static int __init xlblk_init(void) diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 4750de316ad3..88fc5ec665f5 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -846,6 +846,7 @@ static int is_disconnected_device(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); struct device_driver *drv = data; + struct xenbus_driver *xendrv; /* * A device with no driver will never connect. We care only about @@ -858,7 +859,9 @@ static int is_disconnected_device(struct device *dev, void *data) if (drv && (dev->driver != drv)) return 0; - return (xendev->state != XenbusStateConnected); + xendrv = to_xenbus_driver(dev->driver); + return (xendev->state != XenbusStateConnected || + (xendrv->is_ready && !xendrv->is_ready(xendev))); } static int exists_disconnected_device(struct device_driver *drv) -- cgit v1.2.2 From d2f0c52bec954460e72dee48f3a29c6f310d76be Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Wed, 2 Apr 2008 10:54:05 -0700 Subject: xen: Module autoprobing support for frontend drivers Add module aliases to support autoprobing modules for xen frontend devices. Signed-off-by: Mark McLoughlin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/block/xen-blkfront.c | 1 + drivers/net/xen-netfront.c | 1 + drivers/xen/xenbus/xenbus_probe.c | 27 +++++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index dfe61afe676a..ffa0b436129b 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1015,3 +1015,4 @@ module_exit(xlblk_exit); MODULE_DESCRIPTION("Xen virtual block device frontend"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR); +MODULE_ALIAS("xen:vbd"); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 7483d45bc5bc..b3fa27e6c78a 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1809,3 +1809,4 @@ module_exit(netif_exit); MODULE_DESCRIPTION("Xen virtual network device frontend"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("xen:vif"); diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 88fc5ec665f5..57ceb5346b74 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -88,6 +88,16 @@ int xenbus_match(struct device *_dev, struct device_driver *_drv) return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; } +static int xenbus_uevent(struct device *_dev, struct kobj_uevent_env *env) +{ + struct xenbus_device *dev = to_xenbus_device(_dev); + + if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype)) + return -ENOMEM; + + return 0; +} + /* device// => - */ static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) { @@ -166,6 +176,7 @@ static struct xen_bus_type xenbus_frontend = { .bus = { .name = "xen", .match = xenbus_match, + .uevent = xenbus_uevent, .probe = xenbus_dev_probe, .remove = xenbus_dev_remove, .shutdown = xenbus_dev_shutdown, @@ -438,6 +449,12 @@ static ssize_t xendev_show_devtype(struct device *dev, } DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); +static ssize_t xendev_show_modalias(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype); +} +DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL); int xenbus_probe_node(struct xen_bus_type *bus, const char *type, @@ -492,10 +509,16 @@ int xenbus_probe_node(struct xen_bus_type *bus, err = device_create_file(&xendev->dev, &dev_attr_devtype); if (err) - goto fail_remove_file; + goto fail_remove_nodename; + + err = device_create_file(&xendev->dev, &dev_attr_modalias); + if (err) + goto fail_remove_devtype; return 0; -fail_remove_file: +fail_remove_devtype: + device_remove_file(&xendev->dev, &dev_attr_devtype); +fail_remove_nodename: device_remove_file(&xendev->dev, &dev_attr_nodename); fail_unregister: device_unregister(&xendev->dev); -- cgit v1.2.2 From 4f93f09b72d6ff47b2399b79ed6d1cbc7dbf991b Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Wed, 2 Apr 2008 10:54:06 -0700 Subject: xen: Add compatibility aliases for frontend drivers Before getting merged, xen-blkfront was xenblk and xen-netfront was xennet. Temporarily adding compatibility module aliases eases upgrades from older versions by e.g. allowing mkinitrd to find the new version of the module. Signed-off-by: Mark McLoughlin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/block/xen-blkfront.c | 1 + drivers/net/xen-netfront.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ffa0b436129b..d771da816d95 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1016,3 +1016,4 @@ MODULE_DESCRIPTION("Xen virtual block device frontend"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR); MODULE_ALIAS("xen:vbd"); +MODULE_ALIAS("xenblk"); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b3fa27e6c78a..e62018a36133 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1810,3 +1810,4 @@ module_exit(netif_exit); MODULE_DESCRIPTION("Xen virtual network device frontend"); MODULE_LICENSE("GPL"); MODULE_ALIAS("xen:vif"); +MODULE_ALIAS("xennet"); -- cgit v1.2.2 From 4ee36dc08e5c4d16d078f59acd6d9d536f9718dd Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 2 Apr 2008 10:54:07 -0700 Subject: xen pvfb: Para-virtual framebuffer, keyboard and pointer driver This is a pair of Xen para-virtual frontend device drivers: drivers/video/xen-fbfront.c provides a framebuffer, and drivers/input/xen-kbdfront provides keyboard and mouse. The backends run in dom0 user space. The two drivers are not in two separate patches, because the intermediate step (one driver, not the other) is somewhat problematic: the backend in dom0 needs both drivers, and will refuse to complete device initialization unless they're both present. Signed-off-by: Markus Armbruster Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/input/Kconfig | 9 + drivers/input/Makefile | 2 + drivers/input/xen-kbdfront.c | 340 ++++++++++++++++++++++++++ drivers/video/Kconfig | 14 ++ drivers/video/Makefile | 1 + drivers/video/xen-fbfront.c | 550 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 916 insertions(+) create mode 100644 drivers/input/xen-kbdfront.c create mode 100644 drivers/video/xen-fbfront.c (limited to 'drivers') diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 9dea14db724c..5f9d860925a1 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -149,6 +149,15 @@ config INPUT_APMPOWER To compile this driver as a module, choose M here: the module will be called apm-power. +config XEN_KBDDEV_FRONTEND + tristate "Xen virtual keyboard and mouse support" + depends on XEN_FBDEV_FRONTEND + default y + help + This driver implements the front-end of the Xen virtual + keyboard and mouse device driver. It communicates with a back-end + in another domain. + comment "Input Device Drivers" source "drivers/input/keyboard/Kconfig" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 2ae87b19caa8..98c4f9a77876 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -23,3 +23,5 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o + +obj-$(CONFIG_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c new file mode 100644 index 000000000000..0f47f4697cdf --- /dev/null +++ b/drivers/input/xen-kbdfront.c @@ -0,0 +1,340 @@ +/* + * Xen para-virtual input device + * + * Copyright (C) 2005 Anthony Liguori + * Copyright (C) 2006-2008 Red Hat, Inc., Markus Armbruster + * + * Based on linux/drivers/input/mouse/sermouse.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +/* + * TODO: + * + * Switch to grant tables together with xen-fbfront.c. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct xenkbd_info { + struct input_dev *kbd; + struct input_dev *ptr; + struct xenkbd_page *page; + int irq; + struct xenbus_device *xbdev; + char phys[32]; +}; + +static int xenkbd_remove(struct xenbus_device *); +static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *); +static void xenkbd_disconnect_backend(struct xenkbd_info *); + +/* + * Note: if you need to send out events, see xenfb_do_update() for how + * to do that. + */ + +static irqreturn_t input_handler(int rq, void *dev_id) +{ + struct xenkbd_info *info = dev_id; + struct xenkbd_page *page = info->page; + __u32 cons, prod; + + prod = page->in_prod; + if (prod == page->in_cons) + return IRQ_HANDLED; + rmb(); /* ensure we see ring contents up to prod */ + for (cons = page->in_cons; cons != prod; cons++) { + union xenkbd_in_event *event; + struct input_dev *dev; + event = &XENKBD_IN_RING_REF(page, cons); + + dev = info->ptr; + switch (event->type) { + case XENKBD_TYPE_MOTION: + input_report_rel(dev, REL_X, event->motion.rel_x); + input_report_rel(dev, REL_Y, event->motion.rel_y); + break; + case XENKBD_TYPE_KEY: + dev = NULL; + if (test_bit(event->key.keycode, info->kbd->keybit)) + dev = info->kbd; + if (test_bit(event->key.keycode, info->ptr->keybit)) + dev = info->ptr; + if (dev) + input_report_key(dev, event->key.keycode, + event->key.pressed); + else + printk(KERN_WARNING + "xenkbd: unhandled keycode 0x%x\n", + event->key.keycode); + break; + case XENKBD_TYPE_POS: + input_report_abs(dev, ABS_X, event->pos.abs_x); + input_report_abs(dev, ABS_Y, event->pos.abs_y); + break; + } + if (dev) + input_sync(dev); + } + mb(); /* ensure we got ring contents */ + page->in_cons = cons; + notify_remote_via_irq(info->irq); + + return IRQ_HANDLED; +} + +static int __devinit xenkbd_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + int ret, i; + struct xenkbd_info *info; + struct input_dev *kbd, *ptr; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); + return -ENOMEM; + } + dev->dev.driver_data = info; + info->xbdev = dev; + info->irq = -1; + snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); + + info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); + if (!info->page) + goto error_nomem; + + /* keyboard */ + kbd = input_allocate_device(); + if (!kbd) + goto error_nomem; + kbd->name = "Xen Virtual Keyboard"; + kbd->phys = info->phys; + kbd->id.bustype = BUS_PCI; + kbd->id.vendor = 0x5853; + kbd->id.product = 0xffff; + kbd->evbit[0] = BIT(EV_KEY); + for (i = KEY_ESC; i < KEY_UNKNOWN; i++) + set_bit(i, kbd->keybit); + for (i = KEY_OK; i < KEY_MAX; i++) + set_bit(i, kbd->keybit); + + ret = input_register_device(kbd); + if (ret) { + input_free_device(kbd); + xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); + goto error; + } + info->kbd = kbd; + + /* pointing device */ + ptr = input_allocate_device(); + if (!ptr) + goto error_nomem; + ptr->name = "Xen Virtual Pointer"; + ptr->phys = info->phys; + ptr->id.bustype = BUS_PCI; + ptr->id.vendor = 0x5853; + ptr->id.product = 0xfffe; + ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); + for (i = BTN_LEFT; i <= BTN_TASK; i++) + set_bit(i, ptr->keybit); + ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); + input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); + + ret = input_register_device(ptr); + if (ret) { + input_free_device(ptr); + xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); + goto error; + } + info->ptr = ptr; + + ret = xenkbd_connect_backend(dev, info); + if (ret < 0) + goto error; + + return 0; + + error_nomem: + ret = -ENOMEM; + xenbus_dev_fatal(dev, ret, "allocating device memory"); + error: + xenkbd_remove(dev); + return ret; +} + +static int xenkbd_resume(struct xenbus_device *dev) +{ + struct xenkbd_info *info = dev->dev.driver_data; + + xenkbd_disconnect_backend(info); + memset(info->page, 0, PAGE_SIZE); + return xenkbd_connect_backend(dev, info); +} + +static int xenkbd_remove(struct xenbus_device *dev) +{ + struct xenkbd_info *info = dev->dev.driver_data; + + xenkbd_disconnect_backend(info); + if (info->kbd) + input_unregister_device(info->kbd); + if (info->ptr) + input_unregister_device(info->ptr); + free_page((unsigned long)info->page); + kfree(info); + return 0; +} + +static int xenkbd_connect_backend(struct xenbus_device *dev, + struct xenkbd_info *info) +{ + int ret, evtchn; + struct xenbus_transaction xbt; + + ret = xenbus_alloc_evtchn(dev, &evtchn); + if (ret) + return ret; + ret = bind_evtchn_to_irqhandler(evtchn, input_handler, + 0, dev->devicetype, info); + if (ret < 0) { + xenbus_free_evtchn(dev, evtchn); + xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); + return ret; + } + info->irq = ret; + + again: + ret = xenbus_transaction_start(&xbt); + if (ret) { + xenbus_dev_fatal(dev, ret, "starting transaction"); + return ret; + } + ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", + virt_to_mfn(info->page)); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", + evtchn); + if (ret) + goto error_xenbus; + ret = xenbus_transaction_end(xbt, 0); + if (ret) { + if (ret == -EAGAIN) + goto again; + xenbus_dev_fatal(dev, ret, "completing transaction"); + return ret; + } + + xenbus_switch_state(dev, XenbusStateInitialised); + return 0; + + error_xenbus: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, ret, "writing xenstore"); + return ret; +} + +static void xenkbd_disconnect_backend(struct xenkbd_info *info) +{ + if (info->irq >= 0) + unbind_from_irqhandler(info->irq, info); + info->irq = -1; +} + +static void xenkbd_backend_changed(struct xenbus_device *dev, + enum xenbus_state backend_state) +{ + struct xenkbd_info *info = dev->dev.driver_data; + int ret, val; + + switch (backend_state) { + case XenbusStateInitialising: + case XenbusStateInitialised: + case XenbusStateUnknown: + case XenbusStateClosed: + break; + + case XenbusStateInitWait: +InitWait: + ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend, + "feature-abs-pointer", "%d", &val); + if (ret < 0) + val = 0; + if (val) { + ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, + "request-abs-pointer", "1"); + if (ret) + printk(KERN_WARNING + "xenkbd: can't request abs-pointer"); + } + xenbus_switch_state(dev, XenbusStateConnected); + break; + + case XenbusStateConnected: + /* + * Work around xenbus race condition: If backend goes + * through InitWait to Connected fast enough, we can + * get Connected twice here. + */ + if (dev->state != XenbusStateConnected) + goto InitWait; /* no InitWait seen yet, fudge it */ + break; + + case XenbusStateClosing: + xenbus_frontend_closed(dev); + break; + } +} + +static struct xenbus_device_id xenkbd_ids[] = { + { "vkbd" }, + { "" } +}; + +static struct xenbus_driver xenkbd = { + .name = "vkbd", + .owner = THIS_MODULE, + .ids = xenkbd_ids, + .probe = xenkbd_probe, + .remove = xenkbd_remove, + .resume = xenkbd_resume, + .otherend_changed = xenkbd_backend_changed, +}; + +static int __init xenkbd_init(void) +{ + if (!is_running_on_xen()) + return -ENODEV; + + /* Nothing to do if running in dom0. */ + if (is_initial_xendomain()) + return -ENODEV; + + return xenbus_register_frontend(&xenkbd); +} + +static void __exit xenkbd_cleanup(void) +{ + xenbus_unregister_driver(&xenkbd); +} + +module_init(xenkbd_init); +module_exit(xenkbd_cleanup); + +MODULE_LICENSE("GPL"); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 1bd5fb30237d..e3dc8f8d0c3e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1930,6 +1930,20 @@ config FB_VIRTUAL If unsure, say N. +config XEN_FBDEV_FRONTEND + tristate "Xen virtual frame buffer support" + depends on FB && XEN + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + default y + help + This driver implements the front-end of the Xen virtual + frame buffer driver. It communicates with a back-end + in another domain. + source "drivers/video/omap/Kconfig" source "drivers/video/backlight/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 11c0e5e05f21..f172b9b73314 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -114,6 +114,7 @@ obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_XILINX) += xilinxfb.o obj-$(CONFIG_FB_OMAP) += omap/ +obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c new file mode 100644 index 000000000000..619a6f8d65a2 --- /dev/null +++ b/drivers/video/xen-fbfront.c @@ -0,0 +1,550 @@ +/* + * Xen para-virtual frame buffer device + * + * Copyright (C) 2005-2006 Anthony Liguori + * Copyright (C) 2006-2008 Red Hat, Inc., Markus Armbruster + * + * Based on linux/drivers/video/q40fb.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +/* + * TODO: + * + * Switch to grant tables when they become capable of dealing with the + * frame buffer. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct xenfb_info { + unsigned char *fb; + struct fb_info *fb_info; + int x1, y1, x2, y2; /* dirty rectangle, + protected by dirty_lock */ + spinlock_t dirty_lock; + int nr_pages; + int irq; + struct xenfb_page *page; + unsigned long *mfns; + int update_wanted; /* XENFB_TYPE_UPDATE wanted */ + + struct xenbus_device *xbdev; +}; + +static u32 xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8; + +static int xenfb_remove(struct xenbus_device *); +static void xenfb_init_shared_page(struct xenfb_info *); +static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *); +static void xenfb_disconnect_backend(struct xenfb_info *); + +static void xenfb_do_update(struct xenfb_info *info, + int x, int y, int w, int h) +{ + union xenfb_out_event event; + u32 prod; + + event.type = XENFB_TYPE_UPDATE; + event.update.x = x; + event.update.y = y; + event.update.width = w; + event.update.height = h; + + prod = info->page->out_prod; + /* caller ensures !xenfb_queue_full() */ + mb(); /* ensure ring space available */ + XENFB_OUT_RING_REF(info->page, prod) = event; + wmb(); /* ensure ring contents visible */ + info->page->out_prod = prod + 1; + + notify_remote_via_irq(info->irq); +} + +static int xenfb_queue_full(struct xenfb_info *info) +{ + u32 cons, prod; + + prod = info->page->out_prod; + cons = info->page->out_cons; + return prod - cons == XENFB_OUT_RING_LEN; +} + +static void xenfb_refresh(struct xenfb_info *info, + int x1, int y1, int w, int h) +{ + unsigned long flags; + int y2 = y1 + h - 1; + int x2 = x1 + w - 1; + + if (!info->update_wanted) + return; + + spin_lock_irqsave(&info->dirty_lock, flags); + + /* Combine with dirty rectangle: */ + if (info->y1 < y1) + y1 = info->y1; + if (info->y2 > y2) + y2 = info->y2; + if (info->x1 < x1) + x1 = info->x1; + if (info->x2 > x2) + x2 = info->x2; + + if (xenfb_queue_full(info)) { + /* Can't send right now, stash it in the dirty rectangle */ + info->x1 = x1; + info->x2 = x2; + info->y1 = y1; + info->y2 = y2; + spin_unlock_irqrestore(&info->dirty_lock, flags); + return; + } + + /* Clear dirty rectangle: */ + info->x1 = info->y1 = INT_MAX; + info->x2 = info->y2 = 0; + + spin_unlock_irqrestore(&info->dirty_lock, flags); + + if (x1 <= x2 && y1 <= y2) + xenfb_do_update(info, x1, y1, x2 - x1 + 1, y2 - y1 + 1); +} + +static void xenfb_deferred_io(struct fb_info *fb_info, + struct list_head *pagelist) +{ + struct xenfb_info *info = fb_info->par; + struct page *page; + unsigned long beg, end; + int y1, y2, miny, maxy; + + miny = INT_MAX; + maxy = 0; + list_for_each_entry(page, pagelist, lru) { + beg = page->index << PAGE_SHIFT; + end = beg + PAGE_SIZE - 1; + y1 = beg / fb_info->fix.line_length; + y2 = end / fb_info->fix.line_length; + if (y2 >= fb_info->var.yres) + y2 = fb_info->var.yres - 1; + if (miny > y1) + miny = y1; + if (maxy < y2) + maxy = y2; + } + xenfb_refresh(info, 0, miny, fb_info->var.xres, maxy - miny + 1); +} + +static struct fb_deferred_io xenfb_defio = { + .delay = HZ / 20, + .deferred_io = xenfb_deferred_io, +}; + +static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + u32 v; + + if (regno > info->cmap.len) + return 1; + +#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); +#undef CNVT_TOHW + + v = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + + switch (info->var.bits_per_pixel) { + case 16: + case 24: + case 32: + ((u32 *)info->pseudo_palette)[regno] = v; + break; + } + + return 0; +} + +static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) +{ + struct xenfb_info *info = p->par; + + sys_fillrect(p, rect); + xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height); +} + +static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image) +{ + struct xenfb_info *info = p->par; + + sys_imageblit(p, image); + xenfb_refresh(info, image->dx, image->dy, image->width, image->height); +} + +static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) +{ + struct xenfb_info *info = p->par; + + sys_copyarea(p, area); + xenfb_refresh(info, area->dx, area->dy, area->width, area->height); +} + +static ssize_t xenfb_write(struct fb_info *p, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct xenfb_info *info = p->par; + ssize_t res; + + res = fb_sys_write(p, buf, count, ppos); + xenfb_refresh(info, 0, 0, info->page->width, info->page->height); + return res; +} + +static struct fb_ops xenfb_fb_ops = { + .owner = THIS_MODULE, + .fb_read = fb_sys_read, + .fb_write = xenfb_write, + .fb_setcolreg = xenfb_setcolreg, + .fb_fillrect = xenfb_fillrect, + .fb_copyarea = xenfb_copyarea, + .fb_imageblit = xenfb_imageblit, +}; + +static irqreturn_t xenfb_event_handler(int rq, void *dev_id) +{ + /* + * No in events recognized, simply ignore them all. + * If you need to recognize some, see xen-kbdfront's + * input_handler() for how to do that. + */ + struct xenfb_info *info = dev_id; + struct xenfb_page *page = info->page; + + if (page->in_cons != page->in_prod) { + info->page->in_cons = info->page->in_prod; + notify_remote_via_irq(info->irq); + } + + /* Flush dirty rectangle: */ + xenfb_refresh(info, INT_MAX, INT_MAX, -INT_MAX, -INT_MAX); + + return IRQ_HANDLED; +} + +static int __devinit xenfb_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + struct xenfb_info *info; + struct fb_info *fb_info; + int ret; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); + return -ENOMEM; + } + dev->dev.driver_data = info; + info->xbdev = dev; + info->irq = -1; + info->x1 = info->y1 = INT_MAX; + spin_lock_init(&info->dirty_lock); + + info->fb = vmalloc(xenfb_mem_len); + if (info->fb == NULL) + goto error_nomem; + memset(info->fb, 0, xenfb_mem_len); + + info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT; + + info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages); + if (!info->mfns) + goto error_nomem; + + /* set up shared page */ + info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); + if (!info->page) + goto error_nomem; + + xenfb_init_shared_page(info); + + /* abusing framebuffer_alloc() to allocate pseudo_palette */ + fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL); + if (fb_info == NULL) + goto error_nomem; + + /* complete the abuse: */ + fb_info->pseudo_palette = fb_info->par; + fb_info->par = info; + + fb_info->screen_base = info->fb; + + fb_info->fbops = &xenfb_fb_ops; + fb_info->var.xres_virtual = fb_info->var.xres = info->page->width; + fb_info->var.yres_virtual = fb_info->var.yres = info->page->height; + fb_info->var.bits_per_pixel = info->page->depth; + + fb_info->var.red = (struct fb_bitfield){16, 8, 0}; + fb_info->var.green = (struct fb_bitfield){8, 8, 0}; + fb_info->var.blue = (struct fb_bitfield){0, 8, 0}; + + fb_info->var.activate = FB_ACTIVATE_NOW; + fb_info->var.height = -1; + fb_info->var.width = -1; + fb_info->var.vmode = FB_VMODE_NONINTERLACED; + + fb_info->fix.visual = FB_VISUAL_TRUECOLOR; + fb_info->fix.line_length = info->page->line_length; + fb_info->fix.smem_start = 0; + fb_info->fix.smem_len = xenfb_mem_len; + strcpy(fb_info->fix.id, "xen"); + fb_info->fix.type = FB_TYPE_PACKED_PIXELS; + fb_info->fix.accel = FB_ACCEL_NONE; + + fb_info->flags = FBINFO_FLAG_DEFAULT; + + ret = fb_alloc_cmap(&fb_info->cmap, 256, 0); + if (ret < 0) { + framebuffer_release(fb_info); + xenbus_dev_fatal(dev, ret, "fb_alloc_cmap"); + goto error; + } + + fb_info->fbdefio = &xenfb_defio; + fb_deferred_io_init(fb_info); + + ret = register_framebuffer(fb_info); + if (ret) { + fb_deferred_io_cleanup(fb_info); + fb_dealloc_cmap(&fb_info->cmap); + framebuffer_release(fb_info); + xenbus_dev_fatal(dev, ret, "register_framebuffer"); + goto error; + } + info->fb_info = fb_info; + + ret = xenfb_connect_backend(dev, info); + if (ret < 0) + goto error; + + return 0; + + error_nomem: + ret = -ENOMEM; + xenbus_dev_fatal(dev, ret, "allocating device memory"); + error: + xenfb_remove(dev); + return ret; +} + +static int xenfb_resume(struct xenbus_device *dev) +{ + struct xenfb_info *info = dev->dev.driver_data; + + xenfb_disconnect_backend(info); + xenfb_init_shared_page(info); + return xenfb_connect_backend(dev, info); +} + +static int xenfb_remove(struct xenbus_device *dev) +{ + struct xenfb_info *info = dev->dev.driver_data; + + xenfb_disconnect_backend(info); + if (info->fb_info) { + fb_deferred_io_cleanup(info->fb_info); + unregister_framebuffer(info->fb_info); + fb_dealloc_cmap(&info->fb_info->cmap); + framebuffer_release(info->fb_info); + } + free_page((unsigned long)info->page); + vfree(info->mfns); + vfree(info->fb); + kfree(info); + + return 0; +} + +static unsigned long vmalloc_to_mfn(void *address) +{ + return pfn_to_mfn(vmalloc_to_pfn(address)); +} + +static void xenfb_init_shared_page(struct xenfb_info *info) +{ + int i; + + for (i = 0; i < info->nr_pages; i++) + info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE); + + info->page->pd[0] = vmalloc_to_mfn(info->mfns); + info->page->pd[1] = 0; + info->page->width = XENFB_WIDTH; + info->page->height = XENFB_HEIGHT; + info->page->depth = XENFB_DEPTH; + info->page->line_length = (info->page->depth / 8) * info->page->width; + info->page->mem_length = xenfb_mem_len; + info->page->in_cons = info->page->in_prod = 0; + info->page->out_cons = info->page->out_prod = 0; +} + +static int xenfb_connect_backend(struct xenbus_device *dev, + struct xenfb_info *info) +{ + int ret, evtchn; + struct xenbus_transaction xbt; + + ret = xenbus_alloc_evtchn(dev, &evtchn); + if (ret) + return ret; + ret = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, + 0, dev->devicetype, info); + if (ret < 0) { + xenbus_free_evtchn(dev, evtchn); + xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); + return ret; + } + info->irq = ret; + + again: + ret = xenbus_transaction_start(&xbt); + if (ret) { + xenbus_dev_fatal(dev, ret, "starting transaction"); + return ret; + } + ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", + virt_to_mfn(info->page)); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", + evtchn); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "protocol", "%s", + XEN_IO_PROTO_ABI_NATIVE); + if (ret) + goto error_xenbus; + ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1"); + if (ret) + goto error_xenbus; + ret = xenbus_transaction_end(xbt, 0); + if (ret) { + if (ret == -EAGAIN) + goto again; + xenbus_dev_fatal(dev, ret, "completing transaction"); + return ret; + } + + xenbus_switch_state(dev, XenbusStateInitialised); + return 0; + + error_xenbus: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, ret, "writing xenstore"); + return ret; +} + +static void xenfb_disconnect_backend(struct xenfb_info *info) +{ + if (info->irq >= 0) + unbind_from_irqhandler(info->irq, info); + info->irq = -1; +} + +static void xenfb_backend_changed(struct xenbus_device *dev, + enum xenbus_state backend_state) +{ + struct xenfb_info *info = dev->dev.driver_data; + int val; + + switch (backend_state) { + case XenbusStateInitialising: + case XenbusStateInitialised: + case XenbusStateUnknown: + case XenbusStateClosed: + break; + + case XenbusStateInitWait: +InitWait: + xenbus_switch_state(dev, XenbusStateConnected); + break; + + case XenbusStateConnected: + /* + * Work around xenbus race condition: If backend goes + * through InitWait to Connected fast enough, we can + * get Connected twice here. + */ + if (dev->state != XenbusStateConnected) + goto InitWait; /* no InitWait seen yet, fudge it */ + + if (xenbus_scanf(XBT_NIL, info->xbdev->otherend, + "request-update", "%d", &val) < 0) + val = 0; + if (val) + info->update_wanted = 1; + break; + + case XenbusStateClosing: + xenbus_frontend_closed(dev); + break; + } +} + +static struct xenbus_device_id xenfb_ids[] = { + { "vfb" }, + { "" } +}; + +static struct xenbus_driver xenfb = { + .name = "vfb", + .owner = THIS_MODULE, + .ids = xenfb_ids, + .probe = xenfb_probe, + .remove = xenfb_remove, + .resume = xenfb_resume, + .otherend_changed = xenfb_backend_changed, +}; + +static int __init xenfb_init(void) +{ + if (!is_running_on_xen()) + return -ENODEV; + + /* Nothing to do if running in dom0. */ + if (is_initial_xendomain()) + return -ENODEV; + + return xenbus_register_frontend(&xenfb); +} + +static void __exit xenfb_cleanup(void) +{ + xenbus_unregister_driver(&xenfb); +} + +module_init(xenfb_init); +module_exit(xenfb_cleanup); + +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 1775826ceec51187aa868406585799b7e76ffa7d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 2 Apr 2008 10:54:13 -0700 Subject: xen: add balloon driver The balloon driver allows memory to be dynamically added or removed from the domain, in order to allow host memory to be balanced between multiple domains. This patch introduces the Xen balloon driver, though it currently only allows a domain to be shrunk from its initial size (and re-grown back to that size). A later patch will add the ability to grow a domain beyond its initial size. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- drivers/Kconfig | 2 + drivers/xen/Kconfig | 19 ++ drivers/xen/Makefile | 1 + drivers/xen/balloon.c | 712 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 734 insertions(+) create mode 100644 drivers/xen/Kconfig create mode 100644 drivers/xen/balloon.c (limited to 'drivers') diff --git a/drivers/Kconfig b/drivers/Kconfig index 3a0e3549739f..80f0ec91e2cf 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -97,4 +97,6 @@ source "drivers/dca/Kconfig" source "drivers/auxdisplay/Kconfig" source "drivers/uio/Kconfig" + +source "drivers/xen/Kconfig" endmenu diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig new file mode 100644 index 000000000000..4b75a16de009 --- /dev/null +++ b/drivers/xen/Kconfig @@ -0,0 +1,19 @@ +config XEN_BALLOON + bool "Xen memory balloon driver" + depends on XEN + default y + help + The balloon driver allows the Xen domain to request more memory from + the system to expand the domain's memory allocation, or alternatively + return unneeded memory to the system. + +config XEN_SCRUB_PAGES + bool "Scrub pages before returning them to system" + depends on XEN_BALLOON + default y + help + Scrub pages before returning them to the system for reuse by + other domains. This makes sure that any confidential data + is not accidentally visible to other domains. Is it more + secure, but slightly less efficient. + If in doubt, say yes. diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 43f014cfb458..37af04f1ffd9 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,3 +1,4 @@ obj-y += grant-table.o features.o events.o obj-y += xenbus/ obj-$(CONFIG_XEN_XENCOMM) += xencomm.o +obj-$(CONFIG_XEN_BALLOON) += balloon.o diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c new file mode 100644 index 000000000000..ab25ba6cbbb9 --- /dev/null +++ b/drivers/xen/balloon.c @@ -0,0 +1,712 @@ +/****************************************************************************** + * balloon.c + * + * Xen balloon driver - enables returning/claiming memory to/from Xen. + * + * Copyright (c) 2003, B Dragovic + * Copyright (c) 2003-2004, M Williamson, K Fraser + * Copyright (c) 2005 Dan M. Smith, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) + +#define BALLOON_CLASS_NAME "memory" + +struct balloon_stats { + /* We aim for 'current allocation' == 'target allocation'. */ + unsigned long current_pages; + unsigned long target_pages; + /* We may hit the hard limit in Xen. If we do then we remember it. */ + unsigned long hard_limit; + /* + * Drivers may alter the memory reservation independently, but they + * must inform the balloon driver so we avoid hitting the hard limit. + */ + unsigned long driver_pages; + /* Number of pages in high- and low-memory balloons. */ + unsigned long balloon_low; + unsigned long balloon_high; +}; + +static DEFINE_MUTEX(balloon_mutex); + +static struct sys_device balloon_sysdev; + +static int register_balloon(struct sys_device *sysdev); + +/* + * Protects atomic reservation decrease/increase against concurrent increases. + * Also protects non-atomic updates of current_pages and driver_pages, and + * balloon lists. + */ +static DEFINE_SPINLOCK(balloon_lock); + +static struct balloon_stats balloon_stats; + +/* We increase/decrease in batches which fit in a page */ +static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; + +/* VM /proc information for memory */ +extern unsigned long totalram_pages; + +#ifdef CONFIG_HIGHMEM +extern unsigned long totalhigh_pages; +#define inc_totalhigh_pages() (totalhigh_pages++) +#define dec_totalhigh_pages() (totalhigh_pages--) +#else +#define inc_totalhigh_pages() do {} while(0) +#define dec_totalhigh_pages() do {} while(0) +#endif + +/* List of ballooned pages, threaded through the mem_map array. */ +static LIST_HEAD(ballooned_pages); + +/* Main work function, always executed in process context. */ +static void balloon_process(struct work_struct *work); +static DECLARE_WORK(balloon_worker, balloon_process); +static struct timer_list balloon_timer; + +/* When ballooning out (allocating memory to return to Xen) we don't really + want the kernel to try too hard since that can trigger the oom killer. */ +#define GFP_BALLOON \ + (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC) + +static void scrub_page(struct page *page) +{ +#ifdef CONFIG_XEN_SCRUB_PAGES + if (PageHighMem(page)) { + void *v = kmap(page); + clear_page(v); + kunmap(v); + } else { + void *v = page_address(page); + clear_page(v); + } +#endif +} + +/* balloon_append: add the given page to the balloon. */ +static void balloon_append(struct page *page) +{ + /* Lowmem is re-populated first, so highmem pages go at list tail. */ + if (PageHighMem(page)) { + list_add_tail(&page->lru, &ballooned_pages); + balloon_stats.balloon_high++; + dec_totalhigh_pages(); + } else { + list_add(&page->lru, &ballooned_pages); + balloon_stats.balloon_low++; + } +} + +/* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ +static struct page *balloon_retrieve(void) +{ + struct page *page; + + if (list_empty(&ballooned_pages)) + return NULL; + + page = list_entry(ballooned_pages.next, struct page, lru); + list_del(&page->lru); + + if (PageHighMem(page)) { + balloon_stats.balloon_high--; + inc_totalhigh_pages(); + } + else + balloon_stats.balloon_low--; + + return page; +} + +static struct page *balloon_first_page(void) +{ + if (list_empty(&ballooned_pages)) + return NULL; + return list_entry(ballooned_pages.next, struct page, lru); +} + +static struct page *balloon_next_page(struct page *page) +{ + struct list_head *next = page->lru.next; + if (next == &ballooned_pages) + return NULL; + return list_entry(next, struct page, lru); +} + +static void balloon_alarm(unsigned long unused) +{ + schedule_work(&balloon_worker); +} + +static unsigned long current_target(void) +{ + unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit); + + target = min(target, + balloon_stats.current_pages + + balloon_stats.balloon_low + + balloon_stats.balloon_high); + + return target; +} + +static int increase_reservation(unsigned long nr_pages) +{ + unsigned long pfn, i, flags; + struct page *page; + long rc; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (nr_pages > ARRAY_SIZE(frame_list)) + nr_pages = ARRAY_SIZE(frame_list); + + spin_lock_irqsave(&balloon_lock, flags); + + page = balloon_first_page(); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page == NULL); + frame_list[i] = page_to_pfn(page);; + page = balloon_next_page(page); + } + + reservation.extent_start = (unsigned long)frame_list; + reservation.nr_extents = nr_pages; + rc = HYPERVISOR_memory_op( + XENMEM_populate_physmap, &reservation); + if (rc < nr_pages) { + if (rc > 0) { + int ret; + + /* We hit the Xen hard limit: reprobe. */ + reservation.nr_extents = rc; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != rc); + } + if (rc >= 0) + balloon_stats.hard_limit = (balloon_stats.current_pages + rc - + balloon_stats.driver_pages); + goto out; + } + + for (i = 0; i < nr_pages; i++) { + page = balloon_retrieve(); + BUG_ON(page == NULL); + + pfn = page_to_pfn(page); + BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) && + phys_to_machine_mapping_valid(pfn)); + + set_phys_to_machine(pfn, frame_list[i]); + + /* Link back into the page tables if not highmem. */ + if (pfn < max_low_pfn) { + int ret; + ret = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + mfn_pte(frame_list[i], PAGE_KERNEL), + 0); + BUG_ON(ret); + } + + /* Relinquish the page back to the allocator. */ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); + } + + balloon_stats.current_pages += nr_pages; + totalram_pages = balloon_stats.current_pages; + + out: + spin_unlock_irqrestore(&balloon_lock, flags); + + return 0; +} + +static int decrease_reservation(unsigned long nr_pages) +{ + unsigned long pfn, i, flags; + struct page *page; + int need_sleep = 0; + int ret; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (nr_pages > ARRAY_SIZE(frame_list)) + nr_pages = ARRAY_SIZE(frame_list); + + for (i = 0; i < nr_pages; i++) { + if ((page = alloc_page(GFP_BALLOON)) == NULL) { + nr_pages = i; + need_sleep = 1; + break; + } + + pfn = page_to_pfn(page); + frame_list[i] = pfn_to_mfn(pfn); + + scrub_page(page); + } + + /* Ensure that ballooned highmem pages don't have kmaps. */ + kmap_flush_unused(); + flush_tlb_all(); + + spin_lock_irqsave(&balloon_lock, flags); + + /* No more mappings: invalidate P2M and add to balloon. */ + for (i = 0; i < nr_pages; i++) { + pfn = mfn_to_pfn(frame_list[i]); + set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + balloon_append(pfn_to_page(pfn)); + } + + reservation.extent_start = (unsigned long)frame_list; + reservation.nr_extents = nr_pages; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != nr_pages); + + balloon_stats.current_pages -= nr_pages; + totalram_pages = balloon_stats.current_pages; + + spin_unlock_irqrestore(&balloon_lock, flags); + + return need_sleep; +} + +/* + * We avoid multiple worker processes conflicting via the balloon mutex. + * We may of course race updates of the target counts (which are protected + * by the balloon lock), or with changes to the Xen hard limit, but we will + * recover from these in time. + */ +static void balloon_process(struct work_struct *work) +{ + int need_sleep = 0; + long credit; + + mutex_lock(&balloon_mutex); + + do { + credit = current_target() - balloon_stats.current_pages; + if (credit > 0) + need_sleep = (increase_reservation(credit) != 0); + if (credit < 0) + need_sleep = (decrease_reservation(-credit) != 0); + +#ifndef CONFIG_PREEMPT + if (need_resched()) + schedule(); +#endif + } while ((credit != 0) && !need_sleep); + + /* Schedule more work if there is some still to be done. */ + if (current_target() != balloon_stats.current_pages) + mod_timer(&balloon_timer, jiffies + HZ); + + mutex_unlock(&balloon_mutex); +} + +/* Resets the Xen limit, sets new target, and kicks off processing. */ +void balloon_set_new_target(unsigned long target) +{ + /* No need for lock. Not read-modify-write updates. */ + balloon_stats.hard_limit = ~0UL; + balloon_stats.target_pages = target; + schedule_work(&balloon_worker); +} + +static struct xenbus_watch target_watch = +{ + .node = "memory/target" +}; + +/* React to a change in the target key */ +static void watch_target(struct xenbus_watch *watch, + const char **vec, unsigned int len) +{ + unsigned long long new_target; + int err; + + err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); + if (err != 1) { + /* This is ok (for domain0 at least) - so just return */ + return; + } + + /* The given memory/target value is in KiB, so it needs converting to + * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. + */ + balloon_set_new_target(new_target >> (PAGE_SHIFT - 10)); +} + +static int balloon_init_watcher(struct notifier_block *notifier, + unsigned long event, + void *data) +{ + int err; + + err = register_xenbus_watch(&target_watch); + if (err) + printk(KERN_ERR "Failed to set balloon watcher\n"); + + return NOTIFY_DONE; +} + +static struct notifier_block xenstore_notifier; + +static int __init balloon_init(void) +{ + unsigned long pfn; + struct page *page; + + if (!is_running_on_xen()) + return -ENODEV; + + pr_info("xen_balloon: Initialising balloon driver.\n"); + + balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); + totalram_pages = balloon_stats.current_pages; + balloon_stats.target_pages = balloon_stats.current_pages; + balloon_stats.balloon_low = 0; + balloon_stats.balloon_high = 0; + balloon_stats.driver_pages = 0UL; + balloon_stats.hard_limit = ~0UL; + + init_timer(&balloon_timer); + balloon_timer.data = 0; + balloon_timer.function = balloon_alarm; + + register_balloon(&balloon_sysdev); + + /* Initialise the balloon with excess memory space. */ + for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { + page = pfn_to_page(pfn); + if (!PageReserved(page)) + balloon_append(page); + } + + target_watch.callback = watch_target; + xenstore_notifier.notifier_call = balloon_init_watcher; + + register_xenstore_notifier(&xenstore_notifier); + + return 0; +} + +subsys_initcall(balloon_init); + +static void balloon_exit(void) +{ + /* XXX - release balloon here */ + return; +} + +module_exit(balloon_exit); + +static void balloon_update_driver_allowance(long delta) +{ + unsigned long flags; + + spin_lock_irqsave(&balloon_lock, flags); + balloon_stats.driver_pages += delta; + spin_unlock_irqrestore(&balloon_lock, flags); +} + +static int dealloc_pte_fn( + pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) +{ + unsigned long mfn = pte_mfn(*pte); + int ret; + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + reservation.extent_start = (unsigned long)&mfn; + set_pte_at(&init_mm, addr, pte, __pte_ma(0ull)); + set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != 1); + return 0; +} + +static struct page **alloc_empty_pages_and_pagevec(int nr_pages) +{ + unsigned long vaddr, flags; + struct page *page, **pagevec; + int i, ret; + + pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL); + if (pagevec == NULL) + return NULL; + + for (i = 0; i < nr_pages; i++) { + page = pagevec[i] = alloc_page(GFP_KERNEL); + if (page == NULL) + goto err; + + vaddr = (unsigned long)page_address(page); + + scrub_page(page); + + spin_lock_irqsave(&balloon_lock, flags); + + if (xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned long gmfn = page_to_pfn(page); + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + reservation.extent_start = (unsigned long)&gmfn; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + if (ret == 1) + ret = 0; /* success */ + } else { + ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE, + dealloc_pte_fn, NULL); + } + + if (ret != 0) { + spin_unlock_irqrestore(&balloon_lock, flags); + __free_page(page); + goto err; + } + + totalram_pages = --balloon_stats.current_pages; + + spin_unlock_irqrestore(&balloon_lock, flags); + } + + out: + schedule_work(&balloon_worker); + flush_tlb_all(); + return pagevec; + + err: + spin_lock_irqsave(&balloon_lock, flags); + while (--i >= 0) + balloon_append(pagevec[i]); + spin_unlock_irqrestore(&balloon_lock, flags); + kfree(pagevec); + pagevec = NULL; + goto out; +} + +static void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages) +{ + unsigned long flags; + int i; + + if (pagevec == NULL) + return; + + spin_lock_irqsave(&balloon_lock, flags); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page_count(pagevec[i]) != 1); + balloon_append(pagevec[i]); + } + spin_unlock_irqrestore(&balloon_lock, flags); + + kfree(pagevec); + + schedule_work(&balloon_worker); +} + +static void balloon_release_driver_page(struct page *page) +{ + unsigned long flags; + + spin_lock_irqsave(&balloon_lock, flags); + balloon_append(page); + balloon_stats.driver_pages--; + spin_unlock_irqrestore(&balloon_lock, flags); + + schedule_work(&balloon_worker); +} + + +#define BALLOON_SHOW(name, format, args...) \ + static ssize_t show_##name(struct sys_device *dev, \ + char *buf) \ + { \ + return sprintf(buf, format, ##args); \ + } \ + static SYSDEV_ATTR(name, S_IRUGO, show_##name, NULL) + +BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); +BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); +BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); +BALLOON_SHOW(hard_limit_kb, + (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n", + (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); +BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); + +static ssize_t show_target_kb(struct sys_device *dev, char *buf) +{ + return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages)); +} + +static ssize_t store_target_kb(struct sys_device *dev, + const char *buf, + size_t count) +{ + char memstring[64], *endchar; + unsigned long long target_bytes; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (count <= 1) + return -EBADMSG; /* runt */ + if (count > sizeof(memstring)) + return -EFBIG; /* too long */ + strcpy(memstring, buf); + + target_bytes = memparse(memstring, &endchar); + balloon_set_new_target(target_bytes >> PAGE_SHIFT); + + return count; +} + +static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR, + show_target_kb, store_target_kb); + +static struct sysdev_attribute *balloon_attrs[] = { + &attr_target_kb, +}; + +static struct attribute *balloon_info_attrs[] = { + &attr_current_kb.attr, + &attr_low_kb.attr, + &attr_high_kb.attr, + &attr_hard_limit_kb.attr, + &attr_driver_kb.attr, + NULL +}; + +static struct attribute_group balloon_info_group = { + .name = "info", + .attrs = balloon_info_attrs, +}; + +static struct sysdev_class balloon_sysdev_class = { + .name = BALLOON_CLASS_NAME, +}; + +static int register_balloon(struct sys_device *sysdev) +{ + int i, error; + + error = sysdev_class_register(&balloon_sysdev_class); + if (error) + return error; + + sysdev->id = 0; + sysdev->cls = &balloon_sysdev_class; + + error = sysdev_register(sysdev); + if (error) { + sysdev_class_unregister(&balloon_sysdev_class); + return error; + } + + for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++) { + error = sysdev_create_file(sysdev, balloon_attrs[i]); + if (error) + goto fail; + } + + error = sysfs_create_group(&sysdev->kobj, &balloon_info_group); + if (error) + goto fail; + + return 0; + + fail: + while (--i >= 0) + sysdev_remove_file(sysdev, balloon_attrs[i]); + sysdev_unregister(sysdev); + sysdev_class_unregister(&balloon_sysdev_class); + return error; +} + +static void unregister_balloon(struct sys_device *sysdev) +{ + int i; + + sysfs_remove_group(&sysdev->kobj, &balloon_info_group); + for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++) + sysdev_remove_file(sysdev, balloon_attrs[i]); + sysdev_unregister(sysdev); + sysdev_class_unregister(&balloon_sysdev_class); +} + +static void balloon_sysfs_exit(void) +{ + unregister_balloon(&balloon_sysdev); +} + +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From b3ba31f84ea041c0945b5904d4c407ce14b2b72c Mon Sep 17 00:00:00 2001 From: Mrton Nmeth Date: Sun, 9 Mar 2008 20:47:59 +0000 Subject: leds: Add mail LED support for "Clevo D400P" The leds-clevo-mail module also works with model "Clevo D400P", add this model to the white list. Signed-off-by: Mrton Nmeth Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 4 ++++ drivers/leds/leds-clevo-mail.c | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index eb97c4113d78..4f56248fed4e 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -127,6 +127,7 @@ config LEDS_CLEVO_MAIL This module can drive the mail LED for the following notebooks: + Clevo D400P Clevo D410J Clevo D410V Clevo D400V/D470V (not tested, but might work) @@ -134,6 +135,9 @@ config LEDS_CLEVO_MAIL Clevo M5x0N (not tested, but might work) Positivo Mobile (Clevo M5x0V) + If your model is not listed here you can try the "nodetect" + module paramter. + To compile this driver as a module, choose M here: the module will be called leds-clevo-mail. diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index 5750b08b601f..d78fe6cd5a52 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c @@ -67,6 +67,16 @@ static struct dmi_system_id __initdata mail_led_whitelist[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198") } }, + { + .callback = clevo_mail_led_dmi_callback, + .ident = "Clevo D400P", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Clevo"), + DMI_MATCH(DMI_BOARD_NAME, "D400P"), + DMI_MATCH(DMI_BOARD_VERSION, "Rev.A"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0106") + } + }, { .callback = clevo_mail_led_dmi_callback, .ident = "Clevo D410V", -- cgit v1.2.2 From 0013b23d66a2768f5babbb0ea9f03ab067a990d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20M=C3=A1rton?= Date: Sun, 9 Mar 2008 20:54:37 +0000 Subject: leds: disable triggers on brightness set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable any active triggers when the brightness attribute is set to zero. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Márton Németh Signed-off-by: Richard Purdie --- drivers/leds/led-class.c | 3 +++ drivers/leds/led-triggers.c | 12 +++++++++--- drivers/leds/leds.h | 7 +++++++ drivers/leds/ledtrig-timer.c | 23 +++++++++++++++++++---- 4 files changed, 38 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 63aad90247c4..a8dd59ebedf8 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -51,6 +51,9 @@ static ssize_t led_brightness_store(struct device *dev, if (count == size) { ret = count; + + if (state == LED_OFF) + led_trigger_remove(led_cdev); led_set_brightness(led_cdev, state); } diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 13c9026d68af..21dd96909444 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -45,9 +45,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, trigger_name[len - 1] = '\0'; if (!strcmp(trigger_name, "none")) { - down_write(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, NULL); - up_write(&led_cdev->trigger_lock); + led_trigger_remove(led_cdev); return count; } @@ -139,6 +137,13 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) led_cdev->trigger = trigger; } +void led_trigger_remove(struct led_classdev *led_cdev) +{ + down_write(&led_cdev->trigger_lock); + led_trigger_set(led_cdev, NULL); + up_write(&led_cdev->trigger_lock); +} + void led_trigger_set_default(struct led_classdev *led_cdev) { struct led_trigger *trig; @@ -231,6 +236,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger) /* Used by LED Class */ EXPORT_SYMBOL_GPL(led_trigger_set); +EXPORT_SYMBOL_GPL(led_trigger_remove); EXPORT_SYMBOL_GPL(led_trigger_set_default); EXPORT_SYMBOL_GPL(led_trigger_show); EXPORT_SYMBOL_GPL(led_trigger_store); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 12b6fe93b135..0214799639f7 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -27,6 +27,11 @@ static inline void led_set_brightness(struct led_classdev *led_cdev, led_cdev->brightness_set(led_cdev, value); } +static inline int led_get_brightness(struct led_classdev *led_cdev) +{ + return led_cdev->brightness; +} + extern struct rw_semaphore leds_list_lock; extern struct list_head leds_list; @@ -34,9 +39,11 @@ extern struct list_head leds_list; void led_trigger_set_default(struct led_classdev *led_cdev); void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger); +void led_trigger_remove(struct led_classdev *led_cdev); #else #define led_trigger_set_default(x) do {} while(0) #define led_trigger_set(x, y) do {} while(0) +#define led_trigger_remove(x) do {} while(0) #endif ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 82c55d6e4902..706297765d93 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -25,6 +25,9 @@ #include "leds.h" struct timer_trig_data { + int brightness_on; /* LED brightness during "on" period. + * (LED_OFF < brightness_on <= LED_FULL) + */ unsigned long delay_on; /* milliseconds on */ unsigned long delay_off; /* milliseconds off */ struct timer_list timer; @@ -34,17 +37,26 @@ static void led_timer_function(unsigned long data) { struct led_classdev *led_cdev = (struct led_classdev *) data; struct timer_trig_data *timer_data = led_cdev->trigger_data; - unsigned long brightness = LED_OFF; - unsigned long delay = timer_data->delay_off; + unsigned long brightness; + unsigned long delay; if (!timer_data->delay_on || !timer_data->delay_off) { led_set_brightness(led_cdev, LED_OFF); return; } - if (!led_cdev->brightness) { - brightness = LED_FULL; + brightness = led_get_brightness(led_cdev); + if (!brightness) { + /* Time to switch the LED on. */ + brightness = timer_data->brightness_on; delay = timer_data->delay_on; + } else { + /* Store the current brightness value to be able + * to restore it when the delay_off period is over. + */ + timer_data->brightness_on = brightness; + brightness = LED_OFF; + delay = timer_data->delay_off; } led_set_brightness(led_cdev, brightness); @@ -156,6 +168,9 @@ static void timer_trig_activate(struct led_classdev *led_cdev) if (!timer_data) return; + timer_data->brightness_on = led_get_brightness(led_cdev); + if (timer_data->brightness_on == LED_OFF) + timer_data->brightness_on = LED_FULL; led_cdev->trigger_data = timer_data; init_timer(&timer_data->timer); -- cgit v1.2.2 From 4d404fd5c51772720e9c72aa3185bd5119bc6e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20M=C3=A1rton?= Date: Sun, 9 Mar 2008 20:59:57 +0000 Subject: leds: Cleanup various whitespace and code style issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Break the lines which were more than 80 characters into more lines; replace SPACEs with TABs; correct ident at switch-case; change character encoding from ISO-8859-2 to UTF-8. The order of the functions in led-triggers.c changed in order the similar functions can still be together under titles "Used by LED Class", "LED Trigger Interface" and "Simple LED Tigger Interface" as was grouped before when exported with EXPORT_SYMBOL. Signed-off-by: Márton Németh Signed-off-by: Richard Purdie --- drivers/leds/led-core.c | 4 +- drivers/leds/led-triggers.c | 110 ++++++++++++++++++++-------------------- drivers/leds/leds-clevo-mail.c | 6 +-- drivers/leds/leds-cobalt-qube.c | 2 +- drivers/leds/leds-cobalt-raq.c | 6 +-- drivers/leds/leds-corgi.c | 11 ++-- drivers/leds/leds-h1940.c | 64 +++++++++++------------ drivers/leds/leds-hp6xx.c | 6 ++- drivers/leds/leds-s3c24xx.c | 4 +- drivers/leds/leds-spitz.c | 11 ++-- drivers/leds/leds.h | 6 +-- drivers/leds/ledtrig-ide-disk.c | 2 +- drivers/leds/ledtrig-timer.c | 12 ++--- 13 files changed, 126 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 5d1ca10524b6..016d19f5486f 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -19,7 +19,7 @@ #include "leds.h" DECLARE_RWSEM(leds_list_lock); -LIST_HEAD(leds_list); +EXPORT_SYMBOL_GPL(leds_list_lock); +LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); -EXPORT_SYMBOL_GPL(leds_list_lock); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 21dd96909444..0f242b3f09b6 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -29,6 +29,8 @@ static DECLARE_RWSEM(triggers_list_lock); static LIST_HEAD(trigger_list); + /* Used by LED Class */ + ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -64,7 +66,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, return -EINVAL; } - +EXPORT_SYMBOL_GPL(led_trigger_store); ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -94,24 +96,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, len += sprintf(len+buf, "\n"); return len; } - -void led_trigger_event(struct led_trigger *trigger, - enum led_brightness brightness) -{ - struct list_head *entry; - - if (!trigger) - return; - - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); - led_set_brightness(led_cdev, brightness); - } - read_unlock(&trigger->leddev_list_lock); -} +EXPORT_SYMBOL_GPL(led_trigger_show); /* Caller must ensure led_cdev->trigger_lock held */ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) @@ -122,7 +107,8 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) if (led_cdev->trigger) { write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); + write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, + flags); if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); led_set_brightness(led_cdev, LED_OFF); @@ -136,6 +122,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) } led_cdev->trigger = trigger; } +EXPORT_SYMBOL_GPL(led_trigger_set); void led_trigger_remove(struct led_classdev *led_cdev) { @@ -143,6 +130,7 @@ void led_trigger_remove(struct led_classdev *led_cdev) led_trigger_set(led_cdev, NULL); up_write(&led_cdev->trigger_lock); } +EXPORT_SYMBOL_GPL(led_trigger_remove); void led_trigger_set_default(struct led_classdev *led_cdev) { @@ -160,6 +148,9 @@ void led_trigger_set_default(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); } +EXPORT_SYMBOL_GPL(led_trigger_set_default); + +/* LED Trigger Interface */ int led_trigger_register(struct led_trigger *trigger) { @@ -186,26 +177,7 @@ int led_trigger_register(struct led_trigger *trigger) return 0; } - -void led_trigger_register_simple(const char *name, struct led_trigger **tp) -{ - struct led_trigger *trigger; - int err; - - trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); - - if (trigger) { - trigger->name = name; - err = led_trigger_register(trigger); - if (err < 0) - printk(KERN_WARNING "LED trigger %s failed to register" - " (%d)\n", name, err); - } else - printk(KERN_WARNING "LED trigger %s failed to register" - " (no memory)\n", name); - - *tp = trigger; -} +EXPORT_SYMBOL_GPL(led_trigger_register); void led_trigger_unregister(struct led_trigger *trigger) { @@ -226,29 +198,57 @@ void led_trigger_unregister(struct led_trigger *trigger) } up_read(&leds_list_lock); } +EXPORT_SYMBOL_GPL(led_trigger_unregister); -void led_trigger_unregister_simple(struct led_trigger *trigger) +/* Simple LED Tigger Interface */ + +void led_trigger_event(struct led_trigger *trigger, + enum led_brightness brightness) { - if (trigger) - led_trigger_unregister(trigger); - kfree(trigger); + struct list_head *entry; + + if (!trigger) + return; + + read_lock(&trigger->leddev_list_lock); + list_for_each(entry, &trigger->led_cdevs) { + struct led_classdev *led_cdev; + + led_cdev = list_entry(entry, struct led_classdev, trig_list); + led_set_brightness(led_cdev, brightness); + } + read_unlock(&trigger->leddev_list_lock); } +EXPORT_SYMBOL_GPL(led_trigger_event); -/* Used by LED Class */ -EXPORT_SYMBOL_GPL(led_trigger_set); -EXPORT_SYMBOL_GPL(led_trigger_remove); -EXPORT_SYMBOL_GPL(led_trigger_set_default); -EXPORT_SYMBOL_GPL(led_trigger_show); -EXPORT_SYMBOL_GPL(led_trigger_store); +void led_trigger_register_simple(const char *name, struct led_trigger **tp) +{ + struct led_trigger *trigger; + int err; -/* LED Trigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register); -EXPORT_SYMBOL_GPL(led_trigger_unregister); + trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -/* Simple LED Tigger Interface */ + if (trigger) { + trigger->name = name; + err = led_trigger_register(trigger); + if (err < 0) + printk(KERN_WARNING "LED trigger %s failed to register" + " (%d)\n", name, err); + } else + printk(KERN_WARNING "LED trigger %s failed to register" + " (no memory)\n", name); + + *tp = trigger; +} EXPORT_SYMBOL_GPL(led_trigger_register_simple); + +void led_trigger_unregister_simple(struct led_trigger *trigger) +{ + if (trigger) + led_trigger_unregister(trigger); + kfree(trigger); +} EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); -EXPORT_SYMBOL_GPL(led_trigger_event); MODULE_AUTHOR("Richard Purdie"); MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index d78fe6cd5a52..eb3415e88f43 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c @@ -14,7 +14,7 @@ #define CLEVO_MAIL_LED_BLINK_1HZ 0x008A #define CLEVO_MAIL_LED_BLINK_0_5HZ 0x0083 -MODULE_AUTHOR("Márton Németh "); +MODULE_AUTHOR("Márton Németh "); MODULE_DESCRIPTION("Clevo mail LED driver"); MODULE_LICENSE("GPL"); @@ -103,8 +103,8 @@ static void clevo_mail_led_set(struct led_classdev *led_cdev, } static int clevo_mail_led_blink(struct led_classdev *led_cdev, - unsigned long* delay_on, - unsigned long* delay_off) + unsigned long *delay_on, + unsigned long *delay_off) { int status = -EINVAL; diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index 096881a11b1a..059aa2924b1c 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c @@ -18,7 +18,7 @@ static void __iomem *led_port; static u8 led_value; static void qube_front_led_set(struct led_classdev *led_cdev, - enum led_brightness brightness) + enum led_brightness brightness) { if (brightness) led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT; diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c index 6ebfff341e6c..ff0e8c3fbf9b 100644 --- a/drivers/leds/leds-cobalt-raq.c +++ b/drivers/leds/leds-cobalt-raq.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -33,7 +33,7 @@ static u8 led_value; static DEFINE_SPINLOCK(led_value_lock); static void raq_web_led_set(struct led_classdev *led_cdev, - enum led_brightness brightness) + enum led_brightness brightness) { unsigned long flags; @@ -54,7 +54,7 @@ static struct led_classdev raq_web_led = { }; static void raq_power_off_led_set(struct led_classdev *led_cdev, - enum led_brightness brightness) + enum led_brightness brightness) { unsigned long flags; diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c index 29e931f89f9c..a709704b9f93 100644 --- a/drivers/leds/leds-corgi.c +++ b/drivers/leds/leds-corgi.c @@ -21,7 +21,8 @@ #include #include -static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) +static void corgiled_amber_set(struct led_classdev *led_cdev, + enum led_brightness value) { if (value) GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); @@ -29,7 +30,8 @@ static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightnes GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); } -static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value) +static void corgiled_green_set(struct led_classdev *led_cdev, + enum led_brightness value) { if (value) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); @@ -53,7 +55,8 @@ static struct led_classdev corgi_green_led = { static int corgiled_suspend(struct platform_device *dev, pm_message_t state) { #ifdef CONFIG_LEDS_TRIGGERS - if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) + if (corgi_amber_led.trigger && + strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) #endif led_classdev_suspend(&corgi_amber_led); led_classdev_suspend(&corgi_green_led); @@ -110,7 +113,7 @@ static int __init corgiled_init(void) static void __exit corgiled_exit(void) { - platform_driver_unregister(&corgiled_driver); + platform_driver_unregister(&corgiled_driver); } module_init(corgiled_init); diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c index 6e51c9b61027..bcec42230389 100644 --- a/drivers/leds/leds-h1940.c +++ b/drivers/leds/leds-h1940.c @@ -26,20 +26,20 @@ void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value) { switch (value) { - case LED_HALF: - h1940_latch_control(0,H1940_LATCH_LED_FLASH); - s3c2410_gpio_setpin(S3C2410_GPA7,1); - break; - case LED_FULL: - h1940_latch_control(0,H1940_LATCH_LED_GREEN); - s3c2410_gpio_setpin(S3C2410_GPA7,1); - break; - default: - case LED_OFF: - h1940_latch_control(H1940_LATCH_LED_FLASH,0); - h1940_latch_control(H1940_LATCH_LED_GREEN,0); - s3c2410_gpio_setpin(S3C2410_GPA7,0); - break; + case LED_HALF: + h1940_latch_control(0, H1940_LATCH_LED_FLASH); + s3c2410_gpio_setpin(S3C2410_GPA7, 1); + break; + case LED_FULL: + h1940_latch_control(0, H1940_LATCH_LED_GREEN); + s3c2410_gpio_setpin(S3C2410_GPA7, 1); + break; + default: + case LED_OFF: + h1940_latch_control(H1940_LATCH_LED_FLASH, 0); + h1940_latch_control(H1940_LATCH_LED_GREEN, 0); + s3c2410_gpio_setpin(S3C2410_GPA7, 0); + break; } } @@ -55,20 +55,20 @@ static struct led_classdev h1940_greenled = { void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value) { switch (value) { - case LED_HALF: - h1940_latch_control(0,H1940_LATCH_LED_FLASH); - s3c2410_gpio_setpin(S3C2410_GPA1,1); - break; - case LED_FULL: - h1940_latch_control(0,H1940_LATCH_LED_RED); - s3c2410_gpio_setpin(S3C2410_GPA1,1); - break; - default: - case LED_OFF: - h1940_latch_control(H1940_LATCH_LED_FLASH,0); - h1940_latch_control(H1940_LATCH_LED_RED,0); - s3c2410_gpio_setpin(S3C2410_GPA1,0); - break; + case LED_HALF: + h1940_latch_control(0, H1940_LATCH_LED_FLASH); + s3c2410_gpio_setpin(S3C2410_GPA1, 1); + break; + case LED_FULL: + h1940_latch_control(0, H1940_LATCH_LED_RED); + s3c2410_gpio_setpin(S3C2410_GPA1, 1); + break; + default: + case LED_OFF: + h1940_latch_control(H1940_LATCH_LED_FLASH, 0); + h1940_latch_control(H1940_LATCH_LED_RED, 0); + s3c2410_gpio_setpin(S3C2410_GPA1, 0); + break; } } @@ -86,11 +86,11 @@ void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value) { if (value) { /* flashing Blue */ - h1940_latch_control(0,H1940_LATCH_LED_FLASH); - s3c2410_gpio_setpin(S3C2410_GPA3,1); + h1940_latch_control(0, H1940_LATCH_LED_FLASH); + s3c2410_gpio_setpin(S3C2410_GPA3, 1); } else { - h1940_latch_control(H1940_LATCH_LED_FLASH,0); - s3c2410_gpio_setpin(S3C2410_GPA3,0); + h1940_latch_control(H1940_LATCH_LED_FLASH, 0); + s3c2410_gpio_setpin(S3C2410_GPA3, 0); } } diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index 870f5a3789e8..844d5979c904 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c @@ -17,7 +17,8 @@ #include #include -static void hp6xxled_green_set(struct led_classdev *led_cdev, enum led_brightness value) +static void hp6xxled_green_set(struct led_classdev *led_cdev, + enum led_brightness value) { u8 v8; @@ -28,7 +29,8 @@ static void hp6xxled_green_set(struct led_classdev *led_cdev, enum led_brightnes outb(v8 | PKDR_LED_GREEN, PKDR); } -static void hp6xxled_red_set(struct led_classdev *led_cdev, enum led_brightness value) +static void hp6xxled_red_set(struct led_classdev *led_cdev, + enum led_brightness value) { u16 v16; diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c index 0d10e119d8f5..d4f5021dccbf 100644 --- a/drivers/leds/leds-s3c24xx.c +++ b/drivers/leds/leds-s3c24xx.c @@ -51,7 +51,7 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev, if (pd->flags & S3C24XX_LEDF_TRISTATE) s3c2410_gpio_cfgpin(pd->gpio, - value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); + value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); } @@ -151,7 +151,7 @@ static int __init s3c24xx_led_init(void) static void __exit s3c24xx_led_exit(void) { - platform_driver_unregister(&s3c24xx_led_driver); + platform_driver_unregister(&s3c24xx_led_driver); } module_init(s3c24xx_led_init); diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c index 87007cc362c1..e75e8543bc5a 100644 --- a/drivers/leds/leds-spitz.c +++ b/drivers/leds/leds-spitz.c @@ -21,7 +21,8 @@ #include #include -static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) +static void spitzled_amber_set(struct led_classdev *led_cdev, + enum led_brightness value) { if (value) set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); @@ -29,7 +30,8 @@ static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightnes reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); } -static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value) +static void spitzled_green_set(struct led_classdev *led_cdev, + enum led_brightness value) { if (value) set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); @@ -53,7 +55,8 @@ static struct led_classdev spitz_green_led = { static int spitzled_suspend(struct platform_device *dev, pm_message_t state) { #ifdef CONFIG_LEDS_TRIGGERS - if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge")) + if (spitz_amber_led.trigger && + strcmp(spitz_amber_led.trigger->name, "sharpsl-charge")) #endif led_classdev_suspend(&spitz_amber_led); led_classdev_suspend(&spitz_green_led); @@ -116,7 +119,7 @@ static int __init spitzled_init(void) static void __exit spitzled_exit(void) { - platform_driver_unregister(&spitzled_driver); + platform_driver_unregister(&spitzled_driver); } module_init(spitzled_init); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 0214799639f7..5edbf52c4fa7 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -41,9 +41,9 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger); void led_trigger_remove(struct led_classdev *led_cdev); #else -#define led_trigger_set_default(x) do {} while(0) -#define led_trigger_set(x, y) do {} while(0) -#define led_trigger_remove(x) do {} while(0) +#define led_trigger_set_default(x) do {} while (0) +#define led_trigger_set(x, y) do {} while (0) +#define led_trigger_remove(x) do {} while (0) #endif ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c index 54b155c7026f..883a577b1b97 100644 --- a/drivers/leds/ledtrig-ide-disk.c +++ b/drivers/leds/ledtrig-ide-disk.c @@ -38,7 +38,7 @@ static void ledtrig_ide_timerfunc(unsigned long data) if (ide_lastactivity != ide_activity) { ide_lastactivity = ide_activity; led_trigger_event(ledtrig_ide, LED_FULL); - mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); + mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); } else { led_trigger_event(ledtrig_ide, LED_OFF); } diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 706297765d93..5c99f4f0c692 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -64,7 +64,7 @@ static void led_timer_function(unsigned long data) mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); } -static ssize_t led_delay_on_show(struct device *dev, +static ssize_t led_delay_on_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -75,7 +75,7 @@ static ssize_t led_delay_on_show(struct device *dev, return strlen(buf) + 1; } -static ssize_t led_delay_on_store(struct device *dev, +static ssize_t led_delay_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -99,7 +99,7 @@ static ssize_t led_delay_on_store(struct device *dev, /* try to activate hardware acceleration, if any */ if (!led_cdev->blink_set || led_cdev->blink_set(led_cdev, - &timer_data->delay_on, &timer_data->delay_off)) { + &timer_data->delay_on, &timer_data->delay_off)) { /* no hardware acceleration, blink via timer */ mod_timer(&timer_data->timer, jiffies + 1); } @@ -110,7 +110,7 @@ static ssize_t led_delay_on_store(struct device *dev, return ret; } -static ssize_t led_delay_off_show(struct device *dev, +static ssize_t led_delay_off_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -121,7 +121,7 @@ static ssize_t led_delay_off_show(struct device *dev, return strlen(buf) + 1; } -static ssize_t led_delay_off_store(struct device *dev, +static ssize_t led_delay_off_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -145,7 +145,7 @@ static ssize_t led_delay_off_store(struct device *dev, /* try to activate hardware acceleration, if any */ if (!led_cdev->blink_set || led_cdev->blink_set(led_cdev, - &timer_data->delay_on, &timer_data->delay_off)) { + &timer_data->delay_on, &timer_data->delay_off)) { /* no hardware acceleration, blink via timer */ mod_timer(&timer_data->timer, jiffies + 1); } -- cgit v1.2.2 From ca3259b3603539e72faacc6821050ee889a52103 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sun, 9 Mar 2008 23:48:25 +0000 Subject: leds: enable support for blink_set() platform hook in leds-gpio Enhance leds-gpio to provide hardware-based led flashing by passing through the blink_set() call to a optionally set platform-specific function pointer. Signed-off-by: Herbert Valerio Riedel Signed-off-by: Richard Purdie --- drivers/leds/leds-gpio.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 1aae8b332134..b13bd2950e95 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -24,6 +24,8 @@ struct gpio_led_data { u8 new_level; u8 can_sleep; u8 active_low; + int (*platform_gpio_blink_set)(unsigned gpio, + unsigned long *delay_on, unsigned long *delay_off); }; static void gpio_led_work(struct work_struct *work) @@ -60,6 +62,15 @@ static void gpio_led_set(struct led_classdev *led_cdev, gpio_set_value(led_dat->gpio, level); } +static int gpio_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, unsigned long *delay_off) +{ + struct gpio_led_data *led_dat = + container_of(led_cdev, struct gpio_led_data, cdev); + + return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off); +} + static int gpio_led_probe(struct platform_device *pdev) { struct gpio_led_platform_data *pdata = pdev->dev.platform_data; @@ -88,6 +99,10 @@ static int gpio_led_probe(struct platform_device *pdev) led_dat->gpio = cur_led->gpio; led_dat->can_sleep = gpio_cansleep(cur_led->gpio); led_dat->active_low = cur_led->active_low; + if (pdata->gpio_blink_set) { + led_dat->platform_gpio_blink_set = pdata->gpio_blink_set; + led_dat->cdev.blink_set = gpio_blink_set; + } led_dat->cdev.brightness_set = gpio_led_set; led_dat->cdev.brightness = LED_OFF; -- cgit v1.2.2 From 29d76dfa29fe22583aefddccda0bc56aa81035dc Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Tue, 18 Mar 2008 09:47:48 +0000 Subject: leds: Add support to leds with readable status Some led hardware allows drivers to query the led state, and this patch adds a hook to let the led class take advantage of that information when available. Without this functionality, when access to the led hardware is not exclusive (i.e. firmware or hardware might change its state behind the kernel's back), reality goes out of sync with the led class' idea of what the led is doing, which is annoying at best. Behaviour for drivers that do not or cannot read the led status is unchanged. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Richard Purdie --- drivers/leds/led-class.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index a8dd59ebedf8..ac05a928f764 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -24,6 +24,12 @@ static struct class *leds_class; +static void led_update_brightness(struct led_classdev *led_cdev) +{ + if (led_cdev->brightness_get) + led_cdev->brightness = led_cdev->brightness_get(led_cdev); +} + static ssize_t led_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -31,6 +37,7 @@ static ssize_t led_brightness_show(struct device *dev, ssize_t ret = 0; /* no lock needed for this */ + led_update_brightness(led_cdev); sprintf(buf, "%u\n", led_cdev->brightness); ret = strlen(buf) + 1; @@ -113,6 +120,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) list_add_tail(&led_cdev->node, &leds_list); up_write(&leds_list_lock); + led_update_brightness(led_cdev); + #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); -- cgit v1.2.2 From 3b2e46f8c4a5f2d7856c490ab5f0c46b65e2cb99 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Thu, 24 Apr 2008 23:43:09 +0100 Subject: leds: Add new driver for the LEDs on the Freecom FSG-3 The LEDs on the Freecom FSG-3 are connected to an external memory-mapped latch on the ixp4xx expansion bus, and therefore cannot be supported by any of the existing LEDs drivers. Signed-off-by: Rod Whitby Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 6 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-fsg.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+) create mode 100644 drivers/leds/leds-fsg.c (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 4f56248fed4e..2d5ea8a05338 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -65,6 +65,12 @@ config LEDS_NET48XX This option enables support for the Soekris net4801 and net4826 error LED. +config LEDS_FSG + tristate "LED Support for the Freecom FSG-3" + depends on LEDS_CLASS && MACH_FSG + help + This option enables support for the LEDs on the Freecom FSG-3. + config LEDS_WRAP tristate "LED Support for the WRAP series LEDs" depends on LEDS_CLASS && SCx200_GPIO diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e54f42da21a2..9adfa2fe37d4 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o +obj-$(CONFIG_LEDS_FSG) += leds-fsg.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c new file mode 100644 index 000000000000..a7421b8c47d8 --- /dev/null +++ b/drivers/leds/leds-fsg.c @@ -0,0 +1,261 @@ +/* + * LED Driver for the Freecom FSG-3 + * + * Copyright (c) 2008 Rod Whitby + * + * Author: Rod Whitby + * + * Based on leds-spitz.c + * Copyright 2005-2006 Openedhand Ltd. + * Author: Richard Purdie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include + +static short __iomem *latch_address; +static unsigned short latch_value; + + +static void fsg_led_wlan_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_WLAN_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_WLAN_BIT); + *latch_address = latch_value; + } +} + +static void fsg_led_wan_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_WAN_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_WAN_BIT); + *latch_address = latch_value; + } +} + +static void fsg_led_sata_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_SATA_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_SATA_BIT); + *latch_address = latch_value; + } +} + +static void fsg_led_usb_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_USB_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_USB_BIT); + *latch_address = latch_value; + } +} + +static void fsg_led_sync_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_SYNC_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_SYNC_BIT); + *latch_address = latch_value; + } +} + +static void fsg_led_ring_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value) { + latch_value &= ~(1 << FSG_LED_RING_BIT); + *latch_address = latch_value; + } else { + latch_value |= (1 << FSG_LED_RING_BIT); + *latch_address = latch_value; + } +} + + + +static struct led_classdev fsg_wlan_led = { + .name = "fsg:blue:wlan", + .brightness_set = fsg_led_wlan_set, +}; + +static struct led_classdev fsg_wan_led = { + .name = "fsg:blue:wan", + .brightness_set = fsg_led_wan_set, +}; + +static struct led_classdev fsg_sata_led = { + .name = "fsg:blue:sata", + .brightness_set = fsg_led_sata_set, +}; + +static struct led_classdev fsg_usb_led = { + .name = "fsg:blue:usb", + .brightness_set = fsg_led_usb_set, +}; + +static struct led_classdev fsg_sync_led = { + .name = "fsg:blue:sync", + .brightness_set = fsg_led_sync_set, +}; + +static struct led_classdev fsg_ring_led = { + .name = "fsg:blue:ring", + .brightness_set = fsg_led_ring_set, +}; + + + +#ifdef CONFIG_PM +static int fsg_led_suspend(struct platform_device *dev, pm_message_t state) +{ + led_classdev_suspend(&fsg_wlan_led); + led_classdev_suspend(&fsg_wan_led); + led_classdev_suspend(&fsg_sata_led); + led_classdev_suspend(&fsg_usb_led); + led_classdev_suspend(&fsg_sync_led); + led_classdev_suspend(&fsg_ring_led); + return 0; +} + +static int fsg_led_resume(struct platform_device *dev) +{ + led_classdev_resume(&fsg_wlan_led); + led_classdev_resume(&fsg_wan_led); + led_classdev_resume(&fsg_sata_led); + led_classdev_resume(&fsg_usb_led); + led_classdev_resume(&fsg_sync_led); + led_classdev_resume(&fsg_ring_led); + return 0; +} +#endif + + +static int fsg_led_probe(struct platform_device *pdev) +{ + int ret; + + ret = led_classdev_register(&pdev->dev, &fsg_wlan_led); + if (ret < 0) + goto failwlan; + + ret = led_classdev_register(&pdev->dev, &fsg_wan_led); + if (ret < 0) + goto failwan; + + ret = led_classdev_register(&pdev->dev, &fsg_sata_led); + if (ret < 0) + goto failsata; + + ret = led_classdev_register(&pdev->dev, &fsg_usb_led); + if (ret < 0) + goto failusb; + + ret = led_classdev_register(&pdev->dev, &fsg_sync_led); + if (ret < 0) + goto failsync; + + ret = led_classdev_register(&pdev->dev, &fsg_ring_led); + if (ret < 0) + goto failring; + + /* Map the LED chip select address space */ + latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512); + if (!latch_address) { + ret = -ENOMEM; + goto failremap; + } + + latch_value = 0xffff; + *latch_address = latch_value; + + return ret; + + failremap: + led_classdev_unregister(&fsg_ring_led); + failring: + led_classdev_unregister(&fsg_sync_led); + failsync: + led_classdev_unregister(&fsg_usb_led); + failusb: + led_classdev_unregister(&fsg_sata_led); + failsata: + led_classdev_unregister(&fsg_wan_led); + failwan: + led_classdev_unregister(&fsg_wlan_led); + failwlan: + + return ret; +} + +static int fsg_led_remove(struct platform_device *pdev) +{ + iounmap(latch_address); + + led_classdev_unregister(&fsg_wlan_led); + led_classdev_unregister(&fsg_wan_led); + led_classdev_unregister(&fsg_sata_led); + led_classdev_unregister(&fsg_usb_led); + led_classdev_unregister(&fsg_sync_led); + led_classdev_unregister(&fsg_ring_led); + + return 0; +} + + +static struct platform_driver fsg_led_driver = { + .probe = fsg_led_probe, + .remove = fsg_led_remove, +#ifdef CONFIG_PM + .suspend = fsg_led_suspend, + .resume = fsg_led_resume, +#endif + .driver = { + .name = "fsg-led", + }, +}; + + +static int __init fsg_led_init(void) +{ + return platform_driver_register(&fsg_led_driver); +} + +static void __exit fsg_led_exit(void) +{ + platform_driver_unregister(&fsg_led_driver); +} + + +module_init(fsg_led_init); +module_exit(fsg_led_exit); + +MODULE_AUTHOR("Rod Whitby "); +MODULE_DESCRIPTION("Freecom FSG-3 LED driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 060856c799191ffc360105cac49f3f9e68d526b7 Mon Sep 17 00:00:00 2001 From: Nick Forbes Date: Fri, 25 Apr 2008 00:06:52 +0100 Subject: leds: Add default-on trigger Add a trigger which allows LEDs to default to the full brightness state. Signed-off-by: Nick Forbes Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 7 ++++++ drivers/leds/Makefile | 1 + drivers/leds/ledtrig-default-on.c | 45 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 drivers/leds/ledtrig-default-on.c (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 2d5ea8a05338..86a369bc57d6 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -183,4 +183,11 @@ config LEDS_TRIGGER_HEARTBEAT load average. If unsure, say Y. +config LEDS_TRIGGER_DEFAULT_ON + tristate "LED Default ON Trigger" + depends on LEDS_TRIGGERS + help + This allows LEDs to be initialised in the ON state. + If unsure, say Y. + endif # NEW_LEDS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 9adfa2fe37d4..973d626f5f4a 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -26,3 +26,4 @@ obj-$(CONFIG_LEDS_FSG) += leds-fsg.o obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o +obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c new file mode 100644 index 000000000000..92995e40cfa4 --- /dev/null +++ b/drivers/leds/ledtrig-default-on.c @@ -0,0 +1,45 @@ +/* + * LED Kernel Default ON Trigger + * + * Copyright 2008 Nick Forbes + * + * Based on Richard Purdie's ledtrig-timer.c. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include "leds.h" + +static void defon_trig_activate(struct led_classdev *led_cdev) +{ + led_set_brightness(led_cdev, LED_FULL); +} + +static struct led_trigger defon_led_trigger = { + .name = "default-on", + .activate = defon_trig_activate, +}; + +static int __init defon_trig_init(void) +{ + return led_trigger_register(&defon_led_trigger); +} + +static void __exit defon_trig_exit(void) +{ + led_trigger_unregister(&defon_led_trigger); +} + +module_init(defon_trig_init); +module_exit(defon_trig_exit); + +MODULE_AUTHOR("Nick Forbes "); +MODULE_DESCRIPTION("Default-ON LED trigger"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From b345dc7da026016b65162b1ca7cfcd2c7212a285 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 24 Apr 2008 23:34:05 -0400 Subject: Input: wacom - add support for Cintiq 20WSX Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index ffe33842143f..192513e1f04c 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -649,6 +649,7 @@ static struct wacom_features wacom_features[] = { { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, + { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, { } @@ -702,6 +703,7 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, { } -- cgit v1.2.2 From 2b4221bb545899b05872e7b51f55567c10b3894b Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 24 Apr 2008 18:37:34 -0700 Subject: libata: functions with definition should not be extern Noticed by sparse drivers/ata/libata-core.c:3380:12: warning: function 'ata_wait_after_reset' with external linkage has definition Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- 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 b0b00af90d0e..fe5c88ba977e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3377,7 +3377,7 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline, * RETURNS: * 0 if @linke is ready before @deadline; otherwise, -errno. */ -extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, +int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)) { msleep(ATA_WAIT_AFTER_RESET_MSECS); -- cgit v1.2.2 From 8e5443a09851d99084098ecc4066805aa2610d92 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 24 Apr 2008 10:52:44 +0900 Subject: sata_sis: SCR accessors return -EINVAL when requested SCR isn't available sis_scr_cfg_read() can't access SError and was incorrectly returning -1 instead of -EINVAL. This went unnoticed because SError used to be cleared in @postreset() and it didn't care about how scr_read() failed but commit ac371987 moved SError clearing into sata_link_resume() and SCR access failure other than -EINVAL is considered an error condition and exposes the incorrect return value bug as detection failure. Fix it. Also, scsi_scr_cfg_write() was incorrectly returning 0 after it ignored the request to write to SError. Make it also return -EINVAL. This was bisected and reported by Patrick McHardy. Signed-off-by: Tejun Heo Cc: Patrick McHardy Signed-off-by: Jeff Garzik --- drivers/ata/sata_sis.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 6b8e45ba32e8..1010b3069bd5 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -142,7 +142,7 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) u8 pmr; if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ - return 0xffffffff; + return -EINVAL; pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -158,14 +158,14 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) return 0; } -static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); u8 pmr; if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ - return; + return -EINVAL; pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -174,6 +174,8 @@ static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) pci_write_config_dword(pdev, cfg_addr+0x10, val); + + return 0; } static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) @@ -211,14 +213,14 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) pci_read_config_byte(pdev, SIS_PMR, &pmr); if (ap->flags & SIS_FLAG_CFGSCR) - sis_scr_cfg_write(ap, sc_reg, val); + return sis_scr_cfg_write(ap, sc_reg, val); else { iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); + return 0; } - return 0; } static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.2 From 7f7c4072ea552f97a0898331322f71986a97299c Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Thu, 24 Apr 2008 21:02:37 -0700 Subject: niu: Determine the # of ports from the card's VPD data [ Fix minor whitespace and coding style stuff... -DaveM ] Signed-off-by: Matheos Worku Signed-off-by: David S. Miller --- drivers/net/niu.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------- drivers/net/niu.h | 9 ++++++++ 2 files changed, 65 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 7565c2d7f30e..c7c173c3f808 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -6773,6 +6773,37 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, return 0; } +/* niu board models have a trailing dash version incremented + * with HW rev change. Need to ingnore the dash version while + * checking for match + * + * for example, for the 10G card the current vpd.board_model + * is 501-5283-04, of which -04 is the dash version and have + * to be ignored + */ +static int niu_board_model_match(struct niu *np, const char *model) +{ + return !strncmp(np->vpd.board_model, model, strlen(model)); +} + +static int niu_pci_vpd_get_nports(struct niu *np) +{ + int ports = 0; + + if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) || + (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) || + (niu_board_model_match(np, NIU_ALONSO_BM_STR))) { + ports = 4; + } else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) || + (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) || + (niu_board_model_match(np, NIU_FOXXY_BM_STR)) || + (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) { + ports = 2; + } + + return ports; +} + static void __devinit niu_pci_vpd_validate(struct niu *np) { struct net_device *dev = np->dev; @@ -6987,11 +7018,17 @@ static int __devinit niu_get_and_validate_port(struct niu *np) if (parent->plat_type == PLAT_TYPE_NIU) { parent->num_ports = 2; } else { - parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & - ESPC_NUM_PORTS_MACS_VAL; - - if (!parent->num_ports) - parent->num_ports = 4; + parent->num_ports = niu_pci_vpd_get_nports(np); + if (!parent->num_ports) { + /* Fall back to SPROM as last resort. + * This will fail on most cards. + */ + parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & + ESPC_NUM_PORTS_MACS_VAL; + + if (!parent->num_ports) + return -ENODEV; + } } } @@ -7733,15 +7770,16 @@ static int __devinit niu_get_invariants(struct niu *np) have_props = !err; - err = niu_get_and_validate_port(np); - if (err) - return err; - err = niu_init_mac_ipp_pcs_base(np); if (err) return err; - if (!have_props) { + if (have_props) { + err = niu_get_and_validate_port(np); + if (err) + return err; + + } else { if (np->parent->plat_type == PLAT_TYPE_NIU) return -EINVAL; @@ -7753,10 +7791,17 @@ static int __devinit niu_get_invariants(struct niu *np) niu_pci_vpd_fetch(np, offset); nw64(ESPC_PIO_EN, 0); - if (np->flags & NIU_FLAGS_VPD_VALID) + if (np->flags & NIU_FLAGS_VPD_VALID) { niu_pci_vpd_validate(np); + err = niu_get_and_validate_port(np); + if (err) + return err; + } if (!(np->flags & NIU_FLAGS_VPD_VALID)) { + err = niu_get_and_validate_port(np); + if (err) + return err; err = niu_pci_probe_sprom(np); if (err) return err; diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 336aed08b275..35e9afb23bdf 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -2937,6 +2937,15 @@ struct rx_ring_info { #define NIU_MAX_MTU 9216 +/* VPD strings */ +#define NIU_QGC_LP_BM_STR "501-7606" +#define NIU_2XGF_LP_BM_STR "501-7283" +#define NIU_QGC_PEM_BM_STR "501-7765" +#define NIU_2XGF_PEM_BM_STR "501-7626" +#define NIU_ALONSO_BM_STR "373-0202" +#define NIU_FOXXY_BM_STR "501-7961" +#define NIU_2XGF_MRVL_BM_STR "SK-6E82" + #define NIU_VPD_MIN_MAJOR 3 #define NIU_VPD_MIN_MINOR 4 -- cgit v1.2.2 From a5d6ab56daa439d681aab29955498486e452224d Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Thu, 24 Apr 2008 21:09:20 -0700 Subject: niu: Add support for Neptune FEM/NEM cards for C10 server blades [ Minor coding style and whitespace corrections, also bump driver version and release date. -DaveM ] Signed-off-by: Matheos Worku Signed-off-by: David S. Miller --- drivers/net/niu.c | 304 ++++++++++++++++++++++++++++++++++++++++++++++++------ drivers/net/niu.h | 3 + 2 files changed, 277 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index c7c173c3f808..4009c4ce96b4 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.7" -#define DRV_MODULE_RELDATE "February 18, 2008" +#define DRV_MODULE_VERSION "0.8" +#define DRV_MODULE_RELDATE "April 24, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -673,11 +673,16 @@ static int serdes_init_10g(struct niu *np) } if ((sig & mask) != val) { + if (np->flags & NIU_FLAGS_HOTPLUG_PHY) { + np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; + return 0; + } dev_err(np->device, PFX "Port %u signal bits [%08x] are not " "[%08x]\n", np->port, (int) (sig & mask), (int) val); return -ENODEV; } - + if (np->flags & NIU_FLAGS_HOTPLUG_PHY) + np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT; return 0; } @@ -998,6 +1003,28 @@ static int bcm8704_user_dev3_readback(struct niu *np, int reg) return 0; } +static int bcm8706_init_user_dev3(struct niu *np) +{ + int err; + + + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_OPT_DIGITAL_CTRL); + if (err < 0) + return err; + err &= ~USER_ODIG_CTRL_GPIOS; + err |= (0x3 << USER_ODIG_CTRL_GPIOS_SHIFT); + err |= USER_ODIG_CTRL_RESV2; + err = mdio_write(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_OPT_DIGITAL_CTRL, err); + if (err) + return err; + + mdelay(1000); + + return 0; +} + static int bcm8704_init_user_dev3(struct niu *np) { int err; @@ -1127,33 +1154,11 @@ static int xcvr_init_10g_mrvl88x2011(struct niu *np) MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX); } -static int xcvr_init_10g_bcm8704(struct niu *np) + +static int xcvr_diag_bcm870x(struct niu *np) { - struct niu_link_config *lp = &np->link_config; u16 analog_stat0, tx_alarm_status; - int err; - - err = bcm8704_reset(np); - if (err) - return err; - - err = bcm8704_init_user_dev3(np); - if (err) - return err; - - err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, - MII_BMCR); - if (err < 0) - return err; - err &= ~BMCR_LOOPBACK; - - if (lp->loopback_mode == LOOPBACK_MAC) - err |= BMCR_LOOPBACK; - - err = mdio_write(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, - MII_BMCR, err); - if (err) - return err; + int err = 0; #if 1 err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, @@ -1211,6 +1216,89 @@ static int xcvr_init_10g_bcm8704(struct niu *np) return 0; } +static int xcvr_10g_set_lb_bcm870x(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + int err; + + err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + MII_BMCR); + if (err < 0) + return err; + + err &= ~BMCR_LOOPBACK; + + if (lp->loopback_mode == LOOPBACK_MAC) + err |= BMCR_LOOPBACK; + + err = mdio_write(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + MII_BMCR, err); + if (err) + return err; + + return 0; +} + +static int xcvr_init_10g_bcm8706(struct niu *np) +{ + int err = 0; + u64 val; + + if ((np->flags & NIU_FLAGS_HOTPLUG_PHY) && + (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) == 0) + return err; + + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_LED_POLARITY; + val |= XMAC_CONFIG_FORCE_LED_ON; + nw64_mac(XMAC_CONFIG, val); + + val = nr64(MIF_CONFIG); + val |= MIF_CONFIG_INDIRECT_MODE; + nw64(MIF_CONFIG, val); + + err = bcm8704_reset(np); + if (err) + return err; + + err = xcvr_10g_set_lb_bcm870x(np); + if (err) + return err; + + err = bcm8706_init_user_dev3(np); + if (err) + return err; + + err = xcvr_diag_bcm870x(np); + if (err) + return err; + + return 0; +} + +static int xcvr_init_10g_bcm8704(struct niu *np) +{ + int err; + + err = bcm8704_reset(np); + if (err) + return err; + + err = bcm8704_init_user_dev3(np); + if (err) + return err; + + err = xcvr_10g_set_lb_bcm870x(np); + if (err) + return err; + + err = xcvr_diag_bcm870x(np); + if (err) + return err; + + return 0; +} + static int xcvr_init_10g(struct niu *np) { int phy_id, err; @@ -1548,6 +1636,59 @@ out: return err; } +static int link_status_10g_bcm8706(struct niu *np, int *link_up_p) +{ + int err, link_up; + link_up = 0; + + err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, + BCM8704_PMD_RCV_SIGDET); + if (err < 0) + goto out; + if (!(err & PMD_RCV_SIGDET_GLOBAL)) { + err = 0; + goto out; + } + + err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + BCM8704_PCS_10G_R_STATUS); + if (err < 0) + goto out; + + if (!(err & PCS_10G_R_STATUS_BLK_LOCK)) { + err = 0; + goto out; + } + + err = mdio_read(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR, + BCM8704_PHYXS_XGXS_LANE_STAT); + if (err < 0) + goto out; + if (err != (PHYXS_XGXS_LANE_STAT_ALINGED | + PHYXS_XGXS_LANE_STAT_MAGIC | + PHYXS_XGXS_LANE_STAT_PATTEST | + PHYXS_XGXS_LANE_STAT_LANE3 | + PHYXS_XGXS_LANE_STAT_LANE2 | + PHYXS_XGXS_LANE_STAT_LANE1 | + PHYXS_XGXS_LANE_STAT_LANE0)) { + err = 0; + np->link_config.active_speed = SPEED_INVALID; + np->link_config.active_duplex = DUPLEX_INVALID; + goto out; + } + + link_up = 1; + np->link_config.active_speed = SPEED_10000; + np->link_config.active_duplex = DUPLEX_FULL; + err = 0; + +out: + *link_up_p = link_up; + if (np->flags & NIU_FLAGS_HOTPLUG_PHY) + err = 0; + return err; +} + static int link_status_10g_bcom(struct niu *np, int *link_up_p) { int err, link_up; @@ -1627,6 +1768,82 @@ static int link_status_10g(struct niu *np, int *link_up_p) return err; } +static int niu_10g_phy_present(struct niu *np) +{ + u64 sig, mask, val; + + sig = nr64(ESR_INT_SIGNALS); + switch (np->port) { + case 0: + mask = ESR_INT_SIGNALS_P0_BITS; + val = (ESR_INT_SRDY0_P0 | + ESR_INT_DET0_P0 | + ESR_INT_XSRDY_P0 | + ESR_INT_XDP_P0_CH3 | + ESR_INT_XDP_P0_CH2 | + ESR_INT_XDP_P0_CH1 | + ESR_INT_XDP_P0_CH0); + break; + + case 1: + mask = ESR_INT_SIGNALS_P1_BITS; + val = (ESR_INT_SRDY0_P1 | + ESR_INT_DET0_P1 | + ESR_INT_XSRDY_P1 | + ESR_INT_XDP_P1_CH3 | + ESR_INT_XDP_P1_CH2 | + ESR_INT_XDP_P1_CH1 | + ESR_INT_XDP_P1_CH0); + break; + + default: + return 0; + } + + if ((sig & mask) != val) + return 0; + return 1; +} + +static int link_status_10g_hotplug(struct niu *np, int *link_up_p) +{ + unsigned long flags; + int err = 0; + int phy_present; + int phy_present_prev; + + spin_lock_irqsave(&np->lock, flags); + + if (np->link_config.loopback_mode == LOOPBACK_DISABLED) { + phy_present_prev = (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) ? + 1 : 0; + phy_present = niu_10g_phy_present(np); + if (phy_present != phy_present_prev) { + /* state change */ + if (phy_present) { + np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT; + if (np->phy_ops->xcvr_init) + err = np->phy_ops->xcvr_init(np); + if (err) { + /* debounce */ + np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; + } + } else { + np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; + *link_up_p = 0; + niuwarn(LINK, "%s: Hotplug PHY Removed\n", + np->dev->name); + } + } + if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) + err = link_status_10g_bcm8706(np, link_up_p); + } + + spin_unlock_irqrestore(&np->lock, flags); + + return err; +} + static int link_status_1g(struct niu *np, int *link_up_p) { struct niu_link_config *lp = &np->link_config; @@ -1761,6 +1978,12 @@ static const struct niu_phy_ops phy_ops_10g_fiber = { .link_status = link_status_10g, }; +static const struct niu_phy_ops phy_ops_10g_fiber_hotplug = { + .serdes_init = serdes_init_10g, + .xcvr_init = xcvr_init_10g_bcm8706, + .link_status = link_status_10g_hotplug, +}; + static const struct niu_phy_ops phy_ops_10g_copper = { .serdes_init = serdes_init_10g, .link_status = link_status_10g, /* XXX */ @@ -1792,6 +2015,11 @@ static const struct niu_phy_template phy_template_10g_fiber = { .phy_addr_base = 8, }; +static const struct niu_phy_template phy_template_10g_fiber_hotplug = { + .ops = &phy_ops_10g_fiber_hotplug, + .phy_addr_base = 8, +}; + static const struct niu_phy_template phy_template_10g_copper = { .ops = &phy_ops_10g_copper, .phy_addr_base = 10, @@ -1996,6 +2224,13 @@ static int niu_determine_phy_disposition(struct niu *np) plat_type == PLAT_TYPE_VF_P1) phy_addr_off = 8; phy_addr_off += np->port; + if (np->flags & NIU_FLAGS_HOTPLUG_PHY) { + tp = &phy_template_10g_fiber_hotplug; + if (np->port == 0) + phy_addr_off = 8; + if (np->port == 1) + phy_addr_off = 12; + } break; case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: @@ -6830,6 +7065,9 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) } if (np->flags & NIU_FLAGS_10G) np->mac_xcvr = MAC_XCVR_XPCS; + } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { + np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER | + NIU_FLAGS_HOTPLUG_PHY); } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { dev_err(np->device, PFX "Illegal phy string [%s].\n", np->vpd.phy_type); @@ -7052,7 +7290,8 @@ static int __devinit phy_record(struct niu_parent *parent, return 0; if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) && - ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011)) + ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011) && + ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8706)) return 0; } else { if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) @@ -7299,7 +7538,6 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) u32 val; int err; - if (!strcmp(np->vpd.model, "SUNW,CP3220") || !strcmp(np->vpd.model, "SUNW,CP3260")) { num_10g = 0; @@ -7310,6 +7548,12 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) phy_encode(PORT_TYPE_1G, 1) | phy_encode(PORT_TYPE_1G, 2) | phy_encode(PORT_TYPE_1G, 3)); + } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { + num_10g = 2; + num_1g = 0; + parent->num_ports = 2; + val = (phy_encode(PORT_TYPE_10G, 0) | + phy_encode(PORT_TYPE_10G, 1)); } else { err = fill_phy_probe_info(np, parent, info); if (err) diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 35e9afb23bdf..97ffbe137bcb 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -2537,6 +2537,7 @@ struct fcram_hash_ipv6 { #define NIU_PHY_ID_MASK 0xfffff0f0 #define NIU_PHY_ID_BCM8704 0x00206030 +#define NIU_PHY_ID_BCM8706 0x00206035 #define NIU_PHY_ID_BCM5464R 0x002060b0 #define NIU_PHY_ID_MRVL88X2011 0x01410020 @@ -3208,6 +3209,8 @@ struct niu { struct niu_parent *parent; u32 flags; +#define NIU_FLAGS_HOTPLUG_PHY_PRESENT 0x02000000 /* Removebale PHY detected*/ +#define NIU_FLAGS_HOTPLUG_PHY 0x01000000 /* Removebale PHY */ #define NIU_FLAGS_VPD_VALID 0x00800000 /* VPD has valid version */ #define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ #define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ -- cgit v1.2.2 From 59fba744daadaaa85e07a5db96ac3618bc45a9ad Mon Sep 17 00:00:00 2001 From: Craig Shelley Date: Sat, 12 Apr 2008 16:15:54 +0100 Subject: USB: CP2101 Add new device IDs 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 324bb61d68ff..3b4fa94ecf28 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -53,9 +53,11 @@ static void cp2101_shutdown(struct usb_serial*); static int debug; static struct usb_device_id id_table [] = { + { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ + { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ @@ -71,6 +73,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ -- cgit v1.2.2 From d4062fcb9e6164cbbcef773f6b6602e30c4b6007 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 14 Apr 2008 21:27:00 +0800 Subject: USB: Fix memory leak in mon_stat_release Fix the leak of the snap structure allocated in mon_stat_open(). Signed-off-by: Ming Lei Acked-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_stat.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index f6d1491256c4..c7a595cd648a 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -59,6 +59,9 @@ static ssize_t mon_stat_read(struct file *file, char __user *buf, static int mon_stat_release(struct inode *inode, struct file *file) { + struct snap *sp = file->private_data; + file->private_data = NULL; + kfree(sp); return 0; } -- cgit v1.2.2 From 8f7f85e9f9561507b009d26395c53e70758695ec Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Thu, 17 Apr 2008 07:47:34 +0200 Subject: USB: Add HP hs2300 Broadband Wireless Module to sierra.c Add the HP hs2300 Broadband Wireless Module (relabeled MC8775) USB IDs Signed-off-by: Stefan Seyfried Cc: stable 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 ed678811e6a6..7b02a4ae1da4 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -164,6 +164,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ + { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ -- cgit v1.2.2 From 3bb1af5243d41af9518728445e9c9bd30dd47237 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Mar 2008 15:15:36 -0500 Subject: USB: EHCI: carry out port handover during each root-hub resume This patch (as1044) causes EHCI port handover for non-high-speed devices to occur during every root-hub resume, not just in cases where the controller lost power or was reset. This is necessary because: When some machines go into suspend, they remove power from on-board USB devices while retaining suspend current for USB controllers. The user might well unplug a USB device while the system is suspended and then plug it back in before resuming. A corresponding change is made to the core resume routine; now high-speed root hubs will always be resumed when the system wakes up, even if they were suspended before the system went to sleep. If this weren't done then EHCI port handover wouldn't work, since it is called when the EHCI root hub is resumed. Finally, a comment is added to the hub driver explaining the khubd has to be freezable; if it weren't frozen then it could interfere with port handover. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 9 +++++++-- drivers/usb/core/hub.c | 6 ++++++ drivers/usb/host/ehci-hub.c | 4 +--- drivers/usb/host/ehci-pci.c | 1 - 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 801b6f142fa7..ebccdefcc6f2 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1523,9 +1523,14 @@ static int usb_suspend(struct device *dev, pm_message_t message) udev = to_usb_device(dev); /* If udev is already suspended, we can skip this suspend and - * we should also skip the upcoming system resume. */ + * we should also skip the upcoming system resume. High-speed + * root hubs are an exception; they need to resume whenever the + * system wakes up in order for USB-PERSIST port handover to work + * properly. + */ if (udev->state == USB_STATE_SUSPENDED) { - udev->skip_sys_resume = 1; + if (udev->parent || udev->speed != USB_SPEED_HIGH) + udev->skip_sys_resume = 1; return 0; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 57aeca160f38..a42db75c2336 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2890,7 +2890,13 @@ loop: static int hub_thread(void *__unused) { + /* khubd needs to be freezable to avoid intefering with USB-PERSIST + * port handover. Otherwise it might see that a full-speed device + * was gone before the EHCI controller had handed its port over to + * the companion full-speed controller. + */ set_freezable(); + do { hub_events(); wait_event_freezable(khubd_wait, diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4e065e556e4b..8d513a15d0cd 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -281,9 +281,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); spin_unlock_irq (&ehci->lock); - - if (!power_okay) - ehci_handover_companion_ports(ehci); + ehci_handover_companion_ports(ehci); return 0; } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 72ccd56e36dd..040bd8632eb3 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -329,7 +329,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); - ehci_handover_companion_ports(ehci); hcd->state = HC_STATE_SUSPENDED; return 0; -- cgit v1.2.2 From 3eb14915a300f539f271e3716f2421bb0697ed48 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Mar 2008 15:15:43 -0500 Subject: USB: reorganize code in hub.c This patch (as1045) reorganizes some code in the hub driver. hub_port_status() is moved earlier in the file, and a new hub_stop() routine is created to do the work currently in hub_preset() (i.e., disconnect all child devices and quiesce the hub). There are no functional changes. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 58 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a42db75c2336..087e3bb70e09 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -333,6 +333,27 @@ static int get_port_status(struct usb_device *hdev, int port1, return status; } +static int hub_port_status(struct usb_hub *hub, int port1, + u16 *status, u16 *change) +{ + int ret; + + mutex_lock(&hub->status_mutex); + ret = get_port_status(hub->hdev, port1, &hub->status->port); + if (ret < 4) { + dev_err(hub->intfdev, + "%s failed (err = %d)\n", __func__, ret); + if (ret >= 0) + ret = -EIO; + } else { + *status = le16_to_cpu(hub->status->port.wPortStatus); + *change = le16_to_cpu(hub->status->port.wPortChange); + ret = 0; + } + mutex_unlock(&hub->status_mutex); + return ret; +} + static void kick_khubd(struct usb_hub *hub) { unsigned long flags; @@ -610,9 +631,8 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) } /* caller has locked the hub device */ -static int hub_pre_reset(struct usb_interface *intf) +static void hub_stop(struct usb_hub *hub) { - struct usb_hub *hub = usb_get_intfdata(intf); struct usb_device *hdev = hub->hdev; int i; @@ -622,6 +642,14 @@ static int hub_pre_reset(struct usb_interface *intf) usb_disconnect(&hdev->children[i]); } hub_quiesce(hub); +} + +/* caller has locked the hub device */ +static int hub_pre_reset(struct usb_interface *intf) +{ + struct usb_hub *hub = usb_get_intfdata(intf); + + hub_stop(hub); return 0; } @@ -910,7 +938,7 @@ static void hub_disconnect(struct usb_interface *intf) /* Disconnect all children and quiesce the hub */ hub->error = 0; - hub_pre_reset(intf); + hub_stop(hub); usb_set_intfdata (intf, NULL); @@ -1510,28 +1538,6 @@ out_authorized: } -static int hub_port_status(struct usb_hub *hub, int port1, - u16 *status, u16 *change) -{ - int ret; - - mutex_lock(&hub->status_mutex); - ret = get_port_status(hub->hdev, port1, &hub->status->port); - if (ret < 4) { - dev_err (hub->intfdev, - "%s failed (err = %d)\n", __FUNCTION__, ret); - if (ret >= 0) - ret = -EIO; - } else { - *status = le16_to_cpu(hub->status->port.wPortStatus); - *change = le16_to_cpu(hub->status->port.wPortChange); - ret = 0; - } - mutex_unlock(&hub->status_mutex); - return ret; -} - - /* Returns 1 if @hub is a WUSB root hub, 0 otherwise */ static unsigned hub_is_wusb(struct usb_hub *hub) { @@ -2726,7 +2732,7 @@ static void hub_events(void) /* If the hub has died, clean up after it */ if (hdev->state == USB_STATE_NOTATTACHED) { hub->error = -ENODEV; - hub_pre_reset(intf); + hub_stop(hub); goto loop; } -- cgit v1.2.2 From 5e6effaed6da94e727cd45f945ad2489af8570b3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Mar 2008 15:15:51 -0500 Subject: USB: make USB-PERSIST work after every system sleep This patch (as1046) makes USB-PERSIST work more in accordance with the documentation. Currently it takes effect only in cases where the root hub has lost power or been reset, but it is supposed to operate whenever a power session was dropped during a system sleep. A new hub_restart() routine carries out the duties required during a reset or a reset-resume. It checks to see whether occupied ports are still enabled, and if they aren't then it clears the enable-change and connect-change features (to prevent interference by khubd) and sets the child device's reset_resume flag. It also checks ports that are supposed to be unoccupied to verify that the firmware hasn't left the port in an enabled state. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 114 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 087e3bb70e09..df68e2562582 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -644,6 +644,81 @@ static void hub_stop(struct usb_hub *hub) hub_quiesce(hub); } +#define HUB_RESET 1 +#define HUB_RESUME 2 +#define HUB_RESET_RESUME 3 + +#ifdef CONFIG_PM + +static void hub_restart(struct usb_hub *hub, int type) +{ + struct usb_device *hdev = hub->hdev; + int port1; + + /* Check each of the children to see if they require + * USB-PERSIST handling or disconnection. Also check + * each unoccupied port to make sure it is still disabled. + */ + for (port1 = 1; port1 <= hdev->maxchild; ++port1) { + struct usb_device *udev = hdev->children[port1-1]; + int status = 0; + u16 portstatus, portchange; + + if (!udev || udev->state == USB_STATE_NOTATTACHED) { + if (type != HUB_RESET) { + status = hub_port_status(hub, port1, + &portstatus, &portchange); + if (status == 0 && (portstatus & + USB_PORT_STAT_ENABLE)) + clear_port_feature(hdev, port1, + USB_PORT_FEAT_ENABLE); + } + continue; + } + + /* Was the power session lost while we were suspended? */ + switch (type) { + case HUB_RESET_RESUME: + portstatus = 0; + portchange = USB_PORT_STAT_C_CONNECTION; + break; + + case HUB_RESET: + case HUB_RESUME: + status = hub_port_status(hub, port1, + &portstatus, &portchange); + break; + } + + /* For "USB_PERSIST"-enabled children we must + * mark the child device for reset-resume and + * turn off the various status changes to prevent + * khubd from disconnecting it later. + */ + if (USB_PERSIST && udev->persist_enabled && status == 0 && + !(portstatus & USB_PORT_STAT_ENABLE)) { + if (portchange & USB_PORT_STAT_C_ENABLE) + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_ENABLE); + if (portchange & USB_PORT_STAT_C_CONNECTION) + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_CONNECTION); + udev->reset_resume = 1; + } + + /* Otherwise for a reset_resume we must disconnect the child, + * but as we may not lock the child device here + * we have to do a "logical" disconnect. + */ + else if (type == HUB_RESET_RESUME) + hub_port_logical_disconnect(hub, port1); + } + + hub_activate(hub); +} + +#endif /* CONFIG_PM */ + /* caller has locked the hub device */ static int hub_pre_reset(struct usb_interface *intf) { @@ -2015,49 +2090,20 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) static int hub_resume(struct usb_interface *intf) { - struct usb_hub *hub = usb_get_intfdata (intf); - - dev_dbg(&intf->dev, "%s\n", __FUNCTION__); + struct usb_hub *hub = usb_get_intfdata(intf); - /* tell khubd to look for changes on this hub */ - hub_activate(hub); + dev_dbg(&intf->dev, "%s\n", __func__); + hub_restart(hub, HUB_RESUME); return 0; } static int hub_reset_resume(struct usb_interface *intf) { struct usb_hub *hub = usb_get_intfdata(intf); - struct usb_device *hdev = hub->hdev; - int port1; + dev_dbg(&intf->dev, "%s\n", __func__); hub_power_on(hub); - - for (port1 = 1; port1 <= hdev->maxchild; ++port1) { - struct usb_device *child = hdev->children[port1-1]; - - if (child) { - - /* For "USB_PERSIST"-enabled children we must - * mark the child device for reset-resume and - * turn off the connect-change status to prevent - * khubd from disconnecting it later. - */ - if (USB_PERSIST && child->persist_enabled) { - child->reset_resume = 1; - clear_port_feature(hdev, port1, - USB_PORT_FEAT_C_CONNECTION); - - /* Otherwise we must disconnect the child, - * but as we may not lock the child device here - * we have to do a "logical" disconnect. - */ - } else { - hub_port_logical_disconnect(hub, port1); - } - } - } - - hub_activate(hub); + hub_restart(hub, HUB_RESET_RESUME); return 0; } -- cgit v1.2.2 From feccc30d90155bcbc937f87643182a43d25873eb Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Mar 2008 15:15:59 -0500 Subject: USB: remove CONFIG_USB_PERSIST setting This patch (as1047) removes the USB_PERSIST Kconfig option, enabling it permanently. It also prevents the power/persist attribute from being created for hub devices; there's no point in having it since USB-PERSIST is always turned on for hubs. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 25 ------------------------- drivers/usb/core/hub.c | 27 ++++++++++----------------- drivers/usb/core/quirks.c | 12 ++++++++++++ drivers/usb/core/sysfs.c | 22 ++++++++++------------ drivers/usb/host/ehci-hub.c | 11 +---------- 5 files changed, 33 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index a2b0aa48b8ea..c15621d64579 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -102,31 +102,6 @@ config USB_SUSPEND If you are unsure about this, say N here. -config USB_PERSIST - bool "USB device persistence during system suspend (DANGEROUS)" - depends on USB && PM && EXPERIMENTAL - default n - help - - If you say Y here and enable the "power/persist" attribute - for a USB device, the device's data structures will remain - persistent across system suspend, even if the USB bus loses - power. (This includes hibernation, also known as swsusp or - suspend-to-disk.) The devices will reappear as if by magic - when the system wakes up, with no need to unmount USB - filesystems, rmmod host-controller drivers, or do anything - else. - - WARNING: This option can be dangerous! - - If a USB device is replaced by another of the same type while - the system is asleep, there's a good chance the kernel won't - detect the change. Likewise if the media in a USB storage - device is replaced. When this happens it's almost certain to - cause data corruption and maybe even crash your system. - - If you are unsure, say N here. - config USB_OTG bool depends on USB && EXPERIMENTAL diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index df68e2562582..6dc589955d75 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -30,12 +30,6 @@ #include "hcd.h" #include "hub.h" -#ifdef CONFIG_USB_PERSIST -#define USB_PERSIST 1 -#else -#define USB_PERSIST 0 -#endif - /* if we are in debug mode, always announce new devices */ #ifdef DEBUG #ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES @@ -695,7 +689,7 @@ static void hub_restart(struct usb_hub *hub, int type) * turn off the various status changes to prevent * khubd from disconnecting it later. */ - if (USB_PERSIST && udev->persist_enabled && status == 0 && + if (udev->persist_enabled && status == 0 && !(portstatus & USB_PORT_STAT_ENABLE)) { if (portchange & USB_PORT_STAT_C_ENABLE) clear_port_feature(hub->hdev, port1, @@ -1923,9 +1917,8 @@ static int finish_port_resume(struct usb_device *udev) * the host and the device is the same as it was when the device * suspended. * - * If CONFIG_USB_PERSIST and @udev->reset_resume are both set then this - * routine won't check that the port is still enabled. Furthermore, - * if @udev->reset_resume is set then finish_port_resume() above will + * If @udev->reset_resume is set then this routine won't check that the + * port is still enabled. Furthermore, finish_port_resume() above will * reset @udev. The end result is that a broken power session can be * recovered and @udev will appear to persist across a loss of VBUS power. * @@ -1937,8 +1930,8 @@ static int finish_port_resume(struct usb_device *udev) * to it will be lost. Using the USB_PERSIST facility, the device can be * made to appear as if it had not disconnected. * - * This facility is inherently dangerous. Although usb_reset_device() - * makes every effort to insure that the same device is present after the + * This facility can be dangerous. Although usb_reset_device() makes + * every effort to insure that the same device is present after the * reset as before, it cannot provide a 100% guarantee. Furthermore it's * quite possible for a device to remain unaltered but its media to be * changed. If the user replaces a flash memory card while the system is @@ -1983,7 +1976,7 @@ int usb_port_resume(struct usb_device *udev) status = hub_port_status(hub, port1, &portstatus, &portchange); SuspendCleared: - if (USB_PERSIST && udev->reset_resume) + if (udev->reset_resume) want_flags = USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION; else @@ -2113,10 +2106,10 @@ static int hub_reset_resume(struct usb_interface *intf) * * The USB host controller driver calls this function when its root hub * is resumed and Vbus power has been interrupted or the controller - * has been reset. The routine marks @rhdev as having lost power. When - * the hub driver is resumed it will take notice; if CONFIG_USB_PERSIST - * is enabled then it will carry out power-session recovery, otherwise - * it will disconnect all the child devices. + * has been reset. The routine marks @rhdev as having lost power. + * When the hub driver is resumed it will take notice and carry out + * power-session recovery for all the "USB-PERSIST"-enabled child devices; + * the others will be disconnected. */ void usb_root_hub_lost_power(struct usb_device *rhdev) { diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index dfc5418ea10c..f384edf35b44 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -97,4 +97,16 @@ void usb_detect_quirks(struct usb_device *udev) if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) udev->autosuspend_disabled = 1; #endif + +#ifdef CONFIG_PM + /* Hubs are automatically enabled for USB-PERSIST */ + if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) + udev->persist_enabled = 1; +#else + /* In the absense of PM, we can safely enable USB-PERSIST + * for all devices. It will affect things like hub resets + * and EMF-related port disables. + */ + udev->persist_enabled = 1; +#endif /* CONFIG_PM */ } diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index a37ccbd1e007..5b20a60de8ba 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -180,11 +180,9 @@ show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); -#if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) -static const char power_group[] = "power"; -#endif +#ifdef CONFIG_PM -#ifdef CONFIG_USB_PERSIST +static const char power_group[] = "power"; static ssize_t show_persist(struct device *dev, struct device_attribute *attr, char *buf) @@ -222,12 +220,13 @@ static int add_persist_attributes(struct device *dev) if (is_usb_device(dev)) { struct usb_device *udev = to_usb_device(dev); - /* Hubs are automatically enabled for USB_PERSIST */ - if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) - udev->persist_enabled = 1; - rc = sysfs_add_file_to_group(&dev->kobj, - &dev_attr_persist.attr, - power_group); + /* Hubs are automatically enabled for USB_PERSIST, + * no point in creating the attribute file. + */ + if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) + rc = sysfs_add_file_to_group(&dev->kobj, + &dev_attr_persist.attr, + power_group); } return rc; } @@ -238,13 +237,12 @@ static void remove_persist_attributes(struct device *dev) &dev_attr_persist.attr, power_group); } - #else #define add_persist_attributes(dev) 0 #define remove_persist_attributes(dev) do {} while (0) -#endif /* CONFIG_USB_PERSIST */ +#endif /* CONFIG_PM */ #ifdef CONFIG_USB_SUSPEND diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 8d513a15d0cd..fea9e47192db 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -28,7 +28,7 @@ /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_USB_PERSIST +#ifdef CONFIG_PM static int ehci_hub_control( struct usb_hcd *hcd, @@ -104,15 +104,6 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) ehci->owned_ports = 0; } -#else /* CONFIG_USB_PERSIST */ - -static inline void ehci_handover_companion_ports(struct ehci_hcd *ehci) -{ } - -#endif - -#ifdef CONFIG_PM - static int ehci_bus_suspend (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); -- cgit v1.2.2 From eb764c4be1e5db3ee34df5745e98cf2f148c7320 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 3 Mar 2008 15:16:04 -0500 Subject: USB: check serial-number string after device reset This patch (as1048) extends the descriptor checking after a device is reset. Now the SerialNumber string descriptor is compared to its old value, in addition to the device and configuration descriptors. As a consequence, the kmalloc() call in usb_string() is now on the error-handling pathway for usb-storage. Hence its allocation type is changed to GFO_NOIO. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 65 +++++++++++++++++++++++++++++++++++----------- drivers/usb/core/message.c | 2 +- 2 files changed, 51 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6dc589955d75..9fc5179dfc60 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3010,16 +3010,36 @@ void usb_hub_cleanup(void) usb_deregister(&hub_driver); } /* usb_hub_cleanup() */ -static int config_descriptors_changed(struct usb_device *udev) -{ - unsigned index; - unsigned len = 0; - struct usb_config_descriptor *buf; +static int descriptors_changed(struct usb_device *udev, + struct usb_device_descriptor *old_device_descriptor) +{ + int changed = 0; + unsigned index; + unsigned serial_len = 0; + unsigned len; + unsigned old_length; + int length; + char *buf; + + if (memcmp(&udev->descriptor, old_device_descriptor, + sizeof(*old_device_descriptor)) != 0) + return 1; + + /* Since the idVendor, idProduct, and bcdDevice values in the + * device descriptor haven't changed, we will assume the + * Manufacturer and Product strings haven't changed either. + * But the SerialNumber string could be different (e.g., a + * different flash card of the same brand). + */ + if (udev->serial) + serial_len = strlen(udev->serial) + 1; + len = serial_len; for (index = 0; index < udev->descriptor.bNumConfigurations; index++) { - if (len < le16_to_cpu(udev->config[index].desc.wTotalLength)) - len = le16_to_cpu(udev->config[index].desc.wTotalLength); + old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); + len = max(len, old_length); } + buf = kmalloc(len, GFP_NOIO); if (buf == NULL) { dev_err(&udev->dev, "no mem to re-read configs after reset\n"); @@ -3027,25 +3047,41 @@ static int config_descriptors_changed(struct usb_device *udev) return 1; } for (index = 0; index < udev->descriptor.bNumConfigurations; index++) { - int length; - int old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); - + old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf, old_length); - if (length < old_length) { + if (length != old_length) { dev_dbg(&udev->dev, "config index %d, error %d\n", index, length); + changed = 1; break; } if (memcmp (buf, udev->rawdescriptors[index], old_length) != 0) { dev_dbg(&udev->dev, "config index %d changed (#%d)\n", - index, buf->bConfigurationValue); + index, + ((struct usb_config_descriptor *) buf)-> + bConfigurationValue); + changed = 1; break; } } + + if (!changed && serial_len) { + length = usb_string(udev, udev->descriptor.iSerialNumber, + buf, serial_len); + if (length + 1 != serial_len) { + dev_dbg(&udev->dev, "serial string error %d\n", + length); + changed = 1; + } else if (memcmp(buf, udev->serial, length) != 0) { + dev_dbg(&udev->dev, "serial string changed\n"); + changed = 1; + } + } + kfree(buf); - return index != udev->descriptor.bNumConfigurations; + return changed; } /** @@ -3118,8 +3154,7 @@ int usb_reset_device(struct usb_device *udev) goto re_enumerate; /* Device might have changed firmware (DFU or similar) */ - if (memcmp(&udev->descriptor, &descriptor, sizeof descriptor) - || config_descriptors_changed (udev)) { + if (descriptors_changed(udev, &descriptor)) { dev_info(&udev->dev, "device firmware changed\n"); udev->descriptor = descriptor; /* for disconnect() calls */ goto re_enumerate; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index c311f67b7f08..a3695b5115ff 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -784,7 +784,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (size <= 0 || !buf || !index) return -EINVAL; buf[0] = 0; - tbuf = kmalloc(256, GFP_KERNEL); + tbuf = kmalloc(256, GFP_NOIO); if (!tbuf) return -ENOMEM; -- cgit v1.2.2 From 9214d1d80c19016172e685ce7bde0ea757c49097 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Mar 2008 11:04:13 -0500 Subject: USB: enable USB-PERSIST by default This patch (as1052) enables USB-PERSIST for all devices by default. The user won't have to remember to enable it explicitly for devices containing mounted filesystems. Eventually userspace tools like hal may be able to set the persist attribute automatically when a filesystem is mounted on a USB device. When that time comes this patch can be reverted, if people think it matters. This approach has the advantage of giving the user the ability to turn off USB-PERSIST for devices with mounted filesystems, rather than making the kernel always assume it should be on. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f384edf35b44..2e2019390290 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -98,12 +98,14 @@ void usb_detect_quirks(struct usb_device *udev) udev->autosuspend_disabled = 1; #endif -#ifdef CONFIG_PM + /* For the present, all devices default to USB-PERSIST enabled */ +#if 0 /* was: #ifdef CONFIG_PM */ /* Hubs are automatically enabled for USB-PERSIST */ if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) udev->persist_enabled = 1; + #else - /* In the absense of PM, we can safely enable USB-PERSIST + /* In the absence of PM, we can safely enable USB-PERSIST * for all devices. It will affect things like hub resets * and EMF-related port disables. */ -- cgit v1.2.2 From d99388aa0a504f69532db353a976ec133361bb4f Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Mon, 4 Feb 2008 23:57:42 -0800 Subject: USB: microtek: remove unused semaphore No current references, so removing it. Signed-off-by: Daniel Walker Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/microtek.c | 1 - drivers/usb/image/microtek.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index bc207e3c21f5..0badbbe2fd24 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -794,7 +794,6 @@ static int mts_usb_probe(struct usb_interface *intf, new_desc->usb_dev = dev; new_desc->usb_intf = intf; - init_MUTEX(&new_desc->lock); /* endpoints */ new_desc->ep_out = ep_out; diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h index d5d62a939058..ccce318f20a0 100644 --- a/drivers/usb/image/microtek.h +++ b/drivers/usb/image/microtek.h @@ -39,7 +39,6 @@ struct mts_desc { u8 ep_image; struct Scsi_Host * host; - struct semaphore lock; struct urb *urb; struct mts_transfer_context context; -- cgit v1.2.2 From 75c43b6ec6eb114e875e43fb151987c1a558e4f4 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Mon, 4 Feb 2008 23:57:42 -0800 Subject: USB: libusual: locking cleanup I converted the usu_init_notify semaphore to normal mutex usage, and it should still prevent the request_module before the init routine is complete. Before it acted more like a complete, now the mutex protects two distinct section from running at the same time. Signed-off-by: Daniel Walker Cc: Pete Zaitcev Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/libusual.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index 55b952084f0c..a28d49122e7a 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c @@ -9,6 +9,7 @@ #include #include #include +#include /* */ @@ -30,7 +31,7 @@ static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); #define BIAS_NAME_SIZE (sizeof("usb-storage")) static const char *bias_names[3] = { "none", "usb-storage", "ub" }; -static struct semaphore usu_init_notify; +static DEFINE_MUTEX(usu_probe_mutex); static DECLARE_COMPLETION(usu_end_notify); static atomic_t total_threads = ATOMIC_INIT(0); @@ -178,10 +179,7 @@ static int usu_probe_thread(void *arg) int rc; unsigned long flags; - /* A completion does not work here because it's counted. */ - down(&usu_init_notify); - up(&usu_init_notify); - + mutex_lock(&usu_probe_mutex); rc = request_module(bias_names[type]); spin_lock_irqsave(&usu_lock, flags); if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { @@ -194,6 +192,7 @@ static int usu_probe_thread(void *arg) } st->fls &= ~USU_MOD_FL_THREAD; spin_unlock_irqrestore(&usu_lock, flags); + mutex_unlock(&usu_probe_mutex); complete_and_exit(&usu_end_notify, 0); } @@ -204,10 +203,9 @@ static int __init usb_usual_init(void) { int rc; - sema_init(&usu_init_notify, 0); - + mutex_lock(&usu_probe_mutex); rc = usb_register(&usu_driver); - up(&usu_init_notify); + mutex_unlock(&usu_probe_mutex); return rc; } -- cgit v1.2.2 From 5ddeac117f869c0da85e41e89dd5ed1199dab7dd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 4 Feb 2008 23:57:45 -0800 Subject: USB: make USB_STORAGE_ONETOUCH available with PM As Torsten Kaiser pointed out, it seems the dependency of USB_STORAGE_ONETOUCH on !PM should have been removed in commit 7931e1c6f8007d5fef8a0bb2dc71bd97315eeae9. Signed-off-by: Adrian Bunk Cc: Matthew Dharm Cc: Alan Stern Cc: Greg Kroah-Hartman Cc: Torsten Kaiser Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 7e53333be013..05cfc8473bd2 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -123,7 +123,7 @@ config USB_STORAGE_ALAUDA config USB_STORAGE_ONETOUCH bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" - depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL && !PM + depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. -- cgit v1.2.2 From 1409e8e0e4dae15735727d7e2814b62aff609d31 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 4 Feb 2008 23:57:48 -0800 Subject: USB: usb-ohci-sm501-driver: use the conventional convention for suspend and resume Cc: Alan Stern Cc: Magnus Damm Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-sm501.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 4ea92762fb28..8ffcd3e5f56b 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -242,6 +242,9 @@ static int ohci_sm501_resume(struct platform_device *pdev) usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); return 0; } +#else +#define ohci_sm501_suspend NULL +#define ohci_sm501_resume NULL #endif /*-------------------------------------------------------------------------*/ @@ -253,10 +256,8 @@ static struct platform_driver ohci_hcd_sm501_driver = { .probe = ohci_hcd_sm501_drv_probe, .remove = ohci_hcd_sm501_drv_remove, .shutdown = usb_hcd_platform_shutdown, -#ifdef CONFIG_PM .suspend = ohci_sm501_suspend, .resume = ohci_sm501_resume, -#endif .driver = { .owner = THIS_MODULE, .name = "sm501-usb", -- cgit v1.2.2 From c4504a7eb9c4c491e6f31b28169dd49e9bacc8ec Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 11 Feb 2008 15:26:09 +0300 Subject: USB: usbatm: convert heavy init dances to kthread API This is an attempt to kill two birds with one stone. First, we kill one more user of kernel_thread, which is scheduled for removal. Second - we kill one of the last users of kill_proc - the function which is also to be removed, because it uses a pid_t which is not safe now. Signed-off-by: Pavel Emelyanov Signed-off-by: Duncan Sands Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/usbatm.c | 27 +++++++++++++++------------ drivers/usb/atm/usbatm.h | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index e717f5b1caee..07228721cafe 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -80,6 +80,7 @@ #include #include #include +#include #ifdef VERBOSE_DEBUG static int usbatm_print_packet(const unsigned char *data, int len); @@ -1014,10 +1015,7 @@ static int usbatm_do_heavy_init(void *arg) struct usbatm_data *instance = arg; int ret; - daemonize(instance->driver->driver_name); allow_signal(SIGTERM); - instance->thread_pid = current->pid; - complete(&instance->thread_started); ret = instance->driver->heavy_init(instance, instance->usb_intf); @@ -1026,7 +1024,7 @@ static int usbatm_do_heavy_init(void *arg) ret = usbatm_atm_init(instance); mutex_lock(&instance->serialize); - instance->thread_pid = -1; + instance->thread = NULL; mutex_unlock(&instance->serialize); complete_and_exit(&instance->thread_exited, ret); @@ -1034,13 +1032,18 @@ static int usbatm_do_heavy_init(void *arg) static int usbatm_heavy_init(struct usbatm_data *instance) { - int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES); - - if (ret < 0) { - usb_err(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret); - return ret; + struct task_struct *t; + + t = kthread_create(usbatm_do_heavy_init, instance, + instance->driver->driver_name); + if (IS_ERR(t)) { + usb_err(instance, "%s: failed to create kernel_thread (%ld)!\n", + __func__, PTR_ERR(t)); + return PTR_ERR(t); } + instance->thread = t; + wake_up_process(t); wait_for_completion(&instance->thread_started); return 0; @@ -1124,7 +1127,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */ mutex_init(&instance->serialize); - instance->thread_pid = -1; + instance->thread = NULL; init_completion(&instance->thread_started); init_completion(&instance->thread_exited); @@ -1287,8 +1290,8 @@ void usbatm_usb_disconnect(struct usb_interface *intf) mutex_lock(&instance->serialize); instance->disconnected = 1; - if (instance->thread_pid >= 0) - kill_proc(instance->thread_pid, SIGTERM, 1); + if (instance->thread != NULL) + send_sig(SIGTERM, instance->thread, 1); mutex_unlock(&instance->serialize); wait_for_completion(&instance->thread_exited); diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h index fc6c2be5999c..e6887c6cf3cf 100644 --- a/drivers/usb/atm/usbatm.h +++ b/drivers/usb/atm/usbatm.h @@ -175,7 +175,7 @@ struct usbatm_data { int disconnected; /* heavy init */ - int thread_pid; + struct task_struct *thread; struct completion thread_started; struct completion thread_exited; -- cgit v1.2.2 From dbe0dbb7dfda52140d3469d7035a08dfa874fca2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 10 Feb 2008 12:24:00 -0800 Subject: USB: defines for USB "Link Power Management" (LPM) ECN There's a new PM-related change notice for the USB 2.0 specification called "Link Power Management" (LPM). It defines a new "L1 Suspend" state which resembles the current (L2) suspend state, except that it can be entered and exited much more quickly. It should thus be more useful for runtime PM, even though it doesn't mandate reduced power draw from VBUS. This patch provides the relevant #defines for usbcore. Actually implementing these mechanisms requires host silicon that can generate new USB packets, plus hubs handling some new requests and peripherals which understand the new packets. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.h | 2 +- drivers/usb/core/hub.h | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 2d1c3d5e47b8..2c086b8460b1 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -28,7 +28,7 @@ /* * USB Packet IDs (PIDs) */ -#define USB_PID_UNDEF_0 0xf0 +#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */ #define USB_PID_OUT 0xe1 #define USB_PID_ACK 0xd2 #define USB_PID_DATA0 0xc3 diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 1551aed65e05..d672cd81a3e4 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -41,9 +41,10 @@ */ #define USB_PORT_FEAT_CONNECTION 0 #define USB_PORT_FEAT_ENABLE 1 -#define USB_PORT_FEAT_SUSPEND 2 +#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */ #define USB_PORT_FEAT_OVER_CURRENT 3 #define USB_PORT_FEAT_RESET 4 +#define USB_PORT_FEAT_L1 5 /* L1 suspend */ #define USB_PORT_FEAT_POWER 8 #define USB_PORT_FEAT_LOWSPEED 9 #define USB_PORT_FEAT_HIGHSPEED 10 @@ -54,6 +55,7 @@ #define USB_PORT_FEAT_C_RESET 20 #define USB_PORT_FEAT_TEST 21 #define USB_PORT_FEAT_INDICATOR 22 +#define USB_PORT_FEAT_C_PORT_L1 23 /* * Hub Status and Hub Change results @@ -73,7 +75,8 @@ struct usb_port_status { #define USB_PORT_STAT_SUSPEND 0x0004 #define USB_PORT_STAT_OVERCURRENT 0x0008 #define USB_PORT_STAT_RESET 0x0010 -/* bits 5 to 7 are reserved */ +#define USB_PORT_STAT_L1 0x0020 +/* bits 6 to 7 are reserved */ #define USB_PORT_STAT_POWER 0x0100 #define USB_PORT_STAT_LOW_SPEED 0x0200 #define USB_PORT_STAT_HIGH_SPEED 0x0400 @@ -91,6 +94,7 @@ struct usb_port_status { #define USB_PORT_STAT_C_SUSPEND 0x0004 #define USB_PORT_STAT_C_OVERCURRENT 0x0008 #define USB_PORT_STAT_C_RESET 0x0010 +#define USB_PORT_STAT_C_L1 0x0020 /* * wHubCharacteristics (masks) -- cgit v1.2.2 From 9776afc8b3dc487557f3f576002520f59be334e6 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 1 Feb 2008 11:42:05 -0800 Subject: USB: ehci: minor cleanups Minor cleanups to the EHCI code: revision history is what source code repositories should have. Switch to a more standard way to kick in verbose debugging -- don't be EHCI-specific. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 2 +- drivers/usb/host/ehci-hcd.c | 33 ++------------------------------- drivers/usb/host/ehci-hub.c | 2 +- 3 files changed, 4 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 64ebfc5548a3..38eb92e5dc42 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -27,7 +27,7 @@ #define ehci_warn(ehci, fmt, args...) \ dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) -#ifdef EHCI_VERBOSE_DEBUG +#ifdef VERBOSE_DEBUG # define vdbg dbg # define ehci_vdbg ehci_dbg #else diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 85074cb36f38..360712207262 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -57,35 +57,6 @@ * Special thanks to Intel and VIA for providing host controllers to * test this driver on, and Cypress (including In-System Design) for * providing early devices for those host controllers to talk to! - * - * HISTORY: - * - * 2004-05-10 Root hub and PCI suspend/resume support; remote wakeup. (db) - * 2004-02-24 Replace pci_* with generic dma_* API calls (dsaxena@plexity.net) - * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka, - * , updates by DB). - * - * 2002-11-29 Correct handling for hw async_next register. - * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared; - * only scheduling is different, no arbitrary limitations. - * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support, - * clean up HC run state handshaking. - * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts - * 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other - * missing pieces: enabling 64bit dma, handoff from BIOS/SMM. - * 2002-05-07 Some error path cleanups to report better errors; wmb(); - * use non-CVS version id; better iso bandwidth claim. - * 2002-04-19 Control/bulk/interrupt submit no longer uses giveback() on - * errors in submit path. Bugfixes to interrupt scheduling/processing. - * 2002-03-05 Initial high-speed ISO support; reduce ITD memory; shift - * more checking to generic hcd framework (db). Make it work with - * Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt). - * 2002-01-14 Minor cleanup; version synch. - * 2002-01-08 Fix roothub handoff of FS/LS to companion controllers. - * 2002-01-04 Control/Bulk queuing behaves. - * - * 2001-12-12 Initial patch version for Linux 2.5.1 kernel. - * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ #define DRIVER_VERSION "10 Dec 2004" @@ -95,7 +66,7 @@ static const char hcd_name [] = "ehci_hcd"; -#undef EHCI_VERBOSE_DEBUG +#undef VERBOSE_DEBUG #undef EHCI_URB_TRACE #ifdef DEBUG @@ -676,7 +647,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) cmd = ehci_readl(ehci, &ehci->regs->command); bh = 0; -#ifdef EHCI_VERBOSE_DEBUG +#ifdef VERBOSE_DEBUG /* unrequested/ignored: Frame List Rollover */ dbg_status (ehci, "irq", status); #endif diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index fea9e47192db..21ac3781f21a 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -767,7 +767,7 @@ static int ehci_hub_control ( if (temp & PORT_POWER) status |= 1 << USB_PORT_FEAT_POWER; -#ifndef EHCI_VERBOSE_DEBUG +#ifndef VERBOSE_DEBUG if (status & ~0xffff) /* only if wPortChange is interesting */ #endif dbg_port (ehci, "GetStatus", wIndex + 1, temp); -- cgit v1.2.2 From e01e7fe3886715f083313da409c5850472455d06 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 2 Feb 2008 02:42:52 -0800 Subject: USB: ohci: port reset paranoia timeout This limits how long the OHCI port reset loop waits for the hardware to do its job, if the controller either (a) dies, or (b) can't finish the reset. Such limits are always a good idea. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 48e4b11f4d3e..c638e6b33c43 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -564,14 +564,18 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) u32 temp; u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); u16 reset_done = now + PORT_RESET_MSEC; + int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC); /* build a "continuous enough" reset signal, with up to * 3msec gap between pulses. scheduler HZ==100 must work; * this might need to be deadline-scheduled. */ do { + int limit_2; + /* spin until any current reset finishes */ - for (;;) { + limit_2 = PORT_RESET_HW_MSEC * 2; + while (--limit_2 >= 0) { temp = ohci_readl (ohci, portstat); /* handle e.g. CardBus eject */ if (temp == ~(u32)0) @@ -581,6 +585,17 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) udelay (500); } + /* timeout (a hardware error) has been observed when + * EHCI sets CF while this driver is resetting a port; + * presumably other disconnect paths might do it too. + */ + if (limit_2 < 0) { + ohci_dbg(ohci, + "port[%d] reset timeout, stat %08x\n", + port, temp); + break; + } + if (!(temp & RH_PS_CCS)) break; if (temp & RH_PS_PRSC) @@ -590,8 +605,11 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) ohci_writel (ohci, RH_PS_PRS, portstat); msleep(PORT_RESET_HW_MSEC); now = ohci_readl(ohci, &ohci->regs->fmnumber); - } while (tick_before(now, reset_done)); - /* caller synchronizes using PRSC */ + } while (tick_before(now, reset_done) && --limit_1 >= 0); + + /* caller synchronizes using PRSC ... and handles PRS + * still being set when this returns. + */ return 0; } -- cgit v1.2.2 From caa9ef672a045ba0b19184cd3f872b583f066771 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 8 Feb 2008 15:08:44 -0800 Subject: USB: ehci tolerates some buggy devices This teaches EHCI how to to work around bugs in certain high speed devices, by accomodating "bulk" packets that exceed the 512 byte constant value required by the USB 2.0 specification. (Have a look at section 5.8.3, paragraphs 1 and 3.) It also makes the descriptor parsing code warn when it encounters such bugs. (We've had reports of maybe two or three such devices, all pretty recent.) Such devices are nonconformant. The proper fix is have the vendors of those devices do the simple, obvious, and correct thing ... which will let them be used with USB hosts that don't have workarounds for this particular vendor bug. But unless/until they do, we can at least have one of the high speed HCDs work with such buggy devices. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 17 +++++++++++++++++ drivers/usb/host/ehci-q.c | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index a92122a216bc..568244c99bdc 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -145,6 +145,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, endpoint->desc.wMaxPacketSize = cpu_to_le16(8); } + /* + * Some buggy high speed devices have bulk endpoints using + * maxpacket sizes other than 512. High speed HCDs may not + * be able to handle that particular bug, so let's warn... + */ + if (to_usb_device(ddev)->speed == USB_SPEED_HIGH + && usb_endpoint_xfer_bulk(d)) { + unsigned maxp; + + maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff; + if (maxp != 512) + dev_warn(ddev, "config %d interface %d altsetting %d " + "bulk endpoint 0x%X has invalid maxpacket %d\n", + cfgno, inum, asnum, d->bEndpointAddress, + maxp); + } + /* Skip over any Class Specific or Vendor Specific descriptors; * find the next endpoint or interface descriptor */ endpoint->extra = buffer; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2e49de820b14..c0e752cffc68 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -657,6 +657,14 @@ qh_make ( type = usb_pipetype (urb->pipe); maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input); + /* 1024 byte maxpacket is a hardware ceiling. High bandwidth + * acts like up to 3KB, but is built from smaller packets. + */ + if (max_packet(maxp) > 1024) { + ehci_dbg(ehci, "bogus qh maxpacket %d\n", max_packet(maxp)); + goto done; + } + /* Compute interrupt scheduling parameters just once, and save. * - allowing for high bandwidth, how many nsec/uframe are used? * - split transactions need a second CSPLIT uframe; same question @@ -757,7 +765,13 @@ qh_make ( info2 |= (EHCI_TUNE_MULT_HS << 30); } else if (type == PIPE_BULK) { info1 |= (EHCI_TUNE_RL_HS << 28); - info1 |= 512 << 16; /* usb2 fixed maxpacket */ + /* The USB spec says that high speed bulk endpoints + * always use 512 byte maxpacket. But some device + * vendors decided to ignore that, and MSFT is happy + * to help them do so. So now people expect to use + * such nonconformant devices with Linux too; sigh. + */ + info1 |= max_packet(maxp) << 16; info2 |= (EHCI_TUNE_MULT_HS << 30); } else { /* PIPE_INTERRUPT */ info1 |= max_packet (maxp) << 16; -- cgit v1.2.2 From 135db0485cdfa808d69420889ca4a2fad8aed9df Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 11 Feb 2008 18:40:46 -0800 Subject: USB: ehci minor SOC bus glue fixes Various minor fixes to some SOC bus glue for EHCI: - Remove a bogus copyright (by "me"!) which someone added to the FSL driver, and an irrelevant comment. - Un-break MODULE_ALIAS() directives after platform_bus hotplugging acquired a backwards-incompatible change. (Which didn't fix ANY of the in-tree drivers it prevented from hotplugging -- sigh.) - Remove some bogus assignments of platform_bus_type; that's done by the platform_bus code. - Add some FIXMEs for drivers with that pointless two-level idiom for probe() and remove() routines. ("Obfuscation" is a non-goal.) That should help avoid future bus glue which copies that idiom. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-au1xxx.c | 5 +++-- drivers/usb/host/ehci-fsl.c | 9 ++++----- drivers/usb/host/ehci-ixp4xx.c | 3 +-- drivers/usb/host/ehci-ppc-soc.c | 5 +++-- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index da7532d38bf1..8b5f991e949c 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -237,6 +237,7 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* FIXME we only want one one probe() not two */ ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev); return ret; } @@ -245,6 +246,7 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); + /* FIXME we only want one one remove() not two */ usb_ehci_au1xxx_remove(hcd, pdev); return 0; } @@ -265,7 +267,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) return 0; } */ -MODULE_ALIAS("au1xxx-ehci"); +MODULE_ALIAS("platform:au1xxx-ehci"); static struct platform_driver ehci_hcd_au1xxx_driver = { .probe = ehci_hcd_au1xxx_drv_probe, .remove = ehci_hcd_au1xxx_drv_remove, @@ -274,6 +276,5 @@ static struct platform_driver ehci_hcd_au1xxx_driver = { /*.resume = ehci_hcd_au1xxx_drv_resume, */ .driver = { .name = "au1xxx-ehci", - .bus = &platform_bus_type } }; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index adb0defa1631..6d9bed6c1f48 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -1,5 +1,4 @@ /* - * (C) Copyright David Brownell 2000-2002 * Copyright (c) 2005 MontaVista Software * * This program is free software; you can redistribute it and/or modify it @@ -28,7 +27,6 @@ /* FIXME: Power Management is un-ported so temporarily disable it */ #undef CONFIG_PM -/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -331,6 +329,7 @@ static int ehci_fsl_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* FIXME we only want one one probe() not two */ return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev); } @@ -338,12 +337,12 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); + /* FIXME we only want one one remove() not two */ usb_hcd_fsl_remove(hcd, pdev); - return 0; } -MODULE_ALIAS("fsl-ehci"); +MODULE_ALIAS("platform:fsl-ehci"); static struct platform_driver ehci_fsl_driver = { .probe = ehci_fsl_drv_probe, @@ -351,5 +350,5 @@ static struct platform_driver ehci_fsl_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "fsl-ehci", - }, + }, }; diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 3041d8f055f4..601c8795a854 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c @@ -140,13 +140,12 @@ static int ixp4xx_ehci_remove(struct platform_device *pdev) return 0; } -MODULE_ALIAS("ixp4xx-ehci"); +MODULE_ALIAS("platform:ixp4xx-ehci"); static struct platform_driver ixp4xx_ehci_driver = { .probe = ixp4xx_ehci_probe, .remove = ixp4xx_ehci_remove, .driver = { .name = "ixp4xx-ehci", - .bus = &platform_bus_type }, }; diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index a3249078c808..6c76036783a1 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c @@ -175,6 +175,7 @@ static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* FIXME we only want one one probe() not two */ ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev); return ret; } @@ -183,17 +184,17 @@ static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); + /* FIXME we only want one one remove() not two */ usb_ehci_ppc_soc_remove(hcd, pdev); return 0; } -MODULE_ALIAS("ppc-soc-ehci"); +MODULE_ALIAS("platform:ppc-soc-ehci"); static struct platform_driver ehci_ppc_soc_driver = { .probe = ehci_hcd_ppc_soc_drv_probe, .remove = ehci_hcd_ppc_soc_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ppc-soc-ehci", - .bus = &platform_bus_type } }; -- cgit v1.2.2 From 96f9bc373c83a67922dc32f358e8a3b3dd4e18a0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Feb 2008 17:02:33 +0900 Subject: USB: m66592-udc: reduce size of data structure. Poking around with pahole, we see that m66592 handily shoves a u16 in between larger types on 2 separate occasions leaving us with 2 2-byte holes: struct m66592 { ... /* size: 1196, cachelines: 38 */ /* sum members: 1192, holes: 2, sum holes: 4 */ /* last cacheline: 12 bytes */ }; /* definitions: 1 */ Pairing them gets back 4-bytes: struct m66592 { ... /* size: 1192, cachelines: 38 */ /* last cacheline: 8 bytes */ }; /* definitions: 1 */ Unfortunately it's not enough to save a cacheline with this massive structure, but every byte helps. Signed-off-by: Paul Mundt Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/m66592-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 17b792b7f6bf..be0a4c1f80a2 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h @@ -486,10 +486,10 @@ struct m66592 { struct usb_request *ep0_req; /* for internal request */ u16 ep0_data; /* for internal request */ + u16 old_vbus; struct timer_list timer; - u16 old_vbus; int scount; int old_dvsq; -- cgit v1.2.2 From c765d4cad977f7e454a53d5bca5a942156b2d94c Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Sat, 16 Feb 2008 13:44:42 -0800 Subject: USB: EHCI: Refactor "if (handshake()) state = HC_STATE_HALT" Refactor the EHCI "if (handshake()) state = HC_STATE_HALT" idiom, which appears 4 times, by replacing it with calls to a new function called handshake_on_error_set_halt(). Saves a few bytes too. Signed-off-by: Karsten Wiese Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 23 ++++++++++++++--------- drivers/usb/host/ehci-sched.c | 14 ++++++-------- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 360712207262..40f7391bf2aa 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -145,6 +145,16 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, return -ETIMEDOUT; } +static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, + u32 mask, u32 done, int usec) +{ + int error = handshake(ehci, ptr, mask, done, usec); + if (error) + ehci_to_hcd(ehci)->state = HC_STATE_HALT; + + return error; +} + /* force HC to halt state from unknown (EHCI spec section 2.3) */ static int ehci_halt (struct ehci_hcd *ehci) { @@ -217,11 +227,9 @@ static void ehci_quiesce (struct ehci_hcd *ehci) /* wait for any schedule enables/disables to take effect */ temp = ehci_readl(ehci, &ehci->regs->command) << 10; temp &= STS_ASS | STS_PSS; - if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, - temp, 16 * 125) != 0) { - ehci_to_hcd(ehci)->state = HC_STATE_HALT; + if (handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_ASS | STS_PSS, temp, 16 * 125)) return; - } /* then disable anything that's still active */ temp = ehci_readl(ehci, &ehci->regs->command); @@ -229,11 +237,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci) ehci_writel(ehci, temp, &ehci->regs->command); /* hardware can take 16 microframes to turn off ... */ - if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, - 0, 16 * 125) != 0) { - ehci_to_hcd(ehci)->state = HC_STATE_HALT; - return; - } + handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_ASS | STS_PSS, 0, 16 * 125); } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 8a8e08a51ba3..38c606c13db1 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -440,11 +440,10 @@ static int enable_periodic (struct ehci_hcd *ehci) /* did clearing PSE did take effect yet? * takes effect only at frame boundaries... */ - status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125); - if (status != 0) { - ehci_to_hcd(ehci)->state = HC_STATE_HALT; + status = handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_PSS, 0, 9 * 125); + if (status) return status; - } cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; ehci_writel(ehci, cmd, &ehci->regs->command); @@ -465,11 +464,10 @@ static int disable_periodic (struct ehci_hcd *ehci) /* did setting PSE not take effect yet? * takes effect only at frame boundaries... */ - status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); - if (status != 0) { - ehci_to_hcd(ehci)->state = HC_STATE_HALT; + status = handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_PSS, STS_PSS, 9 * 125); + if (status) return status; - } cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; ehci_writel(ehci, cmd, &ehci->regs->command); -- cgit v1.2.2 From 4208978ec4f0d6001facf95be9defccf1a0bf313 Mon Sep 17 00:00:00 2001 From: Savin Zlobec Date: Fri, 15 Feb 2008 13:42:01 +0100 Subject: USB: gadget: Hangup tty on g_serial disconnect On USB cable disconnect g_serial doesn't hangup the port tty, which results in an endless read on the tty device. With the following patch the read and select behave correctly when the cable is unplugged. Tested on at91rm9200 Signed-off-by: Savin Zlobec Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/serial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f5c3896b1d95..433b3f44f42e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -2163,8 +2163,7 @@ static void gs_free_ports(struct gs_dev *dev) port->port_dev = NULL; wake_up_interruptible(&port->port_write_wait); if (port->port_tty) { - wake_up_interruptible(&port->port_tty->read_wait); - wake_up_interruptible(&port->port_tty->write_wait); + tty_hangup(port->port_tty); } spin_unlock_irqrestore(&port->port_lock, flags); } else { -- cgit v1.2.2 From 9544e833f977d1d3e102a070718d613cd234ce8d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 4 Feb 2008 23:57:50 -0800 Subject: USB: io_ti.c: remove pointless eye-candy in debug statements These strings always come up as false positives whenever I'm doing git-conflict fixups (ie: about 1000 times/day). I don't think the zillion "<" and ">" characters are very useful and removing them makes my life that little bit easier. Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index e5ea5ef6335d..63e044adc19a 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1086,12 +1086,11 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { struct ti_i2c_desc *rom_desc; - dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>", __FUNCTION__); + dbg("%s - RUNNING IN DOWNLOAD MODE", __func__); status = TiValidateI2cImage (serial); if (status) { - dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>", - __FUNCTION__); + dbg("%s - DOWNLOAD MODE -- BAD I2C", __func__); return status; } @@ -1345,8 +1344,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) /********************************************************************/ /* Boot Mode */ /********************************************************************/ - dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>>>>>>", - __FUNCTION__); + dbg("%s - RUNNING IN BOOT MODE", __func__); // Configure the TI device so we can use the BULK pipes for download status = TIConfigureBootDevice (serial->serial->dev); @@ -1461,7 +1459,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) StayInBootMode: // Eprom is invalid or blank stay in boot mode - dbg ("%s - <<<<<<<<<<<<<<>>>>>>>>>>>", __FUNCTION__); + dbg("%s - STAYING IN BOOT MODE", __func__); serial->product_info.TiMode = TI_MODE_BOOT; return 0; -- cgit v1.2.2 From 93075544d6c6e9aaa14c44edb6eb3f71144bdeeb Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:14 -0600 Subject: USB: cypress_m8: Feature buffer fixes cypress_m8: Feature buffer fixes From: Mike Isely Don't hardcode the feature buffer size; use sizeof() instead. That way we can easily specify the size in a single spot. Speaking of the feature buffer size, the Cypress app note (and further testing with a DeLorme Earthmate) suggests that this size should be 5 not 8 bytes. Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 779d07851a4d..155b82a25d18 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -290,7 +290,7 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m { int new_baudrate = 0, retval = 0, tries = 0; struct cypress_private *priv; - __u8 feature_buffer[8]; + __u8 feature_buffer[5]; unsigned long flags; dbg("%s", __FUNCTION__); @@ -353,7 +353,7 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m } dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate); - memset(feature_buffer, 0, 8); + memset(feature_buffer, 0, sizeof(feature_buffer)); /* fill the feature_buffer with new configuration */ *((u_int32_t *)feature_buffer) = new_baudrate; @@ -370,16 +370,20 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m feature_buffer[2], feature_buffer[3], feature_buffer[4]); do { - retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), - HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, - 0x0300, 0, feature_buffer, 8, 500); + retval = usb_control_msg(port->serial->dev, + usb_sndctrlpipe(port->serial->dev, 0), + HID_REQ_SET_REPORT, + USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, + 0x0300, 0, feature_buffer, + sizeof(feature_buffer), 500); if (tries++ >= 3) break; - } while (retval != 8 && retval != -ENODEV); + } while (retval != sizeof(feature_buffer) && + retval != -ENODEV); - if (retval != 8) { + if (retval != sizeof(feature_buffer)) { err("%s - failed sending serial line settings - %d", __FUNCTION__, retval); cypress_set_dead(port); } else { @@ -393,19 +397,23 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m case CYPRESS_GET_CONFIG: dbg("%s - retreiving serial line settings", __FUNCTION__); /* set initial values in feature buffer */ - memset(feature_buffer, 0, 8); + memset(feature_buffer, 0, sizeof(feature_buffer)); do { - retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), - HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, - 0x0300, 0, feature_buffer, 8, 500); - + retval = usb_control_msg(port->serial->dev, + usb_rcvctrlpipe(port->serial->dev, 0), + HID_REQ_GET_REPORT, + USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, + 0x0300, 0, feature_buffer, + sizeof(feature_buffer), 500); + if (tries++ >= 3) break; - } while (retval != 5 && retval != -ENODEV); + } while (retval != sizeof(feature_buffer) && + retval != -ENODEV); - if (retval != 5) { + if (retval != sizeof(feature_buffer)) { err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval); cypress_set_dead(port); return retval; -- cgit v1.2.2 From 3416eaa1f8f8d516b77de514e14cf8da256d28fb Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:19 -0600 Subject: USB: cypress_m8: Packet format is separate from characteristic size cypress_m8: Packet format is separate from characteristic size The Cypress app note states that when using an 8 byte packet buffer size that the packet format is modified (to be more compact). However I have since discovered that newer DeLorme Earthmate LT-20 devices (those that are low speed USB with 8 byte packet size) STILL use the format that is really supposed to correspond to 32 byte packets. Further confusing things is the subsequent discovery that there are actually two different types of LT-20 - older LT-20's use 32 byte packets which is probably why this issue wasn't originally encountered. The solution here is to flag the packet format separately from the buffer size. Then at initialization time, identify the correct combination and set it up. This is a critical fix for anyone with a newer LT-20. Older devices and non-Earthmate devices should remain unaffected by this change. (If other devices behave in this, uh, unexpected manner, it's now just a simple 1 line change to fix them as well (change the pkt_fmt member for that device). Default behavior with this patch is still to drive the format as per the app-note; of course for Earthmate devices this is overridden. Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 111 ++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 155b82a25d18..c42d3bdbe98c 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -122,6 +122,11 @@ static struct usb_driver cypress_driver = { .no_dynamic_id = 1, }; +enum packet_format { + packet_format_1, /* b0:status, b1:payload count */ + packet_format_2 /* b0[7:3]:status, b0[2:0]:payload count */ +}; + struct cypress_private { spinlock_t lock; /* private lock */ int chiptype; /* identifier of device, for quirks/etc */ @@ -139,6 +144,7 @@ struct cypress_private { __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ __u8 current_config; /* stores the current configuration byte */ __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ + enum packet_format pkt_fmt; /* format to use for packet send / receive */ int baud_rate; /* stores current baud rate in integer form */ int cbr_mask; /* stores current baud rate in masked form */ int isthrottled; /* if throttled, discard reads */ @@ -532,6 +538,17 @@ static int generic_startup (struct usb_serial *serial) priv->termios_initialized = 0; priv->rx_flags = 0; priv->cbr_mask = B300; + /* Default packet format setting is determined by packet size. + Anything with a size larger then 9 must have a separate + count field since the 3 bit count field is otherwise too + small. Otherwise we can use the slightly more compact + format. This is in accordance with the cypress_m8 serial + converter app note. */ + if (port->interrupt_out_size > 9) { + priv->pkt_fmt = packet_format_1; + } else { + priv->pkt_fmt = packet_format_2; + } if (interval > 0) { priv->write_urb_interval = interval; priv->read_urb_interval = interval; @@ -564,6 +581,9 @@ static int cypress_earthmate_startup (struct usb_serial *serial) priv = usb_get_serial_port_data(serial->port[0]); priv->chiptype = CT_EARTHMATE; + /* All Earthmate devices use the separated-count packet + format! Idiotic. */ + priv->pkt_fmt = packet_format_1; return 0; } /* cypress_earthmate_startup */ @@ -811,21 +831,18 @@ static void cypress_send(struct usb_serial_port *port) memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size); spin_lock_irqsave(&priv->lock, flags); - switch (port->interrupt_out_size) { - case 32: - /* this is for the CY7C64013... */ - offset = 2; - port->interrupt_out_buffer[0] = priv->line_control; - break; - case 8: - /* this is for the CY7C63743... */ - offset = 1; - port->interrupt_out_buffer[0] = priv->line_control; - break; - default: - dbg("%s - wrong packet size", __FUNCTION__); - spin_unlock_irqrestore(&priv->lock, flags); - return; + switch (priv->pkt_fmt) { + default: + case packet_format_1: + /* this is for the CY7C64013... */ + offset = 2; + port->interrupt_out_buffer[0] = priv->line_control; + break; + case packet_format_2: + /* this is for the CY7C63743... */ + offset = 1; + port->interrupt_out_buffer[0] = priv->line_control; + break; } if (priv->line_control & CONTROL_RESET) @@ -846,12 +863,13 @@ static void cypress_send(struct usb_serial_port *port) return; } - switch (port->interrupt_out_size) { - case 32: - port->interrupt_out_buffer[1] = count; - break; - case 8: - port->interrupt_out_buffer[0] |= count; + switch (priv->pkt_fmt) { + default: + case packet_format_1: + port->interrupt_out_buffer[1] = count; + break; + case packet_format_2: + port->interrupt_out_buffer[0] |= count; } dbg("%s - count is %d", __FUNCTION__, count); @@ -864,8 +882,9 @@ send: if (priv->cmd_ctrl) actual_size = 1; else - actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1); - + actual_size = count + + (priv->pkt_fmt == packet_format_1 ? 2 : 1); + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size, port->interrupt_out_urb->transfer_buffer); @@ -1331,30 +1350,32 @@ static void cypress_read_int_callback(struct urb *urb) } spin_lock_irqsave(&priv->lock, flags); - switch(urb->actual_length) { - case 32: - /* This is for the CY7C64013... */ - priv->current_status = data[0] & 0xF8; - bytes = data[1] + 2; - i = 2; - if (bytes > 2) - havedata = 1; - break; - case 8: - /* This is for the CY7C63743... */ - priv->current_status = data[0] & 0xF8; - bytes = (data[0] & 0x07) + 1; - i = 1; - if (bytes > 1) - havedata = 1; - break; - default: - dbg("%s - wrong packet size - received %d bytes", - __FUNCTION__, urb->actual_length); - spin_unlock_irqrestore(&priv->lock, flags); - goto continue_read; + result = urb->actual_length; + switch (priv->pkt_fmt) { + default: + case packet_format_1: + /* This is for the CY7C64013... */ + priv->current_status = data[0] & 0xF8; + bytes = data[1] + 2; + i = 2; + if (bytes > 2) + havedata = 1; + break; + case packet_format_2: + /* This is for the CY7C63743... */ + priv->current_status = data[0] & 0xF8; + bytes = (data[0] & 0x07) + 1; + i = 1; + if (bytes > 1) + havedata = 1; + break; } spin_unlock_irqrestore(&priv->lock, flags); + if (result < bytes) { + dbg("%s - wrong packet size - received %d bytes but packet " + "said %d bytes", __func__, result, bytes); + goto continue_read; + } usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data); -- cgit v1.2.2 From 3d6aa3206540e1e68bda9e8ea11ec71444f1ac71 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:24 -0600 Subject: USB: cypress_m8: Don't issue GET_CONFIG for certain devices Earthmate LT-20 devices (both "old" and "new" versions) can't tolerate a GET_CONFIG command. The original Earthmate has no trouble with this. Presumably other non-Earthmate devices are still OK as well. This change disables the use of GET_CONFIG for cases where it is known not to work. Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index c42d3bdbe98c..f0c5d2a7ab94 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -145,6 +145,7 @@ struct cypress_private { __u8 current_config; /* stores the current configuration byte */ __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ enum packet_format pkt_fmt; /* format to use for packet send / receive */ + int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ int baud_rate; /* stores current baud rate in integer form */ int cbr_mask; /* stores current baud rate in masked form */ int isthrottled; /* if throttled, discard reads */ @@ -401,6 +402,12 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m } break; case CYPRESS_GET_CONFIG: + if (priv->get_cfg_unsafe) { + /* Not implemented for this device, + and if we try to do it we're likely + to crash the hardware. */ + return -ENOTTY; + } dbg("%s - retreiving serial line settings", __FUNCTION__); /* set initial values in feature buffer */ memset(feature_buffer, 0, sizeof(feature_buffer)); @@ -570,20 +577,30 @@ static int generic_startup (struct usb_serial *serial) static int cypress_earthmate_startup (struct usb_serial *serial) { struct cypress_private *priv; + struct usb_serial_port *port = serial->port[0]; dbg("%s", __FUNCTION__); if (generic_startup(serial)) { dbg("%s - Failed setting up port %d", __FUNCTION__, - serial->port[0]->number); + port->number); return 1; } - priv = usb_get_serial_port_data(serial->port[0]); + priv = usb_get_serial_port_data(port); priv->chiptype = CT_EARTHMATE; /* All Earthmate devices use the separated-count packet format! Idiotic. */ priv->pkt_fmt = packet_format_1; + if (serial->dev->descriptor.idProduct != PRODUCT_ID_EARTHMATEUSB) { + /* The old original USB Earthmate seemed able to + handle GET_CONFIG requests; everything they've + produced since that time crashes if this command is + attempted :-( */ + dbg("%s - Marking this device as unsafe for GET_CONFIG " + "commands", __func__); + priv->get_cfg_unsafe = !0; + } return 0; } /* cypress_earthmate_startup */ -- cgit v1.2.2 From 6768306c3d9568bc66dc22f8b863bfbda3e7c4d2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:28 -0600 Subject: USB: cypress_m8: Get rid of pointless NULL check Remove a NULL check in cypress_m8; the check is useless in this context because it is referenced earlier in the same code path thus the kernel would be oops'ed before reaching this point anyway. (And it's really pointless here anyway; if this pointer somehow is NULL the driver is going to have serious problems in many other places.) Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index f0c5d2a7ab94..bdeda0936951 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -1399,13 +1399,11 @@ static void cypress_read_int_callback(struct urb *urb) spin_lock_irqsave(&priv->lock, flags); /* check to see if status has changed */ - if (priv != NULL) { - if (priv->current_status != priv->prev_status) { - priv->diff_status |= priv->current_status ^ - priv->prev_status; - wake_up_interruptible(&priv->delta_msr_wait); - priv->prev_status = priv->current_status; - } + if (priv->current_status != priv->prev_status) { + priv->diff_status |= priv->current_status ^ + priv->prev_status; + wake_up_interruptible(&priv->delta_msr_wait); + priv->prev_status = priv->current_status; } spin_unlock_irqrestore(&priv->lock, flags); -- cgit v1.2.2 From 92983c2121fb46f234add1c36b5e596779899d56 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 10 Feb 2008 20:23:32 -0600 Subject: USB: cypress_m8: Limit baud rate to <=4800 for USB low speed devices The cypress app note for the M8 states that for the USB low speed version of the part, throughput is effectively limited to 800 bytes/sec. So if we were to try a faster baud rate in such cases then we risk overrun errors on receive. Best to just identify this case and limit the rate to 4800 baud or less (by ignoring any request to set a faster rate). The old baud rate setting code was somewhat fragile; this change also hopefully makes it easier in the future to better checking / limiting. Signed-off-by: Mike Isely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 104 +++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index bdeda0936951..4bf45c711b9d 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -291,6 +291,59 @@ static struct usb_serial_driver cypress_ca42v2_device = { *****************************************************************************/ +static int analyze_baud_rate(struct usb_serial_port *port, unsigned baud_mask) +{ + int new_rate; + struct cypress_private *priv; + priv = usb_get_serial_port_data(port); + + /* + * The general purpose firmware for the Cypress M8 allows for + * a maximum speed of 57600bps (I have no idea whether DeLorme + * chose to use the general purpose firmware or not), if you + * need to modify this speed setting for your own project + * please add your own chiptype and modify the code likewise. + * The Cypress HID->COM device will work successfully up to + * 115200bps (but the actual throughput is around 3kBps). + */ + new_rate = mask_to_rate(baud_mask); + if (new_rate < 0) { + dbg("%s - failed setting baud rate, untranslatable speed", + __func__); + return -1; + } + if (port->serial->dev->speed == USB_SPEED_LOW) { + /* + * Mike Isely 2-Feb-2008: The + * Cypress app note that describes this mechanism + * states the the low-speed part can't handle more + * than 800 bytes/sec, in which case 4800 baud is the + * safest speed for a part like that. + */ + if (new_rate > 4800) { + dbg("%s - failed setting baud rate, device incapable " + "speed %d", __func__, new_rate); + return -1; + } + } + switch (priv->chiptype) { + case CT_EARTHMATE: + if (new_rate <= 600) { + /* 300 and 600 baud rates are supported under + * the generic firmware, but are not used with + * NMEA and SiRF protocols */ + dbg("%s - failed setting baud rate, unsupported speed " + "of %d on Earthmate GPS", __func__, new_rate); + return -1; + } + break; + default: + break; + } + return new_rate; +} + + /* This function can either set or retrieve the current serial line settings */ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits, int parity_enable, int parity_type, int reset, int cypress_request_type) @@ -309,54 +362,15 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m switch(cypress_request_type) { case CYPRESS_SET_CONFIG: - - /* - * The general purpose firmware for the Cypress M8 allows for a maximum speed - * of 57600bps (I have no idea whether DeLorme chose to use the general purpose - * firmware or not), if you need to modify this speed setting for your own - * project please add your own chiptype and modify the code likewise. The - * Cypress HID->COM device will work successfully up to 115200bps (but the - * actual throughput is around 3kBps). - */ + new_baudrate = priv->baud_rate; if (baud_mask != priv->cbr_mask) { dbg("%s - baud rate is changing", __FUNCTION__); - if ( priv->chiptype == CT_EARTHMATE ) { - /* 300 and 600 baud rates are supported under the generic firmware, - * but are not used with NMEA and SiRF protocols */ - - if ( (baud_mask == B300) || (baud_mask == B600) ) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } - } else if (priv->chiptype == CT_CYPHIDCOM) { - if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } - } else if (priv->chiptype == CT_CA42V2) { - if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } - } else if (priv->chiptype == CT_GENERIC) { - if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { - err("%s - failed setting baud rate, unsupported speed", - __FUNCTION__); - new_baudrate = priv->baud_rate; - } - } else { - info("%s - please define your chiptype", __FUNCTION__); - new_baudrate = priv->baud_rate; + retval = analyze_baud_rate(port, baud_mask); + if (retval >= 0) { + new_baudrate = retval; + dbg("%s - New baud rate set to %d", + __func__, new_baudrate); } - } else { /* baud rate not changing, keep the old */ - new_baudrate = priv->baud_rate; } dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate); -- cgit v1.2.2 From b994d7f70ae59b874843fa2bc9a28b17b41febd5 Mon Sep 17 00:00:00 2001 From: "matthias@kaehlcke.net" Date: Mon, 18 Feb 2008 20:45:34 +0100 Subject: USB: auerswald: Convert stats_sem in a mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semaphore cp->mutex is used as mutex, convert it to the mutex API Signed-off-by: Matthias Kaehlcke Cc: Wolfgang Mües Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/auerswald.c | 45 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index df7e1ecc810a..498fd4789921 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -31,6 +31,7 @@ #include #include #include +#include /*-------------------------------------------------------------------*/ /* Debug support */ @@ -232,7 +233,7 @@ typedef struct auerscon /* USB device context */ typedef struct { - struct semaphore mutex; /* protection in user context */ + struct mutex mutex; /* protection in user context */ char name[20]; /* name of the /dev/usb entry */ unsigned int dtindex; /* index in the device table */ struct usb_device * usbdev; /* USB device handle */ @@ -1376,7 +1377,7 @@ static int auerchar_open (struct inode *inode, struct file *file) if (cp == NULL) { return -ENODEV; } - if (down_interruptible (&cp->mutex)) { + if (mutex_lock_interruptible(&cp->mutex)) { return -ERESTARTSYS; } @@ -1405,7 +1406,7 @@ static int auerchar_open (struct inode *inode, struct file *file) cp->open_count++; ccp->auerdev = cp; dbg("open %s as /dev/%s", cp->dev_desc, cp->name); - up (&cp->mutex); + mutex_unlock(&cp->mutex); /* file IO stuff */ file->f_pos = 0; @@ -1413,7 +1414,7 @@ static int auerchar_open (struct inode *inode, struct file *file) return nonseekable_open(inode, file); /* Error exit */ -ofail: up (&cp->mutex); +ofail: mutex_unlock(&cp->mutex); auerchar_delete (ccp); return ret; } @@ -1440,14 +1441,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int up (&ccp->mutex); return -ENODEV; } - if (down_interruptible (&cp->mutex)) { + if (mutex_lock_interruptible(&cp->mutex)) { up(&ccp->mutex); return -ERESTARTSYS; } /* Check for removal */ if (!cp->usbdev) { - up(&cp->mutex); + mutex_unlock(&cp->mutex); up(&ccp->mutex); return -ENODEV; } @@ -1550,7 +1551,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int break; } /* release the mutexes */ - up(&cp->mutex); + mutex_unlock(&cp->mutex); up(&ccp->mutex); return ret; } @@ -1721,12 +1722,12 @@ write_again: up (&ccp->mutex); return -ERESTARTSYS; } - if (down_interruptible (&cp->mutex)) { + if (mutex_lock_interruptible(&cp->mutex)) { up (&ccp->mutex); return -ERESTARTSYS; } if (!cp->usbdev) { - up (&cp->mutex); + mutex_unlock(&cp->mutex); up (&ccp->mutex); return -EIO; } @@ -1750,7 +1751,7 @@ write_again: /* are there any buffers left? */ if (!bp) { - up (&cp->mutex); + mutex_unlock(&cp->mutex); up (&ccp->mutex); /* NONBLOCK: don't wait */ @@ -1783,7 +1784,7 @@ write_again: auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); - up (&cp->mutex); + mutex_unlock(&cp->mutex); up (&ccp->mutex); return -EFAULT; } @@ -1803,7 +1804,7 @@ write_again: auerchar_ctrlwrite_complete, bp); /* up we go */ ret = auerchain_submit_urb (&cp->controlchain, bp->urbp); - up (&cp->mutex); + mutex_unlock(&cp->mutex); if (ret) { dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret); auerbuf_releasebuf (bp); @@ -1830,16 +1831,16 @@ static int auerchar_release (struct inode *inode, struct file *file) down(&ccp->mutex); cp = ccp->auerdev; if (cp) { - down(&cp->mutex); + mutex_lock(&cp->mutex); /* remove an open service */ auerswald_removeservice (cp, &ccp->scontext); /* detach from device */ if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) { /* usb device waits for removal */ - up (&cp->mutex); + mutex_unlock(&cp->mutex); auerswald_delete (cp); } else { - up (&cp->mutex); + mutex_unlock(&cp->mutex); } cp = NULL; ccp->auerdev = NULL; @@ -1917,7 +1918,7 @@ static int auerswald_probe (struct usb_interface *intf, } /* Initialize device descriptor */ - init_MUTEX (&cp->mutex); + mutex_init(&cp->mutex); cp->usbdev = usbdev; auerchain_init (&cp->controlchain); auerbuf_init (&cp->bufctl); @@ -2042,7 +2043,7 @@ static void auerswald_disconnect (struct usb_interface *intf) /* give back our USB minor number */ usb_deregister_dev(intf, &auerswald_class); - down (&cp->mutex); + mutex_lock(&cp->mutex); info ("device /dev/%s now disconnecting", cp->name); /* Stop the interrupt endpoint */ @@ -2057,16 +2058,18 @@ static void auerswald_disconnect (struct usb_interface *intf) if (cp->open_count == 0) { /* nobody is using this device. So we can clean up now */ - up (&cp->mutex);/* up() is possible here because no other task - can open the device (see above). I don't want - to kfree() a locked mutex. */ + mutex_unlock(&cp->mutex); + /* mutex_unlock() is possible here because no other task + can open the device (see above). I don't want + to kfree() a locked mutex. */ + auerswald_delete (cp); } else { /* device is used. Remove the pointer to the usb device (it's not valid any more). The last release() will do the clean up */ cp->usbdev = NULL; - up (&cp->mutex); + mutex_unlock(&cp->mutex); /* Terminate waiting writers */ wake_up (&cp->bufferwait); /* Inform all waiting readers */ -- cgit v1.2.2 From 8a0f46b92fcab6652b8e62c006d015d562302d08 Mon Sep 17 00:00:00 2001 From: "matthias@kaehlcke.net" Date: Mon, 18 Feb 2008 20:45:35 +0100 Subject: USB: auerswald: Convert ccp->readmutex in a mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semaphore ccp->readmutex is used as mutex, convert it to the mutex API Signed-off-by: Matthias Kaehlcke Cc: Wolfgang Mües Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/auerswald.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 498fd4789921..46dfbac0f6f0 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -259,7 +259,7 @@ typedef struct auerbufctl_t bufctl; /* controls the buffer chain */ auerscon_t scontext; /* service context */ wait_queue_head_t readwait; /* for synchronous reading */ - struct semaphore readmutex; /* protection against multiple reads */ + struct mutex readmutex; /* protection against multiple reads */ pauerbuf_t readbuf; /* buffer held for partial reading */ unsigned int readoffset; /* current offset in readbuf */ unsigned int removed; /* is != 0 if device is removed */ @@ -1391,7 +1391,7 @@ static int auerchar_open (struct inode *inode, struct file *file) /* Initialize device descriptor */ init_MUTEX( &ccp->mutex); - init_MUTEX( &ccp->readmutex); + mutex_init(&ccp->readmutex); auerbuf_init (&ccp->bufctl); ccp->scontext.id = AUH_UNASSIGNED; ccp->scontext.dispatch = auerchar_ctrlread_dispatch; @@ -1585,7 +1585,7 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, } /* only one reader per device allowed */ - if (down_interruptible (&ccp->readmutex)) { + if (mutex_lock_interruptible(&ccp->readmutex)) { up (&ccp->mutex); return -ERESTARTSYS; } @@ -1603,7 +1603,7 @@ doreadbuf: if (count) { if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) { dbg ("auerswald_read: copy_to_user failed"); - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); up (&ccp->mutex); return -EFAULT; } @@ -1618,7 +1618,7 @@ doreadbuf: } /* return with number of bytes read */ if (count) { - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); up (&ccp->mutex); return count; } @@ -1655,7 +1655,7 @@ doreadlist: dbg ("No read buffer available, returning -EAGAIN"); set_current_state (TASK_RUNNING); remove_wait_queue (&ccp->readwait, &wait); - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); up (&ccp->mutex); return -EAGAIN; /* nonblocking, no data available */ } @@ -1666,18 +1666,18 @@ doreadlist: remove_wait_queue (&ccp->readwait, &wait); if (signal_pending (current)) { /* waked up by a signal */ - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); return -ERESTARTSYS; } /* Anything left to read? */ if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) { - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); return -EIO; } if (down_interruptible (&ccp->mutex)) { - up (&ccp->readmutex); + mutex_unlock(&ccp->readmutex); return -ERESTARTSYS; } -- cgit v1.2.2 From fadec78bd93ede132c34ab94dce0e65a5ae56054 Mon Sep 17 00:00:00 2001 From: "matthias@kaehlcke.net" Date: Mon, 18 Feb 2008 20:45:36 +0100 Subject: USB: auerswald: Convert ccp->mutex in a mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semaphore ccp->mutex is used as mutex, convert it to the mutex API Signed-off-by: Matthias Kaehlcke Cc: Wolfgang Mües Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/auerswald.c | 52 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 46dfbac0f6f0..81d051ca2291 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -254,7 +254,7 @@ typedef struct /* character device context */ typedef struct { - struct semaphore mutex; /* protection in user context */ + struct mutex mutex; /* protection in user context */ pauerswald_t auerdev; /* context pointer of assigned device */ auerbufctl_t bufctl; /* controls the buffer chain */ auerscon_t scontext; /* service context */ @@ -1390,7 +1390,7 @@ static int auerchar_open (struct inode *inode, struct file *file) } /* Initialize device descriptor */ - init_MUTEX( &ccp->mutex); + mutex_init(&ccp->mutex); mutex_init(&ccp->readmutex); auerbuf_init (&ccp->bufctl); ccp->scontext.id = AUH_UNASSIGNED; @@ -1433,23 +1433,23 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int dbg ("ioctl"); /* get the mutexes */ - if (down_interruptible (&ccp->mutex)) { + if (mutex_lock_interruptible(&ccp->mutex)) { return -ERESTARTSYS; } cp = ccp->auerdev; if (!cp) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ENODEV; } if (mutex_lock_interruptible(&cp->mutex)) { - up(&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ERESTARTSYS; } /* Check for removal */ if (!cp->usbdev) { mutex_unlock(&cp->mutex); - up(&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ENODEV; } @@ -1552,7 +1552,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int } /* release the mutexes */ mutex_unlock(&cp->mutex); - up(&ccp->mutex); + mutex_unlock(&ccp->mutex); return ret; } @@ -1575,18 +1575,18 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, return 0; /* get the mutex */ - if (down_interruptible (&ccp->mutex)) + if (mutex_lock_interruptible(&ccp->mutex)) return -ERESTARTSYS; /* Can we expect to read something? */ if (ccp->scontext.id == AUH_UNASSIGNED) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EIO; } /* only one reader per device allowed */ if (mutex_lock_interruptible(&ccp->readmutex)) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ERESTARTSYS; } @@ -1604,7 +1604,7 @@ doreadbuf: if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) { dbg ("auerswald_read: copy_to_user failed"); mutex_unlock(&ccp->readmutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EFAULT; } } @@ -1619,7 +1619,7 @@ doreadbuf: /* return with number of bytes read */ if (count) { mutex_unlock(&ccp->readmutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return count; } } @@ -1656,12 +1656,12 @@ doreadlist: set_current_state (TASK_RUNNING); remove_wait_queue (&ccp->readwait, &wait); mutex_unlock(&ccp->readmutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EAGAIN; /* nonblocking, no data available */ } /* yes, we should wait! */ - up (&ccp->mutex); /* allow other operations while we wait */ + mutex_unlock(&ccp->mutex); /* allow other operations while we wait */ schedule(); remove_wait_queue (&ccp->readwait, &wait); if (signal_pending (current)) { @@ -1676,7 +1676,7 @@ doreadlist: return -EIO; } - if (down_interruptible (&ccp->mutex)) { + if (mutex_lock_interruptible(&ccp->mutex)) { mutex_unlock(&ccp->readmutex); return -ERESTARTSYS; } @@ -1708,27 +1708,27 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t write_again: /* get the mutex */ - if (down_interruptible (&ccp->mutex)) + if (mutex_lock_interruptible(&ccp->mutex)) return -ERESTARTSYS; /* Can we expect to write something? */ if (ccp->scontext.id == AUH_UNASSIGNED) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EIO; } cp = ccp->auerdev; if (!cp) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ERESTARTSYS; } if (mutex_lock_interruptible(&cp->mutex)) { - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -ERESTARTSYS; } if (!cp->usbdev) { mutex_unlock(&cp->mutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EIO; } /* Prepare for sleep */ @@ -1752,7 +1752,7 @@ write_again: /* are there any buffers left? */ if (!bp) { mutex_unlock(&cp->mutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); /* NONBLOCK: don't wait */ if (file->f_flags & O_NONBLOCK) { @@ -1785,7 +1785,7 @@ write_again: /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); mutex_unlock(&cp->mutex); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EFAULT; } @@ -1810,12 +1810,12 @@ write_again: auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return -EIO; } else { dbg ("auerchar_write: Write OK"); - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); return len; } } @@ -1828,7 +1828,7 @@ static int auerchar_release (struct inode *inode, struct file *file) pauerswald_t cp; dbg("release"); - down(&ccp->mutex); + mutex_lock(&ccp->mutex); cp = ccp->auerdev; if (cp) { mutex_lock(&cp->mutex); @@ -1845,7 +1845,7 @@ static int auerchar_release (struct inode *inode, struct file *file) cp = NULL; ccp->auerdev = NULL; } - up (&ccp->mutex); + mutex_unlock(&ccp->mutex); auerchar_delete (ccp); return 0; -- cgit v1.2.2 From 3d01f0fe6b66dd34511eaf35e06764b8997187bc Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Tue, 19 Feb 2008 12:31:49 -0800 Subject: USB: minor ehci xITD simplifications Remove two (or one) conditional tests in per-urb isochronous transfer setup code paths. Signed-off-by: Karsten Wiese Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 38c606c13db1..e3cfe0a03552 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1181,21 +1181,18 @@ itd_urb_transaction ( struct ehci_itd, itd_list); list_del (&itd->itd_list); itd_dma = itd->itd_dma; - } else - itd = NULL; - - if (!itd) { + } else { spin_unlock_irqrestore (&ehci->lock, flags); itd = dma_pool_alloc (ehci->itd_pool, mem_flags, &itd_dma); spin_lock_irqsave (&ehci->lock, flags); + if (!itd) { + iso_sched_free(stream, sched); + spin_unlock_irqrestore(&ehci->lock, flags); + return -ENOMEM; + } } - if (unlikely (NULL == itd)) { - iso_sched_free (stream, sched); - spin_unlock_irqrestore (&ehci->lock, flags); - return -ENOMEM; - } memset (itd, 0, sizeof *itd); itd->itd_dma = itd_dma; list_add (&itd->itd_list, &sched->td_list); @@ -1814,21 +1811,18 @@ sitd_urb_transaction ( struct ehci_sitd, sitd_list); list_del (&sitd->sitd_list); sitd_dma = sitd->sitd_dma; - } else - sitd = NULL; - - if (!sitd) { + } else { spin_unlock_irqrestore (&ehci->lock, flags); sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags, &sitd_dma); spin_lock_irqsave (&ehci->lock, flags); + if (!sitd) { + iso_sched_free(stream, iso_sched); + spin_unlock_irqrestore(&ehci->lock, flags); + return -ENOMEM; + } } - if (!sitd) { - iso_sched_free (stream, iso_sched); - spin_unlock_irqrestore (&ehci->lock, flags); - return -ENOMEM; - } memset (sitd, 0, sizeof *sitd); sitd->sitd_dma = sitd_dma; list_add (&sitd->sitd_list, &iso_sched->td_list); -- cgit v1.2.2 From 2097890c43a8fe90763f31b0010fd6963f5512c8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 20:47:56 +0000 Subject: USB: usb-serial: Prepare for BKL push down Take the lock in usb-serial instead. As it relies on the BKL internally we can't push it any deeper yet. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2138ba8aeb69..aea861e9173e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -401,11 +401,13 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in struct usb_serial_port *port = tty->driver_data; int retval = -ENODEV; + lock_kernel(); if (!port) goto exit; dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + /* Caution - port->open_count is BKL protected */ if (!port->open_count) { dbg ("%s - port not open", __FUNCTION__); goto exit; @@ -416,8 +418,8 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in retval = port->serial->type->ioctl(port, file, cmd, arg); else retval = -ENOIOCTLCMD; - exit: + unlock_kernel(); return retval; } @@ -446,19 +448,24 @@ static void serial_break (struct tty_struct *tty, int break_state) { struct usb_serial_port *port = tty->driver_data; - if (!port) + lock_kernel(); + if (!port) { + unlock_kernel(); return; + } dbg("%s - port %d", __FUNCTION__, port->number); if (!port->open_count) { dbg("%s - port not open", __FUNCTION__); + unlock_kernel(); return; } /* pass on to the driver specific version of this function if it is available */ if (port->serial->type->break_ctl) port->serial->type->break_ctl(port, break_state); + unlock_kernel(); } static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) -- cgit v1.2.2 From 9b0f2582d57d4c9081307c86e11afc9169de7d3e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 20:49:53 +0000 Subject: USB: ftdi_sio: Note missing locking The ftdi_sio driver has no internal locking on the dtr/rts state. Flag that up for someone to fix. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3abb3c863647..4643212eb959 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -533,9 +533,8 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned } buf = kmalloc(1, GFP_NOIO); - if (!buf) { + if (!buf) return -ENOMEM; - } clear &= ~set; /* 'set' takes precedence over 'clear' */ urb_value = 0; @@ -568,6 +567,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); + /* FIXME: locking on last_dtr_rts */ priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; } return rv; -- cgit v1.2.2 From e298449401463dd18f24a87c48f9b0ec62bad936 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 20:51:45 +0000 Subject: USB: serial: Note mos7480 and option don't lock modem status Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 1 + drivers/usb/serial/option.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index aeeb9cb20999..0b29c5383dc8 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1722,6 +1722,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, if (mos7840_port == NULL) return -ENODEV; + /* FIXME: What locks the port registers ? */ mcr = mos7840_port->shadowMCR; if (clear & TIOCM_RTS) mcr &= ~MCR_RTS; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d101025a4c63..0e7eeb2820e2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -458,6 +458,7 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file, portdata = usb_get_serial_port_data(port); + /* FIXME: what locks portdata fields ? */ if (set & TIOCM_RTS) portdata->rts_state = 1; if (set & TIOCM_DTR) -- cgit v1.2.2 From 7b1fc8bc6d6881ff7f8876cbe665b3ad5271bc03 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 21:39:25 +0000 Subject: USB: iuu_phoenix: lock priv->tiostatus properly Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/iuu_phoenix.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index fde188e23ce1..a09b9a85b16d 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -148,20 +148,21 @@ static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear) { struct iuu_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - tty = port->tty; + unsigned long flags; + /* FIXME: locking on tiomstatus */ dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__, port->number, set, clear); + + spin_lock_irqsave(&priv->lock, flags); if (set & TIOCM_RTS) priv->tiostatus = TIOCM_RTS; if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { dbg("%s TIOCMSET RESET called !!!", __FUNCTION__); priv->reset = 1; - return 0; } - + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -173,7 +174,14 @@ static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) { struct iuu_private *priv = usb_get_serial_port_data(port); - return priv->tiostatus; + unsigned long flags; + int rc; + + spin_lock_irqsave(&priv->lock, flags); + rc = priv->tiostatus; + spin_unlock_irqrestore(&priv->lock, flags); + + return rc; } static void iuu_rxcmd(struct urb *urb) -- cgit v1.2.2 From a40d8540f4b7874ef674428cf757e8f466d271ca Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 21:40:34 +0000 Subject: USB: kobil_sct: Get rid of unneeded priv->line_state Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/kobil_sct.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 17b3baead4ad..03cb5dd8cbe3 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -139,7 +139,6 @@ struct kobil_private { int filled; // index of the last char in buf int cur_pos; // index of the next char to send in buf __u16 device_type; - int line_state; }; @@ -161,7 +160,6 @@ static int kobil_startup (struct usb_serial *serial) priv->filled = 0; priv->cur_pos = 0; priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct); - priv->line_state = 0; switch (priv->device_type){ case KOBIL_ADAPTER_B_PRODUCT_ID: @@ -226,7 +224,6 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) dbg("%s - port %d", __FUNCTION__, port->number); priv = usb_get_serial_port_data(port); - priv->line_state = 0; // someone sets the dev to 0 if the close method has been called port->interrupt_in_urb->dev = port->serial->dev; @@ -524,14 +521,11 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", __FUNCTION__, port->number, result, transfer_buffer[0]); - if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) { - priv->line_state |= TIOCM_DSR; - } else { - priv->line_state &= ~TIOCM_DSR; - } - + result = 0; + if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) + result = TIOCM_DSR; kfree(transfer_buffer); - return priv->line_state; + return result; } static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, @@ -544,6 +538,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, unsigned char *transfer_buffer; int transfer_buffer_length = 8; + /* FIXME: locking ? */ priv = usb_get_serial_port_data(port); if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { // This device doesn't support ioctl calls -- cgit v1.2.2 From 04ca89d4948ad4b6ec3b33e9588ae1885643148c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 21:41:40 +0000 Subject: USB: ti_usb_3410_5052: Extend locking to msr and shadow mcr Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 3a3776677339..5b470f76e91b 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1021,14 +1021,17 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int result; unsigned int msr; unsigned int mcr; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); if (tport == NULL) return -ENODEV; + spin_lock_irqsave(&tport->tp_lock, flags); msr = tport->tp_msr; mcr = tport->tp_shadow_mcr; + spin_unlock_irqrestore(&tport->tp_lock, flags); result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0) | ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0) @@ -1049,12 +1052,14 @@ static int ti_tiocmset(struct usb_serial_port *port, struct file *file, { struct ti_port *tport = usb_get_serial_port_data(port); unsigned int mcr; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); if (tport == NULL) return -ENODEV; + spin_lock_irqsave(&tport->tp_lock, flags); mcr = tport->tp_shadow_mcr; if (set & TIOCM_RTS) @@ -1070,6 +1075,7 @@ static int ti_tiocmset(struct usb_serial_port *port, struct file *file, mcr &= ~TI_MCR_DTR; if (clear & TIOCM_LOOP) mcr &= ~TI_MCR_LOOP; + spin_unlock_irqrestore(&tport->tp_lock, flags); return ti_set_mcr(tport, mcr); } @@ -1357,14 +1363,17 @@ static void ti_send(struct ti_port *tport) static int ti_set_mcr(struct ti_port *tport, unsigned int mcr) { + unsigned long flags; int status; status = ti_write_byte(tport->tp_tdev, tport->tp_uart_base_addr + TI_UART_OFFSET_MCR, TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr); + spin_lock_irqsave(&tport->tp_lock, flags); if (!status) tport->tp_shadow_mcr = mcr; + spin_unlock_irqrestore(&tport->tp_lock, flags); return status; } -- cgit v1.2.2 From 3d71fe0bb29a3fbffdbe69dd0696927b6a23dd4e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 21:38:32 +0000 Subject: USB: io_ti: lock mcr and msr shadows properly Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 63e044adc19a..39d71fdb5071 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2559,9 +2559,11 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig { struct edgeport_port *edge_port = usb_get_serial_port_data(port); unsigned int mcr; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); + spin_lock_irqsave(&edge_port->ep_lock, flags); mcr = edge_port->shadow_mcr; if (set & TIOCM_RTS) mcr |= MCR_RTS; @@ -2578,6 +2580,7 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig mcr &= ~MCR_LOOPBACK; edge_port->shadow_mcr = mcr; + spin_unlock_irqrestore(&edge_port->ep_lock, flags); TIRestoreMCR (edge_port, mcr); @@ -2590,9 +2593,12 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int result = 0; unsigned int msr; unsigned int mcr; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); + spin_lock_irqsave(&edge_port->ep_lock, flags); + msr = edge_port->shadow_msr; mcr = edge_port->shadow_mcr; result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ @@ -2604,6 +2610,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) dbg("%s -- %x", __FUNCTION__, result); + spin_unlock_irqrestore(&edge_port->ep_lock, flags); return result; } -- cgit v1.2.2 From dfa5ec79d28300b0d1fdeafbeebf0a6b721edc38 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 4 Mar 2008 15:25:11 -0800 Subject: USB: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. An extract of the semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @haskernel@ @@ #include @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 6 +++--- drivers/usb/misc/usbtest.c | 2 +- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/io_ti.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 9f80e5285575..afd4fbe7713c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -960,9 +960,9 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, r8a66597_write(r8a66597, TRCLR, td->pipe->pipetre); r8a66597_write(r8a66597, - (urb->transfer_buffer_length - + td->maxpacket - 1) - / td->maxpacket, + DIV_ROUND_UP + (urb->transfer_buffer_length, + td->maxpacket), td->pipe->pipetrn); r8a66597_bset(r8a66597, TRENB, td->pipe->pipetre); diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index b6b5b2affad1..17100471e461 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1404,7 +1404,7 @@ static struct urb *iso_alloc_urb ( return NULL; maxp = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11)); - packets = (bytes + maxp - 1) / maxp; + packets = DIV_ROUND_UP(bytes, maxp); urb = usb_alloc_urb (packets, GFP_KERNEL); if (!urb) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4643212eb959..496c0c93ad81 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1406,7 +1406,7 @@ static void ftdi_write_bulk_callback (struct urb *urb) data_offset = priv->write_offset; if (data_offset > 0) { /* Subtract the control bytes */ - countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ)); + countback -= (data_offset * DIV_ROUND_UP(countback, PKTSZ)); } spin_lock_irqsave(&priv->tx_lock, flags); --priv->tx_outstanding_urbs; @@ -1506,7 +1506,7 @@ static void ftdi_read_bulk_callback (struct urb *urb) /* count data bytes, but not status bytes */ countread = urb->actual_length; - countread -= 2 * ((countread + (PKTSZ - 1)) / PKTSZ); + countread -= 2 * DIV_ROUND_UP(countread, PKTSZ); spin_lock_irqsave(&priv->rx_lock, flags); priv->rx_bytes += countread; spin_unlock_irqrestore(&priv->rx_lock, flags); diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 39d71fdb5071..6afee30a6a5c 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -654,7 +654,7 @@ static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int f /* (TIIsTxActive doesn't seem to wait for the last byte) */ if ((baud_rate=port->baud_rate) == 0) baud_rate = 50; - msleep(max(1,(10000+baud_rate-1)/baud_rate)); + msleep(max(1, DIV_ROUND_UP(10000, baud_rate))); } static int TIChooseConfiguration (struct usb_device *dev) -- cgit v1.2.2 From b56394bf325820e9f338eaef2941f18b17b98098 Mon Sep 17 00:00:00 2001 From: Ray Lee Date: Tue, 4 Mar 2008 15:25:12 -0800 Subject: USB: io_ti.c: remove unneeded null tty check The Coverity checker (and Adrian Bunk) spotted an inconsistent NULL check of port->tty (it's blindly dereferenced later without the check). Alan Cox confirmed the check can go. Signed-off-by: Ray Lee Cc: Adrian Bunk Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 6afee30a6a5c..316467ecd778 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1941,8 +1941,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) if (edge_port == NULL) return -ENODEV; - if (port->tty) - port->tty->low_latency = low_latency; + port->tty->low_latency = low_latency; port_number = port->number - port->serial->minor; switch (port_number) { -- cgit v1.2.2 From 22552b286b44b8988e08fb74379507a9b32521b0 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Wed, 5 Mar 2008 23:17:38 -0800 Subject: USB: partial USB embedded host support This provides better support for USB "Embedded Host" functionality, which is a subset of the USB OTG options: * External hub support can be disabled; * USB peripherals not whitelisted in "otg_whitelist.h" will be rejected during enumeration. These options can allow some savings in software and support. Signed-off-by: Robin Getz Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index c15621d64579..fee864c9e62d 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -111,14 +111,16 @@ config USB_OTG config USB_OTG_WHITELIST bool "Rely on OTG Targeted Peripherals List" - depends on USB_OTG - default y + depends on USB_OTG || EMBEDDED + default y if USB_OTG + default n if EMBEDDED help If you say Y here, the "otg_whitelist.h" file will be used as a product whitelist, so USB peripherals not listed there will be rejected during enumeration. This behavior is required by the USB OTG specification for all devices not on your product's - "Targeted Peripherals List". + "Targeted Peripherals List". "Embedded Hosts" are likewise + allowed to support only a limited number of peripherals. Otherwise, peripherals not listed there will only generate a warning and enumeration will continue. That's more like what @@ -127,9 +129,10 @@ config USB_OTG_WHITELIST config USB_OTG_BLACKLIST_HUB bool "Disable external hubs" - depends on USB_OTG + depends on USB_OTG || EMBEDDED help If you say Y here, then Linux will refuse to enumerate external hubs. OTG hosts are allowed to reduce hardware - and software costs by not supporting external hubs. + and software costs by not supporting external hubs. So + are "Emedded Hosts" that don't offer OTG support. -- cgit v1.2.2 From d1b1842c393cf322712b669ec887397b89ed2312 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 5 Mar 2008 23:37:52 -0800 Subject: USB: ehci: remove obsolete workaround for bogus IRQs It was pointed out that we found and fixed the cause of the "bogus" fatal IRQ reports some time ago ... this patch removes the code which was working around that bug ("status" got clobbered), and a comment which needlessly confused folk reading this code. This also includes a minor cleanup to the code which fixed that bug. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 40f7391bf2aa..8c3e860bfce3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -686,6 +686,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* remote wakeup [4.3.1] */ if (status & STS_PCD) { unsigned i = HCS_N_PORTS (ehci->hcs_params); + + /* kick root hub later */ pcd_status = status; /* resume root hub? */ @@ -714,8 +716,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* PCI errors [4.15.2.4] */ if (unlikely ((status & STS_FATAL) != 0)) { - /* bogus "fatal" IRQs appear on some chips... why? */ - status = ehci_readl(ehci, &ehci->regs->status); dbg_cmd (ehci, "fatal", ehci_readl(ehci, &ehci->regs->command)); dbg_status (ehci, "fatal", status); @@ -734,7 +734,7 @@ dead: if (bh) ehci_work (ehci); spin_unlock (&ehci->lock); - if (pcd_status & STS_PCD) + if (pcd_status) usb_hcd_poll_rh_status(hcd); return IRQ_HANDLED; } -- cgit v1.2.2 From e1879b19b0abdb387e4aeb0b935a486cc75042fb Mon Sep 17 00:00:00 2001 From: Matthias Geissert Date: Thu, 6 Mar 2008 22:00:33 +0100 Subject: USB: ipaq: fix devices having more than one endpoint The ipaq module supports devices with one endpoint only. Some devices, e.g. Yakumo Delta 300, have more than one endpoint. This patch fixes support for devices having up to 2 endpoints which used to work on older kernel versions. Signed-off-by: Matthias Geissert Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 9b38a08ac83a..17f2a53b8ba4 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -571,9 +571,9 @@ static struct usb_serial_driver ipaq_device = { .usb_driver = &ipaq_driver, .id_table = ipaq_id_table, .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 2, .open = ipaq_open, .close = ipaq_close, .attach = ipaq_startup, -- cgit v1.2.2 From 70a1c9e086c2e267fbc4533cb870f34999b531d6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Mar 2008 17:00:58 -0500 Subject: USB: remove dev->power.power_state power.power_state is scheduled for removal. This patch (as1053) removes all uses of that field from drivers/usb. Almost all of them were write-only, the most significant exceptions being sl811-hcd.c and u132-hcd.c. Part of this patch was written by Pavel Machek. Signed-off-by: Alan Stern Cc: David Brownell Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 12 ++++-------- drivers/usb/core/hcd-pci.c | 5 ----- drivers/usb/core/usb.h | 2 -- drivers/usb/gadget/dummy_hcd.c | 2 -- drivers/usb/gadget/omap_udc.c | 4 ---- drivers/usb/host/ehci-dbg.c | 2 +- drivers/usb/host/ehci-ps3.c | 1 - drivers/usb/host/isp116x-hcd.c | 12 +----------- drivers/usb/host/ohci-dbg.c | 2 +- drivers/usb/host/ohci-ep93xx.c | 2 -- drivers/usb/host/ohci-omap.c | 2 -- drivers/usb/host/ohci-ps3.c | 1 - drivers/usb/host/ohci-pxa27x.c | 2 -- drivers/usb/host/ohci-sm501.c | 2 -- drivers/usb/host/r8a66597-hcd.c | 2 -- drivers/usb/host/sl811-hcd.c | 8 +------- drivers/usb/host/u132-hcd.c | 7 +------ drivers/usb/misc/usbtest.c | 3 ++- 18 files changed, 11 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ebccdefcc6f2..2ea333a43d65 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -794,8 +794,6 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) done: dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); - if (status == 0) - udev->dev.power.power_state.event = msg.event; return status; } @@ -824,10 +822,8 @@ static int usb_resume_device(struct usb_device *udev) done: dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); - if (status == 0) { + if (status == 0) udev->autoresume_disabled = 0; - udev->dev.power.power_state.event = PM_EVENT_ON; - } return status; } @@ -1180,8 +1176,7 @@ static int usb_resume_both(struct usb_device *udev) } } else { - /* Needed for setting udev->dev.power.power_state.event, - * for possible debugging message, and for reset_resume. */ + /* Needed for reset-resume */ status = usb_resume_device(udev); } @@ -1194,7 +1189,8 @@ static int usb_resume_both(struct usb_device *udev) done: dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); - udev->reset_resume = 0; + if (!status) + udev->reset_resume = 0; return status; } diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 84760ddbc332..739407bb8492 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -73,7 +73,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (pci_enable_device(dev) < 0) return -ENODEV; dev->current_state = PCI_D0; - dev->dev.power.power_state = PMSG_ON; if (!dev->irq) { dev_err(&dev->dev, @@ -302,8 +301,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) done: if (retval == 0) { - dev->dev.power.power_state = PMSG_SUSPEND; - #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ if (machine_is(powermac)) { @@ -406,8 +403,6 @@ int usb_hcd_pci_resume(struct pci_dev *dev) pci_set_master(dev); pci_restore_state(dev); - dev->dev.power.power_state = PMSG_ON; - clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); if (hcd->driver->resume) { diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 2375194a9d43..1bf8ccb9c58d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -114,13 +114,11 @@ static inline int is_usb_device_driver(struct device_driver *drv) static inline void mark_active(struct usb_interface *f) { f->is_active = 1; - f->dev.power.power_state.event = PM_EVENT_ON; } static inline void mark_quiesced(struct usb_interface *f) { f->is_active = 0; - f->dev.power.power_state.event = PM_EVENT_SUSPEND; } static inline int is_active(const struct usb_interface *f) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index cbe44535c0f0..e454775c2ff2 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -900,7 +900,6 @@ static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) set_link_state (dum); spin_unlock_irq (&dum->lock); - pdev->dev.power.power_state = state; usb_hcd_poll_rh_status (dummy_to_hcd (dum)); return 0; } @@ -915,7 +914,6 @@ static int dummy_udc_resume (struct platform_device *pdev) set_link_state (dum); spin_unlock_irq (&dum->lock); - pdev->dev.power.power_state = PMSG_ON; usb_hcd_poll_rh_status (dummy_to_hcd (dum)); return 0; } diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index ee1e9a314cd1..56277d24f041 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1265,8 +1265,6 @@ static int can_pullup(struct omap_udc *udc) static void pullup_enable(struct omap_udc *udc) { - udc->gadget.dev.parent->power.power_state = PMSG_ON; - udc->gadget.dev.power.power_state = PMSG_ON; UDC_SYSCON1_REG |= UDC_PULLUP_EN; if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) OTG_CTRL_REG |= OTG_BSESSVLD; @@ -3061,8 +3059,6 @@ static int omap_udc_suspend(struct platform_device *dev, pm_message_t message) omap_pullup(&udc->gadget, 0); } - udc->gadget.dev.power.power_state = PMSG_SUSPEND; - udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND; return 0; } diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 38eb92e5dc42..4af90df8e7de 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -670,7 +670,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) spin_lock_irqsave (&ehci->lock, flags); - if (buf->bus->controller->power.power_state.event) { + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { size = scnprintf (next, size, "bus %s, device %s (driver " DRIVER_VERSION ")\n" "%s\n" diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index bbda58eb8813..69782221bcf3 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -125,7 +125,6 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev) goto fail_irq; } - dev->core.power.power_state = PMSG_ON; dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 203a3359a648..66d773c726f6 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1442,11 +1442,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd) break; case HCCONTROL_USB_OPER: spin_unlock_irq(&isp116x->lock); - /* Without setting power_state here the - SUSPENDED state won't be removed from - sysfs/usbN/power.state as a response to remote - wakeup. Maybe in the future. */ - hcd->self.root_hub->dev.power.power_state = PMSG_ON; return 0; default: /* HCCONTROL_USB_RESET: this may happen, when during @@ -1460,7 +1455,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd) if ((isp116x->rhdesca & RH_A_NDP) == 2) isp116x_hub_control(hcd, SetPortFeature, USB_PORT_FEAT_POWER, 2, NULL, 0); - hcd->self.root_hub->dev.power.power_state = PMSG_ON; return 0; } @@ -1486,8 +1480,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd) isp116x_write_reg32(isp116x, HCCONTROL, (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); spin_unlock_irq(&isp116x->lock); - /* see analogous comment above */ - hcd->self.root_hub->dev.power.power_state = PMSG_ON; hcd->state = HC_STATE_RUNNING; return 0; @@ -1663,7 +1655,6 @@ static int __devinit isp116x_probe(struct platform_device *pdev) static int isp116x_suspend(struct platform_device *dev, pm_message_t state) { VDBG("%s: state %x\n", __func__, state.event); - dev->dev.power.power_state = state; return 0; } @@ -1672,8 +1663,7 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state) */ static int isp116x_resume(struct platform_device *dev) { - VDBG("%s: state %x\n", __func__, dev->power.power_state.event); - dev->dev.power.power_state = PMSG_ON; + VDBG("%s\n", __func__); return 0; } diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index a22c30aa745d..e06bfaebec54 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -655,7 +655,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) hcd->product_desc, hcd_name); - if (bus->controller->power.power_state.event) { + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { size -= scnprintf (next, size, "SUSPENDED (no register access)\n"); goto done; diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 156e93a9d0df..40c683f8987d 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -177,7 +177,6 @@ static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_ ep93xx_stop_hc(&pdev->dev); hcd->state = HC_STATE_SUSPENDED; - pdev->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -193,7 +192,6 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ohci->next_statechange = jiffies; ep93xx_start_hc(&pdev->dev); - pdev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(hcd); return 0; diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 7bfca1ed1b58..2aafa7b6c81f 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -505,7 +505,6 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) omap_ohci_clock_power(0); ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; - dev->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -518,7 +517,6 @@ static int ohci_omap_resume(struct platform_device *dev) ohci->next_statechange = jiffies; omap_ohci_clock_power(1); - dev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(platform_get_drvdata(dev)); return 0; } diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 01a0caeaa6bc..c1935ae537f8 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -127,7 +127,6 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev) goto fail_irq; } - dev->core.power.power_state = PMSG_ON; dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id); diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 8ad9b3b604b5..5d470263eed8 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -339,7 +339,6 @@ static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_ pxa27x_stop_hc(&pdev->dev); hcd->state = HC_STATE_SUSPENDED; - pdev->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -357,7 +356,6 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) if ((status = pxa27x_start_hc(&pdev->dev)) < 0) return status; - pdev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(hcd); return 0; diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 8ffcd3e5f56b..ab1e366d7790 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -224,7 +224,6 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg) sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; - dev->power.power_state = PMSG_SUSPEND; return 0; } @@ -238,7 +237,6 @@ static int ohci_sm501_resume(struct platform_device *pdev) ohci->next_statechange = jiffies; sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); - dev->power.power_state = PMSG_ON; usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); return 0; } diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index afd4fbe7713c..b46ff9a80b66 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2107,13 +2107,11 @@ static struct hc_driver r8a66597_hc_driver = { #if defined(CONFIG_PM) static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) { - pdev->dev.power.power_state = state; return 0; } static int r8a66597_resume(struct platform_device *pdev) { - pdev->dev.power.power_state = PMSG_ON; return 0; } #else /* if defined(CONFIG_PM) */ diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 629bca0ebe8f..df256d61e2c6 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -94,12 +94,10 @@ static void port_power(struct sl811 *sl811, int is_on) sl811->port1 = (1 << USB_PORT_FEAT_POWER); sl811->irq_enable = SL11H_INTMASK_INSRMV; - hcd->self.controller->power.power_state = PMSG_ON; } else { sl811->port1 = 0; sl811->irq_enable = 0; hcd->state = HC_STATE_HALT; - hcd->self.controller->power.power_state = PMSG_SUSPEND; } sl811->ctrl1 = 0; sl811_write(sl811, SL11H_IRQ_ENABLE, 0); @@ -1772,8 +1770,6 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state) port_power(sl811, 0); break; } - if (retval == 0) - dev->dev.power.power_state = state; return retval; } @@ -1786,15 +1782,13 @@ sl811h_resume(struct platform_device *dev) /* with no "check to see if VBUS is still powered" board hook, * let's assume it'd only be powered to enable remote wakeup. */ - if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND - || !device_can_wakeup(&hcd->self.root_hub->dev)) { + if (!sl811->port1 || !device_can_wakeup(&hcd->self.root_hub->dev)) { sl811->port1 = 0; port_power(sl811, 1); usb_root_hub_lost_power(hcd->self.root_hub); return 0; } - dev->dev.power.power_state = PMSG_ON; return sl811h_bus_resume(hcd); } diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 8e117a795e93..6e9b7edff528 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1534,11 +1534,9 @@ static void u132_power(struct u132 *u132, int is_on) if (u132->power) return; u132->power = 1; - hcd->self.controller->power.power_state = PMSG_ON; } else { u132->power = 0; hcd->state = HC_STATE_HALT; - hcd->self.controller->power.power_state = PMSG_SUSPEND; } } @@ -3227,8 +3225,6 @@ static int u132_suspend(struct platform_device *pdev, pm_message_t state) } break; } - if (retval == 0) - pdev->dev.power.power_state = state; return retval; } } @@ -3246,14 +3242,13 @@ static int u132_resume(struct platform_device *pdev) return -ESHUTDOWN; } else { int retval = 0; - if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { + if (!u132->port[0].power) { int ports = MAX_U132_PORTS; while (ports-- > 0) { port_power(u132, ports, 1); } retval = 0; } else { - pdev->dev.power.power_state = PMSG_ON; retval = u132_bus_resume(hcd); } return retval; diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 17100471e461..2c4fd4d6df95 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1564,7 +1564,8 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (mutex_lock_interruptible(&dev->lock)) return -ERESTARTSYS; - if (intf->dev.power.power_state.event != PM_EVENT_ON) { + /* FIXME: What if a system sleep starts while a test is running? */ + if (!intf->is_active) { mutex_unlock(&dev->lock); return -EHOSTUNREACH; } -- cgit v1.2.2 From 25b70a8665e9854504b9196c3098dadd37c721aa Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 4 Mar 2008 15:11:07 -0800 Subject: USB: ehci: paranoia, reject large control transfers Some EHCI fault paths with large control transfers aren't coded. Avoid problems by rejecting transfers that may need two qTDs (16+ KB). This is mostly paranoia; even 4 KB transfers are rare, and most HCDs use lower limits (so it's unlikely anyone would ever try such a thing). Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8c3e860bfce3..a02dcff5eb21 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -764,8 +764,14 @@ static int ehci_urb_enqueue ( INIT_LIST_HEAD (&qtd_list); switch (usb_pipetype (urb->pipe)) { - // case PIPE_CONTROL: - // case PIPE_BULK: + case PIPE_CONTROL: + /* qh_completions() code doesn't handle all the fault cases + * in multi-TD control transfers. Even 1KB is rare anyway. + */ + if (urb->transfer_buffer_length > (16 * 1024)) + return -EMSGSIZE; + /* FALLTHROUGH */ + /* case PIPE_BULK: */ default: if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) return -ENOMEM; -- cgit v1.2.2 From 8873aaa6e574d85c020a1c472d6d159cd1ec8aef Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 10 Mar 2008 21:59:28 +0000 Subject: USB: cypress_m8: Speed handling The recent changes to this driver cleaned it up a lot, follow that up by sorting the speed side of things out as well Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 169 +++++++--------------------------------- 1 file changed, 29 insertions(+), 140 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4bf45c711b9d..36f8ef079479 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -147,7 +147,6 @@ struct cypress_private { enum packet_format pkt_fmt; /* format to use for packet send / receive */ int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ int baud_rate; /* stores current baud rate in integer form */ - int cbr_mask; /* stores current baud rate in masked form */ int isthrottled; /* if throttled, discard reads */ wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ char prev_status, diff_status; /* used for TIOCMIWAIT */ @@ -183,9 +182,6 @@ static void cypress_unthrottle (struct usb_serial_port *port); static void cypress_set_dead (struct usb_serial_port *port); static void cypress_read_int_callback (struct urb *urb); static void cypress_write_int_callback (struct urb *urb); -/* baud helper functions */ -static int mask_to_rate (unsigned mask); -static unsigned rate_to_mask (int rate); /* write buffer functions */ static struct cypress_buf *cypress_buf_alloc(unsigned int size); static void cypress_buf_free(struct cypress_buf *cb); @@ -291,9 +287,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { *****************************************************************************/ -static int analyze_baud_rate(struct usb_serial_port *port, unsigned baud_mask) +static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) { - int new_rate; struct cypress_private *priv; priv = usb_get_serial_port_data(port); @@ -306,12 +301,6 @@ static int analyze_baud_rate(struct usb_serial_port *port, unsigned baud_mask) * The Cypress HID->COM device will work successfully up to * 115200bps (but the actual throughput is around 3kBps). */ - new_rate = mask_to_rate(baud_mask); - if (new_rate < 0) { - dbg("%s - failed setting baud rate, untranslatable speed", - __func__); - return -1; - } if (port->serial->dev->speed == USB_SPEED_LOW) { /* * Mike Isely 2-Feb-2008: The @@ -345,7 +334,7 @@ static int analyze_baud_rate(struct usb_serial_port *port, unsigned baud_mask) /* This function can either set or retrieve the current serial line settings */ -static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits, +static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_rate, int data_bits, int stop_bits, int parity_enable, int parity_type, int reset, int cypress_request_type) { int new_baudrate = 0, retval = 0, tries = 0; @@ -363,9 +352,13 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m switch(cypress_request_type) { case CYPRESS_SET_CONFIG: new_baudrate = priv->baud_rate; - if (baud_mask != priv->cbr_mask) { + /* 0 means 'Hang up' so doesn't change the true bit rate */ + if (baud_rate == 0) + new_baudrate = priv->baud_rate; + /* Change of speed ? */ + else if (baud_rate != priv->baud_rate) { dbg("%s - baud rate is changing", __FUNCTION__); - retval = analyze_baud_rate(port, baud_mask); + retval = analyze_baud_rate(port, baud_rate); if (retval >= 0) { new_baudrate = retval; dbg("%s - New baud rate set to %d", @@ -410,9 +403,12 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m } else { spin_lock_irqsave(&priv->lock, flags); priv->baud_rate = new_baudrate; - priv->cbr_mask = baud_mask; priv->current_config = feature_buffer[4]; spin_unlock_irqrestore(&priv->lock, flags); + /* If we asked for a speed change encode it */ + if (baud_rate) + tty_encode_baud_rate(port->tty, + new_baudrate, new_baudrate); } break; case CYPRESS_GET_CONFIG: @@ -450,9 +446,6 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m /* store the config in one byte, and later use bit masks to check values */ priv->current_config = feature_buffer[4]; priv->baud_rate = *((u_int32_t *)feature_buffer); - - if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40) - dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__); spin_unlock_irqrestore(&priv->lock, flags); } } @@ -482,51 +475,6 @@ static void cypress_set_dead(struct usb_serial_port *port) } -/* given a baud mask, it will return integer baud on success */ -static int mask_to_rate (unsigned mask) -{ - int rate; - - switch (mask) { - case B0: rate = 0; break; - case B300: rate = 300; break; - case B600: rate = 600; break; - case B1200: rate = 1200; break; - case B2400: rate = 2400; break; - case B4800: rate = 4800; break; - case B9600: rate = 9600; break; - case B19200: rate = 19200; break; - case B38400: rate = 38400; break; - case B57600: rate = 57600; break; - case B115200: rate = 115200; break; - default: rate = -1; - } - - return rate; -} - - -static unsigned rate_to_mask (int rate) -{ - unsigned mask; - - switch (rate) { - case 0: mask = B0; break; - case 300: mask = B300; break; - case 600: mask = B600; break; - case 1200: mask = B1200; break; - case 2400: mask = B2400; break; - case 4800: mask = B4800; break; - case 9600: mask = B9600; break; - case 19200: mask = B19200; break; - case 38400: mask = B38400; break; - case 57600: mask = B57600; break; - case 115200: mask = B115200; break; - default: mask = 0x40; - } - - return mask; -} /***************************************************************************** * Cypress serial driver functions *****************************************************************************/ @@ -558,7 +506,6 @@ static int generic_startup (struct usb_serial *serial) priv->line_control = 0; priv->termios_initialized = 0; priv->rx_flags = 0; - priv->cbr_mask = B300; /* Default packet format setting is determined by packet size. Anything with a size larger then 9 must have a separate count field since the 3 bit count field is otherwise too @@ -1004,9 +951,9 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, priv->line_control &= ~CONTROL_RTS; if (clear & TIOCM_DTR) priv->line_control &= ~CONTROL_DTR; + priv->cmd_ctrl = 1; spin_unlock_irqrestore(&priv->lock, flags); - priv->cmd_ctrl = 1; return cypress_write(port, NULL, 0); } @@ -1018,20 +965,6 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); switch (cmd) { - case TIOCGSERIAL: - if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) { - return -EFAULT; - } - return (0); - break; - case TIOCSSERIAL: - if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) { - return -EFAULT; - } - /* here we need to call cypress_set_termios to invoke the new settings */ - cypress_set_termios(port, &priv->tmp_termios); - return (0); - break; /* This code comes from drivers/char/serial.c and ftdi_sio.c */ case TIOCMIWAIT: while (priv != NULL) { @@ -1079,7 +1012,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct cypress_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; int data_bits, stop_bits, parity_type, parity_enable; - unsigned cflag, iflag, baud_mask; + unsigned cflag, iflag; unsigned long flags; __u8 oldlines; int linechange = 0; @@ -1087,10 +1020,6 @@ static void cypress_set_termios (struct usb_serial_port *port, dbg("%s - port %d", __FUNCTION__, port->number); tty = port->tty; - if ((!tty) || (!tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } spin_lock_irqsave(&priv->lock, flags); if (!priv->termios_initialized) { @@ -1098,40 +1027,37 @@ static void cypress_set_termios (struct usb_serial_port *port, *(tty->termios) = tty_std_termios; tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_ispeed = 4800; + tty->termios->c_ospeed = 4800; } else if (priv->chiptype == CT_CYPHIDCOM) { *(tty->termios) = tty_std_termios; tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_ispeed = 9600; + tty->termios->c_ospeed = 9600; } else if (priv->chiptype == CT_CA42V2) { *(tty->termios) = tty_std_termios; tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_ispeed = 9600; + tty->termios->c_ospeed = 9600; } priv->termios_initialized = 1; } spin_unlock_irqrestore(&priv->lock, flags); + /* Unsupported features need clearing */ + tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); + cflag = tty->termios->c_cflag; iflag = tty->termios->c_iflag; /* check if there are new settings */ if (old_termios) { - if ((cflag != old_termios->c_cflag) || - (RELEVANT_IFLAG(iflag) != - RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - attempting to set new termios settings", - __FUNCTION__); - /* should make a copy of this in case something goes - * wrong in the function, we can restore it */ - spin_lock_irqsave(&priv->lock, flags); - priv->tmp_termios = *(tty->termios); - spin_unlock_irqrestore(&priv->lock, flags); - } else { - dbg("%s - nothing to do, exiting", __FUNCTION__); - return; - } - } else - return; + spin_lock_irqsave(&priv->lock, flags); + priv->tmp_termios = *(tty->termios); + spin_unlock_irqrestore(&priv->lock, flags); + } /* set number of data bits, parity, stop bits */ /* when parity is disabled the parity type bit is ignored */ @@ -1173,53 +1099,16 @@ static void cypress_set_termios (struct usb_serial_port *port, if ((cflag & CBAUD) == B0) { /* drop dtr and rts */ dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__); - baud_mask = B0; priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - } else { - baud_mask = (cflag & CBAUD); - switch(baud_mask) { - case B300: - dbg("%s - setting baud 300bps", __FUNCTION__); - break; - case B600: - dbg("%s - setting baud 600bps", __FUNCTION__); - break; - case B1200: - dbg("%s - setting baud 1200bps", __FUNCTION__); - break; - case B2400: - dbg("%s - setting baud 2400bps", __FUNCTION__); - break; - case B4800: - dbg("%s - setting baud 4800bps", __FUNCTION__); - break; - case B9600: - dbg("%s - setting baud 9600bps", __FUNCTION__); - break; - case B19200: - dbg("%s - setting baud 19200bps", __FUNCTION__); - break; - case B38400: - dbg("%s - setting baud 38400bps", __FUNCTION__); - break; - case B57600: - dbg("%s - setting baud 57600bps", __FUNCTION__); - break; - case B115200: - dbg("%s - setting baud 115200bps", __FUNCTION__); - break; - default: - dbg("%s - unknown masked baud rate", __FUNCTION__); - } + } else priv->line_control = (CONTROL_DTR | CONTROL_RTS); - } spin_unlock_irqrestore(&priv->lock, flags); dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " "%d data_bits (+5)", __FUNCTION__, stop_bits, parity_enable, parity_type, data_bits); - cypress_serial_control(port, baud_mask, data_bits, stop_bits, + cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits, parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); /* we perform a CYPRESS_GET_CONFIG so that the current settings are -- cgit v1.2.2 From ff66e3ce3524125106be3ff18104ecde0849b85c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 12 Mar 2008 13:32:24 -0700 Subject: drivers/usb/core/devio.c: suppress warning with 64k PAGE_SIZE drivers/usb/core/devio.c: In function 'proc_control': drivers/usb/core/devio.c:657: warning: comparison is always false due to limited range of data type Cc: Alan Stern Cc: Pete Zaitcev Cc: Oliver Neukum Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ae94176c64e4..039ba23cc8b6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -647,6 +647,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) struct usbdevfs_ctrltransfer ctrl; unsigned int tmo; unsigned char *tbuf; + unsigned wLength; int i, j, ret; if (copy_from_user(&ctrl, arg, sizeof(ctrl))) @@ -654,7 +655,8 @@ static int proc_control(struct dev_state *ps, void __user *arg) ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); if (ret) return ret; - if (ctrl.wLength > PAGE_SIZE) + wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ + if (wLength > PAGE_SIZE) return -EINVAL; tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); if (!tbuf) -- cgit v1.2.2 From d277064e7e16d02e0078a6bc1820764ae00dea87 Mon Sep 17 00:00:00 2001 From: matthieu castet Date: Wed, 19 Mar 2008 19:40:52 +0100 Subject: USB: mass storage: emulation of sat scsi_pass_thru with ATACB I have got a cypress usb-ide bridge and I would like to tune or monitor my disk with tools like hdparm, hddtemp or smartctl. My controller support a way to send raw ATA command to the disk with something call atacb (see http://download.cypress.com.edgesuite.net/design_resources/datasheets/contents/cy7c68300c_8.pdf). Atacb support can be added for each application, but there is some disadvantages : - all application need to be patched - A race is possible if there other accesses, because the emulation can be split in 2 atacb scsi transactions. One for sending the command, one for reading the register (if ck_cond is set). I have implemented the emulation in usb-storage with a special proto_handler, and an unsual entry. Signed-off-by: Matthieu CASTET Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 11 ++ drivers/usb/storage/Makefile | 1 + drivers/usb/storage/cypress_atacb.c | 200 ++++++++++++++++++++++++++++++++++++ drivers/usb/storage/cypress_atacb.h | 25 +++++ drivers/usb/storage/scsiglue.c | 2 +- drivers/usb/storage/transport.c | 3 +- drivers/usb/storage/unusual_devs.h | 8 ++ drivers/usb/storage/usb.c | 10 ++ 8 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/storage/cypress_atacb.c create mode 100644 drivers/usb/storage/cypress_atacb.h (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 05cfc8473bd2..d3e5f889f68d 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -145,6 +145,17 @@ config USB_STORAGE_KARMA on the resulting scsi device node returns the Karma to normal operation. +config USB_STORAGE_CYPRESS_ATACB + bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" + depends on USB_STORAGE + ---help--- + Say Y here if you want to use SAT (ata pass through) on devices based + on the Cypress USB/ATA bridge supporting ATACB. This will allow you + to use tools to tune and monitor your drive (like hdparm or smartctl). + + If you say no here your device will still work with the standard usb + mass storage class. + config USB_LIBUSUAL bool "The shared table of common (or usual) storage devices" depends on USB diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 023969b4385b..4c596c766c53 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -21,6 +21,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o +usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ initializers.o $(usb-storage-obj-y) diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c new file mode 100644 index 000000000000..d88824b3511c --- /dev/null +++ b/drivers/usb/storage/cypress_atacb.c @@ -0,0 +1,200 @@ +/* + * Support for emulating SAT (ata pass through) on devices based + * on the Cypress USB/ATA bridge supporting ATACB. + * + * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "usb.h" +#include "protocol.h" +#include "scsiglue.h" +#include "debug.h" + +/* + * ATACB is a protocol used on cypress usb<->ata bridge to + * send raw ATA command over mass storage + * There is a ATACB2 protocol that support LBA48 on newer chip. + * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf + * datasheet from cypress.com. + */ +void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) +{ + unsigned char save_cmnd[MAX_COMMAND_SIZE]; + + if (likely(srb->cmnd[0] != ATA_16 && srb->cmnd[0] != ATA_12)) { + usb_stor_transparent_scsi_command(srb, us); + return; + } + + memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); + memset(srb->cmnd, 0, sizeof(srb->cmnd)); + + /* check if we support the command */ + if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ + goto invalid_fld; + /* check protocol */ + switch((save_cmnd[1] >> 1) & 0xf) { + case 3: /*no DATA */ + case 4: /* PIO in */ + case 5: /* PIO out */ + break; + default: + goto invalid_fld; + } + + /* first build the ATACB command */ + srb->cmd_len = 16; + + srb->cmnd[0] = 0x24; /* bVSCBSignature : vendor-specific command + this value can change, but most(all ?) manufacturers + keep the cypress default : 0x24 */ + srb->cmnd[1] = 0x24; /* bVSCBSubCommand : 0x24 for ATACB */ + + srb->cmnd[3] = 0xff - 1; /* features, sector count, lba low, lba med + lba high, device, command are valid */ + srb->cmnd[4] = 1; /* TransferBlockCount : 512 */ + + if (save_cmnd[0] == ATA_16) { + srb->cmnd[ 6] = save_cmnd[ 4]; /* features */ + srb->cmnd[ 7] = save_cmnd[ 6]; /* sector count */ + srb->cmnd[ 8] = save_cmnd[ 8]; /* lba low */ + srb->cmnd[ 9] = save_cmnd[10]; /* lba med */ + srb->cmnd[10] = save_cmnd[12]; /* lba high */ + srb->cmnd[11] = save_cmnd[13]; /* device */ + srb->cmnd[12] = save_cmnd[14]; /* command */ + + if (save_cmnd[1] & 0x01) {/* extended bit set for LBA48 */ + /* this could be supported by atacb2 */ + if (save_cmnd[3] || save_cmnd[5] || save_cmnd[7] || save_cmnd[9] + || save_cmnd[11]) + goto invalid_fld; + } + } + else { /* ATA12 */ + srb->cmnd[ 6] = save_cmnd[3]; /* features */ + srb->cmnd[ 7] = save_cmnd[4]; /* sector count */ + srb->cmnd[ 8] = save_cmnd[5]; /* lba low */ + srb->cmnd[ 9] = save_cmnd[6]; /* lba med */ + srb->cmnd[10] = save_cmnd[7]; /* lba high */ + srb->cmnd[11] = save_cmnd[8]; /* device */ + srb->cmnd[12] = save_cmnd[9]; /* command */ + + } + /* Filter SET_FEATURES - XFER MODE command */ + if ((srb->cmnd[12] == ATA_CMD_SET_FEATURES) + && (srb->cmnd[6] == SETFEATURES_XFER)) + goto invalid_fld; + + if (srb->cmnd[12] == ATA_CMD_ID_ATA || srb->cmnd[12] == ATA_CMD_ID_ATAPI) + srb->cmnd[2] |= (1<<7); /* set IdentifyPacketDevice for these cmds */ + + + usb_stor_transparent_scsi_command(srb, us); + + /* if the device doesn't support ATACB + */ + if (srb->result == SAM_STAT_CHECK_CONDITION && + memcmp(srb->sense_buffer, usb_stor_sense_invalidCDB, + sizeof(usb_stor_sense_invalidCDB)) == 0) { + US_DEBUGP("cypress atacb not supported ???\n"); + goto end; + } + + /* if ck_cond flags is set, and there wasn't critical error, + * build the special sense + */ + if ((srb->result != (DID_ERROR << 16) && + srb->result != (DID_ABORT << 16)) && + save_cmnd[2] & 0x20) { + struct scsi_eh_save ses; + unsigned char regs[8]; + unsigned char *sb = srb->sense_buffer; + unsigned char *desc = sb + 8; + int tmp_result; + + /* build the command for + * reading the ATA registers */ + scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0); + srb->sdb.length = sizeof(regs); + sg_init_one(&ses.sense_sgl, regs, srb->sdb.length); + srb->sdb.table.sgl = &ses.sense_sgl; + srb->sc_data_direction = DMA_FROM_DEVICE; + srb->sdb.table.nents = 1; + /* we use the same command as before, but we set + * the read taskfile bit, for not executing atacb command, + * but reading register selected in srb->cmnd[4] + */ + srb->cmnd[2] = 1; + + usb_stor_transparent_scsi_command(srb, us); + tmp_result = srb->result; + scsi_eh_restore_cmnd(srb, &ses); + /* we fail to get registers, report invalid command */ + if (tmp_result != SAM_STAT_GOOD) + goto invalid_fld; + + /* build the sense */ + memset(sb, 0, SCSI_SENSE_BUFFERSIZE); + + /* set sk, asc for a good command */ + sb[1] = RECOVERED_ERROR; + sb[2] = 0; /* ATA PASS THROUGH INFORMATION AVAILABLE */ + sb[3] = 0x1D; + + /* XXX we should generate sk, asc, ascq from status and error + * regs + * (see 11.1 Error translation ­ ATA device error to SCSI error map) + * and ata_to_sense_error from libata. + */ + + /* Sense data is current and format is descriptor. */ + sb[0] = 0x72; + desc[0] = 0x09; /* ATA_RETURN_DESCRIPTOR */ + + /* set length of additional sense data */ + sb[7] = 14; + desc[1] = 12; + + /* Copy registers into sense buffer. */ + desc[ 2] = 0x00; + desc[ 3] = regs[1]; /* features */ + desc[ 5] = regs[2]; /* sector count */ + desc[ 7] = regs[3]; /* lba low */ + desc[ 9] = regs[4]; /* lba med */ + desc[11] = regs[5]; /* lba high */ + desc[12] = regs[6]; /* device */ + desc[13] = regs[7]; /* command */ + + srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + } + goto end; +invalid_fld: + srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + + memcpy(srb->sense_buffer, + usb_stor_sense_invalidCDB, + sizeof(usb_stor_sense_invalidCDB)); +end: + memcpy(srb->cmnd, save_cmnd, sizeof(save_cmnd)); + if (srb->cmnd[0] == ATA_12) + srb->cmd_len = 12; +} diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/cypress_atacb.h new file mode 100644 index 000000000000..fbada898d56b --- /dev/null +++ b/drivers/usb/storage/cypress_atacb.h @@ -0,0 +1,25 @@ +/* + * Support for emulating SAT (ata pass through) on devices based + * on the Cypress USB/ATA bridge supporting ATACB. + * + * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CYPRESS_ATACB_H_ +#define _CYPRESS_ATACB_H_ +extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*); +#endif diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 8c1e2954f3b9..5405ba8cd9d2 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -132,7 +132,7 @@ static int slave_configure(struct scsi_device *sdev) /* Disk-type devices use MODE SENSE(6) if the protocol * (SubClass) is Transparent SCSI, otherwise they use * MODE SENSE(10). */ - if (us->subclass != US_SC_SCSI) + if (us->subclass != US_SC_SCSI && us->subclass != US_SC_CYP_ATACB) sdev->use_10_for_ms = 1; /* Many disks only accept MODE SENSE transfer lengths of diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index bdd4334bed5a..4628f03b13bf 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -603,7 +603,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE); /* FIXME: we must do the protocol translation here */ - if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI) + if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI || + us->subclass == US_SC_CYP_ATACB) srb->cmd_len = 6; else srb->cmd_len = 12; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 91252075e6e1..732bf52a775e 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1719,6 +1719,14 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_CAPACITY_HEURISTICS), +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB +UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, + "Cypress", + "Cypress AT2LP", + US_SC_CYP_ATACB, US_PR_BULK, NULL, + 0), +#endif + /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index ac6114eea0c3..f59593de3b8f 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -101,6 +101,9 @@ #ifdef CONFIG_USB_STORAGE_KARMA #include "karma.h" #endif +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB +#include "cypress_atacb.h" +#endif /* Some informational data */ MODULE_AUTHOR("Matthew Dharm "); @@ -708,6 +711,13 @@ static int get_protocol(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB + case US_SC_CYP_ATACB: + us->protocol_name = "Transparent SCSI with Cypress ATACB"; + us->proto_handler = cypress_atacb_passthrough; + break; +#endif + default: return -EIO; } -- cgit v1.2.2 From 726627f341beeedba948643c766a6786d75bbf9d Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 02:17:55 -0500 Subject: USB: Remove EXPERIMENTAL designation from USB storage Kconfig entries. Since there seems to be little reason to mark the current USB storage features as "EXPERIMENTAL," remove that dependency. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index d3e5f889f68d..0f6d234d699b 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -32,8 +32,8 @@ config USB_STORAGE_DEBUG verbose debugging messages. config USB_STORAGE_DATAFAB - bool "Datafab Compact Flash Reader support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Datafab Compact Flash Reader support" + depends on USB_STORAGE help Support for certain Datafab CompactFlash readers. Datafab has a web page at . @@ -69,8 +69,8 @@ config USB_STORAGE_DPCM There is a web page at . config USB_STORAGE_USBAT - bool "USBAT/USBAT02-based storage support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "USBAT/USBAT02-based storage support" + depends on USB_STORAGE help Say Y here to include additional code to support storage devices based on the SCM/Shuttle USBAT/USBAT02 processors. @@ -90,30 +90,30 @@ config USB_STORAGE_USBAT - Sandisk ImageMate SDDR-05b config USB_STORAGE_SDDR09 - bool "SanDisk SDDR-09 (and other SmartMedia) support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "SanDisk SDDR-09 (and other SmartMedia) support" + depends on USB_STORAGE help Say Y here to include additional code to support the Sandisk SDDR-09 SmartMedia reader in the USB Mass Storage driver. Also works for the Microtech Zio! SmartMedia reader. config USB_STORAGE_SDDR55 - bool "SanDisk SDDR-55 SmartMedia support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "SanDisk SDDR-55 SmartMedia support" + depends on USB_STORAGE help Say Y here to include additional code to support the Sandisk SDDR-55 SmartMedia reader in the USB Mass Storage driver. config USB_STORAGE_JUMPSHOT - bool "Lexar Jumpshot Compact Flash Reader (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Lexar Jumpshot Compact Flash Reader" + depends on USB_STORAGE help Say Y here to include additional code to support the Lexar Jumpshot USB CompactFlash reader. config USB_STORAGE_ALAUDA - bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)" - depends on USB_STORAGE && EXPERIMENTAL + bool "Olympus MAUSB-10/Fuji DPC-R1 support" + depends on USB_STORAGE help Say Y here to include additional code to support the Olympus MAUSB-10 and Fujifilm DPC-R1 USB Card reader/writer devices. @@ -122,8 +122,8 @@ config USB_STORAGE_ALAUDA XD and SmartMedia cards. config USB_STORAGE_ONETOUCH - bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" - depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL + bool "Support OneTouch Button on Maxtor Hard Drives" + depends on USB_STORAGE && INPUT_EVDEV help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. -- cgit v1.2.2 From afd0e0f2d499a832c3ef17a6872d6244d65cbe17 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 10 Mar 2008 15:09:51 -0400 Subject: USB: Remove EXPERIMENTAL tags from some USB gadget Kconfig entries. Based on a recent discussion on the Linux USB mailing list, remove the designation of EXPERIMENTAL from some USB gadget entries, and tag some of them as DEVELOPMENT. just for fun, i added a bit of help for gadgetfs, explaining the race condition. Signed-off-by: Robert P. J. Day Acked-by: David Brownell --- drivers/usb/gadget/Kconfig | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d681bb27fa58..f7b54651dd42 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -44,8 +44,8 @@ menuconfig USB_GADGET if USB_GADGET config USB_GADGET_DEBUG - boolean "Debugging messages" - depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL + boolean "Debugging messages (DEVELOPMENT)" + depends on USB_GADGET && DEBUG_KERNEL help Many controller and gadget drivers will print some debugging messages if you use this option to ask for those messages. @@ -58,7 +58,7 @@ config USB_GADGET_DEBUG production build. config USB_GADGET_DEBUG_FILES - boolean "Debugging information files" + boolean "Debugging information files (DEVELOPMENT)" depends on USB_GADGET && PROC_FS help Some of the drivers in the "gadget" framework can expose @@ -69,7 +69,7 @@ config USB_GADGET_DEBUG_FILES here. If in doubt, or to conserve kernel memory, say "N". config USB_GADGET_DEBUG_FS - boolean "Debugging information files in debugfs" + boolean "Debugging information files in debugfs (DEVELOPMENT)" depends on USB_GADGET && DEBUG_FS help Some of the drivers in the "gadget" framework can expose @@ -337,7 +337,7 @@ config USB_AT91 config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" - depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL + depends on USB=y || (USB=m && USB_GADGET=m) select USB_GADGET_DUALSPEED help This host controller driver emulates USB, looping all data transfer @@ -404,7 +404,6 @@ choice config USB_ZERO tristate "Gadget Zero (DEVELOPMENT)" - depends on EXPERIMENTAL help Gadget Zero is a two-configuration device. It either sinks and sources bulk data; or it loops back a configurable number of @@ -468,8 +467,8 @@ config USB_ETH dynamically linked module called "g_ether". config USB_ETH_RNDIS - bool "RNDIS support (EXPERIMENTAL)" - depends on USB_ETH && EXPERIMENTAL + bool "RNDIS support" + depends on USB_ETH default y help Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, @@ -495,6 +494,9 @@ config USB_GADGETFS All endpoints, transfer speeds, and transfer types supported by the hardware are available, through read() and write() calls. + Currently, this option is still labelled as EXPERIMENTAL because + of existing race conditions in the underlying in-kernel AIO core. + Say "y" to link the driver statically, or "m" to build a dynamically linked module called "gadgetfs". -- cgit v1.2.2 From bce62c263ab3742365dc1ac919cef732379e354a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 02:46:57 -0500 Subject: USB: Remove EXPERIMENTAL designation from USB misc/ Kconfig entries Since nothing under the USB misc/ seems to be obviously experimental, remove the EXPERIMENTAL dependency from those Kconfig entries. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/Kconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 9c7eb6144d02..a53db1d4e07a 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -33,8 +33,8 @@ config USB_EMI26 module will be called emi26. config USB_ADUTUX - tristate "ADU devices from Ontrak Control Systems (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "ADU devices from Ontrak Control Systems" + depends on USB help Say Y if you want to use an ADU device from Ontrak Control Systems. @@ -43,8 +43,8 @@ config USB_ADUTUX will be called adutux. config USB_AUERSWALD - tristate "USB Auerswald ISDN support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "USB Auerswald ISDN support" + depends on USB help Say Y here if you want to connect an Auerswald USB ISDN Device to your computer's USB port. @@ -53,8 +53,8 @@ config USB_AUERSWALD module will be called auerswald. config USB_RIO500 - tristate "USB Diamond Rio500 support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "USB Diamond Rio500 support" + depends on USB help Say Y here if you want to connect a USB Rio500 mp3 player to your computer's USB port. Please read @@ -64,8 +64,8 @@ config USB_RIO500 module will be called rio500. config USB_LEGOTOWER - tristate "USB Lego Infrared Tower support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "USB Lego Infrared Tower support" + depends on USB help Say Y here if you want to connect a USB Lego Infrared Tower to your computer's USB port. @@ -259,8 +259,8 @@ config USB_IOWARRIOR module will be called iowarrior. config USB_TEST - tristate "USB testing driver (DEVELOPMENT)" - depends on USB && USB_DEVICEFS && EXPERIMENTAL + tristate "USB testing driver" + depends on USB && USB_DEVICEFS help This driver is for testing host controller software. It is used with specialized device firmware for regression and stress testing, -- cgit v1.2.2 From 1b75dc4de94e4e11ab22e284fc0853e21d1ac07a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 03:00:04 -0500 Subject: USB: Remove EXPERIMENTAL designation from USB serial/ Kconfig entries Since nothing under the USB serial/ directory seems to be obviously experimental, remove the EXPERIMENTAL dependency from all of those Kconfig entries. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c1e65dfd9353..a769f6a5d7fb 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -20,8 +20,8 @@ menuconfig USB_SERIAL if USB_SERIAL config USB_SERIAL_CONSOLE - bool "USB Serial Console device support (EXPERIMENTAL)" - depends on USB_SERIAL=y && EXPERIMENTAL + bool "USB Serial Console device support" + depends on USB_SERIAL=y ---help--- If you say Y here, it will be possible to use a USB to serial converter port as the system console (the system console is the @@ -59,8 +59,8 @@ config USB_SERIAL_GENERIC properly. config USB_SERIAL_AIRCABLE - tristate "USB AIRcable Bluetooth Dongle Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB AIRcable Bluetooth Dongle Driver" + depends on USB_SERIAL help Say Y here if you want to use USB AIRcable Bluetooth Dongle. @@ -77,8 +77,8 @@ config USB_SERIAL_AIRPRIME module will be called airprime. config USB_SERIAL_ARK3116 - tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB ARK Micro 3116 USB Serial Driver" + depends on USB_SERIAL help Say Y here if you want to use a ARK Micro 3116 USB to Serial device. @@ -135,7 +135,7 @@ config USB_SERIAL_DIGI_ACCELEPORT config USB_SERIAL_CP2101 tristate "USB CP2101 UART Bridge Controller" - depends on USB_SERIAL && EXPERIMENTAL + depends on USB_SERIAL help Say Y here if you want to use a CP2101/CP2102 based USB to RS232 converter. @@ -145,7 +145,7 @@ config USB_SERIAL_CP2101 config USB_SERIAL_CYPRESS_M8 tristate "USB Cypress M8 USB Serial Driver" - depends on USB_SERIAL && EXPERIMENTAL + depends on USB_SERIAL help Say Y here if you want to use a device that contains the Cypress USB to Serial microcontroller, such as the DeLorme Earthmate GPS. @@ -171,8 +171,8 @@ config USB_SERIAL_EMPEG module will be called empeg. config USB_SERIAL_FTDI_SIO - tristate "USB FTDI Single Port Serial Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB FTDI Single Port Serial Driver" + depends on USB_SERIAL ---help--- Say Y here if you want to use a FTDI SIO single port USB to serial converter device. The implementation I have is called the USC-1000. @@ -218,8 +218,8 @@ config USB_SERIAL_IPAQ module will be called ipaq. config USB_SERIAL_IR - tristate "USB IR Dongle Serial Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB IR Dongle Serial Driver" + depends on USB_SERIAL help Say Y here if you want to enable simple serial support for USB IrDA devices. This is useful if you do not want to use the full IrDA @@ -279,8 +279,8 @@ config USB_SERIAL_GARMIN module will be called garmin_gps. config USB_SERIAL_IPW - tristate "USB IPWireless (3G UMTS TDD) Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB IPWireless (3G UMTS TDD) Driver" + depends on USB_SERIAL help Say Y here if you want to use a IPWireless USB modem such as the ones supplied by Axity3G/Sentech South Africa. @@ -289,8 +289,8 @@ config USB_SERIAL_IPW module will be called ipw. config USB_SERIAL_IUU - tristate "USB Infinity USB Unlimited Phoenix Driver (Experimental)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB Infinity USB Unlimited Phoenix Driver" + depends on USB_SERIAL help Say Y here if you want to use a IUU in phoenix mode and get an extra ttyUSBx device. More information available on @@ -405,8 +405,8 @@ config USB_SERIAL_KEYSPAN_USA49WLC Say Y here to include firmware for the USA-49WLC converter. config USB_SERIAL_KLSI - tristate "USB KL5KUSB105 (Palmconnect) Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB KL5KUSB105 (Palmconnect) Driver" + depends on USB_SERIAL ---help--- Say Y here if you want to use a KL5KUSB105 - based single port serial adapter. The most widely known -- and currently the only @@ -494,7 +494,7 @@ config USB_SERIAL_PL2303 module will be called pl2303. config USB_SERIAL_OTI6858 - tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller (EXPERIMENTAL)" + tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller" depends on USB_SERIAL help Say Y here if you want to use the OTi-6858 single port USB to serial @@ -513,8 +513,8 @@ config USB_SERIAL_HP4X module will be called hp4x. config USB_SERIAL_SAFE - tristate "USB Safe Serial (Encapsulated) Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB Safe Serial (Encapsulated) Driver" + depends on USB_SERIAL config USB_SERIAL_SAFE_PADDED bool "USB Secure Encapsulated Driver - Padded" @@ -542,8 +542,8 @@ config USB_SERIAL_TI module will be called ti_usb_3410_5052. config USB_SERIAL_CYBERJACK - tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader" + depends on USB_SERIAL ---help--- Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard reader. This is an interface to ISO 7816 compatible contact-based @@ -586,8 +586,8 @@ config USB_SERIAL_OPTION it might be accessible via the FTDI_SIO driver. config USB_SERIAL_OMNINET - tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" - depends on USB_SERIAL && EXPERIMENTAL + tristate "USB ZyXEL omni.net LCD Plus Driver" + depends on USB_SERIAL help Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA. -- cgit v1.2.2 From 528e4c12a7c141ce46641537fe7e3d7c29f68b8c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 03:04:05 -0500 Subject: USB: Remove EXPERIMENTAL designation from USB MDC800 support. Since support for the USB Mustek MDC800 Digital Camera has apparently been around since the beginning of the git repository, it's safe to assume it's no longer experimental. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig index 7595dfb38e3b..33350f9dd34f 100644 --- a/drivers/usb/image/Kconfig +++ b/drivers/usb/image/Kconfig @@ -5,8 +5,8 @@ comment "USB Imaging devices" depends on USB config USB_MDC800 - tristate "USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + tristate "USB Mustek MDC800 Digital Camera support" + depends on USB ---help--- Say Y here if you want to connect this type of still camera to your computer's USB port. This driver can be used with gphoto 0.4.3 -- cgit v1.2.2 From b67199967c777cf1aa42949f2bda00a7b937243e Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 03:12:44 -0500 Subject: USB: Remove EXPERIMENTAL from dynamic USB minor allocation. Since this USB feature seems non-experimental, remove that dependency. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index fee864c9e62d..cc9f397e8398 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -76,8 +76,8 @@ config USB_DEVICE_CLASS NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" config USB_DYNAMIC_MINORS - bool "Dynamic USB minor allocation (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL + bool "Dynamic USB minor allocation" + depends on USB help If you say Y here, the USB subsystem will use dynamic minor allocation for any device that uses the USB major number. -- cgit v1.2.2 From 9ec249a658e85fbb3e510c6208fb0c1a1d19c059 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 8 Mar 2008 03:27:44 -0500 Subject: USB: Remove EXPERIMENTAL designation from USB_EHCI_ROOT_HUB_TT. According to David Brownell, this feature doesn't require an experimental designation any longer. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bf8be2a41a4a..27f295b78055 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -30,8 +30,8 @@ config USB_EHCI_HCD module will be called ehci-hcd. config USB_EHCI_ROOT_HUB_TT - bool "Root Hub Transaction Translators (EXPERIMENTAL)" - depends on USB_EHCI_HCD && EXPERIMENTAL + bool "Root Hub Transaction Translators" + depends on USB_EHCI_HCD ---help--- Some EHCI chips have vendor-specific extensions to integrate transaction translators, so that no OHCI or UHCI companion -- cgit v1.2.2 From d43a05fdc2b5675efc45c32d427ff987a10b617a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 9 Mar 2008 13:55:01 -0400 Subject: USB: Fix "cut and paste" booboo in usbmon Makefile. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 90c59535778d..0f76ed5e1617 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile @@ -1,5 +1,5 @@ # -# Makefile for USB Core files and filesystem +# Makefile for USB monitor # usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_bin.o mon_dma.o -- cgit v1.2.2 From 454459b02ea9c8e850fd0b4e770037daf9a7b758 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Wed, 19 Mar 2008 22:29:51 -0700 Subject: usbmon: restore mmap Paolo asked to enable the mmap. I kept it off because I'm do not entirely understand how it workse these days after ->nopage etc. But it seems like working somewhat at least. Signed-Off-By: Pete Zaitcev Cc: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_bin.c | 9 +++------ drivers/usb/mon/mon_main.c | 3 +-- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 1774ba5c4c3b..49145534e06e 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1026,8 +1026,6 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait) return mask; } -#if 0 - /* * open and close: just keep track of how many times the device is * mapped, to use the proper memory allocation function. @@ -1063,13 +1061,13 @@ static int mon_bin_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return 0; } -struct vm_operations_struct mon_bin_vm_ops = { +static struct vm_operations_struct mon_bin_vm_ops = { .open = mon_bin_vma_open, .close = mon_bin_vma_close, .fault = mon_bin_vma_fault, }; -int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) +static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) { /* don't do anything here: "fault" will set up page table entries */ vma->vm_ops = &mon_bin_vm_ops; @@ -1079,8 +1077,6 @@ int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } -#endif /* 0 */ - static const struct file_operations mon_fops_binary = { .owner = THIS_MODULE, .open = mon_bin_open, @@ -1090,6 +1086,7 @@ static const struct file_operations mon_fops_binary = { .poll = mon_bin_poll, .ioctl = mon_bin_ioctl, .release = mon_bin_release, + .mmap = mon_bin_mmap, }; static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp) diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index b371ffd39d36..442d8076b201 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -129,8 +129,7 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) /* */ -static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, - int status) +static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, int status) { unsigned long flags; struct list_head *pos; -- cgit v1.2.2 From 28d1dfadd3ca07e7ec1c3de4f82ac2b8ece4be91 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Thu, 20 Mar 2008 10:53:52 +0100 Subject: USB: cdc-acm tell tty layer not to split things up. It ensures that the tty level do not split the send buffer into 2KB blocks. Signed-off-by: David Engraf Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0147ea39340e..1ded83b66af0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -489,6 +489,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) else rv = 0; + set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty->driver_data = acm; acm->tty = tty; -- cgit v1.2.2 From e4cf3aa8f9cd6ee4d583b5d445b5c152acefcde4 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Thu, 20 Mar 2008 10:01:34 +0100 Subject: USB: increase cdc-acm write throughput the following patch uses 16 write urbs and a writsize of wMaxPacketSize * 20. With this patch I get the maximum througput from my linux system with 20MB/sec read and 15 MB/sec write (full speed 1 MB/sec both) I also deleted the flag URB_NO_FSBR for the writeurbs, because this makes my full speed devices significant slower. Signed-off-by: David Engraf Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 81 +++++++++++++++++++++++---------------------- drivers/usb/class/cdc-acm.h | 7 ++-- 2 files changed, 45 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1ded83b66af0..d9b408113921 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -31,6 +31,7 @@ * v0.23 - use softirq for rx processing, as needed by tty layer * v0.24 - change probe method to evaluate CDC union descriptor * v0.25 - downstream tasks paralelized to maximize throughput + * v0.26 - multiple write urbs, writesize increased */ /* @@ -72,7 +73,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.25" +#define DRIVER_VERSION "v0.26" #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" @@ -118,7 +119,7 @@ static int acm_wb_alloc(struct acm *acm) int i, wbn; struct acm_wb *wb; - wbn = acm->write_current; + wbn = 0; i = 0; for (;;) { wb = &acm->wb[wbn]; @@ -132,11 +133,6 @@ static int acm_wb_alloc(struct acm *acm) } } -static void acm_wb_free(struct acm *acm, int wbn) -{ - acm->wb[wbn].use = 0; -} - static int acm_wb_is_avail(struct acm *acm) { int i, n; @@ -156,26 +152,22 @@ static inline int acm_wb_is_used(struct acm *acm, int wbn) /* * Finish write. */ -static void acm_write_done(struct acm *acm) +static void acm_write_done(struct acm *acm, struct acm_wb *wb) { unsigned long flags; - int wbn; spin_lock_irqsave(&acm->write_lock, flags); acm->write_ready = 1; - wbn = acm->write_current; - acm_wb_free(acm, wbn); - acm->write_current = (wbn + 1) % ACM_NW; + wb->use = 0; spin_unlock_irqrestore(&acm->write_lock, flags); } /* * Poke write. */ -static int acm_write_start(struct acm *acm) +static int acm_write_start(struct acm *acm, int wbn) { unsigned long flags; - int wbn; struct acm_wb *wb; int rc; @@ -190,24 +182,24 @@ static int acm_write_start(struct acm *acm) return 0; /* A white lie */ } - wbn = acm->write_current; if (!acm_wb_is_used(acm, wbn)) { spin_unlock_irqrestore(&acm->write_lock, flags); return 0; } wb = &acm->wb[wbn]; - acm->write_ready = 0; + if(acm_wb_is_avail(acm) <= 1) + acm->write_ready = 0; spin_unlock_irqrestore(&acm->write_lock, flags); - acm->writeurb->transfer_buffer = wb->buf; - acm->writeurb->transfer_dma = wb->dmah; - acm->writeurb->transfer_buffer_length = wb->len; - acm->writeurb->dev = acm->dev; + wb->urb->transfer_buffer = wb->buf; + wb->urb->transfer_dma = wb->dmah; + wb->urb->transfer_buffer_length = wb->len; + wb->urb->dev = acm->dev; - if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) { + if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) { dbg("usb_submit_urb(write bulk) failed: %d", rc); - acm_write_done(acm); + acm_write_done(acm, wb); } return rc; } @@ -450,12 +442,13 @@ urbs: /* data interface wrote those outgoing bytes */ static void acm_write_bulk(struct urb *urb) { - struct acm *acm = (struct acm *)urb->context; + struct acm *acm; + struct acm_wb *wb = (struct acm_wb *)urb->context; dbg("Entering acm_write_bulk with status %d", urb->status); - acm_write_done(acm); - acm_write_start(acm); + acm = wb->instance; + acm_write_done(acm, wb); if (ACM_READY(acm)) schedule_work(&acm->work); } @@ -557,7 +550,8 @@ static void acm_tty_unregister(struct acm *acm) usb_put_intf(acm->control); acm_table[acm->minor] = NULL; usb_free_urb(acm->ctrlurb); - usb_free_urb(acm->writeurb); + for (i = 0; i < ACM_NW; i++) + usb_free_urb(acm->wb[i].urb); for (i = 0; i < nr; i++) usb_free_urb(acm->ru[i].urb); kfree(acm->country_codes); @@ -578,7 +572,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) if (acm->dev) { acm_set_control(acm, acm->ctrlout = 0); usb_kill_urb(acm->ctrlurb); - usb_kill_urb(acm->writeurb); + for (i = 0; i < ACM_NW; i++) + usb_kill_urb(acm->wb[i].urb); for (i = 0; i < nr; i++) usb_kill_urb(acm->ru[i].urb); usb_autopm_put_interface(acm->control); @@ -606,7 +601,6 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c spin_lock_irqsave(&acm->write_lock, flags); if ((wbn = acm_wb_alloc(acm)) < 0) { spin_unlock_irqrestore(&acm->write_lock, flags); - acm_write_start(acm); return 0; } wb = &acm->wb[wbn]; @@ -617,7 +611,7 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c wb->len = count; spin_unlock_irqrestore(&acm->write_lock, flags); - if ((stat = acm_write_start(acm)) < 0) + if ((stat = acm_write_start(acm, wbn)) < 0) return stat; return count; } @@ -977,7 +971,7 @@ skip_normal_probe: ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2); - acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); + acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20; acm->control = control_interface; acm->data = data_interface; acm->minor = minor; @@ -1032,10 +1026,19 @@ skip_normal_probe: goto alloc_fail7; } } - acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); - if (!acm->writeurb) { - dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n"); - goto alloc_fail7; + for(i = 0; i < ACM_NW; i++) + { + struct acm_wb *snd = &(acm->wb[i]); + + if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) { + dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); + goto alloc_fail7; + } + + usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + NULL, acm->writesize, acm_write_bulk, snd); + snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + snd->instance = acm; } usb_set_intfdata (intf, acm); @@ -1071,10 +1074,6 @@ skip_countries: acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; acm->ctrlurb->transfer_dma = acm->ctrl_dma; - usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), - NULL, acm->writesize, acm_write_bulk, acm); - acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); acm_set_control(acm, acm->ctrlout); @@ -1092,7 +1091,8 @@ skip_countries: return 0; alloc_fail8: - usb_free_urb(acm->writeurb); + for (i = 0; i < ACM_NW; i++) + usb_free_urb(acm->wb[i].urb); alloc_fail7: for (i = 0; i < num_rx_buf; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); @@ -1116,7 +1116,8 @@ static void stop_data_traffic(struct acm *acm) tasklet_disable(&acm->urb_task); usb_kill_urb(acm->ctrlurb); - usb_kill_urb(acm->writeurb); + for(i = 0; i < ACM_NW; i++) + usb_kill_urb(acm->wb[i].urb); for (i = 0; i < acm->rx_buflimit; i++) usb_kill_urb(acm->ru[i].urb); diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 8df6a57dcf9e..046e064b033a 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -59,7 +59,7 @@ * when processing onlcr, so we only need 2 buffers. These values must be * powers of 2. */ -#define ACM_NW 2 +#define ACM_NW 16 #define ACM_NR 16 struct acm_wb { @@ -67,6 +67,8 @@ struct acm_wb { dma_addr_t dmah; int len; int use; + struct urb *urb; + struct acm *instance; }; struct acm_rb { @@ -88,7 +90,7 @@ struct acm { struct usb_interface *control; /* control interface */ struct usb_interface *data; /* data interface */ struct tty_struct *tty; /* the corresponding tty */ - struct urb *ctrlurb, *writeurb; /* urbs */ + struct urb *ctrlurb; /* urbs */ u8 *ctrl_buffer; /* buffers of urbs */ dma_addr_t ctrl_dma; /* dma handles of buffers */ u8 *country_codes; /* country codes from device */ @@ -103,7 +105,6 @@ struct acm { struct list_head spare_read_urbs; struct list_head spare_read_bufs; struct list_head filled_read_bufs; - int write_current; /* current write buffer */ int write_used; /* number of non-empty write buffers */ int write_ready; /* write urb is not running */ spinlock_t write_lock; -- cgit v1.2.2 From f3564de4f5ee3e205227691401d875a57b76906d Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Fri, 28 Mar 2008 10:05:08 -0700 Subject: USB: Serial: Sierra: Clean up This patch cleans up some of the sierra driver code. Please package this with the other patches in this group as I would like the driver version to reflect their changes as well. Signed-off-by: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 7b02a4ae1da4..5e55959daaaf 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -1,7 +1,7 @@ /* USB Driver for Sierra Wireless - Copyright (C) 2006, 2007, 2008 Kevin Lloyd + Copyright (C) 2006, 2007, 2008 Kevin Lloyd IMPORTANT DISCLAIMER: This driver is not commercially supported by Sierra Wireless. Use at your own risk. @@ -14,8 +14,8 @@ Whom based his on the Keyspan driver by Hugh Blemings */ -#define DRIVER_VERSION "v.1.2.8" -#define DRIVER_AUTHOR "Kevin Lloyd " +#define DRIVER_VERSION "v.1.2.9c" +#define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" #include @@ -31,7 +31,6 @@ #define SWIMS_USB_REQUEST_SetPower 0x00 #define SWIMS_USB_REQUEST_SetNmea 0x07 #define SWIMS_USB_REQUEST_SetMode 0x0B -#define SWIMS_USB_REQUEST_TYPE_VSC_SET 0x40 #define SWIMS_SET_MODE_Modem 0x0001 /* per port private data */ @@ -55,7 +54,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetPower, /* __u8 request */ - SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ + USB_TYPE_VENDOR, /* __u8 request type */ swiState, /* __u16 value */ 0, /* __u16 index */ NULL, /* void *data */ @@ -70,7 +69,7 @@ static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode) dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n"); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetMode, /* __u8 request */ - SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ + USB_TYPE_VENDOR, /* __u8 request type */ eSWocMode, /* __u16 value */ 0x0000, /* __u16 index */ NULL, /* void *data */ @@ -85,7 +84,7 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) dev_dbg(&udev->dev, "%s", "NMEA Enable sent\n"); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ - SWIMS_USB_REQUEST_TYPE_VSC_SET, /* __u8 request type */ + USB_TYPE_VENDOR, /* __u8 request type */ enable, /* __u16 value */ 0x0000, /* __u16 index */ NULL, /* void *data */ @@ -453,7 +452,7 @@ static void sierra_instat_callback(struct urb *urb) struct usb_serial *serial = port->serial; dbg("%s", __FUNCTION__); - dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); + dbg("%s: urb %p port %p has data %p", __FUNCTION__, urb, port, portdata); if (status == 0) { struct usb_ctrlrequest *req_pkt = @@ -483,7 +482,7 @@ static void sierra_instat_callback(struct urb *urb) tty_hangup(port->tty); } else { dbg("%s: type %x req %x", __FUNCTION__, - req_pkt->bRequestType,req_pkt->bRequest); + req_pkt->bRequestType, req_pkt->bRequest); } } else dbg("%s: error %d", __FUNCTION__, status); -- cgit v1.2.2 From 69a90f8189960f37cc73f5da6c331b23227e2197 Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Mon, 31 Mar 2008 10:20:54 -0700 Subject: USB: Serial: Sierra: C597 fix This patch is for the sierra driver and fixes a Compass 597 bug that allows users to access the SD-Card. This targets kernel 2.6.25-rc7 Signed-off-by: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 5e55959daaaf..af667a1828b0 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -155,7 +155,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ - { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, /* Sierra Wireless C597 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ -- cgit v1.2.2 From 7106967ecc0a33a7d7e2e04798eb9f45377f448b Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Wed, 2 Apr 2008 11:24:56 -0700 Subject: usb/usb-serial-sierra-add-new-dev-group This patch is for the sierra driver and adds support for a new group of devices that have a new USB configuration. This targets kernel 2.6.25-rc7 Signed-off-by: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index af667a1828b0..f791eb8887fc 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -108,6 +108,26 @@ static int sierra_calc_num_ports(struct usb_serial *serial) return result; } +static int sierra_calc_interface(struct usb_serial *serial) +{ + int interface; + struct usb_interface *p_interface; + struct usb_host_interface *p_host_interface; + + /* Get the interface structure pointer from the serial struct */ + p_interface = serial->interface; + + /* Get a pointer to the host interface structure */ + p_host_interface = p_interface->cur_altsetting; + + /* read the interface descriptor for this active altsetting + * to find out the interface number we are on + */ + interface = p_host_interface->desc.bInterfaceNumber; + + return interface; +} + static int sierra_probe(struct usb_serial *serial, const struct usb_device_id *id) { @@ -123,6 +143,22 @@ static int sierra_probe(struct usb_serial *serial, ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; udev = serial->dev; + /* Figure out the interface number from the serial structure */ + ifnum = sierra_calc_interface(serial); + + /* + * If this interface supports more than 1 alternate + * select the 2nd one + */ + if (serial->interface->num_altsetting == 2) { + dev_dbg(&udev->dev, + "Selecting alt setting for interface %d\n", + ifnum); + + /* We know the alternate setting is 1 for the MC8785 */ + usb_set_interface(udev, ifnum, 1); + } + /* Check if in installer mode */ if (truinstall && id->driver_info == DEVICE_INSTALLER) { dev_dbg(&udev->dev, "%s", "FOUND TRU-INSTALL DEVICE(SW)\n"); @@ -165,14 +201,18 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ + { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ + { USB_DEVICE(0x1199, 0x683B), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless MC8785 Composite*/ { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ + { USB_DEVICE(0x1199, 0x6859), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ + { USB_DEVICE(0x1199, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */ { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */ -- cgit v1.2.2 From 619a6f1d1423d08e74ed2b8a2113f12ef18e4373 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 7 Feb 2008 23:59:03 +0100 Subject: USB: add usb-serial spcp8x5 driver Original version of the driver done by Linxb, changes by Harald, and lots of cleanups by me in order to get it into a mergable state. Cc: Linxb Cc: Harald Klein Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 10 + drivers/usb/serial/Makefile | 3 +- drivers/usb/serial/spcp8x5.c | 1075 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1087 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/serial/spcp8x5.c (limited to 'drivers') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index a769f6a5d7fb..f9c6c0922c00 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -503,6 +503,16 @@ config USB_SERIAL_OTI6858 To compile this driver as a module, choose M here: the module will be called oti6858. +config USB_SERIAL_SPCP8X5 + tristate "USB SPCP8x5 USB To Serial Driver" + depends on USB_SERIAL + help + Say Y here if you want to use the spcp8x5 converter chip. This is + commonly found in some Z-Wave USB devices. + + To compile this driver as a module, choose M here: the + module will be called spcp8x5. + config USB_SERIAL_HP4X tristate "USB HP4x Calculators support" depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 0db109a54d10..756859510d8c 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -30,8 +30,8 @@ obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o -obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o +obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o +obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c new file mode 100644 index 000000000000..1b46b846f100 --- /dev/null +++ b/drivers/usb/serial/spcp8x5.c @@ -0,0 +1,1075 @@ +/* + * spcp8x5 USB to serial adaptor driver + * + * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn) + * Copyright (C) 2006 S1 Corp. + * + * Original driver for 2.6.10 pl2303 driver by + * Greg Kroah-Hartman (greg@kroah.com) + * Changes for 2.6.20 by Harald Klein + * + * 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 + + +/* Version Information */ +#define DRIVER_VERSION "v0.04" +#define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver" + +static int debug; + +#define SPCP8x5_007_VID 0x04FC +#define SPCP8x5_007_PID 0x0201 +#define SPCP8x5_008_VID 0x04fc +#define SPCP8x5_008_PID 0x0235 +#define SPCP8x5_PHILIPS_VID 0x0471 +#define SPCP8x5_PHILIPS_PID 0x081e +#define SPCP8x5_INTERMATIC_VID 0x04FC +#define SPCP8x5_INTERMATIC_PID 0x0204 +#define SPCP8x5_835_VID 0x04fc +#define SPCP8x5_835_PID 0x0231 + +static struct usb_device_id id_table [] = { + { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)}, + { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)}, + { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)}, + { USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)}, + { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID)}, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, id_table); + +struct spcp8x5_usb_ctrl_arg { + u8 type; + u8 cmd; + u8 cmd_type; + u16 value; + u16 index; + u16 length; +}; + +/* wait 30s before close */ +#define SPCP8x5_CLOSING_WAIT (30*HZ) + +#define SPCP8x5_BUF_SIZE 1024 + + +/* spcp8x5 spec register define */ +#define MCR_CONTROL_LINE_RTS 0x02 +#define MCR_CONTROL_LINE_DTR 0x01 +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 + +#define MSR_STATUS_LINE_DCD 0x80 +#define MSR_STATUS_LINE_RI 0x40 +#define MSR_STATUS_LINE_DSR 0x20 +#define MSR_STATUS_LINE_CTS 0x10 + +/* verdor command here , we should define myself */ +#define SET_DEFAULT 0x40 +#define SET_DEFAULT_TYPE 0x20 + +#define SET_UART_FORMAT 0x40 +#define SET_UART_FORMAT_TYPE 0x21 +#define SET_UART_FORMAT_SIZE_5 0x00 +#define SET_UART_FORMAT_SIZE_6 0x01 +#define SET_UART_FORMAT_SIZE_7 0x02 +#define SET_UART_FORMAT_SIZE_8 0x03 +#define SET_UART_FORMAT_STOP_1 0x00 +#define SET_UART_FORMAT_STOP_2 0x04 +#define SET_UART_FORMAT_PAR_NONE 0x00 +#define SET_UART_FORMAT_PAR_ODD 0x10 +#define SET_UART_FORMAT_PAR_EVEN 0x30 +#define SET_UART_FORMAT_PAR_MASK 0xD0 +#define SET_UART_FORMAT_PAR_SPACE 0x90 + +#define GET_UART_STATUS_TYPE 0xc0 +#define GET_UART_STATUS 0x22 +#define GET_UART_STATUS_MSR 0x06 + +#define SET_UART_STATUS 0x40 +#define SET_UART_STATUS_TYPE 0x23 +#define SET_UART_STATUS_MCR 0x0004 +#define SET_UART_STATUS_MCR_DTR 0x01 +#define SET_UART_STATUS_MCR_RTS 0x02 +#define SET_UART_STATUS_MCR_LOOP 0x10 + +#define SET_WORKING_MODE 0x40 +#define SET_WORKING_MODE_TYPE 0x24 +#define SET_WORKING_MODE_U2C 0x00 +#define SET_WORKING_MODE_RS485 0x01 +#define SET_WORKING_MODE_PDMA 0x02 +#define SET_WORKING_MODE_SPP 0x03 + +#define SET_FLOWCTL_CHAR 0x40 +#define SET_FLOWCTL_CHAR_TYPE 0x25 + +#define GET_VERSION 0xc0 +#define GET_VERSION_TYPE 0x26 + +#define SET_REGISTER 0x40 +#define SET_REGISTER_TYPE 0x27 + +#define GET_REGISTER 0xc0 +#define GET_REGISTER_TYPE 0x28 + +#define SET_RAM 0x40 +#define SET_RAM_TYPE 0x31 + +#define GET_RAM 0xc0 +#define GET_RAM_TYPE 0x32 + +/* how come ??? */ +#define UART_STATE 0x08 +#define UART_STATE_TRANSIENT_MASK 0x74 +#define UART_DCD 0x01 +#define UART_DSR 0x02 +#define UART_BREAK_ERROR 0x04 +#define UART_RING 0x08 +#define UART_FRAME_ERROR 0x10 +#define UART_PARITY_ERROR 0x20 +#define UART_OVERRUN_ERROR 0x40 +#define UART_CTS 0x80 + +enum spcp8x5_type { + SPCP825_007_TYPE, + SPCP825_008_TYPE, + SPCP825_PHILIP_TYPE, + SPCP825_INTERMATIC_TYPE, + SPCP835_TYPE, +}; + +/* 1st in 1st out buffer 4 driver */ +struct ringbuf { + unsigned int buf_size; + char *buf_buf; + char *buf_get; + char *buf_put; +}; + +/* alloc the ring buf and alloc the buffer itself */ +static inline struct ringbuf *alloc_ringbuf(unsigned int size) +{ + struct ringbuf *pb; + + if (size == 0) + return NULL; + + pb = kmalloc(sizeof(*pb), GFP_KERNEL); + if (pb == NULL) + return NULL; + + pb->buf_buf = kmalloc(size, GFP_KERNEL); + if (pb->buf_buf == NULL) { + kfree(pb); + return NULL; + } + + pb->buf_size = size; + pb->buf_get = pb->buf_put = pb->buf_buf; + + return pb; +} + +/* free the ring buf and the buffer itself */ +static inline void free_ringbuf(struct ringbuf *pb) +{ + if (pb != NULL) { + kfree(pb->buf_buf); + kfree(pb); + } +} + +/* clear pipo , juest repoint the pointer here */ +static inline void clear_ringbuf(struct ringbuf *pb) +{ + if (pb != NULL) + pb->buf_get = pb->buf_put; +} + +/* get the number of data in the pipo */ +static inline unsigned int ringbuf_avail_data(struct ringbuf *pb) +{ + if (pb == NULL) + return 0; + return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size); +} + +/* get the number of space in the pipo */ +static inline unsigned int ringbuf_avail_space(struct ringbuf *pb) +{ + if (pb == NULL) + return 0; + return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size); +} + +/* put count data into pipo */ +static unsigned int put_ringbuf(struct ringbuf *pb, const char *buf, + unsigned int count) +{ + unsigned int len; + + if (pb == NULL) + return 0; + + len = ringbuf_avail_space(pb); + if (count > len) + count = len; + + if (count == 0) + return 0; + + len = pb->buf_buf + pb->buf_size - pb->buf_put; + if (count > len) { + memcpy(pb->buf_put, buf, len); + memcpy(pb->buf_buf, buf+len, count - len); + pb->buf_put = pb->buf_buf + count - len; + } else { + memcpy(pb->buf_put, buf, count); + if (count < len) + pb->buf_put += count; + else /* count == len */ + pb->buf_put = pb->buf_buf; + } + return count; +} + +/* get count data from pipo */ +static unsigned int get_ringbuf(struct ringbuf *pb, char *buf, + unsigned int count) +{ + unsigned int len; + + if (pb == NULL || buf == NULL) + return 0; + + len = ringbuf_avail_data(pb); + if (count > len) + count = len; + + if (count == 0) + return 0; + + len = pb->buf_buf + pb->buf_size - pb->buf_get; + if (count > len) { + memcpy(buf, pb->buf_get, len); + memcpy(buf+len, pb->buf_buf, count - len); + pb->buf_get = pb->buf_buf + count - len; + } else { + memcpy(buf, pb->buf_get, count); + if (count < len) + pb->buf_get += count; + else /* count == len */ + pb->buf_get = pb->buf_buf; + } + + return count; +} + +static struct usb_driver spcp8x5_driver = { + .name = "spcp8x5", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + + +struct spcp8x5_private { + spinlock_t lock; + struct ringbuf *buf; + int write_urb_in_use; + enum spcp8x5_type type; + wait_queue_head_t delta_msr_wait; + u8 line_control; + u8 line_status; + u8 termios_initialized; +}; + +/* desc : when device plug in,this function would be called. + * thanks to usb_serial subsystem,then do almost every things for us. And what + * we should do just alloc the buffer */ +static int spcp8x5_startup(struct usb_serial *serial) +{ + struct spcp8x5_private *priv; + int i; + enum spcp8x5_type type = SPCP825_007_TYPE; + + if (serial->dev->descriptor.idProduct == 0x0201) + type = SPCP825_007_TYPE; + else if (serial->dev->descriptor.idProduct == 0x0231) + type = SPCP835_TYPE; + else if (serial->dev->descriptor.idProduct == 0x0235) + type = SPCP825_008_TYPE; + else if (serial->dev->descriptor.idProduct == 0x0204) + type = SPCP825_INTERMATIC_TYPE; + else if (serial->dev->descriptor.idProduct == 0x0471 && + serial->dev->descriptor.idVendor == 0x081e) + type = SPCP825_PHILIP_TYPE; + dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); + + for (i = 0; i < serial->num_ports; ++i) { + priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); + if (!priv) + goto cleanup; + + spin_lock_init(&priv->lock); + priv->buf = alloc_ringbuf(SPCP8x5_BUF_SIZE); + if (priv->buf == NULL) + goto cleanup2; + + init_waitqueue_head(&priv->delta_msr_wait); + priv->type = type; + usb_set_serial_port_data(serial->port[i] , priv); + + } + + return 0; + +cleanup2: + kfree(priv); +cleanup: + for (--i; i >= 0; --i) { + priv = usb_get_serial_port_data(serial->port[i]); + free_ringbuf(priv->buf); + kfree(priv); + usb_set_serial_port_data(serial->port[i] , NULL); + } + return -ENOMEM; +} + +/* call when the device plug out. free all the memory alloced by probe */ +static void spcp8x5_shutdown(struct usb_serial *serial) +{ + int i; + struct spcp8x5_private *priv; + + for (i = 0; i < serial->num_ports; i++) { + priv = usb_get_serial_port_data(serial->port[i]); + if (priv) { + free_ringbuf(priv->buf); + kfree(priv); + usb_set_serial_port_data(serial->port[i] , NULL); + } + } +} + +/* set the modem control line of the device. + * NOTE spcp825-007 not supported this */ +static int spcp8x5_set_ctrlLine(struct usb_device *dev, u8 value, + enum spcp8x5_type type) +{ + int retval; + u8 mcr = 0 ; + + if (type == SPCP825_007_TYPE) + return -EPERM; + + mcr = (unsigned short)value; + retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + SET_UART_STATUS_TYPE, SET_UART_STATUS, + mcr, 0x04, NULL, 0, 100); + if (retval != 0) + dev_dbg(&dev->dev, "usb_control_msg return %#x\n", retval); + return retval; +} + +/* get the modem status register of the device + * NOTE spcp825-007 not supported this */ +static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, + enum spcp8x5_type type) +{ + u8 *status_buffer; + int ret; + + /* I return Permited not support here but seem inval device + * is more fix */ + if (type == SPCP825_007_TYPE) + return -EPERM; + if (status == NULL) + return -EINVAL; + + status_buffer = kmalloc(1, GFP_KERNEL); + if (!status_buffer) + return -ENOMEM; + status_buffer[0] = status[0]; + + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + GET_UART_STATUS, GET_UART_STATUS_TYPE, + 0, GET_UART_STATUS_MSR, status_buffer, 1, 100); + if (ret < 0) + dev_dbg(&dev->dev, "Get MSR = 0x%p failed (error = %d)", + status_buffer, ret); + + dev_dbg(&dev->dev, "0xc0:0x22:0:6 %d - 0x%p ", ret, status_buffer); + status[0] = status_buffer[0]; + kfree(status_buffer); + + return ret; +} + +/* select the work mode. + * NOTE this function not supported by spcp825-007 */ +static void spcp8x5_set_workMode(struct usb_device *dev, u16 value, + u16 index, enum spcp8x5_type type) +{ + int ret; + + /* I return Permited not support here but seem inval device + * is more fix */ + if (type == SPCP825_007_TYPE) + return; + + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + SET_WORKING_MODE_TYPE, SET_WORKING_MODE, + value, index, NULL, 0, 100); + dev_dbg(&dev->dev, "value = %#x , index = %#x\n", value, index); + if (ret < 0) + dev_dbg(&dev->dev, + "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret); +} + +/* close the serial port. We should wait for data sending to device 1st and + * then kill all urb. */ +static void spcp8x5_close(struct usb_serial_port *port, struct file *filp) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int c_cflag; + int bps; + long timeout; + wait_queue_t wait; + int result; + + dbg("%s - port %d", __func__, port->number); + + /* wait for data to drain from the buffer */ + spin_lock_irqsave(&priv->lock, flags); + timeout = SPCP8x5_CLOSING_WAIT; + init_waitqueue_entry(&wait, current); + add_wait_queue(&port->tty->write_wait, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (ringbuf_avail_data(priv->buf) == 0 || + timeout == 0 || signal_pending(current)) + break; + spin_unlock_irqrestore(&priv->lock, flags); + timeout = schedule_timeout(timeout); + spin_lock_irqsave(&priv->lock, flags); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->tty->write_wait, &wait); + + /* clear out any remaining data in the buffer */ + clear_ringbuf(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); + + /* wait for characters to drain from the device (this is long enough + * for the entire all byte spcp8x5 hardware buffer to drain with no + * flow control for data rates of 1200 bps or more, for lower rates we + * should really know how much data is in the buffer to compute a delay + * that is not unnecessarily long) */ + bps = tty_get_baud_rate(port->tty); + if (bps > 1200) + timeout = max((HZ*2560) / bps, HZ/10); + else + timeout = 2*HZ; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(timeout); + + /* clear control lines */ + if (port->tty) { + c_cflag = port->tty->termios->c_cflag; + if (c_cflag & HUPCL) { + spin_lock_irqsave(&priv->lock, flags); + priv->line_control = 0; + spin_unlock_irqrestore(&priv->lock, flags); + spcp8x5_set_ctrlLine(port->serial->dev, 0 , priv->type); + } + } + + /* kill urb */ + if (port->write_urb != NULL) { + result = usb_unlink_urb(port->write_urb); + if (result) + dev_dbg(&port->dev, + "usb_unlink_urb(write_urb) = %d\n", result); + } + result = usb_unlink_urb(port->read_urb); + if (result) + dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result); +} + +/* set the serial param for transfer. we should check if we really need to + * transfer. then if be set flow contorl we should do this too. */ +static void spcp8x5_set_termios(struct usb_serial_port *port, + struct ktermios *old_termios) +{ + struct usb_serial *serial = port->serial; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int cflag = port->tty->termios->c_cflag; + unsigned int old_cflag = old_termios->c_cflag; + unsigned short uartdata; + unsigned char buf[2] = {0, 0}; + int baud; + int i; + u8 control; + + if ((!port->tty) || (!port->tty->termios)) + return; + + /* for the 1st time call this function */ + spin_lock_irqsave(&priv->lock, flags); + if (!priv->termios_initialized) { + *(port->tty->termios) = tty_std_termios; + port->tty->termios->c_cflag = B115200 | CS8 | CREAD | + HUPCL | CLOCAL; + priv->termios_initialized = 1; + } + spin_unlock_irqrestore(&priv->lock, flags); + + /* check that they really want us to change something */ + if (!tty_termios_hw_change(port->tty->termios, old_termios)) + return; + + /* set DTR/RTS active */ + spin_lock_irqsave(&priv->lock, flags); + control = priv->line_control; + if ((old_cflag & CBAUD) == B0) { + priv->line_control |= MCR_DTR; + if (!(old_cflag & CRTSCTS)) + priv->line_control |= MCR_RTS; + } + if (control != priv->line_control) { + control = priv->line_control; + spin_unlock_irqrestore(&priv->lock, flags); + spcp8x5_set_ctrlLine(serial->dev, control , priv->type); + } else { + spin_unlock_irqrestore(&priv->lock, flags); + } + + /* Set Baud Rate */ + baud = tty_get_baud_rate(port->tty);; + switch (baud) { + case 300: buf[0] = 0x00; break; + case 600: buf[0] = 0x01; break; + case 1200: buf[0] = 0x02; break; + case 2400: buf[0] = 0x03; break; + case 4800: buf[0] = 0x04; break; + case 9600: buf[0] = 0x05; break; + case 19200: buf[0] = 0x07; break; + case 38400: buf[0] = 0x09; break; + case 57600: buf[0] = 0x0a; break; + case 115200: buf[0] = 0x0b; break; + case 230400: buf[0] = 0x0c; break; + case 460800: buf[0] = 0x0d; break; + case 921600: buf[0] = 0x0e; break; +/* case 1200000: buf[0] = 0x0f; break; */ +/* case 2400000: buf[0] = 0x10; break; */ + case 3000000: buf[0] = 0x11; break; +/* case 6000000: buf[0] = 0x12; break; */ + case 0: + case 1000000: + buf[0] = 0x0b; break; + default: + err("spcp825 driver does not support the baudrate " + "requested, using default of 9600."); + } + + /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ + if (cflag & CSIZE) { + switch (cflag & CSIZE) { + case CS5: + buf[1] |= SET_UART_FORMAT_SIZE_5; + break; + case CS6: + buf[1] |= SET_UART_FORMAT_SIZE_6; + break; + case CS7: + buf[1] |= SET_UART_FORMAT_SIZE_7; + break; + default: + case CS8: + buf[1] |= SET_UART_FORMAT_SIZE_8; + break; + } + } + + /* Set Stop bit2 : 0:1bit 1:2bit */ + buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 : + SET_UART_FORMAT_STOP_1; + + /* Set Parity bit3-4 01:Odd 11:Even */ + if (cflag & PARENB) { + buf[1] |= (cflag & PARODD) ? + SET_UART_FORMAT_PAR_ODD : SET_UART_FORMAT_PAR_EVEN ; + } else + buf[1] |= SET_UART_FORMAT_PAR_NONE; + + uartdata = buf[0] | buf[1]<<8; + + i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + SET_UART_FORMAT_TYPE, SET_UART_FORMAT, + uartdata, 0, NULL, 0, 100); + if (i < 0) + err("Set UART format %#x failed (error = %d)", uartdata, i); + dbg("0x21:0x40:0:0 %d\n", i); + + if (cflag & CRTSCTS) { + /* enable hardware flow control */ + spcp8x5_set_workMode(serial->dev, 0x000a, + SET_WORKING_MODE_U2C, priv->type); + } + return; +} + +/* open the serial port. do some usb system call. set termios and get the line + * status of the device. then submit the read urb */ +static int spcp8x5_open(struct usb_serial_port *port, struct file *filp) +{ + struct ktermios tmp_termios; + struct usb_serial *serial = port->serial; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + int ret; + unsigned long flags; + u8 status = 0x30; + /* status 0x30 means DSR and CTS = 1 other CDC RI and delta = 0 */ + + dbg("%s - port %d", __func__, port->number); + + usb_clear_halt(serial->dev, port->write_urb->pipe); + usb_clear_halt(serial->dev, port->read_urb->pipe); + + ret = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + 0x09, 0x00, + 0x01, 0x00, NULL, 0x00, 100); + if (ret) + return ret; + + spin_lock_irqsave(&priv->lock, flags); + if (port->tty->termios->c_cflag & CBAUD) + priv->line_control = MCR_DTR | MCR_RTS; + else + priv->line_control = 0; + spin_unlock_irqrestore(&priv->lock, flags); + + spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type); + + /* Setup termios */ + if (port->tty) + spcp8x5_set_termios(port, &tmp_termios); + + spcp8x5_get_msr(serial->dev, &status, priv->type); + + /* may be we should update uart status here but now we did not do */ + spin_lock_irqsave(&priv->lock, flags); + priv->line_status = status & 0xf0 ; + spin_unlock_irqrestore(&priv->lock, flags); + + /* FIXME: need to assert RTS and DTR if CRTSCTS off */ + + dbg("%s - submitting read urb", __func__); + port->read_urb->dev = serial->dev; + ret = usb_submit_urb(port->read_urb, GFP_KERNEL); + if (ret) { + spcp8x5_close(port, NULL); + return -EPROTO; + } + return 0; +} + +/* bulk read call back function. check the status of the urb. if transfer + * failed return. then update the status and the tty send data to tty subsys. + * submit urb again. + */ +static void spcp8x5_read_bulk_callback(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + struct tty_struct *tty; + unsigned char *data = urb->transfer_buffer; + unsigned long flags; + int i; + int result; + u8 status = 0; + char tty_flag; + + dev_dbg(&port->dev, "start, urb->status = %d, " + "urb->actual_length = %d\n,", urb->status, urb->actual_length); + + /* check the urb status */ + if (urb->status) { + if (!port->open_count) + return; + if (urb->status == -EPROTO) { + /* spcp8x5 mysteriously fails with -EPROTO */ + /* reschedule the read */ + urb->status = 0; + urb->dev = port->serial->dev; + result = usb_submit_urb(urb , GFP_ATOMIC); + if (result) + dev_dbg(&port->dev, + "failed submitting read urb %d\n", + result); + return; + } + dev_dbg(&port->dev, "unable to handle the error, exiting.\n"); + return; + } + + /* get tty_flag from status */ + tty_flag = TTY_NORMAL; + + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + priv->line_status &= ~UART_STATE_TRANSIENT_MASK; + spin_unlock_irqrestore(&priv->lock, flags); + /* wake up the wait for termios */ + wake_up_interruptible(&priv->delta_msr_wait); + + /* break takes precedence over parity, which takes precedence over + * framing errors */ + if (status & UART_BREAK_ERROR) + tty_flag = TTY_BREAK; + else if (status & UART_PARITY_ERROR) + tty_flag = TTY_PARITY; + else if (status & UART_FRAME_ERROR) + tty_flag = TTY_FRAME; + dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); + + tty = port->tty; + if (tty && urb->actual_length) { + tty_buffer_request_room(tty, urb->actual_length + 1); + /* overrun is special, not associated with a char */ + if (status & UART_OVERRUN_ERROR) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + for (i = 0; i < urb->actual_length; ++i) + tty_insert_flip_char(tty, data[i], tty_flag); + tty_flip_buffer_push(tty); + } + + /* Schedule the next read _if_ we are still open */ + if (port->open_count) { + urb->dev = port->serial->dev; + result = usb_submit_urb(urb , GFP_ATOMIC); + if (result) + dev_dbg(&port->dev, "failed submitting read urb %d\n", + result); + } + + return; +} + +/* get data from ring buffer and then write to usb bus */ +static void spcp8x5_send(struct usb_serial_port *port) +{ + int count, result; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->write_urb_in_use) { + dev_dbg(&port->dev, "write urb still used\n"); + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + /* send the 1st urb for writting */ + memset(port->write_urb->transfer_buffer , 0x00 , port->bulk_out_size); + count = get_ringbuf(priv->buf, port->write_urb->transfer_buffer, + port->bulk_out_size); + + if (count == 0) { + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + /* update the urb status */ + priv->write_urb_in_use = 1; + + spin_unlock_irqrestore(&priv->lock, flags); + + port->write_urb->transfer_buffer_length = count; + port->write_urb->dev = port->serial->dev; + + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) { + dev_dbg(&port->dev, "failed submitting write urb, error %d\n", + result); + priv->write_urb_in_use = 0; + /* TODO: reschedule spcp8x5_send */ + } + + + schedule_work(&port->work); +} + +/* this is the call back function for write urb. NOTE we should not sleep in + * this routine. check the urb return code and then submit the write urb again + * to hold the write loop */ +static void spcp8x5_write_bulk_callback(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + int result; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dev_dbg(&port->dev, "urb shutting down with status: %d\n", + urb->status); + priv->write_urb_in_use = 0; + return; + default: + /* error in the urb, so we have to resubmit it */ + dbg("%s - Overflow in write", __func__); + dbg("%s - nonzero write bulk status received: %d", + __func__, urb->status); + port->write_urb->transfer_buffer_length = 1; + port->write_urb->dev = port->serial->dev; + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) + dev_dbg(&port->dev, + "failed resubmitting write urb %d\n", result); + else + return; + } + + priv->write_urb_in_use = 0; + + /* send any buffered data */ + spcp8x5_send(port); +} + +/* write data to ring buffer. and then start the write transfer */ +static int spcp8x5_write(struct usb_serial_port *port, + const unsigned char *buf, int count) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + + dev_dbg(&port->dev, "%d bytes\n", count); + + if (!count) + return count; + + spin_lock_irqsave(&priv->lock, flags); + count = put_ringbuf(priv->buf, buf, count); + spin_unlock_irqrestore(&priv->lock, flags); + + spcp8x5_send(port); + + return count; +} + +static int spcp8x5_wait_modem_info(struct usb_serial_port *port, + unsigned int arg) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int prevstatus; + unsigned int status; + unsigned int changed; + + spin_lock_irqsave(&priv->lock, flags); + prevstatus = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); + + while (1) { + /* wake up in bulk read */ + interruptible_sleep_on(&priv->delta_msr_wait); + + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); + + changed = prevstatus^status; + + if (((arg & TIOCM_RNG) && (changed & MSR_STATUS_LINE_RI)) || + ((arg & TIOCM_DSR) && (changed & MSR_STATUS_LINE_DSR)) || + ((arg & TIOCM_CD) && (changed & MSR_STATUS_LINE_DCD)) || + ((arg & TIOCM_CTS) && (changed & MSR_STATUS_LINE_CTS))) + return 0; + + prevstatus = status; + } + /* NOTREACHED */ + return 0; +} + +static int spcp8x5_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) +{ + dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); + + switch (cmd) { + case TIOCMIWAIT: + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); + return spcp8x5_wait_modem_info(port, arg); + + default: + dbg("%s not supported = 0x%04x", __func__, cmd); + break; + } + + return -ENOIOCTLCMD; +} + +static int spcp8x5_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + u8 control; + + spin_lock_irqsave(&priv->lock, flags); + if (set & TIOCM_RTS) + priv->line_control |= MCR_RTS; + if (set & TIOCM_DTR) + priv->line_control |= MCR_DTR; + if (clear & TIOCM_RTS) + priv->line_control &= ~MCR_RTS; + if (clear & TIOCM_DTR) + priv->line_control &= ~MCR_DTR; + control = priv->line_control; + spin_unlock_irqrestore(&priv->lock, flags); + + return spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); +} + +static int spcp8x5_tiocmget(struct usb_serial_port *port, struct file *file) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int mcr; + unsigned int status; + unsigned int result; + + spin_lock_irqsave(&priv->lock, flags); + mcr = priv->line_control; + status = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); + + result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) + | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) + | ((status & MSR_STATUS_LINE_CTS) ? TIOCM_CTS : 0) + | ((status & MSR_STATUS_LINE_DSR) ? TIOCM_DSR : 0) + | ((status & MSR_STATUS_LINE_RI) ? TIOCM_RI : 0) + | ((status & MSR_STATUS_LINE_DCD) ? TIOCM_CD : 0); + + return result; +} + +/* get the avail space room in ring buffer */ +static int spcp8x5_write_room(struct usb_serial_port *port) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + int room = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + room = ringbuf_avail_space(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); + + return room; +} + +/* get the number of avail data in write ring buffer */ +static int spcp8x5_chars_in_buffer(struct usb_serial_port *port) +{ + struct spcp8x5_private *priv = usb_get_serial_port_data(port); + int chars = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + chars = ringbuf_avail_data(priv->buf); + spin_unlock_irqrestore(&priv->lock, flags); + + return chars; +} + +/* All of the device info needed for the spcp8x5 SIO serial converter */ +static struct usb_serial_driver spcp8x5_device = { + .driver = { + .owner = THIS_MODULE, + .name = "SPCP8x5", + }, + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = spcp8x5_open, + .close = spcp8x5_close, + .write = spcp8x5_write, + .set_termios = spcp8x5_set_termios, + .ioctl = spcp8x5_ioctl, + .tiocmget = spcp8x5_tiocmget, + .tiocmset = spcp8x5_tiocmset, + .write_room = spcp8x5_write_room, + .read_bulk_callback = spcp8x5_read_bulk_callback, + .write_bulk_callback = spcp8x5_write_bulk_callback, + .chars_in_buffer = spcp8x5_chars_in_buffer, + .attach = spcp8x5_startup, + .shutdown = spcp8x5_shutdown, +}; + +static int __init spcp8x5_init(void) +{ + int retval; + retval = usb_serial_register(&spcp8x5_device); + if (retval) + goto failed_usb_serial_register; + retval = usb_register(&spcp8x5_driver); + if (retval) + goto failed_usb_register; + info(DRIVER_DESC " " DRIVER_VERSION); + return 0; +failed_usb_register: + usb_serial_deregister(&spcp8x5_device); +failed_usb_serial_register: + return retval; +} + +static void __exit spcp8x5_exit(void) +{ + usb_deregister(&spcp8x5_driver); + usb_serial_deregister(&spcp8x5_device); +} + +module_init(spcp8x5_init); +module_exit(spcp8x5_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); -- cgit v1.2.2 From b40f8d3980d3eef26b3bd77da5314728a5b30aea Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Sun, 23 Mar 2008 00:00:01 -0700 Subject: usb: u132-hcd driver style clean up I was converting a semaphore in this file to a mutex when I noticed that this file has some fairly rampant style problems. Practically every line has spaces instead of tabs .. Once I cleared that up, checkpatch.pl showed a number of other problem.. I think this file might be a good one to review for new style checks that could be added.. Below are the only two remaining which I didn't remove. #5083: FILE: drivers/usb/host/u132-hcd.c:2907: + error: WARNING: labels should not be indented #5087: FILE: drivers/usb/host/u132-hcd.c:2911: + stall: These labels are actually inside a switch statement, and they are right under "default:". "default:" appears to be exempt and these other label should be too, or default shouldn't be exempt. I also deleted a few lines due to single statements inside { } , if (is_error()) { return; } becomes, if (is_error()) return; with one line deleted. Signed-off-by: Daniel Walker Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 5132 +++++++++++++++++++++---------------------- 1 file changed, 2563 insertions(+), 2569 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 6e9b7edff528..28b8684942d3 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -67,7 +67,7 @@ #include "ohci.h" #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ - OHCI_INTR_WDH) + OHCI_INTR_WDH) MODULE_AUTHOR("Tony Olech - Elan Digital Systems Limited"); MODULE_DESCRIPTION("U132 USB Host Controller Driver"); MODULE_LICENSE("GPL"); @@ -77,15 +77,15 @@ INT_MODULE_PARM(testing, 0); static int distrust_firmware = 1; module_param(distrust_firmware, bool, 0); MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" - "t setup"); + "t setup"); static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); /* * u132_module_lock exists to protect access to global variables * */ static struct mutex u132_module_lock; -static int u132_exiting = 0; -static int u132_instances = 0; +static int u132_exiting; +static int u132_instances; static struct list_head u132_static_list; /* * end of the global variables protected by u132_module_lock @@ -97,115 +97,115 @@ static struct workqueue_struct *workqueue; #define MAX_U132_ENDPS 100 #define MAX_U132_RINGS 4 static const char *cc_to_text[16] = { - "No Error ", - "CRC Error ", - "Bit Stuff ", - "Data Togg ", - "Stall ", - "DevNotResp ", - "PIDCheck ", - "UnExpPID ", - "DataOver ", - "DataUnder ", - "(for hw) ", - "(for hw) ", - "BufferOver ", - "BuffUnder ", - "(for HCD) ", - "(for HCD) " + "No Error ", + "CRC Error ", + "Bit Stuff ", + "Data Togg ", + "Stall ", + "DevNotResp ", + "PIDCheck ", + "UnExpPID ", + "DataOver ", + "DataUnder ", + "(for hw) ", + "(for hw) ", + "BufferOver ", + "BuffUnder ", + "(for HCD) ", + "(for HCD) " }; struct u132_port { - struct u132 *u132; - int reset; - int enable; - int power; - int Status; + struct u132 *u132; + int reset; + int enable; + int power; + int Status; }; struct u132_addr { - u8 address; + u8 address; }; struct u132_udev { - struct kref kref; - struct usb_device *usb_device; - u8 enumeration; - u8 udev_number; - u8 usb_addr; - u8 portnumber; - u8 endp_number_in[16]; - u8 endp_number_out[16]; + struct kref kref; + struct usb_device *usb_device; + u8 enumeration; + u8 udev_number; + u8 usb_addr; + u8 portnumber; + u8 endp_number_in[16]; + u8 endp_number_out[16]; }; #define ENDP_QUEUE_SHIFT 3 #define ENDP_QUEUE_SIZE (1<platform_dev, offsetof(struct \ - ohci_regs, member), 0, data); + usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ + ohci_regs, member), 0, data); #define u132_write_pcimem(u132, member, data) \ - usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ - ohci_regs, member), 0, data); + usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ + ohci_regs, member), 0, data); static inline struct u132 *udev_to_u132(struct u132_udev *udev) { - u8 udev_number = udev->udev_number; - return container_of(udev, struct u132, udev[udev_number]); + u8 udev_number = udev->udev_number; + return container_of(udev, struct u132, udev[udev_number]); } static inline struct u132 *hcd_to_u132(struct usb_hcd *hcd) { - return (struct u132 *)(hcd->hcd_priv); + return (struct u132 *)(hcd->hcd_priv); } static inline struct usb_hcd *u132_to_hcd(struct u132 *u132) { - return container_of((void *)u132, struct usb_hcd, hcd_priv); + return container_of((void *)u132, struct usb_hcd, hcd_priv); } static inline void u132_disable(struct u132 *u132) { - u132_to_hcd(u132)->state = HC_STATE_HALT; + u132_to_hcd(u132)->state = HC_STATE_HALT; } @@ -250,147 +250,147 @@ static inline void u132_disable(struct u132 *u132) #include "../misc/usb_u132.h" static const char hcd_name[] = "u132_hcd"; #define PORT_C_MASK ((USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | \ - USB_PORT_STAT_C_SUSPEND | USB_PORT_STAT_C_OVERCURRENT | \ - USB_PORT_STAT_C_RESET) << 16) + USB_PORT_STAT_C_SUSPEND | USB_PORT_STAT_C_OVERCURRENT | \ + USB_PORT_STAT_C_RESET) << 16) static void u132_hcd_delete(struct kref *kref) { - struct u132 *u132 = kref_to_u132(kref); - struct platform_device *pdev = u132->platform_dev; - struct usb_hcd *hcd = u132_to_hcd(u132); - u132->going += 1; - mutex_lock(&u132_module_lock); - list_del_init(&u132->u132_list); - u132_instances -= 1; - mutex_unlock(&u132_module_lock); - dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" - "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); - usb_put_hcd(hcd); + struct u132 *u132 = kref_to_u132(kref); + struct platform_device *pdev = u132->platform_dev; + struct usb_hcd *hcd = u132_to_hcd(u132); + u132->going += 1; + mutex_lock(&u132_module_lock); + list_del_init(&u132->u132_list); + u132_instances -= 1; + mutex_unlock(&u132_module_lock); + dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" + "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); + usb_put_hcd(hcd); } static inline void u132_u132_put_kref(struct u132 *u132) { - kref_put(&u132->kref, u132_hcd_delete); + kref_put(&u132->kref, u132_hcd_delete); } static inline void u132_u132_init_kref(struct u132 *u132) { - kref_init(&u132->kref); + kref_init(&u132->kref); } static void u132_udev_delete(struct kref *kref) { - struct u132_udev *udev = kref_to_u132_udev(kref); - udev->udev_number = 0; - udev->usb_device = NULL; - udev->usb_addr = 0; - udev->enumeration = 0; + struct u132_udev *udev = kref_to_u132_udev(kref); + udev->udev_number = 0; + udev->usb_device = NULL; + udev->usb_addr = 0; + udev->enumeration = 0; } static inline void u132_udev_put_kref(struct u132 *u132, struct u132_udev *udev) { - kref_put(&udev->kref, u132_udev_delete); + kref_put(&udev->kref, u132_udev_delete); } static inline void u132_udev_get_kref(struct u132 *u132, struct u132_udev *udev) { - kref_get(&udev->kref); + kref_get(&udev->kref); } static inline void u132_udev_init_kref(struct u132 *u132, - struct u132_udev *udev) + struct u132_udev *udev) { - kref_init(&udev->kref); + kref_init(&udev->kref); } static inline void u132_ring_put_kref(struct u132 *u132, struct u132_ring *ring) { - kref_put(&u132->kref, u132_hcd_delete); + kref_put(&u132->kref, u132_hcd_delete); } static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring, - unsigned int delta) + unsigned int delta) { - if (delta > 0) { - if (queue_delayed_work(workqueue, &ring->scheduler, delta)) - return; - } else if (queue_delayed_work(workqueue, &ring->scheduler, 0)) - return; - kref_put(&u132->kref, u132_hcd_delete); - return; + if (delta > 0) { + if (queue_delayed_work(workqueue, &ring->scheduler, delta)) + return; + } else if (queue_delayed_work(workqueue, &ring->scheduler, 0)) + return; + kref_put(&u132->kref, u132_hcd_delete); + return; } static void u132_ring_queue_work(struct u132 *u132, struct u132_ring *ring, - unsigned int delta) + unsigned int delta) { - kref_get(&u132->kref); - u132_ring_requeue_work(u132, ring, delta); - return; + kref_get(&u132->kref); + u132_ring_requeue_work(u132, ring, delta); + return; } static void u132_ring_cancel_work(struct u132 *u132, struct u132_ring *ring) { - if (cancel_delayed_work(&ring->scheduler)) { - kref_put(&u132->kref, u132_hcd_delete); - } + if (cancel_delayed_work(&ring->scheduler)) + kref_put(&u132->kref, u132_hcd_delete); } static void u132_endp_delete(struct kref *kref) { - struct u132_endp *endp = kref_to_u132_endp(kref); - struct u132 *u132 = endp->u132; - u8 usb_addr = endp->usb_addr; - u8 usb_endp = endp->usb_endp; - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - u8 endp_number = endp->endp_number; - struct usb_host_endpoint *hep = endp->hep; - struct u132_ring *ring = endp->ring; - struct list_head *head = &endp->endp_ring; - ring->length -= 1; - if (endp == ring->curr_endp) { - if (list_empty(head)) { - ring->curr_endp = NULL; - list_del(head); - } else { - struct u132_endp *next_endp = list_entry(head->next, - struct u132_endp, endp_ring); - ring->curr_endp = next_endp; - list_del(head); - }} else - list_del(head); - if (endp->input) { - udev->endp_number_in[usb_endp] = 0; - u132_udev_put_kref(u132, udev); - } - if (endp->output) { - udev->endp_number_out[usb_endp] = 0; - u132_udev_put_kref(u132, udev); - } - u132->endp[endp_number - 1] = NULL; - hep->hcpriv = NULL; - kfree(endp); - u132_u132_put_kref(u132); + struct u132_endp *endp = kref_to_u132_endp(kref); + struct u132 *u132 = endp->u132; + u8 usb_addr = endp->usb_addr; + u8 usb_endp = endp->usb_endp; + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + u8 endp_number = endp->endp_number; + struct usb_host_endpoint *hep = endp->hep; + struct u132_ring *ring = endp->ring; + struct list_head *head = &endp->endp_ring; + ring->length -= 1; + if (endp == ring->curr_endp) { + if (list_empty(head)) { + ring->curr_endp = NULL; + list_del(head); + } else { + struct u132_endp *next_endp = list_entry(head->next, + struct u132_endp, endp_ring); + ring->curr_endp = next_endp; + list_del(head); + } + } else + list_del(head); + if (endp->input) { + udev->endp_number_in[usb_endp] = 0; + u132_udev_put_kref(u132, udev); + } + if (endp->output) { + udev->endp_number_out[usb_endp] = 0; + u132_udev_put_kref(u132, udev); + } + u132->endp[endp_number - 1] = NULL; + hep->hcpriv = NULL; + kfree(endp); + u132_u132_put_kref(u132); } static inline void u132_endp_put_kref(struct u132 *u132, struct u132_endp *endp) { - kref_put(&endp->kref, u132_endp_delete); + kref_put(&endp->kref, u132_endp_delete); } static inline void u132_endp_get_kref(struct u132 *u132, struct u132_endp *endp) { - kref_get(&endp->kref); + kref_get(&endp->kref); } static inline void u132_endp_init_kref(struct u132 *u132, - struct u132_endp *endp) + struct u132_endp *endp) { - kref_init(&endp->kref); - kref_get(&u132->kref); + kref_init(&endp->kref); + kref_get(&u132->kref); } static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp, - unsigned int delta) + unsigned int delta) { if (queue_delayed_work(workqueue, &endp->scheduler, delta)) kref_get(&endp->kref); @@ -398,13 +398,13 @@ static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp, static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp) { - if (cancel_delayed_work(&endp->scheduler)) - kref_put(&endp->kref, u132_endp_delete); + if (cancel_delayed_work(&endp->scheduler)) + kref_put(&endp->kref, u132_endp_delete); } static inline void u132_monitor_put_kref(struct u132 *u132) { - kref_put(&u132->kref, u132_hcd_delete); + kref_put(&u132->kref, u132_hcd_delete); } static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta) @@ -421,200 +421,201 @@ static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta) static void u132_monitor_cancel_work(struct u132 *u132) { - if (cancel_delayed_work(&u132->monitor)) - kref_put(&u132->kref, u132_hcd_delete); + if (cancel_delayed_work(&u132->monitor)) + kref_put(&u132->kref, u132_hcd_delete); } static int read_roothub_info(struct u132 *u132) { - u32 revision; - int retval; - retval = u132_read_pcimem(u132, revision, &revision); - if (retval) { - dev_err(&u132->platform_dev->dev, "error %d accessing device co" - "ntrol\n", retval); - return retval; - } else if ((revision & 0xFF) == 0x10) { - } else if ((revision & 0xFF) == 0x11) { - } else { - dev_err(&u132->platform_dev->dev, "device revision is not valid" - " %08X\n", revision); - return -ENODEV; - } - retval = u132_read_pcimem(u132, control, &u132->hc_control); - if (retval) { - dev_err(&u132->platform_dev->dev, "error %d accessing device co" - "ntrol\n", retval); - return retval; - } - retval = u132_read_pcimem(u132, roothub.status, - &u132->hc_roothub_status); - if (retval) { - dev_err(&u132->platform_dev->dev, "error %d accessing device re" - "g roothub.status\n", retval); - return retval; - } - retval = u132_read_pcimem(u132, roothub.a, &u132->hc_roothub_a); - if (retval) { - dev_err(&u132->platform_dev->dev, "error %d accessing device re" - "g roothub.a\n", retval); - return retval; - } - { - int I = u132->num_ports; - int i = 0; - while (I-- > 0) { - retval = u132_read_pcimem(u132, roothub.portstatus[i], - &u132->hc_roothub_portstatus[i]); - if (retval) { - dev_err(&u132->platform_dev->dev, "error %d acc" - "essing device roothub.portstatus[%d]\n" - , retval, i); - return retval; - } else - i += 1; - } - } - return 0; + u32 revision; + int retval; + retval = u132_read_pcimem(u132, revision, &revision); + if (retval) { + dev_err(&u132->platform_dev->dev, "error %d accessing device co" + "ntrol\n", retval); + return retval; + } else if ((revision & 0xFF) == 0x10) { + } else if ((revision & 0xFF) == 0x11) { + } else { + dev_err(&u132->platform_dev->dev, "device revision is not valid" + " %08X\n", revision); + return -ENODEV; + } + retval = u132_read_pcimem(u132, control, &u132->hc_control); + if (retval) { + dev_err(&u132->platform_dev->dev, "error %d accessing device co" + "ntrol\n", retval); + return retval; + } + retval = u132_read_pcimem(u132, roothub.status, + &u132->hc_roothub_status); + if (retval) { + dev_err(&u132->platform_dev->dev, "error %d accessing device re" + "g roothub.status\n", retval); + return retval; + } + retval = u132_read_pcimem(u132, roothub.a, &u132->hc_roothub_a); + if (retval) { + dev_err(&u132->platform_dev->dev, "error %d accessing device re" + "g roothub.a\n", retval); + return retval; + } + { + int I = u132->num_ports; + int i = 0; + while (I-- > 0) { + retval = u132_read_pcimem(u132, roothub.portstatus[i], + &u132->hc_roothub_portstatus[i]); + if (retval) { + dev_err(&u132->platform_dev->dev, "error %d acc" + "essing device roothub.portstatus[%d]\n" + , retval, i); + return retval; + } else + i += 1; + } + } + return 0; } static void u132_hcd_monitor_work(struct work_struct *work) { - struct u132 *u132 = container_of(work, struct u132, monitor.work); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - u132_monitor_put_kref(u132); - return; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - u132_monitor_put_kref(u132); - return; - } else { - int retval; - mutex_lock(&u132->sw_lock); - retval = read_roothub_info(u132); - if (retval) { - struct usb_hcd *hcd = u132_to_hcd(u132); - u132_disable(u132); - u132->going = 1; - mutex_unlock(&u132->sw_lock); - usb_hc_died(hcd); - ftdi_elan_gone_away(u132->platform_dev); - u132_monitor_put_kref(u132); - return; - } else { - u132_monitor_requeue_work(u132, 500); - mutex_unlock(&u132->sw_lock); - return; - } - } + struct u132 *u132 = container_of(work, struct u132, monitor.work); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + u132_monitor_put_kref(u132); + return; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + u132_monitor_put_kref(u132); + return; + } else { + int retval; + mutex_lock(&u132->sw_lock); + retval = read_roothub_info(u132); + if (retval) { + struct usb_hcd *hcd = u132_to_hcd(u132); + u132_disable(u132); + u132->going = 1; + mutex_unlock(&u132->sw_lock); + usb_hc_died(hcd); + ftdi_elan_gone_away(u132->platform_dev); + u132_monitor_put_kref(u132); + return; + } else { + u132_monitor_requeue_work(u132, 500); + mutex_unlock(&u132->sw_lock); + return; + } + } } static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, - struct urb *urb, int status) + struct urb *urb, int status) { - struct u132_ring *ring; - unsigned long irqs; - struct usb_hcd *hcd = u132_to_hcd(u132); - urb->error_count = 0; - spin_lock_irqsave(&endp->queue_lock.slock, irqs); + struct u132_ring *ring; + unsigned long irqs; + struct usb_hcd *hcd = u132_to_hcd(u132); + urb->error_count = 0; + spin_lock_irqsave(&endp->queue_lock.slock, irqs); usb_hcd_unlink_urb_from_ep(hcd, urb); - endp->queue_next += 1; - if (ENDP_QUEUE_SIZE > --endp->queue_size) { - endp->active = 0; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - } else { - struct list_head *next = endp->urb_more.next; - struct u132_urbq *urbq = list_entry(next, struct u132_urbq, - urb_more); - list_del(next); - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = - urbq->urb; - endp->active = 0; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - kfree(urbq); - } down(&u132->scheduler_lock); - ring = endp->ring; - ring->in_use = 0; - u132_ring_cancel_work(u132, ring); - u132_ring_queue_work(u132, ring, 0); - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); + endp->queue_next += 1; + if (ENDP_QUEUE_SIZE > --endp->queue_size) { + endp->active = 0; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + } else { + struct list_head *next = endp->urb_more.next; + struct u132_urbq *urbq = list_entry(next, struct u132_urbq, + urb_more); + list_del(next); + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = + urbq->urb; + endp->active = 0; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + kfree(urbq); + } + down(&u132->scheduler_lock); + ring = endp->ring; + ring->in_use = 0; + u132_ring_cancel_work(u132, ring); + u132_ring_queue_work(u132, ring, 0); + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); usb_hcd_giveback_urb(hcd, urb, status); - return; + return; } static void u132_hcd_forget_urb(struct u132 *u132, struct u132_endp *endp, - struct urb *urb, int status) + struct urb *urb, int status) { - u132_endp_put_kref(u132, endp); + u132_endp_put_kref(u132, endp); } static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, - struct urb *urb, int status) + struct urb *urb, int status) { - unsigned long irqs; - struct usb_hcd *hcd = u132_to_hcd(u132); - urb->error_count = 0; - spin_lock_irqsave(&endp->queue_lock.slock, irqs); + unsigned long irqs; + struct usb_hcd *hcd = u132_to_hcd(u132); + urb->error_count = 0; + spin_lock_irqsave(&endp->queue_lock.slock, irqs); usb_hcd_unlink_urb_from_ep(hcd, urb); - endp->queue_next += 1; - if (ENDP_QUEUE_SIZE > --endp->queue_size) { - endp->active = 0; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - } else { - struct list_head *next = endp->urb_more.next; - struct u132_urbq *urbq = list_entry(next, struct u132_urbq, - urb_more); - list_del(next); - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = - urbq->urb; - endp->active = 0; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - kfree(urbq); + endp->queue_next += 1; + if (ENDP_QUEUE_SIZE > --endp->queue_size) { + endp->active = 0; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + } else { + struct list_head *next = endp->urb_more.next; + struct u132_urbq *urbq = list_entry(next, struct u132_urbq, + urb_more); + list_del(next); + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = + urbq->urb; + endp->active = 0; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + kfree(urbq); } usb_hcd_giveback_urb(hcd, urb, status); - return; + return; } static inline int edset_input(struct u132 *u132, struct u132_ring *ring, - struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, - void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, - int toggle_bits, int error_count, int condition_code, int repeat_number, - int halted, int skipped, int actual, int non_null)) + struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, + void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, + int toggle_bits, int error_count, int condition_code, int repeat_number, + int halted, int skipped, int actual, int non_null)) { - return usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, - urb, address, endp->usb_endp, toggle_bits, callback); + return usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, + urb, address, endp->usb_endp, toggle_bits, callback); } static inline int edset_setup(struct u132 *u132, struct u132_ring *ring, - struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, - void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, - int toggle_bits, int error_count, int condition_code, int repeat_number, - int halted, int skipped, int actual, int non_null)) + struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, + void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, + int toggle_bits, int error_count, int condition_code, int repeat_number, + int halted, int skipped, int actual, int non_null)) { - return usb_ftdi_elan_edset_setup(u132->platform_dev, ring->number, endp, - urb, address, endp->usb_endp, toggle_bits, callback); + return usb_ftdi_elan_edset_setup(u132->platform_dev, ring->number, endp, + urb, address, endp->usb_endp, toggle_bits, callback); } static inline int edset_single(struct u132 *u132, struct u132_ring *ring, - struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, - void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, - int toggle_bits, int error_count, int condition_code, int repeat_number, - int halted, int skipped, int actual, int non_null)) + struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, + void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, + int toggle_bits, int error_count, int condition_code, int repeat_number, + int halted, int skipped, int actual, int non_null)) { - return usb_ftdi_elan_edset_single(u132->platform_dev, ring->number, - endp, urb, address, endp->usb_endp, toggle_bits, callback); + return usb_ftdi_elan_edset_single(u132->platform_dev, ring->number, + endp, urb, address, endp->usb_endp, toggle_bits, callback); } static inline int edset_output(struct u132 *u132, struct u132_ring *ring, - struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, - void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, - int toggle_bits, int error_count, int condition_code, int repeat_number, - int halted, int skipped, int actual, int non_null)) + struct u132_endp *endp, struct urb *urb, u8 address, u8 toggle_bits, + void (*callback) (void *endp, struct urb *urb, u8 *buf, int len, + int toggle_bits, int error_count, int condition_code, int repeat_number, + int halted, int skipped, int actual, int non_null)) { - return usb_ftdi_elan_edset_output(u132->platform_dev, ring->number, - endp, urb, address, endp->usb_endp, toggle_bits, callback); + return usb_ftdi_elan_edset_output(u132->platform_dev, ring->number, + endp, urb, address, endp->usb_endp, toggle_bits, callback); } @@ -623,683 +624,678 @@ static inline int edset_output(struct u132 *u132, struct u132_ring *ring, * */ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - struct u132_ring *ring = endp->ring; - u8 *u = urb->transfer_buffer + urb->actual_length; - u8 *b = buf; - int L = len; - while (L-- > 0) { - *u++ = *b++; - } - urb->actual_length += len; - if ((condition_code == TD_CC_NOERROR) && - (urb->transfer_buffer_length > urb->actual_length)) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - if (urb->actual_length > 0) { - int retval; - up(&u132->scheduler_lock); - retval = edset_single(u132, ring, endp, urb, - address, endp->toggle_bits, - u132_hcd_interrupt_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, - retval); - } else { - ring->in_use = 0; - endp->active = 0; - endp->jiffies = jiffies + - msecs_to_jiffies(urb->interval); - u132_ring_cancel_work(u132, ring); - u132_ring_queue_work(u132, ring, 0); - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - } - return; - } else if ((condition_code == TD_DATAUNDERRUN) && - ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else { - if (condition_code == TD_CC_NOERROR) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, - 0, 1 & toggle_bits); - } else if (condition_code == TD_CC_STALL) { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, endp->usb_endp, - 0, 0); - } else { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, endp->usb_endp, - 0, 0); - dev_err(&u132->platform_dev->dev, "urb=%p givin" - "g back INTERRUPT %s\n", urb, - cc_to_text[condition_code]); - } - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } - } else { + struct u132_ring *ring = endp->ring; + u8 *u = urb->transfer_buffer + urb->actual_length; + u8 *b = buf; + int L = len; + + while (L-- > 0) + *u++ = *b++; + + urb->actual_length += len; + if ((condition_code == TD_CC_NOERROR) && + (urb->transfer_buffer_length > urb->actual_length)) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + if (urb->actual_length > 0) { + int retval; + up(&u132->scheduler_lock); + retval = edset_single(u132, ring, endp, urb, + address, endp->toggle_bits, + u132_hcd_interrupt_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, + retval); + } else { + ring->in_use = 0; + endp->active = 0; + endp->jiffies = jiffies + + msecs_to_jiffies(urb->interval); + u132_ring_cancel_work(u132, ring); + u132_ring_queue_work(u132, ring, 0); + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + } + return; + } else if ((condition_code == TD_DATAUNDERRUN) && + ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else { + if (condition_code == TD_CC_NOERROR) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, + 0, 1 & toggle_bits); + } else if (condition_code == TD_CC_STALL) { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, endp->usb_endp, + 0, 0); + } else { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, endp->usb_endp, + 0, 0); + dev_err(&u132->platform_dev->dev, "urb=%p givin" + "g back INTERRUPT %s\n", urb, + cc_to_text[condition_code]); + } + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - struct u132_ring *ring = endp->ring; - urb->actual_length += len; - endp->toggle_bits = toggle_bits; - if (urb->transfer_buffer_length > urb->actual_length) { - int retval; - up(&u132->scheduler_lock); - retval = edset_output(u132, ring, endp, urb, address, - endp->toggle_bits, u132_hcd_bulk_output_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } - } else { + struct u132_ring *ring = endp->ring; + urb->actual_length += len; + endp->toggle_bits = toggle_bits; + if (urb->transfer_buffer_length > urb->actual_length) { + int retval; + up(&u132->scheduler_lock); + retval = edset_output(u132, ring, endp, urb, address, + endp->toggle_bits, u132_hcd_bulk_output_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - struct u132_ring *ring = endp->ring; - u8 *u = urb->transfer_buffer + urb->actual_length; - u8 *b = buf; - int L = len; - while (L-- > 0) { - *u++ = *b++; - } - urb->actual_length += len; - if ((condition_code == TD_CC_NOERROR) && - (urb->transfer_buffer_length > urb->actual_length)) { - int retval; - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_input(u132->platform_dev, - ring->number, endp, urb, address, - endp->usb_endp, endp->toggle_bits, - u132_hcd_bulk_input_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else if (condition_code == TD_CC_NOERROR) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } else if ((condition_code == TD_DATAUNDERRUN) && - ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else if (condition_code == TD_DATAUNDERRUN) { - endp->toggle_bits = toggle_bits; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, - 1 & toggle_bits); - dev_warn(&u132->platform_dev->dev, "urb=%p(SHORT NOT OK" - ") giving back BULK IN %s\n", urb, - cc_to_text[condition_code]); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else if (condition_code == TD_CC_STALL) { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } else { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0); - dev_err(&u132->platform_dev->dev, "urb=%p giving back B" - "ULK IN code=%d %s\n", urb, condition_code, - cc_to_text[condition_code]); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } - } else { + struct u132_ring *ring = endp->ring; + u8 *u = urb->transfer_buffer + urb->actual_length; + u8 *b = buf; + int L = len; + + while (L-- > 0) + *u++ = *b++; + + urb->actual_length += len; + if ((condition_code == TD_CC_NOERROR) && + (urb->transfer_buffer_length > urb->actual_length)) { + int retval; + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_input(u132->platform_dev, + ring->number, endp, urb, address, + endp->usb_endp, endp->toggle_bits, + u132_hcd_bulk_input_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else if (condition_code == TD_CC_NOERROR) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } else if ((condition_code == TD_DATAUNDERRUN) && + ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else if (condition_code == TD_DATAUNDERRUN) { + endp->toggle_bits = toggle_bits; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, + 1 & toggle_bits); + dev_warn(&u132->platform_dev->dev, "urb=%p(SHORT NOT OK" + ") giving back BULK IN %s\n", urb, + cc_to_text[condition_code]); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else if (condition_code == TD_CC_STALL) { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } else { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0); + dev_err(&u132->platform_dev->dev, "urb=%p giving back B" + "ULK IN code=%d %s\n", urb, condition_code, + cc_to_text[condition_code]); + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else { + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - struct u132_ring *ring = endp->ring; - u8 *u = urb->transfer_buffer; - u8 *b = buf; - int L = len; - while (L-- > 0) { - *u++ = *b++; - } - urb->actual_length = len; - if ((condition_code == TD_CC_NOERROR) || ((condition_code == - TD_DATAUNDERRUN) && ((urb->transfer_flags & - URB_SHORT_NOT_OK) == 0))) { - int retval; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_empty(u132->platform_dev, - ring->number, endp, urb, address, - endp->usb_endp, 0x3, - u132_hcd_configure_empty_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else if (condition_code == TD_CC_STALL) { - up(&u132->scheduler_lock); - dev_warn(&u132->platform_dev->dev, "giving back SETUP I" - "NPUT STALL urb %p\n", urb); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } else { - up(&u132->scheduler_lock); - dev_err(&u132->platform_dev->dev, "giving back SETUP IN" - "PUT %s urb %p\n", cc_to_text[condition_code], - urb); - u132_hcd_giveback_urb(u132, endp, urb, - cc_to_error[condition_code]); - return; - } - } else { + struct u132_ring *ring = endp->ring; + u8 *u = urb->transfer_buffer; + u8 *b = buf; + int L = len; + + while (L-- > 0) + *u++ = *b++; + + urb->actual_length = len; + if ((condition_code == TD_CC_NOERROR) || ((condition_code == + TD_DATAUNDERRUN) && ((urb->transfer_flags & + URB_SHORT_NOT_OK) == 0))) { + int retval; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_empty(u132->platform_dev, + ring->number, endp, urb, address, + endp->usb_endp, 0x3, + u132_hcd_configure_empty_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else if (condition_code == TD_CC_STALL) { + up(&u132->scheduler_lock); + dev_warn(&u132->platform_dev->dev, "giving back SETUP I" + "NPUT STALL urb %p\n", urb); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } else { + up(&u132->scheduler_lock); + dev_err(&u132->platform_dev->dev, "giving back SETUP IN" + "PUT %s urb %p\n", cc_to_text[condition_code], + urb); + u132_hcd_giveback_urb(u132, endp, urb, + cc_to_error[condition_code]); + return; + } + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else { + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - if (usb_pipein(urb->pipe)) { - int retval; - struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_input(u132->platform_dev, - ring->number, endp, urb, address, - endp->usb_endp, 0, - u132_hcd_configure_input_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { - int retval; - struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_input(u132->platform_dev, - ring->number, endp, urb, address, - endp->usb_endp, 0, - u132_hcd_configure_empty_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } - } else { + if (usb_pipein(urb->pipe)) { + int retval; + struct u132_ring *ring = endp->ring; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_input(u132->platform_dev, + ring->number, endp, urb, address, + endp->usb_endp, 0, + u132_hcd_configure_input_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { + int retval; + struct u132_ring *ring = endp->ring; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_input(u132->platform_dev, + ring->number, endp, urb, address, + endp->usb_endp, 0, + u132_hcd_configure_empty_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, - u8 *buf, int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + u8 *buf, int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - u132->addr[0].address = 0; - endp->usb_addr = udev->usb_addr; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else { + u132->addr[0].address = 0; + endp->usb_addr = udev->usb_addr; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, - u8 *buf, int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + u8 *buf, int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - int retval; - struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_input(u132->platform_dev, - ring->number, endp, urb, 0, endp->usb_endp, 0, - u132_hcd_enumeration_empty_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { + int retval; + struct u132_ring *ring = endp->ring; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_input(u132->platform_dev, + ring->number, endp, urb, 0, endp->usb_endp, 0, + u132_hcd_enumeration_empty_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } else { + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, 0); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - int retval; - struct u132_ring *ring = endp->ring; - u8 *u = urb->transfer_buffer; - u8 *b = buf; - int L = len; - while (L-- > 0) { - *u++ = *b++; - } - urb->actual_length = len; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_empty(u132->platform_dev, - ring->number, endp, urb, address, endp->usb_endp, 0x3, - u132_hcd_initial_empty_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { + int retval; + struct u132_ring *ring = endp->ring; + u8 *u = urb->transfer_buffer; + u8 *b = buf; + int L = len; + + while (L-- > 0) + *u++ = *b++; + + urb->actual_length = len; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_empty(u132->platform_dev, + ring->number, endp, urb, address, endp->usb_endp, 0x3, + u132_hcd_initial_empty_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, - int len, int toggle_bits, int error_count, int condition_code, - int repeat_number, int halted, int skipped, int actual, int non_null) -{ - struct u132_endp *endp = data; - struct u132 *u132 = endp->u132; - u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - up(&u132->scheduler_lock); - u132_hcd_forget_urb(u132, endp, urb, -ENODEV); - return; - } else if (endp->dequeueing) { - endp->dequeueing = 0; - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -EINTR); - return; - } else if (u132->going > 0) { + int len, int toggle_bits, int error_count, int condition_code, + int repeat_number, int halted, int skipped, int actual, int non_null) +{ + struct u132_endp *endp = data; + struct u132 *u132 = endp->u132; + u8 address = u132->addr[endp->usb_addr].address; + down(&u132->scheduler_lock); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + up(&u132->scheduler_lock); + u132_hcd_forget_urb(u132, endp, urb, -ENODEV); + return; + } else if (endp->dequeueing) { + endp->dequeueing = 0; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -EINTR); + return; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); - return; + up(&u132->scheduler_lock); + u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); + return; } else if (!urb->unlinked) { - int retval; - struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); - retval = usb_ftdi_elan_edset_input(u132->platform_dev, - ring->number, endp, urb, address, endp->usb_endp, 0, - u132_hcd_initial_input_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { + int retval; + struct u132_ring *ring = endp->ring; + up(&u132->scheduler_lock); + retval = usb_ftdi_elan_edset_input(u132->platform_dev, + ring->number, endp, urb, address, endp->usb_endp, 0, + u132_hcd_initial_input_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + up(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); - return; - } + return; + } } /* @@ -1308,300 +1304,296 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, */ static void u132_hcd_ring_work_scheduler(struct work_struct *work) { - struct u132_ring *ring = + struct u132_ring *ring = container_of(work, struct u132_ring, scheduler.work); - struct u132 *u132 = ring->u132; - down(&u132->scheduler_lock); - if (ring->in_use) { - up(&u132->scheduler_lock); - u132_ring_put_kref(u132, ring); - return; - } else if (ring->curr_endp) { - struct u132_endp *last_endp = ring->curr_endp; - struct list_head *scan; - struct list_head *head = &last_endp->endp_ring; - unsigned long wakeup = 0; - list_for_each(scan, head) { - struct u132_endp *endp = list_entry(scan, - struct u132_endp, endp_ring); - if (endp->queue_next == endp->queue_last) { - } else if ((endp->delayed == 0) - || time_after_eq(jiffies, endp->jiffies)) { - ring->curr_endp = endp; - u132_endp_cancel_work(u132, last_endp); - u132_endp_queue_work(u132, last_endp, 0); - up(&u132->scheduler_lock); - u132_ring_put_kref(u132, ring); - return; - } else { - unsigned long delta = endp->jiffies - jiffies; - if (delta > wakeup) - wakeup = delta; - } - } - if (last_endp->queue_next == last_endp->queue_last) { - } else if ((last_endp->delayed == 0) || time_after_eq(jiffies, - last_endp->jiffies)) { - u132_endp_cancel_work(u132, last_endp); - u132_endp_queue_work(u132, last_endp, 0); - up(&u132->scheduler_lock); - u132_ring_put_kref(u132, ring); - return; - } else { - unsigned long delta = last_endp->jiffies - jiffies; - if (delta > wakeup) - wakeup = delta; - } - if (wakeup > 0) { - u132_ring_requeue_work(u132, ring, wakeup); - up(&u132->scheduler_lock); - return; - } else { - up(&u132->scheduler_lock); - u132_ring_put_kref(u132, ring); - return; - } - } else { - up(&u132->scheduler_lock); - u132_ring_put_kref(u132, ring); - return; - } + struct u132 *u132 = ring->u132; + down(&u132->scheduler_lock); + if (ring->in_use) { + up(&u132->scheduler_lock); + u132_ring_put_kref(u132, ring); + return; + } else if (ring->curr_endp) { + struct u132_endp *last_endp = ring->curr_endp; + struct list_head *scan; + struct list_head *head = &last_endp->endp_ring; + unsigned long wakeup = 0; + list_for_each(scan, head) { + struct u132_endp *endp = list_entry(scan, + struct u132_endp, endp_ring); + if (endp->queue_next == endp->queue_last) { + } else if ((endp->delayed == 0) + || time_after_eq(jiffies, endp->jiffies)) { + ring->curr_endp = endp; + u132_endp_cancel_work(u132, last_endp); + u132_endp_queue_work(u132, last_endp, 0); + up(&u132->scheduler_lock); + u132_ring_put_kref(u132, ring); + return; + } else { + unsigned long delta = endp->jiffies - jiffies; + if (delta > wakeup) + wakeup = delta; + } + } + if (last_endp->queue_next == last_endp->queue_last) { + } else if ((last_endp->delayed == 0) || time_after_eq(jiffies, + last_endp->jiffies)) { + u132_endp_cancel_work(u132, last_endp); + u132_endp_queue_work(u132, last_endp, 0); + up(&u132->scheduler_lock); + u132_ring_put_kref(u132, ring); + return; + } else { + unsigned long delta = last_endp->jiffies - jiffies; + if (delta > wakeup) + wakeup = delta; + } + if (wakeup > 0) { + u132_ring_requeue_work(u132, ring, wakeup); + up(&u132->scheduler_lock); + return; + } else { + up(&u132->scheduler_lock); + u132_ring_put_kref(u132, ring); + return; + } + } else { + up(&u132->scheduler_lock); + u132_ring_put_kref(u132, ring); + return; + } } static void u132_hcd_endp_work_scheduler(struct work_struct *work) { - struct u132_ring *ring; - struct u132_endp *endp = + struct u132_ring *ring; + struct u132_endp *endp = container_of(work, struct u132_endp, scheduler.work); - struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); - ring = endp->ring; - if (endp->edset_flush) { - endp->edset_flush = 0; - if (endp->dequeueing) - usb_ftdi_elan_edset_flush(u132->platform_dev, - ring->number, endp); - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else if (endp->active) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else if (ring->in_use) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else if (endp->queue_next == endp->queue_last) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else if (endp->pipetype == PIPE_INTERRUPT) { - u8 address = u132->addr[endp->usb_addr].address; - if (ring->in_use) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else { - int retval; - struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_single(u132, ring, endp, urb, address, - endp->toggle_bits, u132_hcd_interrupt_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } - } else if (endp->pipetype == PIPE_CONTROL) { - u8 address = u132->addr[endp->usb_addr].address; - if (ring->in_use) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else if (address == 0) { - int retval; - struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_setup(u132, ring, endp, urb, address, - 0x2, u132_hcd_initial_setup_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else if (endp->usb_addr == 0) { - int retval; - struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_setup(u132, ring, endp, urb, 0, 0x2, - u132_hcd_enumeration_address_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } else { - int retval; - u8 address = u132->addr[endp->usb_addr].address; - struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_setup(u132, ring, endp, urb, address, - 0x2, u132_hcd_configure_setup_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, retval); - return; - } - } else { - if (endp->input) { - u8 address = u132->addr[endp->usb_addr].address; - if (ring->in_use) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else { - int retval; - struct urb *urb = endp->urb_list[ - ENDP_QUEUE_MASK & endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_input(u132, ring, endp, urb, - address, endp->toggle_bits, - u132_hcd_bulk_input_recv); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, - retval); - return; - } - } else { /* output pipe */ - u8 address = u132->addr[endp->usb_addr].address; - if (ring->in_use) { - up(&u132->scheduler_lock); - u132_endp_put_kref(u132, endp); - return; - } else { - int retval; - struct urb *urb = endp->urb_list[ - ENDP_QUEUE_MASK & endp->queue_next]; - endp->active = 1; - ring->curr_endp = endp; - ring->in_use = 1; - up(&u132->scheduler_lock); - retval = edset_output(u132, ring, endp, urb, - address, endp->toggle_bits, - u132_hcd_bulk_output_sent); - if (retval == 0) { - } else - u132_hcd_giveback_urb(u132, endp, urb, - retval); - return; - } - } - } + struct u132 *u132 = endp->u132; + down(&u132->scheduler_lock); + ring = endp->ring; + if (endp->edset_flush) { + endp->edset_flush = 0; + if (endp->dequeueing) + usb_ftdi_elan_edset_flush(u132->platform_dev, + ring->number, endp); + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else if (endp->active) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else if (ring->in_use) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else if (endp->queue_next == endp->queue_last) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else if (endp->pipetype == PIPE_INTERRUPT) { + u8 address = u132->addr[endp->usb_addr].address; + if (ring->in_use) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else { + int retval; + struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_single(u132, ring, endp, urb, address, + endp->toggle_bits, u132_hcd_interrupt_recv); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } + } else if (endp->pipetype == PIPE_CONTROL) { + u8 address = u132->addr[endp->usb_addr].address; + if (ring->in_use) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else if (address == 0) { + int retval; + struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_setup(u132, ring, endp, urb, address, + 0x2, u132_hcd_initial_setup_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else if (endp->usb_addr == 0) { + int retval; + struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_setup(u132, ring, endp, urb, 0, 0x2, + u132_hcd_enumeration_address_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } else { + int retval; + u8 address = u132->addr[endp->usb_addr].address; + struct urb *urb = endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_setup(u132, ring, endp, urb, address, + 0x2, u132_hcd_configure_setup_sent); + if (retval != 0) + u132_hcd_giveback_urb(u132, endp, urb, retval); + return; + } + } else { + if (endp->input) { + u8 address = u132->addr[endp->usb_addr].address; + if (ring->in_use) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else { + int retval; + struct urb *urb = endp->urb_list[ + ENDP_QUEUE_MASK & endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_input(u132, ring, endp, urb, + address, endp->toggle_bits, + u132_hcd_bulk_input_recv); + if (retval == 0) { + } else + u132_hcd_giveback_urb(u132, endp, urb, + retval); + return; + } + } else { /* output pipe */ + u8 address = u132->addr[endp->usb_addr].address; + if (ring->in_use) { + up(&u132->scheduler_lock); + u132_endp_put_kref(u132, endp); + return; + } else { + int retval; + struct urb *urb = endp->urb_list[ + ENDP_QUEUE_MASK & endp->queue_next]; + endp->active = 1; + ring->curr_endp = endp; + ring->in_use = 1; + up(&u132->scheduler_lock); + retval = edset_output(u132, ring, endp, urb, + address, endp->toggle_bits, + u132_hcd_bulk_output_sent); + if (retval == 0) { + } else + u132_hcd_giveback_urb(u132, endp, urb, + retval); + return; + } + } + } } #ifdef CONFIG_PM static void port_power(struct u132 *u132, int pn, int is_on) { - u132->port[pn].power = is_on; + u132->port[pn].power = is_on; } #endif static void u132_power(struct u132 *u132, int is_on) { - struct usb_hcd *hcd = u132_to_hcd(u132) - ; /* hub is inactive unless the port is powered */ - if (is_on) { - if (u132->power) - return; - u132->power = 1; - } else { - u132->power = 0; - hcd->state = HC_STATE_HALT; - } + struct usb_hcd *hcd = u132_to_hcd(u132) + ; /* hub is inactive unless the port is powered */ + if (is_on) { + if (u132->power) + return; + u132->power = 1; + } else { + u132->power = 0; + hcd->state = HC_STATE_HALT; + } } static int u132_periodic_reinit(struct u132 *u132) { - int retval; - u32 fi = u132->hc_fminterval & 0x03fff; - u32 fit; - u32 fminterval; - retval = u132_read_pcimem(u132, fminterval, &fminterval); - if (retval) - return retval; - fit = fminterval & FIT; - retval = u132_write_pcimem(u132, fminterval, - (fit ^ FIT) | u132->hc_fminterval); - if (retval) - return retval; - retval = u132_write_pcimem(u132, periodicstart, - ((9 *fi) / 10) & 0x3fff); - if (retval) - return retval; - return 0; + int retval; + u32 fi = u132->hc_fminterval & 0x03fff; + u32 fit; + u32 fminterval; + retval = u132_read_pcimem(u132, fminterval, &fminterval); + if (retval) + return retval; + fit = fminterval & FIT; + retval = u132_write_pcimem(u132, fminterval, + (fit ^ FIT) | u132->hc_fminterval); + if (retval) + return retval; + retval = u132_write_pcimem(u132, periodicstart, + ((9 * fi) / 10) & 0x3fff); + if (retval) + return retval; + return 0; } static char *hcfs2string(int state) { - switch (state) { - case OHCI_USB_RESET: - return "reset"; - case OHCI_USB_RESUME: - return "resume"; - case OHCI_USB_OPER: - return "operational"; - case OHCI_USB_SUSPEND: - return "suspend"; - } - return "?"; + switch (state) { + case OHCI_USB_RESET: + return "reset"; + case OHCI_USB_RESUME: + return "resume"; + case OHCI_USB_OPER: + return "operational"; + case OHCI_USB_SUSPEND: + return "suspend"; + } + return "?"; } static int u132_init(struct u132 *u132) { - int retval; - u32 control; - u132_disable(u132); - u132->next_statechange = jiffies; - retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); - if (retval) - return retval; - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - if (u132->num_ports == 0) { - u32 rh_a = -1; - retval = u132_read_pcimem(u132, roothub.a, &rh_a); - if (retval) - return retval; - u132->num_ports = rh_a & RH_A_NDP; - retval = read_roothub_info(u132); - if (retval) - return retval; - } - if (u132->num_ports > MAX_U132_PORTS) { - return -EINVAL; - } - return 0; + int retval; + u32 control; + u132_disable(u132); + u132->next_statechange = jiffies; + retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); + if (retval) + return retval; + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; + if (u132->num_ports == 0) { + u32 rh_a = -1; + retval = u132_read_pcimem(u132, roothub.a, &rh_a); + if (retval) + return retval; + u132->num_ports = rh_a & RH_A_NDP; + retval = read_roothub_info(u132); + if (retval) + return retval; + } + if (u132->num_ports > MAX_U132_PORTS) + return -EINVAL; + + return 0; } @@ -1611,280 +1603,278 @@ static int u132_init(struct u132 *u132) */ static int u132_run(struct u132 *u132) { - int retval; - u32 control; - u32 status; - u32 fminterval; - u32 periodicstart; - u32 cmdstatus; - u32 roothub_a; - int mask = OHCI_INTR_INIT; - int first = u132->hc_fminterval == 0; - int sleep_time = 0; - int reset_timeout = 30; /* ... allow extra time */ - u132_disable(u132); - if (first) { - u32 temp; - retval = u132_read_pcimem(u132, fminterval, &temp); - if (retval) - return retval; - u132->hc_fminterval = temp & 0x3fff; - if (u132->hc_fminterval != FI) { - } - u132->hc_fminterval |= FSMP(u132->hc_fminterval) << 16; - } - retval = u132_read_pcimem(u132, control, &u132->hc_control); - if (retval) - return retval; - dev_info(&u132->platform_dev->dev, "resetting from state '%s', control " - "= %08X\n", hcfs2string(u132->hc_control & OHCI_CTRL_HCFS), - u132->hc_control); - switch (u132->hc_control & OHCI_CTRL_HCFS) { - case OHCI_USB_OPER: - sleep_time = 0; - break; - case OHCI_USB_SUSPEND: - case OHCI_USB_RESUME: - u132->hc_control &= OHCI_CTRL_RWC; - u132->hc_control |= OHCI_USB_RESUME; - sleep_time = 10; - break; - default: - u132->hc_control &= OHCI_CTRL_RWC; - u132->hc_control |= OHCI_USB_RESET; - sleep_time = 50; - break; - } - retval = u132_write_pcimem(u132, control, u132->hc_control); - if (retval) - return retval; - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - msleep(sleep_time); - retval = u132_read_pcimem(u132, roothub.a, &roothub_a); - if (retval) - return retval; - if (!(roothub_a & RH_A_NPS)) { - int temp; /* power down each port */ - for (temp = 0; temp < u132->num_ports; temp++) { - retval = u132_write_pcimem(u132, - roothub.portstatus[temp], RH_PS_LSDA); - if (retval) - return retval; - } - } - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - retry:retval = u132_read_pcimem(u132, cmdstatus, &status); - if (retval) - return retval; - retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR); - if (retval) - return retval; - extra:{ - retval = u132_read_pcimem(u132, cmdstatus, &status); - if (retval) - return retval; - if (0 != (status & OHCI_HCR)) { - if (--reset_timeout == 0) { - dev_err(&u132->platform_dev->dev, "USB HC reset" - " timed out!\n"); - return -ENODEV; - } else { - msleep(5); - goto extra; - } - } - } - if (u132->flags & OHCI_QUIRK_INITRESET) { - retval = u132_write_pcimem(u132, control, u132->hc_control); - if (retval) - return retval; - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - } - retval = u132_write_pcimem(u132, ed_controlhead, 0x00000000); - if (retval) - return retval; - retval = u132_write_pcimem(u132, ed_bulkhead, 0x11000000); - if (retval) - return retval; - retval = u132_write_pcimem(u132, hcca, 0x00000000); - if (retval) - return retval; - retval = u132_periodic_reinit(u132); - if (retval) - return retval; - retval = u132_read_pcimem(u132, fminterval, &fminterval); - if (retval) - return retval; - retval = u132_read_pcimem(u132, periodicstart, &periodicstart); - if (retval) - return retval; - if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) { - if (!(u132->flags & OHCI_QUIRK_INITRESET)) { - u132->flags |= OHCI_QUIRK_INITRESET; - goto retry; - } else - dev_err(&u132->platform_dev->dev, "init err(%08x %04x)" - "\n", fminterval, periodicstart); - } /* start controller operations */ - u132->hc_control &= OHCI_CTRL_RWC; - u132->hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER; - retval = u132_write_pcimem(u132, control, u132->hc_control); - if (retval) - return retval; - retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF); - if (retval) - return retval; - retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); - if (retval) - return retval; - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - u132_to_hcd(u132)->state = HC_STATE_RUNNING; - retval = u132_write_pcimem(u132, roothub.status, RH_HS_DRWE); - if (retval) - return retval; - retval = u132_write_pcimem(u132, intrstatus, mask); - if (retval) - return retval; - retval = u132_write_pcimem(u132, intrdisable, - OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO | - OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH | - OHCI_INTR_SO); - if (retval) - return retval; /* handle root hub init quirks ... */ - retval = u132_read_pcimem(u132, roothub.a, &roothub_a); - if (retval) - return retval; - roothub_a &= ~(RH_A_PSM | RH_A_OCPM); - if (u132->flags & OHCI_QUIRK_SUPERIO) { - roothub_a |= RH_A_NOCP; - roothub_a &= ~(RH_A_POTPGT | RH_A_NPS); - retval = u132_write_pcimem(u132, roothub.a, roothub_a); - if (retval) - return retval; - } else if ((u132->flags & OHCI_QUIRK_AMD756) || distrust_firmware) { - roothub_a |= RH_A_NPS; - retval = u132_write_pcimem(u132, roothub.a, roothub_a); - if (retval) - return retval; - } - retval = u132_write_pcimem(u132, roothub.status, RH_HS_LPSC); - if (retval) - return retval; - retval = u132_write_pcimem(u132, roothub.b, - (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM); - if (retval) - return retval; - retval = u132_read_pcimem(u132, control, &control); - if (retval) - return retval; - mdelay((roothub_a >> 23) & 0x1fe); - u132_to_hcd(u132)->state = HC_STATE_RUNNING; - return 0; + int retval; + u32 control; + u32 status; + u32 fminterval; + u32 periodicstart; + u32 cmdstatus; + u32 roothub_a; + int mask = OHCI_INTR_INIT; + int first = u132->hc_fminterval == 0; + int sleep_time = 0; + int reset_timeout = 30; /* ... allow extra time */ + u132_disable(u132); + if (first) { + u32 temp; + retval = u132_read_pcimem(u132, fminterval, &temp); + if (retval) + return retval; + u132->hc_fminterval = temp & 0x3fff; + u132->hc_fminterval |= FSMP(u132->hc_fminterval) << 16; + } + retval = u132_read_pcimem(u132, control, &u132->hc_control); + if (retval) + return retval; + dev_info(&u132->platform_dev->dev, "resetting from state '%s', control " + "= %08X\n", hcfs2string(u132->hc_control & OHCI_CTRL_HCFS), + u132->hc_control); + switch (u132->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + sleep_time = 0; + break; + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + u132->hc_control &= OHCI_CTRL_RWC; + u132->hc_control |= OHCI_USB_RESUME; + sleep_time = 10; + break; + default: + u132->hc_control &= OHCI_CTRL_RWC; + u132->hc_control |= OHCI_USB_RESET; + sleep_time = 50; + break; + } + retval = u132_write_pcimem(u132, control, u132->hc_control); + if (retval) + return retval; + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; + msleep(sleep_time); + retval = u132_read_pcimem(u132, roothub.a, &roothub_a); + if (retval) + return retval; + if (!(roothub_a & RH_A_NPS)) { + int temp; /* power down each port */ + for (temp = 0; temp < u132->num_ports; temp++) { + retval = u132_write_pcimem(u132, + roothub.portstatus[temp], RH_PS_LSDA); + if (retval) + return retval; + } + } + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; +retry: + retval = u132_read_pcimem(u132, cmdstatus, &status); + if (retval) + return retval; + retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR); + if (retval) + return retval; +extra: { + retval = u132_read_pcimem(u132, cmdstatus, &status); + if (retval) + return retval; + if (0 != (status & OHCI_HCR)) { + if (--reset_timeout == 0) { + dev_err(&u132->platform_dev->dev, "USB HC reset" + " timed out!\n"); + return -ENODEV; + } else { + msleep(5); + goto extra; + } + } + } + if (u132->flags & OHCI_QUIRK_INITRESET) { + retval = u132_write_pcimem(u132, control, u132->hc_control); + if (retval) + return retval; + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; + } + retval = u132_write_pcimem(u132, ed_controlhead, 0x00000000); + if (retval) + return retval; + retval = u132_write_pcimem(u132, ed_bulkhead, 0x11000000); + if (retval) + return retval; + retval = u132_write_pcimem(u132, hcca, 0x00000000); + if (retval) + return retval; + retval = u132_periodic_reinit(u132); + if (retval) + return retval; + retval = u132_read_pcimem(u132, fminterval, &fminterval); + if (retval) + return retval; + retval = u132_read_pcimem(u132, periodicstart, &periodicstart); + if (retval) + return retval; + if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) { + if (!(u132->flags & OHCI_QUIRK_INITRESET)) { + u132->flags |= OHCI_QUIRK_INITRESET; + goto retry; + } else + dev_err(&u132->platform_dev->dev, "init err(%08x %04x)" + "\n", fminterval, periodicstart); + } /* start controller operations */ + u132->hc_control &= OHCI_CTRL_RWC; + u132->hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER; + retval = u132_write_pcimem(u132, control, u132->hc_control); + if (retval) + return retval; + retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF); + if (retval) + return retval; + retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); + if (retval) + return retval; + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; + u132_to_hcd(u132)->state = HC_STATE_RUNNING; + retval = u132_write_pcimem(u132, roothub.status, RH_HS_DRWE); + if (retval) + return retval; + retval = u132_write_pcimem(u132, intrstatus, mask); + if (retval) + return retval; + retval = u132_write_pcimem(u132, intrdisable, + OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO | + OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH | + OHCI_INTR_SO); + if (retval) + return retval; /* handle root hub init quirks ... */ + retval = u132_read_pcimem(u132, roothub.a, &roothub_a); + if (retval) + return retval; + roothub_a &= ~(RH_A_PSM | RH_A_OCPM); + if (u132->flags & OHCI_QUIRK_SUPERIO) { + roothub_a |= RH_A_NOCP; + roothub_a &= ~(RH_A_POTPGT | RH_A_NPS); + retval = u132_write_pcimem(u132, roothub.a, roothub_a); + if (retval) + return retval; + } else if ((u132->flags & OHCI_QUIRK_AMD756) || distrust_firmware) { + roothub_a |= RH_A_NPS; + retval = u132_write_pcimem(u132, roothub.a, roothub_a); + if (retval) + return retval; + } + retval = u132_write_pcimem(u132, roothub.status, RH_HS_LPSC); + if (retval) + return retval; + retval = u132_write_pcimem(u132, roothub.b, + (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM); + if (retval) + return retval; + retval = u132_read_pcimem(u132, control, &control); + if (retval) + return retval; + mdelay((roothub_a >> 23) & 0x1fe); + u132_to_hcd(u132)->state = HC_STATE_RUNNING; + return 0; } static void u132_hcd_stop(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b" - "een removed %d\n", u132, hcd, u132->going); - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" - "ed\n", hcd); - } else { - mutex_lock(&u132->sw_lock); - msleep(100); - u132_power(u132, 0); - mutex_unlock(&u132->sw_lock); - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b" + "een removed %d\n", u132, hcd, u132->going); + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" + "ed\n", hcd); + } else { + mutex_lock(&u132->sw_lock); + msleep(100); + u132_power(u132, 0); + mutex_unlock(&u132->sw_lock); + } } static int u132_hcd_start(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else if (hcd->self.controller) { - int retval; - struct platform_device *pdev = - to_platform_device(hcd->self.controller); - u16 vendor = ((struct u132_platform_data *) - (pdev->dev.platform_data))->vendor; - u16 device = ((struct u132_platform_data *) - (pdev->dev.platform_data))->device; - mutex_lock(&u132->sw_lock); - msleep(10); - if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { - u132->flags = OHCI_QUIRK_AMD756; - } else if (vendor == PCI_VENDOR_ID_OPTI && device == 0xc861) { - dev_err(&u132->platform_dev->dev, "WARNING: OPTi workar" - "ounds unavailable\n"); - } else if (vendor == PCI_VENDOR_ID_COMPAQ && device == 0xa0f8) - u132->flags |= OHCI_QUIRK_ZFMICRO; - retval = u132_run(u132); - if (retval) { - u132_disable(u132); - u132->going = 1; - } - msleep(100); - mutex_unlock(&u132->sw_lock); - return retval; - } else { - dev_err(&u132->platform_dev->dev, "platform_device missing\n"); - return -ENODEV; - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else if (hcd->self.controller) { + int retval; + struct platform_device *pdev = + to_platform_device(hcd->self.controller); + u16 vendor = ((struct u132_platform_data *) + (pdev->dev.platform_data))->vendor; + u16 device = ((struct u132_platform_data *) + (pdev->dev.platform_data))->device; + mutex_lock(&u132->sw_lock); + msleep(10); + if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { + u132->flags = OHCI_QUIRK_AMD756; + } else if (vendor == PCI_VENDOR_ID_OPTI && device == 0xc861) { + dev_err(&u132->platform_dev->dev, "WARNING: OPTi workar" + "ounds unavailable\n"); + } else if (vendor == PCI_VENDOR_ID_COMPAQ && device == 0xa0f8) + u132->flags |= OHCI_QUIRK_ZFMICRO; + retval = u132_run(u132); + if (retval) { + u132_disable(u132); + u132->going = 1; + } + msleep(100); + mutex_unlock(&u132->sw_lock); + return retval; + } else { + dev_err(&u132->platform_dev->dev, "platform_device missing\n"); + return -ENODEV; + } } static int u132_hcd_reset(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else { - int retval; - mutex_lock(&u132->sw_lock); - retval = u132_init(u132); - if (retval) { - u132_disable(u132); - u132->going = 1; - } - mutex_unlock(&u132->sw_lock); - return retval; - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else { + int retval; + mutex_lock(&u132->sw_lock); + retval = u132_init(u132); + if (retval) { + u132_disable(u132); + u132->going = 1; + } + mutex_unlock(&u132->sw_lock); + return retval; + } } static int create_endpoint_and_queue_int(struct u132 *u132, struct u132_udev *udev, struct urb *urb, - struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, - gfp_t mem_flags) + struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, + gfp_t mem_flags) { - struct u132_ring *ring; - unsigned long irqs; + struct u132_ring *ring; + unsigned long irqs; int rc; u8 endp_number; struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); - if (!endp) { - return -ENOMEM; - } + if (!endp) + return -ENOMEM; spin_lock_init(&endp->queue_lock.slock); spin_lock_irqsave(&endp->queue_lock.slock, irqs); @@ -1897,94 +1887,93 @@ static int create_endpoint_and_queue_int(struct u132 *u132, endp_number = ++u132->num_endpoints; urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); - INIT_LIST_HEAD(&endp->urb_more); - ring = endp->ring = &u132->ring[0]; - if (ring->curr_endp) { - list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); - } else { - INIT_LIST_HEAD(&endp->endp_ring); - ring->curr_endp = endp; - } - ring->length += 1; - endp->dequeueing = 0; - endp->edset_flush = 0; - endp->active = 0; - endp->delayed = 0; - endp->endp_number = endp_number; - endp->u132 = u132; + INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_LIST_HEAD(&endp->urb_more); + ring = endp->ring = &u132->ring[0]; + if (ring->curr_endp) { + list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); + } else { + INIT_LIST_HEAD(&endp->endp_ring); + ring->curr_endp = endp; + } + ring->length += 1; + endp->dequeueing = 0; + endp->edset_flush = 0; + endp->active = 0; + endp->delayed = 0; + endp->endp_number = endp_number; + endp->u132 = u132; endp->hep = urb->ep; - endp->pipetype = usb_pipetype(urb->pipe); - u132_endp_init_kref(u132, endp); - if (usb_pipein(urb->pipe)) { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, usb_endp, 0, 0); - endp->input = 1; - endp->output = 0; - udev->endp_number_in[usb_endp] = endp_number; - u132_udev_get_kref(u132, udev); - } else { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, usb_endp, 1, 0); - endp->input = 0; - endp->output = 1; - udev->endp_number_out[usb_endp] = endp_number; - u132_udev_get_kref(u132, udev); - } - urb->hcpriv = u132; - endp->delayed = 1; - endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); - endp->udev_number = address; - endp->usb_addr = usb_addr; - endp->usb_endp = usb_endp; - endp->queue_size = 1; - endp->queue_last = 0; - endp->queue_next = 0; - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - u132_endp_queue_work(u132, endp, msecs_to_jiffies(urb->interval)); - return 0; + endp->pipetype = usb_pipetype(urb->pipe); + u132_endp_init_kref(u132, endp); + if (usb_pipein(urb->pipe)) { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, usb_endp, 0, 0); + endp->input = 1; + endp->output = 0; + udev->endp_number_in[usb_endp] = endp_number; + u132_udev_get_kref(u132, udev); + } else { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, usb_endp, 1, 0); + endp->input = 0; + endp->output = 1; + udev->endp_number_out[usb_endp] = endp_number; + u132_udev_get_kref(u132, udev); + } + urb->hcpriv = u132; + endp->delayed = 1; + endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); + endp->udev_number = address; + endp->usb_addr = usb_addr; + endp->usb_endp = usb_endp; + endp->queue_size = 1; + endp->queue_last = 0; + endp->queue_next = 0; + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + u132_endp_queue_work(u132, endp, msecs_to_jiffies(urb->interval)); + return 0; } static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, struct urb *urb, - struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, - u8 usb_endp, u8 address) -{ - urb->hcpriv = u132; - endp->delayed = 1; - endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); - if (endp->queue_size++ < ENDP_QUEUE_SIZE) { - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - } else { - struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq), - GFP_ATOMIC); - if (urbq == NULL) { - endp->queue_size -= 1; - return -ENOMEM; - } else { - list_add_tail(&urbq->urb_more, &endp->urb_more); - urbq->urb = urb; - } - } - return 0; + struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, + u8 usb_endp, u8 address) +{ + urb->hcpriv = u132; + endp->delayed = 1; + endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); + if (endp->queue_size++ < ENDP_QUEUE_SIZE) { + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + } else { + struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq), + GFP_ATOMIC); + if (urbq == NULL) { + endp->queue_size -= 1; + return -ENOMEM; + } else { + list_add_tail(&urbq->urb_more, &endp->urb_more); + urbq->urb = urb; + } + } + return 0; } static int create_endpoint_and_queue_bulk(struct u132 *u132, struct u132_udev *udev, struct urb *urb, - struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, - gfp_t mem_flags) + struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, + gfp_t mem_flags) { - int ring_number; - struct u132_ring *ring; - unsigned long irqs; + int ring_number; + struct u132_ring *ring; + unsigned long irqs; int rc; u8 endp_number; struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); - if (!endp) { - return -ENOMEM; - } + if (!endp) + return -ENOMEM; spin_lock_init(&endp->queue_lock.slock); spin_lock_irqsave(&endp->queue_lock.slock, irqs); @@ -1997,91 +1986,90 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, endp_number = ++u132->num_endpoints; urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); - INIT_LIST_HEAD(&endp->urb_more); - endp->dequeueing = 0; - endp->edset_flush = 0; - endp->active = 0; - endp->delayed = 0; - endp->endp_number = endp_number; - endp->u132 = u132; + INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_LIST_HEAD(&endp->urb_more); + endp->dequeueing = 0; + endp->edset_flush = 0; + endp->active = 0; + endp->delayed = 0; + endp->endp_number = endp_number; + endp->u132 = u132; endp->hep = urb->ep; - endp->pipetype = usb_pipetype(urb->pipe); - u132_endp_init_kref(u132, endp); - if (usb_pipein(urb->pipe)) { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, usb_endp, 0, 0); - ring_number = 3; - endp->input = 1; - endp->output = 0; - udev->endp_number_in[usb_endp] = endp_number; - u132_udev_get_kref(u132, udev); - } else { - endp->toggle_bits = 0x2; - usb_settoggle(udev->usb_device, usb_endp, 1, 0); - ring_number = 2; - endp->input = 0; - endp->output = 1; - udev->endp_number_out[usb_endp] = endp_number; - u132_udev_get_kref(u132, udev); - } - ring = endp->ring = &u132->ring[ring_number - 1]; - if (ring->curr_endp) { - list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); - } else { - INIT_LIST_HEAD(&endp->endp_ring); - ring->curr_endp = endp; - } - ring->length += 1; - urb->hcpriv = u132; - endp->udev_number = address; - endp->usb_addr = usb_addr; - endp->usb_endp = usb_endp; - endp->queue_size = 1; - endp->queue_last = 0; - endp->queue_next = 0; - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - u132_endp_queue_work(u132, endp, 0); - return 0; + endp->pipetype = usb_pipetype(urb->pipe); + u132_endp_init_kref(u132, endp); + if (usb_pipein(urb->pipe)) { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, usb_endp, 0, 0); + ring_number = 3; + endp->input = 1; + endp->output = 0; + udev->endp_number_in[usb_endp] = endp_number; + u132_udev_get_kref(u132, udev); + } else { + endp->toggle_bits = 0x2; + usb_settoggle(udev->usb_device, usb_endp, 1, 0); + ring_number = 2; + endp->input = 0; + endp->output = 1; + udev->endp_number_out[usb_endp] = endp_number; + u132_udev_get_kref(u132, udev); + } + ring = endp->ring = &u132->ring[ring_number - 1]; + if (ring->curr_endp) { + list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); + } else { + INIT_LIST_HEAD(&endp->endp_ring); + ring->curr_endp = endp; + } + ring->length += 1; + urb->hcpriv = u132; + endp->udev_number = address; + endp->usb_addr = usb_addr; + endp->usb_endp = usb_endp; + endp->queue_size = 1; + endp->queue_last = 0; + endp->queue_next = 0; + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + u132_endp_queue_work(u132, endp, 0); + return 0; } static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, struct urb *urb, - struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, - u8 usb_endp, u8 address) -{ - urb->hcpriv = u132; - if (endp->queue_size++ < ENDP_QUEUE_SIZE) { - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - } else { - struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq), - GFP_ATOMIC); - if (urbq == NULL) { - endp->queue_size -= 1; - return -ENOMEM; - } else { - list_add_tail(&urbq->urb_more, &endp->urb_more); - urbq->urb = urb; - } - } - return 0; + struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, + u8 usb_endp, u8 address) +{ + urb->hcpriv = u132; + if (endp->queue_size++ < ENDP_QUEUE_SIZE) { + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + } else { + struct u132_urbq *urbq = kmalloc(sizeof(struct u132_urbq), + GFP_ATOMIC); + if (urbq == NULL) { + endp->queue_size -= 1; + return -ENOMEM; + } else { + list_add_tail(&urbq->urb_more, &endp->urb_more); + urbq->urb = urb; + } + } + return 0; } static int create_endpoint_and_queue_control(struct u132 *u132, struct urb *urb, - struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, - gfp_t mem_flags) + struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, + gfp_t mem_flags) { - struct u132_ring *ring; + struct u132_ring *ring; unsigned long irqs; int rc; u8 endp_number; struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); - if (!endp) { - return -ENOMEM; - } + if (!endp) + return -ENOMEM; spin_lock_init(&endp->queue_lock.slock); spin_lock_irqsave(&endp->queue_lock.slock, irqs); @@ -2094,204 +2082,203 @@ static int create_endpoint_and_queue_control(struct u132 *u132, endp_number = ++u132->num_endpoints; urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); - INIT_LIST_HEAD(&endp->urb_more); - ring = endp->ring = &u132->ring[0]; - if (ring->curr_endp) { - list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); - } else { - INIT_LIST_HEAD(&endp->endp_ring); - ring->curr_endp = endp; - } - ring->length += 1; - endp->dequeueing = 0; - endp->edset_flush = 0; - endp->active = 0; - endp->delayed = 0; - endp->endp_number = endp_number; - endp->u132 = u132; + INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_LIST_HEAD(&endp->urb_more); + ring = endp->ring = &u132->ring[0]; + if (ring->curr_endp) { + list_add_tail(&endp->endp_ring, &ring->curr_endp->endp_ring); + } else { + INIT_LIST_HEAD(&endp->endp_ring); + ring->curr_endp = endp; + } + ring->length += 1; + endp->dequeueing = 0; + endp->edset_flush = 0; + endp->active = 0; + endp->delayed = 0; + endp->endp_number = endp_number; + endp->u132 = u132; endp->hep = urb->ep; - u132_endp_init_kref(u132, endp); - u132_endp_get_kref(u132, endp); - if (usb_addr == 0) { - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - endp->udev_number = address; - endp->usb_addr = usb_addr; - endp->usb_endp = usb_endp; - endp->input = 1; - endp->output = 1; - endp->pipetype = usb_pipetype(urb->pipe); - u132_udev_init_kref(u132, udev); - u132_udev_get_kref(u132, udev); - udev->endp_number_in[usb_endp] = endp_number; - udev->endp_number_out[usb_endp] = endp_number; - urb->hcpriv = u132; - endp->queue_size = 1; - endp->queue_last = 0; - endp->queue_next = 0; - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - u132_endp_queue_work(u132, endp, 0); - return 0; - } else { /*(usb_addr > 0) */ - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - endp->udev_number = address; - endp->usb_addr = usb_addr; - endp->usb_endp = usb_endp; - endp->input = 1; - endp->output = 1; - endp->pipetype = usb_pipetype(urb->pipe); - u132_udev_get_kref(u132, udev); - udev->enumeration = 2; - udev->endp_number_in[usb_endp] = endp_number; - udev->endp_number_out[usb_endp] = endp_number; - urb->hcpriv = u132; - endp->queue_size = 1; - endp->queue_last = 0; - endp->queue_next = 0; - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - u132_endp_queue_work(u132, endp, 0); - return 0; - } + u132_endp_init_kref(u132, endp); + u132_endp_get_kref(u132, endp); + if (usb_addr == 0) { + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + endp->udev_number = address; + endp->usb_addr = usb_addr; + endp->usb_endp = usb_endp; + endp->input = 1; + endp->output = 1; + endp->pipetype = usb_pipetype(urb->pipe); + u132_udev_init_kref(u132, udev); + u132_udev_get_kref(u132, udev); + udev->endp_number_in[usb_endp] = endp_number; + udev->endp_number_out[usb_endp] = endp_number; + urb->hcpriv = u132; + endp->queue_size = 1; + endp->queue_last = 0; + endp->queue_next = 0; + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + u132_endp_queue_work(u132, endp, 0); + return 0; + } else { /*(usb_addr > 0) */ + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + endp->udev_number = address; + endp->usb_addr = usb_addr; + endp->usb_endp = usb_endp; + endp->input = 1; + endp->output = 1; + endp->pipetype = usb_pipetype(urb->pipe); + u132_udev_get_kref(u132, udev); + udev->enumeration = 2; + udev->endp_number_in[usb_endp] = endp_number; + udev->endp_number_out[usb_endp] = endp_number; + urb->hcpriv = u132; + endp->queue_size = 1; + endp->queue_last = 0; + endp->queue_next = 0; + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = urb; + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + u132_endp_queue_work(u132, endp, 0); + return 0; + } } static int queue_control_on_old_endpoint(struct u132 *u132, struct urb *urb, - struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, - u8 usb_endp) -{ - if (usb_addr == 0) { - if (usb_pipein(urb->pipe)) { - urb->hcpriv = u132; - if (endp->queue_size++ < ENDP_QUEUE_SIZE) { - endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_last++] = urb; - } else { - struct u132_urbq *urbq = - kmalloc(sizeof(struct u132_urbq), - GFP_ATOMIC); - if (urbq == NULL) { - endp->queue_size -= 1; - return -ENOMEM; - } else { - list_add_tail(&urbq->urb_more, - &endp->urb_more); - urbq->urb = urb; - } - } - return 0; - } else { /* usb_pipeout(urb->pipe) */ - struct u132_addr *addr = &u132->addr[usb_dev->devnum]; - int I = MAX_U132_UDEVS; - int i = 0; - while (--I > 0) { - struct u132_udev *udev = &u132->udev[++i]; - if (udev->usb_device) { - continue; - } else { - udev->enumeration = 1; - u132->addr[0].address = i; - endp->udev_number = i; - udev->udev_number = i; - udev->usb_addr = usb_dev->devnum; - u132_udev_init_kref(u132, udev); - udev->endp_number_in[usb_endp] = - endp->endp_number; - u132_udev_get_kref(u132, udev); - udev->endp_number_out[usb_endp] = - endp->endp_number; - udev->usb_device = usb_dev; - ((u8 *) (urb->setup_packet))[2] = - addr->address = i; - u132_udev_get_kref(u132, udev); - break; - } - } - if (I == 0) { - dev_err(&u132->platform_dev->dev, "run out of d" - "evice space\n"); - return -EINVAL; - } - urb->hcpriv = u132; - if (endp->queue_size++ < ENDP_QUEUE_SIZE) { - endp->urb_list[ENDP_QUEUE_MASK & - endp->queue_last++] = urb; - } else { - struct u132_urbq *urbq = - kmalloc(sizeof(struct u132_urbq), - GFP_ATOMIC); - if (urbq == NULL) { - endp->queue_size -= 1; - return -ENOMEM; - } else { - list_add_tail(&urbq->urb_more, - &endp->urb_more); - urbq->urb = urb; - } - } - return 0; - } - } else { /*(usb_addr > 0) */ - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - urb->hcpriv = u132; - if (udev->enumeration == 2) { - } else - udev->enumeration = 2; - if (endp->queue_size++ < ENDP_QUEUE_SIZE) { - endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = - urb; - } else { - struct u132_urbq *urbq = - kmalloc(sizeof(struct u132_urbq), GFP_ATOMIC); - if (urbq == NULL) { - endp->queue_size -= 1; - return -ENOMEM; - } else { - list_add_tail(&urbq->urb_more, &endp->urb_more); - urbq->urb = urb; - } - } - return 0; - } + struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, + u8 usb_endp) +{ + if (usb_addr == 0) { + if (usb_pipein(urb->pipe)) { + urb->hcpriv = u132; + if (endp->queue_size++ < ENDP_QUEUE_SIZE) { + endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_last++] = urb; + } else { + struct u132_urbq *urbq = + kmalloc(sizeof(struct u132_urbq), + GFP_ATOMIC); + if (urbq == NULL) { + endp->queue_size -= 1; + return -ENOMEM; + } else { + list_add_tail(&urbq->urb_more, + &endp->urb_more); + urbq->urb = urb; + } + } + return 0; + } else { /* usb_pipeout(urb->pipe) */ + struct u132_addr *addr = &u132->addr[usb_dev->devnum]; + int I = MAX_U132_UDEVS; + int i = 0; + while (--I > 0) { + struct u132_udev *udev = &u132->udev[++i]; + if (udev->usb_device) { + continue; + } else { + udev->enumeration = 1; + u132->addr[0].address = i; + endp->udev_number = i; + udev->udev_number = i; + udev->usb_addr = usb_dev->devnum; + u132_udev_init_kref(u132, udev); + udev->endp_number_in[usb_endp] = + endp->endp_number; + u132_udev_get_kref(u132, udev); + udev->endp_number_out[usb_endp] = + endp->endp_number; + udev->usb_device = usb_dev; + ((u8 *) (urb->setup_packet))[2] = + addr->address = i; + u132_udev_get_kref(u132, udev); + break; + } + } + if (I == 0) { + dev_err(&u132->platform_dev->dev, "run out of d" + "evice space\n"); + return -EINVAL; + } + urb->hcpriv = u132; + if (endp->queue_size++ < ENDP_QUEUE_SIZE) { + endp->urb_list[ENDP_QUEUE_MASK & + endp->queue_last++] = urb; + } else { + struct u132_urbq *urbq = + kmalloc(sizeof(struct u132_urbq), + GFP_ATOMIC); + if (urbq == NULL) { + endp->queue_size -= 1; + return -ENOMEM; + } else { + list_add_tail(&urbq->urb_more, + &endp->urb_more); + urbq->urb = urb; + } + } + return 0; + } + } else { /*(usb_addr > 0) */ + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + urb->hcpriv = u132; + if (udev->enumeration != 2) + udev->enumeration = 2; + if (endp->queue_size++ < ENDP_QUEUE_SIZE) { + endp->urb_list[ENDP_QUEUE_MASK & endp->queue_last++] = + urb; + } else { + struct u132_urbq *urbq = + kmalloc(sizeof(struct u132_urbq), GFP_ATOMIC); + if (urbq == NULL) { + endp->queue_size -= 1; + return -ENOMEM; + } else { + list_add_tail(&urbq->urb_more, &endp->urb_more); + urbq->urb = urb; + } + } + return 0; + } } static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { - struct u132 *u132 = hcd_to_u132(hcd); - if (irqs_disabled()) { - if (__GFP_WAIT & mem_flags) { - printk(KERN_ERR "invalid context for function that migh" - "t sleep\n"); - return -EINVAL; - } - } - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { + struct u132 *u132 = hcd_to_u132(hcd); + if (irqs_disabled()) { + if (__GFP_WAIT & mem_flags) { + printk(KERN_ERR "invalid context for function that migh" + "t sleep\n"); + return -EINVAL; + } + } + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - return -ESHUTDOWN; - } else { - u8 usb_addr = usb_pipedevice(urb->pipe); - u8 usb_endp = usb_pipeendpoint(urb->pipe); - struct usb_device *usb_dev = urb->dev; - if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - struct u132_endp *endp = urb->ep->hcpriv; - urb->actual_length = 0; - if (endp) { - unsigned long irqs; - int retval; - spin_lock_irqsave(&endp->queue_lock.slock, - irqs); + return -ESHUTDOWN; + } else { + u8 usb_addr = usb_pipedevice(urb->pipe); + u8 usb_endp = usb_pipeendpoint(urb->pipe); + struct usb_device *usb_dev = urb->dev; + if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + struct u132_endp *endp = urb->ep->hcpriv; + urb->actual_length = 0; + if (endp) { + unsigned long irqs; + int retval; + spin_lock_irqsave(&endp->queue_lock.slock, + irqs); retval = usb_hcd_link_urb_to_ep(hcd, urb); if (retval == 0) { retval = queue_int_on_old_endpoint( @@ -2301,39 +2288,39 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, address); if (retval) usb_hcd_unlink_urb_from_ep( - hcd, urb); + hcd, urb); + } + spin_unlock_irqrestore(&endp->queue_lock.slock, + irqs); + if (retval) { + return retval; + } else { + u132_endp_queue_work(u132, endp, + msecs_to_jiffies(urb->interval)) + ; + return 0; } - spin_unlock_irqrestore(&endp->queue_lock.slock, - irqs); - if (retval) { - return retval; - } else { - u132_endp_queue_work(u132, endp, - msecs_to_jiffies(urb->interval)) - ; - return 0; - } - } else if (u132->num_endpoints == MAX_U132_ENDPS) { - return -EINVAL; - } else { /*(endp == NULL) */ - return create_endpoint_and_queue_int(u132, udev, + } else if (u132->num_endpoints == MAX_U132_ENDPS) { + return -EINVAL; + } else { /*(endp == NULL) */ + return create_endpoint_and_queue_int(u132, udev, urb, usb_dev, usb_addr, usb_endp, address, mem_flags); - } - } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - dev_err(&u132->platform_dev->dev, "the hardware does no" - "t support PIPE_ISOCHRONOUS\n"); - return -EINVAL; - } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - struct u132_endp *endp = urb->ep->hcpriv; - urb->actual_length = 0; - if (endp) { - unsigned long irqs; - int retval; - spin_lock_irqsave(&endp->queue_lock.slock, - irqs); + } + } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + dev_err(&u132->platform_dev->dev, "the hardware does no" + "t support PIPE_ISOCHRONOUS\n"); + return -EINVAL; + } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + struct u132_endp *endp = urb->ep->hcpriv; + urb->actual_length = 0; + if (endp) { + unsigned long irqs; + int retval; + spin_lock_irqsave(&endp->queue_lock.slock, + irqs); retval = usb_hcd_link_urb_to_ep(hcd, urb); if (retval == 0) { retval = queue_bulk_on_old_endpoint( @@ -2343,46 +2330,46 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, address); if (retval) usb_hcd_unlink_urb_from_ep( - hcd, urb); + hcd, urb); + } + spin_unlock_irqrestore(&endp->queue_lock.slock, + irqs); + if (retval) { + return retval; + } else { + u132_endp_queue_work(u132, endp, 0); + return 0; } - spin_unlock_irqrestore(&endp->queue_lock.slock, - irqs); - if (retval) { - return retval; - } else { - u132_endp_queue_work(u132, endp, 0); - return 0; - } - } else if (u132->num_endpoints == MAX_U132_ENDPS) { - return -EINVAL; - } else - return create_endpoint_and_queue_bulk(u132, + } else if (u132->num_endpoints == MAX_U132_ENDPS) { + return -EINVAL; + } else + return create_endpoint_and_queue_bulk(u132, udev, urb, usb_dev, usb_addr, - usb_endp, address, mem_flags); - } else { - struct u132_endp *endp = urb->ep->hcpriv; - u16 urb_size = 8; - u8 *b = urb->setup_packet; - int i = 0; - char data[30 *3 + 4]; - char *d = data; - int m = (sizeof(data) - 1) / 3; - int l = 0; - data[0] = 0; - while (urb_size-- > 0) { - if (i > m) { - } else if (i++ < m) { - int w = sprintf(d, " %02X", *b++); - d += w; - l += w; - } else - d += sprintf(d, " .."); - } - if (endp) { - unsigned long irqs; - int retval; - spin_lock_irqsave(&endp->queue_lock.slock, - irqs); + usb_endp, address, mem_flags); + } else { + struct u132_endp *endp = urb->ep->hcpriv; + u16 urb_size = 8; + u8 *b = urb->setup_packet; + int i = 0; + char data[30 * 3 + 4]; + char *d = data; + int m = (sizeof(data) - 1) / 3; + int l = 0; + data[0] = 0; + while (urb_size-- > 0) { + if (i > m) { + } else if (i++ < m) { + int w = sprintf(d, " %02X", *b++); + d += w; + l += w; + } else + d += sprintf(d, " .."); + } + if (endp) { + unsigned long irqs; + int retval; + spin_lock_irqsave(&endp->queue_lock.slock, + irqs); retval = usb_hcd_link_urb_to_ep(hcd, urb); if (retval == 0) { retval = queue_control_on_old_endpoint( @@ -2393,267 +2380,267 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, usb_hcd_unlink_urb_from_ep( hcd, urb); } - spin_unlock_irqrestore(&endp->queue_lock.slock, - irqs); - if (retval) { - return retval; - } else { - u132_endp_queue_work(u132, endp, 0); - return 0; - } - } else if (u132->num_endpoints == MAX_U132_ENDPS) { - return -EINVAL; - } else - return create_endpoint_and_queue_control(u132, + spin_unlock_irqrestore(&endp->queue_lock.slock, + irqs); + if (retval) { + return retval; + } else { + u132_endp_queue_work(u132, endp, 0); + return 0; + } + } else if (u132->num_endpoints == MAX_U132_ENDPS) { + return -EINVAL; + } else + return create_endpoint_and_queue_control(u132, urb, usb_dev, usb_addr, usb_endp, - mem_flags); - } - } + mem_flags); + } + } } static int dequeue_from_overflow_chain(struct u132 *u132, - struct u132_endp *endp, struct urb *urb) -{ - struct list_head *scan; - struct list_head *head = &endp->urb_more; - list_for_each(scan, head) { - struct u132_urbq *urbq = list_entry(scan, struct u132_urbq, - urb_more); - if (urbq->urb == urb) { - struct usb_hcd *hcd = u132_to_hcd(u132); - list_del(scan); - endp->queue_size -= 1; - urb->error_count = 0; + struct u132_endp *endp, struct urb *urb) +{ + struct list_head *scan; + struct list_head *head = &endp->urb_more; + list_for_each(scan, head) { + struct u132_urbq *urbq = list_entry(scan, struct u132_urbq, + urb_more); + if (urbq->urb == urb) { + struct usb_hcd *hcd = u132_to_hcd(u132); + list_del(scan); + endp->queue_size -= 1; + urb->error_count = 0; usb_hcd_giveback_urb(hcd, urb, 0); - return 0; - } else - continue; - } - dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]=%p ring" - "[%d] %c%c usb_endp=%d usb_addr=%d size=%d next=%04X last=%04X" - "\n", urb, endp->endp_number, endp, endp->ring->number, - endp->input ? 'I' : ' ', endp->output ? 'O' : ' ', - endp->usb_endp, endp->usb_addr, endp->queue_size, - endp->queue_next, endp->queue_last); - return -EINVAL; + return 0; + } else + continue; + } + dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]=%p ring" + "[%d] %c%c usb_endp=%d usb_addr=%d size=%d next=%04X last=%04X" + "\n", urb, endp->endp_number, endp, endp->ring->number, + endp->input ? 'I' : ' ', endp->output ? 'O' : ' ', + endp->usb_endp, endp->usb_addr, endp->queue_size, + endp->queue_next, endp->queue_last); + return -EINVAL; } static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, struct urb *urb, int status) { - unsigned long irqs; + unsigned long irqs; int rc; - spin_lock_irqsave(&endp->queue_lock.slock, irqs); + spin_lock_irqsave(&endp->queue_lock.slock, irqs); rc = usb_hcd_check_unlink_urb(u132_to_hcd(u132), urb, status); if (rc) { spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); return rc; } - if (endp->queue_size == 0) { - dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" - "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, - endp->endp_number, endp, endp->ring->number, - endp->input ? 'I' : ' ', endp->output ? 'O' : ' ', - endp->usb_endp, endp->usb_addr); - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - return -EINVAL; - } - if (urb == endp->urb_list[ENDP_QUEUE_MASK & endp->queue_next]) { - if (endp->active) { - endp->dequeueing = 1; - endp->edset_flush = 1; - u132_endp_queue_work(u132, endp, 0); - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - return 0; - } else { - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + if (endp->queue_size == 0) { + dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" + "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, + endp->endp_number, endp, endp->ring->number, + endp->input ? 'I' : ' ', endp->output ? 'O' : ' ', + endp->usb_endp, endp->usb_addr); + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + return -EINVAL; + } + if (urb == endp->urb_list[ENDP_QUEUE_MASK & endp->queue_next]) { + if (endp->active) { + endp->dequeueing = 1; + endp->edset_flush = 1; + u132_endp_queue_work(u132, endp, 0); + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + return 0; + } else { + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); u132_hcd_abandon_urb(u132, endp, urb, status); - return 0; - } - } else { - u16 queue_list = 0; - u16 queue_size = endp->queue_size; - u16 queue_scan = endp->queue_next; - struct urb **urb_slot = NULL; - while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) { - if (urb == endp->urb_list[ENDP_QUEUE_MASK & - ++queue_scan]) { - urb_slot = &endp->urb_list[ENDP_QUEUE_MASK & - queue_scan]; - break; - } else - continue; - } - while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) { - *urb_slot = endp->urb_list[ENDP_QUEUE_MASK & - ++queue_scan]; - urb_slot = &endp->urb_list[ENDP_QUEUE_MASK & - queue_scan]; - } - if (urb_slot) { - struct usb_hcd *hcd = u132_to_hcd(u132); + return 0; + } + } else { + u16 queue_list = 0; + u16 queue_size = endp->queue_size; + u16 queue_scan = endp->queue_next; + struct urb **urb_slot = NULL; + while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) { + if (urb == endp->urb_list[ENDP_QUEUE_MASK & + ++queue_scan]) { + urb_slot = &endp->urb_list[ENDP_QUEUE_MASK & + queue_scan]; + break; + } else + continue; + } + while (++queue_list < ENDP_QUEUE_SIZE && --queue_size > 0) { + *urb_slot = endp->urb_list[ENDP_QUEUE_MASK & + ++queue_scan]; + urb_slot = &endp->urb_list[ENDP_QUEUE_MASK & + queue_scan]; + } + if (urb_slot) { + struct usb_hcd *hcd = u132_to_hcd(u132); usb_hcd_unlink_urb_from_ep(hcd, urb); - endp->queue_size -= 1; - if (list_empty(&endp->urb_more)) { - spin_unlock_irqrestore(&endp->queue_lock.slock, - irqs); - } else { - struct list_head *next = endp->urb_more.next; - struct u132_urbq *urbq = list_entry(next, - struct u132_urbq, urb_more); - list_del(next); - *urb_slot = urbq->urb; - spin_unlock_irqrestore(&endp->queue_lock.slock, - irqs); - kfree(urbq); - } urb->error_count = 0; + endp->queue_size -= 1; + if (list_empty(&endp->urb_more)) { + spin_unlock_irqrestore(&endp->queue_lock.slock, + irqs); + } else { + struct list_head *next = endp->urb_more.next; + struct u132_urbq *urbq = list_entry(next, + struct u132_urbq, urb_more); + list_del(next); + *urb_slot = urbq->urb; + spin_unlock_irqrestore(&endp->queue_lock.slock, + irqs); + kfree(urbq); + } urb->error_count = 0; usb_hcd_giveback_urb(hcd, urb, status); - return 0; - } else if (list_empty(&endp->urb_more)) { - dev_err(&u132->platform_dev->dev, "urb=%p not found in " - "endp[%d]=%p ring[%d] %c%c usb_endp=%d usb_addr" - "=%d size=%d next=%04X last=%04X\n", urb, - endp->endp_number, endp, endp->ring->number, - endp->input ? 'I' : ' ', - endp->output ? 'O' : ' ', endp->usb_endp, - endp->usb_addr, endp->queue_size, - endp->queue_next, endp->queue_last); - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - return -EINVAL; - } else { + return 0; + } else if (list_empty(&endp->urb_more)) { + dev_err(&u132->platform_dev->dev, "urb=%p not found in " + "endp[%d]=%p ring[%d] %c%c usb_endp=%d usb_addr" + "=%d size=%d next=%04X last=%04X\n", urb, + endp->endp_number, endp, endp->ring->number, + endp->input ? 'I' : ' ', + endp->output ? 'O' : ' ', endp->usb_endp, + endp->usb_addr, endp->queue_size, + endp->queue_next, endp->queue_last); + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + return -EINVAL; + } else { int retval; usb_hcd_unlink_urb_from_ep(u132_to_hcd(u132), urb); retval = dequeue_from_overflow_chain(u132, endp, - urb); - spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - return retval; - } - } + urb); + spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); + return retval; + } + } } static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 2) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else { - u8 usb_addr = usb_pipedevice(urb->pipe); - u8 usb_endp = usb_pipeendpoint(urb->pipe); - u8 address = u132->addr[usb_addr].address; - struct u132_udev *udev = &u132->udev[address]; - if (usb_pipein(urb->pipe)) { - u8 endp_number = udev->endp_number_in[usb_endp]; - struct u132_endp *endp = u132->endp[endp_number - 1]; - return u132_endp_urb_dequeue(u132, endp, urb, status); - } else { - u8 endp_number = udev->endp_number_out[usb_endp]; - struct u132_endp *endp = u132->endp[endp_number - 1]; - return u132_endp_urb_dequeue(u132, endp, urb, status); - } - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 2) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else { + u8 usb_addr = usb_pipedevice(urb->pipe); + u8 usb_endp = usb_pipeendpoint(urb->pipe); + u8 address = u132->addr[usb_addr].address; + struct u132_udev *udev = &u132->udev[address]; + if (usb_pipein(urb->pipe)) { + u8 endp_number = udev->endp_number_in[usb_endp]; + struct u132_endp *endp = u132->endp[endp_number - 1]; + return u132_endp_urb_dequeue(u132, endp, urb, status); + } else { + u8 endp_number = udev->endp_number_out[usb_endp]; + struct u132_endp *endp = u132->endp[endp_number - 1]; + return u132_endp_urb_dequeue(u132, endp, urb, status); + } + } } static void u132_endpoint_disable(struct usb_hcd *hcd, - struct usb_host_endpoint *hep) -{ - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 2) { - dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p" - ") has been removed %d\n", u132, hcd, hep, - u132->going); - } else { - struct u132_endp *endp = hep->hcpriv; - if (endp) - u132_endp_put_kref(u132, endp); - } + struct usb_host_endpoint *hep) +{ + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 2) { + dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p" + ") has been removed %d\n", u132, hcd, hep, + u132->going); + } else { + struct u132_endp *endp = hep->hcpriv; + if (endp) + u132_endp_put_kref(u132, endp); + } } static int u132_get_frame(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else { - int frame = 0; - dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n"); - msleep(100); - return frame; - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else { + int frame = 0; + dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n"); + msleep(100); + return frame; + } } static int u132_roothub_descriptor(struct u132 *u132, - struct usb_hub_descriptor *desc) -{ - int retval; - u16 temp; - u32 rh_a = -1; - u32 rh_b = -1; - retval = u132_read_pcimem(u132, roothub.a, &rh_a); - if (retval) - return retval; - desc->bDescriptorType = 0x29; - desc->bPwrOn2PwrGood = (rh_a & RH_A_POTPGT) >> 24; - desc->bHubContrCurrent = 0; - desc->bNbrPorts = u132->num_ports; - temp = 1 + (u132->num_ports / 8); - desc->bDescLength = 7 + 2 *temp; - temp = 0; - if (rh_a & RH_A_NPS) - temp |= 0x0002; - if (rh_a & RH_A_PSM) - temp |= 0x0001; - if (rh_a & RH_A_NOCP) { - temp |= 0x0010; - } else if (rh_a & RH_A_OCPM) - temp |= 0x0008; - desc->wHubCharacteristics = cpu_to_le16(temp); - retval = u132_read_pcimem(u132, roothub.b, &rh_b); - if (retval) - return retval; - memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); - desc->bitmap[0] = rh_b & RH_B_DR; - if (u132->num_ports > 7) { - desc->bitmap[1] = (rh_b & RH_B_DR) >> 8; - desc->bitmap[2] = 0xff; - } else - desc->bitmap[1] = 0xff; - return 0; + struct usb_hub_descriptor *desc) +{ + int retval; + u16 temp; + u32 rh_a = -1; + u32 rh_b = -1; + retval = u132_read_pcimem(u132, roothub.a, &rh_a); + if (retval) + return retval; + desc->bDescriptorType = 0x29; + desc->bPwrOn2PwrGood = (rh_a & RH_A_POTPGT) >> 24; + desc->bHubContrCurrent = 0; + desc->bNbrPorts = u132->num_ports; + temp = 1 + (u132->num_ports / 8); + desc->bDescLength = 7 + 2 * temp; + temp = 0; + if (rh_a & RH_A_NPS) + temp |= 0x0002; + if (rh_a & RH_A_PSM) + temp |= 0x0001; + if (rh_a & RH_A_NOCP) + temp |= 0x0010; + else if (rh_a & RH_A_OCPM) + temp |= 0x0008; + desc->wHubCharacteristics = cpu_to_le16(temp); + retval = u132_read_pcimem(u132, roothub.b, &rh_b); + if (retval) + return retval; + memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); + desc->bitmap[0] = rh_b & RH_B_DR; + if (u132->num_ports > 7) { + desc->bitmap[1] = (rh_b & RH_B_DR) >> 8; + desc->bitmap[2] = 0xff; + } else + desc->bitmap[1] = 0xff; + return 0; } static int u132_roothub_status(struct u132 *u132, __le32 *desc) { - u32 rh_status = -1; - int ret_status = u132_read_pcimem(u132, roothub.status, &rh_status); - *desc = cpu_to_le32(rh_status); - return ret_status; + u32 rh_status = -1; + int ret_status = u132_read_pcimem(u132, roothub.status, &rh_status); + *desc = cpu_to_le32(rh_status); + return ret_status; } static int u132_roothub_portstatus(struct u132 *u132, __le32 *desc, u16 wIndex) { - if (wIndex == 0 || wIndex > u132->num_ports) { - return -EINVAL; - } else { - int port = wIndex - 1; - u32 rh_portstatus = -1; - int ret_portstatus = u132_read_pcimem(u132, - roothub.portstatus[port], &rh_portstatus); - *desc = cpu_to_le32(rh_portstatus); - if (*(u16 *) (desc + 2)) { - dev_info(&u132->platform_dev->dev, "Port %d Status Chan" - "ge = %08X\n", port, *desc); - } - return ret_portstatus; - } + if (wIndex == 0 || wIndex > u132->num_ports) { + return -EINVAL; + } else { + int port = wIndex - 1; + u32 rh_portstatus = -1; + int ret_portstatus = u132_read_pcimem(u132, + roothub.portstatus[port], &rh_portstatus); + *desc = cpu_to_le32(rh_portstatus); + if (*(u16 *) (desc + 2)) { + dev_info(&u132->platform_dev->dev, "Port %d Status Chan" + "ge = %08X\n", port, *desc); + } + return ret_portstatus; + } } @@ -2664,353 +2651,355 @@ static int u132_roothub_portstatus(struct u132 *u132, __le32 *desc, u16 wIndex) #define tick_before(t1, t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) static int u132_roothub_portreset(struct u132 *u132, int port_index) { - int retval; - u32 fmnumber; - u16 now; - u16 reset_done; - retval = u132_read_pcimem(u132, fmnumber, &fmnumber); - if (retval) - return retval; - now = fmnumber; - reset_done = now + PORT_RESET_MSEC; - do { - u32 portstat; - do { - retval = u132_read_pcimem(u132, - roothub.portstatus[port_index], &portstat); - if (retval) - return retval; - if (RH_PS_PRS & portstat) { - continue; - } else - break; - } while (tick_before(now, reset_done)); - if (RH_PS_PRS & portstat) - return -ENODEV; - if (RH_PS_CCS & portstat) { - if (RH_PS_PRSC & portstat) { - retval = u132_write_pcimem(u132, - roothub.portstatus[port_index], - RH_PS_PRSC); - if (retval) - return retval; - } - } else - break; /* start the next reset, - sleep till it's probably done */ - retval = u132_write_pcimem(u132, roothub.portstatus[port_index], - RH_PS_PRS); - if (retval) - return retval; - msleep(PORT_RESET_HW_MSEC); - retval = u132_read_pcimem(u132, fmnumber, &fmnumber); - if (retval) - return retval; - now = fmnumber; - } while (tick_before(now, reset_done)); - return 0; + int retval; + u32 fmnumber; + u16 now; + u16 reset_done; + retval = u132_read_pcimem(u132, fmnumber, &fmnumber); + if (retval) + return retval; + now = fmnumber; + reset_done = now + PORT_RESET_MSEC; + do { + u32 portstat; + do { + retval = u132_read_pcimem(u132, + roothub.portstatus[port_index], &portstat); + if (retval) + return retval; + if (RH_PS_PRS & portstat) + continue; + else + break; + } while (tick_before(now, reset_done)); + if (RH_PS_PRS & portstat) + return -ENODEV; + if (RH_PS_CCS & portstat) { + if (RH_PS_PRSC & portstat) { + retval = u132_write_pcimem(u132, + roothub.portstatus[port_index], + RH_PS_PRSC); + if (retval) + return retval; + } + } else + break; /* start the next reset, + sleep till it's probably done */ + retval = u132_write_pcimem(u132, roothub.portstatus[port_index], + RH_PS_PRS); + if (retval) + return retval; + msleep(PORT_RESET_HW_MSEC); + retval = u132_read_pcimem(u132, fmnumber, &fmnumber); + if (retval) + return retval; + now = fmnumber; + } while (tick_before(now, reset_done)); + return 0; } static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue, - u16 wIndex) -{ - if (wIndex == 0 || wIndex > u132->num_ports) { - return -EINVAL; - } else { - int retval; - int port_index = wIndex - 1; - struct u132_port *port = &u132->port[port_index]; - port->Status &= ~(1 << wValue); - switch (wValue) { - case USB_PORT_FEAT_SUSPEND: - retval = u132_write_pcimem(u132, - roothub.portstatus[port_index], RH_PS_PSS); - if (retval) - return retval; - return 0; - case USB_PORT_FEAT_POWER: - retval = u132_write_pcimem(u132, - roothub.portstatus[port_index], RH_PS_PPS); - if (retval) - return retval; - return 0; - case USB_PORT_FEAT_RESET: - retval = u132_roothub_portreset(u132, port_index); - if (retval) - return retval; - return 0; - default: - return -EPIPE; - } - } + u16 wIndex) +{ + if (wIndex == 0 || wIndex > u132->num_ports) { + return -EINVAL; + } else { + int retval; + int port_index = wIndex - 1; + struct u132_port *port = &u132->port[port_index]; + port->Status &= ~(1 << wValue); + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + retval = u132_write_pcimem(u132, + roothub.portstatus[port_index], RH_PS_PSS); + if (retval) + return retval; + return 0; + case USB_PORT_FEAT_POWER: + retval = u132_write_pcimem(u132, + roothub.portstatus[port_index], RH_PS_PPS); + if (retval) + return retval; + return 0; + case USB_PORT_FEAT_RESET: + retval = u132_roothub_portreset(u132, port_index); + if (retval) + return retval; + return 0; + default: + return -EPIPE; + } + } } static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue, - u16 wIndex) -{ - if (wIndex == 0 || wIndex > u132->num_ports) { - return -EINVAL; - } else { - int port_index = wIndex - 1; - u32 temp; - int retval; - struct u132_port *port = &u132->port[port_index]; - port->Status &= ~(1 << wValue); - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - temp = RH_PS_CCS; - break; - case USB_PORT_FEAT_C_ENABLE: - temp = RH_PS_PESC; - break; - case USB_PORT_FEAT_SUSPEND: - temp = RH_PS_POCI; - if ((u132->hc_control & OHCI_CTRL_HCFS) - != OHCI_USB_OPER) { - dev_err(&u132->platform_dev->dev, "TODO resume_" - "root_hub\n"); - } - break; - case USB_PORT_FEAT_C_SUSPEND: - temp = RH_PS_PSSC; - break; - case USB_PORT_FEAT_POWER: - temp = RH_PS_LSDA; - break; - case USB_PORT_FEAT_C_CONNECTION: - temp = RH_PS_CSC; - break; - case USB_PORT_FEAT_C_OVER_CURRENT: - temp = RH_PS_OCIC; - break; - case USB_PORT_FEAT_C_RESET: - temp = RH_PS_PRSC; - break; - default: - return -EPIPE; - } - retval = u132_write_pcimem(u132, roothub.portstatus[port_index], - temp); - if (retval) - return retval; - return 0; - } + u16 wIndex) +{ + if (wIndex == 0 || wIndex > u132->num_ports) { + return -EINVAL; + } else { + int port_index = wIndex - 1; + u32 temp; + int retval; + struct u132_port *port = &u132->port[port_index]; + port->Status &= ~(1 << wValue); + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + temp = RH_PS_CCS; + break; + case USB_PORT_FEAT_C_ENABLE: + temp = RH_PS_PESC; + break; + case USB_PORT_FEAT_SUSPEND: + temp = RH_PS_POCI; + if ((u132->hc_control & OHCI_CTRL_HCFS) + != OHCI_USB_OPER) { + dev_err(&u132->platform_dev->dev, "TODO resume_" + "root_hub\n"); + } + break; + case USB_PORT_FEAT_C_SUSPEND: + temp = RH_PS_PSSC; + break; + case USB_PORT_FEAT_POWER: + temp = RH_PS_LSDA; + break; + case USB_PORT_FEAT_C_CONNECTION: + temp = RH_PS_CSC; + break; + case USB_PORT_FEAT_C_OVER_CURRENT: + temp = RH_PS_OCIC; + break; + case USB_PORT_FEAT_C_RESET: + temp = RH_PS_PRSC; + break; + default: + return -EPIPE; + } + retval = u132_write_pcimem(u132, roothub.portstatus[port_index], + temp); + if (retval) + return retval; + return 0; + } } /* the virtual root hub timer IRQ checks for hub status*/ static int u132_hub_status_data(struct usb_hcd *hcd, char *buf) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device hcd=%p has been remov" - "ed %d\n", hcd, u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" - "ed\n", hcd); - return -ESHUTDOWN; - } else { - int i, changed = 0, length = 1; - if (u132->flags & OHCI_QUIRK_AMD756) { - if ((u132->hc_roothub_a & RH_A_NDP) > MAX_ROOT_PORTS) { - dev_err(&u132->platform_dev->dev, "bogus NDP, r" - "ereads as NDP=%d\n", - u132->hc_roothub_a & RH_A_NDP); - goto done; - } - } - if (u132->hc_roothub_status & (RH_HS_LPSC | RH_HS_OCIC)) { - buf[0] = changed = 1; - } else - buf[0] = 0; - if (u132->num_ports > 7) { - buf[1] = 0; - length++; - } - for (i = 0; i < u132->num_ports; i++) { - if (u132->hc_roothub_portstatus[i] & (RH_PS_CSC | - RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | - RH_PS_PRSC)) { - changed = 1; - if (i < 7) { - buf[0] |= 1 << (i + 1); - } else - buf[1] |= 1 << (i - 7); - continue; - } - if (!(u132->hc_roothub_portstatus[i] & RH_PS_CCS)) { - continue; - } - if ((u132->hc_roothub_portstatus[i] & RH_PS_PSS)) { - continue; - } - } - done:return changed ? length : 0; - } + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device hcd=%p has been remov" + "ed %d\n", hcd, u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" + "ed\n", hcd); + return -ESHUTDOWN; + } else { + int i, changed = 0, length = 1; + if (u132->flags & OHCI_QUIRK_AMD756) { + if ((u132->hc_roothub_a & RH_A_NDP) > MAX_ROOT_PORTS) { + dev_err(&u132->platform_dev->dev, "bogus NDP, r" + "ereads as NDP=%d\n", + u132->hc_roothub_a & RH_A_NDP); + goto done; + } + } + if (u132->hc_roothub_status & (RH_HS_LPSC | RH_HS_OCIC)) + buf[0] = changed = 1; + else + buf[0] = 0; + if (u132->num_ports > 7) { + buf[1] = 0; + length++; + } + for (i = 0; i < u132->num_ports; i++) { + if (u132->hc_roothub_portstatus[i] & (RH_PS_CSC | + RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | + RH_PS_PRSC)) { + changed = 1; + if (i < 7) + buf[0] |= 1 << (i + 1); + else + buf[1] |= 1 << (i - 7); + continue; + } + if (!(u132->hc_roothub_portstatus[i] & RH_PS_CCS)) + continue; + + if ((u132->hc_roothub_portstatus[i] & RH_PS_PSS)) + continue; + } +done: + return changed ? length : 0; + } } static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, - u16 wIndex, char *buf, u16 wLength) -{ - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else { - int retval = 0; - mutex_lock(&u132->sw_lock); - switch (typeReq) { - case ClearHubFeature: - switch (wValue) { - case C_HUB_OVER_CURRENT: - case C_HUB_LOCAL_POWER: - break; - default: - goto stall; - } - break; - case SetHubFeature: - switch (wValue) { - case C_HUB_OVER_CURRENT: - case C_HUB_LOCAL_POWER: - break; - default: - goto stall; - } - break; - case ClearPortFeature:{ - retval = u132_roothub_clearportfeature(u132, - wValue, wIndex); - if (retval) - goto error; - break; - } - case GetHubDescriptor:{ - retval = u132_roothub_descriptor(u132, - (struct usb_hub_descriptor *)buf); - if (retval) - goto error; - break; - } - case GetHubStatus:{ - retval = u132_roothub_status(u132, - (__le32 *) buf); - if (retval) - goto error; - break; - } - case GetPortStatus:{ - retval = u132_roothub_portstatus(u132, - (__le32 *) buf, wIndex); - if (retval) - goto error; - break; - } - case SetPortFeature:{ - retval = u132_roothub_setportfeature(u132, - wValue, wIndex); - if (retval) - goto error; - break; - } - default: - goto stall; - error:u132_disable(u132); - u132->going = 1; - break; - stall:retval = -EPIPE; - break; - } - mutex_unlock(&u132->sw_lock); - return retval; - } + u16 wIndex, char *buf, u16 wLength) +{ + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else { + int retval = 0; + mutex_lock(&u132->sw_lock); + switch (typeReq) { + case ClearHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: + case C_HUB_LOCAL_POWER: + break; + default: + goto stall; + } + break; + case SetHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: + case C_HUB_LOCAL_POWER: + break; + default: + goto stall; + } + break; + case ClearPortFeature:{ + retval = u132_roothub_clearportfeature(u132, + wValue, wIndex); + if (retval) + goto error; + break; + } + case GetHubDescriptor:{ + retval = u132_roothub_descriptor(u132, + (struct usb_hub_descriptor *)buf); + if (retval) + goto error; + break; + } + case GetHubStatus:{ + retval = u132_roothub_status(u132, + (__le32 *) buf); + if (retval) + goto error; + break; + } + case GetPortStatus:{ + retval = u132_roothub_portstatus(u132, + (__le32 *) buf, wIndex); + if (retval) + goto error; + break; + } + case SetPortFeature:{ + retval = u132_roothub_setportfeature(u132, + wValue, wIndex); + if (retval) + goto error; + break; + } + default: + goto stall; + error: + u132_disable(u132); + u132->going = 1; + break; + stall: + retval = -EPIPE; + break; + } + mutex_unlock(&u132->sw_lock); + return retval; + } } static int u132_start_port_reset(struct usb_hcd *hcd, unsigned port_num) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else + return 0; } static void u132_hub_irq_enable(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - } else if (u132->going > 0) - dev_err(&u132->platform_dev->dev, "device is being removed\n"); + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + } else if (u132->going > 0) + dev_err(&u132->platform_dev->dev, "device is being removed\n"); } #ifdef CONFIG_PM static int u132_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else + return 0; } static int u132_hcd_resume(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else + return 0; } static int u132_bus_suspend(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else + return 0; } static int u132_bus_resume(struct usb_hcd *hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else + return 0; } #else @@ -3020,25 +3009,25 @@ static int u132_bus_resume(struct usb_hcd *hcd) #define u132_bus_resume NULL #endif static struct hc_driver u132_hc_driver = { - .description = hcd_name, - .hcd_priv_size = sizeof(struct u132), - .irq = NULL, - .flags = HCD_USB11 | HCD_MEMORY, - .reset = u132_hcd_reset, - .start = u132_hcd_start, - .suspend = u132_hcd_suspend, - .resume = u132_hcd_resume, - .stop = u132_hcd_stop, - .urb_enqueue = u132_urb_enqueue, - .urb_dequeue = u132_urb_dequeue, - .endpoint_disable = u132_endpoint_disable, - .get_frame_number = u132_get_frame, - .hub_status_data = u132_hub_status_data, - .hub_control = u132_hub_control, - .bus_suspend = u132_bus_suspend, - .bus_resume = u132_bus_resume, - .start_port_reset = u132_start_port_reset, - .hub_irq_enable = u132_hub_irq_enable, + .description = hcd_name, + .hcd_priv_size = sizeof(struct u132), + .irq = NULL, + .flags = HCD_USB11 | HCD_MEMORY, + .reset = u132_hcd_reset, + .start = u132_hcd_start, + .suspend = u132_hcd_suspend, + .resume = u132_hcd_resume, + .stop = u132_hcd_stop, + .urb_enqueue = u132_urb_enqueue, + .urb_dequeue = u132_urb_dequeue, + .endpoint_disable = u132_endpoint_disable, + .get_frame_number = u132_get_frame, + .hub_status_data = u132_hub_status_data, + .hub_control = u132_hub_control, + .bus_suspend = u132_bus_suspend, + .bus_resume = u132_bus_resume, + .start_port_reset = u132_start_port_reset, + .hub_irq_enable = u132_hub_irq_enable, }; /* @@ -3049,148 +3038,152 @@ static struct hc_driver u132_hc_driver = { */ static int __devexit u132_remove(struct platform_device *pdev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - if (hcd) { - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going++ > 1) { - dev_err(&u132->platform_dev->dev, "already being remove" + struct usb_hcd *hcd = platform_get_drvdata(pdev); + if (hcd) { + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going++ > 1) { + dev_err(&u132->platform_dev->dev, "already being remove" "d\n"); - return -ENODEV; - } else { - int rings = MAX_U132_RINGS; - int endps = MAX_U132_ENDPS; - dev_err(&u132->platform_dev->dev, "removing device u132" + return -ENODEV; + } else { + int rings = MAX_U132_RINGS; + int endps = MAX_U132_ENDPS; + dev_err(&u132->platform_dev->dev, "removing device u132" ".%d\n", u132->sequence_num); - msleep(100); - mutex_lock(&u132->sw_lock); - u132_monitor_cancel_work(u132); - while (rings-- > 0) { - struct u132_ring *ring = &u132->ring[rings]; - u132_ring_cancel_work(u132, ring); - } while (endps-- > 0) { - struct u132_endp *endp = u132->endp[endps]; - if (endp) - u132_endp_cancel_work(u132, endp); - } - u132->going += 1; - printk(KERN_INFO "removing device u132.%d\n", - u132->sequence_num); - mutex_unlock(&u132->sw_lock); - usb_remove_hcd(hcd); - u132_u132_put_kref(u132); - return 0; - } - } else - return 0; + msleep(100); + mutex_lock(&u132->sw_lock); + u132_monitor_cancel_work(u132); + while (rings-- > 0) { + struct u132_ring *ring = &u132->ring[rings]; + u132_ring_cancel_work(u132, ring); + } while (endps-- > 0) { + struct u132_endp *endp = u132->endp[endps]; + if (endp) + u132_endp_cancel_work(u132, endp); + } + u132->going += 1; + printk(KERN_INFO "removing device u132.%d\n", + u132->sequence_num); + mutex_unlock(&u132->sw_lock); + usb_remove_hcd(hcd); + u132_u132_put_kref(u132); + return 0; + } + } else + return 0; } static void u132_initialise(struct u132 *u132, struct platform_device *pdev) { - int rings = MAX_U132_RINGS; - int ports = MAX_U132_PORTS; - int addrs = MAX_U132_ADDRS; - int udevs = MAX_U132_UDEVS; - int endps = MAX_U132_ENDPS; - u132->board = pdev->dev.platform_data; - u132->platform_dev = pdev; - u132->power = 0; - u132->reset = 0; - mutex_init(&u132->sw_lock); - init_MUTEX(&u132->scheduler_lock); - while (rings-- > 0) { - struct u132_ring *ring = &u132->ring[rings]; - ring->u132 = u132; - ring->number = rings + 1; - ring->length = 0; - ring->curr_endp = NULL; - INIT_DELAYED_WORK(&ring->scheduler, + int rings = MAX_U132_RINGS; + int ports = MAX_U132_PORTS; + int addrs = MAX_U132_ADDRS; + int udevs = MAX_U132_UDEVS; + int endps = MAX_U132_ENDPS; + u132->board = pdev->dev.platform_data; + u132->platform_dev = pdev; + u132->power = 0; + u132->reset = 0; + mutex_init(&u132->sw_lock); + init_MUTEX(&u132->scheduler_lock); + while (rings-- > 0) { + struct u132_ring *ring = &u132->ring[rings]; + ring->u132 = u132; + ring->number = rings + 1; + ring->length = 0; + ring->curr_endp = NULL; + INIT_DELAYED_WORK(&ring->scheduler, u132_hcd_ring_work_scheduler); - } mutex_lock(&u132->sw_lock); - INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); - while (ports-- > 0) { - struct u132_port *port = &u132->port[ports]; - port->u132 = u132; - port->reset = 0; - port->enable = 0; - port->power = 0; - port->Status = 0; - } while (addrs-- > 0) { - struct u132_addr *addr = &u132->addr[addrs]; - addr->address = 0; - } while (udevs-- > 0) { - struct u132_udev *udev = &u132->udev[udevs]; - int i = ARRAY_SIZE(udev->endp_number_in); - int o = ARRAY_SIZE(udev->endp_number_out); - udev->usb_device = NULL; - udev->udev_number = 0; - udev->usb_addr = 0; - udev->portnumber = 0; - while (i-- > 0) { - udev->endp_number_in[i] = 0; - } - while (o-- > 0) { - udev->endp_number_out[o] = 0; - } - } - while (endps-- > 0) { - u132->endp[endps] = NULL; - } - mutex_unlock(&u132->sw_lock); - return; + } + mutex_lock(&u132->sw_lock); + INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); + while (ports-- > 0) { + struct u132_port *port = &u132->port[ports]; + port->u132 = u132; + port->reset = 0; + port->enable = 0; + port->power = 0; + port->Status = 0; + } + while (addrs-- > 0) { + struct u132_addr *addr = &u132->addr[addrs]; + addr->address = 0; + } + while (udevs-- > 0) { + struct u132_udev *udev = &u132->udev[udevs]; + int i = ARRAY_SIZE(udev->endp_number_in); + int o = ARRAY_SIZE(udev->endp_number_out); + udev->usb_device = NULL; + udev->udev_number = 0; + udev->usb_addr = 0; + udev->portnumber = 0; + while (i-- > 0) + udev->endp_number_in[i] = 0; + + while (o-- > 0) + udev->endp_number_out[o] = 0; + + } + while (endps-- > 0) + u132->endp[endps] = NULL; + + mutex_unlock(&u132->sw_lock); + return; } static int __devinit u132_probe(struct platform_device *pdev) { - struct usb_hcd *hcd; - int retval; - u32 control; - u32 rh_a = -1; - u32 num_ports; - msleep(100); - if (u132_exiting > 0) { - return -ENODEV; - } - retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE); - if (retval) - return retval; - retval = ftdi_read_pcimem(pdev, control, &control); - if (retval) - return retval; - retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a); - if (retval) - return retval; - num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */ - if (pdev->dev.dma_mask) { - return -EINVAL; - } - hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, pdev->dev.bus_id); - if (!hcd) { - printk(KERN_ERR "failed to create the usb hcd struct for U132\n" - ); - ftdi_elan_gone_away(pdev); - return -ENOMEM; - } else { - int retval = 0; - struct u132 *u132 = hcd_to_u132(hcd); - hcd->rsrc_start = 0; - mutex_lock(&u132_module_lock); - list_add_tail(&u132->u132_list, &u132_static_list); - u132->sequence_num = ++u132_instances; - mutex_unlock(&u132_module_lock); - u132_u132_init_kref(u132); - u132_initialise(u132, pdev); - hcd->product_desc = "ELAN U132 Host Controller"; - retval = usb_add_hcd(hcd, 0, 0); - if (retval != 0) { - dev_err(&u132->platform_dev->dev, "init error %d\n", - retval); - u132_u132_put_kref(u132); - return retval; - } else { - u132_monitor_queue_work(u132, 100); - return 0; - } - } + struct usb_hcd *hcd; + int retval; + u32 control; + u32 rh_a = -1; + u32 num_ports; + + msleep(100); + if (u132_exiting > 0) + return -ENODEV; + + retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE); + if (retval) + return retval; + retval = ftdi_read_pcimem(pdev, control, &control); + if (retval) + return retval; + retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a); + if (retval) + return retval; + num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */ + if (pdev->dev.dma_mask) + return -EINVAL; + + hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, pdev->dev.bus_id); + if (!hcd) { + printk(KERN_ERR "failed to create the usb hcd struct for U132\n" + ); + ftdi_elan_gone_away(pdev); + return -ENOMEM; + } else { + int retval = 0; + struct u132 *u132 = hcd_to_u132(hcd); + hcd->rsrc_start = 0; + mutex_lock(&u132_module_lock); + list_add_tail(&u132->u132_list, &u132_static_list); + u132->sequence_num = ++u132_instances; + mutex_unlock(&u132_module_lock); + u132_u132_init_kref(u132); + u132_initialise(u132, pdev); + hcd->product_desc = "ELAN U132 Host Controller"; + retval = usb_add_hcd(hcd, 0, 0); + if (retval != 0) { + dev_err(&u132->platform_dev->dev, "init error %d\n", + retval); + u132_u132_put_kref(u132); + return retval; + } else { + u132_monitor_queue_work(u132, 100); + return 0; + } + } } @@ -3201,58 +3194,58 @@ static int __devinit u132_probe(struct platform_device *pdev) */ static int u132_suspend(struct platform_device *pdev, pm_message_t state) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else { + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else { int retval = 0, ports; switch (state.event) { case PM_EVENT_FREEZE: - retval = u132_bus_suspend(hcd); + retval = u132_bus_suspend(hcd); break; case PM_EVENT_SUSPEND: case PM_EVENT_HIBERNATE: ports = MAX_U132_PORTS; - while (ports-- > 0) { - port_power(u132, ports, 0); - } + while (ports-- > 0) { + port_power(u132, ports, 0); + } break; } - return retval; - } + return retval; + } } static int u132_resume(struct platform_device *pdev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else { - int retval = 0; + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct u132 *u132 = hcd_to_u132(hcd); + if (u132->going > 1) { + dev_err(&u132->platform_dev->dev, "device has been removed %d\n" + , u132->going); + return -ENODEV; + } else if (u132->going > 0) { + dev_err(&u132->platform_dev->dev, "device is being removed\n"); + return -ESHUTDOWN; + } else { + int retval = 0; if (!u132->port[0].power) { - int ports = MAX_U132_PORTS; - while (ports-- > 0) { - port_power(u132, ports, 1); - } - retval = 0; - } else { - retval = u132_bus_resume(hcd); - } - return retval; - } + int ports = MAX_U132_PORTS; + while (ports-- > 0) { + port_power(u132, ports, 1); + } + retval = 0; + } else { + retval = u132_bus_resume(hcd); + } + return retval; + } } #else @@ -3265,47 +3258,48 @@ static int u132_resume(struct platform_device *pdev) * the platform_driver struct is static because it is per type of module */ static struct platform_driver u132_platform_driver = { - .probe = u132_probe, - .remove = __devexit_p(u132_remove), - .suspend = u132_suspend, - .resume = u132_resume, - .driver = { - .name = (char *)hcd_name, - .owner = THIS_MODULE, - }, + .probe = u132_probe, + .remove = __devexit_p(u132_remove), + .suspend = u132_suspend, + .resume = u132_resume, + .driver = { + .name = (char *)hcd_name, + .owner = THIS_MODULE, + }, }; static int __init u132_hcd_init(void) { - int retval; - INIT_LIST_HEAD(&u132_static_list); - u132_instances = 0; - u132_exiting = 0; - mutex_init(&u132_module_lock); - if (usb_disabled()) - return -ENODEV; - printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, - __DATE__); - workqueue = create_singlethread_workqueue("u132"); - retval = platform_driver_register(&u132_platform_driver); - return retval; + int retval; + INIT_LIST_HEAD(&u132_static_list); + u132_instances = 0; + u132_exiting = 0; + mutex_init(&u132_module_lock); + if (usb_disabled()) + return -ENODEV; + printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, + __DATE__); + workqueue = create_singlethread_workqueue("u132"); + retval = platform_driver_register(&u132_platform_driver); + return retval; } module_init(u132_hcd_init); static void __exit u132_hcd_exit(void) { - struct u132 *u132; - struct u132 *temp; - mutex_lock(&u132_module_lock); - u132_exiting += 1; - mutex_unlock(&u132_module_lock); - list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { - platform_device_unregister(u132->platform_dev); - } platform_driver_unregister(&u132_platform_driver); - printk(KERN_INFO "u132-hcd driver deregistered\n"); - wait_event(u132_hcd_wait, u132_instances == 0); - flush_workqueue(workqueue); - destroy_workqueue(workqueue); + struct u132 *u132; + struct u132 *temp; + mutex_lock(&u132_module_lock); + u132_exiting += 1; + mutex_unlock(&u132_module_lock); + list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { + platform_device_unregister(u132->platform_dev); + } + platform_driver_unregister(&u132_platform_driver); + printk(KERN_INFO "u132-hcd driver deregistered\n"); + wait_event(u132_hcd_wait, u132_instances == 0); + flush_workqueue(workqueue); + destroy_workqueue(workqueue); } -- cgit v1.2.2 From 50d8ca9b5624bf50cc3ff624fe9ababf0c789bd2 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Sun, 23 Mar 2008 00:00:02 -0700 Subject: usb: u132-hcd driver: semaphore to mutex Signed-off-by: Daniel Walker Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 220 ++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 28b8684942d3..4616a880d89c 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -184,7 +184,7 @@ struct u132 { struct kref kref; struct list_head u132_list; struct mutex sw_lock; - struct semaphore scheduler_lock; + struct mutex scheduler_lock; struct u132_platform_data *board; struct platform_device *platform_dev; struct u132_ring ring[MAX_U132_RINGS]; @@ -535,12 +535,12 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); } - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); ring = endp->ring; ring->in_use = 0; u132_ring_cancel_work(u132, ring); u132_ring_queue_work(u132, ring, 0); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); usb_hcd_giveback_urb(hcd, urb, status); return; @@ -631,22 +631,22 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { @@ -666,7 +666,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, 1 & toggle_bits); if (urb->actual_length > 0) { int retval; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_single(u132, ring, endp, urb, address, endp->toggle_bits, u132_hcd_interrupt_recv); @@ -680,7 +680,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, msecs_to_jiffies(urb->interval); u132_ring_cancel_work(u132, ring); u132_ring_queue_work(u132, ring, 0); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); } return; @@ -689,7 +689,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, endp->toggle_bits = toggle_bits; usb_settoggle(udev->usb_device, endp->usb_endp, 0, 1 & toggle_bits); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else { @@ -709,7 +709,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, "g back INTERRUPT %s\n", urb, cc_to_text[condition_code]); } - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, cc_to_error[condition_code]); return; @@ -717,7 +717,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -730,22 +730,22 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, struct u132_endp *endp = data; struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { @@ -754,21 +754,21 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, endp->toggle_bits = toggle_bits; if (urb->transfer_buffer_length > urb->actual_length) { int retval; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_output(u132, ring, endp, urb, address, endp->toggle_bits, u132_hcd_bulk_output_sent); if (retval != 0) u132_hcd_giveback_urb(u132, endp, urb, retval); return; } else { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -782,22 +782,22 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { @@ -816,7 +816,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, endp->toggle_bits = toggle_bits; usb_settoggle(udev->usb_device, endp->usb_endp, 0, 1 & toggle_bits); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, endp->toggle_bits, @@ -828,7 +828,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, endp->toggle_bits = toggle_bits; usb_settoggle(udev->usb_device, endp->usb_endp, 0, 1 & toggle_bits); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, cc_to_error[condition_code]); return; @@ -837,7 +837,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, endp->toggle_bits = toggle_bits; usb_settoggle(udev->usb_device, endp->usb_endp, 0, 1 & toggle_bits); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else if (condition_code == TD_DATAUNDERRUN) { @@ -847,13 +847,13 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, dev_warn(&u132->platform_dev->dev, "urb=%p(SHORT NOT OK" ") giving back BULK IN %s\n", urb, cc_to_text[condition_code]); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else if (condition_code == TD_CC_STALL) { endp->toggle_bits = 0x2; usb_settoggle(udev->usb_device, endp->usb_endp, 0, 0); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, cc_to_error[condition_code]); return; @@ -863,7 +863,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "urb=%p giving back B" "ULK IN code=%d %s\n", urb, condition_code, cc_to_text[condition_code]); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, cc_to_error[condition_code]); return; @@ -871,7 +871,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -883,32 +883,32 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, { struct u132_endp *endp = data; struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -921,22 +921,22 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, struct u132_endp *endp = data; struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { @@ -953,7 +953,7 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, TD_DATAUNDERRUN) && ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0))) { int retval; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_empty(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, 0x3, @@ -962,14 +962,14 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, u132_hcd_giveback_urb(u132, endp, urb, retval); return; } else if (condition_code == TD_CC_STALL) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); dev_warn(&u132->platform_dev->dev, "giving back SETUP I" "NPUT STALL urb %p\n", urb); u132_hcd_giveback_urb(u132, endp, urb, cc_to_error[condition_code]); return; } else { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); dev_err(&u132->platform_dev->dev, "giving back SETUP IN" "PUT %s urb %p\n", cc_to_text[condition_code], urb); @@ -980,7 +980,7 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -992,32 +992,32 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, { struct u132_endp *endp = data; struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1030,29 +1030,29 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, struct u132_endp *endp = data; struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { if (usb_pipein(urb->pipe)) { int retval; struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, 0, @@ -1063,7 +1063,7 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, } else { int retval; struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, 0, @@ -1075,7 +1075,7 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1089,34 +1089,34 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; struct u132_udev *udev = &u132->udev[address]; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { u132->addr[0].address = 0; endp->usb_addr = udev->usb_addr; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1128,28 +1128,28 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, { struct u132_endp *endp = data; struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { int retval; struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, urb, 0, endp->usb_endp, 0, u132_hcd_enumeration_empty_recv); @@ -1159,7 +1159,7 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1171,32 +1171,32 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, { struct u132_endp *endp = data; struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1209,22 +1209,22 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, struct u132_endp *endp = data; struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { @@ -1238,7 +1238,7 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, *u++ = *b++; urb->actual_length = len; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_empty(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, 0x3, u132_hcd_initial_empty_sent); @@ -1248,7 +1248,7 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1261,28 +1261,28 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, struct u132_endp *endp = data; struct u132 *u132 = endp->u132; u8 address = u132->addr[endp->usb_addr].address; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_forget_urb(u132, endp, urb, -ENODEV); return; } else if (endp->dequeueing) { endp->dequeueing = 0; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -EINTR); return; } else if (u132->going > 0) { dev_err(&u132->platform_dev->dev, "device is being removed " "urb=%p\n", urb); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); return; } else if (!urb->unlinked) { int retval; struct u132_ring *ring = endp->ring; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = usb_ftdi_elan_edset_input(u132->platform_dev, ring->number, endp, urb, address, endp->usb_endp, 0, u132_hcd_initial_input_recv); @@ -1292,7 +1292,7 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, } else { dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_hcd_giveback_urb(u132, endp, urb, 0); return; } @@ -1307,9 +1307,9 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) struct u132_ring *ring = container_of(work, struct u132_ring, scheduler.work); struct u132 *u132 = ring->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_ring_put_kref(u132, ring); return; } else if (ring->curr_endp) { @@ -1326,7 +1326,7 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) ring->curr_endp = endp; u132_endp_cancel_work(u132, last_endp); u132_endp_queue_work(u132, last_endp, 0); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_ring_put_kref(u132, ring); return; } else { @@ -1340,7 +1340,7 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) last_endp->jiffies)) { u132_endp_cancel_work(u132, last_endp); u132_endp_queue_work(u132, last_endp, 0); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_ring_put_kref(u132, ring); return; } else { @@ -1350,15 +1350,15 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) } if (wakeup > 0) { u132_ring_requeue_work(u132, ring, wakeup); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); return; } else { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_ring_put_kref(u132, ring); return; } } else { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_ring_put_kref(u132, ring); return; } @@ -1370,32 +1370,32 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) struct u132_endp *endp = container_of(work, struct u132_endp, scheduler.work); struct u132 *u132 = endp->u132; - down(&u132->scheduler_lock); + mutex_lock(&u132->scheduler_lock); ring = endp->ring; if (endp->edset_flush) { endp->edset_flush = 0; if (endp->dequeueing) usb_ftdi_elan_edset_flush(u132->platform_dev, ring->number, endp); - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else if (endp->active) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else if (endp->queue_next == endp->queue_last) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else if (endp->pipetype == PIPE_INTERRUPT) { u8 address = u132->addr[endp->usb_addr].address; if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else { @@ -1405,7 +1405,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_single(u132, ring, endp, urb, address, endp->toggle_bits, u132_hcd_interrupt_recv); if (retval != 0) @@ -1415,7 +1415,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) } else if (endp->pipetype == PIPE_CONTROL) { u8 address = u132->addr[endp->usb_addr].address; if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else if (address == 0) { @@ -1425,7 +1425,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_setup(u132, ring, endp, urb, address, 0x2, u132_hcd_initial_setup_sent); if (retval != 0) @@ -1438,7 +1438,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_setup(u132, ring, endp, urb, 0, 0x2, u132_hcd_enumeration_address_sent); if (retval != 0) @@ -1452,7 +1452,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_setup(u132, ring, endp, urb, address, 0x2, u132_hcd_configure_setup_sent); if (retval != 0) @@ -1463,7 +1463,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) if (endp->input) { u8 address = u132->addr[endp->usb_addr].address; if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else { @@ -1473,7 +1473,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_input(u132, ring, endp, urb, address, endp->toggle_bits, u132_hcd_bulk_input_recv); @@ -1486,7 +1486,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) } else { /* output pipe */ u8 address = u132->addr[endp->usb_addr].address; if (ring->in_use) { - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); return; } else { @@ -1496,7 +1496,7 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) endp->active = 1; ring->curr_endp = endp; ring->in_use = 1; - up(&u132->scheduler_lock); + mutex_unlock(&u132->scheduler_lock); retval = edset_output(u132, ring, endp, urb, address, endp->toggle_bits, u132_hcd_bulk_output_sent); @@ -3085,7 +3085,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) u132->power = 0; u132->reset = 0; mutex_init(&u132->sw_lock); - init_MUTEX(&u132->scheduler_lock); + mutex_init(&u132->scheduler_lock); while (rings-- > 0) { struct u132_ring *ring = &u132->ring[rings]; ring->u132 = u132; -- cgit v1.2.2 From 44a29fd715a017183e83377b297ab3f792995467 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 23 Mar 2008 20:58:28 +0800 Subject: USB: fix comments of 2 functions in hcd.c Remove useless @type note for rh_string() and @r note for usb_hcd_irq() since this two parameters were removed. Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e52ed1663b3c..f936de75f44e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -291,7 +291,6 @@ static int ascii2utf (char *s, u8 *utf, int utfmax) * rh_string - provides manufacturer, product and serial strings for root hub * @id: the string ID number (1: serial number, 2: product, 3: vendor) * @hcd: the host controller for this root hub - * @type: string describing our driver * @data: return packet in UTF-16 LE * @len: length of the return packet * @@ -1677,7 +1676,6 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); * usb_hcd_irq - hook IRQs to HCD framework (bus glue) * @irq: the IRQ being raised * @__hcd: pointer to the HCD whose IRQ is being signaled - * @r: saved hardware registers * * If the controller isn't HALTed, calls the driver's irq handler. * Checks whether the controller is now dead. -- cgit v1.2.2 From 119fc8c9acde650fb92b44c34ea6fc84feb0f6dd Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 21 Mar 2008 22:55:45 +0100 Subject: USB: test for NULL return from platform_get_resource() in ohci_hcd_sm501_drv_remove() platform_get_resource() may return null, so although it seems it will never do so here unless there's a bug elsewhere, it does no harm to be defensive and test. Signed-off-by: Jesper Juhl Acked-by: David Brownell Acked-by: Magnus Damm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-sm501.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index ab1e366d7790..54b6ac2e3e4a 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -199,7 +199,8 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev) usb_put_hcd(hcd); dma_release_declared_memory(&pdev->dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - release_mem_region(mem->start, mem->end - mem->start + 1); + if (mem) + release_mem_region(mem->start, mem->end - mem->start + 1); /* mask interrupts and disable power */ -- cgit v1.2.2 From cc901bbb2e2a4e4f96da3d70dae332882c10054b Mon Sep 17 00:00:00 2001 From: "Craig W. Nadler" Date: Thu, 20 Mar 2008 14:46:26 -0700 Subject: USB: g_printer bugfixes G_PRINTER: Bug fix for blocking reads and a fix for a memory leak. This fixes bugs in blocking IO calls. When the poll() entry point is called receive transfers will be setup if they have not already been. Another bug fix is that the poll() entry point now checks the current receive buffer for data when reporting if any data had been received. A memory leak was fixed that could have occurred when a USB reset happened. Signed-off-by: Craig W. Nadler Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 86 +++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 2c32bd08ee7d..ecc1410073f4 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -390,9 +390,12 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) /* normal completion */ case 0: - list_add_tail(&req->list, &dev->rx_buffers); - wake_up_interruptible(&dev->rx_wait); - DBG(dev, "G_Printer : rx length %d\n", req->actual); + if (req->actual > 0) { + list_add_tail(&req->list, &dev->rx_buffers); + DBG(dev, "G_Printer : rx length %d\n", req->actual); + } else { + list_add(&req->list, &dev->rx_reqs); + } break; /* software-driven interface shutdown */ @@ -417,6 +420,8 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) list_add(&req->list, &dev->rx_reqs); break; } + + wake_up_interruptible(&dev->rx_wait); spin_unlock_irqrestore(&dev->lock, flags); } @@ -494,6 +499,39 @@ printer_close(struct inode *inode, struct file *fd) return 0; } +/* This function must be called with interrupts turned off. */ +static void +setup_rx_reqs(struct printer_dev *dev) +{ + struct usb_request *req; + + while (likely(!list_empty(&dev->rx_reqs))) { + int error; + + req = container_of(dev->rx_reqs.next, + struct usb_request, list); + list_del_init(&req->list); + + /* The USB Host sends us whatever amount of data it wants to + * so we always set the length field to the full USB_BUFSIZE. + * If the amount of data is more than the read() caller asked + * for it will be stored in the request buffer until it is + * asked for by read(). + */ + req->length = USB_BUFSIZE; + req->complete = rx_complete; + + error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + if (error) { + DBG(dev, "rx submit --> %d\n", error); + list_add(&req->list, &dev->rx_reqs); + break; + } else { + list_add(&req->list, &dev->rx_reqs_active); + } + } +} + static ssize_t printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) { @@ -522,31 +560,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) */ dev->reset_printer = 0; - while (likely(!list_empty(&dev->rx_reqs))) { - int error; - - req = container_of(dev->rx_reqs.next, - struct usb_request, list); - list_del_init(&req->list); - - /* The USB Host sends us whatever amount of data it wants to - * so we always set the length field to the full USB_BUFSIZE. - * If the amount of data is more than the read() caller asked - * for it will be stored in the request buffer until it is - * asked for by read(). - */ - req->length = USB_BUFSIZE; - req->complete = rx_complete; - - error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); - if (error) { - DBG(dev, "rx submit --> %d\n", error); - list_add(&req->list, &dev->rx_reqs); - break; - } else { - list_add(&req->list, &dev->rx_reqs_active); - } - } + setup_rx_reqs(dev); bytes_copied = 0; current_rx_req = dev->current_rx_req; @@ -615,9 +629,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) spin_lock_irqsave(&dev->lock, flags); - /* We've disconnected or reset free the req and buffer */ + /* We've disconnected or reset so return. */ if (dev->reset_printer) { - printer_req_free(dev->out_ep, current_rx_req); + list_add(¤t_rx_req->list, &dev->rx_reqs); spin_unlock_irqrestore(&dev->lock, flags); spin_unlock(&dev->lock_printer_io); return -EAGAIN; @@ -735,7 +749,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* We've disconnected or reset so free the req and buffer */ if (dev->reset_printer) { - printer_req_free(dev->in_ep, req); + list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); spin_unlock(&dev->lock_printer_io); return -EAGAIN; @@ -791,6 +805,12 @@ printer_poll(struct file *fd, poll_table *wait) unsigned long flags; int status = 0; + spin_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + setup_rx_reqs(dev); + spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock(&dev->lock_printer_io); + poll_wait(fd, &dev->rx_wait, wait); poll_wait(fd, &dev->tx_wait, wait); @@ -798,7 +818,8 @@ printer_poll(struct file *fd, poll_table *wait) if (likely(!list_empty(&dev->tx_reqs))) status |= POLLOUT | POLLWRNORM; - if (likely(!list_empty(&dev->rx_buffers))) + if (likely(dev->current_rx_bytes) || + likely(!list_empty(&dev->rx_buffers))) status |= POLLIN | POLLRDNORM; spin_unlock_irqrestore(&dev->lock, flags); @@ -1084,6 +1105,7 @@ static void printer_soft_reset(struct printer_dev *dev) if (usb_ep_enable(dev->out_ep, dev->out)) DBG(dev, "Failed to enable USB out_ep\n"); + wake_up_interruptible(&dev->rx_wait); wake_up_interruptible(&dev->tx_wait); wake_up_interruptible(&dev->tx_flush_wait); } -- cgit v1.2.2 From 148d9fe4c91a6356dae1b05b76b8133586c26be4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 27 Mar 2008 14:52:57 -0400 Subject: USB: usb-storage: use adaptive DMA mask This patch (as1060) makes usb-storage set the DMA alignment mask for SCSI slaves to match the maxpacket size of the bulk-IN endpoint, rather than always setting it to 511. For full-speed devices that mask is too restrictive, and wireless USB devices can have maxpacket sizes larger than 512. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/scsiglue.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 5405ba8cd9d2..521f0297aef9 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -73,6 +73,7 @@ static const char* host_info(struct Scsi_Host *host) static int slave_alloc (struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); + struct usb_host_endpoint *bulk_in_ep; /* * Set the INQUIRY transfer length to 36. We don't use any of @@ -84,12 +85,13 @@ static int slave_alloc (struct scsi_device *sdev) /* Scatter-gather buffers (all but the last) must have a length * divisible by the bulk maxpacket size. Otherwise a data packet * would end up being short, causing a premature end to the data - * transfer. Since high-speed bulk pipes have a maxpacket size - * of 512, we'll use that as the scsi device queue's DMA alignment - * mask. Guaranteeing proper alignment of the first buffer will - * have the desired effect because, except at the beginning and - * the end, scatter-gather buffers follow page boundaries. */ - blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); + * transfer. We'll use the maxpacket value of the bulk-IN pipe + * to set the SCSI device queue's DMA alignment mask. + */ + bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)]; + blk_queue_update_dma_alignment(sdev->request_queue, + le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1); + /* wMaxPacketSize must be a power of 2 */ /* * The UFI spec treates the Peripheral Qualifier bits in an -- cgit v1.2.2 From 73d79aaba9ee21aaa1a6676f568ef7b3bdf993ea Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 28 Mar 2008 14:50:27 -0700 Subject: USB: mem leak fixes for AMD 5536 UDC high/full speed USB device controller driver In drivers/usb/gadget/amd5536udc.c::udc_pci_probe(), sizeof(struct udc) storage is allocated for 'dev'. There are many exit points from the function where 'dev' is not free'd but has also not yet been used for anything. The following patch free's 'dev' at the return points where it has not yet been used. Signed-off-by: Jesper Juhl Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/amd5536udc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index b663f23f2642..fc6f3483be44 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3248,6 +3248,8 @@ static int udc_pci_probe( /* pci setup */ if (pci_enable_device(pdev) < 0) { + kfree(dev); + dev = 0; retval = -ENODEV; goto finished; } @@ -3259,6 +3261,8 @@ static int udc_pci_probe( if (!request_mem_region(resource, len, name)) { dev_dbg(&pdev->dev, "pci device used already\n"); + kfree(dev); + dev = 0; retval = -EBUSY; goto finished; } @@ -3267,18 +3271,24 @@ static int udc_pci_probe( dev->virt_addr = ioremap_nocache(resource, len); if (dev->virt_addr == NULL) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); + kfree(dev); + dev = 0; retval = -EFAULT; goto finished; } if (!pdev->irq) { dev_err(&dev->pdev->dev, "irq not set\n"); + kfree(dev); + dev = 0; retval = -ENODEV; goto finished; } if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); + kfree(dev); + dev = 0; retval = -EBUSY; goto finished; } -- cgit v1.2.2 From 9063ff44f081a0297085952f6760dfe1f8ca840e Mon Sep 17 00:00:00 2001 From: Ingo van Lil Date: Fri, 28 Mar 2008 14:50:26 -0700 Subject: USB: gadget: dummy_hcd.c: fix nested switch statements Fix a messed up combination of two nested switch statements in drivers/usb/gadget/dummy_hcd.c. According to the USB spec (section 5.8.3) the maximum packet size for bulk endpoints can be 512 for high-speed devices and 8, 16, 32 or 64 for full-speed devices. Low-speed devices must not have bulk endpoints. Signed-off-by: Ingo van Lil Cc: David Brownell Signed-off-by: Andrew Morton Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/dummy_hcd.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index e454775c2ff2..433f8c47cce5 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -365,16 +365,14 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) case USB_SPEED_HIGH: if (max == 512) break; - /* conserve return statements */ - default: - switch (max) { - case 8: case 16: case 32: case 64: + goto done; + case USB_SPEED_FULL: + if (max == 8 || max == 16 || max == 32 || max == 64) /* we'll fake any legal size */ break; - default: - case USB_SPEED_LOW: - goto done; - } + /* save a return statement */ + default: + goto done; } break; case USB_ENDPOINT_XFER_INT: -- cgit v1.2.2 From 0d22f65515307c878ddd20b1305cce925ca9516c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Apr 2008 11:35:26 -0400 Subject: USB: OHCI: fix bug in controller resume This patch (as1063) fixes a bug in the way ohci-hcd resumes its controllers. It leaves the Master Interrupt Enable bit turned off. If the root hub is resumed immediately this won't matter. But if the root hub is suspended (say because no devices are plugged in), it won't ever wake up by itself. Signed-off-by: Alan Stern CC: David Brownell Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index d0360f65ebd9..b0e2275755c8 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -312,11 +312,13 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) static int ohci_pci_resume (struct usb_hcd *hcd) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* FIXME: we should try to detect loss of VBUS power here */ prepare_for_handover(hcd); - + ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); return 0; } -- cgit v1.2.2 From 6fc88f53aaa4ff8ee621353ac27269b4a656d721 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 3 Apr 2008 21:40:59 +0200 Subject: USB: convert away from urb->status in xpad driver USB is moving to transfering status as a parameter. To ease the transition urb->status is to be touched only once in a function. The xpad driver has been overlooked. Dmitry wants this to go through the USB tree. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 0380597249bb..2854c8fc334b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -339,9 +339,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad, static void xpad_irq_in(struct urb *urb) { struct usb_xpad *xpad = urb->context; - int retval; + int retval, status; - switch (urb->status) { + status = urb->status; + + switch (status) { case 0: /* success */ break; @@ -350,11 +352,11 @@ static void xpad_irq_in(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); + __FUNCTION__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); + __FUNCTION__, status); goto exit; } @@ -373,9 +375,11 @@ exit: #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) static void xpad_irq_out(struct urb *urb) { - int retval; + int retval, status; + + status = urb->status; - switch (urb->status) { + switch (status) { case 0: /* success */ break; @@ -384,11 +388,11 @@ static void xpad_irq_out(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); + __FUNCTION__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); + __FUNCTION__, status); goto exit; } -- cgit v1.2.2 From 7329e211b987a493cbcfca0e98c60eb108ab42df Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Apr 2008 18:02:56 -0400 Subject: USB: root hubs don't lie about their number of TTs Currently EHCI root hubs enumerate with a bDeviceProtocol code indicating that they possess a Transaction Translator. However the vast majority of controllers do not; they rely on a companion controller to handle full- and low-speed communications. This patch (as1064) changes the root-hub device descriptor to match the actual situation. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 14 ++++++++++++-- drivers/usb/core/hcd.h | 1 + drivers/usb/host/ehci-pci.c | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index f936de75f44e..e68fef5361d2 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -129,7 +129,7 @@ static const u8 usb2_rh_dev_descriptor [18] = { 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 0x00, /* __u8 bDeviceSubClass; */ - 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ + 0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */ 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ @@ -354,9 +354,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) __attribute__((aligned(4))); const u8 *bufp = tbuf; int len = 0; - int patch_wakeup = 0; int status; int n; + u8 patch_wakeup = 0; + u8 patch_protocol = 0; might_sleep(); @@ -433,6 +434,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) else goto error; len = 18; + if (hcd->has_tt) + patch_protocol = 1; break; case USB_DT_CONFIG << 8: if (hcd->driver->flags & HCD_USB2) { @@ -527,6 +530,13 @@ error: bmAttributes)) ((struct usb_config_descriptor *)ubuf)->bmAttributes |= USB_CONFIG_ATT_WAKEUP; + + /* report whether RH hardware has an integrated TT */ + if (patch_protocol && + len > offsetof(struct usb_device_descriptor, + bDeviceProtocol)) + ((struct usb_device_descriptor *) ubuf)-> + bDeviceProtocol = 1; } /* any errors get returned through the urb completion */ diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 2c086b8460b1..e0e99471c3fc 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -99,6 +99,7 @@ struct usb_hcd { unsigned poll_pending:1; /* status has changed? */ unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; + unsigned has_tt:1; /* Integrated TT in root hub */ int irq; /* irq allocated */ void __iomem *regs; /* device memory/io */ diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 040bd8632eb3..7c8a2ccf78f1 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -130,6 +130,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { ehci->is_tdi_rh_tt = 1; + hcd->has_tt = 1; tdi_reset(ehci); } break; -- cgit v1.2.2 From 7be7d7418776a41badce7ca00246e270d408e4b9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Apr 2008 18:03:06 -0400 Subject: USB: clarify usage of hcd->suspend/resume methods The .suspend and .resume method pointers in struct usb_hcd have not been fully understood by host-controller driver writers. They are meant for use with PCI controllers; other platform-specific drivers generally should not refer to them. To try and clarify matters, this patch (as1065) renames those methods to .pci_suspend and .pci_resume. It eliminates corresponding dead code and bogus references in the ohci-ssb and u132-hcd drivers. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 10 +++++----- drivers/usb/core/hcd.h | 4 ++-- drivers/usb/host/ehci-pci.c | 4 ++-- drivers/usb/host/ohci-pci.c | 5 ++--- drivers/usb/host/ohci-ssb.c | 35 ----------------------------------- drivers/usb/host/u132-hcd.c | 32 -------------------------------- drivers/usb/host/uhci-hcd.c | 8 ++++---- 7 files changed, 15 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 739407bb8492..5b87ae7f0a6a 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -215,9 +215,9 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) hcd->state == HC_STATE_HALT)) return -EBUSY; - if (hcd->driver->suspend) { - retval = hcd->driver->suspend(hcd, message); - suspend_report_result(hcd->driver->suspend, retval); + if (hcd->driver->pci_suspend) { + retval = hcd->driver->pci_suspend(hcd, message); + suspend_report_result(hcd->driver->pci_suspend, retval); if (retval) goto done; } @@ -405,8 +405,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev) clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - if (hcd->driver->resume) { - retval = hcd->driver->resume(hcd); + if (hcd->driver->pci_resume) { + retval = hcd->driver->pci_resume(hcd); if (retval) { dev_err(hcd->self.controller, "PCI post-resume error %d!\n", retval); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index e0e99471c3fc..3ba258eb05de 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -178,10 +178,10 @@ struct hc_driver { * a whole, not just the root hub; they're for PCI bus glue. */ /* called after suspending the hub, before entering D3 etc */ - int (*suspend) (struct usb_hcd *hcd, pm_message_t message); + int (*pci_suspend) (struct usb_hcd *hcd, pm_message_t message); /* called after entering D0 (etc), before resuming the hub */ - int (*resume) (struct usb_hcd *hcd); + int (*pci_resume) (struct usb_hcd *hcd); /* cleanly make HCD stop writing memory and doing I/O */ void (*stop) (struct usb_hcd *hcd); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7c8a2ccf78f1..a0afc78b273e 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -353,8 +353,8 @@ static const struct hc_driver ehci_pci_hc_driver = { .reset = ehci_pci_setup, .start = ehci_run, #ifdef CONFIG_PM - .suspend = ehci_pci_suspend, - .resume = ehci_pci_resume, + .pci_suspend = ehci_pci_suspend, + .pci_resume = ehci_pci_resume, #endif .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index b0e2275755c8..40b62a35fd3c 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -347,9 +347,8 @@ static const struct hc_driver ohci_pci_hc_driver = { .shutdown = ohci_shutdown, #ifdef CONFIG_PM - /* these suspend/resume entries are for upstream PCI glue ONLY */ - .suspend = ohci_pci_suspend, - .resume = ohci_pci_resume, + .pci_suspend = ohci_pci_suspend, + .pci_resume = ohci_pci_resume, #endif /* diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index 6e9c2d6db887..7879f2fdad84 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c @@ -60,36 +60,6 @@ static int ssb_ohci_start(struct usb_hcd *hcd) return err; } -#ifdef CONFIG_PM -static int ssb_ohci_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) -{ - struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); - struct ohci_hcd *ohci = &ohcidev->ohci; - unsigned long flags; - - spin_lock_irqsave(&ohci->lock, flags); - - ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); - ohci_readl(ohci, &ohci->regs->intrdisable); /* commit write */ - - /* make sure snapshot being resumed re-enumerates everything */ - if (message.event == PM_EVENT_PRETHAW) - ohci_usb_reset(ohci); - - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - spin_unlock_irqrestore(&ohci->lock, flags); - return 0; -} - -static int ssb_ohci_hcd_resume(struct usb_hcd *hcd) -{ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - usb_hcd_resume_root_hub(hcd); - return 0; -} -#endif /* CONFIG_PM */ - static const struct hc_driver ssb_ohci_hc_driver = { .description = "ssb-usb-ohci", .product_desc = "SSB OHCI Controller", @@ -103,11 +73,6 @@ static const struct hc_driver ssb_ohci_hc_driver = { .stop = ohci_stop, .shutdown = ohci_shutdown, -#ifdef CONFIG_PM - .suspend = ssb_ohci_hcd_suspend, - .resume = ssb_ohci_hcd_resume, -#endif - .urb_enqueue = ohci_urb_enqueue, .urb_dequeue = ohci_urb_dequeue, .endpoint_disable = ohci_endpoint_disable, diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 4616a880d89c..9b6323f768b2 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2946,34 +2946,6 @@ static void u132_hub_irq_enable(struct usb_hcd *hcd) #ifdef CONFIG_PM -static int u132_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) -{ - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; -} - -static int u132_hcd_resume(struct usb_hcd *hcd) -{ - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - return -ENODEV; - } else if (u132->going > 0) { - dev_err(&u132->platform_dev->dev, "device is being removed\n"); - return -ESHUTDOWN; - } else - return 0; -} - static int u132_bus_suspend(struct usb_hcd *hcd) { struct u132 *u132 = hcd_to_u132(hcd); @@ -3003,8 +2975,6 @@ static int u132_bus_resume(struct usb_hcd *hcd) } #else -#define u132_hcd_suspend NULL -#define u132_hcd_resume NULL #define u132_bus_suspend NULL #define u132_bus_resume NULL #endif @@ -3015,8 +2985,6 @@ static struct hc_driver u132_hc_driver = { .flags = HCD_USB11 | HCD_MEMORY, .reset = u132_hcd_reset, .start = u132_hcd_start, - .suspend = u132_hcd_suspend, - .resume = u132_hcd_resume, .stop = u132_hcd_stop, .urb_enqueue = u132_urb_enqueue, .urb_dequeue = u132_urb_dequeue, diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index ec987897b8ed..fec9872dd9dc 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -737,7 +737,7 @@ static int uhci_rh_resume(struct usb_hcd *hcd) return rc; } -static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) +static int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); int rc = 0; @@ -774,7 +774,7 @@ done: return rc; } -static int uhci_resume(struct usb_hcd *hcd) +static int uhci_pci_resume(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); @@ -872,8 +872,8 @@ static const struct hc_driver uhci_driver = { .reset = uhci_init, .start = uhci_start, #ifdef CONFIG_PM - .suspend = uhci_suspend, - .resume = uhci_resume, + .pci_suspend = uhci_pci_suspend, + .pci_resume = uhci_pci_resume, .bus_suspend = uhci_rh_suspend, .bus_resume = uhci_rh_resume, #endif -- cgit v1.2.2 From 43bbb7e015c4380064796c5868b536437b165615 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Apr 2008 18:03:17 -0400 Subject: USB: OHCI: host-controller resumes leave root hub suspended Drivers in the ohci-hcd family should perform certain tasks whenever their controller device is resumed. These include checking for loss of power during suspend, turning on port power, and enabling interrupt requests. Until now these jobs have been carried out when the root hub is resumed, not when the controller is. Many drivers work around the resulting awkwardness by automatically resuming their root hub whenever the controller is resumed. But this is wasteful and unnecessary. To simplify the situation, this patch (as1066) adds a new core routine, ohci_finish_controller_resume(), which can be used by all the OHCI-variant drivers. They can call the new routine instead of resuming their root hubs. And ohci-pci.c can call it instead of using its own special-purpose handler. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 1 + drivers/usb/host/ohci-ep93xx.c | 2 +- drivers/usb/host/ohci-hub.c | 43 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci-omap.c | 5 +++-- drivers/usb/host/ohci-pci.c | 43 +----------------------------------------- drivers/usb/host/ohci-pxa27x.c | 3 +-- drivers/usb/host/ohci-sm501.c | 5 +++-- drivers/usb/host/ohci-ssb.c | 1 + 8 files changed, 54 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index d72dc07dda01..e534f9de0f05 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -348,6 +348,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) if (!clocked) at91_start_clock(); + ohci_finish_controller_resume(hcd); return 0; } #else diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 40c683f8987d..5adaf36e47d0 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -192,8 +192,8 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ohci->next_statechange = jiffies; ep93xx_start_hc(&pdev->dev); - usb_hcd_resume_root_hub(hcd); + ohci_finish_controller_resume(hcd); return 0; } #endif diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index c638e6b33c43..28d6d775eb5f 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -326,6 +326,49 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } +/* Carry out the final steps of resuming the controller device */ +static void ohci_finish_controller_resume(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + bool need_reinit = false; + + /* See if the controller is already running or has been reset */ + ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); + if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(&ohci->lock); + hcd->state = HC_STATE_RESUMING; + ohci_rh_resume(ohci); + hcd->state = HC_STATE_QUIESCING; + ohci_rh_suspend(ohci, 0); + hcd->state = HC_STATE_SUSPENDED; + spin_unlock_irq(&ohci->lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, "powerup ports\n"); + for (port = 0; port < ohci->num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + &ohci->regs->roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); + ohci_readl(ohci, &ohci->regs->intrenable); + msleep(20); + } +} + /* Carry out polling-, autostop-, and autoresume-related state changes */ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 2aafa7b6c81f..3a7c24c03671 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -510,14 +510,15 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) static int ohci_omap_resume(struct platform_device *dev) { - struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(1); - usb_hcd_resume_root_hub(platform_get_drvdata(dev)); + ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 40b62a35fd3c..4696cc912e16 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) return ret; } -#if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \ - defined(CONFIG_USB_EHCI_HCD_MODULE)) - -/* Following a power loss, we must prepare to regain control of the ports - * we used to own. This means turning on the port power before ehci-hcd - * tries to switch ownership. - * - * This isn't a 100% perfect solution. On most systems the OHCI controllers - * lie at lower PCI addresses than the EHCI controller, so they will be - * discovered (and hence resumed) first. But there is no guarantee things - * will always work this way. If the EHCI controller is resumed first and - * the OHCI ports are unpowered, then the handover will fail. - */ -static void prepare_for_handover(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int port; - - /* Here we "know" root ports should always stay powered */ - ohci_dbg(ohci, "powerup ports\n"); - for (port = 0; port < ohci->num_ports; port++) - ohci_writel(ohci, RH_PS_PPS, - &ohci->regs->roothub.portstatus[port]); - - /* Flush those writes */ - ohci_readl(ohci, &ohci->regs->control); - msleep(20); -} - -#else - -static inline void prepare_for_handover(struct usb_hcd *hcd) -{ } - -#endif /* CONFIG_USB_PERSIST etc. */ - #ifdef CONFIG_PM static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) @@ -312,13 +276,8 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) static int ohci_pci_resume (struct usb_hcd *hcd) { - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - /* FIXME: we should try to detect loss of VBUS power here */ - prepare_for_handover(hcd); - ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); + ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5d470263eed8..d4ee27d92be8 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -356,8 +356,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) if ((status = pxa27x_start_hc(&pdev->dev)) < 0) return status; - usb_hcd_resume_root_hub(hcd); - + ohci_finish_controller_resume(hcd); return 0; } #endif diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 54b6ac2e3e4a..4a11e1816017 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -231,14 +231,15 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg) static int ohci_sm501_resume(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev)); + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); - usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); + ohci_finish_controller_resume(hcd); return 0; } #else diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index 7879f2fdad84..7275186db315 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c @@ -189,6 +189,7 @@ static int ssb_ohci_resume(struct ssb_device *dev) ssb_device_enable(dev, ohcidev->enable_flags); + ohci_finish_controller_resume(hcd); return 0; } -- cgit v1.2.2 From 96e12fced365262e185a8e935db23973337b8a2a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Apr 2008 14:28:01 -0700 Subject: usb: replace remaining __PRETTY_FUNCTION__ occurrences The kernel is written in C, not C++, use __func__ Signed-off-by: Harvey Harrison Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/microtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 0badbbe2fd24..885867a86de8 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -185,7 +185,7 @@ static struct usb_driver mts_usb_driver = { printk( KERN_DEBUG MTS_NAME x ) #define MTS_DEBUG_GOT_HERE() \ - MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __PRETTY_FUNCTION__ ) + MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __func__ ) #define MTS_DEBUG_INT() \ do { MTS_DEBUG_GOT_HERE(); \ MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ -- cgit v1.2.2 From 61a5c657892a43653d6189972159590751a0673e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Apr 2008 23:46:59 -0400 Subject: USB: rework sysfs removal of interface files Removing an interface's sysfs files before unregistering the interface doesn't work properly, because usb_unbind_interface() will reinstall altsetting 0 and thereby create new sysfs files. This patch (as1074) removes the files after the unregistration is finished. It's not quite as clean, but at least it works. Also, there's no need to check if an interface has been registered before removing its sysfs files. If it hasn't been registered then the files won't have been created, so usb_remove_sysfs_intf_files() will simply do nothing. Signed-off-by: Alan Stern Tested-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a3695b5115ff..5b23f6b017d7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1089,8 +1089,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) continue; dev_dbg(&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); - usb_remove_sysfs_intf_files(interface); device_del(&interface->dev); + usb_remove_sysfs_intf_files(interface); } /* Now that the interfaces are unbound, nobody should @@ -1231,7 +1231,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) */ /* prevent submissions using previous endpoint settings */ - if (iface->cur_altsetting != alt && device_is_registered(&iface->dev)) + if (iface->cur_altsetting != alt) usb_remove_sysfs_intf_files(iface); usb_disable_interface(dev, iface); @@ -1330,8 +1330,7 @@ int usb_reset_configuration(struct usb_device *dev) struct usb_interface *intf = config->interface[i]; struct usb_host_interface *alt; - if (device_is_registered(&intf->dev)) - usb_remove_sysfs_intf_files(intf); + usb_remove_sysfs_intf_files(intf); alt = usb_altnum_to_altsetting(intf, 0); /* No altsetting 0? We'll assume the first altsetting. -- cgit v1.2.2 From 0e530b45783f75a29bde20bbf9e287c915a4f68b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 5 Apr 2008 14:17:14 -0700 Subject: USB: gadget section fixes Restore some section annotations: they were switched to "__devinit" while they should have been "__init", because of bogus warnings. The warnings are now fixed, so the runtime footprint of various drivers can now shrink a bit. On ARMv5, it's about 600 bytes except for the Ethernet gadget, where it can save a bit more. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/epautoconf.c | 12 ++++++------ drivers/usb/gadget/ether.c | 6 +++--- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/rndis.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index f9d07108bc30..8bdad221fa91 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -34,12 +34,12 @@ /* we must assign addresses for configurable endpoints (like net2280) */ -static __devinitdata unsigned epnum; +static __initdata unsigned epnum; // #define MANY_ENDPOINTS #ifdef MANY_ENDPOINTS /* more than 15 configurable endpoints */ -static __devinitdata unsigned in_epnum; +static __initdata unsigned in_epnum; #endif @@ -59,7 +59,7 @@ static __devinitdata unsigned in_epnum; * NOTE: each endpoint is unidirectional, as specified by its USB * descriptor; and isn't specific to a configuration or altsetting. */ -static int __devinit +static int __init ep_matches ( struct usb_gadget *gadget, struct usb_ep *ep, @@ -186,7 +186,7 @@ ep_matches ( return 1; } -static struct usb_ep * __devinit +static struct usb_ep * __init find_ep (struct usb_gadget *gadget, const char *name) { struct usb_ep *ep; @@ -228,7 +228,7 @@ find_ep (struct usb_gadget *gadget, const char *name) * * On failure, this returns a null endpoint descriptor. */ -struct usb_ep * __devinit usb_ep_autoconfig ( +struct usb_ep * __init usb_ep_autoconfig ( struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc ) @@ -295,7 +295,7 @@ struct usb_ep * __devinit usb_ep_autoconfig ( * state such as ep->driver_data and the record of assigned endpoints * used by usb_ep_autoconfig(). */ -void __devinit usb_ep_autoconfig_reset (struct usb_gadget *gadget) +void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget) { struct usb_ep *ep; diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index e99872308144..92b9bf78071f 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2229,7 +2229,7 @@ eth_unbind (struct usb_gadget *gadget) set_gadget_data (gadget, NULL); } -static u8 __devinit nibble (unsigned char c) +static u8 __init nibble (unsigned char c) { if (likely (isdigit (c))) return c - '0'; @@ -2239,7 +2239,7 @@ static u8 __devinit nibble (unsigned char c) return 0; } -static int __devinit get_ether_addr(const char *str, u8 *dev_addr) +static int __init get_ether_addr(const char *str, u8 *dev_addr) { if (str) { unsigned i; @@ -2260,7 +2260,7 @@ static int __devinit get_ether_addr(const char *str, u8 *dev_addr) return 1; } -static int __devinit +static int __init eth_bind (struct usb_gadget *gadget) { struct eth_dev *dev; diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 5b42ccd0035f..ff3a8513e64d 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -1149,7 +1149,7 @@ fail: /* * Creates an output endpoint, and initializes output ports. */ -static int __devinit gmidi_bind(struct usb_gadget *gadget) +static int __init gmidi_bind(struct usb_gadget *gadget) { struct gmidi_device *dev; struct usb_ep *in_ep, *out_ep; diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 3d036647431f..934911ee5c72 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1403,7 +1403,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -int __devinit rndis_init (void) +int __init rndis_init (void) { u8 i; -- cgit v1.2.2 From a89a2cd396b20c46a37fa8db4b652fb00f29d0a4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 7 Apr 2008 15:03:25 -0400 Subject: USB: dummy-hcd: use dynamic allocation for platform_devices This patch (as1075) changes dummy-hcd to dynamically allocate its platform_device structures, using the core platform_device_alloc() interface. This is what it should have done all along, because the dynamically-allocated structures have a release method in the driver core and are therefore immune to being released after the module has been unloaded. Thanks to Richard Purdie for pointing out the need for this change. Signed-off-by: Alan Stern Cc: Richard Purdie Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/dummy_hcd.c | 70 +++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 433f8c47cce5..74f51a703b42 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1933,69 +1933,57 @@ static struct platform_driver dummy_hcd_driver = { /*-------------------------------------------------------------------------*/ -/* These don't need to do anything because the pdev structures are - * statically allocated. */ -static void -dummy_udc_release (struct device *dev) {} - -static void -dummy_hcd_release (struct device *dev) {} - -static struct platform_device the_udc_pdev = { - .name = (char *) gadget_name, - .id = -1, - .dev = { - .release = dummy_udc_release, - }, -}; - -static struct platform_device the_hcd_pdev = { - .name = (char *) driver_name, - .id = -1, - .dev = { - .release = dummy_hcd_release, - }, -}; +static struct platform_device *the_udc_pdev; +static struct platform_device *the_hcd_pdev; static int __init init (void) { - int retval; + int retval = -ENOMEM; if (usb_disabled ()) return -ENODEV; - retval = platform_driver_register (&dummy_hcd_driver); - if (retval < 0) + the_hcd_pdev = platform_device_alloc(driver_name, -1); + if (!the_hcd_pdev) return retval; + the_udc_pdev = platform_device_alloc(gadget_name, -1); + if (!the_udc_pdev) + goto err_alloc_udc; - retval = platform_driver_register (&dummy_udc_driver); + retval = platform_driver_register(&dummy_hcd_driver); + if (retval < 0) + goto err_register_hcd_driver; + retval = platform_driver_register(&dummy_udc_driver); if (retval < 0) goto err_register_udc_driver; - retval = platform_device_register (&the_hcd_pdev); + retval = platform_device_add(the_hcd_pdev); if (retval < 0) - goto err_register_hcd; - - retval = platform_device_register (&the_udc_pdev); + goto err_add_hcd; + retval = platform_device_add(the_udc_pdev); if (retval < 0) - goto err_register_udc; + goto err_add_udc; return retval; -err_register_udc: - platform_device_unregister (&the_hcd_pdev); -err_register_hcd: - platform_driver_unregister (&dummy_udc_driver); +err_add_udc: + platform_device_del(the_hcd_pdev); +err_add_hcd: + platform_driver_unregister(&dummy_udc_driver); err_register_udc_driver: - platform_driver_unregister (&dummy_hcd_driver); + platform_driver_unregister(&dummy_hcd_driver); +err_register_hcd_driver: + platform_device_put(the_udc_pdev); +err_alloc_udc: + platform_device_put(the_hcd_pdev); return retval; } module_init (init); static void __exit cleanup (void) { - platform_device_unregister (&the_udc_pdev); - platform_device_unregister (&the_hcd_pdev); - platform_driver_unregister (&dummy_udc_driver); - platform_driver_unregister (&dummy_hcd_driver); + platform_device_unregister(the_udc_pdev); + platform_device_unregister(the_hcd_pdev); + platform_driver_unregister(&dummy_udc_driver); + platform_driver_unregister(&dummy_hcd_driver); } module_exit (cleanup); -- cgit v1.2.2 From 3cf2723432dd27402a4a4941ad2d04eae5dd639c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 6 Apr 2008 23:32:55 -0700 Subject: USB: at91_udc can prefetch data The at91sam9 chip are ARMv5 so they support preload instructions. Use preloading to load the FIFO a bit faster. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/at91_udc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index fd15ced899d8..5d352c900d2c 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -389,6 +389,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req) u32 csr = __raw_readl(creg); u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0)); unsigned total, count, is_last; + u8 *buf; /* * TODO: allow for writing two packets to the fifo ... that'll @@ -413,6 +414,8 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req) return 0; } + buf = req->req.buf + req->req.actual; + prefetch(buf); total = req->req.length - req->req.actual; if (ep->ep.maxpacket < total) { count = ep->ep.maxpacket; @@ -435,7 +438,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req) * recover when the actual bytecount matters (e.g. for USB Test * and Measurement Class devices). */ - __raw_writesb(dreg, req->req.buf + req->req.actual, count); + __raw_writesb(dreg, buf, count); csr &= ~SET_FX; csr |= CLR_FX | AT91_UDP_TXPKTRDY; __raw_writel(csr, creg); -- cgit v1.2.2 From 21da84a89312dd8d014ca3352d1ab5c2279ec548 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 8 Apr 2008 14:30:18 -0700 Subject: USB: ehci shutdown refactored This patch refactors some shutdown code so it can be shared between ehci_stop() and ehci_shutdown(). This also fixes a couple potential bugs: - ehci_shutdown() was not locking ehci->lock before halting the HC. - ehci_shutdown() didn't disable the watchdog and IAA timers. - ehci_stop() was resetting the host controller when it may have been running, which the EHCI spec says "may result in undefined behavior". ehci_stop() was calling port_power() to turn off the ports, which waited 20ms after applying the port change. The msleep was for the case where the HC might take 20ms to turn the ports on; since we're shutting them off, we can avoid the msleep and just use ehci_turn_off_ports(). ehci_stop() doesn't need to clear the intr_enable register or revert ownership of the companion controllers to the BIOS, because the host controller reset should have done that. There might be a buggy host controller that doesn't follow the reset rules, but for now we assume it's redundant code and remove it. [ A subsequent patch will cancel the timers later ... this version carries forward existing bugs where timers could get re-armed after they're canceled. ] Signed-off-by: Sarah Sharp Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a02dcff5eb21..369a8a5ea7bb 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -331,17 +331,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) &ehci->regs->port_status[port]); } -/* ehci_shutdown kick in for silicon on any bus (not just pci, etc). - * This forcibly disables dma and IRQs, helping kexec and other cases - * where the next system software may expect clean state. +/* + * Halt HC, turn off all ports, and let the BIOS use the companion controllers. + * Should be called with ehci->lock held. */ -static void -ehci_shutdown (struct usb_hcd *hcd) +static void ehci_silence_controller(struct ehci_hcd *ehci) { - struct ehci_hcd *ehci; - - ehci = hcd_to_ehci (hcd); - (void) ehci_halt (ehci); + ehci_halt(ehci); ehci_turn_off_all_ports(ehci); /* make BIOS/etc use companion controller during reboot */ @@ -351,6 +347,22 @@ ehci_shutdown (struct usb_hcd *hcd) ehci_readl(ehci, &ehci->regs->configured_flag); } +/* ehci_shutdown kick in for silicon on any bus (not just pci, etc). + * This forcibly disables dma and IRQs, helping kexec and other cases + * where the next system software may expect clean state. + */ +static void ehci_shutdown(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + del_timer_sync(&ehci->watchdog); + del_timer_sync(&ehci->iaa_watchdog); + + spin_lock_irq(&ehci->lock); + ehci_silence_controller(ehci); + spin_unlock_irq(&ehci->lock); +} + static void ehci_port_power (struct ehci_hcd *ehci, int is_on) { unsigned port; @@ -401,15 +413,15 @@ static void ehci_work (struct ehci_hcd *ehci) timer_action (ehci, TIMER_IO_WATCHDOG); } +/* + * Called when the ehci_hcd module is removed. + */ static void ehci_stop (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); ehci_dbg (ehci, "stop\n"); - /* Turn off port power on all root hub ports. */ - ehci_port_power (ehci, 0); - /* no more interrupts ... */ del_timer_sync (&ehci->watchdog); del_timer_sync(&ehci->iaa_watchdog); @@ -418,13 +430,10 @@ static void ehci_stop (struct usb_hcd *hcd) if (HC_IS_RUNNING (hcd->state)) ehci_quiesce (ehci); + ehci_silence_controller(ehci); ehci_reset (ehci); - ehci_writel(ehci, 0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); - /* let companion controllers work when we aren't */ - ehci_writel(ehci, 0, &ehci->regs->configured_flag); - remove_companion_file(ehci); remove_debug_files (ehci); -- cgit v1.2.2 From 97af0a911bfb1e798c395c6ebabb4731f821736f Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Thu, 10 Apr 2008 14:20:08 +0300 Subject: USB: oti6858: fix TCFLSH ioctl handling Removes unimplemented TCFLSH handling from oti6858, because it was preventing TCFLSH handling by upper layer (line discipline) drivers (see drivers/char/tty_io.c line 3450). Signed-off-by: Paulius Zaleckas Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/oti6858.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index a3847d6c946e..8acc907a3181 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -814,10 +814,6 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, __FUNCTION__, port->number, cmd, arg); switch (cmd) { - case TCFLSH: - /* FIXME */ - return 0; - case TIOCMBIS: if (copy_from_user(&x, user_arg, sizeof(x))) return -EFAULT; -- cgit v1.2.2 From 6d8791076c7742c65dd796ae0ac260ab22e85517 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 10 Apr 2008 21:05:47 +0900 Subject: USB: r8a66597-hcd: fix interrupt transfer interval This driver ignored the value of bInterval and revised the problem that performed interrupt transfer. ASIX USB Ethernet adapter comes to work with this host controller by applying this patch. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 77 +++++++++++++++++++++++++++++++++++------ drivers/usb/host/r8a66597.h | 3 ++ 2 files changed, 70 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index b46ff9a80b66..dac2f7dd69b9 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -46,7 +46,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yoshihiro Shimoda"); MODULE_ALIAS("platform:r8a66597_hcd"); -#define DRIVER_VERSION "29 May 2007" +#define DRIVER_VERSION "10 Apr 2008" static const char hcd_name[] = "r8a66597_hcd"; @@ -577,13 +577,9 @@ static void pipe_buffer_setting(struct r8a66597 *r8a66597, PIPEBUF); r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket, PIPEMAXP); - if (info->interval) - info->interval--; r8a66597_write(r8a66597, info->interval, PIPEPERI); } - - /* this function must be called with interrupt disabled */ static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td) { @@ -825,6 +821,25 @@ static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597, dev->dma_map = 0; } +static unsigned long get_timer_interval(struct urb *urb, __u8 interval) +{ + __u8 i; + unsigned long time = 1; + + if (usb_pipeisoc(urb->pipe)) + return 0; + + if (get_r8a66597_usb_speed(urb->dev->speed) == HSMODE) { + for (i = 0; i < (interval - 1); i++) + time *= 2; + time = time * 125 / 1000; /* uSOF -> msec */ + } else { + time = interval; + } + + return time; +} + /* this function must be called with interrupt disabled */ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, struct usb_host_endpoint *hep, @@ -840,7 +855,16 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, & USB_ENDPOINT_XFERTYPE_MASK); info.bufnum = get_bufnum(info.pipenum); info.buf_bsize = get_buf_bsize(info.pipenum); - info.interval = ep->bInterval; + if (info.type == R8A66597_BULK) { + info.interval = 0; + info.timer_interval = 0; + } else { + if (ep->bInterval > IITV) + info.interval = IITV; + else + info.interval = ep->bInterval ? ep->bInterval - 1 : 0; + info.timer_interval = get_timer_interval(urb, ep->bInterval); + } if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) info.dir_in = 1; else @@ -1582,6 +1606,29 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port) } } +static void r8a66597_interval_timer(unsigned long _r8a66597) +{ + struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; + unsigned long flags; + u16 pipenum; + struct r8a66597_td *td; + + spin_lock_irqsave(&r8a66597->lock, flags); + + for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { + if (!(r8a66597->interval_map & (1 << pipenum))) + continue; + if (timer_pending(&r8a66597->interval_timer[pipenum])) + continue; + + td = r8a66597_get_td(r8a66597, pipenum); + if (td) + start_transfer(r8a66597, td); + } + + spin_unlock_irqrestore(&r8a66597->lock, flags); +} + static void r8a66597_td_timer(unsigned long _r8a66597) { struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; @@ -1763,10 +1810,17 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, urb->hcpriv = td; if (request) { - ret = start_transfer(r8a66597, td); - if (ret < 0) { - list_del(&td->queue); - kfree(td); + if (td->pipe->info.timer_interval) { + r8a66597->interval_map |= 1 << td->pipenum; + mod_timer(&r8a66597->interval_timer[td->pipenum], + jiffies + msecs_to_jiffies( + td->pipe->info.timer_interval)); + } else { + ret = start_transfer(r8a66597, td); + if (ret < 0) { + list_del(&td->queue); + kfree(td); + } } } else set_td_timer(r8a66597, td); @@ -2192,6 +2246,9 @@ static int __init r8a66597_probe(struct platform_device *pdev) init_timer(&r8a66597->td_timer[i]); r8a66597->td_timer[i].function = r8a66597_td_timer; r8a66597->td_timer[i].data = (unsigned long)r8a66597; + setup_timer(&r8a66597->interval_timer[i], + r8a66597_interval_timer, + (unsigned long)r8a66597); } INIT_LIST_HEAD(&r8a66597->child_device); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 57388252b693..a01461017ad6 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -404,6 +404,7 @@ #define make_devsel(addr) (addr << 12) struct r8a66597_pipe_info { + unsigned long timer_interval; u16 pipenum; u16 address; /* R8A66597 HCD usb address */ u16 epnum; @@ -478,9 +479,11 @@ struct r8a66597 { struct timer_list rh_timer; struct timer_list td_timer[R8A66597_MAX_NUM_PIPE]; + struct timer_list interval_timer[R8A66597_MAX_NUM_PIPE]; unsigned short address_map; unsigned short timeout_map; + unsigned short interval_map; unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE]; unsigned char dma_map; -- cgit v1.2.2 From 29fab0cd897519be9009ba8c898410ab83b378e9 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 10 Apr 2008 21:05:55 +0900 Subject: USB: r8a66597-hcd: fix usb device connection timing Fix the problem that enumeration of a USB device was slow. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 56 +++++++++++++++++++++++------------------ drivers/usb/host/r8a66597.h | 3 ++- 2 files changed, 34 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index dac2f7dd69b9..bb48f42bd7ce 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -900,10 +900,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum) } /* this function must be called with interrupt disabled */ -static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) +static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, + u16 syssts) { - r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) - | (1 << USB_PORT_FEAT_C_CONNECTION); + if (syssts == SE0) { + r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); + return; + } + + if (syssts == FS_JSTS) + r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); + else if (syssts == LS_JSTS) + r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); + r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); } @@ -1478,13 +1487,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) } } +static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597) +{ + mod_timer(&r8a66597->rh_timer, + jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME)); +} + static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port) { struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; rh->scount = R8A66597_MAX_SAMPLING; - mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50)); + r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) + | (1 << USB_PORT_FEAT_C_CONNECTION); + r8a66597_root_hub_start_polling(r8a66597); } static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) @@ -1571,37 +1588,28 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port) if ((tmp & USBRST) == USBRST) { r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, dvstctr_reg); - mod_timer(&r8a66597->rh_timer, - jiffies + msecs_to_jiffies(50)); + r8a66597_root_hub_start_polling(r8a66597); } else r8a66597_usb_connect(r8a66597, port); } + if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) { + r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); + r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); + } + if (rh->scount > 0) { tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST; if (tmp == rh->old_syssts) { rh->scount--; - if (rh->scount == 0) { - if (tmp == FS_JSTS) { - r8a66597_bset(r8a66597, HSE, - get_syscfg_reg(port)); - r8a66597_usb_preconnect(r8a66597, port); - } else if (tmp == LS_JSTS) { - r8a66597_bclr(r8a66597, HSE, - get_syscfg_reg(port)); - r8a66597_usb_preconnect(r8a66597, port); - } else if (tmp == SE0) - r8a66597_bset(r8a66597, ATTCHE, - get_intenb_reg(port)); - } else { - mod_timer(&r8a66597->rh_timer, - jiffies + msecs_to_jiffies(50)); - } + if (rh->scount == 0) + r8a66597_check_syssts(r8a66597, port, tmp); + else + r8a66597_root_hub_start_polling(r8a66597); } else { rh->scount = R8A66597_MAX_SAMPLING; rh->old_syssts = tmp; - mod_timer(&r8a66597->rh_timer, - jiffies + msecs_to_jiffies(50)); + r8a66597_root_hub_start_polling(r8a66597); } } } diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index a01461017ad6..f46f7dd944a1 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -396,7 +396,8 @@ #define R8A66597_BUF_BSIZE 8 #define R8A66597_MAX_DEVICE 10 #define R8A66597_MAX_ROOT_HUB 2 -#define R8A66597_MAX_SAMPLING 10 +#define R8A66597_MAX_SAMPLING 5 +#define R8A66597_RH_POLL_TIME 10 #define R8A66597_MAX_DMA_CHANNEL 2 #define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL #define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5)) -- cgit v1.2.2 From 9424ea29658ce5bcdcf527ddf9617b9507ddf1aa Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 10 Apr 2008 21:05:58 +0900 Subject: USB: r8a66597-hcd: Add support for SH7366 USB host R8A66597 is similar to SH7366 USB 2.0 Host/Function module. It can support SH7366 USB host by changing several R8A66597 code. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 6 +++ drivers/usb/host/r8a66597-hcd.c | 115 +++++++++++++++++++++++++++------------- drivers/usb/host/r8a66597.h | 45 ++++++++++++++++ 3 files changed, 129 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 27f295b78055..0b87480dd713 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -260,3 +260,9 @@ config USB_R8A66597_HCD To compile this driver as a module, choose M here: the module will be called r8a66597-hcd. +config SUPERH_ON_CHIP_R8A66597 + boolean "Enable SuperH on-chip USB like the R8A66597" + depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 + help + Renesas SuperH processor has USB like the R8A66597. + This driver supported processor is SH7366. diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bb48f42bd7ce..f4fa93dabdde 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -51,10 +51,12 @@ MODULE_ALIAS("platform:r8a66597_hcd"); static const char hcd_name[] = "r8a66597_hcd"; /* module parameters */ +#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) static unsigned short clock = XTAL12; module_param(clock, ushort, 0644); MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " "(default=0)"); +#endif static unsigned short vif = LDRV; module_param(vif, ushort, 0644); @@ -106,11 +108,22 @@ static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address, r8a66597_write(r8a66597, val, devadd_reg); } -static int enable_controller(struct r8a66597 *r8a66597) +static int r8a66597_clock_enable(struct r8a66597 *r8a66597) { u16 tmp; int i = 0; +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + do { + r8a66597_write(r8a66597, SCKE, SYSCFG0); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 1000) { + err("register access fail."); + return -ENXIO; + } + } while ((tmp & SCKE) != SCKE); + r8a66597_write(r8a66597, 0x04, 0x02); +#else do { r8a66597_write(r8a66597, USBE, SYSCFG0); tmp = r8a66597_read(r8a66597, SYSCFG0); @@ -132,13 +145,63 @@ static int enable_controller(struct r8a66597 *r8a66597) return -ENXIO; } } while ((tmp & SCKE) != SCKE); +#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ + + return 0; +} + +static void r8a66597_clock_disable(struct r8a66597 *r8a66597) +{ + r8a66597_bclr(r8a66597, SCKE, SYSCFG0); + udelay(1); +#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + r8a66597_bclr(r8a66597, PLLC, SYSCFG0); + r8a66597_bclr(r8a66597, XCKE, SYSCFG0); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); +#endif +} + +static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) +{ + u16 val; + + val = port ? DRPD : DCFM | DRPD; + r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); + r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); + + r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); + r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port)); + r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); +} + +static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) +{ + u16 val, tmp; - r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0); - r8a66597_bset(r8a66597, DRPD, SYSCFG1); + r8a66597_write(r8a66597, 0, get_intenb_reg(port)); + r8a66597_write(r8a66597, 0, get_intsts_reg(port)); + + r8a66597_port_power(r8a66597, port, 0); + + do { + tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; + udelay(640); + } while (tmp == EDGESTS); + + val = port ? DRPD : DCFM | DRPD; + r8a66597_bclr(r8a66597, val, get_syscfg_reg(port)); + r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); +} + +static int enable_controller(struct r8a66597 *r8a66597) +{ + int ret, port; + + ret = r8a66597_clock_enable(r8a66597); + if (ret < 0) + return ret; r8a66597_bset(r8a66597, vif & LDRV, PINCFG); - r8a66597_bset(r8a66597, HSE, SYSCFG0); - r8a66597_bset(r8a66597, HSE, SYSCFG1); r8a66597_bset(r8a66597, USBE, SYSCFG0); r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0); @@ -146,53 +209,30 @@ static int enable_controller(struct r8a66597 *r8a66597) r8a66597_bset(r8a66597, BRDY0, BRDYENB); r8a66597_bset(r8a66597, BEMP0, BEMPENB); - r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG); - r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG); - r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); - r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1); - r8a66597_bclr(r8a66597, DTCHE, INTENB1); - r8a66597_bset(r8a66597, ATTCHE, INTENB1); - r8a66597_bclr(r8a66597, DTCHE, INTENB2); - r8a66597_bset(r8a66597, ATTCHE, INTENB2); + + for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + r8a66597_enable_port(r8a66597, port); return 0; } static void disable_controller(struct r8a66597 *r8a66597) { - u16 tmp; + int port; r8a66597_write(r8a66597, 0, INTENB0); - r8a66597_write(r8a66597, 0, INTENB1); - r8a66597_write(r8a66597, 0, INTENB2); r8a66597_write(r8a66597, 0, INTSTS0); - r8a66597_write(r8a66597, 0, INTSTS1); - r8a66597_write(r8a66597, 0, INTSTS2); - - r8a66597_port_power(r8a66597, 0, 0); - r8a66597_port_power(r8a66597, 1, 0); - - do { - tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; - udelay(640); - } while (tmp == EDGESTS); - r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0); - r8a66597_bclr(r8a66597, DRPD, SYSCFG1); - r8a66597_bclr(r8a66597, HSE, SYSCFG0); - r8a66597_bclr(r8a66597, HSE, SYSCFG1); + for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + r8a66597_disable_port(r8a66597, port); - r8a66597_bclr(r8a66597, SCKE, SYSCFG0); - udelay(1); - r8a66597_bclr(r8a66597, PLLC, SYSCFG0); - r8a66597_bclr(r8a66597, XCKE, SYSCFG0); - r8a66597_bclr(r8a66597, USBE, SYSCFG0); + r8a66597_clock_disable(r8a66597); } static int get_parent_r8a66597_address(struct r8a66597 *r8a66597, @@ -711,6 +751,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe, struct urb *urb) { +#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) int i; struct r8a66597_pipe_info *info = &pipe->info; @@ -738,6 +779,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597, break; } } +#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ } /* this function must be called with interrupt disabled */ @@ -1054,8 +1096,7 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); - r8a66597_write(r8a66597, BCLR, CFIFOCTR); - r8a66597_write(r8a66597, BVAL, CFIFOCTR); + r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR); enable_irq_empty(r8a66597, 0); } else { r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index f46f7dd944a1..84ee01417315 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -187,7 +187,11 @@ #define REW 0x4000 /* b14: Buffer rewind */ #define DCLRM 0x2000 /* b13: DMA buffer clear mode */ #define DREQE 0x1000 /* b12: DREQ output enable */ +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#define MBW 0x0800 +#else #define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ +#endif #define MBW_8 0x0000 /* 8bit */ #define MBW_16 0x0400 /* 16bit */ #define BIGEND 0x0100 /* b8: Big endian mode */ @@ -395,7 +399,11 @@ #define R8A66597_MAX_NUM_PIPE 10 #define R8A66597_BUF_BSIZE 8 #define R8A66597_MAX_DEVICE 10 +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#define R8A66597_MAX_ROOT_HUB 1 +#else #define R8A66597_MAX_ROOT_HUB 2 +#endif #define R8A66597_MAX_SAMPLING 5 #define R8A66597_RH_POLL_TIME 10 #define R8A66597_MAX_DMA_CHANNEL 2 @@ -530,8 +538,21 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, unsigned long offset, u16 *buf, int len) { +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + unsigned long fifoaddr = r8a66597->reg + offset; + unsigned long count; + + count = len / 4; + insl(fifoaddr, buf, count); + + if (len & 0x00000003) { + unsigned long tmp = inl(fifoaddr); + memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03); + } +#else len = (len + 1) / 2; insw(r8a66597->reg + offset, buf, len); +#endif } static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, @@ -545,6 +566,24 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, int len) { unsigned long fifoaddr = r8a66597->reg + offset; +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + unsigned long count; + unsigned char *pb; + int i; + + count = len / 4; + outsl(fifoaddr, buf, count); + + if (len & 0x00000003) { + pb = (unsigned char *)buf + count * 4; + for (i = 0; i < (len & 0x00000003); i++) { + if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) + outb(pb[i], fifoaddr + i); + else + outb(pb[i], fifoaddr + 3 - i); + } + } +#else int odd = len & 0x0001; len = len / 2; @@ -553,6 +592,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, buf = &buf[len]; outb((unsigned char)*buf, fifoaddr); } +#endif } static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, @@ -585,6 +625,11 @@ static inline unsigned long get_dvstctr_reg(int port) return port == 0 ? DVSTCTR0 : DVSTCTR1; } +static inline unsigned long get_dmacfg_reg(int port) +{ + return port == 0 ? DMA0CFG : DMA1CFG; +} + static inline unsigned long get_intenb_reg(int port) { return port == 0 ? INTENB1 : INTENB2; -- cgit v1.2.2 From eda769593bbae8aee4e336b0732f6016353301a3 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Apr 2008 14:07:37 +0200 Subject: USB: add extension of anchor API, usb_unlink_anchored_urbs This adds the ability to trigger asynchronous unlinks of anchored URBs. This is needed for error handling in the comntext of completion handlers, which cannot sleep. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9d7e63292c01..1d3ed1322fbe 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -589,6 +589,30 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor) } EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); +/** + * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse + * @anchor: anchor the requests are bound to + * + * this allows all outstanding URBs to be unlinked starting + * from the back of the queue. This function is asynchronous. + * The unlinking is just tiggered. It may happen after this + * function has returned. + */ +void usb_unlink_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + + spin_lock_irq(&anchor->lock); + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, struct urb, + anchor_list); + /* this will unanchor the URB */ + usb_unlink_urb(victim); + } + spin_unlock_irq(&anchor->lock); +} +EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs); + /** * usb_wait_anchor_empty_timeout - wait for an anchor to be unused * @anchor: the anchor you want to become unused -- cgit v1.2.2 From 51c159e7a8310f7272154fdd096315ae86bd36c2 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 6 Apr 2008 08:00:30 -0400 Subject: USB: Remove superfluous "depends on USB_SERIAL" from Kconfig. Given that most of drivers/usb/serial/Kconfig is wrapped inside: if USB_SERIAL ... endif # USB_SERIAL remove the consequently redundant dependencies on USB_SERIAL. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 42 ------------------------------------------ 1 file changed, 42 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index f9c6c0922c00..2cffec85ee7e 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -44,13 +44,11 @@ config USB_SERIAL_CONSOLE config USB_EZUSB bool "Functions for loading firmware on EZUSB chips" - depends on USB_SERIAL help Say Y here if you need EZUSB device support. config USB_SERIAL_GENERIC bool "USB Generic Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use the generic USB serial driver. Please read for more information on @@ -60,7 +58,6 @@ config USB_SERIAL_GENERIC config USB_SERIAL_AIRCABLE tristate "USB AIRcable Bluetooth Dongle Driver" - depends on USB_SERIAL help Say Y here if you want to use USB AIRcable Bluetooth Dongle. @@ -69,7 +66,6 @@ config USB_SERIAL_AIRCABLE config USB_SERIAL_AIRPRIME tristate "USB AirPrime CDMA Wireless Driver" - depends on USB_SERIAL help Say Y here if you want to use a AirPrime CDMA Wireless PC card. @@ -78,7 +74,6 @@ config USB_SERIAL_AIRPRIME config USB_SERIAL_ARK3116 tristate "USB ARK Micro 3116 USB Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use a ARK Micro 3116 USB to Serial device. @@ -88,7 +83,6 @@ config USB_SERIAL_ARK3116 config USB_SERIAL_BELKIN tristate "USB Belkin and Peracom Single Port Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use a Belkin USB Serial single port adaptor (F5U103 is one of the model numbers) or the Peracom single @@ -99,7 +93,6 @@ config USB_SERIAL_BELKIN config USB_SERIAL_CH341 tristate "USB Winchiphead CH341 Single Port Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use a Winchiphead CH341 single port USB to serial adapter. @@ -109,7 +102,6 @@ config USB_SERIAL_CH341 config USB_SERIAL_WHITEHEAT tristate "USB ConnectTech WhiteHEAT Serial Driver" - depends on USB_SERIAL select USB_EZUSB help Say Y here if you want to use a ConnectTech WhiteHEAT 4 port @@ -120,7 +112,6 @@ config USB_SERIAL_WHITEHEAT config USB_SERIAL_DIGI_ACCELEPORT tristate "USB Digi International AccelePort USB Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use Digi AccelePort USB 2 or 4 devices, 2 port (plus parallel port) and 4 port USB serial converters. The @@ -135,7 +126,6 @@ config USB_SERIAL_DIGI_ACCELEPORT config USB_SERIAL_CP2101 tristate "USB CP2101 UART Bridge Controller" - depends on USB_SERIAL help Say Y here if you want to use a CP2101/CP2102 based USB to RS232 converter. @@ -145,7 +135,6 @@ config USB_SERIAL_CP2101 config USB_SERIAL_CYPRESS_M8 tristate "USB Cypress M8 USB Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use a device that contains the Cypress USB to Serial microcontroller, such as the DeLorme Earthmate GPS. @@ -160,7 +149,6 @@ config USB_SERIAL_CYPRESS_M8 config USB_SERIAL_EMPEG tristate "USB Empeg empeg-car Mark I/II Driver" - depends on USB_SERIAL help Say Y here if you want to connect to your Empeg empeg-car Mark I/II mp3 player via USB. The driver uses a single ttyUSB{0,1,2,...} @@ -172,7 +160,6 @@ config USB_SERIAL_EMPEG config USB_SERIAL_FTDI_SIO tristate "USB FTDI Single Port Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use a FTDI SIO single port USB to serial converter device. The implementation I have is called the USC-1000. @@ -186,7 +173,6 @@ config USB_SERIAL_FTDI_SIO config USB_SERIAL_FUNSOFT tristate "USB Fundamental Software Dongle Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use the Fundamental Software dongle. @@ -195,7 +181,6 @@ config USB_SERIAL_FUNSOFT config USB_SERIAL_VISOR tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" - depends on USB_SERIAL help Say Y here if you want to connect to your HandSpring Visor, Palm m500 or m505 through its USB docking station. See @@ -207,7 +192,6 @@ config USB_SERIAL_VISOR config USB_SERIAL_IPAQ tristate "USB PocketPC PDA Driver" - depends on USB_SERIAL help Say Y here if you want to connect to your Compaq iPAQ, HP Jornada or any other PDA running Windows CE 3.0 or PocketPC 2002 @@ -219,7 +203,6 @@ config USB_SERIAL_IPAQ config USB_SERIAL_IR tristate "USB IR Dongle Serial Driver" - depends on USB_SERIAL help Say Y here if you want to enable simple serial support for USB IrDA devices. This is useful if you do not want to use the full IrDA @@ -230,7 +213,6 @@ config USB_SERIAL_IR config USB_SERIAL_EDGEPORT tristate "USB Inside Out Edgeport Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use any of the following devices from Inside Out Networks (Digi): @@ -256,7 +238,6 @@ config USB_SERIAL_EDGEPORT config USB_SERIAL_EDGEPORT_TI tristate "USB Inside Out Edgeport Serial Driver (TI devices)" - depends on USB_SERIAL help Say Y here if you want to use any of the devices from Inside Out Networks (Digi) that are not supported by the io_edgeport driver. @@ -267,7 +248,6 @@ config USB_SERIAL_EDGEPORT_TI config USB_SERIAL_GARMIN tristate "USB Garmin GPS driver" - depends on USB_SERIAL help Say Y here if you want to connect to your Garmin GPS. Should work with most Garmin GPS devices which have a native USB port. @@ -280,7 +260,6 @@ config USB_SERIAL_GARMIN config USB_SERIAL_IPW tristate "USB IPWireless (3G UMTS TDD) Driver" - depends on USB_SERIAL help Say Y here if you want to use a IPWireless USB modem such as the ones supplied by Axity3G/Sentech South Africa. @@ -290,7 +269,6 @@ config USB_SERIAL_IPW config USB_SERIAL_IUU tristate "USB Infinity USB Unlimited Phoenix Driver" - depends on USB_SERIAL help Say Y here if you want to use a IUU in phoenix mode and get an extra ttyUSBx device. More information available on @@ -301,7 +279,6 @@ config USB_SERIAL_IUU config USB_SERIAL_KEYSPAN_PDA tristate "USB Keyspan PDA Single Port Serial Driver" - depends on USB_SERIAL select USB_EZUSB help Say Y here if you want to use a Keyspan PDA single port USB to @@ -313,7 +290,6 @@ config USB_SERIAL_KEYSPAN_PDA config USB_SERIAL_KEYSPAN tristate "USB Keyspan USA-xxx Serial Driver" - depends on USB_SERIAL select USB_EZUSB ---help--- Say Y here if you want to use Keyspan USB to serial converter @@ -406,7 +382,6 @@ config USB_SERIAL_KEYSPAN_USA49WLC config USB_SERIAL_KLSI tristate "USB KL5KUSB105 (Palmconnect) Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use a KL5KUSB105 - based single port serial adapter. The most widely known -- and currently the only @@ -422,7 +397,6 @@ config USB_SERIAL_KLSI config USB_SERIAL_KOBIL_SCT tristate "USB KOBIL chipcard reader" - depends on USB_SERIAL ---help--- Say Y here if you want to use one of the following KOBIL USB chipcard readers: @@ -440,7 +414,6 @@ config USB_SERIAL_KOBIL_SCT config USB_SERIAL_MCT_U232 tristate "USB MCT Single Port Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use a USB Serial single port adapter from Magic Control Technology Corp. (U232 is one of the model numbers). @@ -453,7 +426,6 @@ config USB_SERIAL_MCT_U232 config USB_SERIAL_MOS7720 tristate "USB Moschip 7720 Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use USB Serial single and double port adapters from Moschip Semiconductor Tech. @@ -463,7 +435,6 @@ config USB_SERIAL_MOS7720 config USB_SERIAL_MOS7840 tristate "USB Moschip 7840/7820 USB Serial Driver" - depends on USB_SERIAL ---help--- Say Y here if you want to use a MCS7840 Quad-Serial or MCS7820 Dual-Serial port device from MosChip Semiconductor. @@ -478,14 +449,12 @@ config USB_SERIAL_MOS7840 config USB_SERIAL_NAVMAN tristate "USB Navman GPS device" - depends on USB_SERIAL help To compile this driver as a module, choose M here: the module will be called navman. config USB_SERIAL_PL2303 tristate "USB Prolific 2303 Single Port Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use the PL2303 USB Serial single port adapter from Prolific. @@ -495,7 +464,6 @@ config USB_SERIAL_PL2303 config USB_SERIAL_OTI6858 tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller" - depends on USB_SERIAL help Say Y here if you want to use the OTi-6858 single port USB to serial converter device. @@ -505,7 +473,6 @@ config USB_SERIAL_OTI6858 config USB_SERIAL_SPCP8X5 tristate "USB SPCP8x5 USB To Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use the spcp8x5 converter chip. This is commonly found in some Z-Wave USB devices. @@ -515,7 +482,6 @@ config USB_SERIAL_SPCP8X5 config USB_SERIAL_HP4X tristate "USB HP4x Calculators support" - depends on USB_SERIAL help Say Y here if you want to use an Hewlett-Packard 4x Calculator. @@ -524,7 +490,6 @@ config USB_SERIAL_HP4X config USB_SERIAL_SAFE tristate "USB Safe Serial (Encapsulated) Driver" - depends on USB_SERIAL config USB_SERIAL_SAFE_PADDED bool "USB Secure Encapsulated Driver - Padded" @@ -532,7 +497,6 @@ config USB_SERIAL_SAFE_PADDED config USB_SERIAL_SIERRAWIRELESS tristate "USB Sierra Wireless Driver" - depends on USB_SERIAL help Say M here if you want to use a Sierra Wireless device (if using an PC 5220 or AC580 please use the Airprime driver @@ -543,7 +507,6 @@ config USB_SERIAL_SIERRAWIRELESS config USB_SERIAL_TI tristate "USB TI 3410/5052 Serial Driver" - depends on USB_SERIAL help Say Y here if you want to use the TI USB 3410 or 5052 serial devices. @@ -553,7 +516,6 @@ config USB_SERIAL_TI config USB_SERIAL_CYBERJACK tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader" - depends on USB_SERIAL ---help--- Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard reader. This is an interface to ISO 7816 compatible contact-based @@ -566,7 +528,6 @@ config USB_SERIAL_CYBERJACK config USB_SERIAL_XIRCOM tristate "USB Xircom / Entregra Single Port Serial Driver" - depends on USB_SERIAL select USB_EZUSB help Say Y here if you want to use a Xircom or Entregra single port USB to @@ -578,7 +539,6 @@ config USB_SERIAL_XIRCOM config USB_SERIAL_OPTION tristate "USB driver for GSM and CDMA modems" - depends on USB_SERIAL help Say Y here if you have a GSM or CDMA modem that's connected to USB. @@ -597,7 +557,6 @@ config USB_SERIAL_OPTION config USB_SERIAL_OMNINET tristate "USB ZyXEL omni.net LCD Plus Driver" - depends on USB_SERIAL help Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA. @@ -606,7 +565,6 @@ config USB_SERIAL_OMNINET config USB_SERIAL_DEBUG tristate "USB Debugging Device" - depends on USB_SERIAL help Say Y here if you have a USB debugging device used to receive debugging data from another machine. The most common of these -- cgit v1.2.2 From 6427f7995338387ddded92f98adec19ddbf0ae5e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 10 Apr 2008 12:45:34 -0400 Subject: USB: log an error message when USB enumeration fails This patch (as1077) logs an error message whenever the kernel is unable to enumerate a new USB device. Signed-off-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9fc5179dfc60..1e23e360ea91 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2708,6 +2708,7 @@ loop: if ((status == -ENOTCONN) || (status == -ENOTSUPP)) break; } + dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); done: hub_port_disable(hub, port1, 1); -- cgit v1.2.2 From a082b5c7882bdbd8a86ace8470ca2ecda796d5a7 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 10 Apr 2008 14:21:06 -0700 Subject: USB: ehci: qh/qtd cleanup comments Provide better comments about qh_completions() and QTD handling. That code can be *VERY* confusing, since it's evolved over a few years to cope with both hardware races and silicon quirks. Remove two unlikely() annotations that match the GCC defaults (and are thus pointless); add an "else" to highlight code flow. This patch doesn't change driver behavior. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 50 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index c0e752cffc68..64942ec584c2 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -336,11 +336,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) /* always clean up qtds the hc de-activated */ if ((token & QTD_STS_ACTIVE) == 0) { + /* on STALL, error, and short reads this urb must + * complete and all its qtds must be recycled. + */ if ((token & QTD_STS_HALT) != 0) { stopped = 1; /* magic dummy for some short reads; qh won't advance. * that silicon quirk can kick in with this dummy too. + * + * other short reads won't stop the queue, including + * control transfers (status stage handles that) or + * most other single-qtd reads ... the queue stops if + * URB_SHORT_NOT_OK was set so the driver submitting + * the urbs could clean it up. */ } else if (IS_SHORT_READ (token) && !(qtd->hw_alt_next @@ -354,18 +363,18 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) { break; + /* scan the whole queue for unlinks whenever it stops */ } else { stopped = 1; - if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) + /* cancel everything if we halt, suspend, etc */ + if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) last_status = -ESHUTDOWN; - /* ignore active urbs unless some previous qtd - * for the urb faulted (including short read) or - * its urb was canceled. we may patch qh or qtds. + /* this qtd is active; skip it unless a previous qtd + * for its urb faulted, or its urb was canceled. */ - if (likely(last_status == -EINPROGRESS && - !urb->unlinked)) + else if (last_status == -EINPROGRESS && !urb->unlinked) continue; /* issue status after short control reads */ @@ -375,7 +384,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) continue; } - /* token in overlay may be most current */ + /* qh unlinked; token in overlay may be most current */ if (state == QH_STATE_IDLE && cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current) @@ -402,11 +411,16 @@ halt: if (likely(last_status == -EINPROGRESS)) last_status = qtd_status; + /* if we're removing something not at the queue head, + * patch the hardware queue pointer. + */ if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { last = list_entry (qtd->qtd_list.prev, struct ehci_qtd, qtd_list); last->hw_next = qtd->hw_next; } + + /* remove qtd; it's recycled after possible urb completion */ list_del (&qtd->qtd_list); last = qtd; } @@ -431,7 +445,15 @@ halt: qh_refresh(ehci, qh); break; case QH_STATE_LINKED: - /* should be rare for periodic transfers, + /* We won't refresh a QH that's linked (after the HC + * stopped the queue). That avoids a race: + * - HC reads first part of QH; + * - CPU updates that first part and the token; + * - HC reads rest of that QH, including token + * Result: HC gets an inconsistent image, and then + * DMAs to/from the wrong memory (corrupting it). + * + * That should be rare for interrupt transfers, * except maybe high bandwidth ... */ if ((cpu_to_hc32(ehci, QH_SMASK) @@ -549,6 +571,12 @@ qh_urb_transaction ( this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket); len -= this_qtd_len; buf += this_qtd_len; + + /* + * short reads advance to a "magic" dummy instead of the next + * qtd ... that forces the queue to stop, for manual cleanup. + * (this will usually be overridden later.) + */ if (is_input) qtd->hw_alt_next = ehci->async->hw_alt_next; @@ -568,8 +596,10 @@ qh_urb_transaction ( list_add_tail (&qtd->qtd_list, head); } - /* unless the bulk/interrupt caller wants a chance to clean - * up after short reads, hc should advance qh past this urb + /* + * unless the caller requires manual cleanup after short reads, + * have the alt_next mechanism keep the queue running after the + * last data qtd (the only one, for control and most other cases). */ if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 || usb_pipecontrol (urb->pipe))) -- cgit v1.2.2 From 5f760040bcb4cc0498d4c662c4ea305290198ef3 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Thu, 10 Apr 2008 10:15:53 +0200 Subject: USB: option.c: correct DTR behaviour Setting DTR et al. should work for all interfaces if you actually pass the interface number. :-P This should help with devices that have important pseudo-serial ports that aren't on the first interface in the device. Signed-off-by: Chris Collins Signed-off-by: Matthias Urlichs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0e7eeb2820e2..130aa96746f0 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -28,7 +28,7 @@ device features. */ -#define DRIVER_VERSION "v0.7.1" +#define DRIVER_VERSION "v0.7.2" #define DRIVER_AUTHOR "Matthias Urlichs " #define DRIVER_DESC "USB Driver for GSM modems" @@ -824,16 +824,19 @@ static void option_setup_urbs(struct usb_serial *serial) } } + +/** send RTS/DTR state to the port. + * + * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN + * CDC. +*/ static int option_send_setup(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; struct option_port_private *portdata; - + int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; dbg("%s", __FUNCTION__); - if (port->number != 0) - return 0; - portdata = usb_get_serial_port_data(port); if (port->tty) { @@ -845,7 +848,7 @@ static int option_send_setup(struct usb_serial_port *port) return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); + 0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT); } return 0; -- cgit v1.2.2 From 0ba4034e20abf372dae6c6cabeeeab600acb5889 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 16 Apr 2008 09:17:38 -0700 Subject: USB: serial: remove unneeded number endpoints settings The usb-serial core no longer checks these fields so remove them from all of the individual drivers. They will be removed from the usb-serial core in a patch later in the series. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 3 --- drivers/usb/serial/ark3116.c | 3 --- drivers/usb/serial/belkin_sa.c | 3 --- drivers/usb/serial/ch341.c | 3 --- drivers/usb/serial/cp2101.c | 3 --- drivers/usb/serial/cyberjack.c | 3 --- drivers/usb/serial/cypress_m8.c | 12 ------------ drivers/usb/serial/digi_acceleport.c | 6 ------ drivers/usb/serial/empeg.c | 3 --- drivers/usb/serial/ftdi_sio.c | 3 --- drivers/usb/serial/funsoft.c | 3 --- drivers/usb/serial/garmin_gps.c | 3 --- drivers/usb/serial/generic.c | 3 --- drivers/usb/serial/hp4x.c | 3 --- drivers/usb/serial/io_tables.h | 12 ------------ drivers/usb/serial/io_ti.c | 6 ------ drivers/usb/serial/ipaq.c | 3 --- drivers/usb/serial/ipw.c | 3 --- drivers/usb/serial/ir-usb.c | 3 --- drivers/usb/serial/iuu_phoenix.c | 3 --- drivers/usb/serial/keyspan.h | 16 ---------------- drivers/usb/serial/keyspan_pda.c | 9 --------- drivers/usb/serial/kl5kusb105.c | 3 --- drivers/usb/serial/kobil_sct.c | 4 ---- drivers/usb/serial/mct_u232.c | 3 --- drivers/usb/serial/mos7720.c | 3 --- drivers/usb/serial/mos7840.c | 5 ----- drivers/usb/serial/navman.c | 3 --- drivers/usb/serial/omninet.c | 3 --- drivers/usb/serial/option.c | 3 --- drivers/usb/serial/oti6858.c | 3 --- drivers/usb/serial/pl2303.c | 3 --- drivers/usb/serial/safe_serial.c | 3 --- drivers/usb/serial/sierra.c | 3 --- drivers/usb/serial/spcp8x5.c | 3 --- drivers/usb/serial/ti_usb_3410_5052.c | 6 ------ drivers/usb/serial/usb_debug.c | 3 --- drivers/usb/serial/visor.c | 9 --------- drivers/usb/serial/whiteheat.c | 6 ------ 39 files changed, 175 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index f156dba0300f..d5bcb3774034 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -306,9 +306,6 @@ static struct usb_serial_driver airprime_device = { }, .usb_driver = &airprime_driver, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .open = airprime_open, .close = airprime_close, .write = airprime_write, diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index fe2bfd67ba8e..aa7a6838a3d4 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -447,9 +447,6 @@ static struct usb_serial_driver ark3116_device = { }, .id_table = id_table, .usb_driver = &ark3116_driver, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .attach = ark3116_attach, .set_termios = ark3116_set_termios, diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index df0a2b3b0294..b6950648804f 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -128,9 +128,6 @@ static struct usb_serial_driver belkin_device = { .description = "Belkin / Peracom / GoHubs USB Serial Adapter", .usb_driver = &belkin_driver, .id_table = id_table_combined, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = belkin_sa_open, .close = belkin_sa_close, diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 42582d49b69c..d947d955bceb 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -318,9 +318,6 @@ static struct usb_serial_driver ch341_device = { }, .id_table = id_table, .usb_driver = &ch341_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = ch341_open, .set_termios = ch341_set_termios, diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 3b4fa94ecf28..2af8d21bb121 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -109,9 +109,6 @@ static struct usb_serial_driver cp2101_device = { }, .usb_driver = &cp2101_driver, .id_table = id_table, - .num_interrupt_in = 0, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .open = cp2101_open, .close = cp2101_close, diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 8d9b045aa7e8..cbae876cd678 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -90,9 +90,6 @@ static struct usb_serial_driver cyberjack_device = { .description = "Reiner SCT Cyberjack USB card reader", .usb_driver = &cyberjack_driver, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .attach = cyberjack_startup, .shutdown = cyberjack_shutdown, diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 36f8ef079479..d8304eaf34c4 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -200,10 +200,6 @@ static struct usb_serial_driver cypress_earthmate_device = { .description = "DeLorme Earthmate USB", .usb_driver = &cypress_driver, .id_table = id_table_earthmate, - .num_interrupt_in = 1, - .num_interrupt_out = 1, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = cypress_earthmate_startup, .shutdown = cypress_shutdown, @@ -230,10 +226,6 @@ static struct usb_serial_driver cypress_hidcom_device = { .description = "HID->COM RS232 Adapter", .usb_driver = &cypress_driver, .id_table = id_table_cyphidcomrs232, - .num_interrupt_in = 1, - .num_interrupt_out = 1, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = cypress_hidcom_startup, .shutdown = cypress_shutdown, @@ -260,10 +252,6 @@ static struct usb_serial_driver cypress_ca42v2_device = { .description = "Nokia CA-42 V2 Adapter", .usb_driver = &cypress_driver, .id_table = id_table_nokiaca42v2, - .num_interrupt_in = 1, - .num_interrupt_out = 1, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = cypress_ca42v2_startup, .shutdown = cypress_shutdown, diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 5f9c6e46bee5..4e3d5993a8e3 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -508,9 +508,6 @@ static struct usb_serial_driver digi_acceleport_2_device = { .description = "Digi 2 port USB adapter", .usb_driver = &digi_driver, .id_table = id_table_2, - .num_interrupt_in = 0, - .num_bulk_in = 4, - .num_bulk_out = 4, .num_ports = 3, .open = digi_open, .close = digi_close, @@ -538,9 +535,6 @@ static struct usb_serial_driver digi_acceleport_4_device = { .description = "Digi 4 port USB adapter", .usb_driver = &digi_driver, .id_table = id_table_4, - .num_interrupt_in = 0, - .num_bulk_in = 5, - .num_bulk_out = 5, .num_ports = 4, .open = digi_open, .close = digi_close, diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index a5c8e1e17ea5..2cf821771175 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -118,9 +118,6 @@ static struct usb_serial_driver empeg_device = { }, .id_table = id_table, .usb_driver = &empeg_driver, - .num_interrupt_in = 0, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = empeg_open, .close = empeg_close, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 496c0c93ad81..54b502f2924c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -439,9 +439,6 @@ static struct usb_serial_driver ftdi_sio_device = { .description = "FTDI USB Serial Device", .usb_driver = &ftdi_driver , .id_table = id_table_combined, - .num_interrupt_in = 0, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .probe = ftdi_sio_probe, .port_probe = ftdi_sio_port_probe, diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index b5194dc7d3bb..e8ba2cb5995d 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c @@ -39,9 +39,6 @@ static struct usb_serial_driver funsoft_device = { }, .id_table = id_table, .usb_driver = &funsoft_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, }; diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index d74e43d69230..87b77f92ae07 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1579,9 +1579,6 @@ static struct usb_serial_driver garmin_device = { .description = "Garmin GPS usb/tty", .usb_driver = &garmin_driver, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = garmin_open, .close = garmin_close, diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 7cfce9dabb90..5b0952054dec 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -62,9 +62,6 @@ struct usb_serial_driver usb_serial_generic_device = { }, .id_table = generic_device_ids, .usb_driver = &generic_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .shutdown = usb_serial_generic_shutdown, .throttle = usb_serial_generic_throttle, diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 6c6ebae741c9..75b88b356ebc 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -50,9 +50,6 @@ static struct usb_serial_driver hp49gp_device = { }, .id_table = id_table, .usb_driver = &hp49gp_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, }; diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 6d3008772540..2ec85893f27a 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -111,9 +111,6 @@ static struct usb_serial_driver edgeport_2port_device = { .description = "Edgeport 2 port adapter", .usb_driver = &io_driver, .id_table = edgeport_2port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 2, .open = edge_open, .close = edge_close, @@ -142,9 +139,6 @@ static struct usb_serial_driver edgeport_4port_device = { .description = "Edgeport 4 port adapter", .usb_driver = &io_driver, .id_table = edgeport_4port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 4, .open = edge_open, .close = edge_close, @@ -173,9 +167,6 @@ static struct usb_serial_driver edgeport_8port_device = { .description = "Edgeport 8 port adapter", .usb_driver = &io_driver, .id_table = edgeport_8port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 8, .open = edge_open, .close = edge_close, @@ -203,9 +194,6 @@ static struct usb_serial_driver epic_device = { }, .description = "EPiC device", .id_table = Epic_port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = edge_open, .close = edge_close, diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 316467ecd778..856e4d9afd6f 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -3032,9 +3032,6 @@ static struct usb_serial_driver edgeport_1port_device = { .description = "Edgeport TI 1 port adapter", .usb_driver = &io_driver, .id_table = edgeport_1port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = edge_open, .close = edge_close, @@ -3064,9 +3061,6 @@ static struct usb_serial_driver edgeport_2port_device = { .description = "Edgeport TI 2 port adapter", .usb_driver = &io_driver, .id_table = edgeport_2port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 2, - .num_bulk_out = 2, .num_ports = 2, .open = edge_open, .close = edge_close, diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 17f2a53b8ba4..1711dda0ea6d 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -570,9 +570,6 @@ static struct usb_serial_driver ipaq_device = { .description = "PocketPC PDA", .usb_driver = &ipaq_driver, .id_table = ipaq_id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 2, .open = ipaq_open, .close = ipaq_close, diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index cbe5530f3db2..ec0ccd14e18e 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -448,9 +448,6 @@ static struct usb_serial_driver ipw_device = { .description = "IPWireless converter", .usb_driver = &usb_ipw_driver, .id_table = usb_ipw_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = ipw_open, .close = ipw_close, diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 6b803ab98543..82e12f8d600a 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -145,9 +145,6 @@ static struct usb_serial_driver ir_device = { .description = "IR Dongle", .usb_driver = &ir_driver, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .set_termios = ir_set_termios, .attach = ir_startup, diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index a09b9a85b16d..7fee53441c24 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -1162,9 +1162,6 @@ static struct usb_serial_driver iuu_device = { .name = "iuu_phoenix", }, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = iuu_open, .close = iuu_close, diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 74ce8bca3e66..8d6ed0293bfa 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -636,10 +636,6 @@ static struct usb_serial_driver keyspan_pre_device = { }, .description = "Keyspan - (without firmware)", .id_table = keyspan_pre_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_interrupt_out = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = keyspan_fake_startup, }; @@ -651,10 +647,6 @@ static struct usb_serial_driver keyspan_1port_device = { }, .description = "Keyspan 1 port adapter", .id_table = keyspan_1port_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_interrupt_out = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .open = keyspan_open, .close = keyspan_close, @@ -679,10 +671,6 @@ static struct usb_serial_driver keyspan_2port_device = { }, .description = "Keyspan 2 port adapter", .id_table = keyspan_2port_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_interrupt_out = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 2, .open = keyspan_open, .close = keyspan_close, @@ -707,10 +695,6 @@ static struct usb_serial_driver keyspan_4port_device = { }, .description = "Keyspan 4 port adapter", .id_table = keyspan_4port_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_interrupt_out = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 4, .open = keyspan_open, .close = keyspan_close, diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index b1fa5a376e96..039847795185 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -793,9 +793,6 @@ static struct usb_serial_driver keyspan_pda_fake_device = { .description = "Keyspan PDA - (prerenumeration)", .usb_driver = &keyspan_pda_driver, .id_table = id_table_fake, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = keyspan_pda_fake_startup, }; @@ -810,9 +807,6 @@ static struct usb_serial_driver xircom_pgs_fake_device = { .description = "Xircom / Entregra PGS - (prerenumeration)", .usb_driver = &keyspan_pda_driver, .id_table = id_table_fake_xircom, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .attach = keyspan_pda_fake_startup, }; @@ -826,9 +820,6 @@ static struct usb_serial_driver keyspan_pda_device = { .description = "Keyspan PDA", .usb_driver = &keyspan_pda_driver, .id_table = id_table_std, - .num_interrupt_in = 1, - .num_bulk_in = 0, - .num_bulk_out = 1, .num_ports = 1, .open = keyspan_pda_open, .close = keyspan_pda_close, diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 55736df7d2f4..d71004283904 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -126,9 +126,6 @@ static struct usb_serial_driver kl5kusb105d_device = { .description = "KL5KUSB105D / PalmConnect", .usb_driver = &kl5kusb105d_driver, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = klsi_105_open, .close = klsi_105_close, diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 03cb5dd8cbe3..78458c807eac 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -113,10 +113,6 @@ static struct usb_serial_driver kobil_device = { .description = "KOBIL USB smart card terminal", .usb_driver = &kobil_driver, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_interrupt_out = NUM_DONT_CARE, - .num_bulk_in = 0, - .num_bulk_out = 0, .num_ports = 1, .attach = kobil_startup, .shutdown = kobil_shutdown, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index fc1cea4aba13..b9e0fbacc8a4 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -143,9 +143,6 @@ static struct usb_serial_driver mct_u232_device = { .description = "MCT U232", .usb_driver = &mct_u232_driver, .id_table = id_table_combined, - .num_interrupt_in = 2, - .num_bulk_in = 0, - .num_bulk_out = 1, .num_ports = 1, .open = mct_u232_open, .close = mct_u232_close, diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 40f3a0188807..2e14fdd08464 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1596,9 +1596,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { .description = "Moschip 2 port adapter", .usb_driver = &usb_driver, .id_table = moschip_port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 2, - .num_bulk_out = 2, .num_ports = 2, .open = mos7720_open, .close = mos7720_close, diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 0b29c5383dc8..37c4f0736bc1 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2800,12 +2800,7 @@ static struct usb_serial_driver moschip7840_4port_device = { .description = DRIVER_DESC, .usb_driver = &io_driver, .id_table = moschip_port_id_table, - .num_interrupt_in = 1, //NUM_DONT_CARE,//1, -#ifdef check - .num_bulk_in = 4, - .num_bulk_out = 4, .num_ports = 4, -#endif .open = mos7840_open, .close = mos7840_close, .write = mos7840_write, diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 7f337c9aeb5f..ddaccbcde84d 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -121,9 +121,6 @@ static struct usb_serial_driver navman_device = { }, .id_table = id_table, .usb_driver = &navman_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .open = navman_open, .close = navman_close, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index ee94d9616d82..050511ff2b17 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -95,9 +95,6 @@ static struct usb_serial_driver zyxel_omninet_device = { .description = "ZyXEL - omni.net lcd plus usb", .usb_driver = &omninet_driver, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 2, .num_ports = 1, .attach = omninet_attach, .open = omninet_open, diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 130aa96746f0..f4914209871d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -325,9 +325,6 @@ static struct usb_serial_driver option_1port_device = { .description = "GSM modem (1-port)", .usb_driver = &option_driver, .id_table = option_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .open = option_open, .close = option_close, diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 8acc907a3181..20a680ed0cc7 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -179,9 +179,6 @@ static struct usb_serial_driver oti6858_device = { .name = "oti6858", }, .id_table = id_table, - .num_interrupt_in = 1, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = oti6858_open, .close = oti6858_close, diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 2af778555bdc..1fbb4dbdf23d 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -1114,9 +1114,6 @@ static struct usb_serial_driver pl2303_device = { }, .id_table = id_table, .usb_driver = &pl2303_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = pl2303_open, .close = pl2303_close, diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 4e6dcc199be9..353c54fa0580 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -394,9 +394,6 @@ static struct usb_serial_driver safe_device = { }, .id_table = id_table, .usb_driver = &safe_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .write = safe_write, .write_room = safe_write_room, diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f791eb8887fc..07eabaf9f044 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -746,9 +746,6 @@ static struct usb_serial_driver sierra_device = { .description = "Sierra USB modem", .id_table = id_table, .usb_driver = &sierra_driver, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .calc_num_ports = sierra_calc_num_ports, .probe = sierra_probe, .open = sierra_open, diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 1b46b846f100..2282d620186e 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -1022,9 +1022,6 @@ static struct usb_serial_driver spcp8x5_device = { .name = "SPCP8x5", }, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = spcp8x5_open, .close = spcp8x5_close, diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 5b470f76e91b..f3bbf777c81a 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -264,9 +264,6 @@ static struct usb_serial_driver ti_1port_device = { .description = "TI USB 3410 1 port adapter", .usb_driver = &ti_usb_driver, .id_table = ti_id_table_3410, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = 1, .num_ports = 1, .attach = ti_startup, .shutdown = ti_shutdown, @@ -295,9 +292,6 @@ static struct usb_serial_driver ti_2port_device = { .description = "TI USB 5052 2 port adapter", .usb_driver = &ti_usb_driver, .id_table = ti_id_table_5052, - .num_interrupt_in = 1, - .num_bulk_in = 2, - .num_bulk_out = 2, .num_ports = 2, .attach = ti_startup, .shutdown = ti_shutdown, diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 257a5e436873..f9fc926b56d8 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c @@ -35,9 +35,6 @@ static struct usb_serial_driver debug_device = { .name = "debug", }, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, }; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index c2b01f7c3197..f2d59b06c364 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -189,9 +189,6 @@ static struct usb_serial_driver handspring_device = { .description = "Handspring Visor / Palm OS", .usb_driver = &visor_driver, .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 2, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 2, .open = visor_open, .close = visor_close, @@ -219,9 +216,6 @@ static struct usb_serial_driver clie_5_device = { .description = "Sony Clie 5.0", .usb_driver = &visor_driver, .id_table = clie_id_5_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 2, - .num_bulk_out = 2, .num_ports = 2, .open = visor_open, .close = visor_close, @@ -249,9 +243,6 @@ static struct usb_serial_driver clie_3_5_device = { .description = "Sony Clie 3.5", .usb_driver = &visor_driver, .id_table = clie_id_3_5_table, - .num_interrupt_in = 0, - .num_bulk_in = 1, - .num_bulk_out = 1, .num_ports = 1, .open = visor_open, .close = visor_close, diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 38726ef3132b..c5af57be62f4 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -164,9 +164,6 @@ static struct usb_serial_driver whiteheat_fake_device = { .description = "Connect Tech - WhiteHEAT - (prerenumeration)", .usb_driver = &whiteheat_driver, .id_table = id_table_prerenumeration, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, .probe = whiteheat_firmware_download, .attach = whiteheat_firmware_attach, @@ -180,9 +177,6 @@ static struct usb_serial_driver whiteheat_device = { .description = "Connect Tech - WhiteHEAT", .usb_driver = &whiteheat_driver, .id_table = id_table_std, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, .num_ports = 4, .attach = whiteheat_attach, .shutdown = whiteheat_shutdown, -- cgit v1.2.2 From 9aebfd6bda789891e6d296bb49b5fb32d1057f18 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 16 Apr 2008 09:17:38 -0700 Subject: USB: serial: remove endpoints setting checks from core and header Remove the unused check for num_interrupt and friends as well as remove them from the header file because no usb-serial drivers no longer reference them. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index aea861e9173e..5b464811fa4d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -861,22 +861,6 @@ int usb_serial_probe(struct usb_interface *interface, serial->num_interrupt_in = num_interrupt_in; serial->num_interrupt_out = num_interrupt_out; -#if 0 - /* check that the device meets the driver's requirements */ - if ((type->num_interrupt_in != NUM_DONT_CARE && - type->num_interrupt_in != num_interrupt_in) - || (type->num_interrupt_out != NUM_DONT_CARE && - type->num_interrupt_out != num_interrupt_out) - || (type->num_bulk_in != NUM_DONT_CARE && - type->num_bulk_in != num_bulk_in) - || (type->num_bulk_out != NUM_DONT_CARE && - type->num_bulk_out != num_bulk_out)) { - dbg("wrong number of endpoints"); - kfree(serial); - return -EIO; - } -#endif - /* found all that we need */ dev_info(&interface->dev, "%s converter detected\n", type->description); -- cgit v1.2.2 From b950bdbc67041412cb042e404938667204c7902c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2008 11:45:29 -0400 Subject: USB: g_file_storage: ignore bulk-out data after invalid CBW This patch (as1061) makes g_file_storage more compliant with the Bulk-Only Transport specification. After an invalid CBW is received, the gadget must ignore any further bulk-OUT data until it is reset. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 017a196d041f..0a726e106ccd 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -644,7 +644,7 @@ struct fsg_dev { unsigned long atomic_bitflags; #define REGISTERED 0 -#define CLEAR_BULK_HALTS 1 +#define IGNORE_BULK_OUT 1 #define SUSPENDED 2 struct usb_ep *bulk_in; @@ -2936,8 +2936,8 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) struct usb_request *req = bh->outreq; struct bulk_cb_wrap *cbw = req->buf; - /* Was this a real packet? */ - if (req->status) + /* Was this a real packet? Should it be ignored? */ + if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) return -EINVAL; /* Is the CBW valid? */ @@ -2948,13 +2948,17 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) req->actual, le32_to_cpu(cbw->Signature)); - /* The Bulk-only spec says we MUST stall the bulk pipes! - * If we want to avoid stalls, set a flag so that we will - * clear the endpoint halts at the next reset. */ - if (!mod_data.can_stall) - set_bit(CLEAR_BULK_HALTS, &fsg->atomic_bitflags); - fsg_set_halt(fsg, fsg->bulk_out); + /* The Bulk-only spec says we MUST stall the IN endpoint + * (6.6.1), so it's unavoidable. It also says we must + * retain this state until the next reset, but there's + * no way to tell the controller driver it should ignore + * Clear-Feature(HALT) requests. + * + * We aren't required to halt the OUT endpoint; instead + * we can simply accept and discard any data received + * until the next reset. */ halt_bulk_in_endpoint(fsg); + set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); return -EINVAL; } @@ -3140,6 +3144,7 @@ reset: goto reset; fsg->bulk_out_enabled = 1; fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); + clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); if (transport_is_cbi()) { d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc); @@ -3321,11 +3326,8 @@ static void handle_exception(struct fsg_dev *fsg) /* In case we were forced against our will to halt a * bulk endpoint, clear the halt now. (The SuperH UDC * requires this.) */ - if (test_and_clear_bit(CLEAR_BULK_HALTS, - &fsg->atomic_bitflags)) { + if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) usb_ep_clear_halt(fsg->bulk_in); - usb_ep_clear_halt(fsg->bulk_out); - } if (transport_is_bbb()) { if (fsg->ep0_req_tag == exception_req_tag) -- cgit v1.2.2 From 58a97ffeb2297f154659f339d77eb3f32c4d8b3e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2008 12:17:10 -0400 Subject: USB: HCDs use the do_remote_wakeup flag When a USB device is suspended, whether or not it is enabled for remote wakeup depends on the device_may_wakeup() setting. The setting is then saved in the do_remote_wakeup flag. Later on, however, the device_may_wakeup() value can change because of user activity. So when testing whether a suspended device is or should be enabled for remote wakeup, we should always test do_remote_wakeup instead of device_may_wakeup(). This patch (as1076) makes that change for root hubs in several places. The patch also adjusts uhci-hcd so that when an autostopped controller is suspended, the remote wakeup setting agrees with the value recorded in the root hub's do_remote_wakeup flag. And the patch adjusts ehci-hcd so that wakeup events on selectively suspended ports (i.e., the bus itself isn't suspended) don't turn on the PME# wakeup signal. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 1 - drivers/usb/host/ehci-hub.c | 17 +++++++---------- drivers/usb/host/ehci-pci.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/ohci-hub.c | 5 ++--- drivers/usb/host/uhci-hcd.c | 21 +++++++-------------- 6 files changed, 18 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 2ea333a43d65..edc31e13e95e 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -932,7 +932,6 @@ static int autosuspend_check(struct usb_device *udev, int reschedule) * is disabled. Also fail if any interfaces require remote wakeup * but it isn't available. */ - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); if (udev->pm_usage_cnt > 0) return -EBUSY; if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 21ac3781f21a..536b433d24f7 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -30,6 +30,8 @@ #ifdef CONFIG_PM +#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) + static int ehci_hub_control( struct usb_hcd *hcd, u16 typeReq, @@ -149,10 +151,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) } /* enable remote wakeup on all ports */ - if (device_may_wakeup(&hcd->self.root_hub->dev)) - t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; + if (hcd->self.root_hub->do_remote_wakeup) + t2 |= PORT_WAKE_BITS; else - t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); + t2 &= ~PORT_WAKE_BITS; if (t1 != t2) { ehci_vdbg (ehci, "port %d, %08x -> %08x\n", @@ -174,7 +176,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) /* allow remote wakeup */ mask = INTR_MASK; - if (!device_may_wakeup(&hcd->self.root_hub->dev)) + if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); @@ -232,8 +234,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) i = HCS_N_PORTS (ehci->hcs_params); while (i--) { temp = ehci_readl(ehci, &ehci->regs->port_status [i]); - temp &= ~(PORT_RWC_BITS - | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); + temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); if (test_bit(i, &ehci->bus_suspended) && (temp & PORT_SUSPEND)) { ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); @@ -534,8 +535,6 @@ ehci_hub_descriptor ( /*-------------------------------------------------------------------------*/ -#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) - static int ehci_hub_control ( struct usb_hcd *hcd, u16 typeReq, @@ -801,8 +800,6 @@ static int ehci_hub_control ( if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) goto error; - if (device_may_wakeup(&hcd->self.root_hub->dev)) - temp |= PORT_WAKE_BITS; ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); break; case USB_PORT_FEAT_POWER: diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index a0afc78b273e..88dad4b53131 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -300,7 +300,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd) if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; - if (!device_may_wakeup(&hcd->self.root_hub->dev)) + if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 66d773c726f6..20b9a0d07420 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1400,7 +1400,7 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd) spin_unlock_irqrestore(&isp116x->lock, flags); val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); val |= HCCONTROL_USB_SUSPEND; - if (device_may_wakeup(&hcd->self.root_hub->dev)) + if (hcd->self.root_hub->do_remote_wakeup) val |= HCCONTROL_RWE; /* Wait for usb transfers to finish */ msleep(2); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 28d6d775eb5f..cf3e1d255639 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -103,10 +103,9 @@ __acquires(ohci->lock) finish_unlinks (ohci, ohci_frame_no(ohci)); /* maybe resume can wake root hub */ - if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) || - autostop) + if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) { ohci->hc_control |= OHCI_CTRL_RWE; - else { + } else { ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); ohci->hc_control &= ~OHCI_CTRL_RWE; } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index fec9872dd9dc..f65d5a858733 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -262,20 +262,12 @@ __acquires(uhci->lock) { int auto_stop; int int_enable, egsm_enable; + struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); - dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, - "%s%s\n", __FUNCTION__, + dev_dbg(&rhdev->dev, "%s%s\n", __func__, (auto_stop ? " (auto-stop)" : "")); - /* If we get a suspend request when we're already auto-stopped - * then there's nothing to do. - */ - if (uhci->rh_state == UHCI_RH_AUTO_STOPPED) { - uhci->rh_state = new_state; - return; - } - /* Enable resume-detect interrupts if they work. * Then enter Global Suspend mode if _it_ works, still configured. */ @@ -285,8 +277,10 @@ __acquires(uhci->lock) if (remote_wakeup_is_broken(uhci)) egsm_enable = 0; if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || - !device_may_wakeup( - &uhci_to_hcd(uhci)->self.root_hub->dev)) +#ifdef CONFIG_PM + (!auto_stop && !rhdev->do_remote_wakeup) || +#endif + (auto_stop && !device_may_wakeup(&rhdev->dev))) uhci->working_RD = int_enable = 0; outw(int_enable, uhci->io_addr + USBINTR); @@ -308,8 +302,7 @@ __acquires(uhci->lock) return; } if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) - dev_warn(&uhci_to_hcd(uhci)->self.root_hub->dev, - "Controller not stopped yet!\n"); + dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n"); uhci_get_current_frame_number(uhci); -- cgit v1.2.2 From 5f47493cdf90b8afe5353e59de30e449e775ea8b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2008 12:17:49 -0400 Subject: USB: OHCI: turn off RD when remote wakeup is disabled This patch (as1068b) disables the RD interrupt flag when an OHCI root hub is suspended with remote wakeup disabled. Although the spec clearly states that this flag permits the controller to issue an interrupt when a resume request from downstream is detected and not when a local status change occurs, some controllers mistakenly use it for both types of event. 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 cf3e1d255639..355a82f25274 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -106,7 +106,8 @@ __acquires(ohci->lock) if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) { ohci->hc_control |= OHCI_CTRL_RWE; } else { - ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); + ohci_writel(ohci, OHCI_INTR_RHSC | OHCI_INTR_RD, + &ohci->regs->intrdisable); ohci->hc_control &= ~OHCI_CTRL_RWE; } -- cgit v1.2.2 From e872154921a6b5256a3c412dd69158ac0b135176 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2008 12:17:56 -0400 Subject: USB: don't explicitly reenable root-hub status interrupts This patch (as1069b) changes the way OHCI root-hub status-change interrupts are enabled. Currently a special HCD method, hub_irq_enable(), is called when the hub driver is finished using a root hub. This approach turns out to be subject to races, resulting in unnecessary polling. The patch does away with the method entirely. Instead, the driver automatically enables the RHSC interrupt when no more status changes are present. This scheme is safe with controllers using level-triggered semantics for their interrupt flags. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 9 ------- drivers/usb/core/hcd.h | 2 -- drivers/usb/core/hub.c | 9 ------- drivers/usb/host/ohci-at91.c | 1 - drivers/usb/host/ohci-au1xxx.c | 1 - drivers/usb/host/ohci-ep93xx.c | 1 - drivers/usb/host/ohci-hub.c | 53 ++++++++++++++++++++++++----------------- drivers/usb/host/ohci-lh7a404.c | 1 - drivers/usb/host/ohci-omap.c | 1 - drivers/usb/host/ohci-pci.c | 1 - drivers/usb/host/ohci-pnx4008.c | 1 - drivers/usb/host/ohci-pnx8550.c | 1 - drivers/usb/host/ohci-ppc-of.c | 1 - drivers/usb/host/ohci-ppc-soc.c | 1 - drivers/usb/host/ohci-ps3.c | 1 - drivers/usb/host/ohci-pxa27x.c | 1 - drivers/usb/host/ohci-s3c2410.c | 1 - drivers/usb/host/ohci-sa1111.c | 1 - drivers/usb/host/ohci-sh.c | 1 - drivers/usb/host/ohci-sm501.c | 1 - drivers/usb/host/ohci-ssb.c | 1 - drivers/usb/host/u132-hcd.c | 11 --------- 22 files changed, 31 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e68fef5361d2..bf10e9c4195e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -924,15 +924,6 @@ static int register_root_hub(struct usb_hcd *hcd) return retval; } -void usb_enable_root_hub_irq (struct usb_bus *bus) -{ - struct usb_hcd *hcd; - - hcd = container_of (bus, struct usb_hcd, self); - if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT) - hcd->driver->hub_irq_enable (hcd); -} - /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 3ba258eb05de..1e4b81e9eb50 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -210,8 +210,6 @@ struct hc_driver { int (*bus_suspend)(struct usb_hcd *); int (*bus_resume)(struct usb_hcd *); int (*start_port_reset)(struct usb_hcd *, unsigned port_num); - void (*hub_irq_enable)(struct usb_hcd *); - /* Needed only if port-change IRQs are level-triggered */ /* force handover of high-speed port to full-speed companion */ void (*relinquish_port)(struct usb_hcd *, int); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1e23e360ea91..5a338a5d4fe7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2001,8 +2001,6 @@ int usb_port_resume(struct usb_device *udev) } clear_bit(port1, hub->busy_bits); - if (!hub->hdev->parent && !hub->busy_bits[0]) - usb_enable_root_hub_irq(hub->hdev->bus); if (status == 0) status = finish_port_resume(udev); @@ -2918,11 +2916,6 @@ static void hub_events(void) hub->activating = 0; - /* If this is a root hub, tell the HCD it's okay to - * re-enable port-change interrupts now. */ - if (!hdev->parent && !hub->busy_bits[0]) - usb_enable_root_hub_irq(hdev->bus); - loop_autopm: /* Allow autosuspend if we're not going to run again */ if (list_empty(&hub->event_list)) @@ -3148,8 +3141,6 @@ int usb_reset_device(struct usb_device *udev) break; } clear_bit(port1, parent_hub->busy_bits); - if (!parent_hdev->parent && !parent_hub->busy_bits[0]) - usb_enable_root_hub_irq(parent_hdev->bus); if (ret < 0) goto re_enumerate; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e534f9de0f05..c96db1153dcf 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -261,7 +261,6 @@ static const struct hc_driver ohci_at91_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index f90fe0c7373f..1b9abdba920b 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -288,7 +288,6 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 5adaf36e47d0..06aadfb0ec29 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -135,7 +135,6 @@ static struct hc_driver ohci_ep93xx_hc_driver = { .get_frame_number = ohci_get_frame, .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 355a82f25274..5be3bb3e6a9d 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -36,18 +36,6 @@ /*-------------------------------------------------------------------------*/ -/* hcd->hub_irq_enable() */ -static void ohci_rhsc_enable (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - - spin_lock_irq(&ohci->lock); - if (!ohci->autostop) - del_timer(&hcd->rh_timer); /* Prevent next poll */ - ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); - spin_unlock_irq(&ohci->lock); -} - #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) @@ -374,18 +362,28 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected) { int poll_rh = 1; + int rhsc; + rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC; switch (ohci->hc_control & OHCI_CTRL_HCFS) { case OHCI_USB_OPER: - /* keep on polling until we know a device is connected - * and RHSC is enabled */ + /* If no status changes are pending, enable status-change + * interrupts. + */ + if (!rhsc && !changed) { + rhsc = OHCI_INTR_RHSC; + ohci_writel(ohci, rhsc, &ohci->regs->intrenable); + } + + /* Keep on polling until we know a device is connected + * and RHSC is enabled, or until we autostop. + */ if (!ohci->autostop) { if (any_connected || !device_may_wakeup(&ohci_to_hcd(ohci) ->self.root_hub->dev)) { - if (ohci_readl(ohci, &ohci->regs->intrenable) & - OHCI_INTR_RHSC) + if (rhsc) poll_rh = 0; } else { ohci->autostop = 1; @@ -398,12 +396,13 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, ohci->autostop = 0; ohci->next_statechange = jiffies + STATECHANGE_DELAY; - } else if (time_after_eq(jiffies, + } else if (rhsc && time_after_eq(jiffies, ohci->next_statechange) && !ohci->ed_rm_list && !(ohci->hc_control & OHCI_SCHED_ENABLES)) { ohci_rh_suspend(ohci, 1); + poll_rh = 0; } } break; @@ -417,6 +416,12 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, else usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); } else { + if (!rhsc && (ohci->autostop || + ohci_to_hcd(ohci)->self.root_hub-> + do_remote_wakeup)) + ohci_writel(ohci, OHCI_INTR_RHSC, + &ohci->regs->intrenable); + /* everything is idle, no need for polling */ poll_rh = 0; } @@ -438,12 +443,16 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci) static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected) { - int poll_rh = 1; - - /* keep on polling until RHSC is enabled */ + /* If RHSC is enabled, don't poll */ if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) - poll_rh = 0; - return poll_rh; + return 0; + + /* If no status changes are pending, enable status-change interrupts */ + if (!changed) { + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); + return 0; + } + return 1; } #endif /* CONFIG_PM */ diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 13c12ed22252..96d14fa1d833 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -193,7 +193,6 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 3a7c24c03671..6859fb5f1d6f 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -466,7 +466,6 @@ static const struct hc_driver ohci_omap_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 4696cc912e16..3bf175d95a23 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -327,7 +327,6 @@ static const struct hc_driver ohci_pci_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 28b458f20cc3..664f07ee8732 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c @@ -280,7 +280,6 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c index 605d59cba28e..28467e288a93 100644 --- a/drivers/usb/host/ohci-pnx8550.c +++ b/drivers/usb/host/ohci-pnx8550.c @@ -201,7 +201,6 @@ static const struct hc_driver ohci_pnx8550_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index a67252791223..50e55db13636 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -72,7 +72,6 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 523c30125577..cd3398b675b2 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c @@ -172,7 +172,6 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index c1935ae537f8..bfdeb0d22d05 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -68,7 +68,6 @@ static const struct hc_driver ps3_ohci_hc_driver = { .get_frame_number = ohci_get_frame, .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, .start_port_reset = ohci_start_port_reset, #if defined(CONFIG_PM) .bus_suspend = ohci_bus_suspend, diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index d4ee27d92be8..70b0d4b459e7 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -298,7 +298,6 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index ead4772f0f27..a73d2ff322e2 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -466,7 +466,6 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { */ .hub_status_data = ohci_s3c2410_hub_status_data, .hub_control = ohci_s3c2410_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 0f48f2d99226..99438c65981b 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -231,7 +231,6 @@ static const struct hc_driver ohci_sa1111_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index e7ee607278fe..60f03cc7ec4f 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c @@ -68,7 +68,6 @@ static const struct hc_driver ohci_sh_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 4a11e1816017..77204f001b9a 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -75,7 +75,6 @@ static const struct hc_driver ohci_sm501_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index 7275186db315..c4265caec780 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c @@ -81,7 +81,6 @@ static const struct hc_driver ssb_ohci_hc_driver = { .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, #ifdef CONFIG_PM .bus_suspend = ohci_bus_suspend, .bus_resume = ohci_bus_resume, diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 9b6323f768b2..f29307405bb3 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2934,16 +2934,6 @@ static int u132_start_port_reset(struct usb_hcd *hcd, unsigned port_num) return 0; } -static void u132_hub_irq_enable(struct usb_hcd *hcd) -{ - struct u132 *u132 = hcd_to_u132(hcd); - if (u132->going > 1) { - dev_err(&u132->platform_dev->dev, "device has been removed %d\n" - , u132->going); - } else if (u132->going > 0) - dev_err(&u132->platform_dev->dev, "device is being removed\n"); -} - #ifdef CONFIG_PM static int u132_bus_suspend(struct usb_hcd *hcd) @@ -2995,7 +2985,6 @@ static struct hc_driver u132_hc_driver = { .bus_suspend = u132_bus_suspend, .bus_resume = u132_bus_resume, .start_port_reset = u132_start_port_reset, - .hub_irq_enable = u132_hub_irq_enable, }; /* -- cgit v1.2.2 From c6dbf554bc8a79c9caab3dbf891a33c19068f646 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 13 Apr 2008 14:00:44 -0700 Subject: USB: cdc-acm: signedness fix Fix bogus assignment of "unsigned char *" to "char *": preserve unsignedness. These values are used directly as descriptor lengths when iterating through the buffer, so this *could* cause oddness that potentially includes oopsing. (IMO not likely, except as part of a malicious device...) Fix the bogus warning in CDC ACM which highlighted this problem (by showing a negative descriptor type). It uses the undesirable legacy err() for something that's not even an error; switch to use dev_dbg, and show descriptor types in hex notation to match the convention for such codes. Signed-off-by: David Brownell Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d9b408113921..6d57413ac0f5 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -804,7 +804,7 @@ static int acm_probe (struct usb_interface *intf, { struct usb_cdc_union_desc *union_header = NULL; struct usb_cdc_country_functional_desc *cfd = NULL; - char *buffer = intf->altsetting->extra; + unsigned char *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; struct usb_interface *control_interface; struct usb_interface *data_interface; @@ -881,9 +881,13 @@ static int acm_probe (struct usb_interface *intf, if ((call_management_function & 3) != 3) err("This device cannot do calls on its own. It is no modem."); break; - default: - err("Ignoring extra header, type %d, length %d", buffer[2], buffer[0]); + /* there are LOTS more CDC descriptors that + * could legitimately be found here. + */ + dev_dbg(&intf->dev, "Ignoring descriptor: " + "type %02x, length %d\n", + buffer[2], buffer[0]); break; } next_desc: -- cgit v1.2.2 From 4f6676274fb6303a8e8100d086ea8c2c00c0d8e3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 12 Apr 2008 08:32:05 -0700 Subject: USB: ehci: qh_completions cleanup and bugfix Simplify processing of completed qtds, and correct handling of short reads, by removing two state variables: - "qtd_status" wasn't needed. The current URB's status is either OK (-EINPROGRESS) or some fault status. Once a fault appears, the queue halts and any later QTDs are immediately removed, so no temporary status is needed. (Or for typical short reads, it's not treated as a fault, so no queue halt is needed.) - "do_status" was erroneous. Because of how the queue is set up, short control reads can (and should!) be treated like full size reads, and cleaned up the usual way. The status stage will be executed transparently, and usbcore handles the choice of whether to report this status as unexected. The "do_status" problem caused a rather perplexing timing-dependent problem with usbtest case 10. Sometimes it would make the controller skip a dozen transactions while (wrongly) trying to clean up after a short transfer. Fortunately, removing a dcache contention issue made this become trivial to reproduce (on one test rig), so enough clues finally presented themselves ... I think this has been around for a very long time, but was worsened by recent urb->status changes. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 64942ec584c2..315c7c14aaa8 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -242,7 +242,8 @@ __acquires(ehci->lock) if (unlikely(urb->unlinked)) { COUNT(ehci->stats.unlink); } else { - if (likely(status == -EINPROGRESS)) + /* report non-error and short read status as zero */ + if (status == -EINPROGRESS || status == -EREMOTEIO) status = 0; COUNT(ehci->stats.complete); } @@ -283,7 +284,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) int last_status = -EINPROGRESS; int stopped; unsigned count = 0; - int do_status = 0; u8 state; u32 halt = HALT_BIT(ehci); @@ -309,7 +309,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) struct ehci_qtd *qtd; struct urb *urb; u32 token = 0; - int qtd_status; qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb; @@ -377,13 +376,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) else if (last_status == -EINPROGRESS && !urb->unlinked) continue; - /* issue status after short control reads */ - if (unlikely (do_status != 0) - && QTD_PID (token) == 0 /* OUT */) { - do_status = 0; - continue; - } - /* qh unlinked; token in overlay may be most current */ if (state == QH_STATE_IDLE && cpu_to_hc32(ehci, qtd->qtd_dma) @@ -401,15 +393,21 @@ halt: } } - /* remove it from the queue */ - qtd_status = qtd_copy_status(ehci, urb, qtd->length, token); - if (unlikely(qtd_status == -EREMOTEIO)) { - do_status = (!urb->unlinked && - usb_pipecontrol(urb->pipe)); - qtd_status = 0; + /* unless we already know the urb's status, collect qtd status + * and update count of bytes transferred. in common short read + * cases with only one data qtd (including control transfers), + * queue processing won't halt. but with two or more qtds (for + * example, with a 32 KB transfer), when the first qtd gets a + * short read the second must be removed by hand. + */ + if (last_status == -EINPROGRESS) { + last_status = qtd_copy_status(ehci, urb, + qtd->length, token); + if (last_status == -EREMOTEIO + && (qtd->hw_alt_next + & EHCI_LIST_END(ehci))) + last_status = -EINPROGRESS; } - if (likely(last_status == -EINPROGRESS)) - last_status = qtd_status; /* if we're removing something not at the queue head, * patch the hardware queue pointer. -- cgit v1.2.2 From aff6d18f95bb81b2d07994372c8edcc2c2b41180 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 18 Apr 2008 11:11:26 -0400 Subject: USB: fix compile problems in ehci-hcd This patch (as1072) fixes some recently-introduced compile problems that show up in ehci-hcd when CONFIG_PM is turned off. PORT_WAKE_BITS needs to be defined always. ehci_port_power() is called during initialization by all the EHCI variants other than the PCI version, in which it is "defined but not used". So add a call to it. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 4 ++-- drivers/usb/host/ehci-pci.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 536b433d24f7..efffef64f59d 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -28,10 +28,10 @@ /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_PM - #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) +#ifdef CONFIG_PM + static int ehci_hub_control( struct usb_hcd *hcd, u16 typeReq, diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 88dad4b53131..5bb7f6bb13f3 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -222,6 +222,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif + ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; -- cgit v1.2.2 From 14722ef4acedc643f0b78b7165ceff2d300dae4d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 17 Apr 2008 10:18:11 -0400 Subject: USB: usbfs: export the URB_NO_INTERRUPT flag to userspace This patch (as1079) cleans up the way URB_* flags are exported in usbfs. The URB_NO_INTERRUPT flag is now exported (this is the only behavioral change). USBDEVFS_URB_* macros are added for URB_NO_FSBR, URB_ZERO_PACKET, and URB_NO_INTERRUPT, making explicit the fact that the kernel accepts them. The flag matching takes into account that the URB_* values may change as the kernel evolves, whereas the USBDEVFS_URB_* values must remain fixed since they are a user API. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 039ba23cc8b6..6c4cd82d7d14 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -948,8 +948,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, int ret, ifnum = -1; int is_in; - if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| - URB_NO_FSBR|URB_ZERO_PACKET)) + if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | + USBDEVFS_URB_SHORT_NOT_OK | + USBDEVFS_URB_NO_FSBR | + USBDEVFS_URB_ZERO_PACKET | + USBDEVFS_URB_NO_INTERRUPT)) return -EINVAL; if (!uurb->buffer) return -EINVAL; @@ -1104,8 +1107,24 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, as->urb->pipe = (uurb->type << 30) | __create_pipe(ps->dev, uurb->endpoint & 0xf) | (uurb->endpoint & USB_DIR_IN); - as->urb->transfer_flags = uurb->flags | - (is_in ? URB_DIR_IN : URB_DIR_OUT); + + /* This tedious sequence is necessary because the URB_* flags + * are internal to the kernel and subject to change, whereas + * the USBDEVFS_URB_* flags are a user API and must not be changed. + */ + u = (is_in ? URB_DIR_IN : URB_DIR_OUT); + if (uurb->flags & USBDEVFS_URB_ISO_ASAP) + u |= URB_ISO_ASAP; + if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) + u |= URB_SHORT_NOT_OK; + if (uurb->flags & USBDEVFS_URB_NO_FSBR) + u |= URB_NO_FSBR; + if (uurb->flags & USBDEVFS_URB_ZERO_PACKET) + u |= URB_ZERO_PACKET; + if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) + u |= URB_NO_INTERRUPT; + as->urb->transfer_flags = u; + as->urb->transfer_buffer_length = uurb->buffer_length; as->urb->setup_packet = (unsigned char *)dr; as->urb->start_frame = uurb->start_frame; -- cgit v1.2.2 From 441b62c1edb986827154768d89bbac0ba779984f Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Mon, 3 Mar 2008 16:08:34 -0800 Subject: USB: replace remaining __FUNCTION__ occurrences __FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 6 +- drivers/usb/class/cdc-acm.c | 6 +- drivers/usb/core/devio.c | 42 ++-- drivers/usb/core/driver.c | 30 +-- drivers/usb/core/hub.c | 8 +- drivers/usb/core/inode.c | 4 +- drivers/usb/core/message.c | 8 +- drivers/usb/core/urb.c | 2 +- drivers/usb/gadget/at91_udc.c | 4 +- drivers/usb/gadget/dummy_hcd.c | 12 +- drivers/usb/gadget/ether.c | 12 +- drivers/usb/gadget/file_storage.c | 8 +- drivers/usb/gadget/fsl_usb2_udc.c | 4 +- drivers/usb/gadget/fsl_usb2_udc.h | 2 +- drivers/usb/gadget/goku_udc.c | 20 +- drivers/usb/gadget/inode.c | 18 +- drivers/usb/gadget/lh7a40x_udc.c | 132 ++++++------ drivers/usb/gadget/net2280.h | 2 +- drivers/usb/gadget/omap_udc.c | 16 +- drivers/usb/gadget/printer.c | 6 +- drivers/usb/gadget/pxa2xx_udc.c | 26 +-- drivers/usb/gadget/rndis.c | 146 ++++++------- drivers/usb/host/ehci-q.c | 4 +- drivers/usb/host/ehci-sched.c | 2 +- drivers/usb/host/pci-quirks.c | 6 +- drivers/usb/host/sl811-hcd.c | 4 +- drivers/usb/host/uhci-hcd.c | 6 +- drivers/usb/host/uhci-q.c | 2 +- drivers/usb/misc/adutux.c | 120 +++++------ drivers/usb/misc/appledisplay.c | 6 +- drivers/usb/misc/auerswald.c | 8 +- drivers/usb/misc/emi26.c | 30 +-- drivers/usb/misc/emi62.c | 32 +-- drivers/usb/misc/iowarrior.c | 6 +- drivers/usb/misc/ldusb.c | 10 +- drivers/usb/misc/legousbtower.c | 88 ++++---- drivers/usb/misc/phidgetkit.c | 6 +- drivers/usb/misc/phidgetmotorcontrol.c | 2 +- drivers/usb/misc/phidgetservo.c | 6 +- drivers/usb/misc/usblcd.c | 6 +- drivers/usb/misc/usbtest.c | 4 +- drivers/usb/serial/aircable.c | 52 ++--- drivers/usb/serial/airprime.c | 34 +-- drivers/usb/serial/ark3116.c | 6 +- drivers/usb/serial/belkin_sa.c | 18 +- drivers/usb/serial/console.c | 10 +- drivers/usb/serial/cp2101.c | 108 +++++----- drivers/usb/serial/cyberjack.c | 72 +++---- drivers/usb/serial/cypress_m8.c | 128 ++++++------ drivers/usb/serial/digi_acceleport.c | 36 ++-- drivers/usb/serial/empeg.c | 54 ++--- drivers/usb/serial/ezusb.c | 8 +- drivers/usb/serial/ftdi_sio.c | 156 +++++++------- drivers/usb/serial/garmin_gps.c | 106 +++++----- drivers/usb/serial/generic.c | 44 ++-- drivers/usb/serial/io_edgeport.c | 318 ++++++++++++++-------------- drivers/usb/serial/io_ti.c | 364 ++++++++++++++++----------------- drivers/usb/serial/ipaq.c | 44 ++-- drivers/usb/serial/ipw.c | 48 ++--- drivers/usb/serial/ir-usb.c | 46 ++--- drivers/usb/serial/iuu_phoenix.c | 128 ++++++------ drivers/usb/serial/keyspan.c | 234 ++++++++++----------- drivers/usb/serial/keyspan_pda.c | 20 +- drivers/usb/serial/kl5kusb105.c | 78 +++---- drivers/usb/serial/kobil_sct.c | 56 ++--- drivers/usb/serial/mct_u232.c | 36 ++-- drivers/usb/serial/mos7720.c | 118 +++++------ drivers/usb/serial/mos7840.c | 150 +++++++------- drivers/usb/serial/navman.c | 18 +- drivers/usb/serial/omninet.c | 32 +-- drivers/usb/serial/option.c | 64 +++--- drivers/usb/serial/oti6858.c | 108 +++++----- drivers/usb/serial/pl2303.c | 106 +++++----- drivers/usb/serial/safe_serial.c | 28 +-- drivers/usb/serial/sierra.c | 62 +++--- drivers/usb/serial/ti_usb_3410_5052.c | 190 ++++++++--------- drivers/usb/serial/usb-serial.c | 78 +++---- drivers/usb/serial/visor.c | 86 ++++---- drivers/usb/serial/whiteheat.c | 104 +++++----- drivers/usb/storage/scsiglue.c | 10 +- drivers/usb/storage/transport.c | 18 +- drivers/usb/storage/usb.c | 16 +- drivers/usb/usb-skeleton.c | 6 +- 83 files changed, 2130 insertions(+), 2130 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index c5ec1a55eee3..abb7d7410e63 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -83,7 +83,7 @@ if (debug >= 1) \ dev_dbg(&(usb_dev)->dev, \ "[ueagle-atm dbg] %s: " format, \ - __FUNCTION__, ##args); \ + __func__, ##args); \ } while (0) #define uea_vdbg(usb_dev, format, args...) \ @@ -94,10 +94,10 @@ } while (0) #define uea_enters(usb_dev) \ - uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) + uea_vdbg(usb_dev, "entering %s\n", __func__) #define uea_leaves(usb_dev) \ - uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__) + uea_vdbg(usb_dev, "leaving %s\n", __func__) #define uea_err(usb_dev, format,args...) \ dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6d57413ac0f5..33cdf8fa2f20 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -260,10 +260,10 @@ static void acm_ctrl_irq(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } @@ -307,7 +307,7 @@ exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __func__, retval); } /* data interface returns incoming bytes, or we got unthrottled */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6c4cd82d7d14..de17738f3acb 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1530,60 +1530,60 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, switch (cmd) { case USBDEVFS_CONTROL: - snoop(&dev->dev, "%s: CONTROL\n", __FUNCTION__); + snoop(&dev->dev, "%s: CONTROL\n", __func__); ret = proc_control(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; break; case USBDEVFS_BULK: - snoop(&dev->dev, "%s: BULK\n", __FUNCTION__); + snoop(&dev->dev, "%s: BULK\n", __func__); ret = proc_bulk(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; break; case USBDEVFS_RESETEP: - snoop(&dev->dev, "%s: RESETEP\n", __FUNCTION__); + snoop(&dev->dev, "%s: RESETEP\n", __func__); ret = proc_resetep(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; break; case USBDEVFS_RESET: - snoop(&dev->dev, "%s: RESET\n", __FUNCTION__); + snoop(&dev->dev, "%s: RESET\n", __func__); ret = proc_resetdevice(ps); break; case USBDEVFS_CLEAR_HALT: - snoop(&dev->dev, "%s: CLEAR_HALT\n", __FUNCTION__); + snoop(&dev->dev, "%s: CLEAR_HALT\n", __func__); ret = proc_clearhalt(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; break; case USBDEVFS_GETDRIVER: - snoop(&dev->dev, "%s: GETDRIVER\n", __FUNCTION__); + snoop(&dev->dev, "%s: GETDRIVER\n", __func__); ret = proc_getdriver(ps, p); break; case USBDEVFS_CONNECTINFO: - snoop(&dev->dev, "%s: CONNECTINFO\n", __FUNCTION__); + snoop(&dev->dev, "%s: CONNECTINFO\n", __func__); ret = proc_connectinfo(ps, p); break; case USBDEVFS_SETINTERFACE: - snoop(&dev->dev, "%s: SETINTERFACE\n", __FUNCTION__); + snoop(&dev->dev, "%s: SETINTERFACE\n", __func__); ret = proc_setintf(ps, p); break; case USBDEVFS_SETCONFIGURATION: - snoop(&dev->dev, "%s: SETCONFIGURATION\n", __FUNCTION__); + snoop(&dev->dev, "%s: SETCONFIGURATION\n", __func__); ret = proc_setconfig(ps, p); break; case USBDEVFS_SUBMITURB: - snoop(&dev->dev, "%s: SUBMITURB\n", __FUNCTION__); + snoop(&dev->dev, "%s: SUBMITURB\n", __func__); ret = proc_submiturb(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; @@ -1592,60 +1592,60 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, #ifdef CONFIG_COMPAT case USBDEVFS_SUBMITURB32: - snoop(&dev->dev, "%s: SUBMITURB32\n", __FUNCTION__); + snoop(&dev->dev, "%s: SUBMITURB32\n", __func__); ret = proc_submiturb_compat(ps, p); if (ret >= 0) inode->i_mtime = CURRENT_TIME; break; case USBDEVFS_REAPURB32: - snoop(&dev->dev, "%s: REAPURB32\n", __FUNCTION__); + snoop(&dev->dev, "%s: REAPURB32\n", __func__); ret = proc_reapurb_compat(ps, p); break; case USBDEVFS_REAPURBNDELAY32: - snoop(&dev->dev, "%s: REAPURBDELAY32\n", __FUNCTION__); + snoop(&dev->dev, "%s: REAPURBDELAY32\n", __func__); ret = proc_reapurbnonblock_compat(ps, p); break; case USBDEVFS_IOCTL32: - snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); + snoop(&dev->dev, "%s: IOCTL\n", __func__); ret = proc_ioctl_compat(ps, ptr_to_compat(p)); break; #endif case USBDEVFS_DISCARDURB: - snoop(&dev->dev, "%s: DISCARDURB\n", __FUNCTION__); + snoop(&dev->dev, "%s: DISCARDURB\n", __func__); ret = proc_unlinkurb(ps, p); break; case USBDEVFS_REAPURB: - snoop(&dev->dev, "%s: REAPURB\n", __FUNCTION__); + snoop(&dev->dev, "%s: REAPURB\n", __func__); ret = proc_reapurb(ps, p); break; case USBDEVFS_REAPURBNDELAY: - snoop(&dev->dev, "%s: REAPURBDELAY\n", __FUNCTION__); + snoop(&dev->dev, "%s: REAPURBDELAY\n", __func__); ret = proc_reapurbnonblock(ps, p); break; case USBDEVFS_DISCSIGNAL: - snoop(&dev->dev, "%s: DISCSIGNAL\n", __FUNCTION__); + snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); ret = proc_disconnectsignal(ps, p); break; case USBDEVFS_CLAIMINTERFACE: - snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __FUNCTION__); + snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __func__); ret = proc_claiminterface(ps, p); break; case USBDEVFS_RELEASEINTERFACE: - snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __FUNCTION__); + snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __func__); ret = proc_releaseinterface(ps, p); break; case USBDEVFS_IOCTL: - snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); + snoop(&dev->dev, "%s: IOCTL\n", __func__); ret = proc_ioctl_default(ps, p); break; } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index edc31e13e95e..1e56f1cfa6dc 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -157,7 +157,7 @@ static int usb_probe_device(struct device *dev) struct usb_device *udev; int error = -ENODEV; - dev_dbg(dev, "%s\n", __FUNCTION__); + dev_dbg(dev, "%s\n", __func__); if (!is_usb_device(dev)) /* Sanity check */ return error; @@ -194,7 +194,7 @@ static int usb_probe_interface(struct device *dev) const struct usb_device_id *id; int error = -ENODEV; - dev_dbg(dev, "%s\n", __FUNCTION__); + dev_dbg(dev, "%s\n", __func__); if (is_usb_device(dev)) /* Sanity check */ return error; @@ -211,7 +211,7 @@ static int usb_probe_interface(struct device *dev) if (!id) id = usb_match_dynamic_id(intf, driver); if (id) { - dev_dbg(dev, "%s - got id\n", __FUNCTION__); + dev_dbg(dev, "%s - got id\n", __func__); error = usb_autoresume_device(udev); if (error) @@ -793,7 +793,7 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) status = udriver->suspend(udev, msg); done: - dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); return status; } @@ -821,7 +821,7 @@ static int usb_resume_device(struct usb_device *udev) status = udriver->resume(udev); done: - dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); if (status == 0) udev->autoresume_disabled = 0; return status; @@ -860,7 +860,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg) } done: - dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); return status; } @@ -910,7 +910,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume) } done: - dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); if (status == 0) mark_active(intf); @@ -1093,7 +1093,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) } done: - dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); return status; } @@ -1187,7 +1187,7 @@ static int usb_resume_both(struct usb_device *udev) } done: - dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); + dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); if (!status) udev->reset_resume = 0; return status; @@ -1257,7 +1257,7 @@ void usb_autosuspend_device(struct usb_device *udev) status = usb_autopm_do_device(udev, -1); dev_vdbg(&udev->dev, "%s: cnt %d\n", - __FUNCTION__, udev->pm_usage_cnt); + __func__, udev->pm_usage_cnt); } /** @@ -1277,7 +1277,7 @@ void usb_try_autosuspend_device(struct usb_device *udev) { usb_autopm_do_device(udev, 0); dev_vdbg(&udev->dev, "%s: cnt %d\n", - __FUNCTION__, udev->pm_usage_cnt); + __func__, udev->pm_usage_cnt); } /** @@ -1305,7 +1305,7 @@ int usb_autoresume_device(struct usb_device *udev) status = usb_autopm_do_device(udev, 1); dev_vdbg(&udev->dev, "%s: status %d cnt %d\n", - __FUNCTION__, status, udev->pm_usage_cnt); + __func__, status, udev->pm_usage_cnt); return status; } @@ -1377,7 +1377,7 @@ void usb_autopm_put_interface(struct usb_interface *intf) status = usb_autopm_do_interface(intf, -1); dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __FUNCTION__, status, intf->pm_usage_cnt); + __func__, status, intf->pm_usage_cnt); } EXPORT_SYMBOL_GPL(usb_autopm_put_interface); @@ -1421,7 +1421,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) status = usb_autopm_do_interface(intf, 1); dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __FUNCTION__, status, intf->pm_usage_cnt); + __func__, status, intf->pm_usage_cnt); return status; } EXPORT_SYMBOL_GPL(usb_autopm_get_interface); @@ -1443,7 +1443,7 @@ int usb_autopm_set_interface(struct usb_interface *intf) status = usb_autopm_do_interface(intf, 0); dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", - __FUNCTION__, status, intf->pm_usage_cnt); + __func__, status, intf->pm_usage_cnt); return status; } EXPORT_SYMBOL_GPL(usb_autopm_set_interface); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5a338a5d4fe7..06c3acb161ee 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -575,7 +575,7 @@ static int hub_hub_status(struct usb_hub *hub, ret = get_hub_status(hub->hdev, &hub->status->hub); if (ret < 0) dev_err (hub->intfdev, - "%s failed (err = %d)\n", __FUNCTION__, ret); + "%s failed (err = %d)\n", __func__, ret); else { *status = le16_to_cpu(hub->status->hub.wHubStatus); *change = le16_to_cpu(hub->status->hub.wHubChange); @@ -1270,7 +1270,7 @@ void usb_disconnect(struct usb_device **pdev) int i; if (!udev) { - pr_debug ("%s nodev\n", __FUNCTION__); + pr_debug ("%s nodev\n", __func__); return; } @@ -2072,7 +2072,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) } } - dev_dbg(&intf->dev, "%s\n", __FUNCTION__); + dev_dbg(&intf->dev, "%s\n", __func__); /* stop khubd and related activity */ hub_quiesce(hub); @@ -3125,7 +3125,7 @@ int usb_reset_device(struct usb_device *udev) if (!parent_hdev) { /* this requires hcd-specific logic; see OHCI hc_restart() */ - dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); + dev_dbg(&udev->dev, "%s for root hub!\n", __func__); return -EISDIR; } parent_hub = hdev_to_hub(parent_hdev); diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 83a373e9cc36..8607846e3c3f 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -463,13 +463,13 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent) inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0); if (!inode) { - dbg("%s: could not get inode!",__FUNCTION__); + dbg("%s: could not get inode!",__func__); return -ENOMEM; } root = d_alloc_root(inode); if (!root) { - dbg("%s: could not get root dentry!",__FUNCTION__); + dbg("%s: could not get root dentry!",__func__); iput(inode); return -ENOMEM; } diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5b23f6b017d7..e819e5359d57 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -312,7 +312,7 @@ static void sg_complete(struct urb *urb) retval != -EBUSY) dev_err(&io->dev->dev, "%s, unlink --> %d\n", - __FUNCTION__, retval); + __func__, retval); } else if (urb == io->urbs [i]) found = 1; } @@ -550,7 +550,7 @@ void usb_sg_wait(struct usb_sg_request *io) io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", - __FUNCTION__, retval); + __func__, retval); usb_sg_cancel(io); } spin_lock_irq(&io->lock); @@ -600,7 +600,7 @@ void usb_sg_cancel(struct usb_sg_request *io) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -EBUSY) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", - __FUNCTION__, retval); + __func__, retval); } spin_lock(&io->lock); } @@ -1068,7 +1068,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; - dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__, + dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, skip_ep0 ? "non-ep0" : "all"); for (i = skip_ep0; i < 16; ++i) { usb_disable_endpoint(dev, i); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 1d3ed1322fbe..c0b1ae25ae2a 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -334,7 +334,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) dev_dbg(&dev->dev, "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", usb_endpoint_num(&ep->desc), is_out ? "out" : "in", - __FUNCTION__, max); + __func__, max); return -EMSGSIZE; } diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 5d352c900d2c..9b913afb2e6d 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -460,7 +460,7 @@ static void nuke(struct at91_ep *ep, int status) if (list_empty(&ep->queue)) return; - VDBG("%s %s\n", __FUNCTION__, ep->ep.name); + VDBG("%s %s\n", __func__, ep->ep.name); while (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, struct at91_request, queue); done(ep, req, status); @@ -795,7 +795,7 @@ static int at91_wakeup(struct usb_gadget *gadget) int status = -EINVAL; unsigned long flags; - DBG("%s\n", __FUNCTION__ ); + DBG("%s\n", __func__ ); local_irq_save(flags); if (!udc->clocked || !udc->suspended) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 74f51a703b42..66293105d136 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -892,7 +892,7 @@ static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) { struct dummy *dum = platform_get_drvdata(pdev); - dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); + dev_dbg (&pdev->dev, "%s\n", __func__); spin_lock_irq (&dum->lock); dum->udc_suspended = 1; set_link_state (dum); @@ -906,7 +906,7 @@ static int dummy_udc_resume (struct platform_device *pdev) { struct dummy *dum = platform_get_drvdata(pdev); - dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); + dev_dbg (&pdev->dev, "%s\n", __func__); spin_lock_irq (&dum->lock); dum->udc_suspended = 0; set_link_state (dum); @@ -1707,7 +1707,7 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) { struct dummy *dum = hcd_to_dummy (hcd); - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); + dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq (&dum->lock); dum->rh_state = DUMMY_RH_SUSPENDED; @@ -1722,7 +1722,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd) struct dummy *dum = hcd_to_dummy (hcd); int rc = 0; - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); + dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq (&dum->lock); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { @@ -1896,7 +1896,7 @@ static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) struct dummy *dum; int rc = 0; - dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); + dev_dbg (&pdev->dev, "%s\n", __func__); hcd = platform_get_drvdata (pdev); dum = hcd_to_dummy (hcd); @@ -1912,7 +1912,7 @@ static int dummy_hcd_resume (struct platform_device *pdev) { struct usb_hcd *hcd; - dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); + dev_dbg (&pdev->dev, "%s\n", __func__); hcd = platform_get_drvdata (pdev); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 92b9bf78071f..bb93bdd76593 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1102,7 +1102,7 @@ static void eth_reset_config (struct eth_dev *dev) if (dev->config == 0) return; - DEBUG (dev, "%s\n", __FUNCTION__); + DEBUG (dev, "%s\n", __func__); netif_stop_queue (dev->net); netif_carrier_off (dev->net); @@ -1263,7 +1263,7 @@ static void issue_start_status (struct eth_dev *dev) struct usb_cdc_notification *event; int value; - DEBUG (dev, "%s, flush old status first\n", __FUNCTION__); + DEBUG (dev, "%s, flush old status first\n", __func__); /* flush old status * @@ -1329,7 +1329,7 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) spin_lock(&dev->lock); status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); if (status < 0) - ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status); + ERROR(dev, "%s: rndis parse error %d\n", __func__, status); spin_unlock(&dev->lock); } @@ -2113,7 +2113,7 @@ static int rndis_control_ack (struct net_device *net) static void eth_start (struct eth_dev *dev, gfp_t gfp_flags) { - DEBUG (dev, "%s\n", __FUNCTION__); + DEBUG (dev, "%s\n", __func__); /* fill the rx queue */ rx_fill (dev, gfp_flags); @@ -2133,7 +2133,7 @@ static int eth_open (struct net_device *net) { struct eth_dev *dev = netdev_priv(net); - DEBUG (dev, "%s\n", __FUNCTION__); + DEBUG (dev, "%s\n", __func__); if (netif_carrier_ok (dev->net)) eth_start (dev, GFP_KERNEL); return 0; @@ -2143,7 +2143,7 @@ static int eth_stop (struct net_device *net) { struct eth_dev *dev = netdev_priv(net); - VDEBUG (dev, "%s\n", __FUNCTION__); + VDEBUG (dev, "%s\n", __func__); netif_stop_queue (net); DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 0a726e106ccd..bf3f946fd455 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1104,7 +1104,7 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) if (req->actual > 0) dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + DBG(fsg, "%s --> %d, %u/%u\n", __func__, req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1125,7 +1125,7 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + DBG(fsg, "%s --> %d, %u/%u\n", __func__, req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1146,7 +1146,7 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) dump_msg(fsg, "bulk-out", req->buf, req->actual); if (req->status || req->actual != bh->bulk_out_intended_length) - DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + DBG(fsg, "%s --> %d, %u/%u\n", __func__, req->status, req->actual, bh->bulk_out_intended_length); if (req->status == -ECONNRESET) // Request was cancelled @@ -1169,7 +1169,7 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + DBG(fsg, "%s --> %d, %u/%u\n", __func__, req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 254012ad2b91..651b82701394 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -773,11 +773,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf || !list_empty(&req->queue)) { - VDBG("%s, bad params\n", __FUNCTION__); + VDBG("%s, bad params\n", __func__); return -EINVAL; } if (unlikely(!_ep || !ep->desc)) { - VDBG("%s, bad ep\n", __FUNCTION__); + VDBG("%s, bad ep\n", __func__); return -EINVAL; } if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 9fb0b1ec8526..98b1483ef6a5 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -512,7 +512,7 @@ struct fsl_udc { #ifdef DEBUG #define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt "\n", \ - __FUNCTION__, ## args) + __func__, ## args) #else #define DBG(fmt, args...) do{}while(0) #endif diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index d3e702576de6..64a592cbbe7b 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -692,7 +692,7 @@ static void abort_dma(struct goku_ep *ep, int status) req->req.actual = (curr - req->req.dma) + 1; req->req.status = status; - VDBG(ep->dev, "%s %s %s %d/%d\n", __FUNCTION__, ep->ep.name, + VDBG(ep->dev, "%s %s %s %d/%d\n", __func__, ep->ep.name, ep->is_in ? "IN" : "OUT", req->req.actual, req->req.length); @@ -826,7 +826,7 @@ static int goku_dequeue(struct usb_ep *_ep, struct usb_request *_req) if (dev->ep0state == EP0_SUSPEND) return -EBUSY; - VDBG(dev, "%s %s %s %s %p\n", __FUNCTION__, _ep->name, + VDBG(dev, "%s %s %s %s %p\n", __func__, _ep->name, ep->is_in ? "IN" : "OUT", ep->dma ? "dma" : "pio", _req); @@ -898,7 +898,7 @@ static int goku_set_halt(struct usb_ep *_ep, int value) /* don't change EPxSTATUS_EP_INVALID to READY */ } else if (!ep->desc) { - DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name); + DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name); return -EINVAL; } @@ -940,7 +940,7 @@ static int goku_fifo_status(struct usb_ep *_ep) regs = ep->dev->regs; size = readl(®s->EPxSizeLA[ep->num]) & DATASIZE; size += readl(®s->EPxSizeLB[ep->num]) & DATASIZE; - VDBG(ep->dev, "%s %s %u\n", __FUNCTION__, ep->ep.name, size); + VDBG(ep->dev, "%s %s %u\n", __func__, ep->ep.name, size); return size; } @@ -953,11 +953,11 @@ static void goku_fifo_flush(struct usb_ep *_ep) if (!_ep) return; ep = container_of(_ep, struct goku_ep, ep); - VDBG(ep->dev, "%s %s\n", __FUNCTION__, ep->ep.name); + VDBG(ep->dev, "%s %s\n", __func__, ep->ep.name); /* don't change EPxSTATUS_EP_INVALID to READY */ if (!ep->desc && ep->num != 0) { - DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name); + DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name); return; } @@ -1286,7 +1286,7 @@ static void ep0_start(struct goku_udc *dev) struct goku_udc_regs __iomem *regs = dev->regs; unsigned i; - VDBG(dev, "%s\n", __FUNCTION__); + VDBG(dev, "%s\n", __func__); udc_reset(dev); udc_reinit (dev); @@ -1322,7 +1322,7 @@ static void udc_enable(struct goku_udc *dev) if (readl(&dev->regs->power_detect) & PW_DETECT) ep0_start(dev); else { - DBG(dev, "%s\n", __FUNCTION__); + DBG(dev, "%s\n", __func__); dev->int_enable = INT_PWRDETECT; writel(dev->int_enable, &dev->regs->int_enable); } @@ -1387,7 +1387,7 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) { unsigned i; - DBG (dev, "%s\n", __FUNCTION__); + DBG (dev, "%s\n", __func__); if (dev->gadget.speed == USB_SPEED_UNKNOWN) driver = NULL; @@ -1726,7 +1726,7 @@ static void goku_remove(struct pci_dev *pdev) { struct goku_udc *dev = pci_get_drvdata(pdev); - DBG(dev, "%s\n", __FUNCTION__); + DBG(dev, "%s\n", __func__); BUG_ON(dev->driver); diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 0a6feafc8d28..69b0a2754f2a 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1107,13 +1107,13 @@ scan: switch (state) { default: - DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); + DBG (dev, "fail %s, state %d\n", __func__, state); retval = -ESRCH; break; case STATE_DEV_UNCONNECTED: case STATE_DEV_CONNECTED: spin_unlock_irq (&dev->lock); - DBG (dev, "%s wait\n", __FUNCTION__); + DBG (dev, "%s wait\n", __func__); /* wait for events */ retval = wait_event_interruptible (dev->wait, @@ -1222,7 +1222,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) DBG(dev, "bogus ep0out stall!\n"); } } else - DBG (dev, "fail %s, state %d\n", __FUNCTION__, dev->state); + DBG (dev, "fail %s, state %d\n", __func__, dev->state); spin_unlock_irq (&dev->lock); return retval; @@ -1233,7 +1233,7 @@ ep0_fasync (int f, struct file *fd, int on) { struct dev_data *dev = fd->private_data; // caller must F_SETOWN before signal delivery happens - VDEBUG (dev, "%s %s\n", __FUNCTION__, on ? "on" : "off"); + VDEBUG (dev, "%s %s\n", __func__, on ? "on" : "off"); return fasync_helper (f, fd, on, &dev->fasync); } @@ -1575,7 +1575,7 @@ static void destroy_ep_files (struct dev_data *dev) { struct list_head *entry, *tmp; - DBG (dev, "%s %d\n", __FUNCTION__, dev->state); + DBG (dev, "%s %d\n", __func__, dev->state); /* dev->state must prevent interference */ restart: @@ -1662,7 +1662,7 @@ enomem1: put_dev (dev); kfree (data); enomem0: - DBG (dev, "%s enomem\n", __FUNCTION__); + DBG (dev, "%s enomem\n", __func__); destroy_ep_files (dev); return -ENOMEM; } @@ -1672,7 +1672,7 @@ gadgetfs_unbind (struct usb_gadget *gadget) { struct dev_data *dev = get_gadget_data (gadget); - DBG (dev, "%s\n", __FUNCTION__); + DBG (dev, "%s\n", __func__); spin_lock_irq (&dev->lock); dev->state = STATE_DEV_UNBOUND; @@ -1685,7 +1685,7 @@ gadgetfs_unbind (struct usb_gadget *gadget) /* we've already been disconnected ... no i/o is active */ if (dev->req) usb_ep_free_request (gadget->ep0, dev->req); - DBG (dev, "%s done\n", __FUNCTION__); + DBG (dev, "%s done\n", __func__); put_dev (dev); } @@ -1933,7 +1933,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) fail: spin_unlock_irq (&dev->lock); - pr_debug ("%s: %s fail %Zd, %p\n", shortname, __FUNCTION__, value, dev); + pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev); kfree (dev->buf); dev->buf = NULL; return value; diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 078f72467671..825abd2621b3 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -253,7 +253,7 @@ udc_proc_read(char *page, char **start, off_t off, int count, */ static void udc_disable(struct lh7a40x_udc *dev) { - DEBUG("%s, %p\n", __FUNCTION__, dev); + DEBUG("%s, %p\n", __func__, dev); udc_set_address(dev, 0); @@ -285,7 +285,7 @@ static void udc_reinit(struct lh7a40x_udc *dev) { u32 i; - DEBUG("%s, %p\n", __FUNCTION__, dev); + DEBUG("%s, %p\n", __func__, dev); /* device/ep0 records init */ INIT_LIST_HEAD(&dev->gadget.ep_list); @@ -318,7 +318,7 @@ static void udc_enable(struct lh7a40x_udc *dev) { int ep; - DEBUG("%s, %p\n", __FUNCTION__, dev); + DEBUG("%s, %p\n", __func__, dev); dev->gadget.speed = USB_SPEED_UNKNOWN; @@ -412,7 +412,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) struct lh7a40x_udc *dev = the_controller; int retval; - DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); + DEBUG("%s: %s\n", __func__, driver->driver.name); if (!driver || driver->speed != USB_SPEED_FULL @@ -521,7 +521,7 @@ static int write_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) is_short = unlikely(max < ep_maxpacket(ep)); } - DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__, + DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __func__, ep->ep.name, count, is_last ? "/L" : "", is_short ? "/S" : "", req->req.length - req->req.actual, req); @@ -555,7 +555,7 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) /* make sure there's a packet in the FIFO. */ csr = usb_read(ep->csr1); if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) { - DEBUG("%s: Packet NOT ready!\n", __FUNCTION__); + DEBUG("%s: Packet NOT ready!\n", __func__); return -EINVAL; } @@ -614,7 +614,7 @@ static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status) unsigned int stopped = ep->stopped; u32 index; - DEBUG("%s, %p\n", __FUNCTION__, ep); + DEBUG("%s, %p\n", __func__, ep); list_del_init(&req->queue); if (likely(req->req.status == -EINPROGRESS)) @@ -644,7 +644,7 @@ static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status) /** Enable EP interrupt */ static void pio_irq_enable(int ep) { - DEBUG("%s: %d\n", __FUNCTION__, ep); + DEBUG("%s: %d\n", __func__, ep); switch (ep) { case 1: @@ -665,7 +665,7 @@ static void pio_irq_enable(int ep) /** Disable EP interrupt */ static void pio_irq_disable(int ep) { - DEBUG("%s: %d\n", __FUNCTION__, ep); + DEBUG("%s: %d\n", __func__, ep); switch (ep) { case 1: @@ -690,7 +690,7 @@ void nuke(struct lh7a40x_ep *ep, int status) { struct lh7a40x_request *req; - DEBUG("%s, %p\n", __FUNCTION__, ep); + DEBUG("%s, %p\n", __func__, ep); /* Flush FIFO */ flush(ep); @@ -734,7 +734,7 @@ static void flush_all(struct lh7a40x_udc *dev) */ static void flush(struct lh7a40x_ep *ep) { - DEBUG("%s, %p\n", __FUNCTION__, ep); + DEBUG("%s, %p\n", __func__, ep); switch (ep->ep_type) { case ep_control: @@ -766,7 +766,7 @@ static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) usb_set_index(ep_idx); csr = usb_read(ep->csr1); - DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr); + DEBUG("%s: %d, csr %x\n", __func__, ep_idx, csr); if (csr & USB_IN_CSR1_SENT_STALL) { DEBUG("USB_IN_CSR1_SENT_STALL\n"); @@ -776,7 +776,7 @@ static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) } if (!ep->desc) { - DEBUG("%s: NO EP DESC\n", __FUNCTION__); + DEBUG("%s: NO EP DESC\n", __func__); return; } @@ -802,7 +802,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) struct lh7a40x_ep *ep = &dev->ep[ep_idx]; struct lh7a40x_request *req; - DEBUG("%s: %d\n", __FUNCTION__, ep_idx); + DEBUG("%s: %d\n", __func__, ep_idx); usb_set_index(ep_idx); @@ -814,11 +814,11 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) usb_read(ep-> csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY | USB_OUT_CSR1_SENT_STALL)) { - DEBUG("%s: %x\n", __FUNCTION__, csr); + DEBUG("%s: %x\n", __func__, csr); if (csr & USB_OUT_CSR1_SENT_STALL) { DEBUG("%s: stall sent, flush fifo\n", - __FUNCTION__); + __func__); /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */ flush(ep); } else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) { @@ -832,7 +832,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) if (!req) { printk("%s: NULL REQ %d\n", - __FUNCTION__, ep_idx); + __func__, ep_idx); flush(ep); break; } else { @@ -844,7 +844,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) } else { /* Throw packet away.. */ - printk("%s: No descriptor?!?\n", __FUNCTION__); + printk("%s: No descriptor?!?\n", __func__); flush(ep); } } @@ -886,7 +886,7 @@ static void lh7a40x_reset_intr(struct lh7a40x_udc *dev) #if 0 /* def CONFIG_ARCH_LH7A404 */ /* Does not work always... */ - DEBUG("%s: %d\n", __FUNCTION__, dev->usb_address); + DEBUG("%s: %d\n", __func__, dev->usb_address); if (!dev->usb_address) { /*usb_set(USB_RESET_IO, USB_RESET); @@ -936,7 +936,7 @@ static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev) if (!intr_out && !intr_in && !intr_int) break; - DEBUG("%s (on state %s)\n", __FUNCTION__, + DEBUG("%s (on state %s)\n", __func__, state_names[dev->ep0state]); DEBUG("intr_out = %x\n", intr_out); DEBUG("intr_in = %x\n", intr_in); @@ -1016,14 +1016,14 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep, struct lh7a40x_udc *dev; unsigned long flags; - DEBUG("%s, %p\n", __FUNCTION__, _ep); + DEBUG("%s, %p\n", __func__, _ep); ep = container_of(_ep, struct lh7a40x_ep, ep); if (!_ep || !desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) { - DEBUG("%s, bad ep or descriptor\n", __FUNCTION__); + DEBUG("%s, bad ep or descriptor\n", __func__); return -EINVAL; } @@ -1031,7 +1031,7 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep, if (ep->bmAttributes != desc->bmAttributes && ep->bmAttributes != USB_ENDPOINT_XFER_BULK && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - DEBUG("%s, %s type mismatch\n", __FUNCTION__, _ep->name); + DEBUG("%s, %s type mismatch\n", __func__, _ep->name); return -EINVAL; } @@ -1039,13 +1039,13 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep, if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep)) || !desc->wMaxPacketSize) { - DEBUG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); + DEBUG("%s, bad %s maxpacket\n", __func__, _ep->name); return -ERANGE; } dev = ep->dev; if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DEBUG("%s, bogus device state\n", __FUNCTION__); + DEBUG("%s, bogus device state\n", __func__); return -ESHUTDOWN; } @@ -1061,7 +1061,7 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep, /* Reset halt state (does flush) */ lh7a40x_set_halt(_ep, 0); - DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name); + DEBUG("%s: enabled %s\n", __func__, _ep->name); return 0; } @@ -1073,11 +1073,11 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep) struct lh7a40x_ep *ep; unsigned long flags; - DEBUG("%s, %p\n", __FUNCTION__, _ep); + DEBUG("%s, %p\n", __func__, _ep); ep = container_of(_ep, struct lh7a40x_ep, ep); if (!_ep || !ep->desc) { - DEBUG("%s, %s not enabled\n", __FUNCTION__, + DEBUG("%s, %s not enabled\n", __func__, _ep ? ep->ep.name : NULL); return -EINVAL; } @@ -1097,7 +1097,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep) spin_unlock_irqrestore(&ep->dev->lock, flags); - DEBUG("%s: disabled %s\n", __FUNCTION__, _ep->name); + DEBUG("%s: disabled %s\n", __func__, _ep->name); return 0; } @@ -1106,7 +1106,7 @@ static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, { struct lh7a40x_request *req; - DEBUG("%s, %p\n", __FUNCTION__, ep); + DEBUG("%s, %p\n", __func__, ep); req = kzalloc(sizeof(*req), gfp_flags); if (!req) @@ -1121,7 +1121,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req) { struct lh7a40x_request *req; - DEBUG("%s, %p\n", __FUNCTION__, ep); + DEBUG("%s, %p\n", __func__, ep); req = container_of(_req, struct lh7a40x_request, req); WARN_ON(!list_empty(&req->queue)); @@ -1140,25 +1140,25 @@ static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req, struct lh7a40x_udc *dev; unsigned long flags; - DEBUG("\n\n\n%s, %p\n", __FUNCTION__, _ep); + DEBUG("\n\n\n%s, %p\n", __func__, _ep); req = container_of(_req, struct lh7a40x_request, req); if (unlikely (!_req || !_req->complete || !_req->buf || !list_empty(&req->queue))) { - DEBUG("%s, bad params\n", __FUNCTION__); + DEBUG("%s, bad params\n", __func__); return -EINVAL; } ep = container_of(_ep, struct lh7a40x_ep, ep); if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __FUNCTION__); + DEBUG("%s, bad ep\n", __func__); return -EINVAL; } dev = ep->dev; if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - DEBUG("%s, bogus device state %p\n", __FUNCTION__, dev->driver); + DEBUG("%s, bogus device state %p\n", __func__, dev->driver); return -ESHUTDOWN; } @@ -1218,7 +1218,7 @@ static int lh7a40x_dequeue(struct usb_ep *_ep, struct usb_request *_req) struct lh7a40x_request *req; unsigned long flags; - DEBUG("%s, %p\n", __FUNCTION__, _ep); + DEBUG("%s, %p\n", __func__, _ep); ep = container_of(_ep, struct lh7a40x_ep, ep); if (!_ep || ep->ep.name == ep0name) @@ -1253,13 +1253,13 @@ static int lh7a40x_set_halt(struct usb_ep *_ep, int value) ep = container_of(_ep, struct lh7a40x_ep, ep); if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __FUNCTION__); + DEBUG("%s, bad ep\n", __func__); return -EINVAL; } usb_set_index(ep_index(ep)); - DEBUG("%s, ep %d, val %d\n", __FUNCTION__, ep_index(ep), value); + DEBUG("%s, ep %d, val %d\n", __func__, ep_index(ep), value); spin_lock_irqsave(&ep->dev->lock, flags); @@ -1325,11 +1325,11 @@ static int lh7a40x_fifo_status(struct usb_ep *_ep) ep = container_of(_ep, struct lh7a40x_ep, ep); if (!_ep) { - DEBUG("%s, bad ep\n", __FUNCTION__); + DEBUG("%s, bad ep\n", __func__); return -ENODEV; } - DEBUG("%s, %d\n", __FUNCTION__, ep_index(ep)); + DEBUG("%s, %d\n", __func__, ep_index(ep)); /* LPD can't report unclaimed bytes from IN fifos */ if (ep_is_in(ep)) @@ -1355,7 +1355,7 @@ static void lh7a40x_fifo_flush(struct usb_ep *_ep) ep = container_of(_ep, struct lh7a40x_ep, ep); if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __FUNCTION__); + DEBUG("%s, bad ep\n", __func__); return; } @@ -1376,7 +1376,7 @@ static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) max = ep_maxpacket(ep); - DEBUG_EP0("%s\n", __FUNCTION__); + DEBUG_EP0("%s\n", __func__); count = write_packet(ep, req, max); @@ -1390,7 +1390,7 @@ static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) is_last = 1; } - DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __FUNCTION__, + DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __func__, ep->ep.name, count, is_last ? "/L" : "", req->req.length - req->req.actual, req); @@ -1434,7 +1434,7 @@ static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) unsigned bufferspace, count, is_short; volatile u32 *fifo = (volatile u32 *)ep->fifo; - DEBUG_EP0("%s\n", __FUNCTION__); + DEBUG_EP0("%s\n", __func__); csr = usb_read(USB_EP0_CSR); if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) @@ -1492,7 +1492,7 @@ static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) */ static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address) { - DEBUG_EP0("%s: %d\n", __FUNCTION__, address); + DEBUG_EP0("%s: %d\n", __func__, address); /* c.f. 15.1.2.2 Table 15-4 address will be used after DATA_END is set */ dev->usb_address = address; usb_set((address & USB_FA_FUNCTION_ADDR), USB_FA); @@ -1514,7 +1514,7 @@ static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr) struct lh7a40x_ep *ep = &dev->ep[0]; int ret; - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: %x\n", __func__, csr); if (list_empty(&ep->queue)) req = 0; @@ -1533,13 +1533,13 @@ static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr) if (ret) { /* Done! */ DEBUG_EP0("%s: finished, waiting for status\n", - __FUNCTION__); + __func__); usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR); dev->ep0state = WAIT_FOR_SETUP; } else { /* Not done yet.. */ - DEBUG_EP0("%s: not finished\n", __FUNCTION__); + DEBUG_EP0("%s: not finished\n", __func__); usb_set(EP0_CLR_OUT, USB_EP0_CSR); } } else { @@ -1556,7 +1556,7 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr) struct lh7a40x_ep *ep = &dev->ep[0]; int ret, need_zlp = 0; - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: %x\n", __func__, csr); if (list_empty(&ep->queue)) req = 0; @@ -1564,7 +1564,7 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr) req = list_entry(ep->queue.next, struct lh7a40x_request, queue); if (!req) { - DEBUG_EP0("%s: NULL REQ\n", __FUNCTION__); + DEBUG_EP0("%s: NULL REQ\n", __func__); return 0; } @@ -1585,17 +1585,17 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr) if (ret == 1 && !need_zlp) { /* Last packet */ - DEBUG_EP0("%s: finished, waiting for status\n", __FUNCTION__); + DEBUG_EP0("%s: finished, waiting for status\n", __func__); usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); dev->ep0state = WAIT_FOR_SETUP; } else { - DEBUG_EP0("%s: not finished\n", __FUNCTION__); + DEBUG_EP0("%s: not finished\n", __func__); usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR); } if (need_zlp) { - DEBUG_EP0("%s: Need ZLP!\n", __FUNCTION__); + DEBUG_EP0("%s: Need ZLP!\n", __func__); usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR); dev->ep0state = DATA_STATE_NEED_ZLP; } @@ -1694,7 +1694,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr) struct usb_ctrlrequest ctrl; int i, bytes, is_in; - DEBUG_SETUP("%s: %x\n", __FUNCTION__, csr); + DEBUG_SETUP("%s: %x\n", __func__, csr); /* Nuke all previous transfers */ nuke(ep, -EPROTO); @@ -1799,7 +1799,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr) */ static void lh7a40x_ep0_in_zlp(struct lh7a40x_udc *dev, u32 csr) { - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: %x\n", __func__, csr); /* c.f. Table 15-14 */ usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); @@ -1818,7 +1818,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) usb_set_index(0); csr = usb_read(USB_EP0_CSR); - DEBUG_EP0("%s: csr = %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: csr = %x\n", __func__, csr); /* * For overview of what we should be doing see c.f. Chapter 18.1.2.4 @@ -1832,7 +1832,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) * - clear the SENT_STALL bit */ if (csr & EP0_SENT_STALL) { - DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __func__, csr); usb_clear((EP0_SENT_STALL | EP0_SEND_STALL), USB_EP0_CSR); nuke(ep, -ECONNABORTED); dev->ep0state = WAIT_FOR_SETUP; @@ -1849,7 +1849,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) */ if (!(csr & (EP0_IN_PKT_RDY | EP0_OUT_PKT_RDY))) { DEBUG_EP0("%s: IN_PKT_RDY and OUT_PKT_RDY are clear\n", - __FUNCTION__); + __func__); switch (dev->ep0state) { case DATA_STATE_XMIT: @@ -1877,7 +1877,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) * - set SERVICED_SETUP_END_BIT */ if (csr & EP0_SETUP_END) { - DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __func__, csr); usb_set(EP0_CLR_SETUP_END, USB_EP0_CSR); @@ -1896,7 +1896,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) */ if (csr & EP0_OUT_PKT_RDY) { - DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __FUNCTION__, + DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __func__, csr); switch (dev->ep0state) { @@ -1926,7 +1926,7 @@ static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep) usb_set_index(0); csr = usb_read(USB_EP0_CSR); - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); + DEBUG_EP0("%s: %x\n", __func__, csr); /* Clear "out packet ready" */ usb_set(EP0_CLR_OUT, USB_EP0_CSR); @@ -1949,7 +1949,7 @@ static int lh7a40x_udc_get_frame(struct usb_gadget *_gadget) { u32 frame1 = usb_read(USB_FRM_NUM1); /* Least significant 8 bits */ u32 frame2 = usb_read(USB_FRM_NUM2); /* Most significant 3 bits */ - DEBUG("%s, %p\n", __FUNCTION__, _gadget); + DEBUG("%s, %p\n", __func__, _gadget); return ((frame2 & 0x07) << 8) | (frame1 & 0xff); } @@ -1970,7 +1970,7 @@ static const struct usb_gadget_ops lh7a40x_udc_ops = { static void nop_release(struct device *dev) { - DEBUG("%s %s\n", __FUNCTION__, dev->bus_id); + DEBUG("%s %s\n", __func__, dev->bus_id); } static struct lh7a40x_udc memory = { @@ -2065,7 +2065,7 @@ static int lh7a40x_udc_probe(struct platform_device *pdev) struct lh7a40x_udc *dev = &memory; int retval; - DEBUG("%s: %p\n", __FUNCTION__, pdev); + DEBUG("%s: %p\n", __func__, pdev); spin_lock_init(&dev->lock); dev->dev = &pdev->dev; @@ -2098,7 +2098,7 @@ static int lh7a40x_udc_remove(struct platform_device *pdev) { struct lh7a40x_udc *dev = platform_get_drvdata(pdev); - DEBUG("%s: %p\n", __FUNCTION__, pdev); + DEBUG("%s: %p\n", __func__, pdev); if (dev->driver) return -EBUSY; @@ -2131,7 +2131,7 @@ static struct platform_driver udc_driver = { static int __init udc_init(void) { - DEBUG("%s: %s version %s\n", __FUNCTION__, driver_name, DRIVER_VERSION); + DEBUG("%s: %s version %s\n", __func__, driver_name, DRIVER_VERSION); return platform_driver_register(&udc_driver); } diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index 44ca139983d8..1f2af398a9a4 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -299,7 +299,7 @@ static inline void assert_out_naking (struct net2280_ep *ep, const char *where) &ep->regs->ep_rsp); } } -#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__FUNCTION__) +#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__) #else #define ASSERT_OUT_NAKING(ep) do {} while (0) #endif diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 56277d24f041..95f7662376f1 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -163,7 +163,7 @@ static int omap_ep_enable(struct usb_ep *_ep, || ep->bEndpointAddress != desc->bEndpointAddress || ep->maxpacket < le16_to_cpu (desc->wMaxPacketSize)) { - DBG("%s, bad ep or descriptor\n", __FUNCTION__); + DBG("%s, bad ep or descriptor\n", __func__); return -EINVAL; } maxp = le16_to_cpu (desc->wMaxPacketSize); @@ -171,7 +171,7 @@ static int omap_ep_enable(struct usb_ep *_ep, && maxp != ep->maxpacket) || le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket || !desc->wMaxPacketSize) { - DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); + DBG("%s, bad %s maxpacket\n", __func__, _ep->name); return -ERANGE; } @@ -194,13 +194,13 @@ static int omap_ep_enable(struct usb_ep *_ep, if (ep->bmAttributes != desc->bmAttributes && ep->bmAttributes != USB_ENDPOINT_XFER_BULK && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - DBG("%s, %s type mismatch\n", __FUNCTION__, _ep->name); + DBG("%s, %s type mismatch\n", __func__, _ep->name); return -EINVAL; } udc = ep->udc; if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { - DBG("%s, bogus device state\n", __FUNCTION__); + DBG("%s, bogus device state\n", __func__); return -ESHUTDOWN; } @@ -249,7 +249,7 @@ static int omap_ep_disable(struct usb_ep *_ep) unsigned long flags; if (!_ep || !ep->desc) { - DBG("%s, %s not enabled\n", __FUNCTION__, + DBG("%s, %s not enabled\n", __func__, _ep ? ep->ep.name : NULL); return -EINVAL; } @@ -936,11 +936,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf || !list_empty(&req->queue)) { - DBG("%s, bad params\n", __FUNCTION__); + DBG("%s, bad params\n", __func__); return -EINVAL; } if (!_ep || (!ep->desc && ep->bEndpointAddress)) { - DBG("%s, bad ep\n", __FUNCTION__); + DBG("%s, bad ep\n", __func__); return -EINVAL; } if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { @@ -959,7 +959,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) && (ep->bEndpointAddress & USB_DIR_IN) == 0 && !cpu_class_is_omap2() && (req->req.length % ep->ep.maxpacket) != 0) { - DBG("%s, no partial packet OUT reads\n", __FUNCTION__); + DBG("%s, no partial packet OUT reads\n", __func__); return -EMSGSIZE; } diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index ecc1410073f4..76be75e3ab8f 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -915,7 +915,7 @@ static void printer_reset_interface(struct printer_dev *dev) if (dev->interface < 0) return; - DBG(dev, "%s\n", __FUNCTION__); + DBG(dev, "%s\n", __func__); if (dev->in) usb_ep_disable(dev->in_ep); @@ -1284,7 +1284,7 @@ printer_disconnect(struct usb_gadget *gadget) struct printer_dev *dev = get_gadget_data(gadget); unsigned long flags; - DBG(dev, "%s\n", __FUNCTION__); + DBG(dev, "%s\n", __func__); spin_lock_irqsave(&dev->lock, flags); @@ -1300,7 +1300,7 @@ printer_unbind(struct usb_gadget *gadget) struct usb_request *req; - DBG(dev, "%s\n", __FUNCTION__); + DBG(dev, "%s\n", __func__); /* Remove sysfs files */ device_destroy(usb_gadget_class, g_printer_devno); diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index c00cd8b9d3d1..08f699b1fc57 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -235,7 +235,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, || ep->bEndpointAddress != desc->bEndpointAddress || ep->fifo_size < le16_to_cpu (desc->wMaxPacketSize)) { - DMSG("%s, bad ep or descriptor\n", __FUNCTION__); + DMSG("%s, bad ep or descriptor\n", __func__); return -EINVAL; } @@ -243,7 +243,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, if (ep->bmAttributes != desc->bmAttributes && ep->bmAttributes != USB_ENDPOINT_XFER_BULK && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name); + DMSG("%s, %s type mismatch\n", __func__, _ep->name); return -EINVAL; } @@ -252,13 +252,13 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, && le16_to_cpu (desc->wMaxPacketSize) != BULK_FIFO_SIZE) || !desc->wMaxPacketSize) { - DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); + DMSG("%s, bad %s maxpacket\n", __func__, _ep->name); return -ERANGE; } dev = ep->dev; if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DMSG("%s, bogus device state\n", __FUNCTION__); + DMSG("%s, bogus device state\n", __func__); return -ESHUTDOWN; } @@ -283,7 +283,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) ep = container_of (_ep, struct pxa2xx_ep, ep); if (!_ep || !ep->desc) { - DMSG("%s, %s not enabled\n", __FUNCTION__, + DMSG("%s, %s not enabled\n", __func__, _ep ? ep->ep.name : NULL); return -EINVAL; } @@ -461,7 +461,7 @@ void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag) USIR0 = USIR0_IR0; dev->req_pending = 0; DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n", - __FUNCTION__, tag, UDCCS0, flags); + __func__, tag, UDCCS0, flags); } static int @@ -651,20 +651,20 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req = container_of(_req, struct pxa2xx_request, req); if (unlikely (!_req || !_req->complete || !_req->buf || !list_empty(&req->queue))) { - DMSG("%s, bad params\n", __FUNCTION__); + DMSG("%s, bad params\n", __func__); return -EINVAL; } ep = container_of(_ep, struct pxa2xx_ep, ep); if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DMSG("%s, bad ep\n", __FUNCTION__); + DMSG("%s, bad ep\n", __func__); return -EINVAL; } dev = ep->dev; if (unlikely (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - DMSG("%s, bogus device state\n", __FUNCTION__); + DMSG("%s, bogus device state\n", __func__); return -ESHUTDOWN; } @@ -807,7 +807,7 @@ static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value) if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name)) || ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { - DMSG("%s, bad ep\n", __FUNCTION__); + DMSG("%s, bad ep\n", __func__); return -EINVAL; } if (value == 0) { @@ -859,7 +859,7 @@ static int pxa2xx_ep_fifo_status(struct usb_ep *_ep) ep = container_of(_ep, struct pxa2xx_ep, ep); if (!_ep) { - DMSG("%s, bad ep\n", __FUNCTION__); + DMSG("%s, bad ep\n", __func__); return -ENODEV; } /* pxa can't report unclaimed bytes from IN fifos */ @@ -878,7 +878,7 @@ static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep) ep = container_of(_ep, struct pxa2xx_ep, ep); if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) { - DMSG("%s, bad ep\n", __FUNCTION__); + DMSG("%s, bad ep\n", __func__); return; } @@ -1813,7 +1813,7 @@ pxa2xx_udc_irq(int irq, void *_dev) static void nop_release (struct device *dev) { - DMSG("%s %s\n", __FUNCTION__, dev->bus_id); + DMSG("%s %s\n", __func__, dev->bus_id); } /* this uses load-time allocation and initialization (instead of diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 934911ee5c72..bd58dd504f6f 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -204,7 +204,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_SUPPORTED_LIST: - DBG("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__); + DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__); length = sizeof (oid_supported_list); count = length / sizeof (u32); for (i = 0; i < count; i++) @@ -214,7 +214,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_HARDWARE_STATUS: - DBG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); + DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__); /* Bogus question! * Hardware must be ready to receive high level protocols. * BTW: @@ -227,14 +227,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: - DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); + DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; break; /* mandatory */ case OID_GEN_MEDIA_IN_USE: - DBG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); + DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__); /* one medium, one transport... (maybe you do it better) */ *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; @@ -242,7 +242,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: - DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); + DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -253,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_LINK_SPEED: if (rndis_debug > 1) - DBG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); + DBG("%s: OID_GEN_LINK_SPEED\n", __func__); if (rndis_per_dev_params [configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) *outbuf = __constant_cpu_to_le32 (0); @@ -265,7 +265,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_TRANSMIT_BLOCK_SIZE: - DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__); + DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -275,7 +275,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: - DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); + DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params [configNr].dev) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].dev->mtu); @@ -285,7 +285,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_ID: - DBG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); + DBG("%s: OID_GEN_VENDOR_ID\n", __func__); *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].vendorID); retval = 0; @@ -293,7 +293,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: - DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); + DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); length = strlen (rndis_per_dev_params [configNr].vendorDescr); memcpy (outbuf, rndis_per_dev_params [configNr].vendorDescr, length); @@ -301,7 +301,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_VENDOR_DRIVER_VERSION: - DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__); + DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); /* Created as LE */ *outbuf = rndis_driver_version; retval = 0; @@ -309,14 +309,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_CURRENT_PACKET_FILTER: - DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__); + DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter); retval = 0; break; /* mandatory */ case OID_GEN_MAXIMUM_TOTAL_SIZE: - DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__); + DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); retval = 0; break; @@ -324,14 +324,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) - DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__); + DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .media_state); retval = 0; break; case OID_GEN_PHYSICAL_MEDIUM: - DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__); + DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; @@ -341,7 +341,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! */ case OID_GEN_MAC_OPTIONS: /* from WinME */ - DBG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__); + DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__); *outbuf = __constant_cpu_to_le32( NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_FULL_DUPLEX); @@ -353,7 +353,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_XMIT_OK: if (rndis_debug > 1) - DBG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); + DBG("%s: OID_GEN_XMIT_OK\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].stats->tx_packets - @@ -366,7 +366,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_OK: if (rndis_debug > 1) - DBG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); + DBG("%s: OID_GEN_RCV_OK\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( rndis_per_dev_params [configNr].stats->rx_packets - @@ -379,7 +379,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_XMIT_ERROR: if (rndis_debug > 1) - DBG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); + DBG("%s: OID_GEN_XMIT_ERROR\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->tx_errors); @@ -390,7 +390,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_ERROR: if (rndis_debug > 1) - DBG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); + DBG("%s: OID_GEN_RCV_ERROR\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_errors); @@ -400,7 +400,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_RCV_NO_BUFFER: - DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); + DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_dropped); @@ -410,7 +410,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, #ifdef RNDIS_OPTIONAL_STATS case OID_GEN_DIRECTED_BYTES_XMIT: - DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__); /* * Aunt Tilly's size of shoes * minus antarctica count of penguins @@ -430,7 +430,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_DIRECTED_FRAMES_XMIT: - DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__); /* dito */ if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( @@ -446,7 +446,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_MULTICAST_BYTES_XMIT: - DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->multicast*1234); @@ -455,7 +455,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_MULTICAST_FRAMES_XMIT: - DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->multicast); @@ -464,7 +464,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_BROADCAST_BYTES_XMIT: - DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->tx_packets/42*255); @@ -473,7 +473,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_BROADCAST_FRAMES_XMIT: - DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); + DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->tx_packets/42); @@ -482,19 +482,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_DIRECTED_BYTES_RCV: - DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; case OID_GEN_DIRECTED_FRAMES_RCV: - DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; case OID_GEN_MULTICAST_BYTES_RCV: - DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->multicast * 1111); @@ -503,7 +503,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_MULTICAST_FRAMES_RCV: - DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->multicast); @@ -512,7 +512,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_BROADCAST_BYTES_RCV: - DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_packets/42*255); @@ -521,7 +521,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_BROADCAST_FRAMES_RCV: - DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); + DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_packets/42); @@ -530,7 +530,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_RCV_CRC_ERROR: - DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); + DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_crc_errors); @@ -539,7 +539,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, break; case OID_GEN_TRANSMIT_QUEUE_LENGTH: - DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); + DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; @@ -549,7 +549,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: - DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); + DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy (outbuf, @@ -561,7 +561,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_CURRENT_ADDRESS: - DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); + DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy (outbuf, @@ -573,7 +573,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_MULTICAST_LIST: - DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); + DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); /* Multicast base address only */ *outbuf = __constant_cpu_to_le32 (0xE0000000); retval = 0; @@ -581,21 +581,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: - DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); + DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); /* Multicast base address only */ *outbuf = __constant_cpu_to_le32 (1); retval = 0; break; case OID_802_3_MAC_OPTIONS: - DBG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); + DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__); break; /* ieee802.3 statistics OIDs (table 4-4) */ /* mandatory */ case OID_802_3_RCV_ERROR_ALIGNMENT: - DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); + DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] .stats->rx_frame_errors); @@ -605,51 +605,51 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: - DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: - DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; #ifdef RNDIS_OPTIONAL_STATS case OID_802_3_XMIT_DEFERRED: - DBG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_DEFERRED\n", __func__); /* TODO */ break; case OID_802_3_XMIT_MAX_COLLISIONS: - DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__); /* TODO */ break; case OID_802_3_RCV_OVERRUN: - DBG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); + DBG("%s: OID_802_3_RCV_OVERRUN\n", __func__); /* TODO */ break; case OID_802_3_XMIT_UNDERRUN: - DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __func__); /* TODO */ break; case OID_802_3_XMIT_HEARTBEAT_FAILURE: - DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__); /* TODO */ break; case OID_802_3_XMIT_TIMES_CRS_LOST: - DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__); /* TODO */ break; case OID_802_3_XMIT_LATE_COLLISIONS: - DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); + DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__); /* TODO */ break; #endif /* RNDIS_OPTIONAL_STATS */ @@ -657,7 +657,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, #ifdef RNDIS_PM /* power management OIDs (table 4-5) */ case OID_PNP_CAPABILITIES: - DBG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__); + DBG("%s: OID_PNP_CAPABILITIES\n", __func__); /* for now, no wakeup capabilities */ length = sizeof (struct NDIS_PNP_CAPABILITIES); @@ -665,7 +665,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; break; case OID_PNP_QUERY_POWER: - DBG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, + DBG("%s: OID_PNP_QUERY_POWER D%d\n", __func__, le32_to_cpu(get_unaligned((__le32 *)buf)) - 1); /* only suspend is a real power state, and * it can't be entered by OID_PNP_SET_POWER... @@ -677,7 +677,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, default: pr_warning("%s: query unknown OID 0x%08X\n", - __FUNCTION__, OID); + __func__, OID); } if (retval < 0) length = 0; @@ -729,7 +729,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, *params->filter = (u16) le32_to_cpu(get_unaligned( (__le32 *)buf)); DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", - __FUNCTION__, *params->filter); + __func__, *params->filter); /* this call has a significant side effect: it's * what makes the packet flow start and stop, like @@ -753,7 +753,7 @@ update_linkstate: case OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ - DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); + DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); retval = 0; break; #if 0 @@ -762,7 +762,7 @@ update_linkstate: struct rndis_config_parameter *param; param = (struct rndis_config_parameter *) buf; DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", - __FUNCTION__, + __func__, min(cpu_to_le32(param->ParameterNameLength),80), buf + param->ParameterNameOffset); retval = 0; @@ -778,7 +778,7 @@ update_linkstate: * FIXME ... then things go batty; Windows wedges itself. */ i = le32_to_cpu(get_unaligned((__le32 *)buf)); - DBG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); + DBG("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1); switch (i) { case NdisDeviceStateD0: *params->filter = params->saved_filter; @@ -802,7 +802,7 @@ update_linkstate: default: pr_warning("%s: set unknown OID 0x%08X, size %d\n", - __FUNCTION__, OID, buf_len); + __func__, OID, buf_len); } return retval; @@ -855,7 +855,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) rndis_query_cmplt_type *resp; rndis_resp_t *r; - // DBG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); + // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; /* @@ -908,9 +908,9 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) BufOffset = le32_to_cpu (buf->InformationBufferOffset); #ifdef VERBOSE - DBG("%s: Length: %d\n", __FUNCTION__, BufLength); - DBG("%s: Offset: %d\n", __FUNCTION__, BufOffset); - DBG("%s: InfoBuffer: ", __FUNCTION__); + DBG("%s: Length: %d\n", __func__, BufLength); + DBG("%s: Offset: %d\n", __func__, BufOffset); + DBG("%s: InfoBuffer: ", __func__); for (i = 0; i < BufLength; i++) { DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); @@ -1080,14 +1080,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf) switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", - __FUNCTION__ ); + __func__ ); params->state = RNDIS_INITIALIZED; return rndis_init_response (configNr, (rndis_init_msg_type *) buf); case REMOTE_NDIS_HALT_MSG: DBG("%s: REMOTE_NDIS_HALT_MSG\n", - __FUNCTION__ ); + __func__ ); params->state = RNDIS_UNINITIALIZED; if (params->dev) { netif_carrier_off (params->dev); @@ -1105,7 +1105,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) case REMOTE_NDIS_RESET_MSG: DBG("%s: REMOTE_NDIS_RESET_MSG\n", - __FUNCTION__ ); + __func__ ); return rndis_reset_response (configNr, (rndis_reset_msg_type *) buf); @@ -1113,7 +1113,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", - __FUNCTION__ ); + __func__ ); return rndis_keepalive_response (configNr, (rndis_keepalive_msg_type *) buf); @@ -1124,7 +1124,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf) * suspending itself. */ pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", - __FUNCTION__ , MsgType, MsgLength); + __func__ , MsgType, MsgLength); { unsigned i; for (i = 0; i < MsgLength; i += 16) { @@ -1159,7 +1159,7 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *)) if (!rndis_per_dev_params [i].used) { rndis_per_dev_params [i].used = 1; rndis_per_dev_params [i].ack = rndis_control_ack; - DBG("%s: configNr = %d\n", __FUNCTION__, i); + DBG("%s: configNr = %d\n", __func__, i); return i; } } @@ -1170,7 +1170,7 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *)) void rndis_deregister (int configNr) { - DBG("%s: \n", __FUNCTION__ ); + DBG("%s: \n", __func__ ); if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params [configNr].used = 0; @@ -1182,7 +1182,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev, struct net_device_stats *stats, u16 *cdc_filter) { - DBG("%s:\n", __FUNCTION__ ); + DBG("%s:\n", __func__ ); if (!dev || !stats) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; @@ -1195,7 +1195,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev, int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) { - DBG("%s:\n", __FUNCTION__ ); + DBG("%s:\n", __func__ ); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; @@ -1207,7 +1207,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) { - DBG("%s: %u %u\n", __FUNCTION__, medium, speed); + DBG("%s: %u %u\n", __func__, medium, speed); if (configNr >= RNDIS_MAX_CONFIGS) return -1; rndis_per_dev_params [configNr].medium = medium; @@ -1415,7 +1415,7 @@ int __init rndis_init (void) if (!(rndis_connect_state [i] = create_proc_entry (name, 0660, NULL))) { - DBG("%s :remove entries", __FUNCTION__); + DBG("%s :remove entries", __func__); while (i) { sprintf (name, NAME_TEMPLATE, --i); remove_proc_entry (name, NULL); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 315c7c14aaa8..5ae689139dd0 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -251,7 +251,7 @@ __acquires(ehci->lock) #ifdef EHCI_URB_TRACE ehci_dbg (ehci, "%s %s urb %p ep%d%s status %d len %d/%d\n", - __FUNCTION__, urb->dev->devpath, urb, + __func__, urb->dev->devpath, urb, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", status, @@ -974,7 +974,7 @@ submit_async ( #ifdef EHCI_URB_TRACE ehci_dbg (ehci, "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", - __FUNCTION__, urb->dev->devpath, urb, + __func__, urb->dev->devpath, urb, epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", urb->transfer_buffer_length, qtd, urb->ep->hcpriv); diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e3cfe0a03552..be575e46eac3 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1677,7 +1677,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, #ifdef EHCI_URB_TRACE ehci_dbg (ehci, "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n", - __FUNCTION__, urb->dev->devpath, urb, + __func__, urb->dev->devpath, urb, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", urb->transfer_buffer_length, diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 0ee694f043cc..ae6e70edd745 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -106,7 +106,7 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", - __FUNCTION__, legsup); + __func__, legsup); goto reset_needed; } @@ -114,14 +114,14 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || !(cmd & UHCI_USBCMD_EGSM)) { dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", - __FUNCTION__, cmd); + __func__, cmd); goto reset_needed; } intr = inw(base + UHCI_USBINTR); if (intr & (~UHCI_USBINTR_RESUME)) { dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", - __FUNCTION__, intr); + __func__, intr); goto reset_needed; } return 0; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index df256d61e2c6..274276cf8621 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1335,7 +1335,7 @@ static int sl811h_bus_suspend(struct usb_hcd *hcd) { // SOFs off - DBG("%s\n", __FUNCTION__); + DBG("%s\n", __func__); return 0; } @@ -1343,7 +1343,7 @@ static int sl811h_bus_resume(struct usb_hcd *hcd) { // SOFs on - DBG("%s\n", __FUNCTION__); + DBG("%s\n", __func__); return 0; } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index f65d5a858733..d3e0d8aa3980 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -335,7 +335,7 @@ __releases(uhci->lock) __acquires(uhci->lock) { dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, - "%s%s\n", __FUNCTION__, + "%s%s\n", __func__, uhci->rh_state == UHCI_RH_AUTO_STOPPED ? " (auto-start)" : ""); @@ -735,7 +735,7 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) struct uhci_hcd *uhci = hcd_to_uhci(hcd); int rc = 0; - dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); + dev_dbg(uhci_dev(uhci), "%s\n", __func__); spin_lock_irq(&uhci->lock); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) @@ -771,7 +771,7 @@ static int uhci_pci_resume(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); + dev_dbg(uhci_dev(uhci), "%s\n", __func__); /* Since we aren't in D3 any more, it's safe to set this flag * even if the controller was dead. diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 60379b17bbc1..db645936eedd 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1171,7 +1171,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) /* Some debugging code */ dev_dbg(&urb->dev->dev, "%s: failed with status %x\n", - __FUNCTION__, status); + __func__, status); if (debug > 1 && errbuf) { /* Print the chain for debugging */ diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 5a2c44e4c1f7..965f6eaea6a0 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -147,10 +147,10 @@ static void adu_abort_transfers(struct adu_device *dev) { unsigned long flags; - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); if (dev->udev == NULL) { - dbg(1," %s : udev is null", __FUNCTION__); + dbg(1," %s : udev is null", __func__); goto exit; } @@ -172,12 +172,12 @@ static void adu_abort_transfers(struct adu_device *dev) spin_unlock_irqrestore(&dev->buflock, flags); exit: - dbg(2," %s : leave", __FUNCTION__); + dbg(2," %s : leave", __func__); } static void adu_delete(struct adu_device *dev) { - dbg(2, "%s enter", __FUNCTION__); + dbg(2, "%s enter", __func__); /* free data structures */ usb_free_urb(dev->interrupt_in_urb); @@ -188,7 +188,7 @@ static void adu_delete(struct adu_device *dev) kfree(dev->interrupt_out_buffer); kfree(dev); - dbg(2, "%s : leave", __FUNCTION__); + dbg(2, "%s : leave", __func__); } static void adu_interrupt_in_callback(struct urb *urb) @@ -196,8 +196,8 @@ static void adu_interrupt_in_callback(struct urb *urb) struct adu_device *dev = urb->context; int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); - adu_debug_data(5, __FUNCTION__, urb->actual_length, + dbg(4," %s : enter, status %d", __func__, status); + adu_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); spin_lock(&dev->buflock); @@ -206,7 +206,7 @@ static void adu_interrupt_in_callback(struct urb *urb) if ((status != -ENOENT) && (status != -ECONNRESET) && (status != -ESHUTDOWN)) { dbg(1," %s : nonzero status received: %d", - __FUNCTION__, status); + __func__, status); } goto exit; } @@ -220,10 +220,10 @@ static void adu_interrupt_in_callback(struct urb *urb) dev->interrupt_in_buffer, urb->actual_length); dev->read_buffer_length += urb->actual_length; - dbg(2," %s reading %d ", __FUNCTION__, + dbg(2," %s reading %d ", __func__, urb->actual_length); } else { - dbg(1," %s : read_buffer overflow", __FUNCTION__); + dbg(1," %s : read_buffer overflow", __func__); } } @@ -232,9 +232,9 @@ exit: spin_unlock(&dev->buflock); /* always wake up so we recover from errors */ wake_up_interruptible(&dev->read_wait); - adu_debug_data(5, __FUNCTION__, urb->actual_length, + adu_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __func__, status); } static void adu_interrupt_out_callback(struct urb *urb) @@ -242,14 +242,14 @@ static void adu_interrupt_out_callback(struct urb *urb) struct adu_device *dev = urb->context; int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); - adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); + dbg(4," %s : enter, status %d", __func__, status); + adu_debug_data(5,__func__, urb->actual_length, urb->transfer_buffer); if (status != 0) { if ((status != -ENOENT) && (status != -ECONNRESET)) { dbg(1, " %s :nonzero status received: %d", - __FUNCTION__, status); + __func__, status); } goto exit; } @@ -260,9 +260,9 @@ static void adu_interrupt_out_callback(struct urb *urb) spin_unlock(&dev->buflock); exit: - adu_debug_data(5, __FUNCTION__, urb->actual_length, + adu_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __func__, status); } static int adu_open(struct inode *inode, struct file *file) @@ -272,19 +272,19 @@ static int adu_open(struct inode *inode, struct file *file) int subminor; int retval; - dbg(2,"%s : enter", __FUNCTION__); + dbg(2,"%s : enter", __func__); subminor = iminor(inode); if ((retval = mutex_lock_interruptible(&adutux_mutex))) { - dbg(2, "%s : mutex lock failed", __FUNCTION__); + dbg(2, "%s : mutex lock failed", __func__); goto exit_no_lock; } interface = usb_find_interface(&adu_driver, subminor); if (!interface) { err("%s - error, can't find device for minor %d", - __FUNCTION__, subminor); + __func__, subminor); retval = -ENODEV; goto exit_no_device; } @@ -302,7 +302,7 @@ static int adu_open(struct inode *inode, struct file *file) } ++dev->open_count; - dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count); + dbg(2,"%s : open count %d", __func__, dev->open_count); /* save device in the file's private structure */ file->private_data = dev; @@ -332,23 +332,23 @@ static int adu_open(struct inode *inode, struct file *file) exit_no_device: mutex_unlock(&adutux_mutex); exit_no_lock: - dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); + dbg(2,"%s : leave, return value %d ", __func__, retval); return retval; } static void adu_release_internal(struct adu_device *dev) { - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); /* decrement our usage count for the device */ --dev->open_count; - dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); + dbg(2," %s : open count %d", __func__, dev->open_count); if (dev->open_count <= 0) { adu_abort_transfers(dev); dev->open_count = 0; } - dbg(2," %s : leave", __FUNCTION__); + dbg(2," %s : leave", __func__); } static int adu_release(struct inode *inode, struct file *file) @@ -356,17 +356,17 @@ static int adu_release(struct inode *inode, struct file *file) struct adu_device *dev; int retval = 0; - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); if (file == NULL) { - dbg(1," %s : file is NULL", __FUNCTION__); + dbg(1," %s : file is NULL", __func__); retval = -ENODEV; goto exit; } dev = file->private_data; if (dev == NULL) { - dbg(1," %s : object is NULL", __FUNCTION__); + dbg(1," %s : object is NULL", __func__); retval = -ENODEV; goto exit; } @@ -374,7 +374,7 @@ static int adu_release(struct inode *inode, struct file *file) mutex_lock(&adutux_mutex); /* not interruptible */ if (dev->open_count <= 0) { - dbg(1," %s : device not opened", __FUNCTION__); + dbg(1," %s : device not opened", __func__); retval = -ENODEV; goto exit; } @@ -388,7 +388,7 @@ static int adu_release(struct inode *inode, struct file *file) exit: mutex_unlock(&adutux_mutex); - dbg(2," %s : leave, return value %d", __FUNCTION__, retval); + dbg(2," %s : leave, return value %d", __func__, retval); return retval; } @@ -405,10 +405,10 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, unsigned long flags; DECLARE_WAITQUEUE(wait, current); - dbg(2," %s : enter, count = %Zd, file=%p", __FUNCTION__, count, file); + dbg(2," %s : enter, count = %Zd, file=%p", __func__, count, file); dev = file->private_data; - dbg(2," %s : dev=%p", __FUNCTION__, dev); + dbg(2," %s : dev=%p", __func__, dev); if (mutex_lock_interruptible(&dev->mtx)) return -ERESTARTSYS; @@ -422,16 +422,16 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, /* verify that some data was requested */ if (count == 0) { - dbg(1," %s : read request of 0 bytes", __FUNCTION__); + dbg(1," %s : read request of 0 bytes", __func__); goto exit; } timeout = COMMAND_TIMEOUT; - dbg(2," %s : about to start looping", __FUNCTION__); + dbg(2," %s : about to start looping", __func__); while (bytes_to_read) { int data_in_secondary = dev->secondary_tail - dev->secondary_head; dbg(2," %s : while, data_in_secondary=%d, status=%d", - __FUNCTION__, data_in_secondary, + __func__, data_in_secondary, dev->interrupt_in_urb->status); if (data_in_secondary) { @@ -456,7 +456,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, /* we secure access to the primary */ char *tmp; dbg(2," %s : swap, read_buffer_length = %d", - __FUNCTION__, dev->read_buffer_length); + __func__, dev->read_buffer_length); tmp = dev->read_buffer_secondary; dev->read_buffer_secondary = dev->read_buffer_primary; dev->read_buffer_primary = tmp; @@ -471,10 +471,10 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, if (!dev->read_urb_finished) { /* somebody is doing IO */ spin_unlock_irqrestore(&dev->buflock, flags); - dbg(2," %s : submitted already", __FUNCTION__); + dbg(2," %s : submitted already", __func__); } else { /* we must initiate input */ - dbg(2," %s : initiate input", __FUNCTION__); + dbg(2," %s : initiate input", __func__); dev->read_urb_finished = 0; spin_unlock_irqrestore(&dev->buflock, flags); @@ -492,7 +492,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, if (retval == -ENOMEM) { retval = bytes_read ? bytes_read : -ENOMEM; } - dbg(2," %s : submit failed", __FUNCTION__); + dbg(2," %s : submit failed", __func__); goto exit; } } @@ -511,13 +511,13 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, remove_wait_queue(&dev->read_wait, &wait); if (timeout <= 0) { - dbg(2," %s : timeout", __FUNCTION__); + dbg(2," %s : timeout", __func__); retval = bytes_read ? bytes_read : -ETIMEDOUT; goto exit; } if (signal_pending(current)) { - dbg(2," %s : signal pending", __FUNCTION__); + dbg(2," %s : signal pending", __func__); retval = bytes_read ? bytes_read : -EINTR; goto exit; } @@ -550,7 +550,7 @@ exit: /* unlock the device */ mutex_unlock(&dev->mtx); - dbg(2," %s : leave, return value %d", __FUNCTION__, retval); + dbg(2," %s : leave, return value %d", __func__, retval); return retval; } @@ -565,7 +565,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, unsigned long flags; int retval; - dbg(2," %s : enter, count = %Zd", __FUNCTION__, count); + dbg(2," %s : enter, count = %Zd", __func__, count); dev = file->private_data; @@ -582,7 +582,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, /* verify that we actually have some data to write */ if (count == 0) { - dbg(1," %s : write request of 0 bytes", __FUNCTION__); + dbg(1," %s : write request of 0 bytes", __func__); goto exit; } @@ -595,13 +595,13 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, mutex_unlock(&dev->mtx); if (signal_pending(current)) { - dbg(1," %s : interrupted", __FUNCTION__); + dbg(1," %s : interrupted", __func__); set_current_state(TASK_RUNNING); retval = -EINTR; goto exit_onqueue; } if (schedule_timeout(COMMAND_TIMEOUT) == 0) { - dbg(1, "%s - command timed out.", __FUNCTION__); + dbg(1, "%s - command timed out.", __func__); retval = -ETIMEDOUT; goto exit_onqueue; } @@ -612,18 +612,18 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, goto exit_nolock; } - dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count); + dbg(4," %s : in progress, count = %Zd", __func__, count); } else { spin_unlock_irqrestore(&dev->buflock, flags); set_current_state(TASK_RUNNING); remove_wait_queue(&dev->write_wait, &waita); - dbg(4," %s : sending, count = %Zd", __FUNCTION__, count); + dbg(4," %s : sending, count = %Zd", __func__, count); /* write the data into interrupt_out_buffer from userspace */ buffer_size = le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize); bytes_to_write = count > buffer_size ? buffer_size : count; dbg(4," %s : buffer_size = %Zd, count = %Zd, bytes_to_write = %Zd", - __FUNCTION__, buffer_size, count, bytes_to_write); + __func__, buffer_size, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write) != 0) { retval = -EFAULT; @@ -661,7 +661,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, exit: mutex_unlock(&dev->mtx); exit_nolock: - dbg(2," %s : leave, return value %d", __FUNCTION__, retval); + dbg(2," %s : leave, return value %d", __func__, retval); return retval; exit_onqueue: @@ -706,7 +706,7 @@ static int adu_probe(struct usb_interface *interface, int out_end_size; int i; - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); if (udev == NULL) { dev_err(&interface->dev, "udev is NULL.\n"); @@ -807,7 +807,7 @@ static int adu_probe(struct usb_interface *interface, dev_err(&interface->dev, "Could not retrieve serial number\n"); goto error; } - dbg(2," %s : serial_number=%s", __FUNCTION__, dev->serial_number); + dbg(2," %s : serial_number=%s", __func__, dev->serial_number); /* we can register the device now, as it is ready */ usb_set_intfdata(interface, dev); @@ -828,7 +828,7 @@ static int adu_probe(struct usb_interface *interface, udev->descriptor.idProduct, dev->serial_number, (dev->minor - ADU_MINOR_BASE)); exit: - dbg(2," %s : leave, return value %p (dev)", __FUNCTION__, dev); + dbg(2," %s : leave, return value %p (dev)", __func__, dev); return retval; @@ -847,7 +847,7 @@ static void adu_disconnect(struct usb_interface *interface) struct adu_device *dev; int minor; - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); dev = usb_get_intfdata(interface); @@ -861,7 +861,7 @@ static void adu_disconnect(struct usb_interface *interface) usb_set_intfdata(interface, NULL); /* if the device is not opened, then we clean up right now */ - dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); + dbg(2," %s : open count %d", __func__, dev->open_count); if (!dev->open_count) adu_delete(dev); @@ -870,7 +870,7 @@ static void adu_disconnect(struct usb_interface *interface) dev_info(&interface->dev, "ADU device adutux%d now disconnected\n", (minor - ADU_MINOR_BASE)); - dbg(2," %s : leave", __FUNCTION__); + dbg(2," %s : leave", __func__); } /* usb specific object needed to register this driver with the usb subsystem */ @@ -885,7 +885,7 @@ static int __init adu_init(void) { int result; - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); /* register this driver with the USB subsystem */ result = usb_register(&adu_driver); @@ -899,17 +899,17 @@ static int __init adu_init(void) info("adutux is an experimental driver. Use at your own risk"); exit: - dbg(2," %s : leave, return value %d", __FUNCTION__, result); + dbg(2," %s : leave, return value %d", __func__, result); return result; } static void __exit adu_exit(void) { - dbg(2," %s : enter", __FUNCTION__); + dbg(2," %s : enter", __func__); /* deregister this driver with the USB subsystem */ usb_deregister(&adu_driver); - dbg(2," %s : leave", __FUNCTION__); + dbg(2," %s : leave", __func__); } module_init(adu_init); diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index a5e4c3545c72..a076c24a312a 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -103,11 +103,11 @@ static void appledisplay_complete(struct urb *urb) case -ESHUTDOWN: /* This urb is terminated, clean up */ dbg("%s - urb shuttingdown with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } @@ -131,7 +131,7 @@ exit: retval = usb_submit_urb(pdata->urb, GFP_ATOMIC); if (retval) { err("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __func__, retval); } } diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 81d051ca2291..309c743a09d5 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -983,7 +983,7 @@ static void auerswald_int_complete (struct urb * urb) pauerbuf_t bp = NULL; pauerswald_t cp = (pauerswald_t) urb->context; - dbg ("%s called", __FUNCTION__); + dbg ("%s called", __func__); switch (status) { case 0: @@ -993,10 +993,10 @@ static void auerswald_int_complete (struct urb * urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } @@ -1081,7 +1081,7 @@ exit: ret = usb_submit_urb (urb, GFP_ATOMIC); if (ret) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, ret); + __func__, ret); } /* int memory deallocation diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 4a09b87bdd28..4b9dc81b8453 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -70,8 +70,8 @@ static int emi26_writememory (struct usb_device *dev, int address, unsigned char static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit) { int response; - info("%s - %d", __FUNCTION__, reset_bit); - /* printk(KERN_DEBUG "%s - %d", __FUNCTION__, reset_bit); */ + info("%s - %d", __func__, reset_bit); + /* printk(KERN_DEBUG "%s - %d", __func__, reset_bit); */ response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { err("emi26: set_reset (%d) failed", reset_bit); @@ -91,7 +91,7 @@ static int emi26_load_firmware (struct usb_device *dev) buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); if (!buf) { - err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM); + err( "%s - error loading firmware: error = %d", __func__, -ENOMEM); err = -ENOMEM; goto wraperr; } @@ -99,7 +99,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) { - err( "%s - error loading firmware: error = %d", __FUNCTION__, err); + err( "%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -107,7 +107,7 @@ static int emi26_load_firmware (struct usb_device *dev) for (i=0; g_Loader[i].type == 0; i++) { err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -115,7 +115,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); /* let device settle */ @@ -135,7 +135,7 @@ static int emi26_load_firmware (struct usb_device *dev) } err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } while (i > 0); @@ -143,7 +143,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -151,7 +151,7 @@ static int emi26_load_firmware (struct usb_device *dev) for (i=0; g_Loader[i].type == 0; i++) { err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -160,7 +160,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -169,7 +169,7 @@ static int emi26_load_firmware (struct usb_device *dev) if (!INTERNAL_RAM(g_Firmware[i].address)) { err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -178,7 +178,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -186,7 +186,7 @@ static int emi26_load_firmware (struct usb_device *dev) if (INTERNAL_RAM(g_Firmware[i].address)) { err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -195,7 +195,7 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); /* let device settle */ @@ -221,7 +221,7 @@ static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *i { struct usb_device *dev = interface_to_usbdev(intf); - info("%s start", __FUNCTION__); + info("%s start", __func__); emi26_load_firmware(dev); diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index d1362415922c..1a2b79ac5e10 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -78,7 +78,7 @@ static int emi62_writememory (struct usb_device *dev, int address, unsigned char static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit) { int response; - info("%s - %d", __FUNCTION__, reset_bit); + info("%s - %d", __func__, reset_bit); response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { @@ -100,7 +100,7 @@ static int emi62_load_firmware (struct usb_device *dev) dev_dbg(&dev->dev, "load_firmware\n"); buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); if (!buf) { - err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM); + err( "%s - error loading firmware: error = %d", __func__, -ENOMEM); err = -ENOMEM; goto wraperr; } @@ -108,7 +108,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -116,7 +116,7 @@ static int emi62_load_firmware (struct usb_device *dev) for (i=0; g_emi62_loader[i].type == 0; i++) { err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -124,7 +124,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); /* let device settle */ @@ -144,7 +144,7 @@ static int emi62_load_firmware (struct usb_device *dev) } err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } while (i > 0); @@ -152,7 +152,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -160,7 +160,7 @@ static int emi62_load_firmware (struct usb_device *dev) for (i=0; g_emi62_loader[i].type == 0; i++) { err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -168,7 +168,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); /* let device settle */ @@ -181,7 +181,7 @@ static int emi62_load_firmware (struct usb_device *dev) if (!INTERNAL_RAM(g_HexSpdifFw62[i].address)) { err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_EXTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -191,7 +191,7 @@ static int emi62_load_firmware (struct usb_device *dev) if (!INTERNAL_RAM(g_HexMidiFw62[i].address)) { err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_EXTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d\n", __FUNCTION__, err); + err("%s - error loading firmware: error = %d\n", __func__, err); goto wraperr; return err; } @@ -201,7 +201,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } @@ -211,7 +211,7 @@ static int emi62_load_firmware (struct usb_device *dev) if (INTERNAL_RAM(g_HexSpdifFw62[i].address)) { err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } @@ -221,7 +221,7 @@ static int emi62_load_firmware (struct usb_device *dev) if (INTERNAL_RAM(g_HexMidiFw62[i].address)) { err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_INTERNAL); if (err < 0) { - err("%s - error loading firmware: error = %d\n", __FUNCTION__, err); + err("%s - error loading firmware: error = %d\n", __func__, err); goto wraperr; } } @@ -231,7 +231,7 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); if (err < 0) { - err("%s - error loading firmware: error = %d", __FUNCTION__, err); + err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); /* let device settle */ @@ -260,7 +260,7 @@ static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_device *dev = interface_to_usbdev(intf); dev_dbg(&intf->dev, "emi62_probe\n"); - info("%s start", __FUNCTION__); + info("%s start", __func__); emi62_load_firmware(dev); diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 801070502cc1..0a2549bc0540 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -218,7 +218,7 @@ exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n", - __FUNCTION__, retval); + __func__, retval); } @@ -453,7 +453,7 @@ static ssize_t iowarrior_write(struct file *file, default: /* what do we have here ? An unsupported Product-ID ? */ dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n", - __FUNCTION__, dev->product_id); + __func__, dev->product_id); retval = -EFAULT; goto exit; break; @@ -604,7 +604,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) interface = usb_find_interface(&iowarrior_driver, subminor); if (!interface) { - err("%s - error, can't find device for minor %d", __FUNCTION__, + err("%s - error, can't find device for minor %d", __func__, subminor); return -ENODEV; } diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index c730d20eec66..11580e81e2c6 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -231,7 +231,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) goto exit; } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", - __FUNCTION__, status); + __func__, status); spin_lock(&dev->rbsl); goto resubmit; /* maybe we can recover */ } @@ -247,7 +247,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length); dev->ring_head = next_ring_head; dbg_info(&dev->intf->dev, "%s: received %d bytes\n", - __FUNCTION__, urb->actual_length); + __func__, urb->actual_length); } else { dev_warn(&dev->intf->dev, "Ring buffer overflow, %d bytes dropped\n", @@ -286,7 +286,7 @@ static void ld_usb_interrupt_out_callback(struct urb *urb) status == -ESHUTDOWN)) dbg_info(&dev->intf->dev, "%s - nonzero write interrupt status received: %d\n", - __FUNCTION__, status); + __func__, status); dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); @@ -309,7 +309,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) if (!interface) { err("%s - error, can't find device for minor %d\n", - __FUNCTION__, subminor); + __func__, subminor); return -ENODEV; } @@ -556,7 +556,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write); - dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write); + dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 6664043f4645..fae5b1730ba2 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -31,7 +31,7 @@ * - imported into lejos project * - changed wake_up to wake_up_interruptible * - changed to use lego0 rather than tower0 - * - changed dbg() to use __func__ rather than deprecated __FUNCTION__ + * - changed dbg() to use __func__ rather than deprecated __func__ * 2003-01-12 - 0.53 david (david@csse.uwa.edu.au) * - changed read and write to write everything or * timeout (from a patch by Chris Riesen and Brett Thaeler driver) @@ -49,7 +49,7 @@ * - added poll * - forbid seeking * - added nonblocking I/O - * - changed back __func__ to __FUNCTION__ + * - changed back __func__ to __func__ * - read and log tower firmware version * - reset tower on probe, avoids failure of first write * 2004-03-09 - 0.7 Juergen Stuber @@ -309,7 +309,7 @@ static inline void lego_usb_tower_debug_data (int level, const char *function, i */ static inline void tower_delete (struct lego_usb_tower *dev) { - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); tower_abort_transfers (dev); @@ -321,7 +321,7 @@ static inline void tower_delete (struct lego_usb_tower *dev) kfree (dev->interrupt_out_buffer); kfree (dev); - dbg(2, "%s: leave", __FUNCTION__); + dbg(2, "%s: leave", __func__); } @@ -337,7 +337,7 @@ static int tower_open (struct inode *inode, struct file *file) struct tower_reset_reply reset_reply; int result; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); nonseekable_open(inode, file); subminor = iminor(inode); @@ -346,7 +346,7 @@ static int tower_open (struct inode *inode, struct file *file) if (!interface) { err ("%s - error, can't find device for minor %d", - __FUNCTION__, subminor); + __func__, subminor); retval = -ENODEV; goto exit; } @@ -424,7 +424,7 @@ unlock_exit: mutex_unlock(&dev->lock); exit: - dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); + dbg(2, "%s: leave, return value %d ", __func__, retval); return retval; } @@ -437,12 +437,12 @@ static int tower_release (struct inode *inode, struct file *file) struct lego_usb_tower *dev; int retval = 0; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); dev = (struct lego_usb_tower *)file->private_data; if (dev == NULL) { - dbg(1, "%s: object is NULL", __FUNCTION__); + dbg(1, "%s: object is NULL", __func__); retval = -ENODEV; goto exit_nolock; } @@ -454,7 +454,7 @@ static int tower_release (struct inode *inode, struct file *file) } if (dev->open_count != 1) { - dbg(1, "%s: device not opened exactly once", __FUNCTION__); + dbg(1, "%s: device not opened exactly once", __func__); retval = -ENODEV; goto unlock_exit; } @@ -480,7 +480,7 @@ unlock_exit: exit: mutex_unlock(&open_disc_mutex); exit_nolock: - dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); + dbg(2, "%s: leave, return value %d", __func__, retval); return retval; } @@ -491,10 +491,10 @@ exit_nolock: */ static void tower_abort_transfers (struct lego_usb_tower *dev) { - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); if (dev == NULL) { - dbg(1, "%s: dev is null", __FUNCTION__); + dbg(1, "%s: dev is null", __func__); goto exit; } @@ -509,7 +509,7 @@ static void tower_abort_transfers (struct lego_usb_tower *dev) usb_kill_urb(dev->interrupt_out_urb); exit: - dbg(2, "%s: leave", __FUNCTION__); + dbg(2, "%s: leave", __func__); } @@ -542,7 +542,7 @@ static unsigned int tower_poll (struct file *file, poll_table *wait) struct lego_usb_tower *dev; unsigned int mask = 0; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); dev = file->private_data; @@ -557,7 +557,7 @@ static unsigned int tower_poll (struct file *file, poll_table *wait) mask |= POLLOUT | POLLWRNORM; } - dbg(2, "%s: leave, mask = %d", __FUNCTION__, mask); + dbg(2, "%s: leave, mask = %d", __func__, mask); return mask; } @@ -583,7 +583,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, int retval = 0; unsigned long timeout = 0; - dbg(2, "%s: enter, count = %Zd", __FUNCTION__, count); + dbg(2, "%s: enter, count = %Zd", __func__, count); dev = (struct lego_usb_tower *)file->private_data; @@ -602,7 +602,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, /* verify that we actually have some data to read */ if (count == 0) { - dbg(1, "%s: read request of 0 bytes", __FUNCTION__); + dbg(1, "%s: read request of 0 bytes", __func__); goto unlock_exit; } @@ -658,7 +658,7 @@ unlock_exit: mutex_unlock(&dev->lock); exit: - dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); + dbg(2, "%s: leave, return value %d", __func__, retval); return retval; } @@ -672,7 +672,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t size_t bytes_to_write; int retval = 0; - dbg(2, "%s: enter, count = %Zd", __FUNCTION__, count); + dbg(2, "%s: enter, count = %Zd", __func__, count); dev = (struct lego_usb_tower *)file->private_data; @@ -691,7 +691,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t /* verify that we actually have some data to write */ if (count == 0) { - dbg(1, "%s: write request of 0 bytes", __FUNCTION__); + dbg(1, "%s: write request of 0 bytes", __func__); goto unlock_exit; } @@ -709,7 +709,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t /* write the data into interrupt_out_buffer from userspace */ bytes_to_write = min_t(int, count, write_buffer_size); - dbg(4, "%s: count = %Zd, bytes_to_write = %Zd", __FUNCTION__, count, bytes_to_write); + dbg(4, "%s: count = %Zd, bytes_to_write = %Zd", __func__, count, bytes_to_write); if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; @@ -742,7 +742,7 @@ unlock_exit: mutex_unlock(&dev->lock); exit: - dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); + dbg(2, "%s: leave, return value %d", __func__, retval); return retval; } @@ -757,9 +757,9 @@ static void tower_interrupt_in_callback (struct urb *urb) int status = urb->status; int retval; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); + dbg(4, "%s: enter, status %d", __func__, status); - lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); + lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); if (status) { if (status == -ENOENT || @@ -767,7 +767,7 @@ static void tower_interrupt_in_callback (struct urb *urb) status == -ESHUTDOWN) { goto exit; } else { - dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status); + dbg(1, "%s: nonzero status received: %d", __func__, status); goto resubmit; /* maybe we can recover */ } } @@ -780,9 +780,9 @@ static void tower_interrupt_in_callback (struct urb *urb) urb->actual_length); dev->read_buffer_length += urb->actual_length; dev->read_last_arrival = jiffies; - dbg(3, "%s: received %d bytes", __FUNCTION__, urb->actual_length); + dbg(3, "%s: received %d bytes", __func__, urb->actual_length); } else { - printk(KERN_WARNING "%s: read_buffer overflow, %d bytes dropped", __FUNCTION__, urb->actual_length); + printk(KERN_WARNING "%s: read_buffer overflow, %d bytes dropped", __func__, urb->actual_length); } spin_unlock (&dev->read_buffer_lock); } @@ -792,7 +792,7 @@ resubmit: if (dev->interrupt_in_running && dev->udev) { retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC); if (retval) { - err("%s: usb_submit_urb failed (%d)", __FUNCTION__, retval); + err("%s: usb_submit_urb failed (%d)", __func__, retval); } } @@ -800,8 +800,8 @@ exit: dev->interrupt_in_done = 1; wake_up_interruptible (&dev->read_wait); - lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); + dbg(4, "%s: leave, status %d", __func__, status); } @@ -813,22 +813,22 @@ static void tower_interrupt_out_callback (struct urb *urb) struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; int status = urb->status; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); - lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); + dbg(4, "%s: enter, status %d", __func__, status); + lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); /* sync/async unlink faults aren't errors */ if (status && !(status == -ENOENT || status == -ECONNRESET || status == -ESHUTDOWN)) { dbg(1, "%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); } dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); - lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer); + dbg(4, "%s: leave, status %d", __func__, status); } @@ -849,7 +849,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device int retval = -ENOMEM; int result; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); if (udev == NULL) { info ("udev is NULL."); @@ -978,7 +978,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device exit: - dbg(2, "%s: leave, return value 0x%.8lx (dev)", __FUNCTION__, (long) dev); + dbg(2, "%s: leave, return value 0x%.8lx (dev)", __func__, (long) dev); return retval; @@ -998,7 +998,7 @@ static void tower_disconnect (struct usb_interface *interface) struct lego_usb_tower *dev; int minor; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); dev = usb_get_intfdata (interface); mutex_lock(&open_disc_mutex); @@ -1023,7 +1023,7 @@ static void tower_disconnect (struct usb_interface *interface) info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); - dbg(2, "%s: leave", __FUNCTION__); + dbg(2, "%s: leave", __func__); } @@ -1036,7 +1036,7 @@ static int __init lego_usb_tower_init(void) int result; int retval = 0; - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); /* register this driver with the USB subsystem */ result = usb_register(&tower_driver); @@ -1049,7 +1049,7 @@ static int __init lego_usb_tower_init(void) info(DRIVER_DESC " " DRIVER_VERSION); exit: - dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); + dbg(2, "%s: leave, return value %d", __func__, retval); return retval; } @@ -1060,12 +1060,12 @@ exit: */ static void __exit lego_usb_tower_exit(void) { - dbg(2, "%s: enter", __FUNCTION__); + dbg(2, "%s: enter", __func__); /* deregister this driver with the USB subsystem */ usb_deregister (&tower_driver); - dbg(2, "%s: leave", __FUNCTION__); + dbg(2, "%s: leave", __func__); } module_init (lego_usb_tower_init); diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index aa9bcceabe74..24230c638b8e 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c @@ -113,7 +113,7 @@ static int set_outputs(struct interfacekit *kit) buffer = kzalloc(4, GFP_KERNEL); if (!buffer) { - dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); return -ENOMEM; } buffer[0] = (u8)kit->outputs; @@ -146,7 +146,7 @@ static int change_string(struct interfacekit *kit, const char *display, unsigned buffer = kmalloc(8, GFP_KERNEL); form_buffer = kmalloc(30, GFP_KERNEL); if ((!buffer) || (!form_buffer)) { - dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); goto exit; } @@ -216,7 +216,7 @@ static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, buffer = kzalloc(8, GFP_KERNEL); if (!buffer) { - dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); goto exit; } diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index 2ad09b1f4848..f0113c17cc5a 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c @@ -61,7 +61,7 @@ static int set_motor(struct motorcontrol *mc, int motor) buffer = kzalloc(8, GFP_KERNEL); if (!buffer) { - dev_err(&mc->intf->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&mc->intf->dev, "%s - out of memory\n", __func__); return -ENOMEM; } diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 0d9de2f73930..7d590c09434a 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c @@ -89,7 +89,7 @@ change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, buffer = kmalloc(6, GFP_KERNEL); if (!buffer) { dev_err(&servo->udev->dev, "%s - out of memory\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -162,7 +162,7 @@ change_position_v20(struct phidget_servo *servo, int servo_no, int degrees, buffer = kmalloc(2, GFP_KERNEL); if (!buffer) { dev_err(&servo->udev->dev, "%s - out of memory\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -259,7 +259,7 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL); if (dev == NULL) { - dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&interface->dev, "%s - out of memory\n", __func__); rc = -ENOMEM; goto out; } diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 20777d01db62..ada7bf898fe9 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -78,7 +78,7 @@ static int lcd_open(struct inode *inode, struct file *file) interface = usb_find_interface(&lcd_driver, subminor); if (!interface) { err ("USBLCD: %s - error, can't find device for minor %d", - __FUNCTION__, subminor); + __func__, subminor); return -ENODEV; } @@ -193,7 +193,7 @@ static void lcd_write_bulk_callback(struct urb *urb) status == -ECONNRESET || status == -ESHUTDOWN)) { dbg("USBLCD: %s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); } /* free up our allocated buffer */ @@ -248,7 +248,7 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz /* send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { - err("USBLCD: %s - failed submitting write urb, error %d", __FUNCTION__, retval); + err("USBLCD: %s - failed submitting write urb, error %d", __func__, retval); goto error_unanchor; } diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 2c4fd4d6df95..678fac86c467 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1136,7 +1136,7 @@ static int verify_not_halted (int ep, struct urb *urb) dbg ("ep %02x bogus status: %04x != 0", ep, status); return -EINVAL; } - retval = simple_io (urb, 1, 0, 0, __FUNCTION__); + retval = simple_io (urb, 1, 0, 0, __func__); if (retval != 0) return -EINVAL; return 0; @@ -1158,7 +1158,7 @@ static int verify_halted (int ep, struct urb *urb) dbg ("ep %02x bogus status: %04x != 1", ep, status); return -EINVAL; } - retval = simple_io (urb, 1, 0, -EPIPE, __FUNCTION__); + retval = simple_io (urb, 1, 0, -EPIPE, __func__); if (retval != -EPIPE) return -EINVAL; retval = simple_io (urb, 1, 0, -EPIPE, "verify_still_halted"); diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 1cd29cd6bd00..a238817762ad 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -210,7 +210,7 @@ static void aircable_send(struct usb_serial_port *port) struct aircable_private *priv = usb_get_serial_port_data(port); unsigned char* buf; u16 *dbuf; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->write_urb_busy) return; @@ -220,7 +220,7 @@ static void aircable_send(struct usb_serial_port *port) buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC); if (!buf) { - err("%s- kzalloc(%d) failed.", __FUNCTION__, + err("%s- kzalloc(%d) failed.", __func__, count + HCI_HEADER_LENGTH); return; } @@ -236,7 +236,7 @@ static void aircable_send(struct usb_serial_port *port) kfree(buf); port->write_urb_busy = 1; - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, count + HCI_HEADER_LENGTH, port->write_urb->transfer_buffer); port->write_urb->transfer_buffer_length = count + HCI_HEADER_LENGTH; @@ -246,7 +246,7 @@ static void aircable_send(struct usb_serial_port *port) if (result) { dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", - __FUNCTION__, result); + __func__, result); port->write_urb_busy = 0; } @@ -275,7 +275,7 @@ static void aircable_read(struct work_struct *work) if (!tty) { schedule_work(&priv->rx_work); - err("%s - No tty available", __FUNCTION__); + err("%s - No tty available", __func__); return ; } @@ -286,7 +286,7 @@ static void aircable_read(struct work_struct *work) tty_prepare_flip_string(tty, &data, count); if (!data){ - err("%s- kzalloc(%d) failed.", __FUNCTION__, count); + err("%s- kzalloc(%d) failed.", __func__, count); return; } @@ -332,7 +332,7 @@ static int aircable_attach (struct usb_serial *serial) priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); if (!priv){ - err("%s- kmalloc(%Zd) failed.", __FUNCTION__, + err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct aircable_private)); return -ENOMEM; } @@ -366,7 +366,7 @@ static void aircable_shutdown(struct usb_serial *serial) struct usb_serial_port *port = serial->port[0]; struct aircable_private *priv = usb_get_serial_port_data(port); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (priv) { serial_buf_free(priv->tx_buf); @@ -388,12 +388,12 @@ static int aircable_write(struct usb_serial_port *port, struct aircable_private *priv = usb_get_serial_port_data(port); int temp; - dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); + dbg("%s - port %d, %d bytes", __func__, port->number, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, source); + usb_serial_debug_data(debug, &port->dev, __func__, count, source); if (!count){ - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return count; } @@ -414,7 +414,7 @@ static void aircable_write_bulk_callback(struct urb *urb) int status = urb->status; int result; - dbg("%s - urb status: %d", __FUNCTION__ , status); + dbg("%s - urb status: %d", __func__ , status); /* This has been taken from cypress_m8.c cypress_write_int_callback */ switch (status) { @@ -426,21 +426,21 @@ static void aircable_write_bulk_callback(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); port->write_urb_busy = 0; return; default: /* error in the urb, so we have to resubmit it */ - dbg("%s - Overflow in write", __FUNCTION__); + dbg("%s - Overflow in write", __func__); dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); port->write_urb->transfer_buffer_length = 1; port->write_urb->dev = port->serial->dev; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", - __FUNCTION__, result); + __func__, result); else return; } @@ -460,17 +460,17 @@ static void aircable_read_bulk_callback(struct urb *urb) unsigned char *temp; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { - dbg("%s - urb status = %d", __FUNCTION__, status); + dbg("%s - urb status = %d", __func__, status); if (!port->open_count) { - dbg("%s - port is closed, exiting.", __FUNCTION__); + dbg("%s - port is closed, exiting.", __func__); return; } if (status == -EPROTO) { dbg("%s - caught -EPROTO, resubmitting the urb", - __FUNCTION__); + __func__); usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), @@ -482,14 +482,14 @@ static void aircable_read_bulk_callback(struct urb *urb) if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); return; } - dbg("%s - unable to handle the error, exiting.", __FUNCTION__); + dbg("%s - unable to handle the error, exiting.", __func__); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,urb->transfer_buffer); tty = port->tty; @@ -538,7 +538,7 @@ static void aircable_read_bulk_callback(struct urb *urb) if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); } return; @@ -550,7 +550,7 @@ static void aircable_throttle(struct usb_serial_port *port) struct aircable_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->rx_lock, flags); priv->rx_flags |= THROTTLED; @@ -564,7 +564,7 @@ static void aircable_unthrottle(struct usb_serial_port *port) int actually_throttled; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->rx_lock, flags); actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index d5bcb3774034..725b6b94c274 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -53,7 +53,7 @@ static int airprime_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct airprime_private *priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (port->number != 0) return 0; @@ -83,14 +83,14 @@ static void airprime_read_bulk_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { @@ -101,7 +101,7 @@ static void airprime_read_bulk_callback(struct urb *urb) result = usb_submit_urb (urb, GFP_ATOMIC); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); return; } @@ -112,14 +112,14 @@ static void airprime_write_bulk_callback(struct urb *urb) int status = urb->status; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree (urb->transfer_buffer); if (status) dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); spin_lock_irqsave(&priv->lock, flags); --priv->outstanding_urbs; spin_unlock_irqrestore(&priv->lock, flags); @@ -136,7 +136,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) int i; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* initialize our private data structure if it isn't already created */ if (!priv) { @@ -157,7 +157,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { dev_err(&port->dev, "%s - out of memory.\n", - __FUNCTION__); + __func__); result = -ENOMEM; goto errout; } @@ -165,7 +165,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) if (!urb) { kfree(buffer); dev_err(&port->dev, "%s - no more urbs?\n", - __FUNCTION__); + __func__); result = -ENOMEM; goto errout; } @@ -180,7 +180,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) kfree(buffer); dev_err(&port->dev, "%s - failed submitting read urb %d for port %d, error %d\n", - __FUNCTION__, i, port->number, result); + __func__, i, port->number, result); goto errout; } /* remember this urb so we can kill it when the port is closed */ @@ -212,7 +212,7 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) struct airprime_private *priv = usb_get_serial_port_data(port); int i; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); priv->rts_state = 0; priv->dtr_state = 0; @@ -242,12 +242,12 @@ static int airprime_write(struct usb_serial_port *port, unsigned char *buffer; unsigned long flags; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (priv->outstanding_urbs > NUM_WRITE_URBS) { spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } spin_unlock_irqrestore(&priv->lock, flags); @@ -264,7 +264,7 @@ static int airprime_write(struct usb_serial_port *port, } memcpy (buffer, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, @@ -277,7 +277,7 @@ static int airprime_write(struct usb_serial_port *port, if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", - __FUNCTION__, status); + __func__, status); count = status; kfree (buffer); } else { @@ -328,7 +328,7 @@ static int __init airprime_init(void) static void __exit airprime_exit(void) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); usb_deregister(&airprime_driver); usb_serial_deregister(&airprime_device); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index aa7a6838a3d4..9d708b22e955 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -173,7 +173,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, config = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (!priv->termios_initialized) { @@ -323,7 +323,7 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp) char *buf; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); buf = kmalloc(1, GFP_KERNEL); if (!buf) { @@ -395,7 +395,7 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, return -EFAULT; return 0; default: - dbg("%s cmd 0x%04x not supported", __FUNCTION__, cmd); + dbg("%s cmd 0x%04x not supported", __func__, cmd); break; } diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index b6950648804f..5a2877c22129 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -195,7 +195,7 @@ static void belkin_sa_shutdown (struct usb_serial *serial) struct belkin_sa_private *priv; int i; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { @@ -210,7 +210,7 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) { int retval = 0; - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); /*Start reading from the device*/ /* TODO: Look at possibility of submitting multiple URBs to device to @@ -237,7 +237,7 @@ exit: static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) { - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); /* shutdown our bulk reads and writes */ usb_kill_urb(port->write_urb); @@ -264,15 +264,15 @@ static void belkin_sa_read_int_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* Handle known interrupt data */ /* ignore data[0] and data[1] */ @@ -331,7 +331,7 @@ exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __func__, retval); } static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) @@ -478,7 +478,7 @@ static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file) unsigned long control_state; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&priv->lock, flags); control_state = priv->control_state; @@ -499,7 +499,7 @@ static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file, int rts = 0; int dtr = 0; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&priv->lock, flags); control_state = priv->control_state; diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 66ce30c1b75b..201184c3fb87 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -67,7 +67,7 @@ static int usb_console_setup(struct console *co, char *options) struct tty_struct *tty = NULL; struct ktermios *termios = NULL, dummy; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); if (options) { baud = simple_strtoul(options, NULL, 10); @@ -225,10 +225,10 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun if (count == 0) return; - dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); + dbg("%s - port %d, %d byte(s)", __func__, port->number, count); if (!port->open_count) { - dbg ("%s - port not opened", __FUNCTION__); + dbg ("%s - port not opened", __func__); return; } @@ -248,7 +248,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun retval = serial->type->write(port, buf, i); else retval = usb_serial_generic_write(port, buf, i); - dbg("%s - return value : %d", __FUNCTION__, retval); + dbg("%s - return value : %d", __func__, retval); if (lf) { /* append CR after LF */ unsigned char cr = 13; @@ -256,7 +256,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun retval = serial->type->write(port, &cr, 1); else retval = usb_serial_generic_write(port, &cr, 1); - dbg("%s - return value : %d", __FUNCTION__, retval); + dbg("%s - return value : %d", __func__, retval); } buf += i; count -= i; diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 2af8d21bb121..dc0ea08ed231 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -193,7 +193,7 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); + dev_err(&port->dev, "%s - out of memory.\n", __func__); return -ENOMEM; } @@ -214,7 +214,7 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, if (result != size) { dev_err(&port->dev, "%s - Unable to send config request, " "request=0x%x size=%d result=%d\n", - __FUNCTION__, request, size, result); + __func__, request, size, result); return -EPROTO; } @@ -240,7 +240,7 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -265,7 +265,7 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, if ((size > 2 && result != size) || result < 0) { dev_err(&port->dev, "%s - Unable to send request, " "request=0x%x size=%d result=%d\n", - __FUNCTION__, request, size, result); + __func__, request, size, result); return -EPROTO; } @@ -293,11 +293,11 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) struct usb_serial *serial = port->serial; int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { dev_err(&port->dev, "%s - Unable to enable UART\n", - __FUNCTION__); + __func__); return -EPROTO; } @@ -312,7 +312,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { dev_err(&port->dev, "%s - failed resubmitting read urb, " - "error %d\n", __FUNCTION__, result); + "error %d\n", __func__, result); return result; } @@ -329,7 +329,7 @@ static void cp2101_cleanup (struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (serial->dev) { /* shutdown any bulk reads that might be going on */ @@ -342,10 +342,10 @@ static void cp2101_cleanup (struct usb_serial_port *port) static void cp2101_close (struct usb_serial_port *port, struct file * filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* shutdown our urbs */ - dbg("%s - shutting down urbs", __FUNCTION__); + dbg("%s - shutting down urbs", __func__); usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); @@ -367,10 +367,10 @@ static void cp2101_get_termios (struct usb_serial_port *port) int baud; int bits; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->tty || !port->tty->termios) { - dbg("%s - no tty structures", __FUNCTION__); + dbg("%s - no tty structures", __func__); return; } @@ -379,7 +379,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) if (baud) baud = BAUD_RATE_GEN_FREQ / baud; - dbg("%s - baud rate = %d", __FUNCTION__, baud); + dbg("%s - baud rate = %d", __func__, baud); tty_encode_baud_rate(port->tty, baud, baud); cflag = port->tty->termios->c_cflag; @@ -388,24 +388,24 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag &= ~CSIZE; switch(bits & BITS_DATA_MASK) { case BITS_DATA_5: - dbg("%s - data bits = 5", __FUNCTION__); + dbg("%s - data bits = 5", __func__); cflag |= CS5; break; case BITS_DATA_6: - dbg("%s - data bits = 6", __FUNCTION__); + dbg("%s - data bits = 6", __func__); cflag |= CS6; break; case BITS_DATA_7: - dbg("%s - data bits = 7", __FUNCTION__); + dbg("%s - data bits = 7", __func__); cflag |= CS7; break; case BITS_DATA_8: - dbg("%s - data bits = 8", __FUNCTION__); + dbg("%s - data bits = 8", __func__); cflag |= CS8; break; case BITS_DATA_9: dbg("%s - data bits = 9 (not supported, " - "using 8 data bits)", __FUNCTION__); + "using 8 data bits)", __func__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; @@ -413,7 +413,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) break; default: dbg("%s - Unknown number of data bits, " - "using 8", __FUNCTION__); + "using 8", __func__); cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; @@ -423,35 +423,35 @@ static void cp2101_get_termios (struct usb_serial_port *port) switch(bits & BITS_PARITY_MASK) { case BITS_PARITY_NONE: - dbg("%s - parity = NONE", __FUNCTION__); + dbg("%s - parity = NONE", __func__); cflag &= ~PARENB; break; case BITS_PARITY_ODD: - dbg("%s - parity = ODD", __FUNCTION__); + dbg("%s - parity = ODD", __func__); cflag |= (PARENB|PARODD); break; case BITS_PARITY_EVEN: - dbg("%s - parity = EVEN", __FUNCTION__); + dbg("%s - parity = EVEN", __func__); cflag &= ~PARODD; cflag |= PARENB; break; case BITS_PARITY_MARK: dbg("%s - parity = MARK (not supported, " - "disabling parity)", __FUNCTION__); + "disabling parity)", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, " - "disabling parity)", __FUNCTION__); + "disabling parity)", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown parity mode, " - "disabling parity", __FUNCTION__); + "disabling parity", __func__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); @@ -461,21 +461,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag &= ~CSTOPB; switch(bits & BITS_STOP_MASK) { case BITS_STOP_1: - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); break; case BITS_STOP_1_5: dbg("%s - stop bits = 1.5 (not supported, " - "using 1 stop bit)", __FUNCTION__); + "using 1 stop bit)", __func__); bits &= ~BITS_STOP_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_STOP_2: - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); cflag |= CSTOPB; break; default: dbg("%s - Unknown number of stop bits, " - "using 1 stop bit", __FUNCTION__); + "using 1 stop bit", __func__); bits &= ~BITS_STOP_MASK; cp2101_set_config(port, CP2101_BITS, &bits, 2); break; @@ -483,10 +483,10 @@ static void cp2101_get_termios (struct usb_serial_port *port) cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); if (modem_ctl[0] & 0x0008) { - dbg("%s - flow control = CRTSCTS", __FUNCTION__); + dbg("%s - flow control = CRTSCTS", __func__); cflag |= CRTSCTS; } else { - dbg("%s - flow control = NONE", __FUNCTION__); + dbg("%s - flow control = NONE", __func__); cflag &= ~CRTSCTS; } @@ -500,10 +500,10 @@ static void cp2101_set_termios (struct usb_serial_port *port, int baud=0, bits; unsigned int modem_ctl[4]; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->tty || !port->tty->termios) { - dbg("%s - no tty structures", __FUNCTION__); + dbg("%s - no tty structures", __func__); return; } port->tty->termios->c_cflag &= ~CMSPAR; @@ -542,7 +542,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, } if (baud) { - dbg("%s - Setting baud rate to %d baud", __FUNCTION__, + dbg("%s - Setting baud rate to %d baud", __func__, baud); if (cp2101_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ / baud))) { @@ -562,23 +562,23 @@ static void cp2101_set_termios (struct usb_serial_port *port, switch (cflag & CSIZE) { case CS5: bits |= BITS_DATA_5; - dbg("%s - data bits = 5", __FUNCTION__); + dbg("%s - data bits = 5", __func__); break; case CS6: bits |= BITS_DATA_6; - dbg("%s - data bits = 6", __FUNCTION__); + dbg("%s - data bits = 6", __func__); break; case CS7: bits |= BITS_DATA_7; - dbg("%s - data bits = 7", __FUNCTION__); + dbg("%s - data bits = 7", __func__); break; case CS8: bits |= BITS_DATA_8; - dbg("%s - data bits = 8", __FUNCTION__); + dbg("%s - data bits = 8", __func__); break; /*case CS9: bits |= BITS_DATA_9; - dbg("%s - data bits = 9", __FUNCTION__); + dbg("%s - data bits = 9", __func__); break;*/ default: dev_err(&port->dev, "cp2101 driver does not " @@ -598,10 +598,10 @@ static void cp2101_set_termios (struct usb_serial_port *port, if (cflag & PARENB) { if (cflag & PARODD) { bits |= BITS_PARITY_ODD; - dbg("%s - parity = ODD", __FUNCTION__); + dbg("%s - parity = ODD", __func__); } else { bits |= BITS_PARITY_EVEN; - dbg("%s - parity = EVEN", __FUNCTION__); + dbg("%s - parity = EVEN", __func__); } } if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) @@ -614,10 +614,10 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { bits |= BITS_STOP_1; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of stop bits requested " @@ -627,23 +627,23 @@ static void cp2101_set_termios (struct usb_serial_port *port, if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __FUNCTION__, modem_ctl[0], modem_ctl[1], + __func__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); if (cflag & CRTSCTS) { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x09; modem_ctl[1] = 0x80; - dbg("%s - flow control = CRTSCTS", __FUNCTION__); + dbg("%s - flow control = CRTSCTS", __func__); } else { modem_ctl[0] &= ~0x7B; modem_ctl[0] |= 0x01; modem_ctl[1] |= 0x40; - dbg("%s - flow control = NONE", __FUNCTION__); + dbg("%s - flow control = NONE", __func__); } dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __FUNCTION__, modem_ctl[0], modem_ctl[1], + __func__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); } @@ -655,7 +655,7 @@ static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, { int control = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (set & TIOCM_RTS) { control |= CONTROL_RTS; @@ -674,7 +674,7 @@ static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, control |= CONTROL_WRITE_DTR; } - dbg("%s - control = 0x%.4x", __FUNCTION__, control); + dbg("%s - control = 0x%.4x", __func__, control); return cp2101_set_config(port, CP2101_CONTROL, &control, 2); @@ -684,7 +684,7 @@ static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) { int control, result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); cp2101_get_config(port, CP2101_CONTROL, &control, 1); @@ -695,7 +695,7 @@ static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) |((control & CONTROL_RING)? TIOCM_RI : 0) |((control & CONTROL_DCD) ? TIOCM_CD : 0); - dbg("%s - control = 0x%.2x", __FUNCTION__, control); + dbg("%s - control = 0x%.2x", __func__, control); return result; } @@ -704,12 +704,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) { int state; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (break_state == 0) state = BREAK_OFF; else state = BREAK_ON; - dbg("%s - turning break %s", __FUNCTION__, + dbg("%s - turning break %s", __func__, state==BREAK_OFF ? "off" : "on"); cp2101_set_config(port, CP2101_BREAK, &state, 2); } @@ -725,7 +725,7 @@ static void cp2101_shutdown (struct usb_serial *serial) { int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index cbae876cd678..5348e97b52b5 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -116,7 +116,7 @@ static int cyberjack_startup (struct usb_serial *serial) struct cyberjack_private *priv; int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* allocate the private data structure */ priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); @@ -139,7 +139,7 @@ static int cyberjack_startup (struct usb_serial *serial) GFP_KERNEL); if (result) err(" usb_submit_urb(read int) failed"); - dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); + dbg("%s - usb_submit_urb(int urb)", __func__); } return( 0 ); @@ -149,7 +149,7 @@ static void cyberjack_shutdown (struct usb_serial *serial) { int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i=0; i < serial->num_ports; ++i) { usb_kill_urb(serial->port[i]->interrupt_in_urb); @@ -165,9 +165,9 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp) unsigned long flags; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); - dbg("%s - usb_clear_halt", __FUNCTION__ ); + dbg("%s - usb_clear_halt", __func__ ); usb_clear_halt(port->serial->dev, port->write_urb->pipe); /* force low_latency on so that our tty_push actually forces @@ -188,7 +188,7 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp) static void cyberjack_close (struct usb_serial_port *port, struct file *filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->serial->dev) { /* shutdown any bulk reads that might be going on */ @@ -205,17 +205,17 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b int result; int wrexpected; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return (0); } spin_lock_bh(&port->lock); if (port->write_urb_busy) { spin_unlock_bh(&port->lock); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; @@ -234,13 +234,13 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b /* Copy data */ memcpy (priv->wrbuf+priv->wrfilled, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, + usb_serial_debug_data(debug, &port->dev, __func__, count, priv->wrbuf+priv->wrfilled); priv->wrfilled += count; if( priv->wrfilled >= 3 ) { wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; - dbg("%s - expected data: %d", __FUNCTION__, wrexpected); + dbg("%s - expected data: %d", __func__, wrexpected); } else { wrexpected = sizeof(priv->wrbuf); } @@ -249,7 +249,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b /* We have enough data to begin transmission */ int length; - dbg("%s - transmitting data (frame 1)", __FUNCTION__); + dbg("%s - transmitting data (frame 1)", __func__); length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected; memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length ); @@ -267,7 +267,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled=0; priv->wrsent=0; @@ -276,11 +276,11 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b return 0; } - dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent); - dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled); + dbg("%s - priv->wrsent=%d", __func__,priv->wrsent); + dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled); if( priv->wrsent>=priv->wrfilled ) { - dbg("%s - buffer cleaned", __FUNCTION__); + dbg("%s - buffer cleaned", __func__); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); priv->wrfilled=0; priv->wrsent=0; @@ -305,13 +305,13 @@ static void cyberjack_read_int_callback( struct urb *urb ) int status = urb->status; int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* the urb might have been killed. */ if (status) return; - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* React only to interrupts signaling a bulk_in transfer */ if( (urb->actual_length==4) && (data[0]==0x01) ) { @@ -333,7 +333,7 @@ static void cyberjack_read_int_callback( struct urb *urb ) /* "+=" is probably more fault tollerant than "=" */ priv->rdtodo += size; - dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo); + dbg("%s - rdtodo: %d", __func__, priv->rdtodo); spin_unlock(&priv->lock); @@ -341,8 +341,8 @@ static void cyberjack_read_int_callback( struct urb *urb ) port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if( result ) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); - dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); + err("%s - failed resubmitting read urb, error %d", __func__, result); + dbg("%s - usb_submit_urb(read urb)", __func__); } } @@ -351,7 +351,7 @@ resubmit: result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) err(" usb_submit_urb(read int) failed"); - dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); + dbg("%s - usb_submit_urb(int urb)", __func__); } static void cyberjack_read_bulk_callback (struct urb *urb) @@ -364,18 +364,18 @@ static void cyberjack_read_bulk_callback (struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } tty = port->tty; if (!tty) { - dbg("%s - ignoring since device not open\n", __FUNCTION__); + dbg("%s - ignoring since device not open\n", __func__); return; } if (urb->actual_length) { @@ -394,15 +394,15 @@ static void cyberjack_read_bulk_callback (struct urb *urb) spin_unlock(&priv->lock); - dbg("%s - rdtodo: %d", __FUNCTION__, todo); + dbg("%s - rdtodo: %d", __func__, todo); /* Continue to read if we have still urbs to do. */ if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) { port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); - dbg("%s - usb_submit_urb(read urb)", __FUNCTION__); + err("%s - failed resubmitting read urb, error %d", __func__, result); + dbg("%s - usb_submit_urb(read urb)", __func__); } } @@ -412,12 +412,12 @@ static void cyberjack_write_bulk_callback (struct urb *urb) struct cyberjack_private *priv = usb_get_serial_port_data(port); int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); port->write_urb_busy = 0; if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -427,7 +427,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb) if( priv->wrfilled ) { int length, blksize, result; - dbg("%s - transmitting data (frame n)", __FUNCTION__); + dbg("%s - transmitting data (frame n)", __func__); length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ? port->bulk_out_size : (priv->wrfilled - priv->wrsent); @@ -448,20 +448,20 @@ static void cyberjack_write_bulk_callback (struct urb *urb) /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); /* Throw away data. No better idea what to do with it. */ priv->wrfilled=0; priv->wrsent=0; goto exit; } - dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent); - dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled); + dbg("%s - priv->wrsent=%d", __func__,priv->wrsent); + dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled); blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) { - dbg("%s - buffer cleaned", __FUNCTION__); + dbg("%s - buffer cleaned", __func__); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); priv->wrfilled=0; priv->wrsent=0; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index d8304eaf34c4..01dfc0afc654 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -330,7 +330,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra __u8 feature_buffer[5]; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); priv = usb_get_serial_port_data(port); @@ -345,7 +345,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra new_baudrate = priv->baud_rate; /* Change of speed ? */ else if (baud_rate != priv->baud_rate) { - dbg("%s - baud rate is changing", __FUNCTION__); + dbg("%s - baud rate is changing", __func__); retval = analyze_baud_rate(port, baud_rate); if (retval >= 0) { new_baudrate = retval; @@ -353,7 +353,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra __func__, new_baudrate); } } - dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate); + dbg("%s - baud rate is being sent as %d", __func__, new_baudrate); memset(feature_buffer, 0, sizeof(feature_buffer)); /* fill the feature_buffer with new configuration */ @@ -367,8 +367,8 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra /* 1 bit gap */ feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ - dbg("%s - device is being sent this feature report:", __FUNCTION__); - dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1], + dbg("%s - device is being sent this feature report:", __func__); + dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, feature_buffer[0], feature_buffer[1], feature_buffer[2], feature_buffer[3], feature_buffer[4]); do { @@ -386,7 +386,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra retval != -ENODEV); if (retval != sizeof(feature_buffer)) { - err("%s - failed sending serial line settings - %d", __FUNCTION__, retval); + err("%s - failed sending serial line settings - %d", __func__, retval); cypress_set_dead(port); } else { spin_lock_irqsave(&priv->lock, flags); @@ -406,7 +406,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra to crash the hardware. */ return -ENOTTY; } - dbg("%s - retreiving serial line settings", __FUNCTION__); + dbg("%s - retreiving serial line settings", __func__); /* set initial values in feature buffer */ memset(feature_buffer, 0, sizeof(feature_buffer)); @@ -425,7 +425,7 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra retval != -ENODEV); if (retval != sizeof(feature_buffer)) { - err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval); + err("%s - failed to retrieve serial line settings - %d", __func__, retval); cypress_set_dead(port); return retval; } else { @@ -473,7 +473,7 @@ static int generic_startup (struct usb_serial *serial) struct cypress_private *priv; struct usb_serial_port *port = serial->port[0]; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); if (!priv) @@ -509,12 +509,12 @@ static int generic_startup (struct usb_serial *serial) priv->write_urb_interval = interval; priv->read_urb_interval = interval; dbg("%s - port %d read & write intervals forced to %d", - __FUNCTION__,port->number,interval); + __func__,port->number,interval); } else { priv->write_urb_interval = port->interrupt_out_urb->interval; priv->read_urb_interval = port->interrupt_in_urb->interval; dbg("%s - port %d intervals: read=%d write=%d", - __FUNCTION__,port->number, + __func__,port->number, priv->read_urb_interval,priv->write_urb_interval); } usb_set_serial_port_data(port, priv); @@ -528,10 +528,10 @@ static int cypress_earthmate_startup (struct usb_serial *serial) struct cypress_private *priv; struct usb_serial_port *port = serial->port[0]; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, + dbg("%s - Failed setting up port %d", __func__, port->number); return 1; } @@ -559,10 +559,10 @@ static int cypress_hidcom_startup (struct usb_serial *serial) { struct cypress_private *priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, + dbg("%s - Failed setting up port %d", __func__, serial->port[0]->number); return 1; } @@ -578,10 +578,10 @@ static int cypress_ca42v2_startup (struct usb_serial *serial) { struct cypress_private *priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, + dbg("%s - Failed setting up port %d", __func__, serial->port[0]->number); return 1; } @@ -597,7 +597,7 @@ static void cypress_shutdown (struct usb_serial *serial) { struct cypress_private *priv; - dbg ("%s - port %d", __FUNCTION__, serial->port[0]->number); + dbg ("%s - port %d", __func__, serial->port[0]->number); /* all open ports are closed at this point */ @@ -618,7 +618,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) unsigned long flags; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!priv->comm_is_ok) return -EIO; @@ -646,16 +646,16 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) result = cypress_write(port, NULL, 0); if (result) { - dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result); return result; } else - dbg("%s - success setting the control lines", __FUNCTION__); + dbg("%s - success setting the control lines", __func__); cypress_set_termios(port, &priv->tmp_termios); /* setup the port and start reading from the device */ if(!port->interrupt_in_urb){ - err("%s - interrupt_in_urb is empty!", __FUNCTION__); + err("%s - interrupt_in_urb is empty!", __func__); return(-1); } @@ -666,7 +666,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result){ - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); cypress_set_dead(port); } @@ -682,7 +682,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) long timeout; wait_queue_t wait; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* wait for data to drain from buffer */ spin_lock_irq(&priv->lock); @@ -720,7 +720,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) timeout = 2*HZ; schedule_timeout_interruptible(timeout); - dbg("%s - stopping urbs", __FUNCTION__); + dbg("%s - stopping urbs", __func__); usb_kill_urb (port->interrupt_in_urb); usb_kill_urb (port->interrupt_out_urb); @@ -749,7 +749,7 @@ static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, struct cypress_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); + dbg("%s - port %d, %d bytes", __func__, port->number, count); /* line control commands, which need to be executed immediately, are not put into the buffer for obvious reasons. @@ -782,12 +782,12 @@ static void cypress_send(struct usb_serial_port *port) if (!priv->comm_is_ok) return; - dbg("%s - port %d", __FUNCTION__, port->number); - dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size); + dbg("%s - port %d", __func__, port->number); + dbg("%s - interrupt out size is %d", __func__, port->interrupt_out_size); spin_lock_irqsave(&priv->lock, flags); if (priv->write_urb_in_use) { - dbg("%s - can't write, urb in use", __FUNCTION__); + dbg("%s - can't write, urb in use", __func__); spin_unlock_irqrestore(&priv->lock, flags); return; } @@ -816,7 +816,7 @@ static void cypress_send(struct usb_serial_port *port) if (priv->cmd_ctrl) { priv->cmd_count++; - dbg("%s - line control command being issued", __FUNCTION__); + dbg("%s - line control command being issued", __func__); spin_unlock_irqrestore(&priv->lock, flags); goto send; } else @@ -838,7 +838,7 @@ static void cypress_send(struct usb_serial_port *port) port->interrupt_out_buffer[0] |= count; } - dbg("%s - count is %d", __FUNCTION__, count); + dbg("%s - count is %d", __func__, count); send: spin_lock_irqsave(&priv->lock, flags); @@ -851,7 +851,7 @@ send: actual_size = count + (priv->pkt_fmt == packet_format_1 ? 2 : 1); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size, + usb_serial_debug_data(debug, &port->dev, __func__, port->interrupt_out_size, port->interrupt_out_urb->transfer_buffer); usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, @@ -860,7 +860,7 @@ send: cypress_write_int_callback, port, priv->write_urb_interval); result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, + dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); priv->write_urb_in_use = 0; cypress_set_dead(port); @@ -884,13 +884,13 @@ static int cypress_write_room(struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); room = cypress_buf_space_avail(priv->buf); spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -902,7 +902,7 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) unsigned int result = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); control = priv->line_control; @@ -916,7 +916,7 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) | ((status & UART_RI) ? TIOCM_RI : 0) | ((status & UART_CD) ? TIOCM_CD : 0); - dbg("%s - result = %x", __FUNCTION__, result); + dbg("%s - result = %x", __func__, result); return result; } @@ -928,7 +928,7 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, struct cypress_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (set & TIOCM_RTS) @@ -950,7 +950,7 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi { struct cypress_private *priv = usb_get_serial_port_data(port); - dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); switch (cmd) { /* This code comes from drivers/char/serial.c and ftdi_sio.c */ @@ -988,7 +988,7 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi break; } - dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__, cmd); + dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); return -ENOIOCTLCMD; } /* cypress_ioctl */ @@ -1005,7 +1005,7 @@ static void cypress_set_termios (struct usb_serial_port *port, __u8 oldlines; int linechange = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); tty = port->tty; @@ -1076,7 +1076,7 @@ static void cypress_set_termios (struct usb_serial_port *port, break; default: err("%s - CSIZE was set, but not CS5-CS8", - __FUNCTION__); + __func__); data_bits = 3; } } else @@ -1086,14 +1086,14 @@ static void cypress_set_termios (struct usb_serial_port *port, oldlines = priv->line_control; if ((cflag & CBAUD) == B0) { /* drop dtr and rts */ - dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__); + dbg("%s - dropping the lines, baud rate 0bps", __func__); priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); } else priv->line_control = (CONTROL_DTR | CONTROL_RTS); spin_unlock_irqrestore(&priv->lock, flags); dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " - "%d data_bits (+5)", __FUNCTION__, stop_bits, + "%d data_bits (+5)", __func__, stop_bits, parity_enable, parity_type, data_bits); cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits, @@ -1154,13 +1154,13 @@ static int cypress_chars_in_buffer(struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); chars = cypress_buf_data_avail(priv->buf); spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return chars; } @@ -1170,7 +1170,7 @@ static void cypress_throttle (struct usb_serial_port *port) struct cypress_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); priv->rx_flags = THROTTLED; @@ -1184,7 +1184,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) int actually_throttled, result; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; @@ -1200,7 +1200,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting read urb, " - "error %d\n", __FUNCTION__, result); + "error %d\n", __func__, result); cypress_set_dead(port); } } @@ -1221,7 +1221,7 @@ static void cypress_read_int_callback(struct urb *urb) int i = 0; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); switch (status) { case 0: /* success */ @@ -1237,14 +1237,14 @@ static void cypress_read_int_callback(struct urb *urb) default: /* something ugly is going on... */ dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", - __FUNCTION__, status); + __func__, status); cypress_set_dead(port); return; } spin_lock_irqsave(&priv->lock, flags); if (priv->rx_flags & THROTTLED) { - dbg("%s - now throttling", __FUNCTION__); + dbg("%s - now throttling", __func__); priv->rx_flags |= ACTUALLY_THROTTLED; spin_unlock_irqrestore(&priv->lock, flags); return; @@ -1253,7 +1253,7 @@ static void cypress_read_int_callback(struct urb *urb) tty = port->tty; if (!tty) { - dbg("%s - bad tty pointer - exiting", __FUNCTION__); + dbg("%s - bad tty pointer - exiting", __func__); return; } @@ -1285,7 +1285,7 @@ static void cypress_read_int_callback(struct urb *urb) goto continue_read; } - usb_serial_debug_data (debug, &port->dev, __FUNCTION__, + usb_serial_debug_data (debug, &port->dev, __func__, urb->actual_length, data); spin_lock_irqsave(&priv->lock, flags); @@ -1302,7 +1302,7 @@ static void cypress_read_int_callback(struct urb *urb) * though */ if (tty && !(tty->termios->c_cflag & CLOCAL) && !(priv->current_status & UART_CD)) { - dbg("%s - calling hangup", __FUNCTION__); + dbg("%s - calling hangup", __func__); tty_hangup(tty); goto continue_read; } @@ -1315,7 +1315,7 @@ static void cypress_read_int_callback(struct urb *urb) if (priv->current_status & CYP_ERROR) { spin_unlock_irqrestore(&priv->lock, flags); tty_flag = TTY_PARITY; - dbg("%s - Parity Error detected", __FUNCTION__); + dbg("%s - Parity Error detected", __func__); } else spin_unlock_irqrestore(&priv->lock, flags); @@ -1349,7 +1349,7 @@ continue_read: result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) { dev_err(&urb->dev->dev, "%s - failed resubmitting " - "read urb, error %d\n", __FUNCTION__, + "read urb, error %d\n", __func__, result); cypress_set_dead(port); } @@ -1366,7 +1366,7 @@ static void cypress_write_int_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); switch (status) { case 0: @@ -1377,7 +1377,7 @@ static void cypress_write_int_callback(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); priv->write_urb_in_use = 0; return; case -EPIPE: /* no break needed; clear halt and resubmit */ @@ -1386,19 +1386,19 @@ static void cypress_write_int_callback(struct urb *urb) usb_clear_halt(port->serial->dev, 0x02); /* error in the urb, so we have to resubmit it */ dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); port->interrupt_out_urb->transfer_buffer_length = 1; port->interrupt_out_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); if (!result) return; dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", - __FUNCTION__, result); + __func__, result); cypress_set_dead(port); break; default: dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n", - __FUNCTION__, status); + __func__, status); cypress_set_dead(port); break; } @@ -1603,7 +1603,7 @@ static int __init cypress_init(void) { int retval; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); retval = usb_serial_register(&cypress_earthmate_device); if (retval) @@ -1634,7 +1634,7 @@ failed_em_register: static void __exit cypress_exit (void) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); usb_deregister (&cypress_driver); usb_serial_deregister (&cypress_earthmate_device); diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 4e3d5993a8e3..c7cbc02f1a70 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -659,7 +659,7 @@ static int digi_write_oob_command(struct usb_serial_port *port, } spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + err("%s: usb_submit_urb failed, ret=%d", __func__, ret); return ret; } @@ -740,7 +740,7 @@ static int digi_write_inb_command(struct usb_serial_port *port, if (ret) err("%s: usb_submit_urb failed, ret=%d, port=%d", - __FUNCTION__, ret, priv->dp_port_num); + __func__, ret, priv->dp_port_num); return ret; } @@ -804,7 +804,7 @@ static int digi_set_modem_signals(struct usb_serial_port *port, spin_unlock(&port_priv->dp_port_lock); spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); if (ret) - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + err("%s: usb_submit_urb failed, ret=%d", __func__, ret); return ret; } @@ -897,7 +897,7 @@ static void digi_rx_unthrottle(struct usb_serial_port *port) if (ret) err("%s: usb_submit_urb failed, ret=%d, port=%d", - __FUNCTION__, ret, priv->dp_port_num); + __func__, ret, priv->dp_port_num); } @@ -1107,7 +1107,7 @@ static int digi_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int val; unsigned long flags; - dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); + dbg("%s: TOP: port=%d", __func__, priv->dp_port_num); spin_lock_irqsave(&priv->dp_port_lock, flags); val = priv->dp_modem_signals; @@ -1123,7 +1123,7 @@ static int digi_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int val; unsigned long flags; - dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); + dbg("%s: TOP: port=%d", __func__, priv->dp_port_num); spin_lock_irqsave(&priv->dp_port_lock, flags); val = (priv->dp_modem_signals & ~clear) | set; @@ -1218,7 +1218,7 @@ static int digi_write(struct usb_serial_port *port, const unsigned char *buf, in spin_unlock_irqrestore(&priv->dp_port_lock, flags); if (ret < 0) err("%s: usb_submit_urb failed, ret=%d, port=%d", - __FUNCTION__, ret, priv->dp_port_num); + __func__, ret, priv->dp_port_num); dbg("digi_write: returning %d", ret); return ret; @@ -1239,13 +1239,13 @@ static void digi_write_bulk_callback(struct urb *urb) /* port and serial sanity check */ if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", - __FUNCTION__, status); + __func__, status); return; } serial = port->serial; if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) { err("%s: serial or serial->private is NULL, status=%d", - __FUNCTION__, status); + __func__, status); return; } @@ -1286,7 +1286,7 @@ static void digi_write_bulk_callback(struct urb *urb) spin_unlock(&priv->dp_port_lock); if (ret) err("%s: usb_submit_urb failed, ret=%d, port=%d", - __FUNCTION__, ret, priv->dp_port_num); + __func__, ret, priv->dp_port_num); } static int digi_write_room(struct usb_serial_port *port) @@ -1515,7 +1515,7 @@ static int digi_startup_device(struct usb_serial *serial) port->write_urb->dev = port->serial->dev; if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) { err("%s: usb_submit_urb failed, ret=%d, port=%d", - __FUNCTION__, ret, i); + __func__, ret, i); break; } } @@ -1616,20 +1616,20 @@ static void digi_read_bulk_callback(struct urb *urb) /* port sanity check, do not resubmit if port is not valid */ if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", - __FUNCTION__, status); + __func__, status); return; } if (port->serial == NULL || (serial_priv=usb_get_serial_data(port->serial)) == NULL) { err("%s: serial is bad or serial->private is NULL, status=%d", - __FUNCTION__, status); + __func__, status); return; } /* do not resubmit urb if it has any status error */ if (status) { err("%s: nonzero read bulk status: status=%d, port=%d", - __FUNCTION__, status, priv->dp_port_num); + __func__, status, priv->dp_port_num); return; } @@ -1646,7 +1646,7 @@ static void digi_read_bulk_callback(struct urb *urb) urb->dev = port->serial->dev; if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { err("%s: failed resubmitting urb, ret=%d, port=%d", - __FUNCTION__, ret, priv->dp_port_num); + __func__, ret, priv->dp_port_num); } } @@ -1684,7 +1684,7 @@ static int digi_read_inb_callback(struct urb *urb) if (urb->actual_length != len + 2) { err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, " "port=%d, opcode=%d, len=%d, actual_length=%d, " - "status=%d", __FUNCTION__, status, priv->dp_port_num, + "status=%d", __func__, status, priv->dp_port_num, opcode, len, urb->actual_length, port_status); return -1; } @@ -1733,9 +1733,9 @@ static int digi_read_inb_callback(struct urb *urb) spin_unlock(&priv->dp_port_lock); if (opcode == DIGI_CMD_RECEIVE_DISABLE) - dbg("%s: got RECEIVE_DISABLE", __FUNCTION__); + dbg("%s: got RECEIVE_DISABLE", __func__); else if (opcode != DIGI_CMD_RECEIVE_DATA) - dbg("%s: unknown opcode: %d", __FUNCTION__, opcode); + dbg("%s: unknown opcode: %d", __func__, opcode); return(throttled ? 1 : 0); diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 2cf821771175..5f731d4912f7 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -150,7 +150,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) struct usb_serial *serial = port->serial; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* Force default termio settings */ empeg_set_termios (port, NULL) ; @@ -172,7 +172,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); return result; } @@ -180,7 +180,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) static void empeg_close (struct usb_serial_port *port, struct file * filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* shutdown our bulk read */ usb_kill_urb(port->read_urb); @@ -200,7 +200,7 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int bytes_sent = 0; int transfer_size; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); while (count > 0) { @@ -219,14 +219,14 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, spin_unlock_irqrestore (&write_urb_pool_lock, flags); if (urb == NULL) { - dbg("%s - no more free urbs", __FUNCTION__); + dbg("%s - no more free urbs", __func__); goto exit; } if (urb->transfer_buffer == NULL) { urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); if (urb->transfer_buffer == NULL) { - dev_err(&port->dev, "%s no more kernel memory...\n", __FUNCTION__); + dev_err(&port->dev, "%s no more kernel memory...\n", __func__); goto exit; } } @@ -235,7 +235,7 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, memcpy (urb->transfer_buffer, current_position, transfer_size); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer); /* build up our urb */ usb_fill_bulk_urb ( @@ -251,7 +251,7 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); bytes_sent = status; break; } @@ -275,7 +275,7 @@ static int empeg_write_room (struct usb_serial_port *port) int i; int room = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave (&write_urb_pool_lock, flags); @@ -288,7 +288,7 @@ static int empeg_write_room (struct usb_serial_port *port) spin_unlock_irqrestore (&write_urb_pool_lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return (room); @@ -301,7 +301,7 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port) int i; int chars = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave (&write_urb_pool_lock, flags); @@ -314,7 +314,7 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port) spin_unlock_irqrestore (&write_urb_pool_lock, flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return (chars); @@ -326,11 +326,11 @@ static void empeg_write_bulk_callback (struct urb *urb) struct usb_serial_port *port = urb->context; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -346,15 +346,15 @@ static void empeg_read_bulk_callback (struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; @@ -379,7 +379,7 @@ static void empeg_read_bulk_callback (struct urb *urb) result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); return; @@ -388,7 +388,7 @@ static void empeg_read_bulk_callback (struct urb *urb) static void empeg_throttle (struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->read_urb); } @@ -397,14 +397,14 @@ static void empeg_unthrottle (struct usb_serial_port *port) { int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); return; } @@ -414,14 +414,14 @@ static int empeg_startup (struct usb_serial *serial) { int r; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { err("active config #%d != 1 ??", serial->dev->actconfig->desc.bConfigurationValue); return -ENODEV; } - dbg("%s - reset config", __FUNCTION__); + dbg("%s - reset config", __func__); r = usb_reset_configuration (serial->dev); /* continue on with initialization */ @@ -432,13 +432,13 @@ static int empeg_startup (struct usb_serial *serial) static void empeg_shutdown (struct usb_serial *serial) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) { - dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); return -ENOIOCTLCMD; } @@ -447,7 +447,7 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { struct ktermios *termios = port->tty->termios; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * The empeg-car player wants these particular tty settings. @@ -514,7 +514,7 @@ static int __init empeg_init (void) urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { err("%s - out of memory for urb buffers.", - __FUNCTION__); + __func__); continue; } } diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c index 3f698baa0abb..cc4fbd9d60be 100644 --- a/drivers/usb/serial/ezusb.c +++ b/drivers/usb/serial/ezusb.c @@ -27,13 +27,13 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da /* dbg("ezusb_writememory %x, %d", address, length); */ if (!serial->dev) { - err("%s - no physical device present, failing.", __FUNCTION__); + err("%s - no physical device present, failing.", __func__); return -ENODEV; } transfer_buffer = kmemdup(data, length, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, length); + dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, length); return -ENOMEM; } result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000); @@ -45,10 +45,10 @@ int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit) { int response; - /* dbg("%s - %d", __FUNCTION__, reset_bit); */ + /* dbg("%s - %d", __func__, reset_bit); */ response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) - dev_err(&serial->dev->dev, "%s- %d failed\n", __FUNCTION__, reset_bit); + dev_err(&serial->dev->dev, "%s- %d failed\n", __func__, reset_bit); return response; } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 54b502f2924c..8b531b377dcb 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -525,7 +525,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int rv; if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { - dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__); + dbg("%s - DTR|RTS not being set|cleared", __func__); return 0; /* no change */ } @@ -553,13 +553,13 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned kfree(buf); if (rv < 0) { err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", - __FUNCTION__, + __func__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); } else { - dbg("%s - DTR %s, RTS %s", __FUNCTION__, + dbg("%s - DTR %s, RTS %s", __func__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : @@ -639,7 +639,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) /* 1. Get the baud rate from the tty settings, this observes alt_speed hack */ baud = tty_get_baud_rate(port->tty); - dbg("%s - tty_get_baud_rate reports speed %d", __FUNCTION__, baud); + dbg("%s - tty_get_baud_rate reports speed %d", __func__, baud); /* 2. Observe async-compatible custom_divisor hack, update baudrate if needed */ @@ -647,7 +647,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && (priv->custom_divisor)) { baud = priv->baud_base / priv->custom_divisor; - dbg("%s - custom divisor %d sets baud rate to %d", __FUNCTION__, priv->custom_divisor, baud); + dbg("%s - custom divisor %d sets baud rate to %d", __func__, priv->custom_divisor, baud); } /* 3. Convert baudrate to device-specific divisor */ @@ -668,7 +668,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) case 115200: div_value = ftdi_sio_b115200; break; } /* baud */ if (div_value == 0) { - dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); + dbg("%s - Baudrate (%d) requested is not supported", __func__, baud); div_value = ftdi_sio_b9600; baud = 9600; div_okay = 0; @@ -678,7 +678,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) if (baud <= 3000000) { div_value = ftdi_232am_baud_to_divisor(baud); } else { - dbg("%s - Baud rate too high!", __FUNCTION__); + dbg("%s - Baud rate too high!", __func__); baud = 9600; div_value = ftdi_232am_baud_to_divisor(9600); div_okay = 0; @@ -690,7 +690,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) if (baud <= 3000000) { div_value = ftdi_232bm_baud_to_divisor(baud); } else { - dbg("%s - Baud rate too high!", __FUNCTION__); + dbg("%s - Baud rate too high!", __func__); div_value = ftdi_232bm_baud_to_divisor(9600); div_okay = 0; baud = 9600; @@ -700,7 +700,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) if (div_okay) { dbg("%s - Baud rate set to %d (divisor 0x%lX) on chip %s", - __FUNCTION__, baud, (unsigned long)div_value, + __func__, baud, (unsigned long)div_value, ftdi_chip_name[priv->chip_type]); } @@ -801,7 +801,7 @@ static void ftdi_determine_type(struct usb_serial_port *port) version = le16_to_cpu(udev->descriptor.bcdDevice); interfaces = udev->actconfig->desc.bNumInterfaces; - dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __FUNCTION__, + dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __func__, version, interfaces); if (interfaces > 1) { int inter; @@ -819,7 +819,7 @@ static void ftdi_determine_type(struct usb_serial_port *port) * to 0x200 when iSerialNumber is 0. */ if (version < 0x500) { dbg("%s: something fishy - bcdDevice too low for multi-interface device", - __FUNCTION__); + __func__); } } else if (version < 0x200) { /* Old device. Assume its the original SIO. */ @@ -857,7 +857,7 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a int rv = 0; - dbg("%s",__FUNCTION__); + dbg("%s",__func__); rv = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), @@ -884,7 +884,7 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - dbg("%s: setting latency timer = %i", __FUNCTION__, v); + dbg("%s: setting latency timer = %i", __func__, v); rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), @@ -913,7 +913,7 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - dbg("%s: setting event char = %i", __FUNCTION__, v); + dbg("%s: setting event char = %i", __func__, v); rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), @@ -938,7 +938,7 @@ static int create_sysfs_attrs(struct usb_serial_port *port) struct ftdi_private *priv = usb_get_serial_port_data(port); int retval = 0; - dbg("%s",__FUNCTION__); + dbg("%s",__func__); /* XXX I've no idea if the original SIO supports the event_char * sysfs parameter, so I'm playing it safe. */ @@ -960,7 +960,7 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); - dbg("%s",__FUNCTION__); + dbg("%s",__func__); /* XXX see create_sysfs_attrs */ if (priv->chip_type != SIO) { @@ -1002,11 +1002,11 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); - dbg("%s",__FUNCTION__); + dbg("%s",__func__); priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv){ - err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct ftdi_private)); + err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct ftdi_private)); return -ENOMEM; } @@ -1055,7 +1055,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) /* Called from usbserial:serial_probe */ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) { - dbg("%s",__FUNCTION__); + dbg("%s",__func__); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 77; @@ -1066,7 +1066,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) { - dbg("%s",__FUNCTION__); + dbg("%s",__func__); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 240; @@ -1084,7 +1084,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial) struct usb_device *udev = serial->dev; struct usb_interface *interface = serial->interface; - dbg("%s",__FUNCTION__); + dbg("%s",__func__); if (interface == udev->actconfig->interface[0]) { info("Ignoring serial port reserved for JTAG"); @@ -1120,14 +1120,14 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) */ static void ftdi_shutdown (struct usb_serial *serial) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static int ftdi_sio_port_remove(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); remove_sysfs_attrs(port); @@ -1152,7 +1152,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) int result = 0; char buf[1]; /* Needed for the usb_control_msg I think */ - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&priv->tx_lock, flags); priv->tx_bytes = 0; @@ -1197,7 +1197,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) ftdi_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - err("%s - failed submitting read urb, error %d", __FUNCTION__, result); + err("%s - failed submitting read urb, error %d", __func__, result); return result; @@ -1219,7 +1219,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) struct ftdi_private *priv = usb_get_serial_port_data(port); char buf[1]; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); mutex_lock(&port->serial->disc_mutex); if (c_cflag & HUPCL && !port->serial->disconnected){ @@ -1266,7 +1266,7 @@ static int ftdi_write (struct usb_serial_port *port, int transfer_size; unsigned long flags; - dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count); + dbg("%s port %d, %d bytes", __func__, port->number, count); if (count == 0) { dbg("write request of 0 bytes"); @@ -1275,7 +1275,7 @@ static int ftdi_write (struct usb_serial_port *port, spin_lock_irqsave(&priv->tx_lock, flags); if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { spin_unlock_irqrestore(&priv->tx_lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } priv->tx_outstanding_urbs++; @@ -1295,14 +1295,14 @@ static int ftdi_write (struct usb_serial_port *port, buffer = kmalloc (transfer_size, GFP_ATOMIC); if (!buffer) { - err("%s ran out of kernel memory for urb ...", __FUNCTION__); + err("%s ran out of kernel memory for urb ...", __func__); count = -ENOMEM; goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - err("%s - no more free urbs", __FUNCTION__); + err("%s - no more free urbs", __func__); count = -ENOMEM; goto error_no_urb; } @@ -1334,7 +1334,7 @@ static int ftdi_write (struct usb_serial_port *port, memcpy (buffer, buf, count); } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, buffer); /* fill the buffer and send it */ usb_fill_bulk_urb(urb, port->serial->dev, @@ -1344,7 +1344,7 @@ static int ftdi_write (struct usb_serial_port *port, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, status); + err("%s - failed submitting write urb, error %d", __func__, status); count = status; goto error; } else { @@ -1358,7 +1358,7 @@ static int ftdi_write (struct usb_serial_port *port, * really free it when it is finished with it */ usb_free_urb(urb); - dbg("%s write returning: %d", __FUNCTION__, count); + dbg("%s write returning: %d", __func__, count); return count; error: usb_free_urb(urb); @@ -1386,7 +1386,7 @@ static void ftdi_write_bulk_callback (struct urb *urb) /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree (urb->transfer_buffer); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("nonzero write bulk status received: %d", status); @@ -1395,7 +1395,7 @@ static void ftdi_write_bulk_callback (struct urb *urb) priv = usb_get_serial_port_data(port); if (!priv) { - dbg("%s - bad port private data pointer - exiting", __FUNCTION__); + dbg("%s - bad port private data pointer - exiting", __func__); return; } /* account for transferred data */ @@ -1420,7 +1420,7 @@ static int ftdi_write_room( struct usb_serial_port *port ) int room; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->tx_lock, flags); if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) { @@ -1444,13 +1444,13 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port) int buffered; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->tx_lock, flags); buffered = (int)priv->tx_outstanding_bytes; spin_unlock_irqrestore(&priv->tx_lock, flags); if (buffered < 0) { - err("%s outstanding tx bytes is negative!", __FUNCTION__); + err("%s outstanding tx bytes is negative!", __func__); buffered = 0; } return buffered; @@ -1468,30 +1468,30 @@ static void ftdi_read_bulk_callback (struct urb *urb) int status = urb->status; if (urb->number_of_packets > 0) { - err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__, + err("%s transfer_buffer_length %d actual_length %d number of packets %d",__func__, urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets ); - err("%s transfer_flags %x ", __FUNCTION__,urb->transfer_flags ); + err("%s transfer_flags %x ", __func__,urb->transfer_flags ); } - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->open_count <= 0) return; tty = port->tty; if (!tty) { - dbg("%s - bad tty pointer - exiting",__FUNCTION__); + dbg("%s - bad tty pointer - exiting",__func__); return; } priv = usb_get_serial_port_data(port); if (!priv) { - dbg("%s - bad port private data pointer - exiting", __FUNCTION__); + dbg("%s - bad port private data pointer - exiting", __func__); return; } if (urb != port->read_urb) { - err("%s - Not my urb!", __FUNCTION__); + err("%s - Not my urb!", __func__); } if (status) { @@ -1529,39 +1529,39 @@ static void ftdi_process_read (struct work_struct *work) int packet_offset; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->open_count <= 0) return; tty = port->tty; if (!tty) { - dbg("%s - bad tty pointer - exiting",__FUNCTION__); + dbg("%s - bad tty pointer - exiting",__func__); return; } priv = usb_get_serial_port_data(port); if (!priv) { - dbg("%s - bad port private data pointer - exiting", __FUNCTION__); + dbg("%s - bad port private data pointer - exiting", __func__); return; } urb = port->read_urb; if (!urb) { - dbg("%s - bad read_urb pointer - exiting", __FUNCTION__); + dbg("%s - bad read_urb pointer - exiting", __func__); return; } data = urb->transfer_buffer; if (priv->rx_processed) { - dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__, + dbg("%s - already processed: %d bytes, %d remain", __func__, priv->rx_processed, urb->actual_length - priv->rx_processed); } else { /* The first two bytes of every read packet are status */ if (urb->actual_length > 2) { - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); } else { dbg("Status only: %03oo %03oo",data[0],data[1]); } @@ -1591,17 +1591,17 @@ static void ftdi_process_read (struct work_struct *work) length = min(PKTSZ, urb->actual_length-packet_offset)-2; if (length < 0) { - err("%s - bad packet length: %d", __FUNCTION__, length+2); + err("%s - bad packet length: %d", __func__, length+2); length = 0; } if (priv->rx_flags & THROTTLED) { - dbg("%s - throttled", __FUNCTION__); + dbg("%s - throttled", __func__); break; } if (tty_buffer_request_room(tty, length) < length) { /* break out & wait for throttling/unthrottling to happen */ - dbg("%s - receive room low", __FUNCTION__); + dbg("%s - receive room low", __func__); break; } @@ -1669,7 +1669,7 @@ static void ftdi_process_read (struct work_struct *work) /* not completely processed - record progress */ priv->rx_processed = packet_offset; dbg("%s - incomplete, %d bytes processed, %d remain", - __FUNCTION__, packet_offset, + __func__, packet_offset, urb->actual_length - packet_offset); /* check if we were throttled while processing */ spin_lock_irqsave(&priv->rx_lock, flags); @@ -1677,7 +1677,7 @@ static void ftdi_process_read (struct work_struct *work) priv->rx_flags |= ACTUALLY_THROTTLED; spin_unlock_irqrestore(&priv->rx_lock, flags); dbg("%s - deferring remainder until unthrottled", - __FUNCTION__); + __func__); return; } spin_unlock_irqrestore(&priv->rx_lock, flags); @@ -1686,7 +1686,7 @@ static void ftdi_process_read (struct work_struct *work) /* delay processing of remainder */ schedule_delayed_work(&priv->rx_work, 1); } else { - dbg("%s - port is closed", __FUNCTION__); + dbg("%s - port is closed", __func__); } return; } @@ -1704,7 +1704,7 @@ static void ftdi_process_read (struct work_struct *work) result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + err("%s - failed resubmitting read urb, error %d", __func__, result); } return; @@ -1733,10 +1733,10 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state); + err("%s FAILED to enable/disable break state (state was %d)", __func__,break_state); } - dbg("%s break state is %d - urb is %d", __FUNCTION__,break_state, urb_value); + dbg("%s break state is %d - urb is %d", __func__,break_state, urb_value); } @@ -1760,18 +1760,18 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old unsigned char vstop; unsigned char vstart; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Force baud rate if this device requires it, unless it is set to B0. */ if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) { - dbg("%s: forcing baud rate for this device", __FUNCTION__); + dbg("%s: forcing baud rate for this device", __func__); tty_encode_baud_rate(port->tty, priv->force_baud, priv->force_baud); } /* Force RTS-CTS if this device requires it. */ if (priv->force_rtscts) { - dbg("%s: forcing rtscts for this device", __FUNCTION__); + dbg("%s: forcing rtscts for this device", __func__); termios->c_cflag |= CRTSCTS; } @@ -1815,7 +1815,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_SHORT_TIMEOUT) < 0) { - err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); + err("%s FAILED to set databits/stopbits/parity", __func__); } /* Now do the baudrate */ @@ -1826,14 +1826,14 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { - err("%s error from disable flowcontrol urb", __FUNCTION__); + err("%s error from disable flowcontrol urb", __func__); } /* Drop RTS and DTR */ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* set the baudrate determined before */ if (change_speed(port)) { - err("%s urb failed to set baudrate", __FUNCTION__); + err("%s urb failed to set baudrate", __func__); } /* Ensure RTS and DTR are raised when baudrate changed from 0 */ if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) { @@ -1844,7 +1844,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old /* Set flow control */ /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ if (cflag & CRTSCTS) { - dbg("%s Setting to CRTSCTS flow control", __FUNCTION__); + dbg("%s Setting to CRTSCTS flow control", __func__); if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, @@ -1862,7 +1862,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old * if IXOFF is not set, the pre-xon/xoff code is executed. */ if (iflag & IXOFF) { - dbg("%s request to enable xonxoff iflag=%04x",__FUNCTION__,iflag); + dbg("%s request to enable xonxoff iflag=%04x",__func__,iflag); // Try to enable the XON/XOFF on the ftdi_sio // Set the vstart and vstop -- could have been done up above where // a lot of other dereferencing is done but that would be very @@ -1883,7 +1883,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old } else { /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */ /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */ - dbg("%s Turning off hardware flow control", __FUNCTION__); + dbg("%s Turning off hardware flow control", __func__); if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, @@ -1905,7 +1905,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) unsigned char buf[2]; int ret; - dbg("%s TIOCMGET", __FUNCTION__); + dbg("%s TIOCMGET", __func__); switch (priv->chip_type) { case SIO: /* Request the status from the device */ @@ -1915,7 +1915,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 0, 0, buf, 1, WDR_TIMEOUT)) < 0 ) { - err("%s Could not get modem status of device - err: %d", __FUNCTION__, + err("%s Could not get modem status of device - err: %d", __func__, ret); return(ret); } @@ -1932,7 +1932,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 0, priv->interface, buf, 2, WDR_TIMEOUT)) < 0 ) { - err("%s Could not get modem status of device - err: %d", __FUNCTION__, + err("%s Could not get modem status of device - err: %d", __func__, ret); return(ret); } @@ -1951,7 +1951,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) { - dbg("%s TIOCMSET", __FUNCTION__); + dbg("%s TIOCMSET", __func__); return update_mctrl(port, set, clear); } @@ -1960,7 +1960,7 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne { struct ftdi_private *priv = usb_get_serial_port_data(port); - dbg("%s cmd 0x%04x", __FUNCTION__, cmd); + dbg("%s cmd 0x%04x", __func__, cmd); /* Based on code from acm.c and others */ switch (cmd) { @@ -2019,7 +2019,7 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne /* This is not necessarily an error - turns out the higher layers will do * some ioctls itself (see comment above) */ - dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __FUNCTION__, cmd); + dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __func__, cmd); return(-ENOIOCTLCMD); } /* ftdi_ioctl */ @@ -2030,7 +2030,7 @@ static void ftdi_throttle (struct usb_serial_port *port) struct ftdi_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->rx_lock, flags); priv->rx_flags |= THROTTLED; @@ -2044,7 +2044,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) int actually_throttled; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->rx_lock, flags); actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; @@ -2059,7 +2059,7 @@ static int __init ftdi_init (void) { int retval; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (vendor > 0 && product > 0) { /* Add user specified VID/PID to reserved element of table. */ int i; @@ -2088,7 +2088,7 @@ failed_sio_register: static void __exit ftdi_exit (void) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); usb_deregister (&ftdi_driver); usb_serial_deregister (&ftdi_sio_device); diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 87b77f92ae07..513d771adc4e 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -280,7 +280,7 @@ static void send_to_tty(struct usb_serial_port *port, if (tty && actual_length) { usb_serial_debug_data(debug, &port->dev, - __FUNCTION__, actual_length, data); + __func__, actual_length, data); tty_buffer_request_room(tty, actual_length); tty_insert_flip_string(tty, data, actual_length); @@ -355,7 +355,7 @@ static void pkt_clear(struct garmin_data * garmin_data_p) unsigned long flags; struct garmin_packet *result = NULL; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&garmin_data_p->lock, flags); while (!list_empty(&garmin_data_p->pktlist)) { @@ -379,7 +379,7 @@ static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id) __u8 *ptr = pkt; unsigned l = 0; - dbg("%s - pkt-id: 0x%X.", __FUNCTION__, 0xFF & pkt_id); + dbg("%s - pkt-id: 0x%X.", __func__, 0xFF & pkt_id); *ptr++ = DLE; *ptr++ = ACK; @@ -429,11 +429,11 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) int size = recpkt[1]; usb_serial_debug_data(debug, &garmin_data_p->port->dev, - __FUNCTION__, count-GSP_INITIAL_OFFSET, recpkt); + __func__, count-GSP_INITIAL_OFFSET, recpkt); if (size != (count-GSP_INITIAL_OFFSET-3)) { dbg("%s - invalid size, expected %d bytes, got %d", - __FUNCTION__, size, (count-GSP_INITIAL_OFFSET-3)); + __func__, size, (count-GSP_INITIAL_OFFSET-3)); return -EINVPKT; } @@ -443,7 +443,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) // sanity check, remove after test ... if ((__u8*)&(usbdata[3]) != recpkt) { dbg("%s - ptr mismatch %p - %p", - __FUNCTION__, &(usbdata[4]), recpkt); + __func__, &(usbdata[4]), recpkt); return -EINVPKT; } @@ -454,7 +454,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) if ((0xff & (cksum + *recpkt)) != 0) { dbg("%s - invalid checksum, expected %02x, got %02x", - __FUNCTION__, 0xff & -cksum, 0xff & *recpkt); + __func__, 0xff & -cksum, 0xff & *recpkt); return -EINVPKT; } @@ -519,7 +519,7 @@ static int gsp_receive(struct garmin_data * garmin_data_p, spin_unlock_irqrestore(&garmin_data_p->lock, flags); dbg("%s - dle=%d skip=%d size=%d count=%d", - __FUNCTION__, dleSeen, skip, size, count); + __func__, dleSeen, skip, size, count); if (size == 0) { size = GSP_INITIAL_OFFSET; @@ -578,7 +578,7 @@ static int gsp_receive(struct garmin_data * garmin_data_p, } if (size >= GPS_IN_BUFSIZ) { - dbg("%s - packet too large.", __FUNCTION__); + dbg("%s - packet too large.", __func__); skip = 1; size = GSP_INITIAL_OFFSET; dleSeen = 0; @@ -634,7 +634,7 @@ static int gsp_send(struct garmin_data * garmin_data_p, int i=0; int k; - dbg("%s - state %d - %d bytes.", __FUNCTION__, + dbg("%s - state %d - %d bytes.", __func__, garmin_data_p->state, count); k = garmin_data_p->outsize; @@ -658,13 +658,13 @@ static int gsp_send(struct garmin_data * garmin_data_p, return 0; } - dbg("%s - %d bytes in buffer, %d bytes in pkt.", __FUNCTION__, + dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__, k, i); /* garmin_data_p->outbuffer now contains a complete packet */ usb_serial_debug_data(debug, &garmin_data_p->port->dev, - __FUNCTION__, k, garmin_data_p->outbuffer); + __func__, k, garmin_data_p->outbuffer); garmin_data_p->outsize = 0; @@ -749,7 +749,7 @@ static void gsp_next_packet(struct garmin_data * garmin_data_p) struct garmin_packet *pkt = NULL; while ((pkt = pkt_pop(garmin_data_p)) != NULL) { - dbg("%s - next pkt: %d", __FUNCTION__, pkt->seq); + dbg("%s - next pkt: %d", __func__, pkt->seq); if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) { kfree(pkt); return; @@ -794,7 +794,7 @@ static int nat_receive(struct garmin_data * garmin_data_p, if (len >= GPS_IN_BUFSIZ) { /* seem to be an invalid packet, ignore rest of input */ dbg("%s - packet size too large: %d", - __FUNCTION__, len); + __func__, len); garmin_data_p->insize = 0; count = 0; result = -EINVPKT; @@ -873,11 +873,11 @@ static int process_resetdev_request(struct usb_serial_port *port) spin_unlock_irqrestore(&garmin_data_p->lock, flags); usb_kill_urb (port->interrupt_in_urb); - dbg("%s - usb_reset_device", __FUNCTION__ ); + dbg("%s - usb_reset_device", __func__ ); status = usb_reset_device(port->serial->dev); if (status) dbg("%s - usb_reset_device failed: %d", - __FUNCTION__, status); + __func__, status); return status; } @@ -926,18 +926,18 @@ static int garmin_init_session(struct usb_serial_port *port) if (status == 0) { usb_kill_urb (port->interrupt_in_urb); - dbg("%s - adding interrupt input", __FUNCTION__); + dbg("%s - adding interrupt input", __func__); port->interrupt_in_urb->dev = serial->dev; status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (status) dev_err(&serial->dev->dev, "%s - failed submitting interrupt urb," " error %d\n", - __FUNCTION__, status); + __func__, status); } if (status == 0) { - dbg("%s - starting session ...", __FUNCTION__); + dbg("%s - starting session ...", __func__); garmin_data_p->state = STATE_ACTIVE; status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, sizeof(GARMIN_START_SESSION_REQ), @@ -976,7 +976,7 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) int status = 0; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * Force low_latency on so that our tty_push actually forces the data @@ -1013,7 +1013,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d - mode=%d state=%d flags=0x%X", __FUNCTION__, + dbg("%s - port %d - mode=%d state=%d flags=0x%X", __func__, port->number, garmin_data_p->mode, garmin_data_p->state, garmin_data_p->flags); @@ -1052,7 +1052,7 @@ static void garmin_write_bulk_callback (struct urb *urb) if (port) { struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { @@ -1061,7 +1061,7 @@ static void garmin_write_bulk_callback (struct urb *urb) if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, urb->status); + __func__, urb->status); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= CLEAR_HALT_REQUIRED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); @@ -1088,7 +1088,7 @@ static int garmin_write_bulk (struct usb_serial_port *port, unsigned char *buffer; int status; - dbg("%s - port %d, state %d", __FUNCTION__, port->number, + dbg("%s - port %d, state %d", __func__, port->number, garmin_data_p->state); spin_lock_irqsave(&garmin_data_p->lock, flags); @@ -1110,7 +1110,7 @@ static int garmin_write_bulk (struct usb_serial_port *port, memcpy (buffer, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); usb_fill_bulk_urb (urb, serial->dev, usb_sndbulkpipe (serial->dev, @@ -1134,7 +1134,7 @@ static int garmin_write_bulk (struct usb_serial_port *port, dev_err(&port->dev, "%s - usb_submit_urb(write bulk) " "failed with status = %d\n", - __FUNCTION__, status); + __func__, status); count = status; } @@ -1154,7 +1154,7 @@ static int garmin_write (struct usb_serial_port *port, struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buf); + usb_serial_debug_data(debug, &port->dev, __func__, count, buf); /* check for our private packets */ if (count >= GARMIN_PKTHDR_LENGTH) { @@ -1172,7 +1172,7 @@ static int garmin_write (struct usb_serial_port *port, && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) { dbg("%s - processing private request %d", - __FUNCTION__, pktid); + __func__, pktid); // drop all unfinished transfers garmin_clear(garmin_data_p); @@ -1184,7 +1184,7 @@ static int garmin_write (struct usb_serial_port *port, return -EINVPKT; debug = __le32_to_cpu(privpkt[3]); dbg("%s - debug level set to 0x%X", - __FUNCTION__, debug); + __func__, debug); break; case PRIV_PKTID_SET_MODE: @@ -1192,7 +1192,7 @@ static int garmin_write (struct usb_serial_port *port, return -EINVPKT; garmin_data_p->mode = __le32_to_cpu(privpkt[3]); dbg("%s - mode set to %d", - __FUNCTION__, garmin_data_p->mode); + __func__, garmin_data_p->mode); break; case PRIV_PKTID_INFO_REQ: @@ -1208,7 +1208,7 @@ static int garmin_write (struct usb_serial_port *port, return -EINVPKT; initial_mode = __le32_to_cpu(privpkt[3]); dbg("%s - initial_mode set to %d", - __FUNCTION__, + __func__, garmin_data_p->mode); break; } @@ -1255,7 +1255,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, { if (garmin_data_p->flags & FLAGS_DROP_DATA) { /* abort-transfer cmd is actice */ - dbg("%s - pkt dropped", __FUNCTION__); + dbg("%s - pkt dropped", __func__); } else if (garmin_data_p->state != STATE_DISCONNECTED && garmin_data_p->state != STATE_RESET ) { @@ -1293,21 +1293,21 @@ static void garmin_read_bulk_callback (struct urb *urb) int status = urb->status; int retval; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!serial) { - dbg("%s - bad serial pointer, exiting", __FUNCTION__); + dbg("%s - bad serial pointer, exiting", __func__); return; } if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } usb_serial_debug_data(debug, &port->dev, - __FUNCTION__, urb->actual_length, data); + __func__, urb->actual_length, data); garmin_read_process(garmin_data_p, data, urb->actual_length); @@ -1320,7 +1320,7 @@ static void garmin_read_bulk_callback (struct urb *urb) if (retval) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, retval); + __func__, retval); } else if (urb->actual_length > 0) { /* Continue trying to read until nothing more is received */ if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) { @@ -1328,10 +1328,10 @@ static void garmin_read_bulk_callback (struct urb *urb) if (retval) dev_err(&port->dev, "%s - failed resubmitting read urb, " - "error %d\n", __FUNCTION__, retval); + "error %d\n", __func__, retval); } } else { - dbg("%s - end of bulk data", __FUNCTION__); + dbg("%s - end of bulk data", __func__); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_BULK_IN_ACTIVE; spin_unlock_irqrestore(&garmin_data_p->lock, flags); @@ -1359,22 +1359,22 @@ static void garmin_read_int_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, urb->transfer_buffer); if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) && 0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY, sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) { - dbg("%s - bulk data available.", __FUNCTION__); + dbg("%s - bulk data available.", __func__); if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { @@ -1389,7 +1389,7 @@ static void garmin_read_int_callback (struct urb *urb) if (retval) { dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", - __FUNCTION__, retval); + __func__, retval); } else { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; @@ -1417,14 +1417,14 @@ static void garmin_read_int_callback (struct urb *urb) = __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH)); dbg("%s - start-of-session reply seen - serial %u.", - __FUNCTION__, garmin_data_p->serial_num); + __func__, garmin_data_p->serial_num); } if (garmin_data_p->ignorePkts) { /* this reply belongs to a request generated by the driver, ignore it. */ dbg("%s - pkt ignored (%d)", - __FUNCTION__, garmin_data_p->ignorePkts); + __func__, garmin_data_p->ignorePkts); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts--; spin_unlock_irqrestore(&garmin_data_p->lock, flags); @@ -1437,7 +1437,7 @@ static void garmin_read_int_callback (struct urb *urb) if (retval) dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, retval); + __func__, retval); } @@ -1473,7 +1473,7 @@ static void garmin_throttle (struct usb_serial_port *port) unsigned long flags; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* set flag, data received will be put into a queue for later processing */ spin_lock_irqsave(&garmin_data_p->lock, flags); @@ -1488,7 +1488,7 @@ static void garmin_unthrottle (struct usb_serial_port *port) struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_THROTTLED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); @@ -1503,7 +1503,7 @@ static void garmin_unthrottle (struct usb_serial_port *port) if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, status); + __func__, status); } } @@ -1532,11 +1532,11 @@ static int garmin_attach (struct usb_serial *serial) struct usb_serial_port *port = serial->port[0]; struct garmin_data * garmin_data_p = NULL; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { - dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&port->dev, "%s - Out of memory\n", __func__); return -ENOMEM; } init_timer(&garmin_data_p->timer); @@ -1561,7 +1561,7 @@ static void garmin_shutdown (struct usb_serial *serial) struct usb_serial_port *port = serial->port[0]; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); usb_kill_urb (port->interrupt_in_urb); del_timer_sync(&garmin_data_p->timer); diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 5b0952054dec..2078667db4aa 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -118,7 +118,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) int result = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* force low_latency on so that our tty_push actually forces the data through, otherwise it is scheduled, and with high data rates (like with OHCI) data @@ -145,7 +145,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); } return result; @@ -156,7 +156,7 @@ static void generic_cleanup (struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (serial->dev) { /* shutdown any bulk reads that might be going on */ @@ -194,7 +194,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); generic_cleanup (port); } @@ -204,10 +204,10 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * int result; unsigned char *data; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return (0); } @@ -217,7 +217,7 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy) { spin_unlock_irqrestore(&port->lock, flags); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; @@ -227,7 +227,7 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * memcpy (port->write_urb->transfer_buffer, buf, count); data = port->write_urb->transfer_buffer; - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, data); + usb_serial_debug_data(debug, &port->dev, __func__, count, data); /* set up our urb */ usb_fill_bulk_urb (port->write_urb, serial->dev, @@ -242,7 +242,7 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * port->write_urb_busy = 1; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); /* don't have to grab the lock here, as we will retry if != 0 */ port->write_urb_busy = 0; } else @@ -260,14 +260,14 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) struct usb_serial *serial = port->serial; int room = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (serial->num_bulk_out) { if (!(port->write_urb_busy)) room = port->bulk_out_size; } - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return (room); } @@ -276,14 +276,14 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) struct usb_serial *serial = port->serial; int chars = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (serial->num_bulk_out) { if (port->write_urb_busy) chars = port->write_urb->transfer_buffer_length; } - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return (chars); } @@ -305,7 +305,7 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) usb_serial_generic_read_bulk_callback), port); result = usb_submit_urb(urb, mem_flags); if (result) - dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); } /* Push data to tty layer and resubmit the bulk read URB */ @@ -334,15 +334,15 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) int status = urb->status; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (unlikely(status != 0)) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* Throttle the device if requested by tty */ spin_lock_irqsave(&port->lock, flags); @@ -360,12 +360,12 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); port->write_urb_busy = 0; if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -377,7 +377,7 @@ void usb_serial_generic_throttle (struct usb_serial_port *port) { unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* Set the throttle request flag. It will be picked up * by usb_serial_generic_read_bulk_callback(). */ @@ -391,7 +391,7 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port) int was_throttled; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* Clear the throttle flags */ spin_lock_irqsave(&port->lock, flags); @@ -409,7 +409,7 @@ void usb_serial_generic_shutdown (struct usb_serial *serial) { int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 3428ccc28da7..2b676732e9fa 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -371,7 +371,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) struct usb_string_descriptor StringDesc; struct usb_string_descriptor *pStringDesc; - dbg("%s - USB String ID = %d", __FUNCTION__, Id ); + dbg("%s - USB String ID = %d", __func__, Id ); if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) { return 0; @@ -391,7 +391,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); kfree(pStringDesc); - dbg("%s - USB String %s", __FUNCTION__, string); + dbg("%s - USB String %s", __func__, string); return strlen(string); } @@ -407,7 +407,7 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de struct usb_string_descriptor StringDesc; struct usb_string_descriptor *pStringDesc; - dbg("%s - USB String ID = %d", __FUNCTION__, Id ); + dbg("%s - USB String ID = %d", __func__, Id ); if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) { return 0; @@ -537,7 +537,7 @@ static int get_epic_descriptor(struct edgeport_serial *ep) sizeof(struct edge_compatibility_descriptor), 300); - dbg("%s result = %d", __FUNCTION__, result); + dbg("%s result = %d", __func__, result); if (result > 0) { ep->is_epic = 1; @@ -601,7 +601,7 @@ static void edge_interrupt_callback (struct urb *urb) int result; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); switch (status) { case 0: @@ -612,35 +612,35 @@ static void edge_interrupt_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } // process this interrupt-read even if there are no ports open if (length) { - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, length, data); + usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, length, data); if (length > 1) { bytes_avail = data[0] | (data[1] << 8); if (bytes_avail) { spin_lock(&edge_serial->es_lock); edge_serial->rxBytesAvail += bytes_avail; - dbg("%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d", __FUNCTION__, bytes_avail, edge_serial->rxBytesAvail, edge_serial->read_in_progress); + dbg("%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d", __func__, bytes_avail, edge_serial->rxBytesAvail, edge_serial->read_in_progress); if (edge_serial->rxBytesAvail > 0 && !edge_serial->read_in_progress) { - dbg("%s - posting a read", __FUNCTION__); + dbg("%s - posting a read", __func__); edge_serial->read_in_progress = true; /* we have pending bytes on the bulk in pipe, send a request */ edge_serial->read_urb->dev = edge_serial->serial->dev; result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (result) { - dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __FUNCTION__, result); + dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __func__, result); edge_serial->read_in_progress = false; } } @@ -659,7 +659,7 @@ static void edge_interrupt_callback (struct urb *urb) spin_lock(&edge_port->ep_lock); edge_port->txCredits += txCredits; spin_unlock(&edge_port->ep_lock); - dbg("%s - txcredits for port%d = %d", __FUNCTION__, portNumber, edge_port->txCredits); + dbg("%s - txcredits for port%d = %d", __func__, portNumber, edge_port->txCredits); /* tell the tty driver that something has changed */ if (edge_port->port->tty) @@ -677,7 +677,7 @@ static void edge_interrupt_callback (struct urb *urb) exit: result = usb_submit_urb (urb, GFP_ATOMIC); if (result) { - dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __FUNCTION__, result); + dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __func__, result); } } @@ -695,43 +695,43 @@ static void edge_bulk_in_callback (struct urb *urb) __u16 raw_data_length; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); edge_serial->read_in_progress = false; return; } if (urb->actual_length == 0) { - dbg("%s - read bulk callback with no data", __FUNCTION__); + dbg("%s - read bulk callback with no data", __func__); edge_serial->read_in_progress = false; return; } raw_data_length = urb->actual_length; - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, raw_data_length, data); + usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, raw_data_length, data); spin_lock(&edge_serial->es_lock); /* decrement our rxBytes available by the number that we just got */ edge_serial->rxBytesAvail -= raw_data_length; - dbg("%s - Received = %d, rxBytesAvail %d", __FUNCTION__, raw_data_length, edge_serial->rxBytesAvail); + dbg("%s - Received = %d, rxBytesAvail %d", __func__, raw_data_length, edge_serial->rxBytesAvail); process_rcvd_data (edge_serial, data, urb->actual_length); /* check to see if there's any more data for us to read */ if (edge_serial->rxBytesAvail > 0) { - dbg("%s - posting a read", __FUNCTION__); + dbg("%s - posting a read", __func__); edge_serial->read_urb->dev = edge_serial->serial->dev; retval = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (retval) { dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, " - "retval = %d\n", __FUNCTION__, retval); + "retval = %d\n", __func__, retval); edge_serial->read_in_progress = false; } } else { @@ -753,11 +753,11 @@ static void edge_bulk_out_data_callback (struct urb *urb) struct tty_struct *tty; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); } tty = edge_port->port->tty; @@ -786,10 +786,10 @@ static void edge_bulk_out_cmd_callback (struct urb *urb) struct tty_struct *tty; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); atomic_dec(&CmdUrbs); - dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); + dbg("%s - FREE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs)); /* clean up the transfer buffer */ @@ -799,7 +799,7 @@ static void edge_bulk_out_cmd_callback (struct urb *urb) usb_free_urb (urb); if (status) { - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, status); + dbg("%s - nonzero write bulk status received: %d", __func__, status); return; } @@ -833,7 +833,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) struct edgeport_serial *edge_serial; int response; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return -ENODEV; @@ -883,7 +883,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) * this interrupt will continue as long as the edgeport is connected */ response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL); if (response) { - dev_err(&port->dev, "%s - Error %d submitting control urb\n", __FUNCTION__, response); + dev_err(&port->dev, "%s - Error %d submitting control urb\n", __func__, response); } } @@ -907,7 +907,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0); if (response < 0) { - dev_err(&port->dev, "%s - error sending open port command\n", __FUNCTION__); + dev_err(&port->dev, "%s - error sending open port command\n", __func__); edge_port->openPending = false; return -ENODEV; } @@ -917,7 +917,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) if (!edge_port->open) { /* open timed out */ - dbg("%s - open timedout", __FUNCTION__); + dbg("%s - open timedout", __func__); edge_port->openPending = false; return -ENODEV; } @@ -930,7 +930,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) edge_port->txfifo.fifo = kmalloc (edge_port->maxTxCredits, GFP_KERNEL); if (!edge_port->txfifo.fifo) { - dbg("%s - no memory", __FUNCTION__); + dbg("%s - no memory", __func__); edge_close (port, filp); return -ENOMEM; } @@ -940,14 +940,14 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) edge_port->write_in_progress = false; if (!edge_port->write_urb) { - dbg("%s - no memory", __FUNCTION__); + dbg("%s - no memory", __func__); edge_close (port, filp); return -ENOMEM; } - dbg("%s(%d) - Initialize TX fifo to %d bytes", __FUNCTION__, port->number, edge_port->maxTxCredits); + dbg("%s(%d) - Initialize TX fifo to %d bytes", __func__, port->number, edge_port->maxTxCredits); - dbg("%s exited", __FUNCTION__); + dbg("%s exited", __func__); return 0; } @@ -976,11 +976,11 @@ static void block_until_chase_response(struct edgeport_port *edge_port) // Did we get our Chase response if (!edge_port->chaseResponsePending) { - dbg("%s - Got Chase Response", __FUNCTION__); + dbg("%s - Got Chase Response", __func__); // did we get all of our credit back? if (edge_port->txCredits == edge_port->maxTxCredits ) { - dbg("%s - Got all credits", __FUNCTION__); + dbg("%s - Got all credits", __func__); return; } } @@ -995,12 +995,12 @@ static void block_until_chase_response(struct edgeport_port *edge_port) loop--; if (loop == 0) { edge_port->chaseResponsePending = false; - dbg("%s - Chase TIMEOUT", __FUNCTION__); + dbg("%s - Chase TIMEOUT", __func__); return; } } else { // Reset timeout value back to 10 seconds - dbg("%s - Last %d, Current %d", __FUNCTION__, lastCredits, edge_port->txCredits); + dbg("%s - Last %d, Current %d", __func__, lastCredits, edge_port->txCredits); loop = 10; } } @@ -1031,7 +1031,7 @@ static void block_until_tx_empty (struct edgeport_port *edge_port) // Is the Edgeport Buffer empty? if (lastCount == 0) { - dbg("%s - TX Buffer Empty", __FUNCTION__); + dbg("%s - TX Buffer Empty", __func__); return; } @@ -1040,13 +1040,13 @@ static void block_until_tx_empty (struct edgeport_port *edge_port) schedule_timeout(timeout); finish_wait(&edge_port->wait_chase, &wait); - dbg("%s wait", __FUNCTION__); + dbg("%s wait", __func__); if (lastCount == fifo->count) { // No activity.. count down. loop--; if (loop == 0) { - dbg("%s - TIMEOUT", __FUNCTION__); + dbg("%s - TIMEOUT", __func__); return; } } else { @@ -1067,7 +1067,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) struct edgeport_port *edge_port; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); edge_serial = usb_get_serial_data(port->serial); edge_port = usb_get_serial_port_data(port); @@ -1085,7 +1085,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) /* flush and chase */ edge_port->chaseResponsePending = true; - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); + dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); if (status == 0) { // block until chase finished @@ -1099,7 +1099,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) ((edge_serial->is_epic) && (edge_serial->epic_descriptor.Supports.IOSPClose))) { /* close the port */ - dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); + dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __func__); send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); } @@ -1119,7 +1119,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) kfree(edge_port->txfifo.fifo); edge_port->txfifo.fifo = NULL; - dbg("%s exited", __FUNCTION__); + dbg("%s exited", __func__); } /***************************************************************************** @@ -1139,7 +1139,7 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data, int secondhalf; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return -ENODEV; @@ -1152,12 +1152,12 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data, // calculate number of bytes to put in fifo copySize = min ((unsigned int)count, (edge_port->txCredits - fifo->count)); - dbg("%s(%d) of %d byte(s) Fifo room %d -- will copy %d bytes", __FUNCTION__, + dbg("%s(%d) of %d byte(s) Fifo room %d -- will copy %d bytes", __func__, port->number, count, edge_port->txCredits - fifo->count, copySize); /* catch writes of 0 bytes which the tty driver likes to give us, and when txCredits is empty */ if (copySize == 0) { - dbg("%s - copySize = Zero", __FUNCTION__); + dbg("%s - copySize = Zero", __func__); goto finish_write; } @@ -1169,11 +1169,11 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data, bytesleft = fifo->size - fifo->head; firsthalf = min (bytesleft, copySize); - dbg("%s - copy %d bytes of %d into fifo ", __FUNCTION__, firsthalf, bytesleft); + dbg("%s - copy %d bytes of %d into fifo ", __func__, firsthalf, bytesleft); /* now copy our data */ memcpy(&fifo->fifo[fifo->head], data, firsthalf); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, firsthalf, &fifo->fifo[fifo->head]); + usb_serial_debug_data(debug, &port->dev, __func__, firsthalf, &fifo->fifo[fifo->head]); // update the index and size fifo->head += firsthalf; @@ -1187,9 +1187,9 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data, secondhalf = copySize-firsthalf; if (secondhalf) { - dbg("%s - copy rest of data %d", __FUNCTION__, secondhalf); + dbg("%s - copy rest of data %d", __func__, secondhalf); memcpy(&fifo->fifo[fifo->head], &data[firsthalf], secondhalf); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, secondhalf, &fifo->fifo[fifo->head]); + usb_serial_debug_data(debug, &port->dev, __func__, secondhalf, &fifo->fifo[fifo->head]); // update the index and size fifo->count += secondhalf; fifo->head += secondhalf; @@ -1201,7 +1201,7 @@ finish_write: send_more_port_data((struct edgeport_serial *)usb_get_serial_data(port->serial), edge_port); - dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __FUNCTION__, copySize, edge_port->txCredits, fifo->count); + dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__, copySize, edge_port->txCredits, fifo->count); return copySize; } @@ -1232,14 +1232,14 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge int secondhalf; unsigned long flags; - dbg("%s(%d)", __FUNCTION__, edge_port->port->number); + dbg("%s(%d)", __func__, edge_port->port->number); spin_lock_irqsave(&edge_port->ep_lock, flags); if (edge_port->write_in_progress || !edge_port->open || (fifo->count == 0)) { - dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d", __FUNCTION__, edge_port->port->number, fifo->count, edge_port->write_in_progress); + dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d", __func__, edge_port->port->number, fifo->count, edge_port->write_in_progress); goto exit_send; } @@ -1251,7 +1251,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge // it's better to wait for more credits so we can do a larger // write. if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits,EDGE_FW_BULK_MAX_PACKET_SIZE)) { - dbg("%s(%d) Not enough credit - fifo %d TxCredit %d", __FUNCTION__, edge_port->port->number, fifo->count, edge_port->txCredits ); + dbg("%s(%d) Not enough credit - fifo %d TxCredit %d", __func__, edge_port->port->number, fifo->count, edge_port->txCredits ); goto exit_send; } @@ -1269,7 +1269,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge count = fifo->count; buffer = kmalloc (count+2, GFP_ATOMIC); if (buffer == NULL) { - dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __FUNCTION__); + dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __func__); edge_port->write_in_progress = false; goto exit_send; } @@ -1294,7 +1294,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge } if (count) - usb_serial_debug_data(debug, &edge_port->port->dev, __FUNCTION__, count, &buffer[2]); + usb_serial_debug_data(debug, &edge_port->port->dev, __func__, count, &buffer[2]); /* fill up the urb with all of our data and submit it */ usb_fill_bulk_urb (urb, edge_serial->serial->dev, @@ -1309,14 +1309,14 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { /* something went wrong */ - dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __FUNCTION__, status); + dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __func__, status); edge_port->write_in_progress = false; /* revert the credits as something bad happened. */ edge_port->txCredits += count; edge_port->icount.tx -= count; } - dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __FUNCTION__, count, edge_port->txCredits, fifo->count); + dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __func__, count, edge_port->txCredits, fifo->count); exit_send: spin_unlock_irqrestore(&edge_port->ep_lock, flags); @@ -1337,17 +1337,17 @@ static int edge_write_room (struct usb_serial_port *port) int room; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (edge_port == NULL) return -ENODEV; if (edge_port->closePending) return -ENODEV; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!edge_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return -EINVAL; } @@ -1356,7 +1356,7 @@ static int edge_write_room (struct usb_serial_port *port) room = edge_port->txCredits - edge_port->txfifo.count; spin_unlock_irqrestore(&edge_port->ep_lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -1376,7 +1376,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) int num_chars; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (edge_port == NULL) return -ENODEV; @@ -1384,7 +1384,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) return -ENODEV; if (!edge_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return -EINVAL; } @@ -1392,7 +1392,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) num_chars = edge_port->maxTxCredits - edge_port->txCredits + edge_port->txfifo.count; spin_unlock_irqrestore(&edge_port->ep_lock, flags); if (num_chars) { - dbg("%s(port %d) - returns %d", __FUNCTION__, port->number, num_chars); + dbg("%s(port %d) - returns %d", __func__, port->number, num_chars); } return num_chars; @@ -1410,19 +1410,19 @@ static void edge_throttle (struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; if (!edge_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } tty = port->tty; if (!tty) { - dbg ("%s - no tty available", __FUNCTION__); + dbg ("%s - no tty available", __func__); return; } @@ -1459,19 +1459,19 @@ static void edge_unthrottle (struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; if (!edge_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } tty = port->tty; if (!tty) { - dbg ("%s - no tty available", __FUNCTION__); + dbg ("%s - no tty available", __func__); return; } @@ -1509,18 +1509,18 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old unsigned int cflag; cflag = tty->termios->c_cflag; - dbg("%s - clfag %08x iflag %08x", __FUNCTION__, + dbg("%s - clfag %08x iflag %08x", __func__, tty->termios->c_cflag, tty->termios->c_iflag); - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + dbg("%s - old clfag %08x old iflag %08x", __func__, old_termios->c_cflag, old_termios->c_iflag); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; if (!edge_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } @@ -1549,7 +1549,7 @@ static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *va spin_lock_irqsave(&edge_port->ep_lock, flags); if (edge_port->maxTxCredits == edge_port->txCredits && edge_port->txfifo.count == 0) { - dbg("%s -- Empty", __FUNCTION__); + dbg("%s -- Empty", __func__); result = TIOCSER_TEMT; } spin_unlock_irqrestore(&edge_port->ep_lock, flags); @@ -1569,7 +1569,7 @@ static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int result = tty->read_cnt; - dbg("%s(%d) = %d", __FUNCTION__, edge_port->port->number, result); + dbg("%s(%d) = %d", __func__, edge_port->port->number, result); if (copy_to_user(value, &result, sizeof(int))) return -EFAULT; //return 0; @@ -1581,7 +1581,7 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig struct edgeport_port *edge_port = usb_get_serial_port_data(port); unsigned int mcr; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); mcr = edge_port->shadowMCR; if (set & TIOCM_RTS) @@ -1612,7 +1612,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int msr; unsigned int mcr; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); msr = edge_port->shadowMSR; mcr = edge_port->shadowMCR; @@ -1624,7 +1624,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - dbg("%s -- %x", __FUNCTION__, result); + dbg("%s -- %x", __func__, result); return result; } @@ -1670,30 +1670,30 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned struct async_icount cprev; struct serial_icounter_struct icount; - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); switch (cmd) { // return number of bytes available case TIOCINQ: - dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); + dbg("%s (%d) TIOCINQ", __func__, port->number); return get_number_bytes_avail(edge_port, (unsigned int __user *) arg); break; case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); return get_lsr_info(edge_port, (unsigned int __user *) arg); return 0; case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCGSERIAL", __func__, port->number); return get_serial_info(edge_port, (struct serial_struct __user *) arg); case TIOCSSERIAL: - dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSSERIAL", __func__, port->number); break; case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); cprev = edge_port->icount; while (1) { prepare_to_wait(&edge_port->delta_msr_wait, &wait, TASK_INTERRUPTIBLE); @@ -1732,7 +1732,7 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, icount.rx, icount.tx ); + dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, icount.rx, icount.tx ); if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; @@ -1758,7 +1758,7 @@ static void edge_break (struct usb_serial_port *port, int break_state) /* flush and chase */ edge_port->chaseResponsePending = true; - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); + dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); if (status == 0) { // block until chase finished @@ -1772,14 +1772,14 @@ static void edge_break (struct usb_serial_port *port, int break_state) ((edge_serial->is_epic) && (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { if (break_state == -1) { - dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); + dbg("%s - Sending IOSP_CMD_SET_BREAK", __func__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); } else { - dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); + dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __func__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); } if (status) { - dbg("%s - error sending break set/clear command.", __FUNCTION__); + dbg("%s - error sending break set/clear command.", __func__); } } @@ -1799,14 +1799,14 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha __u16 lastBufferLength; __u16 rxLen; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); lastBufferLength = bufferLength + 1; while (bufferLength > 0) { /* failsafe incase we get a message that we don't understand */ if (lastBufferLength == bufferLength) { - dbg("%s - stuck in loop, exiting it.", __FUNCTION__); + dbg("%s - stuck in loop, exiting it.", __func__); break; } lastBufferLength = bufferLength; @@ -1828,7 +1828,7 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha ++buffer; --bufferLength; - dbg("%s - Hdr1=%02X Hdr2=%02X", __FUNCTION__, edge_serial->rxHeader1, edge_serial->rxHeader2); + dbg("%s - Hdr1=%02X Hdr2=%02X", __func__, edge_serial->rxHeader1, edge_serial->rxHeader2); // Process depending on whether this header is // data or status @@ -1858,7 +1858,7 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha edge_serial->rxPort = IOSP_GET_HDR_PORT(edge_serial->rxHeader1); edge_serial->rxBytesRemaining = IOSP_GET_HDR_DATA_LEN(edge_serial->rxHeader1, edge_serial->rxHeader2); - dbg("%s - Data for Port %u Len %u", __FUNCTION__, edge_serial->rxPort, edge_serial->rxBytesRemaining); + dbg("%s - Data for Port %u Len %u", __func__, edge_serial->rxPort, edge_serial->rxBytesRemaining); //ASSERT( DevExt->RxPort < DevExt->NumPorts ); //ASSERT( DevExt->RxBytesRemaining < IOSP_MAX_DATA_LENGTH ); @@ -1891,7 +1891,7 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha if (edge_port->open) { tty = edge_port->port->tty; if (tty) { - dbg("%s - Sending %d bytes to TTY for port %d", __FUNCTION__, rxLen, edge_serial->rxPort); + dbg("%s - Sending %d bytes to TTY for port %d", __func__, rxLen, edge_serial->rxPort); edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); } edge_port->icount.rx += rxLen; @@ -1930,17 +1930,17 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 port = edge_serial->serial->port[edge_serial->rxPort]; edge_port = usb_get_serial_port_data(port); if (edge_port == NULL) { - dev_err(&edge_serial->serial->dev->dev, "%s - edge_port == NULL for port %d\n", __FUNCTION__, edge_serial->rxPort); + dev_err(&edge_serial->serial->dev->dev, "%s - edge_port == NULL for port %d\n", __func__, edge_serial->rxPort); return; } - dbg("%s - port %d", __FUNCTION__, edge_serial->rxPort); + dbg("%s - port %d", __func__, edge_serial->rxPort); if (code == IOSP_EXT_STATUS) { switch (byte2) { case IOSP_EXT_STATUS_CHASE_RSP: // we want to do EXT status regardless of port open/closed - dbg("%s - Port %u EXT CHASE_RSP Data = %02x", __FUNCTION__, edge_serial->rxPort, byte3 ); + dbg("%s - Port %u EXT CHASE_RSP Data = %02x", __func__, edge_serial->rxPort, byte3 ); // Currently, the only EXT_STATUS is Chase, so process here instead of one more call // to one more subroutine. If/when more EXT_STATUS, there'll be more work to do. // Also, we currently clear flag and close the port regardless of content of above's Byte3. @@ -1951,7 +1951,7 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 return; case IOSP_EXT_STATUS_RX_CHECK_RSP: - dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __FUNCTION__, edge_serial->rxPort, byte3 ); + dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3 ); //Port->RxCheckRsp = true; return; } @@ -1960,7 +1960,7 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 if (code == IOSP_STATUS_OPEN_RSP) { edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3); edge_port->maxTxCredits = edge_port->txCredits; - dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __FUNCTION__, edge_serial->rxPort, byte2, edge_port->txCredits); + dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits); handle_new_msr (edge_port, byte2); /* send the current line settings to the port so we are in sync with any further termios calls */ @@ -1984,23 +1984,23 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 switch (code) { // Not currently sent by Edgeport case IOSP_STATUS_LSR: - dbg("%s - Port %u LSR Status = %02x", __FUNCTION__, edge_serial->rxPort, byte2); + dbg("%s - Port %u LSR Status = %02x", __func__, edge_serial->rxPort, byte2); handle_new_lsr(edge_port, false, byte2, 0); break; case IOSP_STATUS_LSR_DATA: - dbg("%s - Port %u LSR Status = %02x, Data = %02x", __FUNCTION__, edge_serial->rxPort, byte2, byte3); + dbg("%s - Port %u LSR Status = %02x, Data = %02x", __func__, edge_serial->rxPort, byte2, byte3); // byte2 is LSR Register // byte3 is broken data byte handle_new_lsr(edge_port, true, byte2, byte3); break; // // case IOSP_EXT_4_STATUS: - // dbg("%s - Port %u LSR Status = %02x Data = %02x", __FUNCTION__, edge_serial->rxPort, byte2, byte3); + // dbg("%s - Port %u LSR Status = %02x Data = %02x", __func__, edge_serial->rxPort, byte2, byte3); // break; // case IOSP_STATUS_MSR: - dbg("%s - Port %u MSR Status = %02x", __FUNCTION__, edge_serial->rxPort, byte2); + dbg("%s - Port %u MSR Status = %02x", __func__, edge_serial->rxPort, byte2); // Process this new modem status and generate appropriate // events, etc, based on the new status. This routine @@ -2009,7 +2009,7 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 break; default: - dbg("%s - Unrecognized IOSP status code %u\n", __FUNCTION__, code); + dbg("%s - Unrecognized IOSP status code %u\n", __func__, code); break; } @@ -2029,7 +2029,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c cnt = tty_buffer_request_room(tty, length); if (cnt < length) { dev_err(dev, "%s - dropping data, %d bytes lost\n", - __FUNCTION__, length - cnt); + __func__, length - cnt); if(cnt == 0) break; } @@ -2050,7 +2050,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr) { struct async_icount *icount; - dbg("%s %02x", __FUNCTION__, newMsr); + dbg("%s %02x", __func__, newMsr); if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { icount = &edge_port->icount; @@ -2087,7 +2087,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 l __u8 newLsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK)); struct async_icount *icount; - dbg("%s - %02x", __FUNCTION__, newLsr); + dbg("%s - %02x", __func__, newLsr); edge_port->shadowLSR = lsr; @@ -2136,11 +2136,11 @@ static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u __u16 current_length; unsigned char *transfer_buffer; - dbg("%s - %x, %x, %d", __FUNCTION__, extAddr, addr, length); + dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); transfer_buffer = kmalloc (64, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 64); + dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64); return -ENOMEM; } @@ -2152,7 +2152,7 @@ static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u } else { current_length = length; } -// dbg("%s - writing %x, %x, %d", __FUNCTION__, extAddr, addr, current_length); +// dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length); memcpy (transfer_buffer, data, current_length); result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_RAM, 0x40, addr, extAddr, transfer_buffer, current_length, 300); @@ -2181,11 +2181,11 @@ static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u1 __u16 current_length; unsigned char *transfer_buffer; -// dbg("%s - %x, %x, %d", __FUNCTION__, extAddr, addr, length); +// dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); transfer_buffer = kmalloc (64, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 64); + dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64); return -ENOMEM; } @@ -2197,7 +2197,7 @@ static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u1 } else { current_length = length; } -// dbg("%s - writing %x, %x, %d", __FUNCTION__, extAddr, addr, current_length); +// dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length); memcpy (transfer_buffer, data, current_length); result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_ROM, 0x40, addr, extAddr, transfer_buffer, current_length, 300); @@ -2226,11 +2226,11 @@ static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 __u16 current_length; unsigned char *transfer_buffer; - dbg("%s - %x, %x, %d", __FUNCTION__, extAddr, addr, length); + dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); transfer_buffer = kmalloc (64, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 64); + dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64); return -ENOMEM; } @@ -2242,7 +2242,7 @@ static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 } else { current_length = length; } -// dbg("%s - %x, %x, %d", __FUNCTION__, extAddr, addr, current_length); +// dbg("%s - %x, %x, %d", __func__, extAddr, addr, current_length); result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), USB_REQUEST_ION_READ_ROM, 0xC0, addr, extAddr, transfer_buffer, current_length, 300); if (result < 0) @@ -2269,11 +2269,11 @@ static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u int length = 0; int status = 0; - dbg("%s - %d, %d", __FUNCTION__, command, param); + dbg("%s - %d, %d", __func__, command, param); buffer = kmalloc (10, GFP_ATOMIC); if (!buffer) { - dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 10); + dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 10); return -ENOMEM; } @@ -2304,7 +2304,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer struct urb *urb; int timeout; - usb_serial_debug_data(debug, &edge_port->port->dev, __FUNCTION__, length, buffer); + usb_serial_debug_data(debug, &edge_port->port->dev, __func__, length, buffer); /* Allocate our next urb */ urb = usb_alloc_urb (0, GFP_ATOMIC); @@ -2312,7 +2312,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer return -ENOMEM; atomic_inc(&CmdUrbs); - dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); + dbg("%s - ALLOCATE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs)); usb_fill_bulk_urb (urb, edge_serial->serial->dev, usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), @@ -2323,7 +2323,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer if (status) { /* something went wrong */ - dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __FUNCTION__, status); + dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __func__, status); usb_kill_urb(urb); usb_free_urb(urb); atomic_dec(&CmdUrbs); @@ -2337,7 +2337,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer if (edge_port->commandPending) { /* command timed out */ - dbg("%s - command timed out", __FUNCTION__); + dbg("%s - command timed out", __func__); status = -EINVAL; } #endif @@ -2367,18 +2367,18 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa return 0; } - dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); + dbg("%s - port = %d, baud = %d", __func__, edge_port->port->number, baudRate); status = calc_baud_rate_divisor (baudRate, &divisor); if (status) { - dev_err(&edge_port->port->dev, "%s - bad baud rate\n", __FUNCTION__); + dev_err(&edge_port->port->dev, "%s - bad baud rate\n", __func__); return status; } // Alloc memory for the string of commands. cmdBuffer = kmalloc (0x100, GFP_ATOMIC); if (!cmdBuffer) { - dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 0x100); + dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 0x100); return -ENOMEM; } currCmd = cmdBuffer; @@ -2414,7 +2414,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) __u16 custom; - dbg("%s - %d", __FUNCTION__, baudrate); + dbg("%s - %d", __func__, baudrate); for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { if ( divisor_table[i].BaudRate == baudrate ) { @@ -2432,7 +2432,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) *divisor = custom; - dbg("%s - Baud %d = %d\n", __FUNCTION__, baudrate, custom); + dbg("%s - Baud %d = %d\n", __func__, baudrate, custom); return 0; } @@ -2452,7 +2452,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r unsigned long cmdLen = 0; int status; - dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); + dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __func__, regValue); if (edge_serial->is_epic && !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && @@ -2513,29 +2513,29 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi __u8 txFlow; int status; - dbg("%s - port %d", __FUNCTION__, edge_port->port->number); + dbg("%s - port %d", __func__, edge_port->port->number); if (!edge_port->open && !edge_port->openPending) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } tty = edge_port->port->tty; if ((!tty) || (!tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); + dbg("%s - no tty structures", __func__); return; } cflag = tty->termios->c_cflag; switch (cflag & CSIZE) { - case CS5: lData = LCR_BITS_5; mask = 0x1f; dbg("%s - data bits = 5", __FUNCTION__); break; - case CS6: lData = LCR_BITS_6; mask = 0x3f; dbg("%s - data bits = 6", __FUNCTION__); break; - case CS7: lData = LCR_BITS_7; mask = 0x7f; dbg("%s - data bits = 7", __FUNCTION__); break; + case CS5: lData = LCR_BITS_5; mask = 0x1f; dbg("%s - data bits = 5", __func__); break; + case CS6: lData = LCR_BITS_6; mask = 0x3f; dbg("%s - data bits = 6", __func__); break; + case CS7: lData = LCR_BITS_7; mask = 0x7f; dbg("%s - data bits = 7", __func__); break; default: - case CS8: lData = LCR_BITS_8; dbg("%s - data bits = 8", __FUNCTION__); break; + case CS8: lData = LCR_BITS_8; dbg("%s - data bits = 8", __func__); break; } lParity = LCR_PAR_NONE; @@ -2543,28 +2543,28 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi if (cflag & CMSPAR) { if (cflag & PARODD) { lParity = LCR_PAR_MARK; - dbg("%s - parity = mark", __FUNCTION__); + dbg("%s - parity = mark", __func__); } else { lParity = LCR_PAR_SPACE; - dbg("%s - parity = space", __FUNCTION__); + dbg("%s - parity = space", __func__); } } else if (cflag & PARODD) { lParity = LCR_PAR_ODD; - dbg("%s - parity = odd", __FUNCTION__); + dbg("%s - parity = odd", __func__); } else { lParity = LCR_PAR_EVEN; - dbg("%s - parity = even", __FUNCTION__); + dbg("%s - parity = even", __func__); } } else { - dbg("%s - parity = none", __FUNCTION__); + dbg("%s - parity = none", __func__); } if (cflag & CSTOPB) { lStop = LCR_STOP_2; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { lStop = LCR_STOP_1; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } /* figure out the flow control settings */ @@ -2572,9 +2572,9 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi if (cflag & CRTSCTS) { rxFlow |= IOSP_RX_FLOW_RTS; txFlow |= IOSP_TX_FLOW_CTS; - dbg("%s - RTS/CTS is enabled", __FUNCTION__); + dbg("%s - RTS/CTS is enabled", __func__); } else { - dbg("%s - RTS/CTS is disabled", __FUNCTION__); + dbg("%s - RTS/CTS is disabled", __func__); } /* if we are implementing XON/XOFF, set the start and stop character in the device */ @@ -2592,17 +2592,17 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi /* if we are implementing INBOUND XON/XOFF */ if (I_IXOFF(tty)) { rxFlow |= IOSP_RX_FLOW_XON_XOFF; - dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __FUNCTION__, start_char, stop_char); + dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char); } else { - dbg("%s - INBOUND XON/XOFF is disabled", __FUNCTION__); + dbg("%s - INBOUND XON/XOFF is disabled", __func__); } /* if we are implementing OUTBOUND XON/XOFF */ if (I_IXON(tty)) { txFlow |= IOSP_TX_FLOW_XON_XOFF; - dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __FUNCTION__, start_char, stop_char); + dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char); } else { - dbg("%s - OUTBOUND XON/XOFF is disabled", __FUNCTION__); + dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); } } @@ -2645,7 +2645,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi baud = 9600; } - dbg("%s - baud rate = %d", __FUNCTION__, baud); + dbg("%s - baud rate = %d", __func__, baud); status = send_cmd_write_baud_rate (edge_port, baud); if (status == -1) { /* Speed change was not possible - put back the old speed */ @@ -2843,7 +2843,7 @@ static int edge_startup (struct usb_serial *serial) /* create our private serial structure */ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); if (edge_serial == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); return -ENOMEM; } spin_lock_init(&edge_serial->es_lock); @@ -2885,19 +2885,19 @@ static int edge_startup (struct usb_serial *serial) serial->num_ports); } - dbg("%s - time 1 %ld", __FUNCTION__, jiffies); + dbg("%s - time 1 %ld", __func__, jiffies); /* If not an EPiC device */ if (!edge_serial->is_epic) { /* now load the application firmware into this device */ load_application_firmware (edge_serial); - dbg("%s - time 2 %ld", __FUNCTION__, jiffies); + dbg("%s - time 2 %ld", __func__, jiffies); /* Check current Edgeport EEPROM and update if necessary */ update_edgeport_E2PROM (edge_serial); - dbg("%s - time 3 %ld", __FUNCTION__, jiffies); + dbg("%s - time 3 %ld", __func__, jiffies); /* set the configuration to use #1 */ // dbg("set_configuration 1"); @@ -2911,7 +2911,7 @@ static int edge_startup (struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); for (j = 0; j < i; ++j) { kfree (usb_get_serial_port_data(serial->port[j])); usb_set_serial_port_data(serial->port[j], NULL); @@ -3017,7 +3017,7 @@ static int edge_startup (struct usb_serial *serial) * continue as long as the edgeport is connected */ response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); if (response) - err("%s - Error %d submitting control urb", __FUNCTION__, response); + err("%s - Error %d submitting control urb", __func__, response); } return response; } @@ -3032,7 +3032,7 @@ static void edge_shutdown (struct usb_serial *serial) struct edgeport_serial *edge_serial = usb_get_serial_data(serial); int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 856e4d9afd6f..0d412ede839a 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -290,7 +290,7 @@ static int TIReadVendorRequestSync (struct usb_device *dev, return status; if (status != size) { dbg ("%s - wanted to write %d, but only wrote %d", - __FUNCTION__, size, status); + __func__, size, status); return -ECOMM; } return 0; @@ -320,7 +320,7 @@ static int TISendVendorRequestSync (struct usb_device *dev, return status; if (status != size) { dbg ("%s - wanted to write %d, but only wrote %d", - __FUNCTION__, size, status); + __func__, size, status); return -ECOMM; } return 0; @@ -344,7 +344,7 @@ static int TIPurgeDataSync (struct usb_serial_port *port, __u16 mask) { int port_number = port->number - port->serial->minor; - dbg ("%s - port %d, mask %x", __FUNCTION__, port_number, mask); + dbg ("%s - port %d, mask %x", __func__, port_number, mask); return TIWriteCommandSync (port->serial->dev, UMPC_PURGE_PORT, @@ -369,7 +369,7 @@ static int TIReadDownloadMemory(struct usb_device *dev, int start_address, __u8 read_length; __be16 be_start_address; - dbg ("%s - @ %x for %d", __FUNCTION__, start_address, length); + dbg ("%s - @ %x for %d", __func__, start_address, length); /* Read in blocks of 64 bytes * (TI firmware can't handle more than 64 byte reads) @@ -381,7 +381,7 @@ static int TIReadDownloadMemory(struct usb_device *dev, int start_address, read_length = (__u8)length; if (read_length > 1) { - dbg ("%s - @ %x for %d", __FUNCTION__, + dbg ("%s - @ %x for %d", __func__, start_address, read_length); } be_start_address = cpu_to_be16 (start_address); @@ -393,12 +393,12 @@ static int TIReadDownloadMemory(struct usb_device *dev, int start_address, read_length); // TransferBufferLength if (status) { - dbg ("%s - ERROR %x", __FUNCTION__, status); + dbg ("%s - ERROR %x", __func__, status); return status; } if (read_length > 1) { - usb_serial_debug_data(debug, &dev->dev, __FUNCTION__, + usb_serial_debug_data(debug, &dev->dev, __func__, read_length, buffer); } @@ -434,13 +434,13 @@ static int TIReadBootMemory (struct edgeport_serial *serial, int start_address, &buffer[i], // TransferBuffer 0x01); // TransferBufferLength if (status) { - dbg ("%s - ERROR %x", __FUNCTION__, status); + dbg ("%s - ERROR %x", __func__, status); return status; } } - dbg ("%s - start_address = %x, length = %d", __FUNCTION__, start_address, length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, length, buffer); + dbg ("%s - start_address = %x, length = %d", __func__, start_address, length); + usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, length, buffer); serial->TiReadI2C = 1; @@ -472,8 +472,8 @@ static int TIWriteBootMemory (struct edgeport_serial *serial, int start_address, return status; } - dbg ("%s - start_sddr = %x, length = %d", __FUNCTION__, start_address, length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, length, buffer); + dbg ("%s - start_sddr = %x, length = %d", __func__, start_address, length); + usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, length, buffer); return status; } @@ -494,8 +494,8 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address if (write_length > length) write_length = length; - dbg ("%s - BytesInFirstPage Addr = %x, length = %d", __FUNCTION__, start_address, write_length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, write_length, buffer); + dbg ("%s - BytesInFirstPage Addr = %x, length = %d", __func__, start_address, write_length); + usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, write_length, buffer); /* Write first page */ be_start_address = cpu_to_be16 (start_address); @@ -506,7 +506,7 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address buffer, // TransferBuffer write_length); if (status) { - dbg ("%s - ERROR %d", __FUNCTION__, status); + dbg ("%s - ERROR %d", __func__, status); return status; } @@ -521,8 +521,8 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address else write_length = length; - dbg ("%s - Page Write Addr = %x, length = %d", __FUNCTION__, start_address, write_length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, __FUNCTION__, write_length, buffer); + dbg ("%s - Page Write Addr = %x, length = %d", __func__, start_address, write_length); + usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, write_length, buffer); /* Write next page */ be_start_address = cpu_to_be16 (start_address); @@ -533,7 +533,7 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address buffer, // TransferBuffer write_length); // TransferBufferLength if (status) { - dev_err (&serial->serial->dev->dev, "%s - ERROR %d\n", __FUNCTION__, status); + dev_err (&serial->serial->dev->dev, "%s - ERROR %d\n", __func__, status); return status; } @@ -559,7 +559,7 @@ static int TIIsTxActive (struct edgeport_port *port) oedb = kmalloc (sizeof (* oedb), GFP_KERNEL); if (!oedb) { - dev_err (&port->port->dev, "%s - out of memory\n", __FUNCTION__); + dev_err (&port->port->dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -579,7 +579,7 @@ static int TIIsTxActive (struct edgeport_port *port) if (status) goto exit_is_tx_active; - dbg ("%s - XByteCount 0x%X", __FUNCTION__, oedb->XByteCount); + dbg ("%s - XByteCount 0x%X", __func__, oedb->XByteCount); /* and the LSR */ status = TIReadRam (port->port->serial->dev, @@ -589,7 +589,7 @@ static int TIIsTxActive (struct edgeport_port *port) if (status) goto exit_is_tx_active; - dbg ("%s - LSR = 0x%X", __FUNCTION__, *lsr); + dbg ("%s - LSR = 0x%X", __func__, *lsr); /* If either buffer has data or we are transmitting then return TRUE */ if ((oedb->XByteCount & 0x80 ) != 0 ) @@ -600,7 +600,7 @@ static int TIIsTxActive (struct edgeport_port *port) /* We return Not Active if we get any kind of error */ exit_is_tx_active: - dbg ("%s - return %d", __FUNCTION__, bytes_left ); + dbg ("%s - return %d", __func__, bytes_left ); kfree(lsr); kfree(oedb); @@ -664,11 +664,11 @@ static int TIChooseConfiguration (struct usb_device *dev) // we want. However, we just support one config at this point, // configuration # 1, which is Config Descriptor 0. - dbg ("%s - Number of Interfaces = %d", __FUNCTION__, dev->config->desc.bNumInterfaces); - dbg ("%s - MAX Power = %d", __FUNCTION__, dev->config->desc.bMaxPower*2); + dbg ("%s - Number of Interfaces = %d", __func__, dev->config->desc.bNumInterfaces); + dbg ("%s - MAX Power = %d", __func__, dev->config->desc.bMaxPower*2); if (dev->config->desc.bNumInterfaces != 1) { - dev_err (&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", __FUNCTION__); + dev_err (&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", __func__); return -ENODEV; } @@ -751,7 +751,7 @@ static int ValidChecksum(struct ti_i2c_desc *rom_desc, __u8 *buffer) cs = (__u8)(cs + buffer[i]); } if (cs != rom_desc->CheckSum) { - dbg ("%s - Mismatch %x - %x", __FUNCTION__, rom_desc->CheckSum, cs); + dbg ("%s - Mismatch %x - %x", __func__, rom_desc->CheckSum, cs); return -EINVAL; } return 0; @@ -769,12 +769,12 @@ static int TiValidateI2cImage (struct edgeport_serial *serial) rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); if (!rom_desc) { - dev_err (dev, "%s - out of memory\n", __FUNCTION__); + dev_err (dev, "%s - out of memory\n", __func__); return -ENOMEM; } buffer = kmalloc (TI_MAX_I2C_SIZE, GFP_KERNEL); if (!buffer) { - dev_err (dev, "%s - out of memory when allocating buffer\n", __FUNCTION__); + dev_err (dev, "%s - out of memory when allocating buffer\n", __func__); kfree (rom_desc); return -ENOMEM; } @@ -785,7 +785,7 @@ static int TiValidateI2cImage (struct edgeport_serial *serial) goto ExitTiValidateI2cImage; if (*buffer != UMP5152 && *buffer != UMP3410) { - dev_err (dev, "%s - invalid buffer signature\n", __FUNCTION__); + dev_err (dev, "%s - invalid buffer signature\n", __func__); status = -ENODEV; goto ExitTiValidateI2cImage; } @@ -801,11 +801,11 @@ static int TiValidateI2cImage (struct edgeport_serial *serial) if ((start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size) > TI_MAX_I2C_SIZE) { status = -ENODEV; - dbg ("%s - structure too big, erroring out.", __FUNCTION__); + dbg ("%s - structure too big, erroring out.", __func__); break; } - dbg ("%s Type = 0x%x", __FUNCTION__, rom_desc->Type); + dbg ("%s Type = 0x%x", __func__, rom_desc->Type); // Skip type 2 record ttype = rom_desc->Type & 0x0f; @@ -845,13 +845,13 @@ static int TIReadManufDescriptor (struct edgeport_serial *serial, __u8 *buffer) rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); if (!rom_desc) { - dev_err (&serial->serial->dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err (&serial->serial->dev->dev, "%s - out of memory\n", __func__); return -ENOMEM; } start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_ION, rom_desc); if (!start_address) { - dbg ("%s - Edge Descriptor not found in I2C", __FUNCTION__); + dbg ("%s - Edge Descriptor not found in I2C", __func__); status = -ENODEV; goto exit; } @@ -867,12 +867,12 @@ static int TIReadManufDescriptor (struct edgeport_serial *serial, __u8 *buffer) status = ValidChecksum(rom_desc, buffer); desc = (struct edge_ti_manuf_descriptor *)buffer; - dbg ( "%s - IonConfig 0x%x", __FUNCTION__, desc->IonConfig ); - dbg ( "%s - Version %d", __FUNCTION__, desc->Version ); - dbg ( "%s - Cpu/Board 0x%x", __FUNCTION__, desc->CpuRev_BoardRev ); - dbg ( "%s - NumPorts %d", __FUNCTION__, desc->NumPorts ); - dbg ( "%s - NumVirtualPorts %d", __FUNCTION__, desc->NumVirtualPorts ); - dbg ( "%s - TotalPorts %d", __FUNCTION__, desc->TotalPorts ); + dbg ( "%s - IonConfig 0x%x", __func__, desc->IonConfig ); + dbg ( "%s - Version %d", __func__, desc->Version ); + dbg ( "%s - Cpu/Board 0x%x", __func__, desc->CpuRev_BoardRev ); + dbg ( "%s - NumPorts %d", __func__, desc->NumPorts ); + dbg ( "%s - NumVirtualPorts %d", __func__, desc->NumVirtualPorts ); + dbg ( "%s - TotalPorts %d", __func__, desc->TotalPorts ); exit: kfree (rom_desc); @@ -902,7 +902,7 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev) buffer = kmalloc (buffer_size, GFP_KERNEL); if (!buffer) { - dev_err (dev, "%s - out of memory\n", __FUNCTION__); + dev_err (dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -955,11 +955,11 @@ static int TIGetI2cTypeInBootMode (struct edgeport_serial *serial) &data, // TransferBuffer 0x01); // TransferBufferLength if (status) - dbg ("%s - read 2 status error = %d", __FUNCTION__, status); + dbg ("%s - read 2 status error = %d", __func__, status); else - dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); + dbg ("%s - read 2 data = 0x%x", __func__, data); if ((!status) && (data == UMP5152 || data == UMP3410)) { - dbg ("%s - ROM_TYPE_II", __FUNCTION__); + dbg ("%s - ROM_TYPE_II", __func__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; return 0; } @@ -972,16 +972,16 @@ static int TIGetI2cTypeInBootMode (struct edgeport_serial *serial) &data, // TransferBuffer 0x01); // TransferBufferLength if (status) - dbg ("%s - read 3 status error = %d", __FUNCTION__, status); + dbg ("%s - read 3 status error = %d", __func__, status); else - dbg ("%s - read 2 data = 0x%x", __FUNCTION__, data); + dbg ("%s - read 2 data = 0x%x", __func__, data); if ((!status) && (data == UMP5152 || data == UMP3410)) { - dbg ("%s - ROM_TYPE_III", __FUNCTION__); + dbg ("%s - ROM_TYPE_III", __func__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; return 0; } - dbg ("%s - Unknown", __FUNCTION__); + dbg ("%s - Unknown", __func__); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; return -ENODEV; } @@ -1063,7 +1063,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) interface = &serial->serial->interface->cur_altsetting->desc; if (!interface) { - dev_err (dev, "%s - no interface set, error!\n", __FUNCTION__); + dev_err (dev, "%s - no interface set, error!\n", __func__); return -ENODEV; } @@ -1099,7 +1099,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) */ ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); if (!ti_manuf_desc) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); return -ENOMEM; } status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc); @@ -1110,7 +1110,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Check version number of ION descriptor if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) { - dbg ( "%s - Wrong CPU Rev %d (Must be 2)", __FUNCTION__, + dbg ( "%s - Wrong CPU Rev %d (Must be 2)", __func__, TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev)); kfree (ti_manuf_desc); return -EINVAL; @@ -1118,7 +1118,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL); if (!rom_desc) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); kfree (ti_manuf_desc); return -ENOMEM; } @@ -1128,11 +1128,11 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) struct ti_i2c_firmware_rec *firmware_version; __u8 record; - dbg ("%s - Found Type FIRMWARE (Type 2) record", __FUNCTION__); + dbg ("%s - Found Type FIRMWARE (Type 2) record", __func__); firmware_version = kmalloc (sizeof (*firmware_version), GFP_KERNEL); if (!firmware_version) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; @@ -1158,7 +1158,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) (OperationalCodeImageVersion.MinorVersion); dbg ("%s - >>>Firmware Versions Device %d.%d Driver %d.%d", - __FUNCTION__, + __func__, firmware_version->Ver_Major, firmware_version->Ver_Minor, OperationalCodeImageVersion.MajorVersion, @@ -1167,7 +1167,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Check if we have an old version in the I2C and update if necessary if (download_cur_ver != download_new_ver) { dbg ("%s - Update I2C Download from %d.%d to %d.%d", - __FUNCTION__, + __func__, firmware_version->Ver_Major, firmware_version->Ver_Minor, OperationalCodeImageVersion.MajorVersion, @@ -1209,14 +1209,14 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) } if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) { - dev_err (dev, "%s - error resetting device\n", __FUNCTION__); + dev_err (dev, "%s - error resetting device\n", __func__); kfree (firmware_version); kfree (rom_desc); kfree (ti_manuf_desc); return -ENODEV; } - dbg ("%s - HARDWARE RESET", __FUNCTION__); + dbg ("%s - HARDWARE RESET", __func__); // Reset UMP -- Back to BOOT MODE status = TISendVendorRequestSync (serial->serial->dev, @@ -1226,7 +1226,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) NULL, // TransferBuffer 0); // TransferBufferLength - dbg ( "%s - HARDWARE RESET return %d", __FUNCTION__, status); + dbg ( "%s - HARDWARE RESET return %d", __func__, status); /* return an error on purpose. */ kfree (firmware_version); @@ -1244,7 +1244,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) header = kmalloc (HEADER_SIZE, GFP_KERNEL); if (!header) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; @@ -1252,14 +1252,14 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) vheader = kmalloc (HEADER_SIZE, GFP_KERNEL); if (!vheader) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); kfree (header); kfree (rom_desc); kfree (ti_manuf_desc); return -ENOMEM; } - dbg ("%s - Found Type BLANK FIRMWARE (Type F2) record", __FUNCTION__); + dbg ("%s - Found Type BLANK FIRMWARE (Type F2) record", __func__); // In order to update the I2C firmware we must change the type 2 record to type 0xF2. // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver @@ -1297,7 +1297,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) vheader); if (status) { - dbg ("%s - can't read header back", __FUNCTION__); + dbg ("%s - can't read header back", __func__); kfree (vheader); kfree (header); kfree (rom_desc); @@ -1305,7 +1305,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) return status; } if (memcmp(vheader, header, HEADER_SIZE)) { - dbg ("%s - write download record failed", __FUNCTION__); + dbg ("%s - write download record failed", __func__); kfree (vheader); kfree (header); kfree (rom_desc); @@ -1316,7 +1316,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) kfree (vheader); kfree (header); - dbg ("%s - Start firmware update", __FUNCTION__); + dbg ("%s - Start firmware update", __func__); // Tell firmware to copy download image into I2C status = TISendVendorRequestSync (serial->serial->dev, @@ -1326,9 +1326,9 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) NULL, // TransferBuffer 0); // TransferBufferLength - dbg ("%s - Update complete 0x%x", __FUNCTION__, status); + dbg ("%s - Update complete 0x%x", __func__, status); if (status) { - dev_err (dev, "%s - UMPC_COPY_DNLD_TO_I2C failed\n", __FUNCTION__); + dev_err (dev, "%s - UMPC_COPY_DNLD_TO_I2C failed\n", __func__); kfree (rom_desc); kfree (ti_manuf_desc); return status; @@ -1352,7 +1352,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) return status; if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) != USB_VENDOR_ID_ION) { - dbg ("%s - VID = 0x%x", __FUNCTION__, + dbg ("%s - VID = 0x%x", __func__, le16_to_cpu(serial->serial->dev->descriptor.idVendor)); serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; goto StayInBootMode; @@ -1366,7 +1366,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Registry variable set? if (TIStayInBootMode) { - dbg ("%s - TIStayInBootMode", __FUNCTION__); + dbg ("%s - TIStayInBootMode", __func__); goto StayInBootMode; } @@ -1383,7 +1383,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) */ ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL); if (!ti_manuf_desc) { - dev_err (dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (dev, "%s - out of memory.\n", __func__); return -ENOMEM; } status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc); @@ -1394,7 +1394,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Check for version 2 if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) { - dbg ("%s - Wrong CPU Rev %d (Must be 2)", __FUNCTION__, + dbg ("%s - Wrong CPU Rev %d (Must be 2)", __func__, TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev)); kfree (ti_manuf_desc); goto StayInBootMode; @@ -1418,7 +1418,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) buffer_size = (((1024 * 16) - 512) + sizeof(struct ti_i2c_image_header)); buffer = kmalloc (buffer_size, GFP_KERNEL); if (!buffer) { - dev_err (dev, "%s - out of memory\n", __FUNCTION__); + dev_err (dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -1438,20 +1438,20 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) header->CheckSum = cs; // Download the operational code - dbg ("%s - Downloading operational code image (TI UMP)", __FUNCTION__); + dbg ("%s - Downloading operational code image (TI UMP)", __func__); status = TIDownloadCodeImage (serial, buffer, buffer_size); kfree (buffer); if (status) { - dbg ("%s - Error downloading operational code image", __FUNCTION__); + dbg ("%s - Error downloading operational code image", __func__); return status; } // Device will reboot serial->product_info.TiMode = TI_MODE_TRANSITIONING; - dbg ("%s - Download successful -- Device rebooting...", __FUNCTION__); + dbg ("%s - Download successful -- Device rebooting...", __func__); /* return an error on purpose */ return -ENODEV; @@ -1470,7 +1470,7 @@ static int TISetDtr (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); port->shadow_mcr |= MCR_DTR; return TIWriteCommandSync (port->port->serial->dev, @@ -1485,7 +1485,7 @@ static int TIClearDtr (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); port->shadow_mcr &= ~MCR_DTR; return TIWriteCommandSync (port->port->serial->dev, @@ -1500,7 +1500,7 @@ static int TISetRts (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); port->shadow_mcr |= MCR_RTS; return TIWriteCommandSync (port->port->serial->dev, @@ -1515,7 +1515,7 @@ static int TIClearRts (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); port->shadow_mcr &= ~MCR_RTS; return TIWriteCommandSync (port->port->serial->dev, @@ -1530,7 +1530,7 @@ static int TISetLoopBack (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); return TIWriteCommandSync (port->port->serial->dev, UMPC_SET_CLR_LOOPBACK, @@ -1544,7 +1544,7 @@ static int TIClearLoopBack (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); return TIWriteCommandSync (port->port->serial->dev, UMPC_SET_CLR_LOOPBACK, @@ -1558,7 +1558,7 @@ static int TISetBreak (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); return TIWriteCommandSync (port->port->serial->dev, UMPC_SET_CLR_BREAK, @@ -1572,7 +1572,7 @@ static int TIClearBreak (struct edgeport_port *port) { int port_number = port->port->number - port->port->serial->minor; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); return TIWriteCommandSync (port->port->serial->dev, UMPC_SET_CLR_BREAK, @@ -1586,7 +1586,7 @@ static int TIRestoreMCR (struct edgeport_port *port, __u8 mcr) { int status = 0; - dbg ("%s - %x", __FUNCTION__, mcr); + dbg ("%s - %x", __func__, mcr); if (mcr & MCR_DTR) status = TISetDtr (port); @@ -1640,7 +1640,7 @@ static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr) struct async_icount *icount; struct tty_struct *tty; - dbg ("%s - %02x", __FUNCTION__, msr); + dbg ("%s - %02x", __func__, msr); if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { icount = &edge_port->icount; @@ -1679,7 +1679,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 struct async_icount *icount; __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK)); - dbg ("%s - %02x", __FUNCTION__, new_lsr); + dbg ("%s - %02x", __func__, new_lsr); edge_port->shadow_lsr = lsr; @@ -1722,7 +1722,7 @@ static void edge_interrupt_callback (struct urb *urb) __u8 msr; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); switch (status) { case 0: @@ -1733,34 +1733,34 @@ static void edge_interrupt_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dev_err(&urb->dev->dev, "%s - nonzero urb status received: " - "%d\n", __FUNCTION__, status); + "%d\n", __func__, status); goto exit; } if (!length) { - dbg ("%s - no data in urb", __FUNCTION__); + dbg ("%s - no data in urb", __func__); goto exit; } - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, length, data); + usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, length, data); if (length != 2) { - dbg ("%s - expecting packet of size 2, got %d", __FUNCTION__, length); + dbg ("%s - expecting packet of size 2, got %d", __func__, length); goto exit; } port_number = TIUMP_GET_PORT_FROM_CODE (data[0]); function = TIUMP_GET_FUNC_FROM_CODE (data[0]); dbg ("%s - port_number %d, function %d, info 0x%x", - __FUNCTION__, port_number, function, data[1]); + __func__, port_number, function, data[1]); port = edge_serial->serial->port[port_number]; edge_port = usb_get_serial_port_data(port); if (!edge_port) { - dbg ("%s - edge_port not found", __FUNCTION__); + dbg ("%s - edge_port not found", __func__); return; } switch (function) { @@ -1769,12 +1769,12 @@ static void edge_interrupt_callback (struct urb *urb) if (lsr & UMP_UART_LSR_DATA_MASK) { /* Save the LSR event for bulk read completion routine */ dbg ("%s - LSR Event Port %u LSR Status = %02x", - __FUNCTION__, port_number, lsr); + __func__, port_number, lsr); edge_port->lsr_event = 1; edge_port->lsr_mask = lsr; } else { dbg ("%s - ===== Port %d LSR Status = %02x ======", - __FUNCTION__, port_number, lsr); + __func__, port_number, lsr); handle_new_lsr (edge_port, 0, lsr, 0); } break; @@ -1783,13 +1783,13 @@ static void edge_interrupt_callback (struct urb *urb) /* Copy MSR from UMP */ msr = data[1]; dbg ("%s - ===== Port %u MSR Status = %02x ======\n", - __FUNCTION__, port_number, msr); + __func__, port_number, msr); handle_new_msr (edge_port, msr); break; default: dev_err (&urb->dev->dev, "%s - Unknown Interrupt code from UMP %x\n", - __FUNCTION__, data[1]); + __func__, data[1]); break; } @@ -1798,7 +1798,7 @@ exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n", - __FUNCTION__, retval); + __func__, retval); } static void edge_bulk_in_callback (struct urb *urb) @@ -1810,7 +1810,7 @@ static void edge_bulk_in_callback (struct urb *urb) int port_number; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); switch (status) { case 0: @@ -1821,18 +1821,18 @@ static void edge_bulk_in_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n", - __FUNCTION__, status); + __func__, status); } if (status == -EPIPE) goto exit; if (status) { - dev_err(&urb->dev->dev,"%s - stopping read!\n", __FUNCTION__); + dev_err(&urb->dev->dev,"%s - stopping read!\n", __func__); return; } @@ -1841,7 +1841,7 @@ static void edge_bulk_in_callback (struct urb *urb) if (edge_port->lsr_event) { edge_port->lsr_event = 0; dbg ("%s ===== Port %u LSR Status = %02x, Data = %02x ======", - __FUNCTION__, port_number, edge_port->lsr_mask, *data); + __func__, port_number, edge_port->lsr_mask, *data); handle_new_lsr (edge_port, 1, edge_port->lsr_mask, *data); /* Adjust buffer length/pointer */ --urb->actual_length; @@ -1850,10 +1850,10 @@ static void edge_bulk_in_callback (struct urb *urb) tty = edge_port->port->tty; if (tty && urb->actual_length) { - usb_serial_debug_data(debug, &edge_port->port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &edge_port->port->dev, __func__, urb->actual_length, data); if (edge_port->close_pending) { - dbg ("%s - close is pending, dropping data on the floor.", __FUNCTION__); + dbg ("%s - close is pending, dropping data on the floor.", __func__); } else { edge_tty_recv(&edge_port->port->dev, tty, data, urb->actual_length); } @@ -1872,7 +1872,7 @@ exit: spin_unlock(&edge_port->ep_lock); if (retval) dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n", - __FUNCTION__, retval); + __func__, retval); } static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length) @@ -1883,7 +1883,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c cnt = tty_buffer_request_room(tty, length); if (cnt < length) { dev_err(dev, "%s - dropping data, %d bytes lost\n", - __FUNCTION__, length - cnt); + __func__, length - cnt); if(cnt == 0) break; } @@ -1901,7 +1901,7 @@ static void edge_bulk_out_callback (struct urb *urb) struct edgeport_port *edge_port = usb_get_serial_port_data(port); int status = urb->status; - dbg ("%s - port %d", __FUNCTION__, port->number); + dbg ("%s - port %d", __func__, port->number); edge_port->ep_write_urb_in_use = 0; @@ -1914,11 +1914,11 @@ static void edge_bulk_out_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dev_err(&urb->dev->dev, "%s - nonzero write bulk status " - "received: %d\n", __FUNCTION__, status); + "received: %d\n", __func__, status); } /* send any buffered data */ @@ -1936,7 +1936,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) u16 open_settings; u8 transaction_timeout; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return -ENODEV; @@ -1959,7 +1959,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) } dbg ("%s - port_number = %d, uart_base = %04x, dma_address = %04x", - __FUNCTION__, port_number, edge_port->uart_base, edge_port->dma_address); + __func__, port_number, edge_port->uart_base, edge_port->dma_address); dev = port->serial->dev; @@ -1970,7 +1970,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) status = TIClearLoopBack (edge_port); if (status) { dev_err(&port->dev,"%s - cannot send clear loopback command, %d\n", - __FUNCTION__, status); + __func__, status); return status; } @@ -1989,7 +1989,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) UMP_PIPE_TRANS_TIMEOUT_ENA | (transaction_timeout << 2)); - dbg ("%s - Sending UMPC_OPEN_PORT", __FUNCTION__); + dbg ("%s - Sending UMPC_OPEN_PORT", __func__); /* Tell TI to open and start the port */ status = TIWriteCommandSync (dev, @@ -1999,7 +1999,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) NULL, 0); if (status) { - dev_err(&port->dev,"%s - cannot send open command, %d\n", __FUNCTION__, status); + dev_err(&port->dev,"%s - cannot send open command, %d\n", __func__, status); return status; } @@ -2011,14 +2011,14 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) NULL, 0); if (status) { - dev_err(&port->dev,"%s - cannot send start DMA command, %d\n", __FUNCTION__, status); + dev_err(&port->dev,"%s - cannot send start DMA command, %d\n", __func__, status); return status; } /* Clear TX and RX buffers in UMP */ status = TIPurgeDataSync (port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN); if (status) { - dev_err(&port->dev,"%s - cannot send clear buffers command, %d\n", __FUNCTION__, status); + dev_err(&port->dev,"%s - cannot send clear buffers command, %d\n", __func__, status); return status; } @@ -2030,7 +2030,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) &edge_port->shadow_msr, // TransferBuffer 1); // TransferBufferLength if (status) { - dev_err(&port->dev,"%s - cannot send read MSR command, %d\n", __FUNCTION__, status); + dev_err(&port->dev,"%s - cannot send read MSR command, %d\n", __func__, status); return status; } @@ -2047,7 +2047,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) /* we are the first port to be opened, let's post the interrupt urb */ urb = edge_serial->serial->port[0]->interrupt_in_urb; if (!urb) { - dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __FUNCTION__); + dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __func__); status = -EINVAL; goto release_es_lock; } @@ -2056,7 +2056,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) urb->dev = dev; status = usb_submit_urb (urb, GFP_KERNEL); if (status) { - dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __FUNCTION__, status); + dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __func__, status); goto release_es_lock; } } @@ -2071,7 +2071,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) /* start up our bulk read urb */ urb = port->read_urb; if (!urb) { - dev_err (&port->dev, "%s - no read urb present, exiting\n", __FUNCTION__); + dev_err (&port->dev, "%s - no read urb present, exiting\n", __func__); status = -EINVAL; goto unlink_int_urb; } @@ -2081,13 +2081,13 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) urb->dev = dev; status = usb_submit_urb (urb, GFP_KERNEL); if (status) { - dev_err (&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __FUNCTION__, status); + dev_err (&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __func__, status); goto unlink_int_urb; } ++edge_serial->num_ports_open; - dbg("%s - exited", __FUNCTION__); + dbg("%s - exited", __func__); goto release_es_lock; @@ -2106,7 +2106,7 @@ static void edge_close (struct usb_serial_port *port, struct file *filp) int port_number; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); edge_serial = usb_get_serial_data(port->serial); edge_port = usb_get_serial_port_data(port); @@ -2126,7 +2126,7 @@ static void edge_close (struct usb_serial_port *port, struct file *filp) /* assuming we can still talk to the device, * send a close port command to it */ - dbg("%s - send umpc_close_port", __FUNCTION__); + dbg("%s - send umpc_close_port", __func__); port_number = port->number - port->serial->minor; status = TIWriteCommandSync (port->serial->dev, UMPC_CLOSE_PORT, @@ -2144,7 +2144,7 @@ static void edge_close (struct usb_serial_port *port, struct file *filp) mutex_unlock(&edge_serial->es_lock); edge_port->close_pending = 0; - dbg("%s - exited", __FUNCTION__); + dbg("%s - exited", __func__); } static int edge_write (struct usb_serial_port *port, const unsigned char *data, int count) @@ -2152,10 +2152,10 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data, struct edgeport_port *edge_port = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return 0; } @@ -2181,7 +2181,7 @@ static void edge_send(struct usb_serial_port *port) unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&edge_port->ep_lock, flags); @@ -2203,7 +2203,7 @@ static void edge_send(struct usb_serial_port *port) spin_unlock_irqrestore(&edge_port->ep_lock, flags); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer); /* set up our urb */ usb_fill_bulk_urb (port->write_urb, port->serial->dev, @@ -2216,7 +2216,7 @@ static void edge_send(struct usb_serial_port *port) /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); edge_port->ep_write_urb_in_use = 0; // TODO: reschedule edge_send } else { @@ -2237,7 +2237,7 @@ static int edge_write_room (struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return -ENODEV; @@ -2248,7 +2248,7 @@ static int edge_write_room (struct usb_serial_port *port) room = edge_buf_space_avail(edge_port->ep_out_buf); spin_unlock_irqrestore(&edge_port->ep_lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -2258,7 +2258,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return -ENODEV; @@ -2269,7 +2269,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) chars = edge_buf_data_avail(edge_port->ep_out_buf); spin_unlock_irqrestore(&edge_port->ep_lock, flags); - dbg ("%s - returns %d", __FUNCTION__, chars); + dbg ("%s - returns %d", __func__, chars); return chars; } @@ -2279,14 +2279,14 @@ static void edge_throttle (struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; tty = port->tty; if (!tty) { - dbg ("%s - no tty available", __FUNCTION__); + dbg ("%s - no tty available", __func__); return; } @@ -2295,7 +2295,7 @@ static void edge_throttle (struct usb_serial_port *port) unsigned char stop_char = STOP_CHAR(tty); status = edge_write (port, &stop_char, 1); if (status <= 0) { - dev_err(&port->dev, "%s - failed to write stop character, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - failed to write stop character, %d\n", __func__, status); } } @@ -2312,14 +2312,14 @@ static void edge_unthrottle (struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; tty = port->tty; if (!tty) { - dbg ("%s - no tty available", __FUNCTION__); + dbg ("%s - no tty available", __func__); return; } @@ -2328,7 +2328,7 @@ static void edge_unthrottle (struct usb_serial_port *port) unsigned char start_char = START_CHAR(tty); status = edge_write (port, &start_char, 1); if (status <= 0) { - dev_err(&port->dev, "%s - failed to write start character, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status); } } @@ -2337,7 +2337,7 @@ static void edge_unthrottle (struct usb_serial_port *port) if (C_CRTSCTS(tty)) { status = restart_read(edge_port); if (status) - dev_err(&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __func__, status); } } @@ -2387,13 +2387,13 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi int status; int port_number = edge_port->port->number - edge_port->port->serial->minor; - dbg("%s - port %d", __FUNCTION__, edge_port->port->number); + dbg("%s - port %d", __func__, edge_port->port->number); tty = edge_port->port->tty; config = kmalloc (sizeof (*config), GFP_KERNEL); if (!config) { - dev_err (&edge_port->port->dev, "%s - out of memory\n", __FUNCTION__); + dev_err (&edge_port->port->dev, "%s - out of memory\n", __func__); return; } @@ -2409,20 +2409,20 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi switch (cflag & CSIZE) { case CS5: config->bDataBits = UMP_UART_CHAR5BITS; - dbg ("%s - data bits = 5", __FUNCTION__); + dbg ("%s - data bits = 5", __func__); break; case CS6: config->bDataBits = UMP_UART_CHAR6BITS; - dbg ("%s - data bits = 6", __FUNCTION__); + dbg ("%s - data bits = 6", __func__); break; case CS7: config->bDataBits = UMP_UART_CHAR7BITS; - dbg ("%s - data bits = 7", __FUNCTION__); + dbg ("%s - data bits = 7", __func__); break; default: case CS8: config->bDataBits = UMP_UART_CHAR8BITS; - dbg ("%s - data bits = 8", __FUNCTION__); + dbg ("%s - data bits = 8", __func__); break; } @@ -2430,32 +2430,32 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi if (cflag & PARODD) { config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; config->bParity = UMP_UART_ODDPARITY; - dbg("%s - parity = odd", __FUNCTION__); + dbg("%s - parity = odd", __func__); } else { config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; config->bParity = UMP_UART_EVENPARITY; - dbg("%s - parity = even", __FUNCTION__); + dbg("%s - parity = even", __func__); } } else { config->bParity = UMP_UART_NOPARITY; - dbg("%s - parity = none", __FUNCTION__); + dbg("%s - parity = none", __func__); } if (cflag & CSTOPB) { config->bStopBits = UMP_UART_STOPBIT2; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { config->bStopBits = UMP_UART_STOPBIT1; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } /* figure out the flow control settings */ if (cflag & CRTSCTS) { config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW; config->wFlags |= UMP_MASK_UART_FLAGS_RTS_FLOW; - dbg("%s - RTS/CTS is enabled", __FUNCTION__); + dbg("%s - RTS/CTS is enabled", __func__); } else { - dbg("%s - RTS/CTS is disabled", __FUNCTION__); + dbg("%s - RTS/CTS is disabled", __func__); tty->hw_stopped = 0; restart_read(edge_port); } @@ -2469,18 +2469,18 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi if (I_IXOFF(tty)) { config->wFlags |= UMP_MASK_UART_FLAGS_IN_X; dbg ("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __FUNCTION__, config->cXon, config->cXoff); + __func__, config->cXon, config->cXoff); } else { - dbg ("%s - INBOUND XON/XOFF is disabled", __FUNCTION__); + dbg ("%s - INBOUND XON/XOFF is disabled", __func__); } /* if we are implementing OUTBOUND XON/XOFF */ if (I_IXON(tty)) { config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X; dbg ("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __FUNCTION__, config->cXon, config->cXoff); + __func__, config->cXon, config->cXoff); } else { - dbg ("%s - OUTBOUND XON/XOFF is disabled", __FUNCTION__); + dbg ("%s - OUTBOUND XON/XOFF is disabled", __func__); } } @@ -2499,7 +2499,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi /* FIXME: Recompute actual baud from divisor here */ - dbg ("%s - baud rate = %d, wBaudRate = %d", __FUNCTION__, baud, config->wBaudRate); + dbg ("%s - baud rate = %d, wBaudRate = %d", __func__, baud, config->wBaudRate); dbg ("wBaudRate: %d", (int)(461550L / config->wBaudRate)); dbg ("wFlags: 0x%x", config->wFlags); @@ -2522,7 +2522,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi sizeof(*config)); if (status) { dbg ("%s - error %d when trying to write config to device", - __FUNCTION__, status); + __func__, status); } kfree (config); @@ -2538,12 +2538,12 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old cflag = tty->termios->c_cflag; - dbg("%s - clfag %08x iflag %08x", __FUNCTION__, + dbg("%s - clfag %08x iflag %08x", __func__, tty->termios->c_cflag, tty->termios->c_iflag); - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + dbg("%s - old clfag %08x old iflag %08x", __func__, old_termios->c_cflag, old_termios->c_iflag); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (edge_port == NULL) return; @@ -2560,7 +2560,7 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig unsigned int mcr; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&edge_port->ep_lock, flags); mcr = edge_port->shadow_mcr; @@ -2594,7 +2594,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int mcr; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&edge_port->ep_lock, flags); @@ -2608,7 +2608,7 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file) | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - dbg("%s -- %x", __FUNCTION__, result); + dbg("%s -- %x", __func__, result); spin_unlock_irqrestore(&edge_port->ep_lock, flags); return result; @@ -2648,30 +2648,30 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned struct async_icount cnow; struct async_icount cprev; - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); switch (cmd) { case TIOCINQ: - dbg("%s - (%d) TIOCINQ", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCINQ", __func__, port->number); // return get_number_bytes_avail(edge_port, (unsigned int *) arg); break; case TIOCSERGETLSR: - dbg("%s - (%d) TIOCSERGETLSR", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCSERGETLSR", __func__, port->number); // return get_lsr_info(edge_port, (unsigned int *) arg); break; case TIOCGSERIAL: - dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCGSERIAL", __func__, port->number); return get_serial_info(edge_port, (struct serial_struct __user *) arg); break; case TIOCSSERIAL: - dbg("%s - (%d) TIOCSSERIAL", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); break; case TIOCMIWAIT: - dbg("%s - (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); cprev = edge_port->icount; while (1) { interruptible_sleep_on(&edge_port->delta_msr_wait); @@ -2694,7 +2694,7 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned break; case TIOCGICOUNT: - dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, + dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, edge_port->icount.rx, edge_port->icount.tx); if (copy_to_user((void __user *)arg, &edge_port->icount, sizeof(edge_port->icount))) return -EFAULT; @@ -2709,7 +2709,7 @@ static void edge_break (struct usb_serial_port *port, int break_state) struct edgeport_port *edge_port = usb_get_serial_port_data(port); int status; - dbg ("%s - state = %d", __FUNCTION__, break_state); + dbg ("%s - state = %d", __func__, break_state); /* chase the port close */ TIChasePort (edge_port, 0, 0); @@ -2721,7 +2721,7 @@ static void edge_break (struct usb_serial_port *port, int break_state) } if (status) { dbg ("%s - error %d sending break set/clear command.", - __FUNCTION__, status); + __func__, status); } } @@ -2738,7 +2738,7 @@ static int edge_startup (struct usb_serial *serial) /* create our private serial structure */ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); if (edge_serial == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); return -ENOMEM; } mutex_init(&edge_serial->es_lock); @@ -2755,13 +2755,13 @@ static int edge_startup (struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); goto cleanup; } spin_lock_init(&edge_port->ep_lock); edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); if (edge_port->ep_out_buf == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); kfree(edge_port); goto cleanup; } @@ -2790,7 +2790,7 @@ static void edge_shutdown (struct usb_serial *serial) int i; struct edgeport_port *edge_port; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); for (i = 0; i < serial->num_ports; ++i) { edge_port = usb_get_serial_port_data(serial->port[i]); @@ -2822,12 +2822,12 @@ static ssize_t store_uart_mode(struct device *dev, struct edgeport_port *edge_port = usb_get_serial_port_data(port); unsigned int v = simple_strtoul(valbuf, NULL, 0); - dbg("%s: setting uart_mode = %d", __FUNCTION__, v); + dbg("%s: setting uart_mode = %d", __func__, v); if (v < 256) edge_port->bUartMode = v; else - dev_err(dev, "%s - uart_mode %d is invalid\n", __FUNCTION__, v); + dev_err(dev, "%s - uart_mode %d is invalid\n", __func__, v); return count; } diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 1711dda0ea6d..c90436ea8060 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -594,13 +594,13 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) int i, result = 0; int retries = connect_retries; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); bytes_in = 0; bytes_out = 0; priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); if (priv == NULL) { - err("%s - Out of memory", __FUNCTION__); + err("%s - Out of memory", __func__); return -ENOMEM; } usb_set_serial_port_data(port, priv); @@ -679,7 +679,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) } if (!retries && result) { - err("%s - failed doing control urb, error %d", __FUNCTION__, + err("%s - failed doing control urb, error %d", __func__, result); goto error; } @@ -692,7 +692,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, result); + err("%s - failed submitting read urb, error %d", __func__, result); goto error; } @@ -700,7 +700,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) enomem: result = -ENOMEM; - err("%s - Out of memory", __FUNCTION__); + err("%s - Out of memory", __func__); error: ipaq_destroy_lists(port); kfree(priv); @@ -712,7 +712,7 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp) { struct ipaq_private *priv = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * shut down bulk read and write @@ -735,15 +735,15 @@ static void ipaq_read_bulk_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { @@ -760,7 +760,7 @@ static void ipaq_read_bulk_callback(struct urb *urb) ipaq_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + err("%s - failed resubmitting read urb, error %d", __func__, result); return; } @@ -771,7 +771,7 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf, int bytes_sent = 0; int transfer_size; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); while (count > 0) { transfer_size = min(count, PACKET_SIZE); @@ -796,7 +796,7 @@ static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *bu unsigned long flags; if (priv->free_len <= 0) { - dbg("%s - we're stuffed", __FUNCTION__); + dbg("%s - we're stuffed", __func__); return -EAGAIN; } @@ -808,12 +808,12 @@ static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *bu } spin_unlock_irqrestore(&write_list_lock, flags); if (pkt == NULL) { - dbg("%s - we're stuffed", __FUNCTION__); + dbg("%s - we're stuffed", __func__); return -EAGAIN; } memcpy(pkt->data, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, pkt->data); + usb_serial_debug_data(debug, &port->dev, __func__, count, pkt->data); pkt->len = count; pkt->written = 0; @@ -826,7 +826,7 @@ static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *bu spin_unlock_irqrestore(&write_list_lock, flags); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); } } else { spin_unlock_irqrestore(&write_list_lock, flags); @@ -875,11 +875,11 @@ static void ipaq_write_bulk_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -889,7 +889,7 @@ static void ipaq_write_bulk_callback(struct urb *urb) spin_unlock_irqrestore(&write_list_lock, flags); result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); } } else { priv->active = 0; @@ -903,7 +903,7 @@ static int ipaq_write_room(struct usb_serial_port *port) { struct ipaq_private *priv = usb_get_serial_port_data(port); - dbg("%s - freelen %d", __FUNCTION__, priv->free_len); + dbg("%s - freelen %d", __func__, priv->free_len); return priv->free_len; } @@ -911,7 +911,7 @@ static int ipaq_chars_in_buffer(struct usb_serial_port *port) { struct ipaq_private *priv = usb_get_serial_port_data(port); - dbg("%s - queuelen %d", __FUNCTION__, priv->queue_len); + dbg("%s - queuelen %d", __func__, priv->queue_len); return priv->queue_len; } @@ -933,7 +933,7 @@ static void ipaq_destroy_lists(struct usb_serial_port *port) static int ipaq_startup(struct usb_serial *serial) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { err("active config #%d != 1 ??", serial->dev->actconfig->desc.bConfigurationValue); @@ -944,7 +944,7 @@ static int ipaq_startup(struct usb_serial *serial) static void ipaq_shutdown(struct usb_serial *serial) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static int __init ipaq_init(void) diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index ec0ccd14e18e..bc85ca5c1c37 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -169,15 +169,15 @@ static void ipw_read_bulk_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { @@ -195,7 +195,7 @@ static void ipw_read_bulk_callback(struct urb *urb) ipw_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); return; } @@ -206,7 +206,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) u8 *buf_flow_init; int result; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL); if (!buf_flow_init) @@ -217,7 +217,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) /* --1: Tell the modem to initialize (we think) From sniffs this is always the * first thing that gets sent to the modem during opening of the device */ - dbg("%s: Sending SIO_INIT (we guess)",__FUNCTION__); + dbg("%s: Sending SIO_INIT (we guess)",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev,0), IPW_SIO_INIT, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -234,7 +234,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) usb_clear_halt(dev, usb_sndbulkpipe(dev, port->bulk_out_endpointAddress)); /*--2: Start reading from the device */ - dbg("%s: setting up bulk read callback",__FUNCTION__); + dbg("%s: setting up bulk read callback",__func__); usb_fill_bulk_urb(port->read_urb, dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), port->bulk_in_buffer, @@ -242,10 +242,10 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) ipw_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result < 0) - dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result); + dbg("%s - usb_submit_urb(read bulk) failed with status %d", __func__, result); /*--3: Tell the modem to open the floodgates on the rx bulk channel */ - dbg("%s:asking modem for RxRead (RXBULK_ON)",__FUNCTION__); + dbg("%s:asking modem for RxRead (RXBULK_ON)",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_RXCTL, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -258,7 +258,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result); /*--4: setup the initial flowcontrol */ - dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init); + dbg("%s:setting init flowcontrol (%s)",__func__,buf_flow_init); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_HANDFLOW, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -272,7 +272,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) /*--5: raise the dtr */ - dbg("%s:raising dtr",__FUNCTION__); + dbg("%s:raising dtr",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -285,7 +285,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) dev_err(&port->dev, "setting dtr failed (error = %d)\n", result); /*--6: raise the rts */ - dbg("%s:raising rts",__FUNCTION__); + dbg("%s:raising rts",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -307,12 +307,12 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) int result; if (tty_hung_up_p(filp)) { - dbg("%s: tty_hung_up_p ...", __FUNCTION__); + dbg("%s: tty_hung_up_p ...", __func__); return; } /*--1: drop the dtr */ - dbg("%s:dropping dtr",__FUNCTION__); + dbg("%s:dropping dtr",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, @@ -325,7 +325,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result); /*--2: drop the rts */ - dbg("%s:dropping rts",__FUNCTION__); + dbg("%s:dropping rts",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, IPW_PIN_CLRRTS, @@ -338,7 +338,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) /*--3: purge */ - dbg("%s:sending purge",__FUNCTION__); + dbg("%s:sending purge",__func__); result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), IPW_SIO_PURGE, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, 0x03, @@ -373,13 +373,13 @@ static void ipw_write_bulk_callback(struct urb *urb) struct usb_serial_port *port = urb->context; int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); port->write_urb_busy = 0; if (status) dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); usb_serial_port_softint(port); } @@ -389,18 +389,18 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int struct usb_device *dev = port->serial->dev; int ret; - dbg("%s: TOP: count=%d, in_interrupt=%ld", __FUNCTION__, + dbg("%s: TOP: count=%d, in_interrupt=%ld", __func__, count, in_interrupt() ); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return 0; } spin_lock_bh(&port->lock); if (port->write_urb_busy) { spin_unlock_bh(&port->lock); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; @@ -409,7 +409,7 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count = min(count, port->bulk_out_size); memcpy(port->bulk_out_buffer, buf, count); - dbg("%s count now:%d", __FUNCTION__, count); + dbg("%s count now:%d", __func__, count); usb_fill_bulk_urb(port->write_urb, dev, usb_sndbulkpipe(dev, port->bulk_out_endpointAddress), @@ -421,11 +421,11 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (ret != 0) { port->write_urb_busy = 0; - dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, ret); + dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __func__, ret); return ret; } - dbg("%s returning %d", __FUNCTION__, count); + dbg("%s returning %d", __func__, count); return count; } diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 82e12f8d600a..496009cff3a8 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -195,16 +195,16 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, ifnum, desc, sizeof(*desc), 1000); - dbg("%s - ret=%d", __FUNCTION__, ret); + dbg("%s - ret=%d", __func__, ret); if (ret < sizeof(*desc)) { dbg("%s - class descriptor read %s (%d)", - __FUNCTION__, + __func__, (ret<0) ? "failed" : "too short", ret); goto error; } if (desc->bDescriptorType != USB_DT_IRDA) { - dbg("%s - bad class descriptor type", __FUNCTION__); + dbg("%s - bad class descriptor type", __func__); goto error; } @@ -248,7 +248,7 @@ static int ir_startup (struct usb_serial *serial) } dbg ("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s", - __FUNCTION__, + __func__, (irda_desc->wBaudRate & 0x0001) ? " 2400" : "", (irda_desc->wBaudRate & 0x0002) ? " 9600" : "", (irda_desc->wBaudRate & 0x0004) ? " 19200" : "", @@ -281,13 +281,13 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) char *buffer; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (buffer_size) { /* override the default buffer sizes */ buffer = kmalloc (buffer_size, GFP_KERNEL); if (!buffer) { - dev_err (&port->dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (&port->dev, "%s - out of memory.\n", __func__); return -ENOMEM; } kfree (port->read_urb->transfer_buffer); @@ -296,7 +296,7 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) buffer = kmalloc (buffer_size, GFP_KERNEL); if (!buffer) { - dev_err (&port->dev, "%s - out of memory.\n", __FUNCTION__); + dev_err (&port->dev, "%s - out of memory.\n", __func__); return -ENOMEM; } kfree (port->write_urb->transfer_buffer); @@ -316,14 +316,14 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); return result; } static void ir_close (struct usb_serial_port *port, struct file * filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* shutdown our bulk read */ usb_kill_urb(port->read_urb); @@ -335,10 +335,10 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int int result; int transfer_size; - dbg("%s - port = %d, count = %d", __FUNCTION__, port->number, count); + dbg("%s - port = %d, count = %d", __func__, port->number, count); if (!port->tty) { - dev_err (&port->dev, "%s - no tty???\n", __FUNCTION__); + dev_err (&port->dev, "%s - no tty???\n", __func__); return 0; } @@ -348,7 +348,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int spin_lock_bh(&port->lock); if (port->write_urb_busy) { spin_unlock_bh(&port->lock); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; @@ -384,7 +384,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int result = usb_submit_urb (port->write_urb, GFP_ATOMIC); if (result) { port->write_urb_busy = 0; - dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); } else result = transfer_size; @@ -396,19 +396,19 @@ static void ir_write_bulk_callback (struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); port->write_urb_busy = 0; if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } usb_serial_debug_data ( debug, &port->dev, - __FUNCTION__, + __func__, urb->actual_length, urb->transfer_buffer); @@ -423,10 +423,10 @@ static void ir_read_bulk_callback (struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port closed.", __FUNCTION__); + dbg("%s - port closed.", __func__); return; } @@ -444,7 +444,7 @@ static void ir_read_bulk_callback (struct urb *urb) usb_serial_debug_data ( debug, &port->dev, - __FUNCTION__, + __func__, urb->actual_length, data); @@ -477,13 +477,13 @@ static void ir_read_bulk_callback (struct urb *urb) result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); break ; default: dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, + __func__, status); break ; @@ -499,7 +499,7 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t speed_t baud; int ir_baud; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); baud = tty_get_baud_rate(port->tty); @@ -551,7 +551,7 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) - dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); /* Only speed changes are supported */ tty_termios_copy_hw(port->tty->termios, old_termios); diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 7fee53441c24..b486a54c6f46 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -98,10 +98,10 @@ static int iuu_alloc_buf(struct iuu_private *priv) priv->writebuf = kzalloc(256, GFP_KERNEL); if (!priv->buf || !priv->dbgbuf || !priv->writebuf) { iuu_free_buf(priv); - dbg("%s problem allocation buffer", __FUNCTION__); + dbg("%s problem allocation buffer", __func__); return -ENOMEM; } - dbg("%s - Privates buffers allocation success", __FUNCTION__); + dbg("%s - Privates buffers allocation success", __func__); return 0; } @@ -109,7 +109,7 @@ static int iuu_startup(struct usb_serial *serial) { struct iuu_private *priv; priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); - dbg("%s- priv allocation success", __FUNCTION__); + dbg("%s- priv allocation success", __func__); if (!priv) return -ENOMEM; if (iuu_alloc_buf(priv)) { @@ -130,17 +130,17 @@ static void iuu_shutdown(struct usb_serial *serial) if (!port) return; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (priv) { iuu_free_buf(priv); - dbg("%s - I will free all", __FUNCTION__); + dbg("%s - I will free all", __func__); usb_set_serial_port_data(port, NULL); - dbg("%s - priv is not anymore in port structure", __FUNCTION__); + dbg("%s - priv is not anymore in port structure", __func__); kfree(priv); - dbg("%s priv is now kfree", __FUNCTION__); + dbg("%s priv is now kfree", __func__); } } @@ -151,7 +151,7 @@ static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, unsigned long flags; /* FIXME: locking on tiomstatus */ - dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__, + dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __func__, port->number, set, clear); spin_lock_irqsave(&priv->lock, flags); @@ -159,7 +159,7 @@ static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, priv->tiostatus = TIOCM_RTS; if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { - dbg("%s TIOCMSET RESET called !!!", __FUNCTION__); + dbg("%s TIOCMSET RESET called !!!", __func__); priv->reset = 1; } spin_unlock_irqrestore(&priv->lock, flags); @@ -188,10 +188,10 @@ static void iuu_rxcmd(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int result; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); /* error stop all */ return; } @@ -211,7 +211,7 @@ static int iuu_reset(struct usb_serial_port *port, u8 wt) struct iuu_private *priv = usb_get_serial_port_data(port); int result; char *buf_ptr = port->write_urb->transfer_buffer; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* Prepare the reset sequence */ @@ -243,16 +243,16 @@ static void iuu_update_status_callback(struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); u8 *st; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); /* error stop all */ return; } st = urb->transfer_buffer; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (urb->actual_length == 1) { switch (st[0]) { case 0x1: @@ -272,9 +272,9 @@ static void iuu_status_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int result; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), @@ -287,7 +287,7 @@ static int iuu_status(struct usb_serial_port *port) { int result; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1); usb_fill_bulk_urb(port->write_urb, port->serial->dev, @@ -306,7 +306,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) struct usb_serial *serial = port->serial; int actual = 0; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* send the data out the bulk port */ @@ -317,9 +317,9 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) count, &actual, HZ * 1); if (status != IUU_OPERATION_OK) { - dbg("%s - error = %2x", __FUNCTION__, status); + dbg("%s - error = %2x", __func__, status); } else { - dbg("%s - write OK !", __FUNCTION__); + dbg("%s - write OK !", __func__); } return status; } @@ -330,7 +330,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) struct usb_serial *serial = port->serial; int actual = 0; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* send the data out the bulk port */ @@ -341,9 +341,9 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) count, &actual, HZ * 1); if (status != IUU_OPERATION_OK) { - dbg("%s - error = %2x", __FUNCTION__, status); + dbg("%s - error = %2x", __func__, status); } else { - dbg("%s - read OK !", __FUNCTION__); + dbg("%s - read OK !", __func__); } return status; @@ -358,7 +358,7 @@ static int iuu_led(struct usb_serial_port *port, unsigned int R, if (!buf) return -ENOMEM; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); buf[0] = IUU_SET_LED; buf[1] = R & 0xFF; @@ -371,9 +371,9 @@ static int iuu_led(struct usb_serial_port *port, unsigned int R, status = bulk_immediate(port, buf, 8); kfree(buf); if (status != IUU_OPERATION_OK) - dbg("%s - led error status = %2x", __FUNCTION__, status); + dbg("%s - led error status = %2x", __func__, status); else - dbg("%s - led OK !", __FUNCTION__); + dbg("%s - led OK !", __func__); return IUU_OPERATION_OK; } @@ -451,7 +451,7 @@ static int iuu_clk(struct usb_serial_port *port, int dwFrq) unsigned int P2 = 0; int frq = (int)dwFrq; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (frq == 0) { priv->buf[Count++] = IUU_UART_WRITE_I2C; @@ -461,7 +461,7 @@ static int iuu_clk(struct usb_serial_port *port, int dwFrq) status = bulk_immediate(port, (u8 *) priv->buf, Count); if (status != 0) { - dbg("%s - write error ", __FUNCTION__); + dbg("%s - write error ", __func__); return status; } } else if (frq == 3579000) { @@ -570,7 +570,7 @@ static int iuu_clk(struct usb_serial_port *port, int dwFrq) status = bulk_immediate(port, (u8 *) priv->buf, Count); if (status != IUU_OPERATION_OK) - dbg("%s - write error ", __FUNCTION__); + dbg("%s - write error ", __func__); return status; } @@ -581,7 +581,7 @@ static int iuu_uart_flush(struct usb_serial_port *port) u8 rxcmd = IUU_UART_RX; struct iuu_private *priv = usb_get_serial_port_data(port); - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) return -EIO; @@ -589,27 +589,27 @@ static int iuu_uart_flush(struct usb_serial_port *port) for (i = 0; i < 2; i++) { status = bulk_immediate(port, &rxcmd, 1); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_write error", __FUNCTION__); + dbg("%s - uart_flush_write error", __func__); return status; } status = read_immediate(port, &priv->len, 1); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __FUNCTION__); + dbg("%s - uart_flush_read error", __func__); return status; } if (priv->len > 0) { - dbg("%s - uart_flush datalen is : %i ", __FUNCTION__, + dbg("%s - uart_flush datalen is : %i ", __func__, priv->len); status = read_immediate(port, priv->buf, priv->len); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __FUNCTION__); + dbg("%s - uart_flush_read error", __func__); return status; } } } - dbg("%s - uart_flush_read OK!", __FUNCTION__); + dbg("%s - uart_flush_read OK!", __func__); iuu_led(port, 0, 0xF000, 0, 0xFF); return status; } @@ -619,20 +619,20 @@ static void read_buf_callback(struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *)urb->context; unsigned char *data = urb->transfer_buffer; struct tty_struct *tty; - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); if (urb->status == -EPROTO) { /* reschedule needed */ } return; } - dbg("%s - %i chars to write", __FUNCTION__, urb->actual_length); + dbg("%s - %i chars to write", __func__, urb->actual_length); tty = port->tty; if (data == NULL) - dbg("%s - data is NULL !!!", __FUNCTION__); + dbg("%s - data is NULL !!!", __func__); if (tty && urb->actual_length && data) { tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); @@ -647,7 +647,7 @@ static int iuu_bulk_write(struct usb_serial_port *port) int result; int i; char *buf_ptr = port->write_urb->transfer_buffer; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); *buf_ptr++ = IUU_UART_ESC; *buf_ptr++ = IUU_UART_TX; @@ -660,7 +660,7 @@ static int iuu_bulk_write(struct usb_serial_port *port) sprintf(priv->dbgbuf + i*2 , "%02X", priv->writebuf[i]); priv->dbgbuf[priv->writelen+i*2] = 0; - dbg("%s - writing %i chars : %s", __FUNCTION__, + dbg("%s - writing %i chars : %s", __func__, priv->writelen, priv->dbgbuf); } usb_fill_bulk_urb(port->write_urb, port->serial->dev, @@ -679,7 +679,7 @@ static int iuu_bulk_write(struct usb_serial_port *port) static int iuu_read_buf(struct usb_serial_port *port, int len) { int result; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, @@ -701,21 +701,21 @@ static void iuu_uart_read_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; priv->poll++; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); /* error stop all */ return; } if (data == NULL) - dbg("%s - data is NULL !!!", __FUNCTION__); + dbg("%s - data is NULL !!!", __func__); if (urb->actual_length == 1 && data != NULL) len = (int) data[0]; if (urb->actual_length > 1) { - dbg("%s - urb->actual_length = %i", __FUNCTION__, + dbg("%s - urb->actual_length = %i", __func__, urb->actual_length); error = 1; return; @@ -724,7 +724,7 @@ static void iuu_uart_read_callback(struct urb *urb) if (len > 0 && error == 0) { dbg("%s - call read buf - len to read is %i ", - __FUNCTION__, len); + __func__, len); status = iuu_read_buf(port, len); return; } @@ -750,7 +750,7 @@ static void iuu_uart_read_callback(struct urb *urb) } spin_unlock_irqrestore(&priv->lock, flags); /* if nothing to write call again rxcmd */ - dbg("%s - rxcmd recall", __FUNCTION__); + dbg("%s - rxcmd recall", __func__); iuu_led_activity_off(urb); return; } @@ -760,7 +760,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, { struct iuu_private *priv = usb_get_serial_port_data(port); unsigned int flags; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (count > 256) return -ENOMEM; @@ -783,12 +783,12 @@ static void read_rxcmd_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int result; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - urb->status = %d", __func__, urb->status); /* error stop all */ return; } @@ -799,7 +799,7 @@ static void read_rxcmd_callback(struct urb *urb) port->read_urb->transfer_buffer, 256, iuu_uart_read_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - dbg("%s - submit result = %d", __FUNCTION__, result); + dbg("%s - submit result = %d", __func__, result); return; } @@ -820,13 +820,13 @@ static int iuu_uart_on(struct usb_serial_port *port) status = bulk_immediate(port, buf, 4); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_on error", __FUNCTION__); + dbg("%s - uart_on error", __func__); goto uart_enable_failed; } /* iuu_reset() the card after iuu_uart_on() */ status = iuu_uart_flush(port); if (status != IUU_OPERATION_OK) - dbg("%s - uart_flush error", __FUNCTION__); + dbg("%s - uart_flush error", __func__); uart_enable_failed: kfree(buf); return status; @@ -844,7 +844,7 @@ static int iuu_uart_off(struct usb_serial_port *port) status = bulk_immediate(port, buf, 1); if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __FUNCTION__); + dbg("%s - uart_off error", __func__); kfree(buf); return status; @@ -938,7 +938,7 @@ static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, status = bulk_immediate(port, dataout, DataCount); if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __FUNCTION__); + dbg("%s - uart_off error", __func__); kfree(dataout); return status; } @@ -960,7 +960,7 @@ static void iuu_close(struct usb_serial_port *port, struct file *filp) if (!serial) return; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); iuu_uart_off(port); if (serial->dev) { @@ -977,7 +977,7 @@ static void iuu_close(struct usb_serial_port *port, struct file *filp) } /* free writebuf */ /* shutdown our urbs */ - dbg("%s - shutting down urbs", __FUNCTION__); + dbg("%s - shutting down urbs", __func__); usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); usb_kill_urb(port->interrupt_in_urb); @@ -998,7 +998,7 @@ static int iuu_open(struct usb_serial_port *port, struct file *filp) unsigned long flags; struct iuu_private *priv = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); @@ -1135,7 +1135,7 @@ static int iuu_open(struct usb_serial_port *port, struct file *filp) iuu_uart_flush(port); - dbg("%s - initialization done", __FUNCTION__); + dbg("%s - initialization done", __func__); memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); usb_fill_bulk_urb(port->write_urb, port->serial->dev, @@ -1147,11 +1147,11 @@ static int iuu_open(struct usb_serial_port *port, struct file *filp) if (result) { dev_err(&port->dev, "%s - failed submitting read urb," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); iuu_close(port, NULL); return -EPROTO; } else { - dbg("%s - rxcmd OK", __FUNCTION__); + dbg("%s - rxcmd OK", __func__); } return result; } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index ea7bba69f4da..857c5312555a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -244,13 +244,13 @@ module_exit(keyspan_exit); static void keyspan_rx_throttle (struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); } static void keyspan_rx_unthrottle (struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); } @@ -258,7 +258,7 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state) { struct keyspan_port_private *p_priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); p_priv = usb_get_serial_port_data(port); @@ -280,7 +280,7 @@ static void keyspan_set_termios (struct usb_serial_port *port, unsigned int cflag; struct tty_struct *tty = port->tty; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; @@ -377,7 +377,7 @@ static int keyspan_write(struct usb_serial_port *port, } dbg("%s - for port %d (%d chars), flip=%d", - __FUNCTION__, port->number, count, p_priv->out_flip); + __func__, port->number, count, p_priv->out_flip); for (left = count; left > 0; left -= todo) { todo = left; @@ -389,11 +389,11 @@ static int keyspan_write(struct usb_serial_port *port, /* Check we have a valid urb/endpoint before we use it... */ if ((this_urb = p_priv->out_urbs[flip]) == NULL) { /* no bulk out, so return 0 bytes written */ - dbg("%s - no output urb :(", __FUNCTION__); + dbg("%s - no output urb :(", __func__); return count; } - dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip); + dbg("%s - endpoint %d flip %d", __func__, usb_pipeendpoint(this_urb->pipe), flip); if (this_urb->status == -EINPROGRESS) { if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ)) @@ -435,13 +435,13 @@ static void usa26_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); endpoint = usb_pipeendpoint(urb->pipe); if (status) { dbg("%s - nonzero status: %x on endpoint %d.", - __FUNCTION__, status, endpoint); + __func__, status, endpoint); return; } @@ -459,7 +459,7 @@ static void usa26_indat_callback(struct urb *urb) } } else { /* some bytes had errors, every byte has status */ - dbg("%s - RX error!!!!", __FUNCTION__); + dbg("%s - RX error!!!!", __func__); for (i = 0; i + 1 < urb->actual_length; i += 2) { int stat = data[i], flag = 0; if (stat & RXERROR_OVERRUN) @@ -479,7 +479,7 @@ static void usa26_indat_callback(struct urb *urb) urb->dev = port->serial->dev; if (port->open_count) if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } return; } @@ -492,7 +492,7 @@ static void usa2x_outdat_callback(struct urb *urb) port = (struct usb_serial_port *) urb->context; p_priv = usb_get_serial_port_data(port); - dbg ("%s - urb %d", __FUNCTION__, urb == p_priv->out_urbs[1]); + dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); if (port->open_count) usb_serial_port_softint(port); @@ -500,7 +500,7 @@ static void usa2x_outdat_callback(struct urb *urb) static void usa26_inack_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } @@ -513,7 +513,7 @@ static void usa26_outcont_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { - dbg ("%s - sending setup", __FUNCTION__); + dbg ("%s - sending setup", __func__); keyspan_usa26_send_setup(port->serial, port, p_priv->resend_cont - 1); } } @@ -531,11 +531,11 @@ static void usa26_instat_callback(struct urb *urb) serial = (struct usb_serial *) urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } if (urb->actual_length != 9) { - dbg("%s - %d byte report??", __FUNCTION__, urb->actual_length); + dbg("%s - %d byte report??", __func__, urb->actual_length); goto exit; } @@ -543,7 +543,7 @@ static void usa26_instat_callback(struct urb *urb) #if 0 dbg("%s - port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d", - __FUNCTION__, msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff, + __func__, msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff, msg->_txXoff, msg->rxEnabled, msg->controlResponse); #endif @@ -552,7 +552,7 @@ static void usa26_instat_callback(struct urb *urb) /* Check port number from message and retrieve private data */ if (msg->port >= serial->num_ports) { - dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port); + dbg ("%s - Unexpected port number %d", __func__, msg->port); goto exit; } port = serial->port[msg->port]; @@ -576,14 +576,14 @@ static void usa26_instat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } exit: ; } static void usa26_glocont_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } @@ -597,7 +597,7 @@ static void usa28_indat_callback(struct urb *urb) struct keyspan_port_private *p_priv; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); port = (struct usb_serial_port *) urb->context; p_priv = usb_get_serial_port_data(port); @@ -609,7 +609,7 @@ static void usa28_indat_callback(struct urb *urb) do { if (status) { dbg("%s - nonzero status: %x on endpoint %d.", - __FUNCTION__, status, usb_pipeendpoint(urb->pipe)); + __func__, status, usb_pipeendpoint(urb->pipe)); return; } @@ -629,7 +629,7 @@ static void usa28_indat_callback(struct urb *urb) urb->dev = port->serial->dev; if (port->open_count) if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } p_priv->in_flip ^= 1; @@ -639,7 +639,7 @@ static void usa28_indat_callback(struct urb *urb) static void usa28_inack_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } static void usa28_outcont_callback(struct urb *urb) @@ -651,7 +651,7 @@ static void usa28_outcont_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { - dbg ("%s - sending setup", __FUNCTION__); + dbg ("%s - sending setup", __func__); keyspan_usa28_send_setup(port->serial, port, p_priv->resend_cont - 1); } } @@ -670,16 +670,16 @@ static void usa28_instat_callback(struct urb *urb) serial = (struct usb_serial *) urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) { - dbg("%s - bad length %d", __FUNCTION__, urb->actual_length); + dbg("%s - bad length %d", __func__, urb->actual_length); goto exit; } - /*dbg("%s %x %x %x %x %x %x %x %x %x %x %x %x", __FUNCTION__ + /*dbg("%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]);*/ @@ -689,7 +689,7 @@ static void usa28_instat_callback(struct urb *urb) /* Check port number from message and retrieve private data */ if (msg->port >= serial->num_ports) { - dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port); + dbg ("%s - Unexpected port number %d", __func__, msg->port); goto exit; } port = serial->port[msg->port]; @@ -713,14 +713,14 @@ static void usa28_instat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } exit: ; } static void usa28_glocont_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } @@ -731,7 +731,7 @@ static void usa49_glocont_callback(struct urb *urb) struct keyspan_port_private *p_priv; int i; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); serial = (struct usb_serial *) urb->context; for (i = 0; i < serial->num_ports; ++i) { @@ -739,7 +739,7 @@ static void usa49_glocont_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { - dbg ("%s - sending setup", __FUNCTION__); + dbg ("%s - sending setup", __func__); keyspan_usa49_send_setup(serial, port, p_priv->resend_cont - 1); break; } @@ -759,21 +759,21 @@ static void usa49_instat_callback(struct urb *urb) int old_dcd_state; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); serial = (struct usb_serial *) urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) { - dbg("%s - bad length %d", __FUNCTION__, urb->actual_length); + dbg("%s - bad length %d", __func__, urb->actual_length); goto exit; } - /*dbg(" %x %x %x %x %x %x %x %x %x %x %x", __FUNCTION__, + /*dbg(" %x %x %x %x %x %x %x %x %x %x %x", __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10]);*/ @@ -782,7 +782,7 @@ static void usa49_instat_callback(struct urb *urb) /* Check port number from message and retrieve private data */ if (msg->portNumber >= serial->num_ports) { - dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->portNumber); + dbg ("%s - Unexpected port number %d", __func__, msg->portNumber); goto exit; } port = serial->port[msg->portNumber]; @@ -807,14 +807,14 @@ static void usa49_instat_callback(struct urb *urb) urb->dev = serial->dev; if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } exit: ; } static void usa49_inack_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } static void usa49_indat_callback(struct urb *urb) @@ -826,12 +826,12 @@ static void usa49_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); endpoint = usb_pipeendpoint(urb->pipe); if (status) { - dbg("%s - nonzero status: %x on endpoint %d.", __FUNCTION__, + dbg("%s - nonzero status: %x on endpoint %d.", __func__, status, endpoint); return; } @@ -866,7 +866,7 @@ static void usa49_indat_callback(struct urb *urb) urb->dev = port->serial->dev; if (port->open_count) if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } } @@ -879,12 +879,12 @@ static void usa49wg_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); serial = urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } @@ -898,7 +898,7 @@ static void usa49wg_indat_callback(struct urb *urb) /* Check port number from message*/ if (data[i] >= serial->num_ports) { dbg ("%s - Unexpected port number %d", - __FUNCTION__, data[i]); + __func__, data[i]); return; } port = serial->port[data[i++]]; @@ -944,13 +944,13 @@ static void usa49wg_indat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } /* not used, usa-49 doesn't have per-port control endpoints */ static void usa49_outcont_callback(struct urb *urb) { - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); } static void usa90_indat_callback(struct urb *urb) @@ -963,13 +963,13 @@ static void usa90_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); endpoint = usb_pipeendpoint(urb->pipe); if (status) { dbg("%s - nonzero status: %x on endpoint %d.", - __FUNCTION__, status, endpoint); + __func__, status, endpoint); return; } @@ -1000,7 +1000,7 @@ static void usa90_indat_callback(struct urb *urb) } else { /* some bytes had errors, every byte has status */ - dbg("%s - RX error!!!!", __FUNCTION__); + dbg("%s - RX error!!!!", __func__); for (i = 0; i + 1 < urb->actual_length; i += 2) { int stat = data[i], flag = 0; if (stat & RXERROR_OVERRUN) @@ -1021,7 +1021,7 @@ static void usa90_indat_callback(struct urb *urb) urb->dev = port->serial->dev; if (port->open_count) if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } return; } @@ -1040,11 +1040,11 @@ static void usa90_instat_callback(struct urb *urb) serial = (struct usb_serial *) urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } if (urb->actual_length < 14) { - dbg("%s - %d byte report??", __FUNCTION__, urb->actual_length); + dbg("%s - %d byte report??", __func__, urb->actual_length); goto exit; } @@ -1073,7 +1073,7 @@ static void usa90_instat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } exit: ; @@ -1088,7 +1088,7 @@ static void usa90_outcont_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { - dbg ("%s - sending setup", __FUNCTION__); + dbg ("%s - sending setup", __func__); keyspan_usa90_send_setup(port->serial, port, p_priv->resend_cont - 1); } } @@ -1105,17 +1105,17 @@ static void usa67_instat_callback(struct urb *urb) int old_dcd_state; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); serial = urb->context; if (status) { - dbg("%s - nonzero status: %x", __FUNCTION__, status); + dbg("%s - nonzero status: %x", __func__, status); return; } if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) { - dbg("%s - bad length %d", __FUNCTION__, urb->actual_length); + dbg("%s - bad length %d", __func__, urb->actual_length); return; } @@ -1125,7 +1125,7 @@ static void usa67_instat_callback(struct urb *urb) /* Check port number from message and retrieve private data */ if (msg->port >= serial->num_ports) { - dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port); + dbg ("%s - Unexpected port number %d", __func__, msg->port); return; } @@ -1149,7 +1149,7 @@ static void usa67_instat_callback(struct urb *urb) urb->dev = serial->dev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err); + dbg("%s - resubmit read urb failed. (%d)", __func__, err); } static void usa67_glocont_callback(struct urb *urb) @@ -1159,7 +1159,7 @@ static void usa67_glocont_callback(struct urb *urb) struct keyspan_port_private *p_priv; int i; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); serial = urb->context; for (i = 0; i < serial->num_ports; ++i) { @@ -1167,7 +1167,7 @@ static void usa67_glocont_callback(struct urb *urb) p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { - dbg ("%s - sending setup", __FUNCTION__); + dbg ("%s - sending setup", __func__); keyspan_usa67_send_setup(serial, port, p_priv->resend_cont - 1); break; @@ -1183,7 +1183,7 @@ static int keyspan_write_room (struct usb_serial_port *port) int data_len; struct urb *this_urb; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; @@ -1228,7 +1228,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; - dbg("%s - port%d.", __FUNCTION__, port->number); + dbg("%s - port%d.", __func__, port->number); /* Set some sane defaults */ p_priv->rts_state = 1; @@ -1253,7 +1253,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) usb_clear_halt(urb->dev, urb->pipe); if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { - dbg("%s - submit urb %d failed (%d)", __FUNCTION__, i, err); + dbg("%s - submit urb %d failed (%d)", __func__, i, err); } } @@ -1305,7 +1305,7 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp) struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -1320,7 +1320,7 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp) } /*while (p_priv->outcont_urb->status == -EINPROGRESS) { - dbg("%s - urb in progress", __FUNCTION__); + dbg("%s - urb in progress", __func__); }*/ p_priv->out_flip = 0; @@ -1484,10 +1484,10 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, if (endpoint == -1) return NULL; /* endpoint not needed */ - dbg ("%s - alloc for endpoint %d.", __FUNCTION__, endpoint); + dbg ("%s - alloc for endpoint %d.", __func__, endpoint); urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ if (urb == NULL) { - dbg ("%s - alloc for endpoint %d failed.", __FUNCTION__, endpoint); + dbg ("%s - alloc for endpoint %d failed.", __func__, endpoint); return NULL; } @@ -1588,7 +1588,7 @@ static void keyspan_setup_urbs(struct usb_serial *serial) struct callbacks *cback; int endp; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); d_details = s_priv->device_details; @@ -1662,7 +1662,7 @@ static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, div, /* divisor */ cnt; /* inverse of divisor (programmed into 8051) */ - dbg ("%s - %d.", __FUNCTION__, baud_rate); + dbg ("%s - %d.", __func__, baud_rate); /* prevent divide by zero... */ if( (b16 = (baud_rate * 16L)) == 0) { @@ -1695,7 +1695,7 @@ static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, *rate_hi = (u8) ((cnt >> 8) & 0xff); } if (rate_low && rate_hi) { - dbg ("%s - %d %02x %02x.", __FUNCTION__, baud_rate, *rate_hi, *rate_low); + dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low); } return (KEYSPAN_BAUD_RATE_OK); @@ -1708,7 +1708,7 @@ static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, u32 b16, /* baud rate times 16 (actual rate used internally) */ div; /* divisor */ - dbg ("%s - %d.", __FUNCTION__, baud_rate); + dbg ("%s - %d.", __func__, baud_rate); /* prevent divide by zero... */ if( (b16 = (baud_rate * 16L)) == 0) @@ -1731,7 +1731,7 @@ static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, *rate_hi = (u8) ((div >> 8) & 0xff); if (rate_low && rate_hi) - dbg ("%s - %d %02x %02x.", __FUNCTION__, baud_rate, *rate_hi, *rate_low); + dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low); return (KEYSPAN_BAUD_RATE_OK); } @@ -1748,7 +1748,7 @@ static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, u8 best_prescaler; int i; - dbg ("%s - %d.", __FUNCTION__, baud_rate); + dbg ("%s - %d.", __func__, baud_rate); /* prevent divide by zero */ if( (b16 = baud_rate * 16L) == 0) { @@ -1796,7 +1796,7 @@ static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, } if (prescaler) { *prescaler = best_prescaler; - /* dbg("%s - %d %d", __FUNCTION__, *prescaler, div); */ + /* dbg("%s - %d %d", __func__, *prescaler, div); */ } return (KEYSPAN_BAUD_RATE_OK); } @@ -1809,7 +1809,7 @@ static int keyspan_usa28_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, div, /* divisor */ cnt; /* inverse of divisor (programmed into 8051) */ - dbg ("%s - %d.", __FUNCTION__, baud_rate); + dbg ("%s - %d.", __func__, baud_rate); /* prevent divide by zero */ if ((b16 = baud_rate * 16L) == 0) @@ -1848,7 +1848,7 @@ static int keyspan_usa28_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, if (rate_hi) { *rate_hi = (u8) ((cnt >> 8) & 0xff); } - dbg ("%s - %d OK.", __FUNCTION__, baud_rate); + dbg ("%s - %d OK.", __func__, baud_rate); return (KEYSPAN_BAUD_RATE_OK); } @@ -1864,7 +1864,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, struct urb *this_urb; int device_port, err; - dbg ("%s reset=%d", __FUNCTION__, reset_port); + dbg ("%s reset=%d", __func__, reset_port); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -1874,11 +1874,11 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, outcont_urb = d_details->outcont_endpoints[port->number]; this_urb = p_priv->outcont_urb; - dbg("%s - endpoint %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe)); + dbg("%s - endpoint %d", __func__, usb_pipeendpoint(this_urb->pipe)); /* Make sure we have an urb then send the message */ if (this_urb == NULL) { - dbg("%s - oops no urb.", __FUNCTION__); + dbg("%s - oops no urb.", __func__); return -1; } @@ -1887,7 +1887,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, if ((reset_port + 1) > p_priv->resend_cont) p_priv->resend_cont = reset_port + 1; if (this_urb->status == -EINPROGRESS) { - /* dbg ("%s - already writing", __FUNCTION__); */ + /* dbg ("%s - already writing", __func__); */ mdelay(5); return(-1); } @@ -1901,7 +1901,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, if (d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, &msg.baudHi, &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) { - dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__, + dbg("%s - Invalid baud rate %d requested, using 9600.", __func__, p_priv->baud); msg.baudLo = 0; msg.baudHi = 125; /* Values for 9600 baud */ @@ -1996,11 +1996,11 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, this_urb->dev = serial->dev; if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { - dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err); + dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); } #if 0 else { - dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__ + dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__ outcont_urb, this_urb->transfer_buffer_length, usb_pipeendpoint(this_urb->pipe)); } @@ -2020,7 +2020,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, struct urb *this_urb; int device_port, err; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -2029,7 +2029,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, /* only do something if we have a bulk out endpoint */ if ((this_urb = p_priv->outcont_urb) == NULL) { - dbg("%s - oops no urb.", __FUNCTION__); + dbg("%s - oops no urb.", __func__); return -1; } @@ -2038,7 +2038,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, if ((reset_port + 1) > p_priv->resend_cont) p_priv->resend_cont = reset_port + 1; if (this_urb->status == -EINPROGRESS) { - dbg ("%s already writing", __FUNCTION__); + dbg ("%s already writing", __func__); mdelay(5); return(-1); } @@ -2048,7 +2048,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, msg.setBaudRate = 1; if (d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk, &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE ) { - dbg("%s - Invalid baud rate requested %d.", __FUNCTION__, p_priv->baud); + dbg("%s - Invalid baud rate requested %d.", __func__, p_priv->baud); msg.baudLo = 0xff; msg.baudHi = 0xb2; /* Values for 9600 baud */ } @@ -2122,11 +2122,11 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, this_urb->dev = serial->dev; if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { - dbg("%s - usb_submit_urb(setup) failed", __FUNCTION__); + dbg("%s - usb_submit_urb(setup) failed", __func__); } #if 0 else { - dbg("%s - usb_submit_urb(setup) OK %d bytes", __FUNCTION__, + dbg("%s - usb_submit_urb(setup) OK %d bytes", __func__, this_urb->transfer_buffer_length); } #endif @@ -2146,7 +2146,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, struct urb *this_urb; int err, device_port; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -2157,11 +2157,11 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, /* Work out which port within the device is being setup */ device_port = port->number - port->serial->minor; - dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port); + dbg("%s - endpoint %d port %d (%d)",__func__, usb_pipeendpoint(this_urb->pipe), port->number, device_port); /* Make sure we have an urb then send the message */ if (this_urb == NULL) { - dbg("%s - oops no urb for port %d.", __FUNCTION__, port->number); + dbg("%s - oops no urb for port %d.", __func__, port->number); return -1; } @@ -2171,7 +2171,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, p_priv->resend_cont = reset_port + 1; if (this_urb->status == -EINPROGRESS) { - /* dbg ("%s - already writing", __FUNCTION__); */ + /* dbg ("%s - already writing", __func__); */ mdelay(5); return(-1); } @@ -2188,7 +2188,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, if (d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, &msg.baudHi, &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) { - dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__, + dbg("%s - Invalid baud rate %d requested, using 9600.", __func__, p_priv->baud); msg.baudLo = 0; msg.baudHi = 125; /* Values for 9600 baud */ @@ -2307,11 +2307,11 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, this_urb->dev = serial->dev; } if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { - dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err); + dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); } #if 0 else { - dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__, + dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__, outcont_urb, this_urb->transfer_buffer_length, usb_pipeendpoint(this_urb->pipe)); } @@ -2332,7 +2332,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, int err; u8 prescaler; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -2340,7 +2340,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, /* only do something if we have a bulk out endpoint */ if ((this_urb = p_priv->outcont_urb) == NULL) { - dbg("%s - oops no urb.", __FUNCTION__); + dbg("%s - oops no urb.", __func__); return -1; } @@ -2349,7 +2349,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, if ((reset_port + 1) > p_priv->resend_cont) p_priv->resend_cont = reset_port + 1; if (this_urb->status == -EINPROGRESS) { - dbg ("%s already writing", __FUNCTION__); + dbg ("%s already writing", __func__); mdelay(5); return(-1); } @@ -2363,7 +2363,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, if (d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, &msg.baudHi, &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE ) { - dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__, + dbg("%s - Invalid baud rate %d requested, using 9600.", __func__, p_priv->baud); p_priv->baud = 9600; d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, @@ -2453,7 +2453,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, this_urb->dev = serial->dev; if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { - dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err); + dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); } return (0); } @@ -2469,7 +2469,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, struct urb *this_urb; int err, device_port; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); @@ -2482,7 +2482,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, /* Make sure we have an urb then send the message */ if (this_urb == NULL) { - dbg("%s - oops no urb for port %d.", __FUNCTION__, + dbg("%s - oops no urb for port %d.", __func__, port->number); return -1; } @@ -2492,7 +2492,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, if ((reset_port + 1) > p_priv->resend_cont) p_priv->resend_cont = reset_port + 1; if (this_urb->status == -EINPROGRESS) { - /* dbg ("%s - already writing", __FUNCTION__); */ + /* dbg ("%s - already writing", __func__); */ mdelay(5); return(-1); } @@ -2508,7 +2508,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, if (d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, &msg.baudHi, &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) { - dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__, + dbg("%s - Invalid baud rate %d requested, using 9600.", __func__, p_priv->baud); msg.baudLo = 0; msg.baudHi = 125; /* Values for 9600 baud */ @@ -2601,7 +2601,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, err = usb_submit_urb(this_urb, GFP_ATOMIC); if (err != 0) - dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, + dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); return (0); } @@ -2612,7 +2612,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) struct keyspan_serial_private *s_priv; const struct keyspan_device_details *d_details; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); s_priv = usb_get_serial_data(serial); d_details = s_priv->device_details; @@ -2647,20 +2647,20 @@ static int keyspan_startup (struct usb_serial *serial) struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct)) break; if (d_details == NULL) { - dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, le16_to_cpu(serial->dev->descriptor.idProduct)); + dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __func__, le16_to_cpu(serial->dev->descriptor.idProduct)); return 1; } /* Setup private data for serial driver */ s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); if (!s_priv) { - dbg("%s - kmalloc for keyspan_serial_private failed.", __FUNCTION__); + dbg("%s - kmalloc for keyspan_serial_private failed.", __func__); return -ENOMEM; } @@ -2672,7 +2672,7 @@ static int keyspan_startup (struct usb_serial *serial) port = serial->port[i]; p_priv = kzalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); if (!p_priv) { - dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __FUNCTION__, i); + dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i); return (1); } p_priv->device_details = d_details; @@ -2685,14 +2685,14 @@ static int keyspan_startup (struct usb_serial *serial) s_priv->instat_urb->dev = serial->dev; err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL); if (err != 0) - dbg("%s - submit instat urb failed %d", __FUNCTION__, + dbg("%s - submit instat urb failed %d", __func__, err); } if (s_priv->indat_urb != NULL) { s_priv->indat_urb->dev = serial->dev; err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL); if (err != 0) - dbg("%s - submit indat urb failed %d", __FUNCTION__, + dbg("%s - submit indat urb failed %d", __func__, err); } @@ -2706,7 +2706,7 @@ static void keyspan_shutdown (struct usb_serial *serial) struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); s_priv = usb_get_serial_data(serial); diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 039847795185..6ce292ef1c47 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -208,7 +208,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) 2000); if (result < 0) dbg("%s - error %d from usb_control_msg", - __FUNCTION__, result); + __func__, result); } @@ -232,11 +232,11 @@ static void keyspan_pda_rx_interrupt (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } @@ -274,7 +274,7 @@ exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __func__, retval); } @@ -358,7 +358,7 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state value, 0, NULL, 0, 2000); if (result < 0) dbg("%s - error %d from usb_control_msg", - __FUNCTION__, result); + __func__, result); /* there is something funky about this.. the TCSBRK that 'cu' performs ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4 seconds apart, but it feels like the break sent isn't as long as it @@ -665,11 +665,11 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp) 1, 2000); if (rc < 0) { - dbg("%s - roomquery failed", __FUNCTION__); + dbg("%s - roomquery failed", __func__); goto error; } if (rc == 0) { - dbg("%s - roomquery returned 0 bytes", __FUNCTION__); + dbg("%s - roomquery returned 0 bytes", __func__); rc = -EIO; goto error; } @@ -688,7 +688,7 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp) port->interrupt_in_urb->dev = serial->dev; rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (rc) { - dbg("%s - usb_submit_urb(read int) failed", __FUNCTION__); + dbg("%s - usb_submit_urb(read int) failed", __func__); goto error; } @@ -732,7 +732,7 @@ static int keyspan_pda_fake_startup (struct usb_serial *serial) record = &xircom_pgs_firmware[0]; #endif if (record == NULL) { - err("%s: unknown vendor, aborting.", __FUNCTION__); + err("%s: unknown vendor, aborting.", __func__); return -ENODEV; } @@ -779,7 +779,7 @@ static int keyspan_pda_startup (struct usb_serial *serial) static void keyspan_pda_shutdown (struct usb_serial *serial) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); kfree(usb_get_serial_port_data(serial->port[0])); } diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index d71004283904..160e19263e25 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -191,7 +191,7 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port, if (rc < 0) err("Change port settings failed (error = %d)", rc); info("%s - %d byte block, baudrate %x, databits %d, u1 %d, u2 %d", - __FUNCTION__, + __func__, settings->pktlen, settings->baudrate, settings->databits, settings->unknown1, settings->unknown2); @@ -222,7 +222,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1,-1}; __u16 status; - info("%s - sending SIO Poll request", __FUNCTION__); + info("%s - sending SIO Poll request", __func__); rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), KL5KUSB105A_SIO_POLL, @@ -237,7 +237,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, else { status = le16_to_cpu(*(u16 *)status_buf); - info("%s - read status %x %x", __FUNCTION__, + info("%s - read status %x %x", __func__, status_buf[0], status_buf[1]); *line_state_p = klsi_105_status2linestate(status); @@ -265,7 +265,7 @@ static int klsi_105_startup (struct usb_serial *serial) priv = kmalloc(sizeof(struct klsi_105_private), GFP_KERNEL); if (!priv) { - dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); + dbg("%skmalloc for klsi_105_private failed.", __func__); i--; goto err_cleanup; } @@ -295,7 +295,7 @@ static int klsi_105_startup (struct usb_serial *serial) urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { - err("%s - out of memory for urb buffers.", __FUNCTION__); + err("%s - out of memory for urb buffers.", __func__); goto err_cleanup; } } @@ -325,7 +325,7 @@ static void klsi_105_shutdown (struct usb_serial *serial) { int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { @@ -370,7 +370,7 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) struct klsi_105_port_settings cfg; unsigned long flags; - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); /* force low_latency on so that our tty_push actually forces * the data through @@ -416,7 +416,7 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) rc = usb_submit_urb(port->read_urb, GFP_KERNEL); if (rc) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, rc); + err("%s - failed submitting read urb, error %d", __func__, rc); retval = rc; goto exit; } @@ -434,14 +434,14 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) err("Enabling read failed (error = %d)", rc); retval = rc; } else - dbg("%s - enabled reading", __FUNCTION__); + dbg("%s - enabled reading", __func__); rc = klsi_105_get_line_state(port, &line_state); if (rc >= 0) { spin_lock_irqsave (&priv->lock, flags); priv->line_state = line_state; spin_unlock_irqrestore (&priv->lock, flags); - dbg("%s - read line state 0x%lx", __FUNCTION__, line_state); + dbg("%s - read line state 0x%lx", __func__, line_state); retval = 0; } else retval = rc; @@ -456,7 +456,7 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp) struct klsi_105_private *priv = usb_get_serial_port_data(port); int rc; - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); mutex_lock(&port->serial->disc_mutex); if (!port->serial->disconnected) { @@ -499,7 +499,7 @@ static int klsi_105_write (struct usb_serial_port *port, int result, size; int bytes_sent=0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); while (count > 0) { /* try to find a free urb (write 0 bytes if none) */ @@ -511,21 +511,21 @@ static int klsi_105_write (struct usb_serial_port *port, for (i=0; iwrite_urb_pool[i]->status != -EINPROGRESS) { urb = priv->write_urb_pool[i]; - dbg("%s - using pool URB %d", __FUNCTION__, i); + dbg("%s - using pool URB %d", __func__, i); break; } } spin_unlock_irqrestore (&priv->lock, flags); if (urb==NULL) { - dbg("%s - no more free urbs", __FUNCTION__); + dbg("%s - no more free urbs", __func__); goto exit; } if (urb->transfer_buffer == NULL) { urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); if (urb->transfer_buffer == NULL) { - err("%s - no more kernel memory...", __FUNCTION__); + err("%s - no more kernel memory...", __func__); goto exit; } } @@ -551,7 +551,7 @@ static int klsi_105_write (struct usb_serial_port *port, /* send the data out the bulk port */ result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); goto exit; } buf += size; @@ -570,10 +570,10 @@ static void klsi_105_write_bulk_callback ( struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, + dbg("%s - nonzero write bulk status received: %d", __func__, status); return; } @@ -600,7 +600,7 @@ static int klsi_105_chars_in_buffer (struct usb_serial_port *port) spin_unlock_irqrestore (&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return (chars); } @@ -620,7 +620,7 @@ static int klsi_105_write_room (struct usb_serial_port *port) spin_unlock_irqrestore (&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return (room); } @@ -635,11 +635,11 @@ static void klsi_105_read_bulk_callback (struct urb *urb) int rc; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* The urb might have been killed. */ if (status) { - dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, + dbg("%s - nonzero read bulk status received: %d", __func__, status); return; } @@ -649,12 +649,12 @@ static void klsi_105_read_bulk_callback (struct urb *urb) */ if (urb->actual_length == 0) { /* empty urbs seem to happen, we ignore them */ - /* dbg("%s - emtpy URB", __FUNCTION__); */ + /* dbg("%s - emtpy URB", __func__); */ ; } else if (urb->actual_length <= 2) { - dbg("%s - size %d URB not understood", __FUNCTION__, + dbg("%s - size %d URB not understood", __func__, urb->actual_length); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); } else { int bytes_sent = ((__u8 *) data)[0] + @@ -666,12 +666,12 @@ static void klsi_105_read_bulk_callback (struct urb *urb) * intermixed tty_flip_buffer_push()s * FIXME */ - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); if (bytes_sent + 2 > urb->actual_length) { dbg("%s - trying to read more data than available" - " (%d vs. %d)", __FUNCTION__, + " (%d vs. %d)", __func__, bytes_sent+2, urb->actual_length); /* cap at implied limit */ bytes_sent = urb->actual_length - 2; @@ -694,7 +694,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb) port); rc = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (rc) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, rc); + err("%s - failed resubmitting read urb, error %d", __func__, rc); } /* klsi_105_read_bulk_callback */ @@ -718,7 +718,7 @@ static void klsi_105_set_termios (struct usb_serial_port *port, if( (cflag & CBAUD) != (old_cflag & CBAUD) ) { /* reassert DTR and (maybe) RTS on transition from B0 */ if( (old_cflag & CBAUD) == B0 ) { - dbg("%s: baud was B0", __FUNCTION__); + dbg("%s: baud was B0", __func__); #if 0 priv->control_state |= TIOCM_DTR; /* don't set RTS if using hardware flow control */ @@ -764,7 +764,7 @@ static void klsi_105_set_termios (struct usb_serial_port *port, break; } if ((cflag & CBAUD) == B0 ) { - dbg("%s: baud is B0", __FUNCTION__); + dbg("%s: baud is B0", __func__); /* Drop RTS and DTR */ /* maybe this should be simulated by sending read * disable and read enable messages? @@ -781,11 +781,11 @@ static void klsi_105_set_termios (struct usb_serial_port *port, /* set the number of data bits */ switch (cflag & CSIZE) { case CS5: - dbg("%s - 5 bits/byte not supported", __FUNCTION__); + dbg("%s - 5 bits/byte not supported", __func__); spin_unlock_irqrestore (&priv->lock, flags); return ; case CS6: - dbg("%s - 6 bits/byte not supported", __FUNCTION__); + dbg("%s - 6 bits/byte not supported", __func__); spin_unlock_irqrestore (&priv->lock, flags); return ; case CS7: @@ -859,7 +859,7 @@ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state ) struct mct_u232_private *priv = (struct mct_u232_private *)port->private; unsigned char lcr = priv->last_lcr; - dbg("%sstate=%d", __FUNCTION__, break_state); + dbg("%sstate=%d", __func__, break_state); if (break_state) lcr |= MCT_U232_SET_BREAK; @@ -874,7 +874,7 @@ static int klsi_105_tiocmget (struct usb_serial_port *port, struct file *file) unsigned long flags; int rc; unsigned long line_state; - dbg("%s - request, just guessing", __FUNCTION__); + dbg("%s - request, just guessing", __func__); rc = klsi_105_get_line_state(port, &line_state); if (rc < 0) { @@ -886,7 +886,7 @@ static int klsi_105_tiocmget (struct usb_serial_port *port, struct file *file) spin_lock_irqsave (&priv->lock, flags); priv->line_state = line_state; spin_unlock_irqrestore (&priv->lock, flags); - dbg("%s - read line state 0x%lx", __FUNCTION__, line_state); + dbg("%s - read line state 0x%lx", __func__, line_state); return (int)line_state; } @@ -895,7 +895,7 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file, { int retval = -EINVAL; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* if this ever gets implemented, it should be done something like this: struct usb_serial *serial = port->serial; @@ -921,7 +921,7 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file, static void klsi_105_throttle (struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->read_urb); } @@ -929,12 +929,12 @@ static void klsi_105_unthrottle (struct usb_serial_port *port) { int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - err("%s - failed submitting read urb, error %d", __FUNCTION__, + err("%s - failed submitting read urb, error %d", __func__, result); } diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 78458c807eac..693f00da7c03 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -183,11 +183,11 @@ static int kobil_startup (struct usb_serial *serial) for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { endpoint = &altsetting->endpoint[i]; if (usb_endpoint_is_int_out(&endpoint->desc)) { - dbg("%s Found interrupt out endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress); + dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; } if (usb_endpoint_is_int_in(&endpoint->desc)) { - dbg("%s Found interrupt in endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress); + dbg("%s Found interrupt in endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; } } @@ -198,7 +198,7 @@ static int kobil_startup (struct usb_serial *serial) static void kobil_shutdown (struct usb_serial *serial) { int i; - dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); + dbg("%s - port %d", __func__, serial->port[0]->number); for (i=0; i < serial->num_ports; ++i) { while (serial->port[i]->open_count > 0) { @@ -218,7 +218,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) int transfer_buffer_length = 8; int write_urb_transfer_buffer_length = 8; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); priv = usb_get_serial_port_data(port); // someone sets the dev to 0 if the close method has been called @@ -245,10 +245,10 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) // allocate write_urb if (!port->write_urb) { - dbg("%s - port %d Allocating port->write_urb", __FUNCTION__, port->number); + dbg("%s - port %d Allocating port->write_urb", __func__, port->number); port->write_urb = usb_alloc_urb(0, GFP_KERNEL); if (!port->write_urb) { - dbg("%s - port %d usb_alloc_urb failed", __FUNCTION__, port->number); + dbg("%s - port %d usb_alloc_urb failed", __func__, port->number); kfree(transfer_buffer); return -ENOMEM; } @@ -274,7 +274,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) transfer_buffer_length, KOBIL_TIMEOUT ); - dbg("%s - port %d Send get_HW_version URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result); dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); // get firmware version @@ -288,7 +288,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) transfer_buffer_length, KOBIL_TIMEOUT ); - dbg("%s - port %d Send get_FW_version URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result); dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] ); if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { @@ -303,7 +303,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) 0, KOBIL_TIMEOUT ); - dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result); // reset all queues result = usb_control_msg( port->serial->dev, @@ -316,13 +316,13 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) 0, KOBIL_TIMEOUT ); - dbg("%s - port %d Send reset_all_queues URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result); } if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { // start reading (Adapter B 'cause PNP string) result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); - dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } kfree(transfer_buffer); @@ -332,7 +332,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) static void kobil_close (struct usb_serial_port *port, struct file *filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->write_urb) { usb_kill_urb(port->write_urb); @@ -352,11 +352,11 @@ static void kobil_read_int_callback(struct urb *urb) int status = urb->status; // char *dbg_data; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - port %d Read int status not zero: %d", - __FUNCTION__, port->number, status); + __func__, port->number, status); return; } @@ -386,7 +386,7 @@ static void kobil_read_int_callback(struct urb *urb) port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } @@ -404,21 +404,21 @@ static int kobil_write (struct usb_serial_port *port, struct kobil_private * priv; if (count == 0) { - dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number); + dbg("%s - port %d write request of 0 bytes", __func__, port->number); return 0; } priv = usb_get_serial_port_data(port); if (count > (KOBIL_BUF_LENGTH - priv->filled)) { - dbg("%s - port %d Error: write request bigger than buffer size", __FUNCTION__, port->number); + dbg("%s - port %d Error: write request bigger than buffer size", __func__, port->number); return -ENOMEM; } // Copy data to buffer memcpy (priv->buf + priv->filled, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, priv->buf + priv->filled); + usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); priv->filled = priv->filled + count; @@ -450,7 +450,7 @@ static int kobil_write (struct usb_serial_port *port, priv->cur_pos = priv->cur_pos + length; result = usb_submit_urb( port->write_urb, GFP_NOIO ); - dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result); todo = priv->filled - priv->cur_pos; if (todo > 0) { @@ -471,7 +471,7 @@ static int kobil_write (struct usb_serial_port *port, port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO ); - dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result); } } return count; @@ -480,7 +480,7 @@ static int kobil_write (struct usb_serial_port *port, static int kobil_write_room (struct usb_serial_port *port) { - //dbg("%s - port %d", __FUNCTION__, port->number); + //dbg("%s - port %d", __func__, port->number); return 8; } @@ -515,7 +515,7 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) KOBIL_TIMEOUT); dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", - __FUNCTION__, port->number, result, transfer_buffer[0]); + __func__, port->number, result, transfer_buffer[0]); result = 0; if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) @@ -558,9 +558,9 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { if (dtr != 0) - dbg("%s - port %d Setting DTR", __FUNCTION__, port->number); + dbg("%s - port %d Setting DTR", __func__, port->number); else - dbg("%s - port %d Clearing DTR", __FUNCTION__, port->number); + dbg("%s - port %d Clearing DTR", __func__, port->number); result = usb_control_msg( port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0 ), SUSBCRequest_SetStatusLinesOrQueues, @@ -572,9 +572,9 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, KOBIL_TIMEOUT); } else { if (rts != 0) - dbg("%s - port %d Setting RTS", __FUNCTION__, port->number); + dbg("%s - port %d Setting RTS", __func__, port->number); else - dbg("%s - port %d Clearing RTS", __FUNCTION__, port->number); + dbg("%s - port %d Clearing RTS", __func__, port->number); result = usb_control_msg( port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0 ), SUSBCRequest_SetStatusLinesOrQueues, @@ -585,7 +585,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, 0, KOBIL_TIMEOUT); } - dbg("%s - port %d Send set_status_line URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result); kfree(transfer_buffer); return (result < 0) ? result : 0; } @@ -678,7 +678,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigne KOBIL_TIMEOUT ); - dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); + dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result); kfree(transfer_buffer); return (result < 0) ? -EFAULT : 0; default: diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index b9e0fbacc8a4..e25c0c2791eb 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -399,7 +399,7 @@ static void mct_u232_shutdown (struct usb_serial *serial) struct mct_u232_private *priv; int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i=0; i < serial->num_ports; ++i) { /* My special items, the standard routines free my urbs */ @@ -421,7 +421,7 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp) unsigned char last_lcr; unsigned char last_msr; - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); /* Compensate for a hardware bug: although the Sitecom U232-P25 * device reports a maximum output packet size of 32 bytes, @@ -486,7 +486,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp) unsigned int c_cflag; unsigned int control_state; struct mct_u232_private *priv = usb_get_serial_port_data(port); - dbg("%s port %d", __FUNCTION__, port->number); + dbg("%s port %d", __func__, port->number); if (port->tty) { c_cflag = port->tty->termios->c_cflag; @@ -532,21 +532,21 @@ static void mct_u232_read_int_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } if (!serial) { - dbg("%s - bad serial pointer, exiting", __FUNCTION__); + dbg("%s - bad serial pointer, exiting", __func__); return; } - dbg("%s - port %d", __FUNCTION__, port->number); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + dbg("%s - port %d", __func__, port->number); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* * Work-a-round: handle the 'usual' bulk-in pipe here @@ -603,7 +603,7 @@ exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __func__, retval); } /* mct_u232_read_int_callback */ static void mct_u232_set_termios (struct usb_serial_port *port, @@ -633,7 +633,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port, /* reassert DTR and RTS on transition from B0 */ if ((old_cflag & CBAUD) == B0) { - dbg("%s: baud was B0", __FUNCTION__); + dbg("%s: baud was B0", __func__); control_state |= TIOCM_DTR | TIOCM_RTS; mct_u232_set_modem_ctrl(serial, control_state); } @@ -641,7 +641,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port, mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty)); if ((cflag & CBAUD) == B0 ) { - dbg("%s: baud is B0", __FUNCTION__); + dbg("%s: baud is B0", __func__); /* Drop RTS and DTR */ control_state &= ~(TIOCM_DTR | TIOCM_RTS); mct_u232_set_modem_ctrl(serial, control_state); @@ -696,7 +696,7 @@ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state ) unsigned char lcr; unsigned long flags; - dbg("%sstate=%d", __FUNCTION__, break_state); + dbg("%sstate=%d", __func__, break_state); spin_lock_irqsave(&priv->lock, flags); lcr = priv->last_lcr; @@ -715,7 +715,7 @@ static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file) unsigned int control_state; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&priv->lock, flags); control_state = priv->control_state; @@ -732,7 +732,7 @@ static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int control_state; unsigned long flags; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); spin_lock_irqsave(&priv->lock, flags); control_state = priv->control_state; @@ -754,7 +754,7 @@ static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file, static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) { - dbg("%scmd=0x%x", __FUNCTION__, cmd); + dbg("%scmd=0x%x", __func__, cmd); /* Based on code from acm.c and others */ switch (cmd) { @@ -769,7 +769,7 @@ static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file, return 0; default: - dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd); + dbg("%s: arg not supported - 0x%04x", __func__,cmd); return(-ENOIOCTLCMD); break; } @@ -784,7 +784,7 @@ static void mct_u232_throttle (struct usb_serial_port *port) struct tty_struct *tty; tty = port->tty; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); priv->rx_flags |= THROTTLED; @@ -806,7 +806,7 @@ static void mct_u232_unthrottle (struct usb_serial_port *port) unsigned int control_state; struct tty_struct *tty; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); tty = port->tty; spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 2e14fdd08464..74b889bf19cf 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -118,11 +118,11 @@ static void mos7720_interrupt_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } @@ -183,7 +183,7 @@ exit: if (result) dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", - __FUNCTION__, result); + __func__, result); return; } @@ -214,7 +214,7 @@ static void mos7720_bulk_in_callback(struct urb *urb) port = mos7720_port->port; - dbg("Entering...%s", __FUNCTION__); + dbg("Entering...%s", __func__); data = urb->transfer_buffer; @@ -362,7 +362,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { - err("%s-out of memory for urb buffers.", __FUNCTION__); + err("%s-out of memory for urb buffers.", __func__); usb_free_urb(mos7720_port->write_urb_pool[j]); mos7720_port->write_urb_pool[j] = NULL; continue; @@ -479,7 +479,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) if (response) dev_err(&port->dev, "%s - Error %d submitting control urb\n", - __FUNCTION__, response); + __func__, response); } /* set up our bulk in urb */ @@ -492,7 +492,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) response = usb_submit_urb(port->read_urb, GFP_KERNEL); if (response) dev_err(&port->dev, - "%s - Error %d submitting read urb\n", __FUNCTION__, response); + "%s - Error %d submitting read urb\n", __func__, response); /* initialize our icount structure */ memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); @@ -521,11 +521,11 @@ static int mos7720_chars_in_buffer(struct usb_serial_port *port) int chars = 0; struct moschip_port *mos7720_port; - dbg("%s:entering ...........", __FUNCTION__); + dbg("%s:entering ...........", __func__); mos7720_port = usb_get_serial_port_data(port); if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __FUNCTION__); + dbg("%s:leaving ...........", __func__); return -ENODEV; } @@ -533,7 +533,7 @@ static int mos7720_chars_in_buffer(struct usb_serial_port *port) if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) chars += URB_TRANSFER_BUFFER_SIZE; } - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return chars; } @@ -585,7 +585,7 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp) mutex_unlock(&serial->disc_mutex); mos7720_port->open = 0; - dbg("Leaving %s", __FUNCTION__); + dbg("Leaving %s", __func__); } static void mos7720_break(struct usb_serial_port *port, int break_state) @@ -594,7 +594,7 @@ static void mos7720_break(struct usb_serial_port *port, int break_state) struct usb_serial *serial; struct moschip_port *mos7720_port; - dbg("Entering %s", __FUNCTION__); + dbg("Entering %s", __func__); serial = port->serial; @@ -627,11 +627,11 @@ static int mos7720_write_room(struct usb_serial_port *port) int room = 0; int i; - dbg("%s:entering ...........", __FUNCTION__); + dbg("%s:entering ...........", __func__); mos7720_port = usb_get_serial_port_data(port); if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __FUNCTION__); + dbg("%s:leaving ...........", __func__); return -ENODEV; } @@ -640,7 +640,7 @@ static int mos7720_write_room(struct usb_serial_port *port) room += URB_TRANSFER_BUFFER_SIZE; } - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -657,7 +657,7 @@ static int mos7720_write(struct usb_serial_port *port, struct urb *urb; const unsigned char *current_position = data; - dbg("%s:entering ...........", __FUNCTION__); + dbg("%s:entering ...........", __func__); serial = port->serial; @@ -679,7 +679,7 @@ static int mos7720_write(struct usb_serial_port *port, } if (urb == NULL) { - dbg("%s - no more free urbs", __FUNCTION__); + dbg("%s - no more free urbs", __func__); goto exit; } @@ -687,14 +687,14 @@ static int mos7720_write(struct usb_serial_port *port, urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - err("%s no more kernel memory...", __FUNCTION__); + err("%s no more kernel memory...", __func__); goto exit; } } transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE); memcpy(urb->transfer_buffer, current_position, transfer_size); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, + usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer); /* fill urb with data and submit */ @@ -708,7 +708,7 @@ static int mos7720_write(struct usb_serial_port *port, status = usb_submit_urb(urb,GFP_ATOMIC); if (status) { err("%s - usb_submit_urb(write bulk) failed with status = %d", - __FUNCTION__, status); + __func__, status); bytes_sent = status; goto exit; } @@ -724,7 +724,7 @@ static void mos7720_throttle(struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s- port %d\n", __FUNCTION__, port->number); + dbg("%s- port %d\n", __func__, port->number); mos7720_port = usb_get_serial_port_data(port); @@ -736,11 +736,11 @@ static void mos7720_throttle(struct usb_serial_port *port) return; } - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); tty = port->tty; if (!tty) { - dbg("%s - no tty available", __FUNCTION__); + dbg("%s - no tty available", __func__); return; } @@ -773,15 +773,15 @@ static void mos7720_unthrottle(struct usb_serial_port *port) return; if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); tty = port->tty; if (!tty) { - dbg("%s - no tty available", __FUNCTION__); + dbg("%s - no tty available", __func__); return; } @@ -922,7 +922,7 @@ static int calc_baud_rate_divisor(int baudrate, int *divisor) __u16 round; - dbg("%s - %d", __FUNCTION__, baudrate); + dbg("%s - %d", __func__, baudrate); for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { if (divisor_table[i].baudrate == baudrate) { @@ -973,15 +973,15 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, port = mos7720_port->port; serial = port->serial; - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); number = port->number - port->serial->minor; - dbg("%s - port = %d, baud = %d", __FUNCTION__, port->number, baudrate); + dbg("%s - port = %d, baud = %d", __func__, port->number, baudrate); /* Calculate the Divisor */ status = calc_baud_rate_divisor(baudrate, &divisor); if (status) { - err("%s - bad baud rate", __FUNCTION__); + err("%s - bad baud rate", __func__); return status; } @@ -1034,16 +1034,16 @@ static void change_port_settings(struct moschip_port *mos7720_port, serial = port->serial; port_number = port->number - port->serial->minor; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } tty = mos7720_port->port->tty; - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); lData = UART_LCR_WLEN8; lStop = 0x00; /* 1 stop bit */ @@ -1078,14 +1078,14 @@ static void change_port_settings(struct moschip_port *mos7720_port, if (cflag & PARENB) { if (cflag & PARODD) { lParity = UART_LCR_PARITY; - dbg("%s - parity = odd", __FUNCTION__); + dbg("%s - parity = odd", __func__); } else { lParity = (UART_LCR_EPAR | UART_LCR_PARITY); - dbg("%s - parity = even", __FUNCTION__); + dbg("%s - parity = even", __func__); } } else { - dbg("%s - parity = none", __FUNCTION__); + dbg("%s - parity = none", __func__); } if (cflag & CMSPAR) @@ -1094,10 +1094,10 @@ static void change_port_settings(struct moschip_port *mos7720_port, /* Change the Stop bit */ if (cflag & CSTOPB) { lStop = UART_LCR_STOP; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { lStop = 0x00; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } #define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ @@ -1171,7 +1171,7 @@ static void change_port_settings(struct moschip_port *mos7720_port, return; } - dbg("%s - baud rate = %d", __FUNCTION__, baud); + dbg("%s - baud rate = %d", __func__, baud); status = send_cmd_write_baud_rate(mos7720_port, baud); /* FIXME: needs to write actual resulting baud back not just blindly do so */ @@ -1217,7 +1217,7 @@ static void mos7720_set_termios(struct usb_serial_port *port, if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } @@ -1225,15 +1225,15 @@ static void mos7720_set_termios(struct usb_serial_port *port, cflag = tty->termios->c_cflag; - dbg("%s - cflag %08x iflag %08x", __FUNCTION__, + dbg("%s - cflag %08x iflag %08x", __func__, tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); - dbg("%s - old cflag %08x old iflag %08x", __FUNCTION__, + dbg("%s - old cflag %08x old iflag %08x", __func__, old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* change the port settings to the new ones specified */ change_port_settings(mos7720_port, old_termios); @@ -1271,7 +1271,7 @@ static int get_lsr_info(struct moschip_port *mos7720_port, count = mos7720_chars_in_buffer(mos7720_port->port); if (count == 0) { - dbg("%s -- Empty", __FUNCTION__); + dbg("%s -- Empty", __func__); result = TIOCSER_TEMT; } @@ -1296,7 +1296,7 @@ static int get_number_bytes_avail(struct moschip_port *mos7720_port, result = tty->read_cnt; - dbg("%s(%d) = %d", __FUNCTION__, mos7720_port->port->number, result); + dbg("%s(%d) = %d", __func__, mos7720_port->port->number, result); if (copy_to_user(value, &result, sizeof(int))) return -EFAULT; @@ -1374,7 +1374,7 @@ static int get_modem_info(struct moschip_port *mos7720_port, | ((msr & UART_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - dbg("%s -- %x", __FUNCTION__, result); + dbg("%s -- %x", __func__, result); if (copy_to_user(value, &result, sizeof(int))) return -EFAULT; @@ -1418,45 +1418,45 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, if (mos7720_port == NULL) return -ENODEV; - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); switch (cmd) { case TIOCINQ: /* return number of bytes available */ - dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); + dbg("%s (%d) TIOCINQ", __func__, port->number); return get_number_bytes_avail(mos7720_port, (unsigned int __user *)arg); break; case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); return get_lsr_info(mos7720_port, (unsigned int __user *)arg); return 0; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: - dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, + dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__, port->number); return set_modem_info(mos7720_port, cmd, (unsigned int __user *)arg); case TIOCMGET: - dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMGET", __func__, port->number); return get_modem_info(mos7720_port, (unsigned int __user *)arg); case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCGSERIAL", __func__, port->number); return get_serial_info(mos7720_port, (struct serial_struct __user *)arg); case TIOCSSERIAL: - dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSSERIAL", __func__, port->number); break; case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); cprev = mos7720_port->icount; while (1) { if (signal_pending(current)) @@ -1490,7 +1490,7 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, + dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, icount.rx, icount.tx ); if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) return -EFAULT; @@ -1508,7 +1508,7 @@ static int mos7720_startup(struct usb_serial *serial) int i; char data; - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); if (!serial) { dbg("Invalid Handler"); @@ -1520,7 +1520,7 @@ static int mos7720_startup(struct usb_serial *serial) /* create our private serial structure */ mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); if (mos7720_serial == NULL) { - err("%s - Out of memory", __FUNCTION__); + err("%s - Out of memory", __func__); return -ENOMEM; } @@ -1533,7 +1533,7 @@ static int mos7720_startup(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7720_port == NULL) { - err("%s - Out of memory", __FUNCTION__); + err("%s - Out of memory", __func__); usb_set_serial_data(serial, NULL); kfree(mos7720_serial); return -ENOMEM; @@ -1617,7 +1617,7 @@ static int __init moschip7720_init(void) { int retval; - dbg("%s: Entering ..........", __FUNCTION__); + dbg("%s: Entering ..........", __func__); /* Register with the usb serial */ retval = usb_serial_register(&moschip7720_2port_driver); diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 37c4f0736bc1..7823222570b6 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -403,7 +403,7 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) { struct async_icount *icount; - dbg("%s - %02x", __FUNCTION__, new_lsr); + dbg("%s - %02x", __func__, new_lsr); if (new_lsr & SERIAL_LSR_BI) { // @@ -459,21 +459,21 @@ static void mos7840_control_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } - dbg("%s urb buffer size is %d\n", __FUNCTION__, urb->actual_length); - dbg("%s mos7840_port->MsrLsr is %d port %d\n", __FUNCTION__, + dbg("%s urb buffer size is %d\n", __func__, urb->actual_length); + dbg("%s mos7840_port->MsrLsr is %d port %d\n", __func__, mos7840_port->MsrLsr, mos7840_port->port_num); data = urb->transfer_buffer; regval = (__u8) data[0]; - dbg("%s data is %x\n", __FUNCTION__, regval); + dbg("%s data is %x\n", __func__, regval); if (mos7840_port->MsrLsr == 0) mos7840_handle_new_msr(mos7840_port, regval); else if (mos7840_port->MsrLsr == 1) @@ -487,7 +487,7 @@ exit: if (result) { dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); + __func__, result); } } @@ -542,11 +542,11 @@ static void mos7840_interrupt_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } @@ -614,7 +614,7 @@ exit: if (result) { dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); + __func__, result); } } @@ -692,12 +692,12 @@ static void mos7840_bulk_in_callback(struct urb *urb) } port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return; } - serial = mos7840_get_usb_serial(port, __FUNCTION__); + serial = mos7840_get_usb_serial(port, __func__); if (!serial) { dbg("%s\n", "Bad serial pointer "); return; @@ -767,7 +767,7 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) return; } - if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(mos7840_port->port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return; } @@ -815,14 +815,14 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) struct moschip_port *mos7840_port; struct moschip_port *port0; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return -ENODEV; } serial = port->serial; - if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) { + if (mos7840_serial_paranoia_check(serial, __func__)) { dbg("%s", "Serial Paranoia failed \n"); return -ENODEV; } @@ -851,7 +851,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) if (!urb->transfer_buffer) { usb_free_urb(urb); mos7840_port->write_urb_pool[j] = NULL; - err("%s-out of memory for urb buffers.", __FUNCTION__); + err("%s-out of memory for urb buffers.", __func__); continue; } } @@ -1039,7 +1039,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) GFP_KERNEL); if (response) { err("%s - Error %d submitting interrupt urb", - __FUNCTION__, response); + __func__, response); } } @@ -1072,7 +1072,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) port->bulk_in_endpointAddress); response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); if (response) { - err("%s - Error %d submitting control urb", __FUNCTION__, + err("%s - Error %d submitting control urb", __func__, response); } @@ -1116,7 +1116,7 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port) dbg("%s \n", " mos7840_chars_in_buffer:entering ..........."); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return -1; } @@ -1134,7 +1134,7 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port) } } spin_unlock_irqrestore(&mos7840_port->pool_lock,flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return chars; } @@ -1171,7 +1171,7 @@ static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port) /* No activity.. count down section */ wait--; if (wait == 0) { - dbg("%s - TIMEOUT", __FUNCTION__); + dbg("%s - TIMEOUT", __func__); return; } else { /* Reset timeout value back to seconds */ @@ -1195,12 +1195,12 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp) dbg("%s\n", "mos7840_close:entering..."); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return; } - serial = mos7840_get_usb_serial(port, __FUNCTION__); + serial = mos7840_get_usb_serial(port, __func__); if (!serial) { dbg("%s", "Serial Paranoia failed \n"); return; @@ -1314,7 +1314,7 @@ static void mos7840_block_until_chase_response(struct moschip_port /* No activity.. count down section */ wait--; if (wait == 0) { - dbg("%s - TIMEOUT", __FUNCTION__); + dbg("%s - TIMEOUT", __func__); return; } else { /* Reset timeout value back to seconds */ @@ -1337,12 +1337,12 @@ static void mos7840_break(struct usb_serial_port *port, int break_state) dbg("%s \n", "Entering ..........."); dbg("mos7840_break: Start\n"); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return; } - serial = mos7840_get_usb_serial(port, __FUNCTION__); + serial = mos7840_get_usb_serial(port, __func__); if (!serial) { dbg("%s", "Serial Paranoia failed \n"); return; @@ -1392,7 +1392,7 @@ static int mos7840_write_room(struct usb_serial_port *port) dbg("%s \n", " mos7840_write_room:entering ..........."); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); dbg("%s \n", " mos7840_write_room:leaving ..........."); return -1; @@ -1413,7 +1413,7 @@ static int mos7840_write_room(struct usb_serial_port *port) spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1; - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -1480,13 +1480,13 @@ static int mos7840_write(struct usb_serial_port *port, status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); #endif - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Port Paranoia failed \n"); return -1; } serial = port->serial; - if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) { + if (mos7840_serial_paranoia_check(serial, __func__)) { dbg("%s", "Serial Paranoia failed \n"); return -1; } @@ -1512,7 +1512,7 @@ static int mos7840_write(struct usb_serial_port *port, spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); if (urb == NULL) { - dbg("%s - no more free urbs", __FUNCTION__); + dbg("%s - no more free urbs", __func__); goto exit; } @@ -1521,7 +1521,7 @@ static int mos7840_write(struct usb_serial_port *port, kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - err("%s no more kernel memory...", __FUNCTION__); + err("%s no more kernel memory...", __func__); goto exit; } } @@ -1547,7 +1547,7 @@ static int mos7840_write(struct usb_serial_port *port, if (status) { mos7840_port->busy[i] = 0; err("%s - usb_submit_urb(write bulk) failed with status = %d", - __FUNCTION__, status); + __func__, status); bytes_sent = status; goto exit; } @@ -1573,7 +1573,7 @@ static void mos7840_throttle(struct usb_serial_port *port) struct tty_struct *tty; int status; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return; } @@ -1594,7 +1594,7 @@ static void mos7840_throttle(struct usb_serial_port *port) tty = port->tty; if (!tty) { - dbg("%s - no tty available", __FUNCTION__); + dbg("%s - no tty available", __func__); return; } @@ -1634,7 +1634,7 @@ static void mos7840_unthrottle(struct usb_serial_port *port) int status; struct moschip_port *mos7840_port = mos7840_get_port_private(port); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return; } @@ -1643,7 +1643,7 @@ static void mos7840_unthrottle(struct usb_serial_port *port) return; if (!mos7840_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } @@ -1651,7 +1651,7 @@ static void mos7840_unthrottle(struct usb_serial_port *port) tty = port->tty; if (!tty) { - dbg("%s - no tty available", __FUNCTION__); + dbg("%s - no tty available", __func__); return; } @@ -1688,7 +1688,7 @@ static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file) int status = 0; mos7840_port = mos7840_get_port_private(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (mos7840_port == NULL) return -ENODEV; @@ -1703,7 +1703,7 @@ static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file) | ((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0) | ((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0); - dbg("%s - 0x%04X", __FUNCTION__, result); + dbg("%s - 0x%04X", __func__, result); return result; } @@ -1715,7 +1715,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int mcr; unsigned int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); mos7840_port = mos7840_get_port_private(port); @@ -1759,7 +1759,7 @@ static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor, __u16 * clk_sel_val) { - dbg("%s - %d", __FUNCTION__, baudRate); + dbg("%s - %d", __func__, baudRate); if (baudRate <= 115200) { *divisor = 115200 / baudRate; @@ -1842,12 +1842,12 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, return -1; port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return -1; } - if (mos7840_serial_paranoia_check(port->serial, __FUNCTION__)) { + if (mos7840_serial_paranoia_check(port->serial, __func__)) { dbg("%s", "Invalid Serial \n"); return -1; } @@ -1856,7 +1856,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, number = mos7840_port->port->number - mos7840_port->port->serial->minor; - dbg("%s - port = %d, baud = %d", __FUNCTION__, + dbg("%s - port = %d, baud = %d", __func__, mos7840_port->port->number, baudRate); //reset clk_uart_sel in spregOffset if (baudRate > 115200) { @@ -1916,7 +1916,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, /* Calculate the Divisor */ if (status) { - err("%s - bad baud rate", __FUNCTION__); + err("%s - bad baud rate", __func__); dbg("%s\n", "bad baud rate"); return status; } @@ -1970,22 +1970,22 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return; } - if (mos7840_serial_paranoia_check(port->serial, __FUNCTION__)) { + if (mos7840_serial_paranoia_check(port->serial, __func__)) { dbg("%s", "Invalid Serial \n"); return; } serial = port->serial; - dbg("%s - port %d", __FUNCTION__, mos7840_port->port->number); + dbg("%s - port %d", __func__, mos7840_port->port->number); if (!mos7840_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } @@ -2024,14 +2024,14 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, if (cflag & PARENB) { if (cflag & PARODD) { lParity = LCR_PAR_ODD; - dbg("%s - parity = odd", __FUNCTION__); + dbg("%s - parity = odd", __func__); } else { lParity = LCR_PAR_EVEN; - dbg("%s - parity = even", __FUNCTION__); + dbg("%s - parity = even", __func__); } } else { - dbg("%s - parity = none", __FUNCTION__); + dbg("%s - parity = none", __func__); } if (cflag & CMSPAR) { @@ -2041,10 +2041,10 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, /* Change the Stop bit */ if (cflag & CSTOPB) { lStop = LCR_STOP_2; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { lStop = LCR_STOP_1; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } /* Update the LCR with the correct value */ @@ -2101,7 +2101,7 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, baud = 9600; } - dbg("%s - baud rate = %d", __FUNCTION__, baud); + dbg("%s - baud rate = %d", __func__, baud); status = mos7840_send_cmd_write_baud_rate(mos7840_port, baud); /* Enable Interrupts */ @@ -2141,14 +2141,14 @@ static void mos7840_set_termios(struct usb_serial_port *port, struct moschip_port *mos7840_port; struct tty_struct *tty; dbg("mos7840_set_termios: START\n"); - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return; } serial = port->serial; - if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) { + if (mos7840_serial_paranoia_check(serial, __func__)) { dbg("%s", "Invalid Serial \n"); return; } @@ -2161,7 +2161,7 @@ static void mos7840_set_termios(struct usb_serial_port *port, tty = port->tty; if (!mos7840_port->open) { - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); return; } @@ -2169,11 +2169,11 @@ static void mos7840_set_termios(struct usb_serial_port *port, cflag = tty->termios->c_cflag; - dbg("%s - clfag %08x iflag %08x", __FUNCTION__, + dbg("%s - clfag %08x iflag %08x", __func__, tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + dbg("%s - old clfag %08x old iflag %08x", __func__, old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* change the port settings to the new ones specified */ @@ -2214,7 +2214,7 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port, count = mos7840_chars_in_buffer(mos7840_port->port); if (count == 0) { - dbg("%s -- Empty", __FUNCTION__); + dbg("%s -- Empty", __func__); result = TIOCSER_TEMT; } @@ -2241,7 +2241,7 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, return -1; port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return -1; } @@ -2315,7 +2315,7 @@ static int mos7840_get_modem_info(struct moschip_port *mos7840_port, |((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */ |((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */ - dbg("%s -- %x", __FUNCTION__, result); + dbg("%s -- %x", __func__, result); if (copy_to_user(value, &result, sizeof(int))) return -EFAULT; @@ -2372,7 +2372,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, struct serial_icounter_struct icount; int mosret = 0; - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { + if (mos7840_port_paranoia_check(port, __func__)) { dbg("%s", "Invalid port \n"); return -1; } @@ -2384,39 +2384,39 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, tty = mos7840_port->port->tty; - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); switch (cmd) { /* return number of bytes available */ case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); return mos7840_get_lsr_info(mos7840_port, argp); return 0; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: - dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, + dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__, port->number); mosret = mos7840_set_modem_info(mos7840_port, cmd, argp); return mosret; case TIOCMGET: - dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMGET", __func__, port->number); return mos7840_get_modem_info(mos7840_port, argp); case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCGSERIAL", __func__, port->number); return mos7840_get_serial_info(mos7840_port, argp); case TIOCSSERIAL: - dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); + dbg("%s (%d) TIOCSSERIAL", __func__, port->number); break; case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); cprev = mos7840_port->icount; while (1) { //interruptible_sleep_on(&mos7840_port->delta_msr_wait); @@ -2459,7 +2459,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, + dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, icount.rx, icount.tx); if (copy_to_user(argp, &icount, sizeof(icount))) return -EFAULT; @@ -2522,7 +2522,7 @@ static int mos7840_startup(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7840_port == NULL) { - err("%s - Out of memory", __FUNCTION__); + err("%s - Out of memory", __func__); status = -ENOMEM; i--; /* don't follow NULL pointer cleaning up */ goto error; diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index ddaccbcde84d..7cea325d577c 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -49,15 +49,15 @@ static void navman_read_int_callback(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; @@ -72,29 +72,29 @@ exit: if (result) dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); + __func__, result); } static int navman_open(struct usb_serial_port *port, struct file *filp) { int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (port->interrupt_in_urb) { - dbg("%s - adding interrupt input for treo", __FUNCTION__); + dbg("%s - adding interrupt input for treo", __func__); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n", - __FUNCTION__, result); + __func__, result); } return result; } static void navman_close(struct usb_serial_port *port, struct file *filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->interrupt_in_urb); } @@ -102,7 +102,7 @@ static void navman_close(struct usb_serial_port *port, struct file *filp) static int navman_write(struct usb_serial_port *port, const unsigned char *buf, int count) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * This device can't write any data, only read from the device diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 050511ff2b17..1b041c59aab2 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -150,7 +150,7 @@ static int omninet_attach (struct usb_serial *serial) od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); if( !od ) { - err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct omninet_data)); + err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct omninet_data)); return -ENOMEM; } usb_set_serial_port_data(port, od); @@ -163,7 +163,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) struct usb_serial_port *wport; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); wport = serial->port[1]; wport->tty = port->tty; @@ -175,7 +175,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) omninet_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, result); + err("%s - failed submitting read urb, error %d", __func__, result); } return result; @@ -183,7 +183,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) static void omninet_close (struct usb_serial_port *port, struct file * filp) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->read_urb); } @@ -201,11 +201,11 @@ static void omninet_read_bulk_callback (struct urb *urb) int i; int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -233,7 +233,7 @@ static void omninet_read_bulk_callback (struct urb *urb) omninet_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + err("%s - failed resubmitting read urb, error %d", __func__, result); return; } @@ -248,17 +248,17 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return (0); } spin_lock_bh(&wport->lock); if (wport->write_urb_busy) { spin_unlock_bh(&wport->lock); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } wport->write_urb_busy = 1; @@ -268,7 +268,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, wport->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, wport->write_urb->transfer_buffer); header->oh_seq = od->od_outseq++; header->oh_len = count; @@ -282,7 +282,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { wport->write_urb_busy = 0; - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); } else result = count; @@ -300,7 +300,7 @@ static int omninet_write_room (struct usb_serial_port *port) if (wport->write_urb_busy) room = wport->bulk_out_size - OMNINET_HEADERLEN; - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return (room); } @@ -311,12 +311,12 @@ static void omninet_write_bulk_callback (struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *) urb->context; int status = urb->status; - dbg("%s - port %0x\n", __FUNCTION__, port->number); + dbg("%s - port %0x\n", __func__, port->number); port->write_urb_busy = 0; if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -328,7 +328,7 @@ static void omninet_shutdown (struct usb_serial *serial) { struct usb_serial_port *wport = serial->port[1]; struct usb_serial_port *port = serial->port[0]; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); usb_kill_urb(wport->write_urb); kfree(usb_get_serial_port_data(port)); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f4914209871d..920241897c95 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -408,24 +408,24 @@ module_exit(option_exit); static void option_rx_throttle(struct usb_serial_port *port) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void option_rx_unthrottle(struct usb_serial_port *port) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void option_break_ctl(struct usb_serial_port *port, int break_state) { /* Unfortunately, I don't know how to send a break */ - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void option_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Doesn't support option setting */ tty_termios_copy_hw(port->tty->termios, old_termios); option_send_setup(port); @@ -486,7 +486,7 @@ static int option_write(struct usb_serial_port *port, portdata = usb_get_serial_port_data(port); - dbg("%s: write (%d chars)", __FUNCTION__, count); + dbg("%s: write (%d chars)", __func__, count); i = 0; left = count; @@ -507,7 +507,7 @@ static int option_write(struct usb_serial_port *port, dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status); - dbg("%s: endpoint %d buf %d", __FUNCTION__, + dbg("%s: endpoint %d buf %d", __func__, usb_pipeendpoint(this_urb->pipe), i); /* send the data */ @@ -529,7 +529,7 @@ static int option_write(struct usb_serial_port *port, } count -= left; - dbg("%s: wrote (did %d)", __FUNCTION__, count); + dbg("%s: wrote (did %d)", __func__, count); return count; } @@ -542,14 +542,14 @@ static void option_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg("%s: %p", __FUNCTION__, urb); + dbg("%s: %p", __func__, urb); endpoint = usb_pipeendpoint(urb->pipe); port = (struct usb_serial_port *) urb->context; if (status) { dbg("%s: nonzero status: %d on endpoint %02x.", - __FUNCTION__, status, endpoint); + __func__, status, endpoint); } else { tty = port->tty; if (urb->actual_length) { @@ -557,7 +557,7 @@ static void option_indat_callback(struct urb *urb) tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } else { - dbg("%s: empty read urb received", __FUNCTION__); + dbg("%s: empty read urb received", __func__); } /* Resubmit urb so we continue receiving */ @@ -565,7 +565,7 @@ static void option_indat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err) printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __FUNCTION__, err); + "(%d)", __func__, err); } } return; @@ -577,7 +577,7 @@ static void option_outdat_callback(struct urb *urb) struct option_port_private *portdata; int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); port = (struct usb_serial_port *) urb->context; @@ -601,15 +601,15 @@ static void option_instat_callback(struct urb *urb) struct option_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; - dbg("%s", __FUNCTION__); - dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); + dbg("%s", __func__); + dbg("%s: urb %p port %p has data %p", __func__,urb,port,portdata); if (status == 0) { struct usb_ctrlrequest *req_pkt = (struct usb_ctrlrequest *)urb->transfer_buffer; if (!req_pkt) { - dbg("%s: NULL req_pkt\n", __FUNCTION__); + dbg("%s: NULL req_pkt\n", __func__); return; } if ((req_pkt->bRequestType == 0xA1) && @@ -619,7 +619,7 @@ static void option_instat_callback(struct urb *urb) urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); - dbg("%s: signal x%x", __FUNCTION__, signals); + dbg("%s: signal x%x", __func__, signals); old_dcd_state = portdata->dcd_state; portdata->cts_state = 1; @@ -631,11 +631,11 @@ static void option_instat_callback(struct urb *urb) old_dcd_state && !portdata->dcd_state) tty_hangup(port->tty); } else { - dbg("%s: type %x req %x", __FUNCTION__, + dbg("%s: type %x req %x", __func__, req_pkt->bRequestType,req_pkt->bRequest); } } else - dbg("%s: error %d", __FUNCTION__, status); + dbg("%s: error %d", __func__, status); /* Resubmit urb so we continue receiving IRQ data */ if (status != -ESHUTDOWN) { @@ -643,7 +643,7 @@ static void option_instat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err) dbg("%s: resubmit intr urb failed. (%d)", - __FUNCTION__, err); + __func__, err); } } @@ -662,7 +662,7 @@ static int option_write_room(struct usb_serial_port *port) data_len += OUT_BUFLEN; } - dbg("%s: %d", __FUNCTION__, data_len); + dbg("%s: %d", __func__, data_len); return data_len; } @@ -680,7 +680,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port) if (this_urb && test_bit(i, &portdata->out_busy)) data_len += this_urb->transfer_buffer_length; } - dbg("%s: %d", __FUNCTION__, data_len); + dbg("%s: %d", __func__, data_len); return data_len; } @@ -693,7 +693,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) portdata = usb_get_serial_port_data(port); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Set some sane defaults */ portdata->rts_state = 1; @@ -705,7 +705,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) if (! urb) continue; if (urb->dev != serial->dev) { - dbg("%s: dev %p != %p", __FUNCTION__, + dbg("%s: dev %p != %p", __func__, urb->dev, serial->dev); continue; } @@ -719,7 +719,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp) err = usb_submit_urb(urb, GFP_KERNEL); if (err) { dbg("%s: submit urb %d failed (%d) %d", - __FUNCTION__, i, err, + __func__, i, err, urb->transfer_buffer_length); } } @@ -747,7 +747,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp) struct usb_serial *serial = port->serial; struct option_port_private *portdata; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); portdata = usb_get_serial_port_data(port); portdata->rts_state = 0; @@ -780,7 +780,7 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); + dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); return NULL; } @@ -799,7 +799,7 @@ static void option_setup_urbs(struct usb_serial *serial) struct usb_serial_port *port; struct option_port_private *portdata; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; @@ -832,7 +832,7 @@ static int option_send_setup(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct option_port_private *portdata; int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); portdata = usb_get_serial_port_data(port); @@ -858,7 +858,7 @@ static int option_startup(struct usb_serial *serial) struct option_port_private *portdata; u8 *buffer; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { @@ -866,7 +866,7 @@ static int option_startup(struct usb_serial *serial) portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) { dbg("%s: kmalloc for option_port_private (%d) failed!.", - __FUNCTION__, i); + __func__, i); return (1); } @@ -891,7 +891,7 @@ static int option_startup(struct usb_serial *serial) err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (err) dbg("%s: submit irq_in urb failed %d", - __FUNCTION__, err); + __func__, err); } option_setup_urbs(serial); @@ -915,7 +915,7 @@ static void option_shutdown(struct usb_serial *serial) struct usb_serial_port *port; struct option_port_private *portdata; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Stop reading/writing urbs */ for (i = 0; i < serial->num_ports; ++i) { diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 20a680ed0cc7..87f33e06301c 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -235,10 +235,10 @@ static void setup_line(struct work_struct *work) unsigned long flags; int result; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { - dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__); + dev_err(&port->dev, "%s(): out of memory!\n", __func__); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); return; @@ -253,7 +253,7 @@ static void setup_line(struct work_struct *work) 100); if (result != OTI6858_CTRL_PKT_SIZE) { - dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__); + dev_err(&port->dev, "%s(): error reading status\n", __func__); kfree(new_setup); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); @@ -286,12 +286,12 @@ static void setup_line(struct work_struct *work) priv->setup_done = 1; spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s(): submitting interrupt urb", __FUNCTION__); + dbg("%s(): submitting interrupt urb", __func__); port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result != 0) { dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __FUNCTION__, result); + " with error %d\n", __func__, result); } } @@ -303,7 +303,7 @@ void send_data(struct work_struct *work) unsigned long flags; unsigned char allow; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (priv->flags.write_urb_in_use) { @@ -331,12 +331,12 @@ void send_data(struct work_struct *work) if (count == 0) { priv->flags.write_urb_in_use = 0; - dbg("%s(): submitting interrupt urb", __FUNCTION__); + dbg("%s(): submitting interrupt urb", __func__); port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result != 0) { dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __FUNCTION__, result); + " with error %d\n", __func__, result); } return; } @@ -350,7 +350,7 @@ void send_data(struct work_struct *work) result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result != 0) { dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __FUNCTION__, result); + " with error %d\n", __func__, result); priv->flags.write_urb_in_use = 0; } @@ -401,7 +401,7 @@ static int oti6858_write(struct usb_serial_port *port, struct oti6858_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s(port = %d, count = %d)", __FUNCTION__, port->number, count); + dbg("%s(port = %d, count = %d)", __func__, port->number, count); if (!count) return count; @@ -419,7 +419,7 @@ static int oti6858_write_room(struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); room = oti6858_buf_space_avail(priv->buf); @@ -434,7 +434,7 @@ static int oti6858_chars_in_buffer(struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); chars = oti6858_buf_data_avail(priv->buf); @@ -453,10 +453,10 @@ static void oti6858_set_termios(struct usb_serial_port *port, u16 divisor; int br; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); if (!port->tty || !port->tty->termios) { - dbg("%s(): no tty structures", __FUNCTION__); + dbg("%s(): no tty structures", __func__); return; } @@ -572,7 +572,7 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) unsigned long flags; int result; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); @@ -581,7 +581,7 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) return 0; if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { - dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__); + dev_err(&port->dev, "%s(): out of memory!\n", __func__); return -ENOMEM; } @@ -610,12 +610,12 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) spin_unlock_irqrestore(&priv->lock, flags); kfree(buf); - dbg("%s(): submitting interrupt urb", __FUNCTION__); + dbg("%s(): submitting interrupt urb", __func__); port->interrupt_in_urb->dev = serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result != 0) { dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __FUNCTION__, result); + " with error %d\n", __func__, result); oti6858_close(port, NULL); return -EPROTO; } @@ -634,14 +634,14 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) long timeout; wait_queue_t wait; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); /* wait for data to drain from the buffer */ spin_lock_irqsave(&priv->lock, flags); timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ init_waitqueue_entry(&wait, current); add_wait_queue(&port->tty->write_wait, &wait); - dbg("%s(): entering wait loop", __FUNCTION__); + dbg("%s(): entering wait loop", __func__); for (;;) { set_current_state(TASK_INTERRUPTIBLE); if (oti6858_buf_data_avail(priv->buf) == 0 @@ -654,7 +654,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) } set_current_state(TASK_RUNNING); remove_wait_queue(&port->tty->write_wait, &wait); - dbg("%s(): after wait loop", __FUNCTION__); + dbg("%s(): after wait loop", __func__); /* clear out any remaining data in the buffer */ oti6858_buf_clear(priv->buf); @@ -675,7 +675,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) */ timeout = 2*HZ; schedule_timeout_interruptible(timeout); - dbg("%s(): after schedule_timeout_interruptible()", __FUNCTION__); + dbg("%s(): after schedule_timeout_interruptible()", __func__); /* cancel scheduled setup */ cancel_delayed_work(&priv->delayed_setup_work); @@ -683,7 +683,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) flush_scheduled_work(); /* shutdown our urbs */ - dbg("%s(): shutting down urbs", __FUNCTION__); + dbg("%s(): shutting down urbs", __func__); usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); usb_kill_urb(port->interrupt_in_urb); @@ -706,7 +706,7 @@ static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, u8 control; dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)", - __FUNCTION__, port->number, set, clear); + __func__, port->number, set, clear); if (!usb_get_intfdata(port->serial->interface)) return -ENODEV; @@ -738,7 +738,7 @@ static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file) unsigned pin_state; unsigned result = 0; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); if (!usb_get_intfdata(port->serial->interface)) return -ENODEV; @@ -761,7 +761,7 @@ static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file) if ((pin_state & PIN_DCD) != 0) result |= TIOCM_CD; - dbg("%s() = 0x%08x", __FUNCTION__, result); + dbg("%s() = 0x%08x", __func__, result); return result; } @@ -808,7 +808,7 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, unsigned int x; dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", - __FUNCTION__, port->number, cmd, arg); + __func__, port->number, cmd, arg); switch (cmd) { case TIOCMBIS: @@ -822,11 +822,11 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, return oti6858_tiocmset(port, NULL, 0, x); case TIOCMIWAIT: - dbg("%s(): TIOCMIWAIT", __FUNCTION__); + dbg("%s(): TIOCMIWAIT", __func__); return wait_modem_info(port, arg); default: - dbg("%s(): 0x%04x not supported", __FUNCTION__, cmd); + dbg("%s(): 0x%04x not supported", __func__, cmd); break; } @@ -837,10 +837,10 @@ static void oti6858_break_ctl(struct usb_serial_port *port, int break_state) { int state; - dbg("%s(port = %d)", __FUNCTION__, port->number); + dbg("%s(port = %d)", __func__, port->number); state = (break_state == 0) ? 0 : 1; - dbg("%s(): turning break %s", __FUNCTION__, state ? "on" : "off"); + dbg("%s(): turning break %s", __func__, state ? "on" : "off"); /* FIXME */ /* @@ -848,7 +848,7 @@ static void oti6858_break_ctl(struct usb_serial_port *port, int break_state) BREAK_REQUEST, BREAK_REQUEST_TYPE, state, 0, NULL, 0, 100); if (result != 0) - dbg("%s(): error sending break", __FUNCTION__); + dbg("%s(): error sending break", __func__); */ } @@ -857,7 +857,7 @@ static void oti6858_shutdown(struct usb_serial *serial) struct oti6858_private *priv; int i; - dbg("%s()", __FUNCTION__); + dbg("%s()", __func__); for (i = 0; i < serial->num_ports; ++i) { priv = usb_get_serial_port_data(serial->port[i]); @@ -877,7 +877,7 @@ static void oti6858_read_int_callback(struct urb *urb) int status = urb->status; dbg("%s(port = %d, status = %d)", - __FUNCTION__, port->number, status); + __func__, port->number, status); switch (status) { case 0: @@ -888,11 +888,11 @@ static void oti6858_read_int_callback(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s(): urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s(): nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); break; } @@ -909,7 +909,7 @@ static void oti6858_read_int_callback(struct urb *urb) priv->setup_done = 0; resubmit = 0; dbg("%s(): scheduling setup_line()", - __FUNCTION__); + __func__); schedule_delayed_work(&priv->delayed_setup_work, 0); } } @@ -924,7 +924,7 @@ static void oti6858_read_int_callback(struct urb *urb) priv->setup_done = 0; resubmit = 0; dbg("%s(): scheduling setup_line()", - __FUNCTION__); + __func__); schedule_delayed_work(&priv->delayed_setup_work, 0); } } @@ -953,7 +953,7 @@ static void oti6858_read_int_callback(struct urb *urb) if (result != 0) { priv->flags.read_urb_in_use = 0; dev_err(&port->dev, "%s(): usb_submit_urb() failed," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); } else { resubmit = 0; } @@ -972,13 +972,13 @@ static void oti6858_read_int_callback(struct urb *urb) if (resubmit) { int result; -// dbg("%s(): submitting interrupt urb", __FUNCTION__); +// dbg("%s(): submitting interrupt urb", __func__); urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result != 0) { dev_err(&urb->dev->dev, "%s(): usb_submit_urb() failed with" - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); } } } @@ -994,7 +994,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) int result; dbg("%s(port = %d, status = %d)", - __FUNCTION__, port->number, status); + __func__, port->number, status); spin_lock_irqsave(&priv->lock, flags); priv->flags.read_urb_in_use = 0; @@ -1002,20 +1002,20 @@ static void oti6858_read_bulk_callback(struct urb *urb) if (status != 0) { if (!port->open_count) { - dbg("%s(): port is closed, exiting", __FUNCTION__); + dbg("%s(): port is closed, exiting", __func__); return; } /* if (status == -EPROTO) { // PL2303 mysteriously fails with -EPROTO reschedule the read - dbg("%s - caught -EPROTO, resubmitting the urb", __FUNCTION__); + dbg("%s - caught -EPROTO, resubmitting the urb", __func__); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) - dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); return; } */ - dbg("%s(): unable to handle the error, exiting", __FUNCTION__); + dbg("%s(): unable to handle the error, exiting", __func__); return; } @@ -1031,7 +1031,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result != 0) { dev_err(&port->dev, "%s(): usb_submit_urb() failed," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); } } } @@ -1044,7 +1044,7 @@ static void oti6858_write_bulk_callback(struct urb *urb) int result; dbg("%s(port = %d, status = %d)", - __FUNCTION__, port->number, status); + __func__, port->number, status); switch (status) { case 0: @@ -1055,21 +1055,21 @@ static void oti6858_write_bulk_callback(struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s(): urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); priv->flags.write_urb_in_use = 0; return; default: /* error in the urb, so we have to resubmit it */ dbg("%s(): nonzero write bulk status received: %d", - __FUNCTION__, status); - dbg("%s(): overflow in write", __FUNCTION__); + __func__, status); + dbg("%s(): overflow in write", __func__); port->write_urb->transfer_buffer_length = 1; port->write_urb->dev = port->serial->dev; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s(): usb_submit_urb() failed," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); } else { return; } @@ -1079,11 +1079,11 @@ static void oti6858_write_bulk_callback(struct urb *urb) // schedule the interrupt urb if we are still open */ port->interrupt_in_urb->dev = port->serial->dev; - dbg("%s(): submitting interrupt urb", __FUNCTION__); + dbg("%s(): submitting interrupt urb", __func__); result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result != 0) { dev_err(&port->dev, "%s(): failed submitting int urb," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); } } diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1fbb4dbdf23d..2b4ab371c762 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -410,7 +410,7 @@ static int set_control_lines(struct usb_device *dev, u8 value) retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, value, 0, NULL, 0, 100); - dbg("%s - value = %d, retval = %d", __FUNCTION__, value, retval); + dbg("%s - value = %d, retval = %d", __func__, value, retval); return retval; } @@ -420,7 +420,7 @@ static void pl2303_send(struct usb_serial_port *port) struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); @@ -441,7 +441,7 @@ static void pl2303_send(struct usb_serial_port *port) spin_unlock_irqrestore(&priv->lock, flags); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, + usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer); port->write_urb->transfer_buffer_length = count; @@ -449,7 +449,7 @@ static void pl2303_send(struct usb_serial_port *port) result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - failed submitting write urb," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); priv->write_urb_in_use = 0; // TODO: reschedule pl2303_send } @@ -463,7 +463,7 @@ static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf, struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); + dbg("%s - port %d, %d bytes", __func__, port->number, count); if (!count) return count; @@ -483,13 +483,13 @@ static int pl2303_write_room(struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); room = pl2303_buf_space_avail(priv->buf); spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -499,13 +499,13 @@ static int pl2303_chars_in_buffer(struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); chars = pl2303_buf_data_avail(priv->buf); spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return chars; } @@ -521,7 +521,7 @@ static void pl2303_set_termios(struct usb_serial_port *port, int i; u8 control; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (!priv->termios_initialized) { @@ -545,7 +545,7 @@ static void pl2303_set_termios(struct usb_serial_port *port, buf = kzalloc(7, GFP_KERNEL); if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); + dev_err(&port->dev, "%s - out of memory.\n", __func__); return; } @@ -563,11 +563,11 @@ static void pl2303_set_termios(struct usb_serial_port *port, default: case CS8: buf[6] = 8; break; } - dbg("%s - data bits = %d", __FUNCTION__, buf[6]); + dbg("%s - data bits = %d", __func__, buf[6]); } baud = tty_get_baud_rate(port->tty);; - dbg("%s - baud = %d", __FUNCTION__, baud); + dbg("%s - baud = %d", __func__, baud); if (baud) { buf[0] = baud & 0xff; buf[1] = (baud >> 8) & 0xff; @@ -580,10 +580,10 @@ static void pl2303_set_termios(struct usb_serial_port *port, /* For reference buf[4]=2 is 2 stop bits */ if (cflag & CSTOPB) { buf[4] = 2; - dbg("%s - stop bits = 2", __FUNCTION__); + dbg("%s - stop bits = 2", __func__); } else { buf[4] = 0; - dbg("%s - stop bits = 1", __FUNCTION__); + dbg("%s - stop bits = 1", __func__); } if (cflag & PARENB) { @@ -594,14 +594,14 @@ static void pl2303_set_termios(struct usb_serial_port *port, /* For reference buf[5]=4 is space parity */ if (cflag & PARODD) { buf[5] = 1; - dbg("%s - parity = odd", __FUNCTION__); + dbg("%s - parity = odd", __func__); } else { buf[5] = 2; - dbg("%s - parity = even", __FUNCTION__); + dbg("%s - parity = even", __func__); } } else { buf[5] = 0; - dbg("%s - parity = none", __FUNCTION__); + dbg("%s - parity = none", __func__); } i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), @@ -657,7 +657,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) long timeout; wait_queue_t wait; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* wait for data to drain from the buffer */ spin_lock_irqsave(&priv->lock, flags); @@ -695,7 +695,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) schedule_timeout_interruptible(timeout); /* shutdown our urbs */ - dbg("%s - shutting down urbs", __FUNCTION__); + dbg("%s - shutting down urbs", __func__); usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); usb_kill_urb(port->interrupt_in_urb); @@ -719,7 +719,7 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) struct pl2303_private *priv = usb_get_serial_port_data(port); int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (priv->type != HX) { usb_clear_halt(serial->dev, port->write_urb->pipe); @@ -737,22 +737,22 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp) //FIXME: need to assert RTS and DTR if CRTSCTS off - dbg("%s - submitting read urb", __FUNCTION__); + dbg("%s - submitting read urb", __func__); port->read_urb->dev = serial->dev; result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { dev_err(&port->dev, "%s - failed submitting read urb," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); pl2303_close(port, NULL); return -EPROTO; } - dbg("%s - submitting interrupt urb", __FUNCTION__); + dbg("%s - submitting interrupt urb", __func__); port->interrupt_in_urb->dev = serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) { dev_err(&port->dev, "%s - failed submitting interrupt urb," - " error %d\n", __FUNCTION__, result); + " error %d\n", __func__, result); pl2303_close(port, NULL); return -EPROTO; } @@ -792,7 +792,7 @@ static int pl2303_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int status; unsigned int result; - dbg("%s (%d)", __FUNCTION__, port->number); + dbg("%s (%d)", __func__, port->number); if (!usb_get_intfdata(port->serial->interface)) return -ENODEV; @@ -809,7 +809,7 @@ static int pl2303_tiocmget(struct usb_serial_port *port, struct file *file) | ((status & UART_RING) ? TIOCM_RI : 0) | ((status & UART_DCD) ? TIOCM_CD : 0); - dbg("%s - result = %x", __FUNCTION__, result); + dbg("%s - result = %x", __func__, result); return result; } @@ -853,15 +853,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) static int pl2303_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { - dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd); + dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); switch (cmd) { case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); return wait_modem_info(port, arg); default: - dbg("%s not supported = 0x%04x", __FUNCTION__, cmd); + dbg("%s not supported = 0x%04x", __func__, cmd); break; } @@ -874,19 +874,19 @@ static void pl2303_break_ctl(struct usb_serial_port *port, int break_state) u16 state; int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (break_state == 0) state = BREAK_OFF; else state = BREAK_ON; - dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); + dbg("%s - turning break %s", __func__, state==BREAK_OFF ? "off" : "on"); result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), BREAK_REQUEST, BREAK_REQUEST_TYPE, state, 0, NULL, 0, 100); if (result) - dbg("%s - error sending break = %d", __FUNCTION__, result); + dbg("%s - error sending break = %d", __func__, result); } static void pl2303_shutdown(struct usb_serial *serial) @@ -894,7 +894,7 @@ static void pl2303_shutdown(struct usb_serial *serial) int i; struct pl2303_private *priv; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i = 0; i < serial->num_ports; ++i) { priv = usb_get_serial_port_data(serial->port[i]); @@ -949,7 +949,7 @@ static void pl2303_read_int_callback(struct urb *urb) int status = urb->status; int retval; - dbg("%s (%d)", __FUNCTION__, port->number); + dbg("%s (%d)", __func__, port->number); switch (status) { case 0: @@ -959,16 +959,16 @@ static void pl2303_read_int_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, + dbg("%s - urb shutting down with status: %d", __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, + dbg("%s - nonzero urb status received: %d", __func__, status); goto exit; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, urb->transfer_buffer); pl2303_update_line_status(port, data, actual_length); @@ -978,7 +978,7 @@ exit: if (retval) dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n", - __FUNCTION__, retval); + __func__, retval); } static void pl2303_read_bulk_callback(struct urb *urb) @@ -994,32 +994,32 @@ static void pl2303_read_bulk_callback(struct urb *urb) u8 line_status; char tty_flag; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { - dbg("%s - urb status = %d", __FUNCTION__, status); + dbg("%s - urb status = %d", __func__, status); if (!port->open_count) { - dbg("%s - port is closed, exiting.", __FUNCTION__); + dbg("%s - port is closed, exiting.", __func__); return; } if (status == -EPROTO) { /* PL2303 mysteriously fails with -EPROTO reschedule * the read */ dbg("%s - caught -EPROTO, resubmitting the urb", - __FUNCTION__); + __func__); urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed" " resubmitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); return; } - dbg("%s - unable to handle the error, exiting.", __FUNCTION__); + dbg("%s - unable to handle the error, exiting.", __func__); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* get tty_flag from status */ @@ -1039,7 +1039,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) tty_flag = TTY_PARITY; else if (line_status & UART_FRAME_ERROR) tty_flag = TTY_FRAME; - dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag); + dbg("%s - tty_flag = %d", __func__, tty_flag); tty = port->tty; if (tty && urb->actual_length) { @@ -1058,7 +1058,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) result = usb_submit_urb(urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting" - " read urb, error %d\n", __FUNCTION__, result); + " read urb, error %d\n", __func__, result); } return; @@ -1071,7 +1071,7 @@ static void pl2303_write_bulk_callback(struct urb *urb) int result; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); switch (status) { case 0: @@ -1081,21 +1081,21 @@ static void pl2303_write_bulk_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, + dbg("%s - urb shutting down with status: %d", __func__, status); priv->write_urb_in_use = 0; return; default: /* error in the urb, so we have to resubmit it */ - dbg("%s - Overflow in write", __FUNCTION__); - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, + dbg("%s - Overflow in write", __func__); + dbg("%s - nonzero write bulk status received: %d", __func__, status); port->write_urb->transfer_buffer_length = 1; port->write_urb->dev = port->serial->dev; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting write" - " urb, error %d\n", __FUNCTION__, result); + " urb, error %d\n", __func__, result); else return; } diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 353c54fa0580..3fe98a52b914 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -202,11 +202,11 @@ static void safe_read_bulk_callback (struct urb *urb) int result; int status = urb->status; - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -232,18 +232,18 @@ static void safe_read_bulk_callback (struct urb *urb) if (actual_length <= (length - 2)) { - info ("%s - actual: %d", __FUNCTION__, actual_length); + info ("%s - actual: %d", __func__, actual_length); for (i = 0; i < actual_length; i++) { tty_insert_flip_char (port->tty, data[i], 0); } tty_flip_buffer_push (port->tty); } else { - err ("%s - inconsistent lengths %d:%d", __FUNCTION__, + err ("%s - inconsistent lengths %d:%d", __func__, actual_length, length); } } else { - err ("%s - bad CRC %x", __FUNCTION__, fcs); + err ("%s - bad CRC %x", __func__, fcs); } } else { for (i = 0; i < length; i++) { @@ -259,7 +259,7 @@ static void safe_read_bulk_callback (struct urb *urb) safe_read_bulk_callback, port); if ((result = usb_submit_urb (urb, GFP_ATOMIC))) { - err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + err ("%s - failed resubmitting read urb, error %d", __func__, result); } } @@ -274,7 +274,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i count); if (!port->write_urb) { - dbg ("%s - write urb NULL", __FUNCTION__); + dbg ("%s - write urb NULL", __func__); return (0); } @@ -282,17 +282,17 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i port->write_urb->transfer_buffer_length); if (!port->write_urb->transfer_buffer_length) { - dbg ("%s - write urb transfer_buffer_length zero", __FUNCTION__); + dbg ("%s - write urb transfer_buffer_length zero", __func__); return (0); } if (count == 0) { - dbg ("%s - write request of 0 bytes", __FUNCTION__); + dbg ("%s - write request of 0 bytes", __func__); return (0); } spin_lock_bh(&port->lock); if (port->write_urb_busy) { spin_unlock_bh(&port->lock); - dbg("%s - already writing", __FUNCTION__); + dbg("%s - already writing", __func__); return 0; } port->write_urb_busy = 1; @@ -332,7 +332,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i port->write_urb->transfer_buffer_length = count; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer); #ifdef ECHO_TX { int i; @@ -349,10 +349,10 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i port->write_urb->dev = port->serial->dev; if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) { port->write_urb_busy = 0; - err ("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err ("%s - failed submitting write urb, error %d", __func__, result); return 0; } - dbg ("%s urb: %p submitted", __FUNCTION__, port->write_urb); + dbg ("%s urb: %p submitted", __func__, port->write_urb); return (count); } @@ -361,7 +361,7 @@ static int safe_write_room (struct usb_serial_port *port) { int room = 0; // Default: no room - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); if (port->write_urb_busy) room = port->bulk_out_size - (safe ? 2 : 0); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 07eabaf9f044..ed30adefff85 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -256,7 +256,7 @@ static int sierra_send_setup(struct usb_serial_port *port) struct sierra_port_private *portdata; __u16 interface = 0; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); portdata = usb_get_serial_port_data(port); @@ -286,24 +286,24 @@ static int sierra_send_setup(struct usb_serial_port *port) static void sierra_rx_throttle(struct usb_serial_port *port) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void sierra_rx_unthrottle(struct usb_serial_port *port) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void sierra_break_ctl(struct usb_serial_port *port, int break_state) { /* Unfortunately, I don't know how to send a break */ - dbg("%s", __FUNCTION__); + dbg("%s", __func__); } static void sierra_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); tty_termios_copy_hw(port->tty->termios, old_termios); sierra_send_setup(port); } @@ -357,14 +357,14 @@ static void sierra_outdat_callback(struct urb *urb) int status = urb->status; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree(urb->transfer_buffer); if (status) dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); spin_lock_irqsave(&portdata->lock, flags); --portdata->outstanding_urbs; @@ -386,12 +386,12 @@ static int sierra_write(struct usb_serial_port *port, portdata = usb_get_serial_port_data(port); - dbg("%s: write (%d chars)", __FUNCTION__, count); + dbg("%s: write (%d chars)", __func__, count); spin_lock_irqsave(&portdata->lock, flags); if (portdata->outstanding_urbs > N_OUT_URB) { spin_unlock_irqrestore(&portdata->lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } portdata->outstanding_urbs++; @@ -413,7 +413,7 @@ static int sierra_write(struct usb_serial_port *port, memcpy(buffer, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, @@ -424,7 +424,7 @@ static int sierra_write(struct usb_serial_port *port, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __FUNCTION__, status); + "with status = %d\n", __func__, status); count = status; goto error; } @@ -454,14 +454,14 @@ static void sierra_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg("%s: %p", __FUNCTION__, urb); + dbg("%s: %p", __func__, urb); endpoint = usb_pipeendpoint(urb->pipe); port = (struct usb_serial_port *) urb->context; if (status) { dbg("%s: nonzero status: %d on endpoint %02x.", - __FUNCTION__, status, endpoint); + __func__, status, endpoint); } else { tty = port->tty; if (urb->actual_length) { @@ -469,7 +469,7 @@ static void sierra_indat_callback(struct urb *urb) tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); } else { - dbg("%s: empty read urb received", __FUNCTION__); + dbg("%s: empty read urb received", __func__); } /* Resubmit urb so we continue receiving */ @@ -491,15 +491,15 @@ static void sierra_instat_callback(struct urb *urb) struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; - dbg("%s", __FUNCTION__); - dbg("%s: urb %p port %p has data %p", __FUNCTION__, urb, port, portdata); + dbg("%s", __func__); + dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); if (status == 0) { struct usb_ctrlrequest *req_pkt = (struct usb_ctrlrequest *)urb->transfer_buffer; if (!req_pkt) { - dbg("%s: NULL req_pkt\n", __FUNCTION__); + dbg("%s: NULL req_pkt\n", __func__); return; } if ((req_pkt->bRequestType == 0xA1) && @@ -509,7 +509,7 @@ static void sierra_instat_callback(struct urb *urb) urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); - dbg("%s: signal x%x", __FUNCTION__, signals); + dbg("%s: signal x%x", __func__, signals); old_dcd_state = portdata->dcd_state; portdata->cts_state = 1; @@ -521,11 +521,11 @@ static void sierra_instat_callback(struct urb *urb) old_dcd_state && !portdata->dcd_state) tty_hangup(port->tty); } else { - dbg("%s: type %x req %x", __FUNCTION__, + dbg("%s: type %x req %x", __func__, req_pkt->bRequestType, req_pkt->bRequest); } } else - dbg("%s: error %d", __FUNCTION__, status); + dbg("%s: error %d", __func__, status); /* Resubmit urb so we continue receiving IRQ data */ if (status != -ESHUTDOWN) { @@ -533,7 +533,7 @@ static void sierra_instat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err) dbg("%s: resubmit intr urb failed. (%d)", - __FUNCTION__, err); + __func__, err); } } @@ -542,14 +542,14 @@ static int sierra_write_room(struct usb_serial_port *port) struct sierra_port_private *portdata = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* try to give a good number back based on if we have any free urbs at * this point in time */ spin_lock_irqsave(&portdata->lock, flags); if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) { spin_unlock_irqrestore(&portdata->lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } spin_unlock_irqrestore(&portdata->lock, flags); @@ -559,7 +559,7 @@ static int sierra_write_room(struct usb_serial_port *port) static int sierra_chars_in_buffer(struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * We can't really account for how much data we @@ -580,7 +580,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) portdata = usb_get_serial_port_data(port); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Set some sane defaults */ portdata->rts_state = 1; @@ -592,7 +592,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) if (!urb) continue; if (urb->dev != serial->dev) { - dbg("%s: dev %p != %p", __FUNCTION__, + dbg("%s: dev %p != %p", __func__, urb->dev, serial->dev); continue; } @@ -630,7 +630,7 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp) struct usb_serial *serial = port->serial; struct sierra_port_private *portdata; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); portdata = usb_get_serial_port_data(port); portdata->rts_state = 0; @@ -660,7 +660,7 @@ static int sierra_startup(struct usb_serial *serial) int i; int j; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* Set Device mode to D0 */ sierra_set_power_state(serial->dev, 0x0000); @@ -675,7 +675,7 @@ static int sierra_startup(struct usb_serial *serial) portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) { dbg("%s: kmalloc for sierra_port_private (%d) failed!.", - __FUNCTION__, i); + __func__, i); return -ENOMEM; } spin_lock_init(&portdata->lock); @@ -696,7 +696,7 @@ static int sierra_startup(struct usb_serial *serial) urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { dbg("%s: alloc for in port failed.", - __FUNCTION__); + __func__); continue; } /* Fill URB using supplied data. */ @@ -718,7 +718,7 @@ static void sierra_shutdown(struct usb_serial *serial) struct usb_serial_port *port; struct sierra_port_private *portdata; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index f3bbf777c81a..e0b1564de900 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -408,14 +408,14 @@ static int ti_startup(struct usb_serial *serial) dbg("%s - product 0x%4X, num configurations %d, configuration value %d", - __FUNCTION__, le16_to_cpu(dev->descriptor.idProduct), + __func__, le16_to_cpu(dev->descriptor.idProduct), dev->descriptor.bNumConfigurations, dev->actconfig->desc.bConfigurationValue); /* create device structure */ tdev = kzalloc(sizeof(struct ti_device), GFP_KERNEL); if (tdev == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&dev->dev, "%s - out of memory\n", __func__); return -ENOMEM; } mutex_init(&tdev->td_open_close_lock); @@ -425,7 +425,7 @@ static int ti_startup(struct usb_serial *serial) /* determine device type */ if (usb_match_id(serial->interface, ti_id_table_3410)) tdev->td_is_3410 = 1; - dbg("%s - device type is %s", __FUNCTION__, tdev->td_is_3410 ? "3410" : "5052"); + dbg("%s - device type is %s", __func__, tdev->td_is_3410 ? "3410" : "5052"); /* if we have only 1 configuration, download firmware */ if (dev->descriptor.bNumConfigurations == 1) { @@ -459,7 +459,7 @@ static int ti_startup(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); if (tport == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&dev->dev, "%s - out of memory\n", __func__); status = -ENOMEM; goto free_tports; } @@ -471,7 +471,7 @@ static int ti_startup(struct usb_serial *serial) init_waitqueue_head(&tport->tp_write_wait); tport->tp_write_buf = ti_buf_alloc(); if (tport->tp_write_buf == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&dev->dev, "%s - out of memory\n", __func__); kfree(tport); status = -ENOMEM; goto free_tports; @@ -504,7 +504,7 @@ static void ti_shutdown(struct usb_serial *serial) struct ti_device *tdev = usb_get_serial_data(serial); struct ti_port *tport; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i=0; i < serial->num_ports; ++i) { tport = usb_get_serial_port_data(serial->port[i]); @@ -532,7 +532,7 @@ static int ti_open(struct usb_serial_port *port, struct file *file) TI_PIPE_TIMEOUT_ENABLE | (TI_TRANSFER_TIMEOUT << 2)); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return -ENODEV; @@ -557,10 +557,10 @@ static int ti_open(struct usb_serial_port *port, struct file *file) /* start interrupt urb the first time a port is opened on this device */ if (tdev->td_open_port_count == 0) { - dbg("%s - start interrupt in urb", __FUNCTION__); + dbg("%s - start interrupt in urb", __func__); urb = tdev->td_serial->port[0]->interrupt_in_urb; if (!urb) { - dev_err(&port->dev, "%s - no interrupt urb\n", __FUNCTION__); + dev_err(&port->dev, "%s - no interrupt urb\n", __func__); status = -EINVAL; goto release_lock; } @@ -569,40 +569,40 @@ static int ti_open(struct usb_serial_port *port, struct file *file) urb->dev = dev; status = usb_submit_urb(urb, GFP_KERNEL); if (status) { - dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __func__, status); goto release_lock; } } ti_set_termios(port, port->tty->termios); - dbg("%s - sending TI_OPEN_PORT", __FUNCTION__); + dbg("%s - sending TI_OPEN_PORT", __func__); status = ti_command_out_sync(tdev, TI_OPEN_PORT, (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot send open command, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot send open command, %d\n", __func__, status); goto unlink_int_urb; } - dbg("%s - sending TI_START_PORT", __FUNCTION__); + dbg("%s - sending TI_START_PORT", __func__); status = ti_command_out_sync(tdev, TI_START_PORT, (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot send start command, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot send start command, %d\n", __func__, status); goto unlink_int_urb; } - dbg("%s - sending TI_PURGE_PORT", __FUNCTION__); + dbg("%s - sending TI_PURGE_PORT", __func__); status = ti_command_out_sync(tdev, TI_PURGE_PORT, (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __func__, status); goto unlink_int_urb; } status = ti_command_out_sync(tdev, TI_PURGE_PORT, (__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __func__, status); goto unlink_int_urb; } @@ -613,27 +613,27 @@ static int ti_open(struct usb_serial_port *port, struct file *file) ti_set_termios(port, port->tty->termios); - dbg("%s - sending TI_OPEN_PORT (2)", __FUNCTION__); + dbg("%s - sending TI_OPEN_PORT (2)", __func__); status = ti_command_out_sync(tdev, TI_OPEN_PORT, (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __func__, status); goto unlink_int_urb; } - dbg("%s - sending TI_START_PORT (2)", __FUNCTION__); + dbg("%s - sending TI_START_PORT (2)", __func__); status = ti_command_out_sync(tdev, TI_START_PORT, (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); if (status) { - dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __func__, status); goto unlink_int_urb; } /* start read urb */ - dbg("%s - start read urb", __FUNCTION__); + dbg("%s - start read urb", __func__); urb = port->read_urb; if (!urb) { - dev_err(&port->dev, "%s - no read urb\n", __FUNCTION__); + dev_err(&port->dev, "%s - no read urb\n", __func__); status = -EINVAL; goto unlink_int_urb; } @@ -643,7 +643,7 @@ static int ti_open(struct usb_serial_port *port, struct file *file) urb->dev = dev; status = usb_submit_urb(urb, GFP_KERNEL); if (status) { - dev_err(&port->dev, "%s - submit read urb failed, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - submit read urb failed, %d\n", __func__, status); goto unlink_int_urb; } @@ -657,7 +657,7 @@ unlink_int_urb: usb_kill_urb(port->serial->port[0]->interrupt_in_urb); release_lock: mutex_unlock(&tdev->td_open_close_lock); - dbg("%s - exit %d", __FUNCTION__, status); + dbg("%s - exit %d", __func__, status); return status; } @@ -670,7 +670,7 @@ static void ti_close(struct usb_serial_port *port, struct file *file) int status; int do_unlock; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); tdev = usb_get_serial_data(port->serial); tport = usb_get_serial_port_data(port); @@ -687,11 +687,11 @@ static void ti_close(struct usb_serial_port *port, struct file *file) port_number = port->number - port->serial->minor; - dbg("%s - sending TI_CLOSE_PORT", __FUNCTION__); + dbg("%s - sending TI_CLOSE_PORT", __func__); status = ti_command_out_sync(tdev, TI_CLOSE_PORT, (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); if (status) - dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __func__, status); /* if mutex_lock is interrupted, continue anyway */ do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); @@ -704,7 +704,7 @@ static void ti_close(struct usb_serial_port *port, struct file *file) if (do_unlock) mutex_unlock(&tdev->td_open_close_lock); - dbg("%s - exit", __FUNCTION__); + dbg("%s - exit", __func__); } @@ -714,10 +714,10 @@ static int ti_write(struct usb_serial_port *port, const unsigned char *data, struct ti_port *tport = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return 0; } @@ -740,7 +740,7 @@ static int ti_write_room(struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return -ENODEV; @@ -749,7 +749,7 @@ static int ti_write_room(struct usb_serial_port *port) room = ti_buf_space_avail(tport->tp_write_buf); spin_unlock_irqrestore(&tport->tp_lock, flags); - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return room; } @@ -760,7 +760,7 @@ static int ti_chars_in_buffer(struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return -ENODEV; @@ -769,7 +769,7 @@ static int ti_chars_in_buffer(struct usb_serial_port *port) chars = ti_buf_data_avail(tport->tp_write_buf); spin_unlock_irqrestore(&tport->tp_lock, flags); - dbg("%s - returns %d", __FUNCTION__, chars); + dbg("%s - returns %d", __func__, chars); return chars; } @@ -779,14 +779,14 @@ static void ti_throttle(struct usb_serial_port *port) struct ti_port *tport = usb_get_serial_port_data(port); struct tty_struct *tty; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return; tty = port->tty; if (!tty) { - dbg("%s - no tty", __FUNCTION__); + dbg("%s - no tty", __func__); return; } @@ -802,21 +802,21 @@ static void ti_unthrottle(struct usb_serial_port *port) struct tty_struct *tty; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return; tty = port->tty; if (!tty) { - dbg("%s - no tty", __FUNCTION__); + dbg("%s - no tty", __func__); return; } if (I_IXOFF(tty) || C_CRTSCTS(tty)) { status = ti_restart_read(tport, tty); if (status) - dev_err(&port->dev, "%s - cannot restart read, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - cannot restart read, %d\n", __func__, status); } } @@ -828,24 +828,24 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file, struct async_icount cnow; struct async_icount cprev; - dbg("%s - port %d, cmd = 0x%04X", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd = 0x%04X", __func__, port->number, cmd); if (tport == NULL) return -ENODEV; switch (cmd) { case TIOCGSERIAL: - dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCGSERIAL", __func__, port->number); return ti_get_serial_info(tport, (struct serial_struct __user *)arg); break; case TIOCSSERIAL: - dbg("%s - (%d) TIOCSSERIAL", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); return ti_set_serial_info(tport, (struct serial_struct __user *)arg); break; case TIOCMIWAIT: - dbg("%s - (%d) TIOCMIWAIT", __FUNCTION__, port->number); + dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); cprev = tport->tp_icount; while (1) { interruptible_sleep_on(&tport->tp_msr_wait); @@ -866,7 +866,7 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file, break; case TIOCGICOUNT: - dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, tport->tp_icount.rx, tport->tp_icount.tx); + dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, tport->tp_icount.rx, tport->tp_icount.tx); if (copy_to_user((void __user *)arg, &tport->tp_icount, sizeof(tport->tp_icount))) return -EFAULT; return 0; @@ -888,20 +888,20 @@ static void ti_set_termios(struct usb_serial_port *port, int port_number = port->number - port->serial->minor; unsigned int mcr; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); cflag = tty->termios->c_cflag; iflag = tty->termios->c_iflag; - dbg("%s - cflag %08x, iflag %08x", __FUNCTION__, cflag, iflag); - dbg("%s - old clfag %08x, old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag); + dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); + dbg("%s - old clfag %08x, old iflag %08x", __func__, old_termios->c_cflag, old_termios->c_iflag); if (tport == NULL) return; config = kmalloc(sizeof(*config), GFP_KERNEL); if (!config) { - dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&port->dev, "%s - out of memory\n", __func__); return; } @@ -985,7 +985,7 @@ static void ti_set_termios(struct usb_serial_port *port, tty_encode_baud_rate(tty, baud, baud); dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d", - __FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode); + __func__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode); cpu_to_be16s(&config->wBaudRate); cpu_to_be16s(&config->wFlags); @@ -994,7 +994,7 @@ static void ti_set_termios(struct usb_serial_port *port, (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config, sizeof(*config)); if (status) - dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __FUNCTION__, port_number, status); + dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __func__, port_number, status); /* SET_CONFIG asserts RTS and DTR, reset them correctly */ mcr = tport->tp_shadow_mcr; @@ -1003,7 +1003,7 @@ static void ti_set_termios(struct usb_serial_port *port, mcr &= ~(TI_MCR_DTR | TI_MCR_RTS); status = ti_set_mcr(tport, mcr); if (status) - dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __FUNCTION__, port_number, status); + dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __func__, port_number, status); kfree(config); } @@ -1017,7 +1017,7 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file) unsigned int mcr; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return -ENODEV; @@ -1035,7 +1035,7 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file) | ((msr & TI_MSR_RI) ? TIOCM_RI : 0) | ((msr & TI_MSR_DSR) ? TIOCM_DSR : 0); - dbg("%s - 0x%04X", __FUNCTION__, result); + dbg("%s - 0x%04X", __func__, result); return result; } @@ -1048,7 +1048,7 @@ static int ti_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int mcr; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (tport == NULL) return -ENODEV; @@ -1080,7 +1080,7 @@ static void ti_break(struct usb_serial_port *port, int break_state) struct ti_port *tport = usb_get_serial_port_data(port); int status; - dbg("%s - state = %d", __FUNCTION__, break_state); + dbg("%s - state = %d", __func__, break_state); if (tport == NULL) return; @@ -1092,7 +1092,7 @@ static void ti_break(struct usb_serial_port *port, int break_state) TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0); if (status) - dbg("%s - error setting break, %d", __FUNCTION__, status); + dbg("%s - error setting break, %d", __func__, status); } @@ -1111,7 +1111,7 @@ static void ti_interrupt_callback(struct urb *urb) int retval; __u8 msr; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); switch (status) { case 0: @@ -1119,33 +1119,33 @@ static void ti_interrupt_callback(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __FUNCTION__, status); + dbg("%s - urb shutting down, %d", __func__, status); tdev->td_urb_error = 1; return; default: dev_err(dev, "%s - nonzero urb status, %d\n", - __FUNCTION__, status); + __func__, status); tdev->td_urb_error = 1; goto exit; } if (length != 2) { - dbg("%s - bad packet size, %d", __FUNCTION__, length); + dbg("%s - bad packet size, %d", __func__, length); goto exit; } if (data[0] == TI_CODE_HARDWARE_ERROR) { - dev_err(dev, "%s - hardware error, %d\n", __FUNCTION__, data[1]); + dev_err(dev, "%s - hardware error, %d\n", __func__, data[1]); goto exit; } port_number = TI_GET_PORT_FROM_CODE(data[0]); function = TI_GET_FUNC_FROM_CODE(data[0]); - dbg("%s - port_number %d, function %d, data 0x%02X", __FUNCTION__, port_number, function, data[1]); + dbg("%s - port_number %d, function %d, data 0x%02X", __func__, port_number, function, data[1]); if (port_number >= serial->num_ports) { - dev_err(dev, "%s - bad port number, %d\n", __FUNCTION__, port_number); + dev_err(dev, "%s - bad port number, %d\n", __func__, port_number); goto exit; } @@ -1157,17 +1157,17 @@ static void ti_interrupt_callback(struct urb *urb) switch (function) { case TI_CODE_DATA_ERROR: - dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __FUNCTION__, port_number, data[1]); + dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __func__, port_number, data[1]); break; case TI_CODE_MODEM_STATUS: msr = data[1]; - dbg("%s - port %d, msr 0x%02X", __FUNCTION__, port_number, msr); + dbg("%s - port %d, msr 0x%02X", __func__, port_number, msr); ti_handle_new_msr(tport, msr); break; default: - dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __FUNCTION__, data[1]); + dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __func__, data[1]); break; } @@ -1175,7 +1175,7 @@ exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", - __FUNCTION__, retval); + __func__, retval); } @@ -1187,7 +1187,7 @@ static void ti_bulk_in_callback(struct urb *urb) int status = urb->status; int retval = 0; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); switch (status) { case 0: @@ -1195,13 +1195,13 @@ static void ti_bulk_in_callback(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __FUNCTION__, status); + dbg("%s - urb shutting down, %d", __func__, status); tport->tp_tdev->td_urb_error = 1; wake_up_interruptible(&tport->tp_write_wait); return; default: dev_err(dev, "%s - nonzero urb status, %d\n", - __FUNCTION__, status ); + __func__, status ); tport->tp_tdev->td_urb_error = 1; wake_up_interruptible(&tport->tp_write_wait); } @@ -1210,16 +1210,16 @@ static void ti_bulk_in_callback(struct urb *urb) goto exit; if (status) { - dev_err(dev, "%s - stopping read!\n", __FUNCTION__); + dev_err(dev, "%s - stopping read!\n", __func__); return; } if (port->tty && urb->actual_length) { - usb_serial_debug_data(debug, dev, __FUNCTION__, + usb_serial_debug_data(debug, dev, __func__, urb->actual_length, urb->transfer_buffer); if (!tport->tp_is_open) - dbg("%s - port closed, dropping data", __FUNCTION__); + dbg("%s - port closed, dropping data", __func__); else ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer, urb->actual_length); @@ -1241,7 +1241,7 @@ exit: spin_unlock(&tport->tp_lock); if (retval) dev_err(dev, "%s - resubmit read urb failed, %d\n", - __FUNCTION__, retval); + __func__, retval); } @@ -1252,7 +1252,7 @@ static void ti_bulk_out_callback(struct urb *urb) struct device *dev = &urb->dev->dev; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); tport->tp_write_urb_in_use = 0; @@ -1262,13 +1262,13 @@ static void ti_bulk_out_callback(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __FUNCTION__, status); + dbg("%s - urb shutting down, %d", __func__, status); tport->tp_tdev->td_urb_error = 1; wake_up_interruptible(&tport->tp_write_wait); return; default: dev_err(dev, "%s - nonzero urb status, %d\n", - __FUNCTION__, status); + __func__, status); tport->tp_tdev->td_urb_error = 1; wake_up_interruptible(&tport->tp_write_wait); } @@ -1286,7 +1286,7 @@ static void ti_recv(struct device *dev, struct tty_struct *tty, do { cnt = tty_buffer_request_room(tty, length); if (cnt < length) { - dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length - cnt); + dev_err(dev, "%s - dropping data, %d bytes lost\n", __func__, length - cnt); if(cnt == 0) break; } @@ -1307,7 +1307,7 @@ static void ti_send(struct ti_port *tport) unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&tport->tp_lock, flags); @@ -1329,7 +1329,7 @@ static void ti_send(struct ti_port *tport) spin_unlock_irqrestore(&tport->tp_lock, flags); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer); usb_fill_bulk_urb(port->write_urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, @@ -1339,7 +1339,7 @@ static void ti_send(struct ti_port *tport) result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - submit write urb failed, %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - submit write urb failed, %d\n", __func__, result); tport->tp_write_urb_in_use = 0; /* TODO: reschedule ti_send */ } else { @@ -1381,23 +1381,23 @@ static int ti_get_lsr(struct ti_port *tport) int port_number = port->number - port->serial->minor; struct ti_port_status *data; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); size = sizeof(struct ti_port_status); data = kmalloc(size, GFP_KERNEL); if (!data) { - dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&port->dev, "%s - out of memory\n", __func__); return -ENOMEM; } status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS, (__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size); if (status) { - dev_err(&port->dev, "%s - get port status command failed, %d\n", __FUNCTION__, status); + dev_err(&port->dev, "%s - get port status command failed, %d\n", __func__, status); goto free_data; } - dbg("%s - lsr 0x%02X", __FUNCTION__, data->bLSR); + dbg("%s - lsr 0x%02X", __func__, data->bLSR); tport->tp_lsr = data->bLSR; @@ -1458,7 +1458,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) struct tty_struct *tty; unsigned long flags; - dbg("%s - msr 0x%02X", __FUNCTION__, msr); + dbg("%s - msr 0x%02X", __func__, msr); if (msr & TI_MSR_DELTA_MASK) { spin_lock_irqsave(&tport->tp_lock, flags); @@ -1496,7 +1496,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) struct usb_serial_port *port = tport->tp_port; wait_queue_t wait; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irq(&tport->tp_lock); @@ -1628,12 +1628,12 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr, struct ti_write_data_bytes *data; struct device *dev = &tdev->td_serial->dev->dev; - dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __FUNCTION__, addr, mask, byte); + dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __func__, addr, mask, byte); size = sizeof(struct ti_write_data_bytes) + 2; data = kmalloc(size, GFP_KERNEL); if (!data) { - dev_err(dev, "%s - out of memory\n", __FUNCTION__); + dev_err(dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -1649,7 +1649,7 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr, (__u8 *)data, size); if (status < 0) - dev_err(dev, "%s - failed, %d\n", __FUNCTION__, status); + dev_err(dev, "%s - failed, %d\n", __func__, status); kfree(data); @@ -1676,7 +1676,7 @@ static int ti_download_firmware(struct ti_device *tdev, buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header); buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { - dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&dev->dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -1690,7 +1690,7 @@ static int ti_download_firmware(struct ti_device *tdev, header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header))); header->bCheckSum = cs; - dbg("%s - downloading firmware", __FUNCTION__); + dbg("%s - downloading firmware", __func__); for (pos = 0; pos < buffer_size; pos += done) { len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE); status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, 1000); @@ -1701,11 +1701,11 @@ static int ti_download_firmware(struct ti_device *tdev, kfree(buffer); if (status) { - dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __FUNCTION__, status); + dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __func__, status); return status; } - dbg("%s - download successful", __FUNCTION__); + dbg("%s - download successful", __func__); return 0; } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 5b464811fa4d..baf953d14d82 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -81,7 +81,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po unsigned int i, j; int good_spot; - dbg("%s %d", __FUNCTION__, num_ports); + dbg("%s %d", __func__, num_ports); *minor = 0; mutex_lock(&table_lock); @@ -101,7 +101,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po *minor = i; j = 0; - dbg("%s - minor base = %d", __FUNCTION__, *minor); + dbg("%s - minor base = %d", __func__, *minor); for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) { serial_table[i] = serial; serial->port[j++]->number = i; @@ -117,7 +117,7 @@ static void return_serial(struct usb_serial *serial) { int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (serial == NULL) return; @@ -135,7 +135,7 @@ static void destroy_serial(struct kref *kref) serial = to_usb_serial(kref); - dbg("%s - %s", __FUNCTION__, serial->type->description); + dbg("%s - %s", __func__, serial->type->description); serial->type->shutdown(serial); @@ -187,7 +187,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) unsigned int portNumber; int retval; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* get the serial object associated with this tty pointer */ serial = usb_serial_get_by_index(tty->index); @@ -259,7 +259,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) if (!port) return; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); mutex_lock(&port->mutex); @@ -299,11 +299,11 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) goto exit; - dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); + dbg("%s - port %d, %d byte(s)", __func__, port->number, count); if (!port->open_count) { retval = -EINVAL; - dbg("%s - port not opened", __FUNCTION__); + dbg("%s - port not opened", __func__); goto exit; } @@ -322,10 +322,10 @@ static int serial_write_room (struct tty_struct *tty) if (!port) goto exit; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); goto exit; } @@ -344,10 +344,10 @@ static int serial_chars_in_buffer (struct tty_struct *tty) if (!port) goto exit; - dbg("%s = port %d", __FUNCTION__, port->number); + dbg("%s = port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); goto exit; } @@ -365,10 +365,10 @@ static void serial_throttle (struct tty_struct * tty) if (!port) return; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg ("%s - port not open", __FUNCTION__); + dbg ("%s - port not open", __func__); return; } @@ -384,10 +384,10 @@ static void serial_unthrottle (struct tty_struct * tty) if (!port) return; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); return; } @@ -405,11 +405,11 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in if (!port) goto exit; - dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); /* Caution - port->open_count is BKL protected */ if (!port->open_count) { - dbg ("%s - port not open", __FUNCTION__); + dbg ("%s - port not open", __func__); goto exit; } @@ -430,10 +430,10 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) if (!port) return; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); return; } @@ -454,10 +454,10 @@ static void serial_break (struct tty_struct *tty, int break_state) return; } - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); unlock_kernel(); return; } @@ -476,7 +476,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int off_t begin = 0; char tmp[40]; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); length += sprintf (page, "usbserinfo:1.0 driver:2.0\n"); for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { serial = usb_serial_get_by_index(i); @@ -522,10 +522,10 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file) if (!port) return -ENODEV; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); return -ENODEV; } @@ -543,10 +543,10 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file, if (!port) return -ENODEV; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->open_count) { - dbg("%s - port not open", __FUNCTION__); + dbg("%s - port not open", __func__); return -ENODEV; } @@ -572,7 +572,7 @@ static void usb_serial_port_work(struct work_struct *work) container_of(work, struct usb_serial_port, work); struct tty_struct *tty; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port) return; @@ -588,7 +588,7 @@ static void port_release(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); - dbg ("%s - %s", __FUNCTION__, dev->bus_id); + dbg ("%s - %s", __func__, dev->bus_id); port_free(port); } @@ -634,7 +634,7 @@ static struct usb_serial * create_serial (struct usb_device *dev, serial = kzalloc(sizeof(*serial), GFP_KERNEL); if (!serial) { - dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&dev->dev, "%s - out of memory\n", __func__); return NULL; } serial->dev = usb_get_dev(dev); @@ -729,7 +729,7 @@ int usb_serial_probe(struct usb_interface *interface, serial = create_serial (dev, interface, type); if (!serial) { unlock_kernel(); - dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&interface->dev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -874,7 +874,7 @@ int usb_serial_probe(struct usb_interface *interface, serial->num_port_pointers = max_endpoints; unlock_kernel(); - dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); + dbg("%s - setting up %d port structures for this device", __func__, max_endpoints); for (i = 0; i < max_endpoints; ++i) { port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); if (!port) @@ -1022,7 +1022,7 @@ int usb_serial_probe(struct usb_interface *interface, port->dev.release = &port_release; snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number); - dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id); + dbg ("%s - registering %s", __func__, port->dev.bus_id); retval = device_register(&port->dev); if (retval) dev_err(&port->dev, "Error registering port device, " @@ -1081,7 +1081,7 @@ void usb_serial_disconnect(struct usb_interface *interface) struct usb_serial_port *port; usb_serial_console_disconnect(serial); - dbg ("%s", __FUNCTION__); + dbg ("%s", __func__); mutex_lock(&serial->disc_mutex); usb_set_intfdata (interface, NULL); @@ -1165,7 +1165,7 @@ static int __init usb_serial_init(void) result = bus_register(&usb_serial_bus_type); if (result) { - err("%s - registering bus driver failed", __FUNCTION__); + err("%s - registering bus driver failed", __func__); goto exit_bus; } @@ -1182,21 +1182,21 @@ static int __init usb_serial_init(void) tty_set_operations(usb_serial_tty_driver, &serial_ops); result = tty_register_driver(usb_serial_tty_driver); if (result) { - err("%s - tty_register_driver failed", __FUNCTION__); + err("%s - tty_register_driver failed", __func__); goto exit_reg_driver; } /* register the USB driver */ result = usb_register(&usb_serial_driver); if (result < 0) { - err("%s - usb_register failed", __FUNCTION__); + err("%s - usb_register failed", __func__); goto exit_tty; } /* register the generic driver, if we should */ result = usb_serial_generic_register(debug); if (result < 0) { - err("%s - registering generic driver failed", __FUNCTION__); + err("%s - registering generic driver failed", __func__); goto exit_generic; } @@ -1214,7 +1214,7 @@ exit_reg_driver: bus_unregister(&usb_serial_bus_type); exit_bus: - err ("%s - returning with error %d", __FUNCTION__, result); + err ("%s - returning with error %d", __func__, result); put_tty_driver(usb_serial_tty_driver); return result; } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index f2d59b06c364..137df445e296 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -281,7 +281,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) unsigned long flags; int result = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (!port->read_urb) { /* this is needed for some brain dead Sony devices */ @@ -313,16 +313,16 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", - __FUNCTION__, result); + __func__, result); goto exit; } if (port->interrupt_in_urb) { - dbg("%s - adding interrupt input for treo", __FUNCTION__); + dbg("%s - adding interrupt input for treo", __func__); result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n", - __FUNCTION__, result); + __func__, result); } exit: return result; @@ -334,7 +334,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) struct visor_private *priv = usb_get_serial_port_data(port); unsigned char *transfer_buffer; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* shutdown our urbs */ usb_kill_urb(port->read_urb); @@ -370,12 +370,12 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, unsigned long flags; int status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); if (priv->outstanding_urbs > URB_UPPER_LIMIT) { spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } priv->outstanding_urbs++; @@ -397,7 +397,7 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, memcpy (buffer, buf, count); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); usb_fill_bulk_urb (urb, serial->dev, usb_sndbulkpipe (serial->dev, @@ -409,7 +409,7 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", - __FUNCTION__, status); + __func__, status); count = status; goto error; } else { @@ -440,7 +440,7 @@ static int visor_write_room (struct usb_serial_port *port) struct visor_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * We really can take anything the user throws at us @@ -451,7 +451,7 @@ static int visor_write_room (struct usb_serial_port *port) spin_lock_irqsave(&priv->lock, flags); if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - write limit hit\n", __FUNCTION__); + dbg("%s - write limit hit\n", __func__); return 0; } spin_unlock_irqrestore(&priv->lock, flags); @@ -462,7 +462,7 @@ static int visor_write_room (struct usb_serial_port *port) static int visor_chars_in_buffer (struct usb_serial_port *port) { - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); /* * We can't really account for how much data we @@ -484,11 +484,11 @@ static void visor_write_bulk_callback (struct urb *urb) /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree (urb->transfer_buffer); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); spin_lock_irqsave(&priv->lock, flags); --priv->outstanding_urbs; @@ -508,15 +508,15 @@ static void visor_read_bulk_callback (struct urb *urb) int result; int available_room; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { @@ -542,7 +542,7 @@ static void visor_read_bulk_callback (struct urb *urb) visor_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); } else { priv->actually_throttled = 1; } @@ -564,11 +564,11 @@ static void visor_read_int_callback (struct urb *urb) case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", - __FUNCTION__, status); + __func__, status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __func__, status); goto exit; } @@ -579,14 +579,14 @@ static void visor_read_int_callback (struct urb *urb) * Rumor has it this endpoint is used to notify when data * is ready to be read from the bulk ones. */ - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, urb->transfer_buffer); exit: result = usb_submit_urb (urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); + __func__, result); } static void visor_throttle (struct usb_serial_port *port) @@ -594,7 +594,7 @@ static void visor_throttle (struct usb_serial_port *port) struct visor_private *priv = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); priv->throttled = 1; spin_unlock_irqrestore(&priv->lock, flags); @@ -607,7 +607,7 @@ static void visor_unthrottle (struct usb_serial_port *port) unsigned long flags; int result; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&priv->lock, flags); priv->throttled = 0; priv->actually_throttled = 0; @@ -616,7 +616,7 @@ static void visor_unthrottle (struct usb_serial_port *port) port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); } static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id) @@ -629,11 +629,11 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i int i; int num_ports = 0; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__, + dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, sizeof(*connection_info)); return -ENOMEM; } @@ -646,7 +646,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i sizeof(*connection_info), 300); if (retval < 0) { dev_err(dev, "%s - error %d getting connection information\n", - __FUNCTION__, retval); + __func__, retval); goto exit; } @@ -706,7 +706,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i 0x02, 300); if (retval < 0) dev_err(dev, "%s - error %d getting bytes available request\n", - __FUNCTION__, retval); + __func__, retval); retval = 0; exit: @@ -722,11 +722,11 @@ static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_i unsigned char *transfer_buffer; int retval; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL); if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__, + dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, sizeof(*connection_info)); return -ENOMEM; } @@ -738,9 +738,9 @@ static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_i sizeof (*connection_info), 300); if (retval < 0) dev_err(dev, "%s - error %d getting connection info\n", - __FUNCTION__, retval); + __func__, retval); else - usb_serial_debug_data(debug, &serial->dev->dev, __FUNCTION__, + usb_serial_debug_data(debug, &serial->dev->dev, __func__, retval, transfer_buffer); kfree (transfer_buffer); @@ -753,7 +753,7 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i int retval = 0; int (*startup) (struct usb_serial *serial, const struct usb_device_id *id); - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (serial->dev->actconfig->desc.bConfigurationValue != 1) { err("active config #%d != 1 ??", @@ -807,7 +807,7 @@ static int clie_3_5_startup (struct usb_serial *serial) int result; u8 data; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* * Note that PEG-300 series devices expect the following two calls. @@ -818,11 +818,11 @@ static int clie_3_5_startup (struct usb_serial *serial) USB_REQ_GET_CONFIGURATION, USB_DIR_IN, 0, 0, &data, 1, 3000); if (result < 0) { - dev_err(dev, "%s: get config number failed: %d\n", __FUNCTION__, result); + dev_err(dev, "%s: get config number failed: %d\n", __func__, result); return result; } if (result != 1) { - dev_err(dev, "%s: get config number bad return length: %d\n", __FUNCTION__, result); + dev_err(dev, "%s: get config number bad return length: %d\n", __func__, result); return -EIO; } @@ -832,11 +832,11 @@ static int clie_3_5_startup (struct usb_serial *serial) USB_DIR_IN | USB_RECIP_INTERFACE, 0, 0, &data, 1, 3000); if (result < 0) { - dev_err(dev, "%s: get interface number failed: %d\n", __FUNCTION__, result); + dev_err(dev, "%s: get interface number failed: %d\n", __func__, result); return result; } if (result != 1) { - dev_err(dev, "%s: get interface number bad return length: %d\n", __FUNCTION__, result); + dev_err(dev, "%s: get interface number bad return length: %d\n", __func__, result); return -EIO; } @@ -854,7 +854,7 @@ static int treo_attach (struct usb_serial *serial) (serial->num_interrupt_in == 0)) goto generic_startup; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* * It appears that Treos and Kyoceras want to use the @@ -885,7 +885,7 @@ generic_startup: static int clie_5_attach (struct usb_serial *serial) { - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* TH55 registers 2 ports. Communication in from the UX50/TH55 uses bulk_in_endpointAddress from port 0 @@ -909,7 +909,7 @@ static void visor_shutdown (struct usb_serial *serial) struct visor_private *priv; int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); for (i = 0; i < serial->num_ports; i++) { priv = usb_get_serial_port_data(serial->port[i]); @@ -922,7 +922,7 @@ static void visor_shutdown (struct usb_serial *serial) static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) { - dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); return -ENOIOCTLCMD; } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index c5af57be62f4..fb02424de4a0 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -282,7 +282,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct int response; const struct whiteheat_hex_record *record; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); response = ezusb_set_reset (serial, 1); @@ -292,7 +292,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct (unsigned char *)record->data, record->data_size, 0xa0); if (response < 0) { err("%s - ezusb_writememory failed for loader (%d %04X %p %d)", - __FUNCTION__, response, record->address, record->data, record->data_size); + __func__, response, record->address, record->data, record->data_size); break; } ++record; @@ -309,7 +309,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct (unsigned char *)record->data, record->data_size, 0xa3); if (response < 0) { err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", - __FUNCTION__, response, record->address, record->data, record->data_size); + __func__, response, record->address, record->data, record->data_size); break; } ++record; @@ -323,7 +323,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct (unsigned char *)record->data, record->data_size, 0xa0); if (response < 0) { err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", - __FUNCTION__, response, record->address, record->data, record->data_size); + __func__, response, record->address, record->data, record->data_size); break; } ++record; @@ -561,7 +561,7 @@ static void whiteheat_shutdown (struct usb_serial *serial) struct list_head *tmp2; int i; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); /* free up our private data for our command port */ command_port = serial->port[COMMAND_PORT]; @@ -598,7 +598,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) int retval = 0; struct ktermios old_term; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); retval = start_command_port(port->serial); if (retval) @@ -631,14 +631,14 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) /* Start reading from the device */ retval = start_port_read(port); if (retval) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, retval); + err("%s - failed submitting read urb, error %d", __func__, retval); firm_close(port); stop_command_port(port->serial); goto exit; } exit: - dbg("%s - exit, retval = %d", __FUNCTION__, retval); + dbg("%s - exit, retval = %d", __func__, retval); return retval; } @@ -651,7 +651,7 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) struct list_head *tmp; struct list_head *tmp2; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); mutex_lock(&port->serial->disc_mutex); /* filp is NULL when called from usb_serial_disconnect */ @@ -726,10 +726,10 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu unsigned long flags; struct list_head *tmp; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); + dbg("%s - write request of 0 bytes", __func__); return (0); } @@ -748,13 +748,13 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu bytes = (count > port->bulk_out_size) ? port->bulk_out_size : count; memcpy (urb->transfer_buffer, buf + sent, bytes); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, bytes, urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, bytes, urb->transfer_buffer); urb->dev = serial->dev; urb->transfer_buffer_length = bytes; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, result); + err("%s - failed submitting write urb, error %d", __func__, result); sent = result; spin_lock_irqsave(&info->lock, flags); list_add(tmp, &info->tx_urbs_free); @@ -780,7 +780,7 @@ static int whiteheat_write_room(struct usb_serial_port *port) int room = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&info->lock, flags); list_for_each(tmp, &info->tx_urbs_free) @@ -788,7 +788,7 @@ static int whiteheat_write_room(struct usb_serial_port *port) spin_unlock_irqrestore(&info->lock, flags); room *= port->bulk_out_size; - dbg("%s - returns %d", __FUNCTION__, room); + dbg("%s - returns %d", __func__, room); return (room); } @@ -798,7 +798,7 @@ static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file) struct whiteheat_private *info = usb_get_serial_port_data(port); unsigned int modem_signals = 0; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); firm_get_dtr_rts(port); if (info->mcr & UART_MCR_DTR) @@ -815,7 +815,7 @@ static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, { struct whiteheat_private *info = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); if (set & TIOCM_RTS) info->mcr |= UART_MCR_RTS; @@ -838,7 +838,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un struct serial_struct serstruct; void __user *user_arg = (void __user *)arg; - dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); switch (cmd) { case TIOCGSERIAL: @@ -880,7 +880,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { - dbg("%s -port %d", __FUNCTION__, port->number); + dbg("%s -port %d", __func__, port->number); firm_setup_port(port); } @@ -898,7 +898,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port) int chars = 0; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&info->lock, flags); list_for_each(tmp, &info->tx_urbs_submitted) { @@ -907,7 +907,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port) } spin_unlock_irqrestore(&info->lock, flags); - dbg ("%s - returns %d", __FUNCTION__, chars); + dbg ("%s - returns %d", __func__, chars); return chars; } @@ -917,7 +917,7 @@ static void whiteheat_throttle (struct usb_serial_port *port) struct whiteheat_private *info = usb_get_serial_port_data(port); unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&info->lock, flags); info->flags |= THROTTLED; @@ -933,7 +933,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port) int actually_throttled; unsigned long flags; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock_irqsave(&info->lock, flags); actually_throttled = info->flags & ACTUALLY_THROTTLED; @@ -954,7 +954,7 @@ static void command_port_write_callback(struct urb *urb) { int status = urb->status; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (status) { dbg("nonzero urb status: %d", status); @@ -971,22 +971,22 @@ static void command_port_read_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int result; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); command_info = usb_get_serial_port_data(command_port); if (!command_info) { - dbg ("%s - command_info is NULL, exiting.", __FUNCTION__); + dbg ("%s - command_info is NULL, exiting.", __func__); return; } if (status) { - dbg("%s - nonzero urb status: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status: %d", __func__, status); if (status != -ENOENT) command_info->command_finished = WHITEHEAT_CMD_FAILURE; wake_up(&command_info->wait_command); return; } - usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &command_port->dev, __func__, urb->actual_length, data); if (data[0] == WHITEHEAT_CMD_COMPLETE) { command_info->command_finished = WHITEHEAT_CMD_COMPLETE; @@ -996,20 +996,20 @@ static void command_port_read_callback(struct urb *urb) wake_up(&command_info->wait_command); } else if (data[0] == WHITEHEAT_EVENT) { /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */ - dbg("%s - event received", __FUNCTION__); + dbg("%s - event received", __func__); } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1); command_info->command_finished = WHITEHEAT_CMD_COMPLETE; wake_up(&command_info->wait_command); } else { - dbg("%s - bad reply from firmware", __FUNCTION__); + dbg("%s - bad reply from firmware", __func__); } /* Continue trying to always read */ command_port->read_urb->dev = command_port->serial->dev; result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC); if (result) - dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + dbg("%s - failed resubmitting read urb, error %d", __func__, result); } @@ -1021,13 +1021,13 @@ static void whiteheat_read_callback(struct urb *urb) struct whiteheat_private *info = usb_get_serial_port_data(port); int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock(&info->lock); wrap = urb_to_wrap(urb, &info->rx_urbs_submitted); if (!wrap) { spin_unlock(&info->lock); - err("%s - Not my urb!", __FUNCTION__); + err("%s - Not my urb!", __func__); return; } list_del(&wrap->list); @@ -1035,14 +1035,14 @@ static void whiteheat_read_callback(struct urb *urb) if (status) { dbg("%s - nonzero read bulk status received: %d", - __FUNCTION__, status); + __func__, status); spin_lock(&info->lock); list_add(&wrap->list, &info->rx_urbs_free); spin_unlock(&info->lock); return; } - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); spin_lock(&info->lock); list_add_tail(&wrap->list, &info->rx_urb_q); @@ -1064,13 +1064,13 @@ static void whiteheat_write_callback(struct urb *urb) struct whiteheat_urb_wrap *wrap; int status = urb->status; - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); spin_lock(&info->lock); wrap = urb_to_wrap(urb, &info->tx_urbs_submitted); if (!wrap) { spin_unlock(&info->lock); - err("%s - Not my urb!", __FUNCTION__); + err("%s - Not my urb!", __func__); return; } list_move(&wrap->list, &info->tx_urbs_free); @@ -1078,7 +1078,7 @@ static void whiteheat_write_callback(struct urb *urb) if (status) { dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __func__, status); return; } @@ -1098,7 +1098,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d int retval = 0; int t; - dbg("%s - command %d", __FUNCTION__, command); + dbg("%s - command %d", __func__, command); command_port = port->serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); @@ -1112,7 +1112,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d command_port->write_urb->dev = port->serial->dev; retval = usb_submit_urb (command_port->write_urb, GFP_NOIO); if (retval) { - dbg("%s - submit urb failed", __FUNCTION__); + dbg("%s - submit urb failed", __func__); goto exit; } @@ -1123,19 +1123,19 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d usb_kill_urb(command_port->write_urb); if (command_info->command_finished == false) { - dbg("%s - command timed out.", __FUNCTION__); + dbg("%s - command timed out.", __func__); retval = -ETIMEDOUT; goto exit; } if (command_info->command_finished == WHITEHEAT_CMD_FAILURE) { - dbg("%s - command failed.", __FUNCTION__); + dbg("%s - command failed.", __func__); retval = -EIO; goto exit; } if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) { - dbg("%s - command completed.", __FUNCTION__); + dbg("%s - command completed.", __func__); switch (command) { case WHITEHEAT_GET_DTR_RTS: info = usb_get_serial_port_data(port); @@ -1180,7 +1180,7 @@ static int firm_setup_port(struct usb_serial_port *port) { default: case CS8: port_settings.bits = 8; break; } - dbg("%s - data bits = %d", __FUNCTION__, port_settings.bits); + dbg("%s - data bits = %d", __func__, port_settings.bits); /* determine the parity */ if (cflag & PARENB) @@ -1196,21 +1196,21 @@ static int firm_setup_port(struct usb_serial_port *port) { port_settings.parity = WHITEHEAT_PAR_EVEN; else port_settings.parity = WHITEHEAT_PAR_NONE; - dbg("%s - parity = %c", __FUNCTION__, port_settings.parity); + dbg("%s - parity = %c", __func__, port_settings.parity); /* figure out the stop bits requested */ if (cflag & CSTOPB) port_settings.stop = 2; else port_settings.stop = 1; - dbg("%s - stop bits = %d", __FUNCTION__, port_settings.stop); + dbg("%s - stop bits = %d", __func__, port_settings.stop); /* figure out the flow control settings */ if (cflag & CRTSCTS) port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS); else port_settings.hflow = WHITEHEAT_HFLOW_NONE; - dbg("%s - hardware flow control = %s %s %s %s", __FUNCTION__, + dbg("%s - hardware flow control = %s %s %s %s", __func__, (port_settings.hflow & WHITEHEAT_HFLOW_CTS) ? "CTS" : "", (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "", (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "", @@ -1221,15 +1221,15 @@ static int firm_setup_port(struct usb_serial_port *port) { port_settings.sflow = WHITEHEAT_SFLOW_RXTX; else port_settings.sflow = WHITEHEAT_SFLOW_NONE; - dbg("%s - software flow control = %c", __FUNCTION__, port_settings.sflow); + dbg("%s - software flow control = %c", __func__, port_settings.sflow); port_settings.xon = START_CHAR(port->tty); port_settings.xoff = STOP_CHAR(port->tty); - dbg("%s - XON = %2x, XOFF = %2x", __FUNCTION__, port_settings.xon, port_settings.xoff); + dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff); /* get the baud rate wanted */ port_settings.baud = tty_get_baud_rate(port->tty); - dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud); + dbg("%s - baud rate = %d", __func__, port_settings.baud); /* fixme: should set validated settings */ tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud); @@ -1312,7 +1312,7 @@ static int start_command_port(struct usb_serial *serial) command_port->read_urb->dev = serial->dev; retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL); if (retval) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, retval); + err("%s - failed submitting read urb, error %d", __func__, retval); goto exit; } } @@ -1448,7 +1448,7 @@ static void rx_data_softint(struct work_struct *work) urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); + err("%s - failed resubmitting read urb, error %d", __func__, result); spin_lock_irqsave(&info->lock, flags); list_add(tmp, &info->rx_urbs_free); continue; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 521f0297aef9..3fcde9f0fa5f 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -228,12 +228,12 @@ static int queuecommand(struct scsi_cmnd *srb, { struct us_data *us = host_to_us(srb->device->host); - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* check for state-transition errors */ if (us->srb != NULL) { printk(KERN_ERR USB_STORAGE "Error in %s: us->srb = %p\n", - __FUNCTION__, us->srb); + __func__, us->srb); return SCSI_MLQUEUE_HOST_BUSY; } @@ -262,7 +262,7 @@ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING * bits are protected by the host lock. */ @@ -299,7 +299,7 @@ static int device_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* lock the device pointers and do the reset */ mutex_lock(&(us->dev_mutex)); @@ -315,7 +315,7 @@ static int bus_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); result = usb_stor_port_reset(us); return result < 0 ? FAILED : SUCCESS; } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 4628f03b13bf..db55ec39bb83 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -198,7 +198,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, int status; US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", - __FUNCTION__, request, requesttype, + __func__, request, requesttype, value, index, size); /* fill in the devrequest structure */ @@ -250,7 +250,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); - US_DEBUGP("%s: result = %d\n", __FUNCTION__, result); + US_DEBUGP("%s: result = %d\n", __func__, result); return result; } @@ -332,7 +332,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, int result; US_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", - __FUNCTION__, request, requesttype, + __func__, request, requesttype, value, index, size); /* fill in the devrequest structure */ @@ -366,7 +366,7 @@ static int usb_stor_intr_transfer(struct us_data *us, void *buf, unsigned int pipe = us->recv_intr_pipe; unsigned int maxp; - US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length); + US_DEBUGP("%s: xfer %u bytes\n", __func__, length); /* calculate the max packet size */ maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)); @@ -393,7 +393,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, { int result; - US_DEBUGP("%s: xfer %u bytes\n", __FUNCTION__, length); + US_DEBUGP("%s: xfer %u bytes\n", __func__, length); /* fill and submit the URB */ usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length, @@ -424,7 +424,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, return USB_STOR_XFER_ERROR; /* initialize the scatter-gather request block */ - US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, + US_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, length, num_sg); result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, GFP_NOIO); @@ -701,7 +701,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* Stop the current URB transfer */ void usb_stor_stop_transport(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); /* If the state machine is blocked waiting for an URB, * let's wake it up. The test_and_clear_bit() call @@ -1135,7 +1135,7 @@ static int usb_stor_reset_common(struct us_data *us, int usb_stor_CB_reset(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); memset(us->iobuf, 0xFF, CB_RESET_CMD_SIZE); us->iobuf[0] = SEND_DIAGNOSTIC; @@ -1150,7 +1150,7 @@ int usb_stor_CB_reset(struct us_data *us) */ int usb_stor_Bulk_reset(struct us_data *us) { - US_DEBUGP("%s called\n", __FUNCTION__); + US_DEBUGP("%s called\n", __func__); return usb_stor_reset_common(us, US_BULK_RESET_REQUEST, USB_TYPE_CLASS | USB_RECIP_INTERFACE, diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index f59593de3b8f..a856effad3bd 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -190,7 +190,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) /* Wait until no command is running */ mutex_lock(&us->dev_mutex); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_SUSPEND); @@ -207,7 +207,7 @@ static int storage_resume(struct usb_interface *iface) mutex_lock(&us->dev_mutex); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_RESUME); @@ -219,7 +219,7 @@ static int storage_reset_resume(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Report the reset to the SCSI core */ usb_stor_report_bus_reset(us); @@ -240,7 +240,7 @@ static int storage_pre_reset(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Make sure no command runs during the reset */ mutex_lock(&us->dev_mutex); @@ -251,7 +251,7 @@ static int storage_post_reset(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - US_DEBUGP("%s\n", __FUNCTION__); + US_DEBUGP("%s\n", __func__); /* Report the reset to the SCSI core */ usb_stor_report_bus_reset(us); @@ -437,7 +437,7 @@ SkipForAbort: /* Associate our private data with the USB device */ static int associate_dev(struct us_data *us, struct usb_interface *intf) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); /* Fill in the device-related fields */ us->pusb_dev = interface_to_usbdev(intf); @@ -816,7 +816,7 @@ static int usb_stor_acquire_resources(struct us_data *us) /* Release all our dynamic resources */ static void usb_stor_release_resources(struct us_data *us) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); /* Tell the control thread to exit. The SCSI host must * already have been removed so it won't try to queue @@ -842,7 +842,7 @@ static void usb_stor_release_resources(struct us_data *us) /* Dissociate from the USB device */ static void dissociate_dev(struct us_data *us) { - US_DEBUGP("-- %s\n", __FUNCTION__); + US_DEBUGP("-- %s\n", __func__); kfree(us->sensebuf); diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index c815a40e167f..73e6a66d95a7 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -88,7 +88,7 @@ static int skel_open(struct inode *inode, struct file *file) interface = usb_find_interface(&skel_driver, subminor); if (!interface) { err ("%s - error, can't find device for minor %d", - __FUNCTION__, subminor); + __func__, subminor); retval = -ENODEV; goto exit; } @@ -220,7 +220,7 @@ static void skel_write_bulk_callback(struct urb *urb) urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) err("%s - nonzero write bulk status received: %d", - __FUNCTION__, urb->status); + __func__, urb->status); spin_lock(&dev->err_lock); dev->errors = urb->status; @@ -301,7 +301,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou retval = usb_submit_urb(urb, GFP_KERNEL); mutex_unlock(&dev->io_mutex); if (retval) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); + err("%s - failed submitting write urb, error %d", __func__, retval); goto error_unanchor; } -- cgit v1.2.2 From a5b6f60c5a30c494017c7a2d11c4067f90d3d0df Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 8 Apr 2008 17:16:06 +0100 Subject: usb serial: more fixes and groundwork for tty changes - If a termios change fails due to lack of memory we should copy the old settings back over as the device has not changed - Note various locking problems - kl5kusb105 had various remaining tty flag handling problems - Make safe_serial use tty_insert_flip_string not open coded loops - set termios speed properly in usb_serial Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ark3116.c | 1 + drivers/usb/serial/cyberjack.c | 31 +++++++++++++++--------------- drivers/usb/serial/generic.c | 5 +++-- drivers/usb/serial/keyspan.c | 19 ++++++++++--------- drivers/usb/serial/keyspan_pda.c | 9 +++++++-- drivers/usb/serial/kl5kusb105.c | 41 ++++++++++++++++++++++++---------------- drivers/usb/serial/mos7720.c | 1 + drivers/usb/serial/navman.c | 10 +++++----- drivers/usb/serial/omninet.c | 3 ++- drivers/usb/serial/option.c | 3 +++ drivers/usb/serial/pl2303.c | 2 ++ drivers/usb/serial/safe_serial.c | 27 +++++++++++--------------- drivers/usb/serial/sierra.c | 2 ++ drivers/usb/serial/usb-serial.c | 2 ++ drivers/usb/serial/visor.c | 2 ++ drivers/usb/serial/whiteheat.c | 2 +- 16 files changed, 93 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 9d708b22e955..599ab2e548a7 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -192,6 +192,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, buf = kmalloc(1, GFP_KERNEL); if (!buf) { dbg("error kmalloc"); + *port->tty->termios = *old_termios; return; } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 5348e97b52b5..d077534ceaeb 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -151,7 +151,7 @@ static void cyberjack_shutdown (struct usb_serial *serial) dbg("%s", __func__); - for (i=0; i < serial->num_ports; ++i) { + for (i = 0; i < serial->num_ports; ++i) { usb_kill_urb(serial->port[i]->interrupt_in_urb); /* My special items, the standard routines free my urbs */ kfree(usb_get_serial_port_data(serial->port[i])); @@ -209,7 +209,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b if (count == 0) { dbg("%s - write request of 0 bytes", __func__); - return (0); + return 0; } spin_lock_bh(&port->lock); @@ -223,12 +223,12 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b spin_lock_irqsave(&priv->lock, flags); - if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) { + if( (count+priv->wrfilled) > sizeof(priv->wrbuf) ) { /* To much data for buffer. Reset buffer. */ - priv->wrfilled=0; - spin_unlock_irqrestore(&priv->lock, flags); + priv->wrfilled = 0; port->write_urb_busy = 0; - return (0); + spin_unlock_irqrestore(&priv->lock, flags); + return 0; } /* Copy data */ @@ -269,8 +269,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b if (result) { err("%s - failed submitting write urb, error %d", __func__, result); /* Throw away data. No better idea what to do with it. */ - priv->wrfilled=0; - priv->wrsent=0; + priv->wrfilled = 0; + priv->wrsent = 0; spin_unlock_irqrestore(&priv->lock, flags); port->write_urb_busy = 0; return 0; @@ -282,8 +282,8 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b if( priv->wrsent>=priv->wrfilled ) { dbg("%s - buffer cleaned", __func__); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); - priv->wrfilled=0; - priv->wrsent=0; + priv->wrfilled = 0; + priv->wrsent = 0; } } @@ -294,6 +294,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b static int cyberjack_write_room( struct usb_serial_port *port ) { + /* FIXME: .... */ return CYBERJACK_LOCAL_BUF_SIZE; } @@ -314,7 +315,7 @@ static void cyberjack_read_int_callback( struct urb *urb ) usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); /* React only to interrupts signaling a bulk_in transfer */ - if( (urb->actual_length==4) && (data[0]==0x01) ) { + if( (urb->actual_length == 4) && (data[0] == 0x01) ) { short old_rdtodo; /* This is a announcement of coming bulk_ins. */ @@ -450,8 +451,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb) if (result) { err("%s - failed submitting write urb, error %d", __func__, result); /* Throw away data. No better idea what to do with it. */ - priv->wrfilled=0; - priv->wrsent=0; + priv->wrfilled = 0; + priv->wrsent = 0; goto exit; } @@ -463,8 +464,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb) if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) { dbg("%s - buffer cleaned", __func__); memset( priv->wrbuf, 0, sizeof(priv->wrbuf) ); - priv->wrfilled=0; - priv->wrsent=0; + priv->wrfilled = 0; + priv->wrsent = 0; } } diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 2078667db4aa..65765ce76251 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -262,13 +262,14 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) dbg("%s - port %d", __func__, port->number); + /* FIXME: Locking */ if (serial->num_bulk_out) { if (!(port->write_urb_busy)) room = port->bulk_out_size; } dbg("%s - returns %d", __func__, room); - return (room); + return room; } int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) @@ -278,6 +279,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) dbg("%s - port %d", __func__, port->number); + /* FIXME: Locking */ if (serial->num_bulk_out) { if (port->write_urb_busy) chars = port->write_urb->transfer_buffer_length; @@ -368,7 +370,6 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb) __func__, status); return; } - usb_serial_port_softint(port); } EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 857c5312555a..0d122feb2b22 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1187,6 +1187,7 @@ static int keyspan_write_room (struct usb_serial_port *port) p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; + /* FIXME: locking */ if (d_details->msg_format == msg_usa90) data_len = 64; else @@ -1203,13 +1204,13 @@ static int keyspan_write_room (struct usb_serial_port *port) if (this_urb->status != -EINPROGRESS) return (data_len); } - return (0); + return 0; } static int keyspan_chars_in_buffer (struct usb_serial_port *port) { - return (0); + return 0; } @@ -1289,7 +1290,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) //mdelay(100); //keyspan_set_termios(port, NULL); - return (0); + return 0; } static inline void stop_urb(struct urb *urb) @@ -2006,7 +2007,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, } #endif - return (0); + return 0; } static int keyspan_usa28_send_setup(struct usb_serial *serial, @@ -2131,7 +2132,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, } #endif - return (0); + return 0; } static int keyspan_usa49_send_setup(struct usb_serial *serial, @@ -2317,7 +2318,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, } #endif - return (0); + return 0; } static int keyspan_usa90_send_setup(struct usb_serial *serial, @@ -2455,7 +2456,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial, if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); } - return (0); + return 0; } static int keyspan_usa67_send_setup(struct usb_serial *serial, @@ -2603,7 +2604,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial, if (err != 0) dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); - return (0); + return 0; } static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) @@ -2696,7 +2697,7 @@ static int keyspan_startup (struct usb_serial *serial) err); } - return (0); + return 0; } static void keyspan_shutdown (struct usb_serial *serial) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 6ce292ef1c47..b650fb4754b4 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -636,14 +636,19 @@ static int keyspan_pda_write_room (struct usb_serial_port *port) static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) { struct keyspan_pda_private *priv; + unsigned long flags; + int ret = 0; priv = usb_get_serial_port_data(port); /* when throttled, return at least WAKEUP_CHARS to tell select() (via n_tty.c:normal_poll() ) that we're not writeable. */ + + spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy || priv->tx_throttled) - return 256; - return 0; + ret = 256; + spin_unlock_irqrestore(&port->lock, flags); + return ret; } diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 160e19263e25..b3ac045ab408 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -702,12 +702,14 @@ static void klsi_105_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { struct klsi_105_private *priv = usb_get_serial_port_data(port); - unsigned int iflag = port->tty->termios->c_iflag; + struct tty_struct *tty = port->tty; + unsigned int iflag = tty->termios->c_iflag; unsigned int old_iflag = old_termios->c_iflag; - unsigned int cflag = port->tty->termios->c_cflag; + unsigned int cflag = tty->termios->c_cflag; unsigned int old_cflag = old_termios->c_cflag; struct klsi_105_port_settings cfg; unsigned long flags; + speed_t baud; /* lock while we are modifying the settings */ spin_lock_irqsave (&priv->lock, flags); @@ -715,6 +717,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, /* * Update baud rate */ + baud = tty_get_baud_rate(tty); + if( (cflag & CBAUD) != (old_cflag & CBAUD) ) { /* reassert DTR and (maybe) RTS on transition from B0 */ if( (old_cflag & CBAUD) == B0 ) { @@ -728,8 +732,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, mct_u232_set_modem_ctrl(serial, priv->control_state); #endif } - - switch(tty_get_baud_rate(port->tty)) { + } + switch(baud) { case 0: /* handled below */ break; case 1200: @@ -757,25 +761,26 @@ static void klsi_105_set_termios (struct usb_serial_port *port, priv->cfg.baudrate = kl5kusb105a_sio_b115200; break; default: - err("KLSI USB->Serial converter:" + dbg("KLSI USB->Serial converter:" " unsupported baudrate request, using default" " of 9600"); priv->cfg.baudrate = kl5kusb105a_sio_b9600; + baud = 9600; break; - } - if ((cflag & CBAUD) == B0 ) { - dbg("%s: baud is B0", __func__); - /* Drop RTS and DTR */ - /* maybe this should be simulated by sending read - * disable and read enable messages? - */ - ; + } + if ((cflag & CBAUD) == B0 ) { + dbg("%s: baud is B0", __func__); + /* Drop RTS and DTR */ + /* maybe this should be simulated by sending read + * disable and read enable messages? + */ + ; #if 0 - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, priv->control_state); + priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); + mct_u232_set_modem_ctrl(serial, priv->control_state); #endif - } } + tty_encode_baud_rate(tty, baud, baud); if ((cflag & CSIZE) != (old_cflag & CSIZE)) { /* set the number of data bits */ @@ -807,6 +812,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) { + /* Not currently supported */ + tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB); #if 0 priv->last_lcr = 0; @@ -834,6 +841,8 @@ static void klsi_105_set_termios (struct usb_serial_port *port, || (iflag & IXON) != (old_iflag & IXON) || (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) { + /* Not currently supported */ + tty->termios->c_cflag &= ~CRTSCTS; /* Drop DTR/RTS if no flow control otherwise assert */ #if 0 if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) ) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 74b889bf19cf..50f1fe263338 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -635,6 +635,7 @@ static int mos7720_write_room(struct usb_serial_port *port) return -ENODEV; } + /* FIXME: Locking */ for (i = 0; i < NUM_URBS; ++i) { if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) room += URB_TRANSFER_BUFFER_SIZE; diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 7cea325d577c..43c8894353bf 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -6,6 +6,10 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. + * + * TODO: + * Add termios method that uses copy_hw but also kills all echo + * flags as the navman is rx only so cannot echo. */ #include @@ -106,12 +110,8 @@ static int navman_write(struct usb_serial_port *port, /* * This device can't write any data, only read from the device - * so we just silently eat all data sent to us and say it was - * successfully sent. - * Evil, I know, but do you have a better idea? */ - - return count; + return -EOPNOTSUPP; } static struct usb_serial_driver navman_device = { diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 1b041c59aab2..10090cb52d31 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -295,8 +295,9 @@ static int omninet_write_room (struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct usb_serial_port *wport = serial->port[1]; - int room = 0; // Default: no room + int room = 0; /* Default: no room */ + /* FIXME: no consistent locking for write_urb_busy */ if (wport->write_urb_busy) room = wport->bulk_out_size - OMNINET_HEADERLEN; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 920241897c95..a83892627d66 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -656,6 +656,7 @@ static int option_write_room(struct usb_serial_port *port) portdata = usb_get_serial_port_data(port); + for (i=0; i < N_OUT_URB; i++) { this_urb = portdata->out_urbs[i]; if (this_urb && !test_bit(i, &portdata->out_busy)) @@ -677,6 +678,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port) for (i=0; i < N_OUT_URB; i++) { this_urb = portdata->out_urbs[i]; + /* FIXME: This locking is insufficient as this_urb may + go unused during the test */ if (this_urb && test_bit(i, &portdata->out_busy)) data_len += this_urb->transfer_buffer_length; } diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 2b4ab371c762..c60930ec9341 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -546,6 +546,8 @@ static void pl2303_set_termios(struct usb_serial_port *port, buf = kzalloc(7, GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __func__); + /* Report back no change occurred */ + *port->tty->termios = *old_termios; return; } diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 3fe98a52b914..e6acac49a9c8 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -198,7 +198,6 @@ static void safe_read_bulk_callback (struct urb *urb) struct usb_serial_port *port = (struct usb_serial_port *) urb->context; unsigned char *data = urb->transfer_buffer; unsigned char length = urb->actual_length; - int i; int result; int status = urb->status; @@ -227,16 +226,10 @@ static void safe_read_bulk_callback (struct urb *urb) if (safe) { __u16 fcs; if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) { - int actual_length = data[length - 2] >> 2; - if (actual_length <= (length - 2)) { - info ("%s - actual: %d", __func__, actual_length); - - for (i = 0; i < actual_length; i++) { - tty_insert_flip_char (port->tty, data[i], 0); - } + tty_insert_flip_string(port->tty, data, actual_length); tty_flip_buffer_push (port->tty); } else { err ("%s - inconsistent lengths %d:%d", __func__, @@ -246,9 +239,7 @@ static void safe_read_bulk_callback (struct urb *urb) err ("%s - bad CRC %x", __func__, fcs); } } else { - for (i = 0; i < length; i++) { - tty_insert_flip_char (port->tty, data[i], 0); - } + tty_insert_flip_string(port->tty, data, length); tty_flip_buffer_push (port->tty); } @@ -260,6 +251,7 @@ static void safe_read_bulk_callback (struct urb *urb) if ((result = usb_submit_urb (urb, GFP_ATOMIC))) { err ("%s - failed resubmitting read urb, error %d", __func__, result); + /* FIXME: Need a mechanism to retry later if this happens */ } } @@ -275,7 +267,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i if (!port->write_urb) { dbg ("%s - write urb NULL", __func__); - return (0); + return 0; } dbg ("safe_write write_urb: %d transfer_buffer_length", @@ -283,11 +275,11 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i if (!port->write_urb->transfer_buffer_length) { dbg ("%s - write urb transfer_buffer_length zero", __func__); - return (0); + return 0; } if (count == 0) { dbg ("%s - write request of 0 bytes", __func__); - return (0); + return 0; } spin_lock_bh(&port->lock); if (port->write_urb_busy) { @@ -359,18 +351,21 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i static int safe_write_room (struct usb_serial_port *port) { - int room = 0; // Default: no room + int room = 0; /* Default: no room */ + unsigned long flags; dbg ("%s", __func__); + spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy) room = port->bulk_out_size - (safe ? 2 : 0); + spin_unlock_irqrestore(&port->lock, flags); if (room) { dbg ("safe_write_room returns %d", room); } - return (room); + return room; } static int safe_startup (struct usb_serial *serial) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ed30adefff85..23188873eb07 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -566,6 +566,8 @@ static int sierra_chars_in_buffer(struct usb_serial_port *port) * have sent out, but hasn't made it through to the * device as we can't see the backend here, so just * tell the tty layer that everything is flushed. + * + * FIXME: should walk the outstanding urbs info */ return 0; } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index baf953d14d82..a9934a3f9845 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1179,6 +1179,8 @@ static int __init usb_serial_init(void) usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; usb_serial_tty_driver->init_termios = tty_std_termios; usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + usb_serial_tty_driver->init_termios.c_ispeed = 9600; + usb_serial_tty_driver->init_termios.c_ospeed = 9600; tty_set_operations(usb_serial_tty_driver, &serial_ops); result = tty_register_driver(usb_serial_tty_driver); if (result) { diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 137df445e296..a100a52a376e 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -469,6 +469,8 @@ static int visor_chars_in_buffer (struct usb_serial_port *port) * have sent out, but hasn't made it through to the * device, so just tell the tty layer that everything * is flushed. + * + * FIXME: Should walk outstanding_urbs */ return 0; } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index fb02424de4a0..6926a81a0ccd 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -219,7 +219,7 @@ struct whiteheat_urb_wrap { struct whiteheat_private { spinlock_t lock; __u8 flags; - __u8 mcr; + __u8 mcr; /* FIXME: no locking on mcr */ struct list_head rx_urbs_free; struct list_head rx_urbs_submitted; struct list_head rx_urb_q; -- cgit v1.2.2 From cdc97792289179974af6dda781c855696358d307 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 24 Feb 2008 18:41:47 +0800 Subject: USB: remove unnecessary type casting of urb->context urb->context code cleanup Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 2 +- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/misc/auerswald.c | 12 ++++++------ drivers/usb/misc/ftdi-elan.c | 2 +- drivers/usb/misc/iowarrior.c | 4 ++-- drivers/usb/misc/legousbtower.c | 4 ++-- drivers/usb/misc/usblcd.c | 2 +- drivers/usb/misc/usbtest.c | 4 ++-- drivers/usb/serial/belkin_sa.c | 2 +- drivers/usb/serial/cyberjack.c | 6 +++--- drivers/usb/serial/cypress_m8.c | 4 ++-- drivers/usb/serial/digi_acceleport.c | 8 ++++---- drivers/usb/serial/empeg.c | 2 +- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/garmin_gps.c | 6 +++--- drivers/usb/serial/generic.c | 4 ++-- drivers/usb/serial/io_edgeport.c | 8 ++++---- drivers/usb/serial/io_ti.c | 6 +++--- drivers/usb/serial/ipaq.c | 4 ++-- drivers/usb/serial/ir-usb.c | 4 ++-- drivers/usb/serial/iuu_phoenix.c | 16 ++++++++-------- drivers/usb/serial/keyspan.c | 28 ++++++++++++++-------------- drivers/usb/serial/keyspan_pda.c | 4 ++-- drivers/usb/serial/kl5kusb105.c | 4 ++-- drivers/usb/serial/mct_u232.c | 2 +- drivers/usb/serial/mos7840.c | 8 ++++---- drivers/usb/serial/omninet.c | 4 ++-- drivers/usb/serial/option.c | 6 +++--- drivers/usb/serial/oti6858.c | 6 +++--- drivers/usb/serial/pl2303.c | 6 +++--- drivers/usb/serial/safe_serial.c | 2 +- drivers/usb/serial/sierra.c | 4 ++-- drivers/usb/serial/ti_usb_3410_5052.c | 6 +++--- drivers/usb/serial/visor.c | 6 +++--- drivers/usb/serial/whiteheat.c | 6 +++--- drivers/usb/storage/transport.c | 2 +- drivers/usb/usb-skeleton.c | 2 +- 37 files changed, 101 insertions(+), 101 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index a51eeedc18d4..d470c72b737e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -444,7 +444,7 @@ CXACRU_ALL_FILES(INIT); /* the following three functions are stolen from drivers/usb/core/message.c */ static void cxacru_blocking_completion(struct urb *urb) { - complete((struct completion *)urb->context); + complete(urb->context); } static void cxacru_timeout_kill(unsigned long data) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 33cdf8fa2f20..7b572e75e73c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -443,7 +443,7 @@ urbs: static void acm_write_bulk(struct urb *urb) { struct acm *acm; - struct acm_wb *wb = (struct acm_wb *)urb->context; + struct acm_wb *wb = urb->context; dbg("Entering acm_write_bulk with status %d", urb->status); diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 309c743a09d5..093938697426 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -284,7 +284,7 @@ static void auerchain_complete (struct urb * urb) int result; /* get pointer to element and to chain */ - pauerchainelement_t acep = (pauerchainelement_t) urb->context; + pauerchainelement_t acep = urb->context; pauerchain_t acp = acep->chain; /* restore original entries in urb */ @@ -594,7 +594,7 @@ ac_fail:/* free the elements */ /* completion handler for synchronous chained URBs */ static void auerchain_blocking_completion (struct urb *urb) { - pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context; + pauerchain_chs_t pchs = urb->context; pchs->done = 1; wmb(); wake_up (&pchs->wqh); @@ -847,7 +847,7 @@ static int auerswald_status_retry (int status) /* Completion of asynchronous write block */ static void auerchar_ctrlwrite_complete (struct urb * urb) { - pauerbuf_t bp = (pauerbuf_t) urb->context; + pauerbuf_t bp = urb->context; pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); dbg ("auerchar_ctrlwrite_complete called"); @@ -860,7 +860,7 @@ static void auerchar_ctrlwrite_complete (struct urb * urb) /* Completion handler for dummy retry packet */ static void auerswald_ctrlread_wretcomplete (struct urb * urb) { - pauerbuf_t bp = (pauerbuf_t) urb->context; + pauerbuf_t bp = urb->context; pauerswald_t cp; int ret; int status = urb->status; @@ -904,7 +904,7 @@ static void auerswald_ctrlread_complete (struct urb * urb) unsigned int serviceid; pauerswald_t cp; pauerscon_t scp; - pauerbuf_t bp = (pauerbuf_t) urb->context; + pauerbuf_t bp = urb->context; int status = urb->status; int ret; @@ -981,7 +981,7 @@ static void auerswald_int_complete (struct urb * urb) int ret; int status = urb->status; pauerbuf_t bp = NULL; - pauerswald_t cp = (pauerswald_t) urb->context; + pauerswald_t cp = urb->context; dbg ("%s called", __func__); diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 148b7fe639b2..ec88b3bfee46 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -746,7 +746,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, static void ftdi_elan_write_bulk_callback(struct urb *urb) { - struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; + struct usb_ftdi *ftdi = urb->context; int status = urb->status; if (status && !(status == -ENOENT || status == -ECONNRESET || diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 0a2549bc0540..1cb54a28347f 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(usb, iowarrior_ids); */ static void iowarrior_callback(struct urb *urb) { - struct iowarrior *dev = (struct iowarrior *)urb->context; + struct iowarrior *dev = urb->context; int intr_idx; int read_idx; int aux_idx; @@ -230,7 +230,7 @@ static void iowarrior_write_callback(struct urb *urb) struct iowarrior *dev; int status = urb->status; - dev = (struct iowarrior *)urb->context; + dev = urb->context; /* sync/async unlink faults aren't errors */ if (status && !(status == -ENOENT || diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index fae5b1730ba2..9370326a5940 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -753,7 +753,7 @@ exit: */ static void tower_interrupt_in_callback (struct urb *urb) { - struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; + struct lego_usb_tower *dev = urb->context; int status = urb->status; int retval; @@ -810,7 +810,7 @@ exit: */ static void tower_interrupt_out_callback (struct urb *urb) { - struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; + struct lego_usb_tower *dev = urb->context; int status = urb->status; dbg(4, "%s: enter, status %d", __func__, status); diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index ada7bf898fe9..7f7021ee4189 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -185,7 +185,7 @@ static void lcd_write_bulk_callback(struct urb *urb) struct usb_lcd *dev; int status = urb->status; - dev = (struct usb_lcd *)urb->context; + dev = urb->context; /* sync/async unlink faults aren't errors */ if (status && diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 678fac86c467..a51983854ca0 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -201,7 +201,7 @@ found: static void simple_callback (struct urb *urb) { - complete ((struct completion *) urb->context); + complete(urb->context); } static struct urb *simple_alloc_urb ( @@ -1046,7 +1046,7 @@ static void unlink1_callback (struct urb *urb) status = usb_submit_urb (urb, GFP_ATOMIC); if (status) { urb->status = status; - complete ((struct completion *) urb->context); + complete(urb->context); } } diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 5a2877c22129..0a322fc53d6e 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -248,7 +248,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) static void belkin_sa_read_int_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct belkin_sa_private *priv; unsigned char *data = urb->transfer_buffer; int retval; diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index d077534ceaeb..c164e2cf2752 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -300,7 +300,7 @@ static int cyberjack_write_room( struct usb_serial_port *port ) static void cyberjack_read_int_callback( struct urb *urb ) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; int status = urb->status; @@ -357,7 +357,7 @@ resubmit: static void cyberjack_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; @@ -409,7 +409,7 @@ static void cyberjack_read_bulk_callback (struct urb *urb) static void cyberjack_write_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); int status = urb->status; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 01dfc0afc654..32121794808d 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -1209,7 +1209,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) static void cypress_read_int_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct cypress_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; @@ -1361,7 +1361,7 @@ continue_read: static void cypress_write_int_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct cypress_private *priv = usb_get_serial_port_data(port); int result; int status = urb->status; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index c7cbc02f1a70..d17d1645714f 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1227,7 +1227,7 @@ static int digi_write(struct usb_serial_port *port, const unsigned char *buf, in static void digi_write_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct usb_serial *serial; struct digi_port *priv; struct digi_serial *serial_priv; @@ -1605,7 +1605,7 @@ static void digi_shutdown(struct usb_serial *serial) static void digi_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct digi_port *priv; struct digi_serial *serial_priv; int ret; @@ -1664,7 +1664,7 @@ static void digi_read_bulk_callback(struct urb *urb) static int digi_read_inb_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty = port->tty; struct digi_port *priv = usb_get_serial_port_data(port); int opcode = ((unsigned char *)urb->transfer_buffer)[0]; @@ -1754,7 +1754,7 @@ static int digi_read_inb_callback(struct urb *urb) static int digi_read_oob_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct usb_serial *serial = port->serial; struct digi_port *priv = usb_get_serial_port_data(port); int opcode, line, status, val; diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 5f731d4912f7..c5ec309a3cb1 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -340,7 +340,7 @@ static void empeg_write_bulk_callback (struct urb *urb) static void empeg_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int result; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8b531b377dcb..23f51a41093e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1377,7 +1377,7 @@ error_no_buffer: static void ftdi_write_bulk_callback (struct urb *urb) { unsigned long flags; - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct ftdi_private *priv; int data_offset; /* will be 1 for the SIO and 0 otherwise */ unsigned long countback; @@ -1460,7 +1460,7 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port) static void ftdi_read_bulk_callback (struct urb *urb) { /* ftdi_read_bulk_callback */ - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty; struct ftdi_private *priv; unsigned long countread; diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 513d771adc4e..8ce5a56a48e3 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1046,7 +1046,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) static void garmin_write_bulk_callback (struct urb *urb) { unsigned long flags; - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; if (port) { @@ -1286,7 +1286,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, static void garmin_read_bulk_callback (struct urb *urb) { unsigned long flags; - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; @@ -1344,7 +1344,7 @@ static void garmin_read_int_callback (struct urb *urb) { unsigned long flags; int retval; - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 65765ce76251..537f12a027c2 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -331,7 +331,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port) void usb_serial_generic_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; int status = urb->status; unsigned long flags; @@ -359,7 +359,7 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); void usb_serial_generic_write_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; dbg("%s - port %d", __func__, port->number); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 2b676732e9fa..ce2e487f3240 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -589,7 +589,7 @@ static int get_epic_descriptor(struct edgeport_serial *ep) *****************************************************************************/ static void edge_interrupt_callback (struct urb *urb) { - struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; + struct edgeport_serial *edge_serial = urb->context; struct edgeport_port *edge_port; struct usb_serial_port *port; unsigned char *data = urb->transfer_buffer; @@ -689,7 +689,7 @@ exit: *****************************************************************************/ static void edge_bulk_in_callback (struct urb *urb) { - struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; + struct edgeport_serial *edge_serial = urb->context; unsigned char *data = urb->transfer_buffer; int retval; __u16 raw_data_length; @@ -749,7 +749,7 @@ static void edge_bulk_in_callback (struct urb *urb) *****************************************************************************/ static void edge_bulk_out_data_callback (struct urb *urb) { - struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; + struct edgeport_port *edge_port = urb->context; struct tty_struct *tty; int status = urb->status; @@ -782,7 +782,7 @@ static void edge_bulk_out_data_callback (struct urb *urb) *****************************************************************************/ static void edge_bulk_out_cmd_callback (struct urb *urb) { - struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; + struct edgeport_port *edge_port = urb->context; struct tty_struct *tty; int status = urb->status; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 0d412ede839a..05e4fa730730 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1710,7 +1710,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 static void edge_interrupt_callback (struct urb *urb) { - struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; + struct edgeport_serial *edge_serial = urb->context; struct usb_serial_port *port; struct edgeport_port *edge_port; unsigned char *data = urb->transfer_buffer; @@ -1803,7 +1803,7 @@ exit: static void edge_bulk_in_callback (struct urb *urb) { - struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; + struct edgeport_port *edge_port = urb->context; unsigned char *data = urb->transfer_buffer; struct tty_struct *tty; int retval = 0; @@ -1897,7 +1897,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c static void edge_bulk_out_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct edgeport_port *edge_port = usb_get_serial_port_data(port); int status = urb->status; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index c90436ea8060..ea924dc48496 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -729,7 +729,7 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp) static void ipaq_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int result; @@ -869,7 +869,7 @@ static void ipaq_write_gather(struct usb_serial_port *port) static void ipaq_write_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct ipaq_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result; diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 496009cff3a8..004d57385a75 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -393,7 +393,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int static void ir_write_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; dbg("%s - port %d", __func__, port->number); @@ -417,7 +417,7 @@ static void ir_write_bulk_callback (struct urb *urb) static void ir_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int result; diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index b486a54c6f46..8a217648b250 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -186,7 +186,7 @@ static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) static void iuu_rxcmd(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; dbg("%s - enter", __func__); @@ -240,7 +240,7 @@ static int iuu_reset(struct usb_serial_port *port, u8 wt) */ static void iuu_update_status_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); u8 *st; dbg("%s - enter", __func__); @@ -270,7 +270,7 @@ static void iuu_update_status_callback(struct urb *urb) static void iuu_status_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; dbg("%s - enter", __func__); @@ -392,7 +392,7 @@ static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1, static void iuu_led_activity_on(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; char *buf_ptr = port->write_urb->transfer_buffer; *buf_ptr++ = IUU_SET_LED; @@ -413,7 +413,7 @@ static void iuu_led_activity_on(struct urb *urb) static void iuu_led_activity_off(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; char *buf_ptr = port->write_urb->transfer_buffer; if (xmas == 1) { @@ -616,7 +616,7 @@ static int iuu_uart_flush(struct usb_serial_port *port) static void read_buf_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; struct tty_struct *tty; dbg("%s - urb->status = %d", __func__, urb->status); @@ -692,7 +692,7 @@ static int iuu_read_buf(struct usb_serial_port *port, int len) static void iuu_uart_read_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); unsigned int flags; int status; @@ -781,7 +781,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, static void read_rxcmd_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; dbg("%s - enter", __func__); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 0d122feb2b22..3df8a66c5c3c 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -445,7 +445,7 @@ static void usa26_indat_callback(struct urb *urb) return; } - port = (struct usb_serial_port *) urb->context; + port = urb->context; tty = port->tty; if (tty && urb->actual_length) { /* 0x80 bit is error flag */ @@ -490,7 +490,7 @@ static void usa2x_outdat_callback(struct urb *urb) struct usb_serial_port *port; struct keyspan_port_private *p_priv; - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); @@ -509,7 +509,7 @@ static void usa26_outcont_callback(struct urb *urb) struct usb_serial_port *port; struct keyspan_port_private *p_priv; - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { @@ -528,7 +528,7 @@ static void usa26_instat_callback(struct urb *urb) int old_dcd_state, err; int status = urb->status; - serial = (struct usb_serial *) urb->context; + serial = urb->context; if (status) { dbg("%s - nonzero status: %x", __func__, status); @@ -599,7 +599,7 @@ static void usa28_indat_callback(struct urb *urb) dbg ("%s", __func__); - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); data = urb->transfer_buffer; @@ -613,7 +613,7 @@ static void usa28_indat_callback(struct urb *urb) return; } - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); data = urb->transfer_buffer; @@ -647,7 +647,7 @@ static void usa28_outcont_callback(struct urb *urb) struct usb_serial_port *port; struct keyspan_port_private *p_priv; - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { @@ -667,7 +667,7 @@ static void usa28_instat_callback(struct urb *urb) int old_dcd_state; int status = urb->status; - serial = (struct usb_serial *) urb->context; + serial = urb->context; if (status) { dbg("%s - nonzero status: %x", __func__, status); @@ -733,7 +733,7 @@ static void usa49_glocont_callback(struct urb *urb) dbg ("%s", __func__); - serial = (struct usb_serial *) urb->context; + serial = urb->context; for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv = usb_get_serial_port_data(port); @@ -761,7 +761,7 @@ static void usa49_instat_callback(struct urb *urb) dbg ("%s", __func__); - serial = (struct usb_serial *) urb->context; + serial = urb->context; if (status) { dbg("%s - nonzero status: %x", __func__, status); @@ -836,7 +836,7 @@ static void usa49_indat_callback(struct urb *urb) return; } - port = (struct usb_serial_port *) urb->context; + port = urb->context; tty = port->tty; if (tty && urb->actual_length) { /* 0x80 bit is error flag */ @@ -973,7 +973,7 @@ static void usa90_indat_callback(struct urb *urb) return; } - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); tty = port->tty; @@ -1037,7 +1037,7 @@ static void usa90_instat_callback(struct urb *urb) int old_dcd_state, err; int status = urb->status; - serial = (struct usb_serial *) urb->context; + serial = urb->context; if (status) { dbg("%s - nonzero status: %x", __func__, status); @@ -1084,7 +1084,7 @@ static void usa90_outcont_callback(struct urb *urb) struct usb_serial_port *port; struct keyspan_port_private *p_priv; - port = (struct usb_serial_port *) urb->context; + port = urb->context; p_priv = usb_get_serial_port_data(port); if (p_priv->resend_cont) { diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index b650fb4754b4..ff54203944ca 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -214,7 +214,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) static void keyspan_pda_rx_interrupt (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct tty_struct *tty = port->tty; unsigned char *data = urb->transfer_buffer; int i; @@ -608,7 +608,7 @@ exit: static void keyspan_pda_write_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct keyspan_pda_private *priv; port->write_urb_busy = 0; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index b3ac045ab408..b395ac759888 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -567,7 +567,7 @@ exit: static void klsi_105_write_bulk_callback ( struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; dbg("%s - port %d", __func__, port->number); @@ -628,7 +628,7 @@ static int klsi_105_write_room (struct usb_serial_port *port) static void klsi_105_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct klsi_105_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index e25c0c2791eb..5fc2cef30e39 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -514,7 +514,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp) static void mct_u232_read_int_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct mct_u232_private *priv = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; struct tty_struct *tty; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 7823222570b6..6bcb82d3911a 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -449,7 +449,7 @@ static void mos7840_control_callback(struct urb *urb) int result = 0; int status = urb->status; - mos7840_port = (struct moschip_port *)urb->context; + mos7840_port = urb->context; switch (status) { case 0: @@ -554,7 +554,7 @@ static void mos7840_interrupt_callback(struct urb *urb) length = urb->actual_length; data = urb->transfer_buffer; - serial = (struct usb_serial *)urb->context; + serial = urb->context; /* Moschip get 5 bytes * Byte 1 IIR Port 1 (port.number is 0) @@ -685,7 +685,7 @@ static void mos7840_bulk_in_callback(struct urb *urb) return; } - mos7840_port = (struct moschip_port *)urb->context; + mos7840_port = urb->context; if (!mos7840_port) { dbg("%s", "NULL mos7840_port pointer \n"); return; @@ -752,7 +752,7 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) int status = urb->status; int i; - mos7840_port = (struct moschip_port *)urb->context; + mos7840_port = urb->context; spin_lock(&mos7840_port->pool_lock); for (i = 0; i < NUM_URBS; i++) { if (urb == mos7840_port->write_urb_pool[i]) { diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 10090cb52d31..7b7422f49478 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -194,7 +194,7 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp) static void omninet_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; struct omninet_header *header = (struct omninet_header *) &data[0]; int status = urb->status; @@ -309,7 +309,7 @@ static int omninet_write_room (struct usb_serial_port *port) static void omninet_write_bulk_callback (struct urb *urb) { /* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */ - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; dbg("%s - port %0x\n", __func__, port->number); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a83892627d66..e4be2d442b1e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -545,7 +545,7 @@ static void option_indat_callback(struct urb *urb) dbg("%s: %p", __func__, urb); endpoint = usb_pipeendpoint(urb->pipe); - port = (struct usb_serial_port *) urb->context; + port = urb->context; if (status) { dbg("%s: nonzero status: %d on endpoint %02x.", @@ -579,7 +579,7 @@ static void option_outdat_callback(struct urb *urb) dbg("%s", __func__); - port = (struct usb_serial_port *) urb->context; + port = urb->context; usb_serial_port_softint(port); @@ -597,7 +597,7 @@ static void option_instat_callback(struct urb *urb) { int err; int status = urb->status; - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct option_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 87f33e06301c..d92bb6501c84 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -871,7 +871,7 @@ static void oti6858_shutdown(struct usb_serial *serial) static void oti6858_read_int_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct oti6858_private *priv = usb_get_serial_port_data(port); int transient = 0, can_recv = 0, resubmit = 1; int status = urb->status; @@ -985,7 +985,7 @@ static void oti6858_read_int_callback(struct urb *urb) static void oti6858_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct oti6858_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; @@ -1038,7 +1038,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) static void oti6858_write_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct oti6858_private *priv = usb_get_serial_port_data(port); int status = urb->status; int result; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c60930ec9341..c605fb68f807 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -945,7 +945,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, static void pl2303_read_int_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; unsigned int actual_length = urb->actual_length; int status = urb->status; @@ -985,7 +985,7 @@ exit: static void pl2303_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct pl2303_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; @@ -1068,7 +1068,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) static void pl2303_write_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct pl2303_private *priv = usb_get_serial_port_data(port); int result; int status = urb->status; diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index e6acac49a9c8..94bddf06ea4f 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -195,7 +195,7 @@ static __u16 __inline__ fcs_compute10 (unsigned char *sp, int len, __u16 fcs) static void safe_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; unsigned char length = urb->actual_length; int result; diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 23188873eb07..29074c1ba22b 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -457,7 +457,7 @@ static void sierra_indat_callback(struct urb *urb) dbg("%s: %p", __func__, urb); endpoint = usb_pipeendpoint(urb->pipe); - port = (struct usb_serial_port *) urb->context; + port = urb->context; if (status) { dbg("%s: nonzero status: %d on endpoint %02x.", @@ -487,7 +487,7 @@ static void sierra_instat_callback(struct urb *urb) { int err; int status = urb->status; - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct usb_serial_port *port = urb->context; struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index e0b1564de900..a1c8aef01417 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1098,7 +1098,7 @@ static void ti_break(struct usb_serial_port *port, int break_state) static void ti_interrupt_callback(struct urb *urb) { - struct ti_device *tdev = (struct ti_device *)urb->context; + struct ti_device *tdev = urb->context; struct usb_serial_port *port; struct usb_serial *serial = tdev->td_serial; struct ti_port *tport; @@ -1181,7 +1181,7 @@ exit: static void ti_bulk_in_callback(struct urb *urb) { - struct ti_port *tport = (struct ti_port *)urb->context; + struct ti_port *tport = urb->context; struct usb_serial_port *port = tport->tp_port; struct device *dev = &urb->dev->dev; int status = urb->status; @@ -1247,7 +1247,7 @@ exit: static void ti_bulk_out_callback(struct urb *urb) { - struct ti_port *tport = (struct ti_port *)urb->context; + struct ti_port *tport = urb->context; struct usb_serial_port *port = tport->tp_port; struct device *dev = &urb->dev->dev; int status = urb->status; diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index a100a52a376e..5fc20122145f 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -478,7 +478,7 @@ static int visor_chars_in_buffer (struct usb_serial_port *port) static void visor_write_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct visor_private *priv = usb_get_serial_port_data(port); int status = urb->status; unsigned long flags; @@ -502,7 +502,7 @@ static void visor_write_bulk_callback (struct urb *urb) static void visor_read_bulk_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct visor_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; int status = urb->status; @@ -553,7 +553,7 @@ static void visor_read_bulk_callback (struct urb *urb) static void visor_read_int_callback (struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int status = urb->status; int result; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 6926a81a0ccd..e96bf8663ffc 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -965,7 +965,7 @@ static void command_port_write_callback(struct urb *urb) static void command_port_read_callback(struct urb *urb) { - struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *command_port = urb->context; struct whiteheat_command_private *command_info; int status = urb->status; unsigned char *data = urb->transfer_buffer; @@ -1015,7 +1015,7 @@ static void command_port_read_callback(struct urb *urb) static void whiteheat_read_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct whiteheat_urb_wrap *wrap; unsigned char *data = urb->transfer_buffer; struct whiteheat_private *info = usb_get_serial_port_data(port); @@ -1059,7 +1059,7 @@ static void whiteheat_read_callback(struct urb *urb) static void whiteheat_write_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct whiteheat_private *info = usb_get_serial_port_data(port); struct whiteheat_urb_wrap *wrap; int status = urb->status; diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index db55ec39bb83..6610d2dd1e7f 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -110,7 +110,7 @@ */ static void usb_stor_blocking_completion(struct urb *urb) { - struct completion *urb_done_ptr = (struct completion *)urb->context; + struct completion *urb_done_ptr = urb->context; complete(urb_done_ptr); } diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 73e6a66d95a7..be76084c8d7e 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -212,7 +212,7 @@ static void skel_write_bulk_callback(struct urb *urb) { struct usb_skel *dev; - dev = (struct usb_skel *)urb->context; + dev = urb->context; /* sync/async unlink faults aren't errors */ if (urb->status) { -- cgit v1.2.2 From 8af548dc8e36f845943ffcba07fafaa56c844221 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 8 Apr 2008 13:24:46 -0700 Subject: wusb: teach choose_address() about wireless devices Modify choose_address() so it knows about our special scheme of addressing WUSB devices (1:1 w/ port number). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 06c3acb161ee..baae2aa0dbf6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1195,21 +1195,42 @@ void usb_set_device_state(struct usb_device *udev, spin_unlock_irqrestore(&device_state_lock, flags); } +/* + * WUSB devices are simple: they have no hubs behind, so the mapping + * device <-> virtual port number becomes 1:1. Why? to simplify the + * life of the device connection logic in + * drivers/usb/wusbcore/devconnect.c. When we do the initial secret + * handshake we need to assign a temporary address in the unauthorized + * space. For simplicity we use the first virtual port number found to + * be free [drivers/usb/wusbcore/devconnect.c:wusbhc_devconnect_ack()] + * and that becomes it's address [X < 128] or its unauthorized address + * [X | 0x80]. + * + * We add 1 as an offset to the one-based USB-stack port number + * (zero-based wusb virtual port index) for two reasons: (a) dev addr + * 0 is reserved by USB for default address; (b) Linux's USB stack + * uses always #1 for the root hub of the controller. So USB stack's + * port #1, which is wusb virtual-port #0 has address #2. + */ static void choose_address(struct usb_device *udev) { int devnum; struct usb_bus *bus = udev->bus; /* If khubd ever becomes multithreaded, this will need a lock */ - - /* Try to allocate the next devnum beginning at bus->devnum_next. */ - devnum = find_next_zero_bit(bus->devmap.devicemap, 128, - bus->devnum_next); - if (devnum >= 128) - devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1); - - bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); - + if (udev->wusb) { + devnum = udev->portnum + 1; + BUG_ON(test_bit(devnum, bus->devmap.devicemap)); + } else { + /* Try to allocate the next devnum beginning at + * bus->devnum_next. */ + devnum = find_next_zero_bit(bus->devmap.devicemap, 128, + bus->devnum_next); + if (devnum >= 128) + devnum = find_next_zero_bit(bus->devmap.devicemap, + 128, 1); + bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1); + } if (devnum < 128) { set_bit(devnum, bus->devmap.devicemap); udev->devnum = devnum; @@ -2611,6 +2632,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, udev->speed = USB_SPEED_UNKNOWN; udev->bus_mA = hub->mA_per_port; udev->level = hdev->level + 1; + udev->wusb = hub_is_wusb(hub); /* set the address */ choose_address(udev); -- cgit v1.2.2 From 6c529cdca914ba2a08a4bba54f11dedc2d3a7c17 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 8 Apr 2008 13:24:46 -0700 Subject: wusb: devices dont use a set address A WUSB device gets his address during the connection phase; later on, during the authenthication phase (driven from user space) we assign the final address. So we need to skip in hub_port_init() the actual setting of the address for WUSB devices. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index baae2aa0dbf6..1815034ccb7a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2419,26 +2419,33 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, #undef GET_DESCRIPTOR_BUFSIZE } - for (j = 0; j < SET_ADDRESS_TRIES; ++j) { - retval = hub_set_address(udev, devnum); - if (retval >= 0) + /* + * If device is WUSB, we already assigned an + * unauthorized address in the Connect Ack sequence; + * authorization will assign the final address. + */ + if (udev->wusb == 0) { + for (j = 0; j < SET_ADDRESS_TRIES; ++j) { + retval = hub_set_address(udev, devnum); + if (retval >= 0) + break; + msleep(200); + } + if (retval < 0) { + dev_err(&udev->dev, + "device not accepting address %d, error %d\n", + devnum, retval); + goto fail; + } + + /* cope with hardware quirkiness: + * - let SET_ADDRESS settle, some device hardware wants it + * - read ep0 maxpacket even for high and low speed, + */ + msleep(10); + if (USE_NEW_SCHEME(retry_counter)) break; - msleep(200); - } - if (retval < 0) { - dev_err(&udev->dev, - "device not accepting address %d, error %d\n", - devnum, retval); - goto fail; - } - - /* cope with hardware quirkiness: - * - let SET_ADDRESS settle, some device hardware wants it - * - read ep0 maxpacket even for high and low speed, - */ - msleep(10); - if (USE_NEW_SCHEME(retry_counter)) - break; + } retval = usb_get_device_descriptor(udev, 8); if (retval < 8) { @@ -2455,7 +2462,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; - i = udev->descriptor.bMaxPacketSize0 == 0xff? + i = udev->descriptor.bMaxPacketSize0 == 0xff? /* wusb device? */ 512 : udev->descriptor.bMaxPacketSize0; if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { if (udev->speed != USB_SPEED_FULL || -- cgit v1.2.2 From fc721f5194dc98c8108fb155a4fbae1cd746cf41 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 8 Apr 2008 13:24:46 -0700 Subject: wusb: make ep0_reinit available for modules We need to be able to call ep0_reinit() [renamed to usb_ep0_reinit()] from the WUSB security code. The reason is that when we authenticate the device, it's address changes (from having bit 7 set to having it cleared). Thus, we need to signal the USB stack to reinitialize EP0, so the status with the previous address kept at the HCD layer is cleared and properly reinitialized. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 11 ++++++----- drivers/usb/core/hub.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1815034ccb7a..830c851384bf 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2211,12 +2211,13 @@ static int hub_port_debounce(struct usb_hub *hub, int port1) return portstatus; } -static void ep0_reinit(struct usb_device *udev) +void usb_ep0_reinit(struct usb_device *udev) { usb_disable_endpoint(udev, 0 + USB_DIR_IN); usb_disable_endpoint(udev, 0 + USB_DIR_OUT); usb_enable_endpoint(udev, &udev->ep0); } +EXPORT_SYMBOL_GPL(usb_ep0_reinit); #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) @@ -2237,7 +2238,7 @@ static int hub_set_address(struct usb_device *udev, int devnum) if (retval == 0) { udev->devnum = devnum; /* Device now using proper address */ usb_set_device_state(udev, USB_STATE_ADDRESS); - ep0_reinit(udev); + usb_ep0_reinit(udev); } return retval; } @@ -2473,7 +2474,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, } dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); - ep0_reinit(udev); + usb_ep0_reinit(udev); } retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); @@ -2729,7 +2730,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, loop_disable: hub_port_disable(hub, port1, 1); loop: - ep0_reinit(udev); + usb_ep0_reinit(udev); release_address(udev); usb_put_dev(udev); if ((status == -ENOTCONN) || (status == -ENOTSUPP)) @@ -3164,7 +3165,7 @@ int usb_reset_device(struct usb_device *udev) /* ep0 maxpacket size may change; let the HCD know about it. * Other endpoints will be handled by re-enumeration. */ - ep0_reinit(udev); + usb_ep0_reinit(udev); ret = hub_port_init(parent_hub, udev, port1, i); if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV) break; diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index d672cd81a3e4..2a116ce53c9b 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -195,5 +195,6 @@ struct usb_tt_clear { }; extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); +extern void usb_ep0_reinit(struct usb_device *); #endif /* __LINUX_HUB_H */ -- cgit v1.2.2 From 4953d141dc5db748475001cfbfdcc42e66cf900e Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 8 Apr 2008 13:24:46 -0700 Subject: usb: don't update devnum for wusb devices For WUSB devices, usb_dev.devnum is a device index and not the real device address (which is managed by wusbcore). Therefore, only set devnum once (in choose_address()) and never change it. Signed-off-by: David Vrabel Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 830c851384bf..eb57fcc701d7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1245,6 +1245,13 @@ static void release_address(struct usb_device *udev) } } +static void update_address(struct usb_device *udev, int devnum) +{ + /* The address for a WUSB device is managed by wusbcore. */ + if (!udev->wusb) + udev->devnum = devnum; +} + #ifdef CONFIG_USB_SUSPEND static void usb_stop_pm(struct usb_device *udev) @@ -1733,7 +1740,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, case 0: /* TRSTRCY = 10 ms; plus some extra */ msleep(10 + 40); - udev->devnum = 0; /* Device now at address 0 */ + update_address(udev, 0); /* FALL THROUGH */ case -ENOTCONN: case -ENODEV: @@ -2236,7 +2243,8 @@ static int hub_set_address(struct usb_device *udev, int devnum) USB_REQ_SET_ADDRESS, 0, devnum, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval == 0) { - udev->devnum = devnum; /* Device now using proper address */ + /* Device now using proper address. */ + update_address(udev, devnum); usb_set_device_state(udev, USB_STATE_ADDRESS); usb_ep0_reinit(udev); } @@ -2491,7 +2499,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, fail: if (retval) { hub_port_disable(hub, port1, 0); - udev->devnum = devnum; /* for disconnect processing */ + update_address(udev, devnum); /* for disconnect processing */ } mutex_unlock(&usb_address0_mutex); return retval; -- cgit v1.2.2 From 458622fcdc5b316de8d74efd7e610803f0308c14 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:41:57 -0700 Subject: ATA/IDE: fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable ATA and IDE platform drivers, to re-enable auto loading. NOTE: both ata/pata_platform.c and ide/legacy/ide_platform.c claim to provide "the" platform_pata driver, and there's no build-time mutual exclusion mechanism. This means that configs which enable both drivers will make some trouble when hotplugging... [dbrownell@users.sourceforge.net: more drivers, registration fixes] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Cc: Tejun Heo Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_at32.c | 3 +++ drivers/ata/pata_bf54x.c | 1 + drivers/ata/pata_ixp4xx_cf.c | 1 + drivers/ata/pata_platform.c | 1 + drivers/ata/pata_rb500_cf.c | 3 +++ drivers/ide/arm/palm_bk3710.c | 4 ++++ drivers/ide/legacy/ide_platform.c | 2 ++ 7 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index 3e8651d78952..5e104385d6a3 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -381,6 +381,9 @@ static int __exit pata_at32_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:at32_ide"); + static struct platform_driver pata_at32_driver = { .remove = __exit_p(pata_at32_remove), .driver = { diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 0a5ad98635b1..e4cf73c4b70b 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1601,3 +1601,4 @@ MODULE_AUTHOR("Sonic Zhang "); MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 8a175f23b907..de8d186f5abf 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -221,6 +221,7 @@ MODULE_AUTHOR("Alessandro Zummo "); MODULE_DESCRIPTION("low-level driver for ixp4xx Compact Flash PATA"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:" DRV_NAME); module_init(ixp4xx_pata_init); module_exit(ixp4xx_pata_exit); diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 6527c56c34a3..8f65ad61b8af 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -277,3 +277,4 @@ MODULE_AUTHOR("Paul Mundt"); MODULE_DESCRIPTION("low-level driver for platform device ATA"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/ata/pata_rb500_cf.c b/drivers/ata/pata_rb500_cf.c index 800ae4601f44..4345174aaeec 100644 --- a/drivers/ata/pata_rb500_cf.c +++ b/drivers/ata/pata_rb500_cf.c @@ -239,6 +239,9 @@ static __devexit int rb500_pata_driver_remove(struct platform_device *pdev) return 0; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:" DRV_NAME); + static struct platform_driver rb500_pata_platform_driver = { .probe = rb500_pata_driver_probe, .remove = __devexit_p(rb500_pata_driver_remove), diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 474162cdf665..420fcb78a7cd 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -409,9 +409,13 @@ out: return -ENODEV; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:palm_bk3710"); + static struct platform_driver platform_bk_driver = { .driver = { .name = "palm_bk3710", + .owner = THIS_MODULE, }, .probe = palm_bk3710_probe, .remove = NULL, diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 249651e2da42..361b1bb544bf 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c @@ -130,6 +130,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev) static struct platform_driver platform_ide_driver = { .driver = { .name = "pata_platform", + .owner = THIS_MODULE, }, .probe = plat_ide_probe, .remove = __devexit_p(plat_ide_remove), @@ -147,6 +148,7 @@ static void __exit platform_ide_exit(void) MODULE_DESCRIPTION("Platform IDE driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pata_platform"); module_init(platform_ide_init); module_exit(platform_ide_exit); -- cgit v1.2.2 From 411cb3869afd91ed40e8f12df64cd9e315356305 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Apr 2008 20:48:36 +0900 Subject: libata: make WARN_ON conditions in ata_sff_hsm_move() more strict WARN_ON()'s in ata_hsm_move() was too liberal and got triggerred when it shouldn't (e.g. hotplug events at the right moment). As the HSM only deals with device errors and state machine violations, make it check only against them. Signed-off-by: Tejun Heo Cc: Mark Lord Cc: Albert Lee Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 15499522e642..2ec65a8fda79 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1208,7 +1208,7 @@ fsm_start: DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n", ap->print_id, qc->dev->devno, status); - WARN_ON(qc->err_mask); + WARN_ON(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM)); ap->hsm_task_state = HSM_ST_IDLE; @@ -1222,7 +1222,7 @@ fsm_start: /* make sure qc->err_mask is available to * know what's wrong and recover */ - WARN_ON(qc->err_mask == 0); + WARN_ON(!(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM))); ap->hsm_task_state = HSM_ST_IDLE; -- cgit v1.2.2 From 15fe982e429e0e6b7466719acb6cfd9dbfe47f0c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Apr 2008 20:52:58 +0900 Subject: ahci: retry enabling AHCI a few times before spitting out WARN_ON() Some chips need AHCI_EN set more than once to actually set it. Try a few times before giving up and spitting out WARN_ON(). Signed-off-by: Tejun Heo Cc: Peer Chen Cc: Volker Armin Hemmann Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 986e3324e302..7c4f886f1f16 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -556,16 +556,27 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap) static void ahci_enable_ahci(void __iomem *mmio) { + int i; u32 tmp; /* turn on AHCI_EN */ tmp = readl(mmio + HOST_CTL); - if (!(tmp & HOST_AHCI_EN)) { + if (tmp & HOST_AHCI_EN) + return; + + /* Some controllers need AHCI_EN to be written multiple times. + * Try a few times before giving up. + */ + for (i = 0; i < 5; i++) { tmp |= HOST_AHCI_EN; writel(tmp, mmio + HOST_CTL); tmp = readl(mmio + HOST_CTL); /* flush && sanity check */ - WARN_ON(!(tmp & HOST_AHCI_EN)); + if (tmp & HOST_AHCI_EN) + return; + msleep(10); } + + WARN_ON(1); } /** -- cgit v1.2.2 From a0b9f4bc1ec2ea25e47e7958e544fef0d122e012 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Apr 2008 12:14:05 +0900 Subject: sata_nv: make hardreset return -EAGAIN on success sata_nv hardreset can't classify but was left out while unifying follow-up SRST request mechanism[1]. This caused detection failures on those controllers. Fix it. Reported and bisected by Roland Dreier, Petr Vandrovec and Marc Dionne. Thanks guys. [1] 305d2a1ab137d11d573319c315748a87060fe82d Signed-off-by: Tejun Heo Cc: Roland Dreier Cc: Petr Vandrovec Cc: Marc Dionne Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 109b07495721..858f70610eda 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1591,13 +1591,16 @@ static void nv_mcp55_thaw(struct ata_port *ap) static int nv_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { - unsigned int dummy; + int rc; /* SATA hardreset fails to retrieve proper device signature on - * some controllers. Don't classify on hardreset. For more - * info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352 + * some controllers. Request follow up SRST. For more info, + * see http://bugzilla.kernel.org/show_bug.cgi?id=3352 */ - return sata_sff_hardreset(link, &dummy, deadline); + rc = sata_sff_hardreset(link, class, deadline); + if (rc) + return rc; + return -EAGAIN; } static void nv_adma_error_handler(struct ata_port *ap) -- cgit v1.2.2 From 66a9099e02e3fca5198ab52b4bb7088f03dee42e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Apr 2008 01:50:35 +0300 Subject: libata-acpi.c: remove unneeded #if's These #if's are unneeded since they: - did anyway not handle the CONFIG_ACPI_DOCK_MODULE case correctly and - this is already handled in include/acpi/acpi_drivers.h and - it's now correctly handled in kconfig. Signed-off-by: Adrian Bunk Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 8c1cfc645c85..70b77e0899a8 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -227,11 +227,9 @@ void ata_acpi_associate(struct ata_host *host) acpi_install_notify_handler(ap->acpi_handle, ACPI_SYSTEM_NOTIFY, ata_acpi_ap_notify, ap); -#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) /* we might be on a docking station */ register_hotplug_dock_device(ap->acpi_handle, ata_acpi_ap_notify, ap); -#endif } for (j = 0; j < ata_link_max_devices(&ap->link); j++) { @@ -241,11 +239,9 @@ void ata_acpi_associate(struct ata_host *host) acpi_install_notify_handler(dev->acpi_handle, ACPI_SYSTEM_NOTIFY, ata_acpi_dev_notify, dev); -#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) /* we might be on a docking station */ register_hotplug_dock_device(dev->acpi_handle, ata_acpi_dev_notify, dev); -#endif } } } -- cgit v1.2.2 From 6bdb4fc9f9e5307012f6f2afb8642b52dad9c186 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Apr 2008 11:51:11 +0300 Subject: make sata_print_link_status() static sata_print_link_status() can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fe5c88ba977e..ce76702af1ee 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2616,7 +2616,7 @@ void ata_port_probe(struct ata_port *ap) * LOCKING: * None. */ -void sata_print_link_status(struct ata_link *link) +static void sata_print_link_status(struct ata_link *link) { u32 sstatus, scontrol, tmp; @@ -6208,7 +6208,6 @@ EXPORT_SYMBOL_GPL(ata_host_detach); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); -EXPORT_SYMBOL_GPL(sata_print_link_status); EXPORT_SYMBOL_GPL(atapi_cmd_type); EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); -- cgit v1.2.2 From 1dc55e876182a13dcc5991c3aab893f38455d8a7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Apr 2008 11:51:17 +0300 Subject: make sata_set_spd_needed() static sata_set_spd_needed() can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- drivers/ata/libata.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ce76702af1ee..51b7d2fad36a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2772,7 +2772,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) * RETURNS: * 1 if SATA spd configuration is needed, 0 otherwise. */ -int sata_set_spd_needed(struct ata_link *link) +static int sata_set_spd_needed(struct ata_link *link) { u32 scontrol; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 4aeeabb10a47..ae2cfd95d43e 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -101,7 +101,6 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, unsigned int readid_flags); extern int ata_dev_configure(struct ata_device *dev); extern int sata_down_spd_limit(struct ata_link *link); -extern int sata_set_spd_needed(struct ata_link *link); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern void ata_sg_clean(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc); -- cgit v1.2.2 From a6116c9e60978a6deaa20691c67ffed727e50df1 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 23 Apr 2008 22:36:25 -0400 Subject: libata-eh set tf flags in NCQ EH result_tf Fix mis-reporting of NCQ errors by ensuring that result_tf->flags is properly initialized in libata-eh. This allows ata_gen_ata_sense() to report the failed block number correctly to SCSI after a media error during NCQ. This patch may also be a candidate for backporting to earlier kernels. Without this fix, SCSI will fail I/O on the entire request rather than just the bad sector. That can be bad for a request that was merged from many independent read reads from different tasks. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index d94359a24d41..61dcd0026c64 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1402,6 +1402,7 @@ static void ata_eh_analyze_ncq_error(struct ata_link *link) /* we've got the perpetrator, condemn it */ qc = __ata_qc_from_tag(ap, tag); memcpy(&qc->result_tf, &tf, sizeof(tf)); + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; ehc->i.err_mask &= ~AC_ERR_DEV; } -- cgit v1.2.2 From 01ce2601e4ba354fe1e25bb940817570d0c8ed4f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 20 Apr 2008 22:03:27 -0500 Subject: ata_piix: add Asus Eee 701 controller to short cable list The drive is directly soldered to the controller, so there is no cable at all. Remove the 40-wire assumption so the drive can operate at max speed. Before patch: $ dd if=/dev/sda of=/dev/null bs=2M count=64 iflag=direct 134217728 bytes (134 MB) copied, 5.29612 s, 25.3 MB/s After patch: $ dd if=/dev/sda of=/dev/null bs=2M count=64 iflag=direct 134217728 bytes (134 MB) copied, 3.94955 s, 34.0 MB/s Signed-off-by: Dan McGee 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 b7c38eeb498f..ea2c7649d399 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -573,6 +573,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ /* end marker */ { 0, } }; -- cgit v1.2.2 From 352fab701ca4753dd005b67ce5e512be944eb591 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 14:43:42 -0400 Subject: sata_mv more cosmetics More cosmetic cleanups prior to the interrupt/error handling logic changes. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 131 ++++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index d52ce1188327..c01d6bf4c593 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -124,11 +124,11 @@ enum { MV_MAX_SG_CT = 256, MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT), - MV_PORTS_PER_HC = 4, - /* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */ + /* Determine hc from 0-7 port: hc = port >> MV_PORT_HC_SHIFT */ MV_PORT_HC_SHIFT = 2, - /* == (port % MV_PORTS_PER_HC) to determine hard port from 0-7 port */ - MV_PORT_MASK = 3, + MV_PORTS_PER_HC = (1 << MV_PORT_HC_SHIFT), /* 4 */ + /* Determine hc port from 0-7 port: hardport = port & MV_PORT_MASK */ + MV_PORT_MASK = (MV_PORTS_PER_HC - 1), /* 3 */ /* Host Flags */ MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ @@ -188,8 +188,8 @@ enum { HC_MAIN_IRQ_MASK_OFS = 0x1d64, HC_SOC_MAIN_IRQ_CAUSE_OFS = 0x20020, HC_SOC_MAIN_IRQ_MASK_OFS = 0x20024, - PORT0_ERR = (1 << 0), /* shift by port # */ - PORT0_DONE = (1 << 1), /* shift by port # */ + ERR_IRQ = (1 << 0), /* shift by port # */ + DONE_IRQ = (1 << 1), /* shift by port # */ HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */ HC_SHIFT = 9, /* bits 9-17 = HC1's ports */ PCI_ERR = (1 << 18), @@ -215,8 +215,8 @@ enum { HC_CFG_OFS = 0, HC_IRQ_CAUSE_OFS = 0x14, - CRPB_DMA_DONE = (1 << 0), /* shift by port # */ - HC_IRQ_COAL = (1 << 4), /* IRQ coalescing */ + DMA_IRQ = (1 << 0), /* shift by port # */ + HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */ DEV_IRQ = (1 << 8), /* shift by port # */ /* Shadow block registers */ @@ -349,6 +349,8 @@ enum { EDMA_IORDY_TMOUT = 0x34, EDMA_ARB_CFG = 0x38, + GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */ + /* Host private flags (hp_flags) */ MV_HP_FLAG_MSI = (1 << 0), MV_HP_ERRATA_50XXB0 = (1 << 1), @@ -722,11 +724,6 @@ static inline void writelfl(unsigned long data, void __iomem *addr) (void) readl(addr); /* flush to avoid PCI posted write */ } -static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) -{ - return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); -} - static inline unsigned int mv_hc_from_port(unsigned int port) { return port >> MV_PORT_HC_SHIFT; @@ -737,6 +734,11 @@ static inline unsigned int mv_hardport_from_port(unsigned int port) return port & MV_PORT_MASK; } +static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) +{ + return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); +} + static inline void __iomem *mv_hc_base_from_port(void __iomem *base, unsigned int port) { @@ -837,9 +839,9 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, } if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { struct mv_host_priv *hpriv = ap->host->private_data; - int hard_port = mv_hardport_from_port(ap->port_no); + int hardport = mv_hardport_from_port(ap->port_no); void __iomem *hc_mmio = mv_hc_base_from_port( - mv_host_base(ap->host), hard_port); + mv_host_base(ap->host), hardport); u32 hc_irq_cause, ipending; /* clear EDMA event indicators, if any */ @@ -847,8 +849,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, /* clear EDMA interrupt indicator, if any */ hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - ipending = (DEV_IRQ << hard_port) | - (CRPB_DMA_DONE << hard_port); + ipending = (DEV_IRQ | DMA_IRQ) << hardport; if (hc_irq_cause & ipending) { writelfl(hc_irq_cause & ~ipending, hc_mmio + HC_IRQ_CAUSE_OFS); @@ -864,7 +865,6 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); pp->pp_flags |= MV_PP_FLAG_EDMA_EN; } - WARN_ON(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS))); } /** @@ -1036,10 +1036,16 @@ static void mv6_dev_config(struct ata_device *adev) * See mv_qc_prep() for more info. */ if (adev->flags & ATA_DFLAG_NCQ) { - if (sata_pmp_attached(adev->link->ap)) + if (sata_pmp_attached(adev->link->ap)) { adev->flags &= ~ATA_DFLAG_NCQ; - else if (adev->max_sectors > ATA_MAX_SECTORS) - adev->max_sectors = ATA_MAX_SECTORS; + ata_dev_printk(adev, KERN_INFO, + "NCQ disabled for command-based switching\n"); + } else if (adev->max_sectors > GEN_II_NCQ_MAX_SECTORS) { + adev->max_sectors = GEN_II_NCQ_MAX_SECTORS; + ata_dev_printk(adev, KERN_INFO, + "max_sectors limited to %u for NCQ\n", + adev->max_sectors); + } } } @@ -1493,12 +1499,11 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); - ata_ehi_push_desc(ehi, "edma_err 0x%08x", edma_err_cause); + ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause); /* - * all generations share these EDMA error cause bits + * All generations share these EDMA error cause bits: */ - if (edma_err_cause & EDMA_ERR_DEV) err_mask |= AC_ERR_DEV; if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | @@ -1515,23 +1520,22 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) action |= ATA_EH_RESET; } + /* + * Gen-I has a different SELF_DIS bit, + * different FREEZE bits, and no SERR bit: + */ if (IS_GEN_I(hpriv)) { eh_freeze_mask = EDMA_EH_FREEZE_5; - if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { - pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; ata_ehi_push_desc(ehi, "EDMA self-disable"); } } else { eh_freeze_mask = EDMA_EH_FREEZE; - if (edma_err_cause & EDMA_ERR_SELF_DIS) { - pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; ata_ehi_push_desc(ehi, "EDMA self-disable"); } - if (edma_err_cause & EDMA_ERR_SERR) { sata_scr_read(&ap->link, SCR_ERROR, &serr); sata_scr_write_flush(&ap->link, SCR_ERROR, serr); @@ -1644,6 +1648,7 @@ static void mv_intr_edma(struct ata_port *ap) pp->resp_idx++; } + /* Update the software queue position index in hardware */ if (work_done) writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | (out_index << EDMA_RSP_Q_PTR_SHIFT), @@ -1696,7 +1701,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) for (port = port0; port < last_port; port++) { struct ata_port *ap = host->ports[port]; struct mv_port_priv *pp; - int have_err_bits, hard_port, shift; + int have_err_bits, hardport, shift; if ((!ap) || (ap->flags & ATA_FLAG_DISABLED)) continue; @@ -1707,7 +1712,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) if (port >= MV_PORTS_PER_HC) shift++; /* skip bit 8 in the HC Main IRQ reg */ - have_err_bits = ((PORT0_ERR << shift) & relevant); + have_err_bits = ((ERR_IRQ << shift) & relevant); if (unlikely(have_err_bits)) { struct ata_queued_cmd *qc; @@ -1720,13 +1725,13 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) continue; } - hard_port = mv_hardport_from_port(port); /* range 0..3 */ + hardport = mv_hardport_from_port(port); /* range 0..3 */ if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) + if ((DMA_IRQ << hardport) & hc_irq_cause) mv_intr_edma(ap); } else { - if ((DEV_IRQ << hard_port) & hc_irq_cause) + if ((DEV_IRQ << hardport) & hc_irq_cause) mv_intr_pio(ap); } } @@ -1793,30 +1798,28 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) struct mv_host_priv *hpriv = host->private_data; unsigned int hc, handled = 0, n_hcs; void __iomem *mmio = hpriv->base; - u32 irq_stat, irq_mask; + u32 main_cause, main_mask; - /* Note to self: &host->lock == &ap->host->lock == ap->lock */ spin_lock(&host->lock); - - irq_stat = readl(hpriv->main_cause_reg_addr); - irq_mask = readl(hpriv->main_mask_reg_addr); - - /* check the cases where we either have nothing pending or have read - * a bogus register value which can indicate HW removal or PCI fault + main_cause = readl(hpriv->main_cause_reg_addr); + main_mask = readl(hpriv->main_mask_reg_addr); + /* + * Deal with cases where we either have nothing pending, or have read + * a bogus register value which can indicate HW removal or PCI fault. */ - if (!(irq_stat & irq_mask) || (0xffffffffU == irq_stat)) + if (!(main_cause & main_mask) || (main_cause == 0xffffffffU)) goto out_unlock; n_hcs = mv_get_hc_count(host->ports[0]->flags); - if (unlikely((irq_stat & PCI_ERR) && HAS_PCI(host))) { + if (unlikely((main_cause & PCI_ERR) && HAS_PCI(host))) { mv_pci_error(host, mmio); handled = 1; goto out_unlock; /* skip all other HC irq handling */ } for (hc = 0; hc < n_hcs; hc++) { - u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT)); + u32 relevant = main_cause & (HC0_IRQ_PEND << (hc * HC_SHIFT)); if (relevant) { mv_host_intr(host, relevant, hc); handled = 1; @@ -1825,7 +1828,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) out_unlock: spin_unlock(&host->lock); - return IRQ_RETVAL(handled); } @@ -2410,8 +2412,8 @@ static void mv_eh_freeze(struct ata_port *ap) { struct mv_host_priv *hpriv = ap->host->private_data; unsigned int hc = (ap->port_no > 3) ? 1 : 0; - u32 tmp, mask; unsigned int shift; + u32 main_mask; /* FIXME: handle coalescing completion events properly */ @@ -2419,11 +2421,10 @@ static void mv_eh_freeze(struct ata_port *ap) if (hc > 0) shift++; - mask = 0x3 << shift; - /* disable assertion of portN err, done events */ - tmp = readl(hpriv->main_mask_reg_addr); - writelfl(tmp & ~mask, hpriv->main_mask_reg_addr); + main_mask = readl(hpriv->main_mask_reg_addr); + main_mask &= ~((DONE_IRQ | ERR_IRQ) << shift); + writelfl(main_mask, hpriv->main_mask_reg_addr); } static void mv_eh_thaw(struct ata_port *ap) @@ -2433,8 +2434,8 @@ static void mv_eh_thaw(struct ata_port *ap) unsigned int hc = (ap->port_no > 3) ? 1 : 0; void __iomem *hc_mmio = mv_hc_base(mmio, hc); void __iomem *port_mmio = mv_ap_base(ap); - u32 tmp, mask, hc_irq_cause; unsigned int shift, hc_port_no = ap->port_no; + u32 main_mask, hc_irq_cause; /* FIXME: handle coalescing completion events properly */ @@ -2444,20 +2445,18 @@ static void mv_eh_thaw(struct ata_port *ap) hc_port_no -= 4; } - mask = 0x3 << shift; - /* clear EDMA errors on this port */ writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); /* clear pending irq events */ hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - hc_irq_cause &= ~(1 << hc_port_no); /* clear CRPB-done */ - hc_irq_cause &= ~(1 << (hc_port_no + 8)); /* clear Device int */ + hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hc_port_no); writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); /* enable assertion of portN err, done events */ - tmp = readl(hpriv->main_mask_reg_addr); - writelfl(tmp | mask, hpriv->main_mask_reg_addr); + main_mask = readl(hpriv->main_mask_reg_addr); + main_mask |= ((DONE_IRQ | ERR_IRQ) << shift); + writelfl(main_mask, hpriv->main_mask_reg_addr); } /** @@ -2668,19 +2667,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) rc = mv_chip_id(host, board_idx); if (rc) - goto done; + goto done; if (HAS_PCI(host)) { - hpriv->main_cause_reg_addr = hpriv->base + - HC_MAIN_IRQ_CAUSE_OFS; - hpriv->main_mask_reg_addr = hpriv->base + HC_MAIN_IRQ_MASK_OFS; + hpriv->main_cause_reg_addr = mmio + HC_MAIN_IRQ_CAUSE_OFS; + hpriv->main_mask_reg_addr = mmio + HC_MAIN_IRQ_MASK_OFS; } else { - hpriv->main_cause_reg_addr = hpriv->base + - HC_SOC_MAIN_IRQ_CAUSE_OFS; - hpriv->main_mask_reg_addr = hpriv->base + - HC_SOC_MAIN_IRQ_MASK_OFS; + hpriv->main_cause_reg_addr = mmio + HC_SOC_MAIN_IRQ_CAUSE_OFS; + hpriv->main_mask_reg_addr = mmio + HC_SOC_MAIN_IRQ_MASK_OFS; } - /* global interrupt mask */ + + /* global interrupt mask: 0 == mask everything */ writel(0, hpriv->main_mask_reg_addr); n_hc = mv_get_hc_count(host->ports[0]->flags); -- cgit v1.2.2 From f9f7fe014fc7197a5f36f9d9859cbb27c3bdd2ab Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 14:44:42 -0400 Subject: sata_mv mask all interrupt coalescing bits Ignore *all* interrupt coalescing bits on all controllers, not just some of each. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index c01d6bf4c593..b3f35a6af32b 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -205,6 +205,7 @@ enum { HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | + PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | HC_MAIN_RSVD), HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | -- cgit v1.2.2 From 1cfd19aeb8c8b6291a9d11143b4d8f3dac508ed4 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 15:05:50 -0400 Subject: sata_mv: simplify freeze/thaw bit-shift calculations Introduce the MV_PORT_TO_SHIFT_AND_HARDPORT() macro, to centralize/simplify various scattered bits of logic for calculating bit shifts and the like. Some of the places that do this get it wrong, too, so consolidating the algorithm at one place will help keep the code correct. For now, we use the new macro in mv_eh_{freeze,thaw}. A subsequent patch will re-use this in the interrupt handlers Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index b3f35a6af32b..552006853cd7 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -735,6 +735,24 @@ static inline unsigned int mv_hardport_from_port(unsigned int port) return port & MV_PORT_MASK; } +/* + * Consolidate some rather tricky bit shift calculations. + * This is hot-path stuff, so not a function. + * Simple code, with two return values, so macro rather than inline. + * + * port is the sole input, in range 0..7. + * shift is one output, for use with the main_cause and main_mask registers. + * hardport is the other output, in range 0..3 + * + * Note that port and hardport may be the same variable in some cases. + */ +#define MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport) \ +{ \ + shift = mv_hc_from_port(port) * HC_SHIFT; \ + hardport = mv_hardport_from_port(port); \ + shift += hardport * 2; \ +} + static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) { return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); @@ -2412,15 +2430,13 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, static void mv_eh_freeze(struct ata_port *ap) { struct mv_host_priv *hpriv = ap->host->private_data; - unsigned int hc = (ap->port_no > 3) ? 1 : 0; - unsigned int shift; + unsigned int shift, hardport, port = ap->port_no; u32 main_mask; /* FIXME: handle coalescing completion events properly */ - shift = ap->port_no * 2; - if (hc > 0) - shift++; + mv_stop_edma(ap); + MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); /* disable assertion of portN err, done events */ main_mask = readl(hpriv->main_mask_reg_addr); @@ -2431,28 +2447,22 @@ static void mv_eh_freeze(struct ata_port *ap) static void mv_eh_thaw(struct ata_port *ap) { struct mv_host_priv *hpriv = ap->host->private_data; - void __iomem *mmio = hpriv->base; - unsigned int hc = (ap->port_no > 3) ? 1 : 0; - void __iomem *hc_mmio = mv_hc_base(mmio, hc); + unsigned int shift, hardport, port = ap->port_no; + void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); void __iomem *port_mmio = mv_ap_base(ap); - unsigned int shift, hc_port_no = ap->port_no; u32 main_mask, hc_irq_cause; /* FIXME: handle coalescing completion events properly */ - shift = ap->port_no * 2; - if (hc > 0) { - shift++; - hc_port_no -= 4; - } + MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); /* clear EDMA errors on this port */ writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); /* clear pending irq events */ hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hc_port_no); - writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); + hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); + writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); /* enable assertion of portN err, done events */ main_mask = readl(hpriv->main_mask_reg_addr); -- cgit v1.2.2 From fcfb1f77cea81f74d865b4d33f2e452ffa1973e8 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 15:06:40 -0400 Subject: sata_mv: simplify request/response queue handling Try and simplify handling of the request/response queues. Maintain the cached copies of queue indexes in a fully-masked state, rather than having each use of them have to do the masking. Split off handling of a single crpb response into a separate function, to reduce complexity in the main mv_process_crpb_entries() routine. Ignore the rarely-valid error bits from the crpb status field, as we already handle that information in mv_err_intr(). For now, preserve the rest of the original logic. A later patch will deal with fixing that separately. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 109 ++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 552006853cd7..cee78f9e9d1b 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -804,7 +804,8 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, /* * initialize request queue */ - index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT; + pp->req_idx &= MV_MAX_Q_DEPTH_MASK; /* paranoia */ + index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; WARN_ON(pp->crqb_dma & 0x3ff); writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); @@ -820,7 +821,8 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, /* * initialize response queue */ - index = (pp->resp_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_RSP_Q_PTR_SHIFT; + pp->resp_idx &= MV_MAX_Q_DEPTH_MASK; /* paranoia */ + index = pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT; WARN_ON(pp->crpb_dma & 0xff); writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); @@ -1312,7 +1314,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) flags |= (qc->dev->link->pmp & 0xf) << CRQB_PMP_SHIFT; /* get current queue index from software */ - in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK; + in_index = pp->req_idx; pp->crqb[in_index].sg_addr = cpu_to_le32(pp->sg_tbl_dma[qc->tag] & 0xffffffff); @@ -1404,7 +1406,7 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) flags |= (qc->dev->link->pmp & 0xf) << CRQB_PMP_SHIFT; /* get current queue index from software */ - in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK; + in_index = pp->req_idx; crqb = (struct mv_crqb_iie *) &pp->crqb[in_index]; crqb->addr = cpu_to_le32(pp->sg_tbl_dma[qc->tag] & 0xffffffff); @@ -1471,9 +1473,8 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) mv_start_dma(ap, port_mmio, pp, qc->tf.protocol); - pp->req_idx++; - - in_index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT; + pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; + in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; /* and write the request in pointer to kick the EDMA to life */ writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index, @@ -1607,70 +1608,72 @@ static void mv_intr_pio(struct ata_port *ap) ata_qc_complete(qc); } -static void mv_intr_edma(struct ata_port *ap) +static void mv_process_crpb_response(struct ata_port *ap, + struct mv_crpb *response, unsigned int tag, int ncq_enabled) +{ + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); + + if (qc) { + u8 ata_status; + u16 edma_status = le16_to_cpu(response->flags); + /* + * edma_status from a response queue entry: + * LSB is from EDMA_ERR_IRQ_CAUSE_OFS (non-NCQ only). + * MSB is saved ATA status from command completion. + */ + if (!ncq_enabled) { + u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV; + if (err_cause) { + /* + * Error will be seen/handled by mv_err_intr(). + * So do nothing at all here. + */ + return; + } + } + ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; + qc->err_mask |= ac_err_mask(ata_status); + ata_qc_complete(qc); + } else { + ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", + __func__, tag); + } +} + +static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_host_priv *hpriv = ap->host->private_data; - struct mv_port_priv *pp = ap->private_data; - struct ata_queued_cmd *qc; - u32 out_index, in_index; + u32 in_index; bool work_done = false; + int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN); - /* get h/w response queue pointer */ + /* Get the hardware queue position index */ in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; - while (1) { - u16 status; + /* Process new responses from since the last time we looked */ + while (in_index != pp->resp_idx) { unsigned int tag; + struct mv_crpb *response = &pp->crpb[pp->resp_idx]; - /* get s/w response queue last-read pointer, and compare */ - out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK; - if (in_index == out_index) - break; + pp->resp_idx = (pp->resp_idx + 1) & MV_MAX_Q_DEPTH_MASK; - /* 50xx: get active ATA command */ - if (IS_GEN_I(hpriv)) + if (IS_GEN_I(hpriv)) { + /* 50xx: no NCQ, only one command active at a time */ tag = ap->link.active_tag; - - /* Gen II/IIE: get active ATA command via tag, to enable - * support for queueing. this works transparently for - * queued and non-queued modes. - */ - else - tag = le16_to_cpu(pp->crpb[out_index].id) & 0x1f; - - qc = ata_qc_from_tag(ap, tag); - - /* For non-NCQ mode, the lower 8 bits of status - * are from EDMA_ERR_IRQ_CAUSE_OFS, - * which should be zero if all went well. - */ - status = le16_to_cpu(pp->crpb[out_index].flags); - if ((status & 0xff) && !(pp->pp_flags & MV_PP_FLAG_NCQ_EN)) { - mv_err_intr(ap, qc); - return; - } - - /* and finally, complete the ATA command */ - if (qc) { - qc->err_mask |= - ac_err_mask(status >> CRPB_FLAG_STATUS_SHIFT); - ata_qc_complete(qc); + } else { + /* Gen II/IIE: get command tag from CRPB entry */ + tag = le16_to_cpu(response->id) & 0x1f; } - - /* advance software response queue pointer, to - * indicate (after the loop completes) to hardware - * that we have consumed a response queue entry. - */ + mv_process_crpb_response(ap, response, tag, ncq_enabled); work_done = true; - pp->resp_idx++; } /* Update the software queue position index in hardware */ if (work_done) writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | - (out_index << EDMA_RSP_Q_PTR_SHIFT), + (pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT), port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); } @@ -1748,7 +1751,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { if ((DMA_IRQ << hardport) & hc_irq_cause) - mv_intr_edma(ap); + mv_process_crpb_entries(ap, pp); } else { if ((DEV_IRQ << hardport) & hc_irq_cause) mv_intr_pio(ap); -- cgit v1.2.2 From a3718c1f230240361ed92d3e53342df0ff7efa8c Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 15:07:18 -0400 Subject: sata_mv: tidy host controller interrupt handling Tidy up host controller interrupt handling, by moving the weirdo bit shifting from mv_interrupt() to mv_host_intr(). This lets us take advantage of the MV_PORT_TO_SHIFT_AND_HARDPORT() macro from an earlier patch to greatly simplify the port numbering logic. Also, defer reading the hc_irq_cause (one per hc) until it is actually proven to be needed. This may save a microsecond or so per interrupt, on average (a later patchset will further reduce unnecessary register reads throughout the driver). Apart from that, we still leave the actual IRQ handling logic alone. Subsequent patches in this series will address that. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 107 +++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index cee78f9e9d1b..97da46a86fdd 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1693,50 +1693,48 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp * LOCKING: * Inherited from caller. */ -static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) +static int mv_host_intr(struct ata_host *host, u32 main_cause) { struct mv_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->base; - void __iomem *hc_mmio = mv_hc_base(mmio, hc); - u32 hc_irq_cause; - int port, port0, last_port; - - if (hc == 0) - port0 = 0; - else - port0 = MV_PORTS_PER_HC; - - if (HAS_PCI(host)) - last_port = port0 + MV_PORTS_PER_HC; - else - last_port = port0 + hpriv->n_ports; - /* we'll need the HC success int register in most cases */ - hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); - if (!hc_irq_cause) - return; - - writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); + void __iomem *mmio = hpriv->base, *hc_mmio = NULL; + u32 hc_irq_cause = 0; + unsigned int handled = 0, port; - VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n", - hc, relevant, hc_irq_cause); - - for (port = port0; port < last_port; port++) { + for (port = 0; port < hpriv->n_ports; port++) { struct ata_port *ap = host->ports[port]; struct mv_port_priv *pp; - int have_err_bits, hardport, shift; - - if ((!ap) || (ap->flags & ATA_FLAG_DISABLED)) + unsigned int shift, hardport, port_cause; + /* + * When we move to the second hc, flag our cached + * copies of hc_mmio (and hc_irq_cause) as invalid again. + */ + if (port == MV_PORTS_PER_HC) + hc_mmio = NULL; + /* + * Do nothing if port is not interrupting or is disabled: + */ + MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); + port_cause = (main_cause >> shift) & (DONE_IRQ | ERR_IRQ); + if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED)) continue; + /* + * Each hc within the host has its own hc_irq_cause register. + * We defer reading it until we know we need it, right now: + * + * FIXME later: we don't really need to read this register + * (some logic changes required below if we go that way), + * because it doesn't tell us anything new. But we do need + * to write to it, outside the top of this loop, + * to reset the interrupt triggers for next time. + */ + if (!hc_mmio) { + hc_mmio = mv_hc_base_from_port(mmio, port); + hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); + writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); + handled = 1; + } - pp = ap->private_data; - - shift = port << 1; /* (port * 2) */ - if (port >= MV_PORTS_PER_HC) - shift++; /* skip bit 8 in the HC Main IRQ reg */ - - have_err_bits = ((ERR_IRQ << shift) & relevant); - - if (unlikely(have_err_bits)) { + if (unlikely(port_cause & ERR_IRQ)) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->link.active_tag); @@ -1747,8 +1745,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) continue; } - hardport = mv_hardport_from_port(port); /* range 0..3 */ - + pp = ap->private_data; if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { if ((DMA_IRQ << hardport) & hc_irq_cause) mv_process_crpb_entries(ap, pp); @@ -1757,10 +1754,10 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) mv_intr_pio(ap); } } - VPRINTK("EXIT\n"); + return handled; } -static void mv_pci_error(struct ata_host *host, void __iomem *mmio) +static int mv_pci_error(struct ata_host *host, void __iomem *mmio) { struct mv_host_priv *hpriv = host->private_data; struct ata_port *ap; @@ -1798,6 +1795,7 @@ static void mv_pci_error(struct ata_host *host, void __iomem *mmio) ata_port_freeze(ap); } } + return 1; /* handled */ } /** @@ -1818,8 +1816,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; struct mv_host_priv *hpriv = host->private_data; - unsigned int hc, handled = 0, n_hcs; - void __iomem *mmio = hpriv->base; + unsigned int handled = 0; u32 main_cause, main_mask; spin_lock(&host->lock); @@ -1829,26 +1826,12 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) * Deal with cases where we either have nothing pending, or have read * a bogus register value which can indicate HW removal or PCI fault. */ - if (!(main_cause & main_mask) || (main_cause == 0xffffffffU)) - goto out_unlock; - - n_hcs = mv_get_hc_count(host->ports[0]->flags); - - if (unlikely((main_cause & PCI_ERR) && HAS_PCI(host))) { - mv_pci_error(host, mmio); - handled = 1; - goto out_unlock; /* skip all other HC irq handling */ - } - - for (hc = 0; hc < n_hcs; hc++) { - u32 relevant = main_cause & (HC0_IRQ_PEND << (hc * HC_SHIFT)); - if (relevant) { - mv_host_intr(host, relevant, hc); - handled = 1; - } + if ((main_cause & main_mask) && (main_cause != 0xffffffffU)) { + if (unlikely((main_cause & PCI_ERR) && HAS_PCI(host))) + handled = mv_pci_error(host, hpriv->base); + else + handled = mv_host_intr(host, main_cause); } - -out_unlock: spin_unlock(&host->lock); return IRQ_RETVAL(handled); } -- cgit v1.2.2 From 8f767f8a02e6c65d393fd0f2ca19a91c9898cc2d Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 14:53:07 -0400 Subject: sata_mv: more interrupt handling rework Continue fixing the interrupt handling logic. Get rid of mv_intr_pio(), by using ata_sff_host_intr() for PIO.. Add a mv_unexpected_intr() catch-all for "impossible" scenarios, where we get an interrupt that shouldn't have happened (never seen in testing, but just in case..). Rearrange the logic so that we always process completed response queue entries before looking for other events, This avoids having to re-issue commands that had already succeeded. As part of this, we split out some duplicated functionality into a new function, mv_get_active_qc(). Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 106 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 97da46a86fdd..944359256959 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1483,6 +1483,43 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) return 0; } +static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) +{ + struct mv_port_priv *pp = ap->private_data; + struct ata_queued_cmd *qc; + + if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) + return NULL; + qc = ata_qc_from_tag(ap, ap->link.active_tag); + if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) + qc = NULL; + return qc; +} + +static void mv_unexpected_intr(struct ata_port *ap) +{ + struct mv_port_priv *pp = ap->private_data; + struct ata_eh_info *ehi = &ap->link.eh_info; + char *when = ""; + + /* + * We got a device interrupt from something that + * was supposed to be using EDMA or polling. + */ + ata_ehi_clear_desc(ehi); + if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { + when = " while EDMA enabled"; + } else { + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); + if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) + when = " while polling"; + } + ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when); + ehi->err_mask |= AC_ERR_OTHER; + ehi->action |= ATA_EH_RESET; + ata_port_freeze(ap); +} + /** * mv_err_intr - Handle error interrupts on the port * @ap: ATA channel to manipulate @@ -1586,28 +1623,6 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ata_port_abort(ap); } -static void mv_intr_pio(struct ata_port *ap) -{ - struct ata_queued_cmd *qc; - u8 ata_status; - - /* ignore spurious intr if drive still BUSY */ - ata_status = readb(ap->ioaddr.status_addr); - if (unlikely(ata_status & ATA_BUSY)) - return; - - /* get active ATA command */ - qc = ata_qc_from_tag(ap, ap->link.active_tag); - if (unlikely(!qc)) /* no active tag */ - return; - if (qc->tf.flags & ATA_TFLAG_POLLING) /* polling; we don't own qc */ - return; - - /* and finally, complete the ATA command */ - qc->err_mask |= ac_err_mask(ata_status); - ata_qc_complete(qc); -} - static void mv_process_crpb_response(struct ata_port *ap, struct mv_crpb *response, unsigned int tag, int ncq_enabled) { @@ -1680,15 +1695,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp /** * mv_host_intr - Handle all interrupts on the given host controller * @host: host specific structure - * @relevant: port error bits relevant to this host controller - * @hc: which host controller we're to look at - * - * Read then write clear the HC interrupt status then walk each - * port connected to the HC and see if it needs servicing. Port - * success ints are reported in the HC interrupt status reg, the - * port error ints are reported in the higher level main - * interrupt status register and thus are passed in via the - * 'relevant' argument. + * @main_cause: Main interrupt cause register for the chip. * * LOCKING: * Inherited from caller. @@ -1733,25 +1740,28 @@ static int mv_host_intr(struct ata_host *host, u32 main_cause) writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); handled = 1; } - - if (unlikely(port_cause & ERR_IRQ)) { - struct ata_queued_cmd *qc; - - qc = ata_qc_from_tag(ap, ap->link.active_tag); - if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) - continue; - - mv_err_intr(ap, qc); - continue; - } - + /* + * Process completed CRPB response(s) before other events. + */ pp = ap->private_data; - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - if ((DMA_IRQ << hardport) & hc_irq_cause) + if (hc_irq_cause & (DMA_IRQ << hardport)) { + if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) mv_process_crpb_entries(ap, pp); - } else { - if ((DEV_IRQ << hardport) & hc_irq_cause) - mv_intr_pio(ap); + } + /* + * Handle chip-reported errors, or continue on to handle PIO. + */ + if (unlikely(port_cause & ERR_IRQ)) { + mv_err_intr(ap, mv_get_active_qc(ap)); + } else if (hc_irq_cause & (DEV_IRQ << hardport)) { + if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { + struct ata_queued_cmd *qc = mv_get_active_qc(ap); + if (qc) { + ata_sff_host_intr(ap, qc); + continue; + } + } + mv_unexpected_intr(ap); } } return handled; -- cgit v1.2.2 From 8d07379d251ab24d937e6cb0748b71106dddbc74 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 15:07:49 -0400 Subject: sata_mv: leave SError bits untouched in mv_err_intr Here it is again, minus the checkpatch.pl complaint: Rework mv_err_intr() to leave the SError bits as-is, so that libata-eh has a chance to see/use them. We originally thought that clearing them here was necessary before writing back to edma_err_cause (per the Marvell datasheets), but we will end up reseting the chip regardless in those cases. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 944359256959..4fa54805eb41 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1523,13 +1523,11 @@ static void mv_unexpected_intr(struct ata_port *ap) /** * mv_err_intr - Handle error interrupts on the port * @ap: ATA channel to manipulate - * @reset_allowed: bool: 0 == don't trigger from reset here + * @qc: affected command (non-NCQ), or NULL * - * In most cases, just clear the interrupt and move on. However, - * some cases require an eDMA reset, which also performs a COMRESET. - * The SERR case requires a clear of pending errors in the SATA - * SERROR register. Finally, if the port disabled DMA, - * update our cached copy to match. + * Most cases require a full reset of the chip's state machine, + * which also performs a COMRESET. + * Also, if the port disabled DMA, update our cached copy to match. * * LOCKING: * Inherited from caller. @@ -1540,21 +1538,18 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) u32 edma_err_cause, eh_freeze_mask, serr = 0; struct mv_port_priv *pp = ap->private_data; struct mv_host_priv *hpriv = ap->host->private_data; - unsigned int edma_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN); unsigned int action = 0, err_mask = 0; struct ata_eh_info *ehi = &ap->link.eh_info; ata_ehi_clear_desc(ehi); - if (!edma_enabled) { - /* just a guess: do we need to do this? should we - * expand this, and do it in all cases? - */ - sata_scr_read(&ap->link, SCR_ERROR, &serr); - sata_scr_write_flush(&ap->link, SCR_ERROR, serr); - } - + /* + * Read and clear the err_cause bits. This won't actually + * clear for some errors (eg. SError), but we will be doing + * a hard reset in those cases regardless, which *will* clear it. + */ edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); + writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause); @@ -1594,16 +1589,19 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ata_ehi_push_desc(ehi, "EDMA self-disable"); } if (edma_err_cause & EDMA_ERR_SERR) { - sata_scr_read(&ap->link, SCR_ERROR, &serr); - sata_scr_write_flush(&ap->link, SCR_ERROR, serr); - err_mask = AC_ERR_ATA_BUS; + /* + * Ensure that we read our own SCR, not a pmp link SCR: + */ + ap->ops->scr_read(ap, SCR_ERROR, &serr); + /* + * Don't clear SError here; leave it for libata-eh: + */ + ata_ehi_push_desc(ehi, "SError=%08x", serr); + err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_RESET; } } - /* Clear EDMA now that SERR cleanup done */ - writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); - if (!err_mask) { err_mask = AC_ERR_OTHER; action |= ATA_EH_RESET; -- cgit v1.2.2 From 85afb934575abdff1b2ac8ea4d522d1355f22a89 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Sat, 19 Apr 2008 14:54:41 -0400 Subject: sata_mv: re-enable hotplug, update TODO list Re-enable hotplug, now that the interrupt/error handling are mostly sane. Also update the TODO list at the top. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 79 +++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 4fa54805eb41..26a6337195b3 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -23,46 +23,34 @@ */ /* - sata_mv TODO list: - - 1) Needs a full errata audit for all chipsets. I implemented most - of the errata workarounds found in the Marvell vendor driver, but - I distinctly remember a couple workarounds (one related to PCI-X) - are still needed. - - 2) Improve/fix IRQ and error handling sequences. - - 3) ATAPI support (Marvell claims the 60xx/70xx chips can do it). - - 4) Think about TCQ support here, and for libata in general - with controllers that suppport it via host-queuing hardware - (a software-only implementation could be a nightmare). - - 5) Investigate problems with PCI Message Signalled Interrupts (MSI). - - 6) Cache frequently-accessed registers in mv_port_priv to reduce overhead. - - 7) Fix/reenable hot plug/unplug (should happen as a side-effect of (2) above). - - 8) Develop a low-power-consumption strategy, and implement it. - - 9) [Experiment, low priority] See if ATAPI can be supported using - "unknown FIS" or "vendor-specific FIS" support, or something creative - like that. - - 10) [Experiment, low priority] Investigate interrupt coalescing. - Quite often, especially with PCI Message Signalled Interrupts (MSI), - the overhead reduced by interrupt mitigation is quite often not - worth the latency cost. - - 11) [Experiment, Marvell value added] Is it possible to use target - mode to cross-connect two Linux boxes with Marvell cards? If so, - creating LibATA target mode support would be very interesting. - - Target mode, for those without docs, is the ability to directly - connect two SATA controllers. - -*/ + * sata_mv TODO list: + * + * --> Errata workaround for NCQ device errors. + * + * --> More errata workarounds for PCI-X. + * + * --> Complete a full errata audit for all chipsets to identify others. + * + * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). + * + * --> Investigate problems with PCI Message Signalled Interrupts (MSI). + * + * --> Cache frequently-accessed registers in mv_port_priv to reduce overhead. + * + * --> Develop a low-power-consumption strategy, and implement it. + * + * --> [Experiment, low priority] Investigate interrupt coalescing. + * Quite often, especially with PCI Message Signalled Interrupts (MSI), + * the overhead reduced by interrupt mitigation is quite often not + * worth the latency cost. + * + * --> [Experiment, Marvell value added] Is it possible to use target + * mode to cross-connect two Linux boxes with Marvell cards? If so, + * creating LibATA target mode support would be very interesting. + * + * Target mode, for those without docs, is the ability to directly + * connect two SATA ports. + */ #include #include @@ -300,9 +288,7 @@ enum { EDMA_ERR_IRQ_TRANSIENT = EDMA_ERR_LNK_CTRL_RX_0 | EDMA_ERR_LNK_CTRL_RX_1 | EDMA_ERR_LNK_CTRL_RX_3 | - EDMA_ERR_LNK_CTRL_TX | - /* temporary, until we fix hotplug: */ - (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON), + EDMA_ERR_LNK_CTRL_TX, EDMA_EH_FREEZE = EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | @@ -2124,13 +2110,6 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); rc = 1; } - /* - * Temporary: wait 3 seconds before port-probing can happen, - * so that we don't miss finding sleepy SilXXXX port-multipliers. - * This can go away once hotplug is fully/correctly implemented. - */ - if (rc == 0) - msleep(3000); done: return rc; } -- cgit v1.2.2 From f9d42491723dbb77bdc9b9dc7e096ea57d535992 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 25 Apr 2008 11:37:54 +0800 Subject: pata_bf54x: decrease count first. When count reaches 0 the postfix decrement still subtracts (to -1), so bfin_reset_controller() returns as if the busy flag was cleared while it was not. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: Jeff Garzik --- drivers/ata/pata_bf54x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index e4cf73c4b70b..a75de0684c15 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1417,7 +1417,7 @@ static int bfin_reset_controller(struct ata_host *host) count = 10000000; do { status = read_atapi_register(base, ATA_REG_STATUS); - } while (count-- && (status & ATA_BUSY)); + } while (--count && (status & ATA_BUSY)); /* Enable only ATAPI Device interrupt */ ATAPI_SET_INT_MASK(base, 1); -- cgit v1.2.2 From f38d1008b034e39397d3da67919e220c851db75e Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Wed, 23 Apr 2008 16:56:17 -0500 Subject: ucc_geth: Fix sneaky merge conflict regarding bus_id The patch that changed mdio_bus to a string didn't conflict strongly enough with the patch that added fixed PHY support to UCC. Gather it back into the fold. Fixes this error: ... CC drivers/net/ucc_geth.o 'ucc_geth_probe': /home/bunk/linux/kernel-2.6/git/linux-2.6/drivers/net/ucc_geth.c:3935: error: incompatible types in assignment make[3]: *** [drivers/net/ucc_geth.o] Error 1 Signed-off-by: Andy Fleming Signed-off-by: Jeff Garzik --- drivers/net/ucc_geth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 29a4d650e8a8..0aac91c3e4e4 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3926,7 +3926,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); fixed_link = of_get_property(np, "fixed-link", NULL); if (fixed_link) { - ug_info->mdio_bus = 0; + snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "0"); ug_info->phy_address = fixed_link[0]; phy = NULL; } else { -- cgit v1.2.2 From b35b3b49fc6750806964048b31799c8782980ef9 Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 23 Apr 2008 13:28:08 -0400 Subject: S2io: Fix memory leak during free_tx_buffers - Fix the memory leak during free_tx_buffers. Signed-off-by: Santosh Rastapur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index dcbe01b0ca0d..ab96aa292b78 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2458,7 +2458,7 @@ static void free_tx_buffers(struct s2io_nic *nic) for (i = 0; i < config->tx_fifo_num; i++) { unsigned long flags; spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags); - for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { + for (j = 0; j < config->tx_cfg[i].fifo_len; j++) { txdp = (struct TxD *) \ mac_control->fifos[i].list_info[j].list_virt_addr; skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); -- cgit v1.2.2 From 10371b5e6ba22173425877ea6a7040619b005fa1 Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 23 Apr 2008 13:28:58 -0400 Subject: S2io: Version update for memory leak fix during free_tx_buffers - Updated version number. Signed-off-by: Santosh Rastapur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ab96aa292b78..81fd7abc27e4 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -86,7 +86,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.20" +#define DRV_VERSION "2.0.26.22" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; -- cgit v1.2.2 From 99993af6981aaf8d212a5efa888a19c9db152d58 Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 23 Apr 2008 13:29:42 -0400 Subject: S2io: Removed receive buffer replenishment tasklet - Removed receive buffer replenishment tasklet s2io_tasklet and instead allocating the receive buffers in either the interrupt handler (no napi) or the napi handler (napi enabled). Signed-off-by: Surjit Reang Signed-off-by: Sreenivasa Honnur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 93 +++--------------------------------------------------- drivers/net/s2io.h | 3 -- 2 files changed, 4 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 81fd7abc27e4..4344e6ed9041 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -117,20 +117,6 @@ static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ ADAPTER_STATUS_RMAC_LOCAL_FAULT))) -#define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status)) -#define PANIC 1 -#define LOW 2 -static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring) -{ - struct mac_info *mac_control; - - mac_control = &sp->mac_control; - if (rxb_size <= rxd_count[sp->rxd_mode]) - return PANIC; - else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) - return LOW; - return 0; -} static inline int is_s2io_card_up(const struct s2io_nic * sp) { @@ -4105,7 +4091,6 @@ static int s2io_close(struct net_device *dev) do_s2io_delete_unicast_mc(sp, tmp64); } - /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); return 0; @@ -4370,29 +4355,9 @@ s2io_alarm_handle(unsigned long data) static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) { - int rxb_size, level; - - if (!sp->lro) { - rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); - level = rx_buffer_level(sp, rxb_size, rng_n); - - if ((level == PANIC) && (!TASKLET_IN_USE)) { - int ret; - DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); - DBG_PRINT(INTR_DBG, "PANIC levels\n"); - if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "Out of memory in %s", - __FUNCTION__); - clear_bit(0, (&sp->tasklet_status)); - return -1; - } - clear_bit(0, (&sp->tasklet_status)); - } else if (level == LOW) - tasklet_schedule(&sp->task); - - } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); - DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); + if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { + DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); + DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } return 0; } @@ -6769,49 +6734,6 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) return ret; } -/** - * s2io_tasklet - Bottom half of the ISR. - * @dev_adr : address of the device structure in dma_addr_t format. - * Description: - * This is the tasklet or the bottom half of the ISR. This is - * an extension of the ISR which is scheduled by the scheduler to be run - * when the load on the CPU is low. All low priority tasks of the ISR can - * be pushed into the tasklet. For now the tasklet is used only to - * replenish the Rx buffers in the Rx buffer descriptors. - * Return value: - * void. - */ - -static void s2io_tasklet(unsigned long dev_addr) -{ - struct net_device *dev = (struct net_device *) dev_addr; - struct s2io_nic *sp = dev->priv; - int i, ret; - struct mac_info *mac_control; - struct config_param *config; - - mac_control = &sp->mac_control; - config = &sp->config; - - if (!TASKLET_IN_USE) { - for (i = 0; i < config->rx_ring_num; i++) { - ret = fill_rx_buffers(sp, i); - if (ret == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s: Out of ", - dev->name); - DBG_PRINT(INFO_DBG, "memory in tasklet\n"); - break; - } else if (ret == -EFILL) { - DBG_PRINT(INFO_DBG, - "%s: Rx Ring %d is full\n", - dev->name, i); - break; - } - } - clear_bit(0, (&sp->tasklet_status)); - } -} - /** * s2io_set_link - Set the LInk status * @data: long pointer to device private structue @@ -7186,9 +7108,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) s2io_rem_isr(sp); - /* Kill tasklet. */ - tasklet_kill(&sp->task); - /* Check if the device is Quiescent and then Reset the NIC */ while(do_io) { /* As per the HW requirement we need to replenish the @@ -7314,9 +7233,6 @@ static int s2io_card_up(struct s2io_nic * sp) S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); - /* Enable tasklet for the device */ - tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); - /* Enable select interrupts */ en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); if (sp->config.intr_type != INTA) @@ -8119,10 +8035,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) s2io_reset(sp); /* - * Initialize the tasklet status and link state flags + * Initialize link state flags * and the card state parameter */ - sp->tasklet_status = 0; sp->state = 0; /* Initialize spinlocks */ diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index e68fdf7e4260..e3136cfd6db2 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -868,8 +868,6 @@ struct s2io_nic { int device_enabled_once; char name[60]; - struct tasklet_struct task; - volatile unsigned long tasklet_status; /* Timer that handles I/O errors/exceptions */ struct timer_list alarm_timer; @@ -1094,7 +1092,6 @@ static void s2io_handle_errors(void * dev_id); static int s2io_starter(void); static void s2io_closer(void); static void s2io_tx_watchdog(struct net_device *dev); -static void s2io_tasklet(unsigned long dev_addr); static void s2io_set_multicast(struct net_device *dev); static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); static void s2io_link(struct s2io_nic * sp, int link); -- cgit v1.2.2 From c9fcbf4774d7a29b73078017af25d100f152a4af Mon Sep 17 00:00:00 2001 From: Sreenivasa Honnur Date: Wed, 23 Apr 2008 13:31:33 -0400 Subject: S2io: Removed rx_lock and put_lock - Removed rx_lock and put_lock as the buffer replenishment and receive completion is handled serially. Signed-off-by: Surjit Reang Signed-off-by: Sreenivasa Honnur Signed-off-by: Ramkrishna Vepa Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 31 ++----------------------------- drivers/net/s2io.h | 6 ------ 2 files changed, 2 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 4344e6ed9041..157fd932e951 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2530,7 +2530,6 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) struct config_param *config; u64 tmp; struct buffAdd *ba; - unsigned long flags; struct RxD_t *first_rxdp = NULL; u64 Buffer0_ptr = 0, Buffer1_ptr = 0; struct RxD1 *rxdp1; @@ -2578,15 +2577,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", dev->name, rxdp); } - if(!napi) { - spin_lock_irqsave(&nic->put_lock, flags); - mac_control->rings[ring_no].put_pos = - (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; - spin_unlock_irqrestore(&nic->put_lock, flags); - } else { - mac_control->rings[ring_no].put_pos = - (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; - } + if ((rxdp->Control_1 & RXD_OWN_XENA) && ((nic->rxd_mode == RXD_MODE_3B) && (rxdp->Control_2 & s2BIT(0)))) { @@ -2964,7 +2955,7 @@ static void rx_intr_handler(struct ring_info *ring_data) { struct s2io_nic *nic = ring_data->nic; struct net_device *dev = (struct net_device *) nic->dev; - int get_block, put_block, put_offset; + int get_block, put_block; struct rx_curr_get_info get_info, put_info; struct RxD_t *rxdp; struct sk_buff *skb; @@ -2973,19 +2964,11 @@ static void rx_intr_handler(struct ring_info *ring_data) struct RxD1* rxdp1; struct RxD3* rxdp3; - spin_lock(&nic->rx_lock); - get_info = ring_data->rx_curr_get_info; get_block = get_info.block_index; memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); put_block = put_info.block_index; rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr; - if (!napi) { - spin_lock(&nic->put_lock); - put_offset = ring_data->put_pos; - spin_unlock(&nic->put_lock); - } else - put_offset = ring_data->put_pos; while (RXD_IS_UP2DT(rxdp)) { /* @@ -3002,7 +2985,6 @@ static void rx_intr_handler(struct ring_info *ring_data) DBG_PRINT(ERR_DBG, "%s: The skb is ", dev->name); DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); - spin_unlock(&nic->rx_lock); return; } if (nic->rxd_mode == RXD_MODE_1) { @@ -3058,8 +3040,6 @@ static void rx_intr_handler(struct ring_info *ring_data) } } } - - spin_unlock(&nic->rx_lock); } /** @@ -7083,7 +7063,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) { int cnt = 0; struct XENA_dev_config __iomem *bar0 = sp->bar0; - unsigned long flags; register u64 val64 = 0; struct config_param *config; config = &sp->config; @@ -7142,9 +7121,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) free_tx_buffers(sp); /* Free all Rx buffers */ - spin_lock_irqsave(&sp->rx_lock, flags); free_rx_buffers(sp); - spin_unlock_irqrestore(&sp->rx_lock, flags); clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state)); } @@ -8044,10 +8021,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) for (i = 0; i < sp->config.tx_fifo_num; i++) spin_lock_init(&mac_control->fifos[i].tx_lock); - if (!napi) - spin_lock_init(&sp->put_lock); - spin_lock_init(&sp->rx_lock); - /* * SXE-002: Configure link and activity LED to init state * on driver load. diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index e3136cfd6db2..ce53a02105f2 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -703,9 +703,6 @@ struct ring_info { */ struct rx_curr_get_info rx_curr_get_info; - /* Index to the absolute position of the put pointer of Rx ring */ - int put_pos; - /* Buffer Address store. */ struct buffAdd **ba; struct s2io_nic *nic; @@ -877,8 +874,6 @@ struct s2io_nic { atomic_t rx_bufs_left[MAX_RX_RINGS]; - spinlock_t put_lock; - #define PROMISC 1 #define ALL_MULTI 2 @@ -962,7 +957,6 @@ struct s2io_nic { u8 lro; u16 lro_max_aggr_per_sess; volatile unsigned long state; - spinlock_t rx_lock; u64 general_int_mask; #define VPD_STRING_LEN 80 u8 product_name[VPD_STRING_LEN]; -- cgit v1.2.2 From 7c25769f88ff0b186766d6a9f9390a2e9fd4670f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 23 Apr 2008 11:09:00 -0700 Subject: e1000e: cleanup several stats issues Several stats registers are completely unused and we just waste pci bus time reading them. We also omit using the high 32 bits of the GORC/ GOTC counters. We can just read clear them and only read the low registers. Mii-tool can also break es2lan if it executes a MII PHY register ioctl while the device is in autonegotiation. Unfortunately it seems that several applications and installations still perform this ioctl call periodically and especially in this crucial startup time. We can fool the ioctl by providing fail safe information that mimics the "down" link state and only perform the dangerous PHY reads once after link comes up to fill in the real values. As long as link stays up the information will not change. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/82571.c | 6 -- drivers/net/e1000e/defines.h | 2 + drivers/net/e1000e/e1000.h | 25 +++++-- drivers/net/e1000e/es2lan.c | 2 - drivers/net/e1000e/ethtool.c | 6 +- drivers/net/e1000e/hw.h | 12 ++-- drivers/net/e1000e/netdev.c | 155 ++++++++++++++++++++++++++----------------- 7 files changed, 122 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 01c88664bad3..462351ca2c81 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1326,12 +1326,10 @@ struct e1000_info e1000_82571_info = { .mac = e1000_82571, .flags = FLAG_HAS_HW_VLAN_FILTER | FLAG_HAS_JUMBO_FRAMES - | FLAG_HAS_STATS_PTC_PRC | FLAG_HAS_WOL | FLAG_APME_IN_CTRL3 | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD - | FLAG_HAS_STATS_ICR_ICT | FLAG_HAS_SMART_POWER_DOWN | FLAG_RESET_OVERWRITES_LAA /* errata */ | FLAG_TARC_SPEED_MODE_BIT /* errata */ @@ -1347,12 +1345,10 @@ struct e1000_info e1000_82572_info = { .mac = e1000_82572, .flags = FLAG_HAS_HW_VLAN_FILTER | FLAG_HAS_JUMBO_FRAMES - | FLAG_HAS_STATS_PTC_PRC | FLAG_HAS_WOL | FLAG_APME_IN_CTRL3 | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD - | FLAG_HAS_STATS_ICR_ICT | FLAG_TARC_SPEED_MODE_BIT, /* errata */ .pba = 38, .get_variants = e1000_get_variants_82571, @@ -1365,11 +1361,9 @@ struct e1000_info e1000_82573_info = { .mac = e1000_82573, .flags = FLAG_HAS_HW_VLAN_FILTER | FLAG_HAS_JUMBO_FRAMES - | FLAG_HAS_STATS_PTC_PRC | FLAG_HAS_WOL | FLAG_APME_IN_CTRL3 | FLAG_RX_CSUM_ENABLED - | FLAG_HAS_STATS_ICR_ICT | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_ERT diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 572cfd44397a..4fb9d8722739 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -527,8 +527,10 @@ #define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ #define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ #define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ #define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ /* NVM Control */ #define E1000_EECD_SK 0x00000001 /* NVM Clock */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 5a89dff52264..4d3d1c2991c9 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -147,6 +147,18 @@ struct e1000_ring { struct e1000_queue_stats stats; }; +/* PHY register snapshot values */ +struct e1000_phy_regs { + u16 bmcr; /* basic mode control register */ + u16 bmsr; /* basic mode status register */ + u16 advertise; /* auto-negotiation advertisement */ + u16 lpa; /* link partner ability register */ + u16 expansion; /* auto-negotiation expansion reg */ + u16 ctrl1000; /* 1000BASE-T control register */ + u16 stat1000; /* 1000BASE-T status register */ + u16 estatus; /* extended status register */ +}; + /* board specific private data structure */ struct e1000_adapter { struct timer_list watchdog_timer; @@ -202,8 +214,8 @@ struct e1000_adapter { /* Tx stats */ u64 tpt_old; u64 colc_old; - u64 gotcl_old; - u32 gotcl; + u32 gotc; + u64 gotc_old; u32 tx_timeout_count; u32 tx_fifo_head; u32 tx_head_addr; @@ -227,8 +239,8 @@ struct e1000_adapter { u64 hw_csum_err; u64 hw_csum_good; u64 rx_hdr_split; - u64 gorcl_old; - u32 gorcl; + u32 gorc; + u64 gorc_old; u32 alloc_rx_buff_failed; u32 rx_dma_failed; @@ -250,6 +262,9 @@ struct e1000_adapter { struct e1000_phy_info phy_info; struct e1000_phy_stats phy_stats; + /* Snapshot of PHY registers */ + struct e1000_phy_regs phy_regs; + struct e1000_ring test_tx_ring; struct e1000_ring test_rx_ring; u32 test_icr; @@ -286,8 +301,6 @@ struct e1000_info { #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) -#define FLAG_HAS_STATS_ICR_ICT (1 << 9) -#define FLAG_HAS_STATS_PTC_PRC (1 << 10) #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) #define FLAG_IS_QUAD_PORT_A (1 << 12) #define FLAG_IS_QUAD_PORT (1 << 13) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index d59a99ae44be..13a6f4484de9 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -1231,12 +1231,10 @@ struct e1000_info e1000_es2_info = { .mac = e1000_80003es2lan, .flags = FLAG_HAS_HW_VLAN_FILTER | FLAG_HAS_JUMBO_FRAMES - | FLAG_HAS_STATS_PTC_PRC | FLAG_HAS_WOL | FLAG_APME_IN_CTRL3 | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD - | FLAG_HAS_STATS_ICR_ICT | FLAG_RX_NEEDS_RESTART /* errata */ | FLAG_TARC_SET_BIT_ZERO /* errata */ | FLAG_APME_CHECK_PORT_B diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 6d1b257bbda6..c894a6f03bb4 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -46,8 +46,8 @@ struct e1000_stats { static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_packets", E1000_STAT(stats.gprc) }, { "tx_packets", E1000_STAT(stats.gptc) }, - { "rx_bytes", E1000_STAT(stats.gorcl) }, - { "tx_bytes", E1000_STAT(stats.gotcl) }, + { "rx_bytes", E1000_STAT(stats.gorc) }, + { "tx_bytes", E1000_STAT(stats.gotc) }, { "rx_broadcast", E1000_STAT(stats.bprc) }, { "tx_broadcast", E1000_STAT(stats.bptc) }, { "rx_multicast", E1000_STAT(stats.mprc) }, @@ -83,7 +83,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) }, { "tx_flow_control_xon", E1000_STAT(stats.xontxc) }, { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) }, - { "rx_long_byte_count", E1000_STAT(stats.gorcl) }, + { "rx_long_byte_count", E1000_STAT(stats.gorc) }, { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, { "rx_header_split", E1000_STAT(rx_hdr_split) }, diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 53f1ac6327fa..a930e6d9cf02 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -592,10 +592,8 @@ struct e1000_hw_stats { u64 bprc; u64 mprc; u64 gptc; - u64 gorcl; - u64 gorch; - u64 gotcl; - u64 gotch; + u64 gorc; + u64 gotc; u64 rnbc; u64 ruc; u64 rfc; @@ -604,10 +602,8 @@ struct e1000_hw_stats { u64 mgprc; u64 mgpdc; u64 mgptc; - u64 torl; - u64 torh; - u64 totl; - u64 toth; + u64 tor; + u64 tot; u64 tpr; u64 tpt; u64 ptc64; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c8dc47fd132a..9d1143aa6189 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -466,10 +466,10 @@ next_desc: if (cleaned_count) adapter->alloc_rx_buf(adapter, cleaned_count); - adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; - adapter->net_stats.rx_packets += total_rx_packets; + adapter->total_rx_packets += total_rx_packets; adapter->net_stats.rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; return cleaned; } @@ -606,8 +606,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_packets += total_tx_packets; - adapter->net_stats.tx_packets += total_tx_packets; adapter->net_stats.tx_bytes += total_tx_bytes; + adapter->net_stats.tx_packets += total_tx_packets; return cleaned; } @@ -775,10 +775,10 @@ next_desc: if (cleaned_count) adapter->alloc_rx_buf(adapter, cleaned_count); - adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; - adapter->net_stats.rx_packets += total_rx_packets; + adapter->total_rx_packets += total_rx_packets; adapter->net_stats.rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; return cleaned; } @@ -2506,56 +2506,27 @@ void e1000e_update_stats(struct e1000_adapter *adapter) adapter->stats.crcerrs += er32(CRCERRS); adapter->stats.gprc += er32(GPRC); - adapter->stats.gorcl += er32(GORCL); - adapter->stats.gorch += er32(GORCH); + adapter->stats.gorc += er32(GORCL); + er32(GORCH); /* Clear gorc */ adapter->stats.bprc += er32(BPRC); adapter->stats.mprc += er32(MPRC); adapter->stats.roc += er32(ROC); - if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) { - adapter->stats.prc64 += er32(PRC64); - adapter->stats.prc127 += er32(PRC127); - adapter->stats.prc255 += er32(PRC255); - adapter->stats.prc511 += er32(PRC511); - adapter->stats.prc1023 += er32(PRC1023); - adapter->stats.prc1522 += er32(PRC1522); - adapter->stats.symerrs += er32(SYMERRS); - adapter->stats.sec += er32(SEC); - } - adapter->stats.mpc += er32(MPC); adapter->stats.scc += er32(SCC); adapter->stats.ecol += er32(ECOL); adapter->stats.mcc += er32(MCC); adapter->stats.latecol += er32(LATECOL); adapter->stats.dc += er32(DC); - adapter->stats.rlec += er32(RLEC); adapter->stats.xonrxc += er32(XONRXC); adapter->stats.xontxc += er32(XONTXC); adapter->stats.xoffrxc += er32(XOFFRXC); adapter->stats.xofftxc += er32(XOFFTXC); - adapter->stats.fcruc += er32(FCRUC); adapter->stats.gptc += er32(GPTC); - adapter->stats.gotcl += er32(GOTCL); - adapter->stats.gotch += er32(GOTCH); + adapter->stats.gotc += er32(GOTCL); + er32(GOTCH); /* Clear gotc */ adapter->stats.rnbc += er32(RNBC); adapter->stats.ruc += er32(RUC); - adapter->stats.rfc += er32(RFC); - adapter->stats.rjc += er32(RJC); - adapter->stats.torl += er32(TORL); - adapter->stats.torh += er32(TORH); - adapter->stats.totl += er32(TOTL); - adapter->stats.toth += er32(TOTH); - adapter->stats.tpr += er32(TPR); - - if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) { - adapter->stats.ptc64 += er32(PTC64); - adapter->stats.ptc127 += er32(PTC127); - adapter->stats.ptc255 += er32(PTC255); - adapter->stats.ptc511 += er32(PTC511); - adapter->stats.ptc1023 += er32(PTC1023); - adapter->stats.ptc1522 += er32(PTC1522); - } adapter->stats.mptc += er32(MPTC); adapter->stats.bptc += er32(BPTC); @@ -2574,19 +2545,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) adapter->stats.tsctc += er32(TSCTC); adapter->stats.tsctfc += er32(TSCTFC); - adapter->stats.iac += er32(IAC); - - if (adapter->flags & FLAG_HAS_STATS_ICR_ICT) { - adapter->stats.icrxoc += er32(ICRXOC); - adapter->stats.icrxptc += er32(ICRXPTC); - adapter->stats.icrxatc += er32(ICRXATC); - adapter->stats.ictxptc += er32(ICTXPTC); - adapter->stats.ictxatc += er32(ICTXATC); - adapter->stats.ictxqec += er32(ICTXQEC); - adapter->stats.ictxqmtc += er32(ICTXQMTC); - adapter->stats.icrxdmtc += er32(ICRXDMTC); - } - /* Fill out the OS statistics structure */ adapter->net_stats.multicast = adapter->stats.mprc; adapter->net_stats.collisions = adapter->stats.colc; @@ -2633,6 +2591,54 @@ void e1000e_update_stats(struct e1000_adapter *adapter) spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); } +/** + * e1000_phy_read_status - Update the PHY register status snapshot + * @adapter: board private structure + **/ +static void e1000_phy_read_status(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + struct e1000_phy_regs *phy = &adapter->phy_regs; + int ret_val; + unsigned long irq_flags; + + + spin_lock_irqsave(&adapter->stats_lock, irq_flags); + + if ((er32(STATUS) & E1000_STATUS_LU) && + (adapter->hw.phy.media_type == e1000_media_type_copper)) { + ret_val = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr); + ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr); + ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise); + ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa); + ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion); + ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000); + ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000); + ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus); + if (ret_val) + ndev_warn(adapter->netdev, + "Error reading PHY register\n"); + } else { + /* + * Do not read PHY registers if link is not up + * Set values to typical power-on defaults + */ + phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX); + phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | + BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE | + BMSR_ERCAP); + phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP | + ADVERTISE_ALL | ADVERTISE_CSMA); + phy->lpa = 0; + phy->expansion = EXPANSION_ENABLENPAGE; + phy->ctrl1000 = ADVERTISE_1000FULL; + phy->stat1000 = 0; + phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); + } + + spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); +} + static void e1000_print_link_info(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; @@ -2745,6 +2751,7 @@ static void e1000_watchdog_task(struct work_struct *work) if (!netif_carrier_ok(netdev)) { bool txb2b = 1; /* update snapshot of PHY registers on LSC */ + e1000_phy_read_status(adapter); mac->ops.get_link_up_info(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); @@ -2842,10 +2849,10 @@ link_up: mac->collision_delta = adapter->stats.colc - adapter->colc_old; adapter->colc_old = adapter->stats.colc; - adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old; - adapter->gorcl_old = adapter->stats.gorcl; - adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old; - adapter->gotcl_old = adapter->stats.gotcl; + adapter->gorc = adapter->stats.gorc - adapter->gorc_old; + adapter->gorc_old = adapter->stats.gorc; + adapter->gotc = adapter->stats.gotc - adapter->gotc_old; + adapter->gotc_old = adapter->stats.gotc; e1000e_update_adaptive(&adapter->hw); @@ -3500,7 +3507,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, { struct e1000_adapter *adapter = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(ifr); - unsigned long irq_flags; if (adapter->hw.phy.media_type != e1000_media_type_copper) return -EOPNOTSUPP; @@ -3512,13 +3518,40 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) return -EPERM; - spin_lock_irqsave(&adapter->stats_lock, irq_flags); - if (e1e_rphy(&adapter->hw, data->reg_num & 0x1F, - &data->val_out)) { - spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); + switch (data->reg_num & 0x1F) { + case MII_BMCR: + data->val_out = adapter->phy_regs.bmcr; + break; + case MII_BMSR: + data->val_out = adapter->phy_regs.bmsr; + break; + case MII_PHYSID1: + data->val_out = (adapter->hw.phy.id >> 16); + break; + case MII_PHYSID2: + data->val_out = (adapter->hw.phy.id & 0xFFFF); + break; + case MII_ADVERTISE: + data->val_out = adapter->phy_regs.advertise; + break; + case MII_LPA: + data->val_out = adapter->phy_regs.lpa; + break; + case MII_EXPANSION: + data->val_out = adapter->phy_regs.expansion; + break; + case MII_CTRL1000: + data->val_out = adapter->phy_regs.ctrl1000; + break; + case MII_STAT1000: + data->val_out = adapter->phy_regs.stat1000; + break; + case MII_ESTATUS: + data->val_out = adapter->phy_regs.estatus; + break; + default: return -EIO; } - spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); break; case SIOCSMIIREG: default: -- cgit v1.2.2 From de5b3077da8275e87196a1e34c5535f5279c5e1a Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 23 Apr 2008 11:09:08 -0700 Subject: e1000e: Add interrupt moderation run-time ethtool interface The ethtool -c / -C interface can now be used to modify the irq moderation algorithm. This change does not require an adapter reset and can thus be used at all times. The adapter only supports changing/reading rx-usecs which has special values for 0, 1 and 3: 0 - no irq moderation whatsoever 1 - normal moderation favoring regular mixed traffic (default) 3 - best attempt at low latency possible at cost of CPU For values between 10 and 10000 the rx-usecs defines "the minimum time between successive irqs" in usec, unlike the module parameter. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/e1000.h | 3 +++ drivers/net/e1000e/ethtool.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 4d3d1c2991c9..79a426feffb7 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -70,6 +70,9 @@ struct e1000_info; #define E1000_MAX_RXD 4096 #define E1000_MIN_RXD 80 +#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */ +#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */ + /* Early Receive defines */ #define E1000_ERT_2048 0x100 diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index c894a6f03bb4..ce045acce63e 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1770,6 +1770,47 @@ static int e1000_phys_id(struct net_device *netdev, u32 data) return 0; } +static int e1000_get_coalesce(struct net_device *netdev, + struct ethtool_coalesce *ec) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + + if (adapter->itr_setting <= 3) + ec->rx_coalesce_usecs = adapter->itr_setting; + else + ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; + + return 0; +} + +static int e1000_set_coalesce(struct net_device *netdev, + struct ethtool_coalesce *ec) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + + if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || + ((ec->rx_coalesce_usecs > 3) && + (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || + (ec->rx_coalesce_usecs == 2)) + return -EINVAL; + + if (ec->rx_coalesce_usecs <= 3) { + adapter->itr = 20000; + adapter->itr_setting = ec->rx_coalesce_usecs; + } else { + adapter->itr = (1000000 / ec->rx_coalesce_usecs); + adapter->itr_setting = adapter->itr & ~3; + } + + if (adapter->itr_setting != 0) + ew32(ITR, 1000000000 / (adapter->itr * 256)); + else + ew32(ITR, 0); + + return 0; +} + static int e1000_nway_reset(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); @@ -1845,6 +1886,8 @@ static const struct ethtool_ops e1000_ethtool_ops = { .phys_id = e1000_phys_id, .get_ethtool_stats = e1000_get_ethtool_stats, .get_sset_count = e1000e_get_sset_count, + .get_coalesce = e1000_get_coalesce, + .set_coalesce = e1000_set_coalesce, }; void e1000e_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.2 From 2d9498f369706d6db174abd2e75b37732b9dbbde Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 23 Apr 2008 11:09:14 -0700 Subject: e1000e: Fix HW Error on es2lan, ARP capture issue by BMC Several components to this complex fix. The es2lan cards occasionally gave a "HW Error" especially when forcing speed. Some users also reported that the BMC stole ARP packets. The fixes include setting the proper SW_FW bits to tell the BMC that we're active and not do any un-initialization at all, so the setup routine is largely changed. Signed-off-by: David Graham Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/defines.h | 1 + drivers/net/e1000e/e1000.h | 2 + drivers/net/e1000e/es2lan.c | 127 ++++++++++++++++++++++++++++++++----------- drivers/net/e1000e/phy.c | 73 ++++++++++++++----------- 4 files changed, 137 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 4fb9d8722739..2a53875cddbf 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -184,6 +184,7 @@ #define E1000_SWFW_EEP_SM 0x1 #define E1000_SWFW_PHY0_SM 0x2 #define E1000_SWFW_PHY1_SM 0x4 +#define E1000_SWFW_CSR_SM 0x8 /* Device Control */ #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 79a426feffb7..f6835c321516 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -449,6 +449,8 @@ extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, u32 usec_interval, bool *success); extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); +extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); +extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000e_check_downshift(struct e1000_hw *hw); static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 13a6f4484de9..dc552d7d6fac 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -41,6 +41,7 @@ #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 #define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 #define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 +#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F #define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 #define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 @@ -48,6 +49,7 @@ #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 +#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 @@ -85,6 +87,9 @@ /* Kumeran Mode Control Register (Page 193, Register 16) */ #define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 +/* Max number of times Kumeran read/write should be validated */ +#define GG82563_MAX_KMRN_RETRY 0x5 + /* Power Management Control Register (Page 193, Register 20) */ #define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enable SERDES Electrical Idle */ @@ -270,6 +275,7 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) u16 mask; mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; + mask |= E1000_SWFW_CSR_SM; return e1000_acquire_swfw_sync_80003es2lan(hw, mask); } @@ -286,6 +292,8 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) u16 mask; mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; + mask |= E1000_SWFW_CSR_SM; + e1000_release_swfw_sync_80003es2lan(hw, mask); } @@ -410,20 +418,27 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 page_select; u16 temp; + ret_val = e1000_acquire_phy_80003es2lan(hw); + if (ret_val) + return ret_val; + /* Select Configuration Page */ - if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) + if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; - else + } else { /* * Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; + } temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); - ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); - if (ret_val) + ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp); + if (ret_val) { + e1000_release_phy_80003es2lan(hw); return ret_val; + } /* * The "ready" bit in the MDIC register may be incorrectly set @@ -433,20 +448,21 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, udelay(200); /* ...and verify the command was successful. */ - ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); + ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { ret_val = -E1000_ERR_PHY; + e1000_release_phy_80003es2lan(hw); return ret_val; } udelay(200); - ret_val = e1000e_read_phy_reg_m88(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); udelay(200); + e1000_release_phy_80003es2lan(hw); return ret_val; } @@ -467,20 +483,27 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 page_select; u16 temp; + ret_val = e1000_acquire_phy_80003es2lan(hw); + if (ret_val) + return ret_val; + /* Select Configuration Page */ - if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) + if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; - else + } else { /* * Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; + } temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); - ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); - if (ret_val) + ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp); + if (ret_val) { + e1000_release_phy_80003es2lan(hw); return ret_val; + } /* @@ -491,18 +514,20 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, udelay(200); /* ...and verify the command was successful. */ - ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); + ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); - if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) + if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { + e1000_release_phy_80003es2lan(hw); return -E1000_ERR_PHY; + } udelay(200); - ret_val = e1000e_write_phy_reg_m88(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); udelay(200); + e1000_release_phy_80003es2lan(hw); return ret_val; } @@ -882,10 +907,10 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u32 ctrl_ext; - u16 data; + u32 i = 0; + u16 data, data2; - ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, - &data); + ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); if (ret_val) return ret_val; @@ -893,8 +918,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ data |= GG82563_MSCR_TX_CLK_1000MBPS_25; - ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, - data); + ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, data); if (ret_val) return ret_val; @@ -954,6 +978,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) return ret_val; + ret_val = e1000e_read_kmrn_reg(hw, + E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, + &data); + if (ret_val) + return ret_val; + data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; + ret_val = e1000e_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, + data); + if (ret_val) + return ret_val; + ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data); if (ret_val) return ret_val; @@ -983,9 +1019,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) return ret_val; - ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &data); - if (ret_val) - return ret_val; + do { + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, + &data); + if (ret_val) + return ret_val; + + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, + &data2); + if (ret_val) + return ret_val; + i++; + } while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY)); data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data); @@ -1074,7 +1119,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) { s32 ret_val; u32 tipg; - u16 reg_data; + u32 i = 0; + u16 reg_data, reg_data2; reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, @@ -1088,9 +1134,16 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; ew32(TIPG, tipg); - ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); - if (ret_val) - return ret_val; + do { + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); + if (ret_val) + return ret_val; + + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); + if (ret_val) + return ret_val; + i++; + } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); if (duplex == HALF_DUPLEX) reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; @@ -1112,8 +1165,9 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) { s32 ret_val; - u16 reg_data; + u16 reg_data, reg_data2; u32 tipg; + u32 i = 0; reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, @@ -1127,9 +1181,16 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; ew32(TIPG, tipg); - ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); - if (ret_val) - return ret_val; + do { + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); + if (ret_val) + return ret_val; + + ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); + if (ret_val) + return ret_val; + i++; + } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 3a4574caa75b..e102332a6bee 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -116,7 +116,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) } /** - * e1000_read_phy_reg_mdic - Read MDI control register + * e1000e_read_phy_reg_mdic - Read MDI control register * @hw: pointer to the HW structure * @offset: register offset to be read * @data: pointer to the read data @@ -124,7 +124,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) * Reads the MDI control register in the PHY at offset and stores the * information read to data. **/ -static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; @@ -150,7 +150,7 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * Increasing the time out as testing showed failures with * the lower time out */ - for (i = 0; i < 64; i++) { + for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { udelay(50); mdic = er32(MDIC); if (mdic & E1000_MDIC_READY) @@ -170,14 +170,14 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) } /** - * e1000_write_phy_reg_mdic - Write MDI control register + * e1000e_write_phy_reg_mdic - Write MDI control register * @hw: pointer to the HW structure * @offset: register offset to write to * @data: data to write to register at offset * * Writes data to MDI control register in the PHY at offset. **/ -static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; @@ -199,9 +199,13 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) ew32(MDIC, mdic); - /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) { - udelay(5); + /* + * Poll the ready bit to see if the MDI read completed + * Increasing the time out as testing showed failures with + * the lower time out + */ + for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { + udelay(50); mdic = er32(MDIC); if (mdic & E1000_MDIC_READY) break; @@ -210,6 +214,10 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) hw_dbg(hw, "MDI Write did not complete\n"); return -E1000_ERR_PHY; } + if (mdic & E1000_MDIC_ERROR) { + hw_dbg(hw, "MDI Error\n"); + return -E1000_ERR_PHY; + } return 0; } @@ -232,9 +240,8 @@ s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) if (ret_val) return ret_val; - ret_val = e1000_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); hw->phy.ops.release_phy(hw); @@ -258,9 +265,8 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) if (ret_val) return ret_val; - ret_val = e1000_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); hw->phy.ops.release_phy(hw); @@ -286,18 +292,17 @@ s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) return ret_val; if (offset > MAX_PHY_MULTI_PAGE_REG) { - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (u16)offset); + ret_val = e1000e_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (u16)offset); if (ret_val) { hw->phy.ops.release_phy(hw); return ret_val; } } - ret_val = e1000_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); hw->phy.ops.release_phy(hw); @@ -322,18 +327,17 @@ s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) return ret_val; if (offset > MAX_PHY_MULTI_PAGE_REG) { - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (u16)offset); + ret_val = e1000e_write_phy_reg_mdic(hw, + IGP01E1000_PHY_PAGE_SELECT, + (u16)offset); if (ret_val) { hw->phy.ops.release_phy(hw); return ret_val; } } - ret_val = e1000_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, + data); hw->phy.ops.release_phy(hw); @@ -420,7 +424,9 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) if (ret_val) return ret_val; - phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + /* For newer PHYs this bit is downshift enable */ + if (phy->type == e1000_phy_m88) + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; /* * Options: @@ -463,7 +469,7 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) if (ret_val) return ret_val; - if (phy->revision < 4) { + if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) { /* * Force TX_CLK in the Extended PHY Specific Control Register * to 25MHz clock. @@ -518,8 +524,11 @@ s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw) return ret_val; } - /* Wait 15ms for MAC to configure PHY from NVM settings. */ - msleep(15); + /* + * Wait 100ms for MAC to configure PHY from NVM settings, to avoid + * timeout issues when LFS is enabled. + */ + msleep(100); /* disable lplu d0 during driver init */ ret_val = e1000_set_d0_lplu_state(hw, 0); @@ -1152,9 +1161,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active) if (!active) { data &= ~IGP02E1000_PM_D3_LPLU; - ret_val = e1e_wphy(hw, - IGP02E1000_PHY_POWER_MGMT, - data); + ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); if (ret_val) return ret_val; /* -- cgit v1.2.2 From 7b1be1987c1e8163b3631dcd1ce4f03707d60c3b Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 23 Apr 2008 11:09:19 -0700 Subject: e1000e: lower ring minimum size to 64 The lower limit of 80 descriptors in the ring is only valid for one older 8254x chipset. All e1000e devices can use as low as 64 descriptors. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/e1000.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index f6835c321516..38bfd0d261fe 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -64,11 +64,11 @@ struct e1000_info; /* Tx/Rx descriptor defines */ #define E1000_DEFAULT_TXD 256 #define E1000_MAX_TXD 4096 -#define E1000_MIN_TXD 80 +#define E1000_MIN_TXD 64 #define E1000_DEFAULT_RXD 256 #define E1000_MAX_RXD 4096 -#define E1000_MIN_RXD 80 +#define E1000_MIN_RXD 64 #define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */ #define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */ -- cgit v1.2.2 From fb3b27bc00ca2b6d69c3a22ff43b4d95fef47bed Mon Sep 17 00:00:00 2001 From: Wendy Xiong Date: Wed, 23 Apr 2008 11:09:24 -0700 Subject: ixgbe: save and restore pcie/msi state to support EEH recovery To enable EEH support for pci-express network adapters, pcie/msi state needs to be saved and restored for that adapter. Tested this EEH patch with Intel 10G pci-express ixgbe adapter. Signed-off-by: Wendy Xiong Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index cb371a8c24a7..7b859220c255 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3431,6 +3431,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } pci_set_master(pdev); + pci_save_state(pdev); #ifdef CONFIG_NETDEVICES_MULTIQUEUE netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES); @@ -3721,6 +3722,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); -- cgit v1.2.2 From aad32739641d3a75818fbe653d4b0d530e965f2f Mon Sep 17 00:00:00 2001 From: Wendy Xiong Date: Wed, 23 Apr 2008 11:09:29 -0700 Subject: e1000e: save and restore pcie/msi state to support EEH recovery To enable EEH support for pci-express network adapters, pcie/msi state needs to be saved and restored for that adapter. Tested this EEH patch with 2ports and 4ports pci-express e1000e adapters. Signed-off-by: Wendy Xiong Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9d1143aa6189..603ef9a6ddc1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3807,6 +3807,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); @@ -3933,6 +3934,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, goto err_pci_reg; pci_set_master(pdev); + pci_save_state(pdev); err = -ENOMEM; netdev = alloc_etherdev(sizeof(struct e1000_adapter)); -- cgit v1.2.2 From c682fc238a9ed45633822f107e1e9de192059bcc Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 23 Apr 2008 11:09:34 -0700 Subject: igb: save and restore pcie/msi state to support EEH recovery To enable EEH support for pci-express network adapters, pcie/msi state needs to be saved and restored for that adapter. [after similar patches for ixgbe and e1000e from Wendy Xiong] Signed-off-by: Auke Kok Cc: Wendy Xiong Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index aaee02e9e3f0..ae398f04c7b4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -871,6 +871,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, goto err_pci_reg; pci_set_master(pdev); + pci_save_state(pdev); err = -ENOMEM; netdev = alloc_etherdev(sizeof(struct igb_adapter)); @@ -4079,6 +4080,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); -- cgit v1.2.2 From f014e97ec6a447184f48a9d43432ab2ad1ffc7d8 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 23 Apr 2008 11:09:39 -0700 Subject: e1000e: Increment version to 0.2.1 Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 603ef9a6ddc1..8991ab8911e2 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -46,7 +46,7 @@ #include "e1000.h" -#define DRV_VERSION "0.2.0" +#define DRV_VERSION "0.2.1" char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.2 From f34ebab68a8e3c80ff4364f4c61734faec5161d4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 22 Apr 2008 10:46:42 +1000 Subject: ibm_newemac: Fix problem with jumbo frame support and EMAC V4.patch This fixes the jumbo frame support on EMAC V4 systems. Now the correct bit is set depending on the EMAC version configured. Tested on Kilauea (405EX) and Canyonlands (460EX). Signed-off-by: Stefan Roese Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 378a23963495..f10c762fd0b2 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -524,7 +524,10 @@ static int emac_configure(struct emac_instance *dev) rx_size = dev->rx_fifo_size_gige; if (dev->ndev->mtu > ETH_DATA_LEN) { - mr1 |= EMAC_MR1_JPSM; + if (emac_has_feature(dev, EMAC_FTR_EMAC4)) + mr1 |= EMAC4_MR1_JPSM; + else + mr1 |= EMAC_MR1_JPSM; dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO; } else dev->stop_timeout = STOP_TIMEOUT_1000; -- cgit v1.2.2 From afd1dee896e8b1cbd24258ac673aeccd803ff582 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 22 Apr 2008 10:46:42 +1000 Subject: ibm_newemac: Add support for 460EX/GT-type MAL rx-channel handling On some 4xx PPC's (e.g. 460EX/GT), the rx channel number is a multiple of 8 (e.g. 8 for EMAC1, 16 for EMAC2), but enabling in MAL_RXCASR needs the divided by 8 value for the bitmask. Signed-off-by: Stefan Roese Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/mal.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 6869f08c9dcb..fb9c9eb114f4 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -136,6 +136,14 @@ void mal_enable_rx_channel(struct mal_instance *mal, int channel) { unsigned long flags; + /* + * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple + * of 8, but enabling in MAL_RXCASR needs the divided by 8 value + * for the bitmask + */ + if (!(channel % 8)) + channel >>= 3; + spin_lock_irqsave(&mal->lock, flags); MAL_DBG(mal, "enable_rx(%d)" NL, channel); @@ -148,6 +156,14 @@ void mal_enable_rx_channel(struct mal_instance *mal, int channel) void mal_disable_rx_channel(struct mal_instance *mal, int channel) { + /* + * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple + * of 8, but enabling in MAL_RXCASR needs the divided by 8 value + * for the bitmask + */ + if (!(channel % 8)) + channel >>= 3; + set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel)); MAL_DBG(mal, "disable_rx(%d)" NL, channel); -- cgit v1.2.2 From 51d4a1cc2e20e2848c6141989f733f0e6548598b Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 22 Apr 2008 10:46:43 +1000 Subject: ibm_newemac: Fix section mismatch warnings This patch fixes several section mismatch warnings in the ibm_newemac driver similar to: WARNING: vmlinux.o(.devinit.text+0x3a04): Section mismatch in reference from the function emac_probe() to the function .devexit.text:tah_detach() The function __devinit emac_probe() references a function __devexit tah_detach(). Signed-off-by: Josh Boyer Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 2 +- drivers/net/ibm_newemac/mal.c | 4 ++-- drivers/net/ibm_newemac/rgmii.c | 2 +- drivers/net/ibm_newemac/tah.c | 2 +- drivers/net/ibm_newemac/zmii.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index f10c762fd0b2..c30348e402d5 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2240,7 +2240,7 @@ static int __devinit emac_of_bus_notify(struct notifier_block *nb, return 0; } -static struct notifier_block emac_of_bus_notifier = { +static struct notifier_block emac_of_bus_notifier __devinitdata = { .notifier_call = emac_of_bus_notify }; diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index fb9c9eb114f4..10c267b2b961 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -61,8 +61,8 @@ int __devinit mal_register_commac(struct mal_instance *mal, return 0; } -void __devexit mal_unregister_commac(struct mal_instance *mal, - struct mal_commac *commac) +void mal_unregister_commac(struct mal_instance *mal, + struct mal_commac *commac) { unsigned long flags; diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 5757788227be..e32da3de2695 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -179,7 +179,7 @@ void rgmii_put_mdio(struct of_device *ofdev, int input) mutex_unlock(&dev->lock); } -void __devexit rgmii_detach(struct of_device *ofdev, int input) +void rgmii_detach(struct of_device *ofdev, int input) { struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); struct rgmii_regs __iomem *p = dev->base; diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index b023d10d7e1c..30173a9fb557 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -35,7 +35,7 @@ int __devinit tah_attach(struct of_device *ofdev, int channel) return 0; } -void __devexit tah_detach(struct of_device *ofdev, int channel) +void tah_detach(struct of_device *ofdev, int channel) { struct tah_instance *dev = dev_get_drvdata(&ofdev->dev); diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 2ea472aeab06..17b154124943 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -189,7 +189,7 @@ void zmii_set_speed(struct of_device *ofdev, int input, int speed) mutex_unlock(&dev->lock); } -void __devexit zmii_detach(struct of_device *ofdev, int input) +void zmii_detach(struct of_device *ofdev, int input) { struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev); -- cgit v1.2.2 From be63c09afe9153be6ba4373d1b69848cf2b32268 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 22 Apr 2008 10:46:44 +1000 Subject: ibm_newemac Use status property for unused/unwired EMACs Convert ibm_newemac to use the of_device_is_available function when checking for unused/unwired EMACs. We leave the current check for an "unused" property to maintain backwards compatibility for older device trees. Newer device trees should simply use the standard "status" property in the EMAC node. Signed-off-by: Josh Boyer Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index c30348e402d5..7c66727359d4 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2562,8 +2562,11 @@ static int __devinit emac_probe(struct of_device *ofdev, struct device_node **blist = NULL; int err, i; - /* Skip unused/unwired EMACS */ - if (of_get_property(np, "unused", NULL)) + /* Skip unused/unwired EMACS. We leave the check for an unused + * property here for now, but new flat device trees should set a + * status property to "disabled" instead. + */ + if (of_get_property(np, "unused", NULL) || !of_device_is_available(np)) return -ENODEV; /* Find ourselves in the bootlist if we are there */ -- cgit v1.2.2 From 0925ab5d385b6cd1c435c82bfc01898c81f3d062 Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Tue, 22 Apr 2008 10:46:46 +1000 Subject: ibm_newemac: PowerPC 440GX EMAC PHY clock workaround The PowerPC 440GX Taishan board fails to reset EMAC3 (reset timeout error) if there's no link. Because of that it fails to find PHY chip. The older ibm_emac driver had a workaround for that: the EMAC_CLK_INTERNAL/EMAC_CLK_EXTERNAL macros, which toggle the Ethernet Clock Select bit in the SDR0_MFR register. This patch does the same for "ibm,emac-440gx" compatible chips. The workaround forces clock on -all- EMACs, so we select clock under global emac_phy_map_lock. BenH: Made that #ifdef CONFIG_PPC_DCR_NATIVE for now as dcri_* stuff doesn't exist for MMIO type DCRs like Cell. Some future rework & improvements of the DCR infrastructure will make that cleaner but for now, this makes it work. Signed-off-by: Valentine Barshak Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 18 +++++++++++++++++- drivers/net/ibm_newemac/core.h | 8 ++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 7c66727359d4..4176dd6a2e83 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include "core.h" @@ -2333,6 +2335,11 @@ static int __devinit emac_init_phy(struct emac_instance *dev) dev->phy.mdio_read = emac_mdio_read; dev->phy.mdio_write = emac_mdio_write; + /* Enable internal clock source */ +#ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS); +#endif /* Configure EMAC with defaults so we can at least use MDIO * This is needed mostly for 440GX */ @@ -2365,6 +2372,12 @@ static int __devinit emac_init_phy(struct emac_instance *dev) if (!emac_mii_phy_probe(&dev->phy, i)) break; } + + /* Enable external clock source */ +#ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_MFR, SDR0_MFR_ECS, 0); +#endif mutex_unlock(&emac_phy_map_lock); if (i == 0x20) { printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name); @@ -2490,8 +2503,11 @@ static int __devinit emac_init_config(struct emac_instance *dev) } /* Check EMAC version */ - if (of_device_is_compatible(np, "ibm,emac4")) + if (of_device_is_compatible(np, "ibm,emac4")) { dev->features |= EMAC_FTR_EMAC4; + if (of_device_is_compatible(np, "ibm,emac-440gx")) + dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; + } /* Fixup some feature bits based on the device tree */ if (of_get_property(np, "has-inverted-stacr-oc", NULL)) diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 4e74d8287c65..96ec48266b4a 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -301,6 +301,10 @@ struct emac_instance { * Set if we have new type STACR with STAOPC */ #define EMAC_FTR_HAS_NEW_STACR 0x00000040 +/* + * Set if we need phy clock workaround for 440gx + */ +#define EMAC_FTR_440GX_PHY_CLK_FIX 0x00000080 /* Right now, we don't quite handle the always/possible masks on the @@ -312,8 +316,8 @@ enum { EMAC_FTRS_POSSIBLE = #ifdef CONFIG_IBM_NEW_EMAC_EMAC4 - EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | - EMAC_FTR_STACR_OC_INVERT | + EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | + EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX | #endif #ifdef CONFIG_IBM_NEW_EMAC_TAH EMAC_FTR_HAS_TAH | -- cgit v1.2.2 From 11121e3008a9282fc185cb2e81eda2d5436d099b Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Tue, 22 Apr 2008 10:46:48 +1000 Subject: ibm_newemac: PowerPC 440EP/440GR EMAC PHY clock workaround This patch adds ibm_newemac PHY clock workaround for 440EP/440GR EMAC attached to a PHY which doesn't generate RX clock if there is no link. The code is based on the previous ibm_emac driver stuff. The 440EP/440GR allows controlling each EMAC clock separately as opposed to global clock selection for 440GX. BenH: Made that #ifdef CONFIG_PPC_DCR_NATIVE for now as dcri_* stuff doesn't exist for MMIO type DCRs like Cell. Some future rework & improvements of the DCR infrastructure will make that cleaner but for now, this makes it work. Signed-off-by: Valentine Barshak Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 43 +++++++++++++++++++++++++++++++++++++++++- drivers/net/ibm_newemac/core.h | 6 +++++- 2 files changed, 47 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 4176dd6a2e83..490d690b5e7f 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -129,10 +129,35 @@ static struct device_node *emac_boot_list[EMAC_BOOT_LIST_SIZE]; static inline void emac_report_timeout_error(struct emac_instance *dev, const char *error) { - if (net_ratelimit()) + if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX | + EMAC_FTR_440EP_PHY_CLK_FIX)) + DBG(dev, "%s" NL, error); + else if (net_ratelimit()) printk(KERN_ERR "%s: %s\n", dev->ndev->name, error); } +/* EMAC PHY clock workaround: + * 440EP/440GR has more sane SDR0_MFR register implementation than 440GX, + * which allows controlling each EMAC clock + */ +static inline void emac_rx_clk_tx(struct emac_instance *dev) +{ +#ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_MFR, + 0, SDR0_MFR_ECS >> dev->cell_index); +#endif +} + +static inline void emac_rx_clk_default(struct emac_instance *dev) +{ +#ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_MFR, + SDR0_MFR_ECS >> dev->cell_index, 0); +#endif +} + /* PHY polling intervals */ #define PHY_POLL_LINK_ON HZ #define PHY_POLL_LINK_OFF (HZ / 5) @@ -1099,9 +1124,11 @@ static int emac_open(struct net_device *ndev) int link_poll_interval; if (dev->phy.def->ops->poll_link(&dev->phy)) { dev->phy.def->ops->read_link(&dev->phy); + emac_rx_clk_default(dev); netif_carrier_on(dev->ndev); link_poll_interval = PHY_POLL_LINK_ON; } else { + emac_rx_clk_tx(dev); netif_carrier_off(dev->ndev); link_poll_interval = PHY_POLL_LINK_OFF; } @@ -1179,6 +1206,7 @@ static void emac_link_timer(struct work_struct *work) if (dev->phy.def->ops->poll_link(&dev->phy)) { if (!netif_carrier_ok(dev->ndev)) { + emac_rx_clk_default(dev); /* Get new link parameters */ dev->phy.def->ops->read_link(&dev->phy); @@ -1191,6 +1219,7 @@ static void emac_link_timer(struct work_struct *work) link_poll_interval = PHY_POLL_LINK_ON; } else { if (netif_carrier_ok(dev->ndev)) { + emac_rx_clk_tx(dev); netif_carrier_off(dev->ndev); netif_tx_disable(dev->ndev); emac_reinitialize(dev); @@ -2339,6 +2368,14 @@ static int __devinit emac_init_phy(struct emac_instance *dev) #ifdef CONFIG_PPC_DCR_NATIVE if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS); +#endif + /* PHY clock workaround */ + emac_rx_clk_tx(dev); + + /* Enable internal clock source on 440GX*/ +#ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS); #endif /* Configure EMAC with defaults so we can at least use MDIO * This is needed mostly for 440GX @@ -2507,6 +2544,10 @@ static int __devinit emac_init_config(struct emac_instance *dev) dev->features |= EMAC_FTR_EMAC4; if (of_device_is_compatible(np, "ibm,emac-440gx")) dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; + } else { + if (of_device_is_compatible(np, "ibm,emac-440ep") || + of_device_is_compatible(np, "ibm,emac-440gr")) + dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; } /* Fixup some feature bits based on the device tree */ diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 96ec48266b4a..1683db9870a4 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -305,6 +305,10 @@ struct emac_instance { * Set if we need phy clock workaround for 440gx */ #define EMAC_FTR_440GX_PHY_CLK_FIX 0x00000080 +/* + * Set if we need phy clock workaround for 440ep or 440gr + */ +#define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100 /* Right now, we don't quite handle the always/possible masks on the @@ -328,7 +332,7 @@ enum { #ifdef CONFIG_IBM_NEW_EMAC_RGMII EMAC_FTR_HAS_RGMII | #endif - 0, + EMAC_FTR_440EP_PHY_CLK_FIX, }; static inline int emac_has_feature(struct emac_instance *dev, -- cgit v1.2.2 From 5a0e2cd51145748c4fd44d0c3a06d39eb87e8725 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Sun, 20 Apr 2008 22:44:15 -0600 Subject: [netdrvr] typhoon: typhoon_resume - remove call to start_queue While trying to fix http://bugzilla.kernel.org/show_bug.cgi?id=8952 I looked at a few other drivers to figure out what drivers _should_ be doing for suspend/resume. I noticed typhoon driver is likely doing more than it needs to. Patch below is untested since I don't have the HW. Suspend/resume code across NIC drivers is fairly inconsistent. And I couldn't find any documentation on what the canonical sequence NICs need to do for suspend or resume. Is there any? Barring contrary advice, I'm going model the tulip suspend/resume fixes after tg3.c since a number of "modern" (< 5 years old) laptops have that and I'm silly enough to assume it works. Signed-off-by: Jeff Garzik --- drivers/net/typhoon.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 333961bb7873..c0dd25ba7a18 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -2183,7 +2183,6 @@ typhoon_resume(struct pci_dev *pdev) } netif_device_attach(dev); - netif_start_queue(dev); return 0; reset: -- cgit v1.2.2 From 6131a2601f42cd7fdbac0e960713396fe68af59f Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 20 Apr 2008 19:32:34 +0200 Subject: tehuti: check register size Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/tehuti.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 17585e5eed53..d2e1b219673d 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -625,6 +625,12 @@ static void __init bdx_firmware_endianess(void) s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]); } +static int bdx_range_check(struct bdx_priv *priv, u32 offset) +{ + return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ? + -EINVAL : 0; +} + static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) { struct bdx_priv *priv = ndev->priv; @@ -646,6 +652,9 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) switch (data[0]) { case BDX_OP_READ: + error = bdx_range_check(priv, data[1]); + if (error < 0) + return error; data[2] = READ_REG(priv, data[1]); DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2], data[2]); @@ -655,6 +664,11 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) break; case BDX_OP_WRITE: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + error = bdx_range_check(priv, data[1]); + if (error < 0) + return error; WRITE_REG(priv, data[1], data[2]); DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]); break; -- cgit v1.2.2 From 7cda1edf029370d396fb610f7e41fad9a7123164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Augonnet?= Date: Sun, 20 Apr 2008 19:15:51 +0200 Subject: Removing dead code in drivers/net/wan/hdlc_fr.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The local variable "prefix" is never used anymore, and the content of this string appears a bit later, directly in a call to "alloc_netdev" after doing exactly the same if/else test. So there seems to be no point keeping those 4 lines anymore. Signed-off-by: Cédric Augonnet Signed-off-by: Krzysztof HaÅ‚asa Signed-off-by: Jeff Garzik --- drivers/net/wan/hdlc_fr.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index c4ab0326f911..520bb0b1a9a2 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1090,10 +1090,6 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) pvc_device *pvc = NULL; struct net_device *dev; int result, used; - char * prefix = "pvc%d"; - - if (type == ARPHRD_ETHER) - prefix = "pvceth%d"; if ((pvc = add_pvc(frad, dlci)) == NULL) { printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", -- cgit v1.2.2 From d753d82405ac3504ed69fb6be4d219d9702b8d64 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Sun, 20 Apr 2008 19:10:56 +0200 Subject: WAN: Fix confusing insmod error code for C101 too. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof HaÅ‚asa Signed-off-by: Jeff Garzik --- drivers/net/wan/c101.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index c4c8eab8574f..c2cc42f723d5 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -402,7 +402,7 @@ static int __init c101_init(void) #ifdef MODULE printk(KERN_INFO "c101: no card initialized\n"); #endif - return -ENOSYS; /* no parameters specified, abort */ + return -EINVAL; /* no parameters specified, abort */ } printk(KERN_INFO "%s\n", version); @@ -420,11 +420,11 @@ static int __init c101_init(void) c101_run(irq, ram); if (*hw == '\x0') - return first_card ? 0 : -ENOSYS; + return first_card ? 0 : -EINVAL; }while(*hw++ == ':'); printk(KERN_ERR "c101: invalid hardware parameters\n"); - return first_card ? 0 : -ENOSYS; + return first_card ? 0 : -EINVAL; } -- cgit v1.2.2 From 751c2e4755027468a79349f8e9f4885a4518426e Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 20 Apr 2008 18:05:31 +0200 Subject: korina: fix misplaced return statement The driver takes the error unwind path without condition. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/korina.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 1d24a73a0e1a..305be6242524 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1031,6 +1031,8 @@ static int korina_open(struct net_device *dev) dev->name, lp->und_irq); goto err_free_ovr_irq; } +out: + return ret; err_free_ovr_irq: free_irq(lp->ovr_irq, dev); @@ -1041,8 +1043,6 @@ err_free_rx_irq: err_release: korina_free_ring(dev); goto out; -out: - return ret; } static int korina_close(struct net_device *dev) -- cgit v1.2.2 From e3152ab901bcec132639d123b0e7c2b5ed237957 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 20 Apr 2008 18:06:13 +0200 Subject: korina: misc cleanup - useless initialization (korina_ope / korina_restart) - use a single variable for the status code in korina_probe and propagate the error status code from below - useless checks in korina_remove : the variables are necessarily set when korina_probe succeeds Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/korina.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 305be6242524..e18576316bda 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -883,7 +883,7 @@ static int korina_init(struct net_device *dev) static int korina_restart(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); - int ret = 0; + int ret; /* * Disable interrupts @@ -987,7 +987,7 @@ static void korina_poll_controller(struct net_device *dev) static int korina_open(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); - int ret = 0; + int ret; /* Initialize */ ret = korina_init(dev); @@ -1082,7 +1082,7 @@ static int korina_probe(struct platform_device *pdev) struct korina_private *lp; struct net_device *dev; struct resource *r; - int retval, err; + int rc; dev = alloc_etherdev(sizeof(struct korina_private)); if (!dev) { @@ -1106,7 +1106,7 @@ static int korina_probe(struct platform_device *pdev) lp->eth_regs = ioremap_nocache(r->start, r->end - r->start); if (!lp->eth_regs) { printk(KERN_ERR DRV_NAME "cannot remap registers\n"); - retval = -ENXIO; + rc = -ENXIO; goto probe_err_out; } @@ -1114,7 +1114,7 @@ static int korina_probe(struct platform_device *pdev) lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start); if (!lp->rx_dma_regs) { printk(KERN_ERR DRV_NAME "cannot remap Rx DMA registers\n"); - retval = -ENXIO; + rc = -ENXIO; goto probe_err_dma_rx; } @@ -1122,14 +1122,14 @@ static int korina_probe(struct platform_device *pdev) lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start); if (!lp->tx_dma_regs) { printk(KERN_ERR DRV_NAME "cannot remap Tx DMA registers\n"); - retval = -ENXIO; + rc = -ENXIO; goto probe_err_dma_tx; } lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL); if (!lp->td_ring) { printk(KERN_ERR DRV_NAME "cannot allocate descriptors\n"); - retval = -ENOMEM; + rc = -ENXIO; goto probe_err_td_ring; } @@ -1166,14 +1166,14 @@ static int korina_probe(struct platform_device *pdev) lp->mii_if.phy_id_mask = 0x1f; lp->mii_if.reg_num_mask = 0x1f; - err = register_netdev(dev); - if (err) { + rc = register_netdev(dev); + if (rc < 0) { printk(KERN_ERR DRV_NAME - ": cannot register net device %d\n", err); - retval = -EINVAL; + ": cannot register net device %d\n", rc); goto probe_err_register; } - return 0; +out: + return rc; probe_err_register: kfree(lp->td_ring); @@ -1185,7 +1185,7 @@ probe_err_dma_rx: iounmap(lp->eth_regs); probe_err_out: free_netdev(dev); - return retval; + goto out; } static int korina_remove(struct platform_device *pdev) @@ -1193,12 +1193,9 @@ static int korina_remove(struct platform_device *pdev) struct korina_device *bif = platform_get_drvdata(pdev); struct korina_private *lp = netdev_priv(bif->dev); - if (lp->eth_regs) - iounmap(lp->eth_regs); - if (lp->rx_dma_regs) - iounmap(lp->rx_dma_regs); - if (lp->tx_dma_regs) - iounmap(lp->tx_dma_regs); + iounmap(lp->eth_regs); + iounmap(lp->rx_dma_regs); + iounmap(lp->tx_dma_regs); platform_set_drvdata(pdev, NULL); unregister_netdev(bif->dev); -- cgit v1.2.2 From 3b49f0354561aefc5235b8dd6ee4ae779a26e06b Mon Sep 17 00:00:00 2001 From: Chris Snook Date: Fri, 18 Apr 2008 21:47:41 -0400 Subject: atlx: remove flash vendor parameter There's no good reason to manually set the flash vendor in a module parameter, outside of an Atheros hardware lab. Remove it, so nobody accidentally bricks their board using it incorrectly. Signed-off-by: Chris Snook Signed-off-by: Jeff Garzik --- drivers/net/atlx/atlx.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index 4186326d1b94..b7bf70ef3b63 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -278,30 +278,10 @@ module_param_array_named(int_mod_timer, int_mod_timer, int, &num_int_mod_timer, 0); MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); -/* - * flash_vendor - * - * Valid Range: 0-2 - * - * 0 - Atmel - * 1 - SST - * 2 - ST - * - * Default Value: 0 - */ -static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_flash_vendor; -module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0); -MODULE_PARM_DESC(flash_vendor, "SPI flash vendor"); - #define DEFAULT_INT_MOD_CNT 100 /* 200us */ #define MAX_INT_MOD_CNT 65000 #define MIN_INT_MOD_CNT 50 -#define FLASH_VENDOR_DEFAULT 0 -#define FLASH_VENDOR_MIN 0 -#define FLASH_VENDOR_MAX 2 - struct atl1_option { enum { enable_option, range_option, list_option } type; char *name; @@ -409,25 +389,6 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) } else adapter->imt = (u16) (opt.def); } - - { /* Flash Vendor */ - struct atl1_option opt = { - .type = range_option, - .name = "SPI Flash Vendor", - .err = "using default of " - __MODULE_STRING(FLASH_VENDOR_DEFAULT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = {.min = FLASH_VENDOR_MIN, - .max = FLASH_VENDOR_MAX} } - }; - int val; - if (num_flash_vendor > bd) { - val = flash_vendor[bd]; - atl1_validate_option(&val, &opt, pdev); - adapter->hw.flash_vendor = (u8) val; - } else - adapter->hw.flash_vendor = (u8) (opt.def); - } } #endif /* ATLX_C */ -- cgit v1.2.2 From 8ec7226a93dcd4a314e2387d1033aef01145061b Mon Sep 17 00:00:00 2001 From: Chris Snook Date: Fri, 18 Apr 2008 21:51:53 -0400 Subject: [netdrvr] atlx: code movement: move atl1 parameter parsing Move some code from atlx.c to atl1.c to prevent build conflict with the upcoming atl2 code. No changes, just movement. Signed-off-by: Chris Snook Signed-off-by: Jeff Garzik --- drivers/net/atlx/atl1.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/atlx/atlx.c | 138 ------------------------------------------------ 2 files changed, 138 insertions(+), 138 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 5586fc624688..0afe522b8f7b 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -90,6 +90,144 @@ /* Temporary hack for merging atl1 and atl2 */ #include "atlx.c" +/* + * This is the only thing that needs to be changed to adjust the + * maximum number of ports that the driver can manage. + */ +#define ATL1_MAX_NIC 4 + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET } + +/* + * Interrupt Moderate Timer in units of 2 us + * + * Valid Range: 10-65535 + * + * Default Value: 100 (200us) + */ +static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; +static int num_int_mod_timer; +module_param_array_named(int_mod_timer, int_mod_timer, int, + &num_int_mod_timer, 0); +MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); + +#define DEFAULT_INT_MOD_CNT 100 /* 200us */ +#define MAX_INT_MOD_CNT 65000 +#define MIN_INT_MOD_CNT 50 + +struct atl1_option { + enum { enable_option, range_option, list_option } type; + char *name; + char *err; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + struct atl1_opt_list { + int i; + char *str; + } *p; + } l; + } arg; +}; + +static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, + struct pci_dev *pdev) +{ + if (*value == OPTION_UNSET) { + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + dev_info(&pdev->dev, "%s enabled\n", opt->name); + return 0; + case OPTION_DISABLED: + dev_info(&pdev->dev, "%s disabled\n", opt->name); + return 0; + } + break; + case range_option: + if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { + dev_info(&pdev->dev, "%s set to %i\n", opt->name, + *value); + return 0; + } + break; + case list_option:{ + int i; + struct atl1_opt_list *ent; + + for (i = 0; i < opt->arg.l.nr; i++) { + ent = &opt->arg.l.p[i]; + if (*value == ent->i) { + if (ent->str[0] != '\0') + dev_info(&pdev->dev, "%s\n", + ent->str); + return 0; + } + } + } + break; + + default: + break; + } + + dev_info(&pdev->dev, "invalid %s specified (%i) %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +/* + * atl1_check_options - Range Checking for Command Line Parameters + * @adapter: board private structure + * + * This routine checks all command line parameters for valid user + * input. If an invalid value is given, or if no user specified + * value exists, a default value is used. The final value is stored + * in a variable in the adapter structure. + */ +void __devinit atl1_check_options(struct atl1_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + int bd = adapter->bd_number; + if (bd >= ATL1_MAX_NIC) { + dev_notice(&pdev->dev, "no configuration for board#%i\n", bd); + dev_notice(&pdev->dev, "using defaults for all values\n"); + } + { /* Interrupt Moderate Timer */ + struct atl1_option opt = { + .type = range_option, + .name = "Interrupt Moderator Timer", + .err = "using default of " + __MODULE_STRING(DEFAULT_INT_MOD_CNT), + .def = DEFAULT_INT_MOD_CNT, + .arg = {.r = {.min = MIN_INT_MOD_CNT, + .max = MAX_INT_MOD_CNT} } + }; + int val; + if (num_int_mod_timer > bd) { + val = int_mod_timer[bd]; + atl1_validate_option(&val, &opt, pdev); + adapter->imt = (u16) val; + } else + adapter->imt = (u16) (opt.def); + } +} + /* * atl1_pci_tbl - PCI Device ID Table */ diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index b7bf70ef3b63..f06b854e2501 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c @@ -253,142 +253,4 @@ static void atlx_restore_vlan(struct atlx_adapter *adapter) atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp); } -/* - * This is the only thing that needs to be changed to adjust the - * maximum number of ports that the driver can manage. - */ -#define ATL1_MAX_NIC 4 - -#define OPTION_UNSET -1 -#define OPTION_DISABLED 0 -#define OPTION_ENABLED 1 - -#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET } - -/* - * Interrupt Moderate Timer in units of 2 us - * - * Valid Range: 10-65535 - * - * Default Value: 100 (200us) - */ -static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_int_mod_timer; -module_param_array_named(int_mod_timer, int_mod_timer, int, - &num_int_mod_timer, 0); -MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); - -#define DEFAULT_INT_MOD_CNT 100 /* 200us */ -#define MAX_INT_MOD_CNT 65000 -#define MIN_INT_MOD_CNT 50 - -struct atl1_option { - enum { enable_option, range_option, list_option } type; - char *name; - char *err; - int def; - union { - struct { /* range_option info */ - int min; - int max; - } r; - struct { /* list_option info */ - int nr; - struct atl1_opt_list { - int i; - char *str; - } *p; - } l; - } arg; -}; - -static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, - struct pci_dev *pdev) -{ - if (*value == OPTION_UNSET) { - *value = opt->def; - return 0; - } - - switch (opt->type) { - case enable_option: - switch (*value) { - case OPTION_ENABLED: - dev_info(&pdev->dev, "%s enabled\n", opt->name); - return 0; - case OPTION_DISABLED: - dev_info(&pdev->dev, "%s disabled\n", opt->name); - return 0; - } - break; - case range_option: - if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - dev_info(&pdev->dev, "%s set to %i\n", opt->name, - *value); - return 0; - } - break; - case list_option:{ - int i; - struct atl1_opt_list *ent; - - for (i = 0; i < opt->arg.l.nr; i++) { - ent = &opt->arg.l.p[i]; - if (*value == ent->i) { - if (ent->str[0] != '\0') - dev_info(&pdev->dev, "%s\n", - ent->str); - return 0; - } - } - } - break; - - default: - break; - } - - dev_info(&pdev->dev, "invalid %s specified (%i) %s\n", - opt->name, *value, opt->err); - *value = opt->def; - return -1; -} - -/* - * atl1_check_options - Range Checking for Command Line Parameters - * @adapter: board private structure - * - * This routine checks all command line parameters for valid user - * input. If an invalid value is given, or if no user specified - * value exists, a default value is used. The final value is stored - * in a variable in the adapter structure. - */ -void __devinit atl1_check_options(struct atl1_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - int bd = adapter->bd_number; - if (bd >= ATL1_MAX_NIC) { - dev_notice(&pdev->dev, "no configuration for board#%i\n", bd); - dev_notice(&pdev->dev, "using defaults for all values\n"); - } - { /* Interrupt Moderate Timer */ - struct atl1_option opt = { - .type = range_option, - .name = "Interrupt Moderator Timer", - .err = "using default of " - __MODULE_STRING(DEFAULT_INT_MOD_CNT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = {.min = MIN_INT_MOD_CNT, - .max = MAX_INT_MOD_CNT} } - }; - int val; - if (num_int_mod_timer > bd) { - val = int_mod_timer[bd]; - atl1_validate_option(&val, &opt, pdev); - adapter->imt = (u16) val; - } else - adapter->imt = (u16) (opt.def); - } -} - #endif /* ATLX_C */ -- cgit v1.2.2 From f62220d3a9ccb879c3f90f845ae57b724b7bbb62 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Fri, 18 Apr 2008 17:29:54 -0500 Subject: phylib: Add support for board-level PHY fixups Sometimes the specific interaction between the platform and the PHY requires special handling. For instance, to change where the PHY's clock input is, or to add a delay to account for latency issues in the data path. We add a mechanism for registering a callback with the PHY Lib to be called on matching PHYs when they are brought up, or reset. Signed-off-by: Andy Fleming Signed-off-by: Jeff Garzik --- drivers/net/phy/mdio_bus.c | 3 + drivers/net/phy/phy.c | 4 +- drivers/net/phy/phy_device.c | 129 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 123 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 963630c65ca9..94e0b7ed76f1 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -89,6 +89,9 @@ int mdiobus_register(struct mii_bus *bus) phydev->bus = bus; + /* Run all of the fixups for this PHY */ + phy_scan_fixups(phydev); + err = device_register(&phydev->dev); if (err) { diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 12fccb1c76dc..3c18bb594957 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -406,8 +406,10 @@ int phy_mii_ioctl(struct phy_device *phydev, if (mii_data->reg_num == MII_BMCR && val & BMCR_RESET - && phydev->drv->config_init) + && phydev->drv->config_init) { + phy_scan_fixups(phydev); phydev->drv->config_init(phydev); + } break; default: diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 8b1121b02f98..ddf8d51832a6 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -53,6 +53,96 @@ static void phy_device_release(struct device *dev) phy_device_free(to_phy_device(dev)); } +static LIST_HEAD(phy_fixup_list); +static DEFINE_MUTEX(phy_fixup_lock); + +/* + * Creates a new phy_fixup and adds it to the list + * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) + * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY) + * It can also be PHY_ANY_UID + * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before + * comparison + * @run: The actual code to be run when a matching PHY is found + */ +int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, + int (*run)(struct phy_device *)) +{ + struct phy_fixup *fixup; + + fixup = kzalloc(sizeof(struct phy_fixup), GFP_KERNEL); + if (!fixup) + return -ENOMEM; + + strncpy(fixup->bus_id, bus_id, BUS_ID_SIZE); + fixup->phy_uid = phy_uid; + fixup->phy_uid_mask = phy_uid_mask; + fixup->run = run; + + mutex_lock(&phy_fixup_lock); + list_add_tail(&fixup->list, &phy_fixup_list); + mutex_unlock(&phy_fixup_lock); + + return 0; +} +EXPORT_SYMBOL(phy_register_fixup); + +/* Registers a fixup to be run on any PHY with the UID in phy_uid */ +int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, + int (*run)(struct phy_device *)) +{ + return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run); +} +EXPORT_SYMBOL(phy_register_fixup_for_uid); + +/* Registers a fixup to be run on the PHY with id string bus_id */ +int phy_register_fixup_for_id(const char *bus_id, + int (*run)(struct phy_device *)) +{ + return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run); +} +EXPORT_SYMBOL(phy_register_fixup_for_id); + +/* + * Returns 1 if fixup matches phydev in bus_id and phy_uid. + * Fixups can be set to match any in one or more fields. + */ +static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) +{ + if (strcmp(fixup->bus_id, phydev->dev.bus_id) != 0) + if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0) + return 0; + + if ((fixup->phy_uid & fixup->phy_uid_mask) != + (phydev->phy_id & fixup->phy_uid_mask)) + if (fixup->phy_uid != PHY_ANY_UID) + return 0; + + return 1; +} + +/* Runs any matching fixups for this phydev */ +int phy_scan_fixups(struct phy_device *phydev) +{ + struct phy_fixup *fixup; + + mutex_lock(&phy_fixup_lock); + list_for_each_entry(fixup, &phy_fixup_list, list) { + if (phy_needs_fixup(phydev, fixup)) { + int err; + + err = fixup->run(phydev); + + if (err < 0) + return err; + } + } + mutex_unlock(&phy_fixup_lock); + + return 0; +} +EXPORT_SYMBOL(phy_scan_fixups); + struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) { struct phy_device *dev; @@ -179,13 +269,13 @@ void phy_prepare_link(struct phy_device *phydev, * choose to call only the subset of functions which provide * the desired functionality. */ -struct phy_device * phy_connect(struct net_device *dev, const char *phy_id, +struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, void (*handler)(struct net_device *), u32 flags, phy_interface_t interface) { struct phy_device *phydev; - phydev = phy_attach(dev, phy_id, flags, interface); + phydev = phy_attach(dev, bus_id, flags, interface); if (IS_ERR(phydev)) return phydev; @@ -226,7 +316,7 @@ static int phy_compare_id(struct device *dev, void *data) /** * phy_attach - attach a network device to a particular PHY device * @dev: network device to attach - * @phy_id: PHY device to attach + * @bus_id: PHY device to attach * @flags: PHY device's dev_flags * @interface: PHY device's interface * @@ -238,7 +328,7 @@ static int phy_compare_id(struct device *dev, void *data) * change. The phy_device is returned to the attaching driver. */ struct phy_device *phy_attach(struct net_device *dev, - const char *phy_id, u32 flags, phy_interface_t interface) + const char *bus_id, u32 flags, phy_interface_t interface) { struct bus_type *bus = &mdio_bus_type; struct phy_device *phydev; @@ -246,12 +336,12 @@ struct phy_device *phy_attach(struct net_device *dev, /* Search the list of PHY devices on the mdio bus for the * PHY with the requested name */ - d = bus_find_device(bus, NULL, (void *)phy_id, phy_compare_id); + d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id); if (d) { phydev = to_phy_device(d); } else { - printk(KERN_ERR "%s not found\n", phy_id); + printk(KERN_ERR "%s not found\n", bus_id); return ERR_PTR(-ENODEV); } @@ -271,7 +361,7 @@ struct phy_device *phy_attach(struct net_device *dev, if (phydev->attached_dev) { printk(KERN_ERR "%s: %s already attached\n", - dev->name, phy_id); + dev->name, bus_id); return ERR_PTR(-EBUSY); } @@ -287,6 +377,11 @@ struct phy_device *phy_attach(struct net_device *dev, if (phydev->drv->config_init) { int err; + err = phy_scan_fixups(phydev); + + if (err < 0) + return ERR_PTR(err); + err = phydev->drv->config_init(phydev); if (err < 0) @@ -395,6 +490,7 @@ EXPORT_SYMBOL(genphy_config_advert); */ int genphy_setup_forced(struct phy_device *phydev) { + int err; int ctl = 0; phydev->pause = phydev->asym_pause = 0; @@ -407,17 +503,26 @@ int genphy_setup_forced(struct phy_device *phydev) if (DUPLEX_FULL == phydev->duplex) ctl |= BMCR_FULLDPLX; - ctl = phy_write(phydev, MII_BMCR, ctl); + err = phy_write(phydev, MII_BMCR, ctl); - if (ctl < 0) - return ctl; + if (err < 0) + return err; + + /* + * Run the fixups on this PHY, just in case the + * board code needs to change something after a reset + */ + err = phy_scan_fixups(phydev); + + if (err < 0) + return err; /* We just reset the device, so we'd better configure any * settings the PHY requires to operate */ if (phydev->drv->config_init) - ctl = phydev->drv->config_init(phydev); + err = phydev->drv->config_init(phydev); - return ctl; + return err; } -- cgit v1.2.2 From 22559c5d7488fe21f5f46117a4d275fc72066aa6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 18 Apr 2008 13:50:39 -0700 Subject: ehea: make things static ehea_flush_sq() and ehea_purge_sq() should be static. Cc: Jeff Garzik Cc: Thomas Klein Cc: Thomas Klein Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 9ff7538b7595..f9bc21c74b59 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2611,7 +2611,7 @@ static int ehea_stop(struct net_device *dev) return ret; } -void ehea_purge_sq(struct ehea_qp *orig_qp) +static void ehea_purge_sq(struct ehea_qp *orig_qp) { struct ehea_qp qp = *orig_qp; struct ehea_qp_init_attr *init_attr = &qp.init_attr; @@ -2625,7 +2625,7 @@ void ehea_purge_sq(struct ehea_qp *orig_qp) } } -void ehea_flush_sq(struct ehea_port *port) +static void ehea_flush_sq(struct ehea_port *port) { int i; -- cgit v1.2.2 From a433686c73bf63242475ef7e611114f43dd06581 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Fri, 18 Apr 2008 13:50:43 -0700 Subject: forcedeth: new backoff implementation This patch adds support for a new backoff algorithm for half duplex supported in newer hardware. The old method is will be designated as legacy mode. Re-seeding random values for the backoff algorithms are performed when a transmit has failed due to a maximum retry count (1 to 15, where max is considered the wraparound case of 0). Signed-off-by: Ayaz Abdulla Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/forcedeth.c | 212 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 178 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 8c4214b0ee1f..73d85b31fbdc 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -96,6 +96,7 @@ #define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */ #define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */ #define DEV_NEED_TX_LIMIT 0x40000 /* device needs to limit tx */ +#define DEV_HAS_GEAR_MODE 0x80000 /* device supports gear mode */ enum { NvRegIrqStatus = 0x000, @@ -174,11 +175,13 @@ enum { NvRegReceiverStatus = 0x98, #define NVREG_RCVSTAT_BUSY 0x01 - NvRegRandomSeed = 0x9c, -#define NVREG_RNDSEED_MASK 0x00ff -#define NVREG_RNDSEED_FORCE 0x7f00 -#define NVREG_RNDSEED_FORCE2 0x2d00 -#define NVREG_RNDSEED_FORCE3 0x7400 + NvRegSlotTime = 0x9c, +#define NVREG_SLOTTIME_LEGBF_ENABLED 0x80000000 +#define NVREG_SLOTTIME_10_100_FULL 0x00007f00 +#define NVREG_SLOTTIME_1000_FULL 0x0003ff00 +#define NVREG_SLOTTIME_HALF 0x0000ff00 +#define NVREG_SLOTTIME_DEFAULT 0x00007f00 +#define NVREG_SLOTTIME_MASK 0x000000ff NvRegTxDeferral = 0xA0, #define NVREG_TX_DEFERRAL_DEFAULT 0x15050f @@ -201,6 +204,11 @@ enum { NvRegPhyInterface = 0xC0, #define PHY_RGMII 0x10000000 + NvRegBackOffControl = 0xC4, +#define NVREG_BKOFFCTRL_DEFAULT 0x70000000 +#define NVREG_BKOFFCTRL_SEED_MASK 0x000003ff +#define NVREG_BKOFFCTRL_SELECT 24 +#define NVREG_BKOFFCTRL_GEAR 12 NvRegTxRingPhysAddr = 0x100, NvRegRxRingPhysAddr = 0x104, @@ -352,6 +360,7 @@ union ring_type { #define NV_TX_LASTPACKET (1<<16) #define NV_TX_RETRYERROR (1<<19) +#define NV_TX_RETRYCOUNT_MASK (0xF<<20) #define NV_TX_FORCED_INTERRUPT (1<<24) #define NV_TX_DEFERRED (1<<26) #define NV_TX_CARRIERLOST (1<<27) @@ -362,6 +371,7 @@ union ring_type { #define NV_TX2_LASTPACKET (1<<29) #define NV_TX2_RETRYERROR (1<<18) +#define NV_TX2_RETRYCOUNT_MASK (0xF<<19) #define NV_TX2_FORCED_INTERRUPT (1<<30) #define NV_TX2_DEFERRED (1<<25) #define NV_TX2_CARRIERLOST (1<<26) @@ -1769,6 +1779,115 @@ static inline u32 nv_get_empty_tx_slots(struct fe_priv *np) return (u32)(np->tx_ring_size - ((np->tx_ring_size + (np->put_tx_ctx - np->get_tx_ctx)) % np->tx_ring_size)); } +static void nv_legacybackoff_reseed(struct net_device *dev) +{ + u8 __iomem *base = get_hwbase(dev); + u32 reg; + u32 low; + int tx_status = 0; + + reg = readl(base + NvRegSlotTime) & ~NVREG_SLOTTIME_MASK; + get_random_bytes(&low, sizeof(low)); + reg |= low & NVREG_SLOTTIME_MASK; + + /* Need to stop tx before change takes effect. + * Caller has already gained np->lock. + */ + tx_status = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START; + if (tx_status) + nv_stop_tx(dev); + nv_stop_rx(dev); + writel(reg, base + NvRegSlotTime); + if (tx_status) + nv_start_tx(dev); + nv_start_rx(dev); +} + +/* Gear Backoff Seeds */ +#define BACKOFF_SEEDSET_ROWS 8 +#define BACKOFF_SEEDSET_LFSRS 15 + +/* Known Good seed sets */ +static const u32 main_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974}, + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974}, + {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984}, + {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984}, + {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84}, + {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}}; + +static const u32 gear_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}}; + +static void nv_gear_backoff_reseed(struct net_device *dev) +{ + u8 __iomem *base = get_hwbase(dev); + u32 miniseed1, miniseed2, miniseed2_reversed, miniseed3, miniseed3_reversed; + u32 temp, seedset, combinedSeed; + int i; + + /* Setup seed for free running LFSR */ + /* We are going to read the time stamp counter 3 times + and swizzle bits around to increase randomness */ + get_random_bytes(&miniseed1, sizeof(miniseed1)); + miniseed1 &= 0x0fff; + if (miniseed1 == 0) + miniseed1 = 0xabc; + + get_random_bytes(&miniseed2, sizeof(miniseed2)); + miniseed2 &= 0x0fff; + if (miniseed2 == 0) + miniseed2 = 0xabc; + miniseed2_reversed = + ((miniseed2 & 0xF00) >> 8) | + (miniseed2 & 0x0F0) | + ((miniseed2 & 0x00F) << 8); + + get_random_bytes(&miniseed3, sizeof(miniseed3)); + miniseed3 &= 0x0fff; + if (miniseed3 == 0) + miniseed3 = 0xabc; + miniseed3_reversed = + ((miniseed3 & 0xF00) >> 8) | + (miniseed3 & 0x0F0) | + ((miniseed3 & 0x00F) << 8); + + combinedSeed = ((miniseed1 ^ miniseed2_reversed) << 12) | + (miniseed2 ^ miniseed3_reversed); + + /* Seeds can not be zero */ + if ((combinedSeed & NVREG_BKOFFCTRL_SEED_MASK) == 0) + combinedSeed |= 0x08; + if ((combinedSeed & (NVREG_BKOFFCTRL_SEED_MASK << NVREG_BKOFFCTRL_GEAR)) == 0) + combinedSeed |= 0x8000; + + /* No need to disable tx here */ + temp = NVREG_BKOFFCTRL_DEFAULT | (0 << NVREG_BKOFFCTRL_SELECT); + temp |= combinedSeed & NVREG_BKOFFCTRL_SEED_MASK; + temp |= combinedSeed >> NVREG_BKOFFCTRL_GEAR; + writel(temp,base + NvRegBackOffControl); + + /* Setup seeds for all gear LFSRs. */ + get_random_bytes(&seedset, sizeof(seedset)); + seedset = seedset % BACKOFF_SEEDSET_ROWS; + for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) + { + temp = NVREG_BKOFFCTRL_DEFAULT | (i << NVREG_BKOFFCTRL_SELECT); + temp |= main_seedset[seedset][i-1] & 0x3ff; + temp |= ((gear_seedset[seedset][i-1] & 0x3ff) << NVREG_BKOFFCTRL_GEAR); + writel(temp, base + NvRegBackOffControl); + } +} + /* * nv_start_xmit: dev->hard_start_xmit function * Called with netif_tx_lock held. @@ -2088,6 +2207,8 @@ static void nv_tx_done(struct net_device *dev) dev->stats.tx_fifo_errors++; if (flags & NV_TX_CARRIERLOST) dev->stats.tx_carrier_errors++; + if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK)) + nv_legacybackoff_reseed(dev); dev->stats.tx_errors++; } else { dev->stats.tx_packets++; @@ -2103,6 +2224,8 @@ static void nv_tx_done(struct net_device *dev) dev->stats.tx_fifo_errors++; if (flags & NV_TX2_CARRIERLOST) dev->stats.tx_carrier_errors++; + if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) + nv_legacybackoff_reseed(dev); dev->stats.tx_errors++; } else { dev->stats.tx_packets++; @@ -2144,6 +2267,15 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit) if (flags & NV_TX2_LASTPACKET) { if (!(flags & NV_TX2_ERROR)) dev->stats.tx_packets++; + else { + if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) { + if (np->driver_data & DEV_HAS_GEAR_MODE) + nv_gear_backoff_reseed(dev); + else + nv_legacybackoff_reseed(dev); + } + } + dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; @@ -2905,15 +3037,14 @@ set_speed: } if (np->gigabit == PHY_GIGABIT) { - phyreg = readl(base + NvRegRandomSeed); + phyreg = readl(base + NvRegSlotTime); phyreg &= ~(0x3FF00); - if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) - phyreg |= NVREG_RNDSEED_FORCE3; - else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) - phyreg |= NVREG_RNDSEED_FORCE2; + if (((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) || + ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)) + phyreg |= NVREG_SLOTTIME_10_100_FULL; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) - phyreg |= NVREG_RNDSEED_FORCE; - writel(phyreg, base + NvRegRandomSeed); + phyreg |= NVREG_SLOTTIME_1000_FULL; + writel(phyreg, base + NvRegSlotTime); } phyreg = readl(base + NvRegPhyInterface); @@ -4843,6 +4974,7 @@ static int nv_open(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); int ret = 1; int oom, i; + u32 low; dprintk(KERN_DEBUG "nv_open: begin\n"); @@ -4902,8 +5034,20 @@ static int nv_open(struct net_device *dev) writel(np->rx_buf_sz, base + NvRegOffloadConfig); writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); - get_random_bytes(&i, sizeof(i)); - writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed); + + get_random_bytes(&low, sizeof(low)); + low &= NVREG_SLOTTIME_MASK; + if (np->desc_ver == DESC_VER_1) { + writel(low|NVREG_SLOTTIME_DEFAULT, base + NvRegSlotTime); + } else { + if (!(np->driver_data & DEV_HAS_GEAR_MODE)) { + /* setup legacy backoff */ + writel(NVREG_SLOTTIME_LEGBF_ENABLED|NVREG_SLOTTIME_10_100_FULL|low, base + NvRegSlotTime); + } else { + writel(NVREG_SLOTTIME_10_100_FULL, base + NvRegSlotTime); + nv_gear_backoff_reseed(dev); + } + } writel(NVREG_TX_DEFERRAL_DEFAULT, base + NvRegTxDeferral); writel(NVREG_RX_DEFERRAL_DEFAULT, base + NvRegRxDeferral); if (poll_interval == -1) { @@ -5632,83 +5776,83 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, {0,}, }; -- cgit v1.2.2 From 72abb46101fb5c47a9592914adb221b430ff26bd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 18 Apr 2008 13:50:44 -0700 Subject: net drivers: fix platform driver hotplug/coldplug Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable network platform drivers, to re-enable auto loading. NOTE: didn't change drivers/net/fs_enet/fs_enet-main.c "old binding" support. That looks problematic in the first place (it even uses the ancient "struct device_driver" binding scheme for platform_bus!) and I suspect it will vanish soonish when arch/powerpc rules the world. Also, drivers/net/ne.c would have needed more thought to sort out. [akpm@linux-foundation.org: fix sgiseeq.c] [dbrownell@users.sourceforge.net: more drivers, registration fixes] Signed-off-by: Kay Sievers Signed-off-by: David Brownell Cc: Scott Wood Cc: Vitaly Bordug Cc: Dale Farnsworth Cc: Ben Dooks Cc: Ralf Baechle Cc: Andrew Victor Cc: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/arm/at91_ether.c | 1 + drivers/net/arm/ep93xx_eth.c | 2 ++ drivers/net/ax88796.c | 1 + drivers/net/bfin_mac.c | 7 +++++-- drivers/net/cpmac.c | 2 ++ drivers/net/dm9000.c | 1 + drivers/net/gianfar.c | 4 ++++ drivers/net/irda/ali-ircc.c | 2 ++ drivers/net/irda/pxaficp_ir.c | 2 ++ drivers/net/irda/sa1100_ir.c | 2 ++ drivers/net/jazzsonic.c | 2 ++ drivers/net/macb.c | 2 ++ drivers/net/meth.c | 2 ++ drivers/net/mv643xx_eth.c | 5 ++++- drivers/net/netx-eth.c | 2 +- drivers/net/sgiseeq.c | 4 +++- drivers/net/smc911x.c | 2 ++ drivers/net/smc91x.c | 2 ++ drivers/net/sni_82596.c | 2 ++ drivers/net/tsi108_eth.c | 2 ++ 20 files changed, 44 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 0ae0d83e5d22..770226d904d4 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -1246,3 +1246,4 @@ module_exit(at91ether_exit) MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); MODULE_AUTHOR("Andrew Victor"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 91a6590d107b..ecd8fc6146e9 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -897,6 +897,7 @@ static struct platform_driver ep93xx_eth_driver = { .remove = ep93xx_eth_remove, .driver = { .name = "ep93xx-eth", + .owner = THIS_MODULE, }, }; @@ -914,3 +915,4 @@ static void __exit ep93xx_eth_cleanup_module(void) module_init(ep93xx_eth_init_module); module_exit(ep93xx_eth_cleanup_module); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ep93xx-eth"); diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 194949afacd0..0b4adf4a0f7d 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -1005,3 +1005,4 @@ module_exit(axdrv_exit); MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver"); MODULE_AUTHOR("Ben Dooks, "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:ax88796"); diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 717dcc1aa1e9..4fec8581bfd7 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -47,6 +47,7 @@ MODULE_AUTHOR(DRV_AUTHOR); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(DRV_DESC); +MODULE_ALIAS("platform:bfin_mac"); #if defined(CONFIG_BFIN_MAC_USE_L1) # define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size) @@ -1089,8 +1090,9 @@ static struct platform_driver bfin_mac_driver = { .resume = bfin_mac_resume, .suspend = bfin_mac_suspend, .driver = { - .name = DRV_NAME, - }, + .name = DRV_NAME, + .owner = THIS_MODULE, + }, }; static int __init bfin_mac_init(void) @@ -1106,3 +1108,4 @@ static void __exit bfin_mac_cleanup(void) } module_exit(bfin_mac_cleanup); + diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 9da7ff437031..2b5740b3d182 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -42,6 +42,7 @@ MODULE_AUTHOR("Eugene Konev "); MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:cpmac"); static int debug_level = 8; static int dumb_switch; @@ -1103,6 +1104,7 @@ static int __devexit cpmac_remove(struct platform_device *pdev) static struct platform_driver cpmac_driver = { .driver.name = "cpmac", + .driver.owner = THIS_MODULE, .probe = cpmac_probe, .remove = __devexit_p(cpmac_remove), }; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index d63cc93f055d..e6fe2614ea6d 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1418,3 +1418,4 @@ module_exit(dm9000_cleanup); MODULE_AUTHOR("Sascha Hauer, Ben Dooks"); MODULE_DESCRIPTION("Davicom DM9000 network driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:dm9000"); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index c8c3df737d73..b917616bf6f1 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2001,12 +2001,16 @@ static irqreturn_t gfar_error(int irq, void *dev_id) return IRQ_HANDLED; } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:fsl-gianfar"); + /* Structure for a device driver */ static struct platform_driver gfar_driver = { .probe = gfar_probe, .remove = gfar_remove, .driver = { .name = "fsl-gianfar", + .owner = THIS_MODULE, }, }; diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 9f584521304a..083b0dd70fef 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -60,6 +60,7 @@ static struct platform_driver ali_ircc_driver = { .resume = ali_ircc_resume, .driver = { .name = ALI_IRCC_DRIVER_NAME, + .owner = THIS_MODULE, }, }; @@ -2256,6 +2257,7 @@ static void FIR2SIR(int iobase) MODULE_AUTHOR("Benjamin Kong "); MODULE_DESCRIPTION("ALi FIR Controller Driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" ALI_IRCC_DRIVER_NAME); module_param_array(io, int, NULL, 0); diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 8c09344f58dc..60b94bb4d25e 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -897,6 +897,7 @@ static int pxa_irda_remove(struct platform_device *_dev) static struct platform_driver pxa_ir_driver = { .driver = { .name = "pxa2xx-ir", + .owner = THIS_MODULE, }, .probe = pxa_irda_probe, .remove = pxa_irda_remove, @@ -918,3 +919,4 @@ module_init(pxa_irda_init); module_exit(pxa_irda_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-ir"); diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 056639f72bec..1bc8518f9197 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -1008,6 +1008,7 @@ static struct platform_driver sa1100ir_driver = { .resume = sa1100_irda_resume, .driver = { .name = "sa11x0-ir", + .owner = THIS_MODULE, }, }; @@ -1041,3 +1042,4 @@ MODULE_LICENSE("GPL"); MODULE_PARM_DESC(power_level, "IrDA power level, 1 (low) to 3 (high)"); MODULE_PARM_DESC(tx_lpm, "Enable transmitter low power (1.6us) mode"); MODULE_PARM_DESC(max_rate, "Maximum baud rate (4000000, 115200, 57600, 38400, 19200, 9600)"); +MODULE_ALIAS("platform:sa11x0-ir"); diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 5c154fe13859..07944820f745 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -249,6 +249,7 @@ out: MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); module_param(sonic_debug, int, 0); MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); +MODULE_ALIAS("platform:jazzsonic"); #include "sonic.c" @@ -271,6 +272,7 @@ static struct platform_driver jazz_sonic_driver = { .remove = __devexit_p(jazz_sonic_device_remove), .driver = { .name = jazz_sonic_string, + .owner = THIS_MODULE, }, }; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index d513bb8a4902..92dccd43bdca 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1281,6 +1281,7 @@ static struct platform_driver macb_driver = { .remove = __exit_p(macb_remove), .driver = { .name = "macb", + .owner = THIS_MODULE, }, }; @@ -1300,3 +1301,4 @@ module_exit(macb_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Atmel MACB Ethernet driver"); MODULE_AUTHOR("Haavard Skinnemoen "); +MODULE_ALIAS("platform:macb"); diff --git a/drivers/net/meth.c b/drivers/net/meth.c index cdaa8fc21809..0b32648a2136 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -830,6 +830,7 @@ static struct platform_driver meth_driver = { .remove = __devexit_p(meth_remove), .driver = { .name = "meth", + .owner = THIS_MODULE, } }; @@ -855,3 +856,4 @@ module_exit(meth_exit_module); MODULE_AUTHOR("Ilya Volynets "); MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:meth"); diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 601ffd69ebc8..381b36e5f64c 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2030,6 +2030,7 @@ static struct platform_driver mv643xx_eth_driver = { .shutdown = mv643xx_eth_shutdown, .driver = { .name = MV643XX_ETH_NAME, + .owner = THIS_MODULE, }, }; @@ -2038,6 +2039,7 @@ static struct platform_driver mv643xx_eth_shared_driver = { .remove = mv643xx_eth_shared_remove, .driver = { .name = MV643XX_ETH_SHARED_NAME, + .owner = THIS_MODULE, }, }; @@ -2085,7 +2087,8 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani" " and Dale Farnsworth"); MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); -MODULE_ALIAS("platform:mv643xx_eth"); +MODULE_ALIAS("platform:" MV643XX_ETH_NAME); +MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME); /* * The second part is the low level driver of the gigE ethernet ports. diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 78d34af13a1c..dc442e370850 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -502,4 +502,4 @@ module_exit(netx_eth_cleanup); MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_LICENSE("GPL"); - +MODULE_ALIAS("platform:" CARDNAME); diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 78994ede0cb0..6261201403cd 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -825,7 +825,8 @@ static struct platform_driver sgiseeq_driver = { .probe = sgiseeq_probe, .remove = __devexit_p(sgiseeq_remove), .driver = { - .name = "sgiseeq" + .name = "sgiseeq", + .owner = THIS_MODULE, } }; @@ -850,3 +851,4 @@ module_exit(sgiseeq_module_exit); MODULE_DESCRIPTION("SGI Seeq 8003 driver"); MODULE_AUTHOR("Linux/MIPS Mailing List "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:sgiseeq"); diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 76cc1d3adf71..8fbc08b73589 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -92,6 +92,7 @@ module_param(tx_fifo_kb, int, 0400); MODULE_PARM_DESC(tx_fifo_kb,"transmit FIFO size in KB (1 Date: Fri, 18 Apr 2008 13:50:48 -0700 Subject: smc911x: test after postfix decrement fails in smc911x_{reset,drop_pkt} When timeout reaches 0 the postfix decrement still subtracts, so the test fails. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Peter Korsgaard Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/smc911x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 8fbc08b73589..4e2800205189 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -244,7 +244,7 @@ static void smc911x_reset(struct net_device *dev) do { udelay(10); reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_; - } while ( timeout-- && !reg); + } while (--timeout && !reg); if (timeout == 0) { PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name); return; @@ -268,7 +268,7 @@ static void smc911x_reset(struct net_device *dev) resets++; break; } - } while ( timeout-- && (reg & HW_CFG_SRST_)); + } while (--timeout && (reg & HW_CFG_SRST_)); } if (timeout == 0) { PRINTK("%s: smc911x_reset timeout waiting for reset\n", dev->name); @@ -414,7 +414,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev) do { udelay(10); reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_; - } while ( timeout-- && reg); + } while (--timeout && reg); if (timeout == 0) { PRINTK("%s: timeout waiting for RX fast forward\n", dev->name); } -- cgit v1.2.2 From 8d74849b91536b126c822968b0f5a1dfd658394d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 22 Apr 2008 11:48:35 -0700 Subject: netxen: reduce stack usage of netxen_nic_flash_print Don't need to keep a struct netxen_new_user_info on the stack when we only are interested in printing the serial_num. Change to only reading the serial_num. Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_hw.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 05748ca6f216..af7356468251 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -1132,8 +1132,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) u32 fw_minor = 0; u32 fw_build = 0; char brd_name[NETXEN_MAX_SHORT_NAME]; - struct netxen_new_user_info user_info; - int i, addr = NETXEN_USER_START; + char serial_num[32]; + int i, addr; __le32 *ptr32; struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); @@ -1150,10 +1150,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) valid = 0; } if (valid) { - ptr32 = (u32 *) & user_info; - for (i = 0; - i < sizeof(struct netxen_new_user_info) / sizeof(u32); - i++) { + ptr32 = (u32 *)&serial_num; + addr = NETXEN_USER_START + + offsetof(struct netxen_new_user_info, serial_num); + for (i = 0; i < 8; i++) { if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { printk("%s: ERROR reading %s board userarea.\n", netxen_nic_driver_name, @@ -1163,10 +1163,11 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) ptr32++; addr += sizeof(u32); } + get_brd_name_by_type(board_info->board_type, brd_name); printk("NetXen %s Board S/N %s Chip id 0x%x\n", - brd_name, user_info.serial_num, board_info->chip_id); + brd_name, serial_num, board_info->chip_id); printk("NetXen %s Board #%d, Chip id 0x%x\n", board_info->board_type == 0x0b ? "XGB" : "GBE", -- cgit v1.2.2 From 815b97c6b8861f2e539c9ecb44c02b7b8ac11ca4 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Tue, 22 Apr 2008 17:18:29 -0500 Subject: gianfar: Fix skb allocation strategy gianfar was unable to handle failed skb allocation for rx buffers, so we were spinning until it succeeded. Actually, it was worse--we were spinning for a long time, and then silently failing. Instead, we take Stephen Hemminger's suggestion to try the allocation earlier, and drop the packet if it failed. We also make a couple of tweaks to how buffer descriptors are set up. Signed-off-by: Andy Fleming Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 100 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b917616bf6f1..99a4b990939f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -98,7 +98,6 @@ #include "gianfar_mii.h" #define TX_TIMEOUT (1*HZ) -#define SKB_ALLOC_TIMEOUT 1000000 #undef BRIEF_GFAR_ERRORS #undef VERBOSE_GFAR_ERRORS @@ -115,7 +114,9 @@ static int gfar_enet_open(struct net_device *dev); static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev); static void gfar_timeout(struct net_device *dev); static int gfar_close(struct net_device *dev); -struct sk_buff *gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp); +struct sk_buff *gfar_new_skb(struct net_device *dev); +static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp, + struct sk_buff *skb); static int gfar_set_mac_address(struct net_device *dev); static int gfar_change_mtu(struct net_device *dev, int new_mtu); static irqreturn_t gfar_error(int irq, void *dev_id); @@ -783,14 +784,21 @@ int startup_gfar(struct net_device *dev) rxbdp = priv->rx_bd_base; for (i = 0; i < priv->rx_ring_size; i++) { - struct sk_buff *skb = NULL; + struct sk_buff *skb; - rxbdp->status = 0; + skb = gfar_new_skb(dev); - skb = gfar_new_skb(dev, rxbdp); + if (!skb) { + printk(KERN_ERR "%s: Can't allocate RX buffers\n", + dev->name); + + goto err_rxalloc_fail; + } priv->rx_skbuff[i] = skb; + gfar_new_rxbdp(dev, rxbdp, skb); + rxbdp++; } @@ -916,6 +924,7 @@ rx_irq_fail: tx_irq_fail: free_irq(priv->interruptError, dev); err_irq_fail: +err_rxalloc_fail: rx_skb_fail: free_skb_resources(priv); tx_skb_fail: @@ -1328,18 +1337,37 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id) return IRQ_HANDLED; } -struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) +static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp, + struct sk_buff *skb) +{ + struct gfar_private *priv = netdev_priv(dev); + u32 * status_len = (u32 *)bdp; + u16 flags; + + bdp->bufPtr = dma_map_single(&dev->dev, skb->data, + priv->rx_buffer_size, DMA_FROM_DEVICE); + + flags = RXBD_EMPTY | RXBD_INTERRUPT; + + if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1) + flags |= RXBD_WRAP; + + eieio(); + + *status_len = (u32)flags << 16; +} + + +struct sk_buff * gfar_new_skb(struct net_device *dev) { unsigned int alignamount; struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb = NULL; - unsigned int timeout = SKB_ALLOC_TIMEOUT; /* We have to allocate the skb, so keep trying till we succeed */ - while ((!skb) && timeout--) - skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT); + skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT); - if (NULL == skb) + if (!skb) return NULL; alignamount = RXBUF_ALIGNMENT - @@ -1350,15 +1378,6 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) */ skb_reserve(skb, alignamount); - bdp->bufPtr = dma_map_single(&dev->dev, skb->data, - priv->rx_buffer_size, DMA_FROM_DEVICE); - - bdp->length = 0; - - /* Mark the buffer empty */ - eieio(); - bdp->status |= (RXBD_EMPTY | RXBD_INTERRUPT); - return skb; } @@ -1544,10 +1563,31 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) bdp = priv->cur_rx; while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { + struct sk_buff *newskb; rmb(); + + /* Add another skb for the future */ + newskb = gfar_new_skb(dev); + skb = priv->rx_skbuff[priv->skb_currx]; - if ((bdp->status & RXBD_LAST) && !(bdp->status & RXBD_ERR)) { + /* We drop the frame if we failed to allocate a new buffer */ + if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || + bdp->status & RXBD_ERR)) { + count_errors(bdp->status, dev); + + if (unlikely(!newskb)) + newskb = skb; + + if (skb) { + dma_unmap_single(&priv->dev->dev, + bdp->bufPtr, + priv->rx_buffer_size, + DMA_FROM_DEVICE); + + dev_kfree_skb_any(skb); + } + } else { /* Increment the number of packets */ dev->stats.rx_packets++; howmany++; @@ -1558,23 +1598,14 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) gfar_process_frame(dev, skb, pkt_len); dev->stats.rx_bytes += pkt_len; - } else { - count_errors(bdp->status, dev); - - if (skb) - dev_kfree_skb_any(skb); - - priv->rx_skbuff[priv->skb_currx] = NULL; } dev->last_rx = jiffies; - /* Clear the status flags for this buffer */ - bdp->status &= ~RXBD_STATS; + priv->rx_skbuff[priv->skb_currx] = newskb; - /* Add another skb for the future */ - skb = gfar_new_skb(dev, bdp); - priv->rx_skbuff[priv->skb_currx] = skb; + /* Setup the new bdp */ + gfar_new_rxbdp(dev, bdp, newskb); /* Update to the next pointer */ if (bdp->status & RXBD_WRAP) @@ -1584,9 +1615,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) /* update to point at the next skb */ priv->skb_currx = - (priv->skb_currx + - 1) & RX_RING_MOD_MASK(priv->rx_ring_size); - + (priv->skb_currx + 1) & + RX_RING_MOD_MASK(priv->rx_ring_size); } /* Update the current rxbd pointer to be the next one */ -- cgit v1.2.2 From cca87c18ce3357e52facf6519f4ab0fbedd1279f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 23 Apr 2008 15:17:14 +1000 Subject: ibm_newemac: Increase MDIO timeouts This patch doubles the MDIO timeouts in EMAC as there are field cases where they are two short to communicate with some PHYs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/net/ibm_newemac/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 490d690b5e7f..5d2108c5ac7c 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -738,7 +738,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg) rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); /* Wait for management interface to become idle */ - n = 10; + n = 20; while (!emac_phy_done(dev, in_be32(&p->stacr))) { udelay(1); if (!--n) { @@ -763,7 +763,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg) out_be32(&p->stacr, r); /* Wait for read to complete */ - n = 100; + n = 200; while (!emac_phy_done(dev, (r = in_be32(&p->stacr)))) { udelay(1); if (!--n) { @@ -810,7 +810,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg, rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port); /* Wait for management interface to be idle */ - n = 10; + n = 20; while (!emac_phy_done(dev, in_be32(&p->stacr))) { udelay(1); if (!--n) { @@ -836,7 +836,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg, out_be32(&p->stacr, r); /* Wait for write to complete */ - n = 100; + n = 200; while (!emac_phy_done(dev, in_be32(&p->stacr))) { udelay(1); if (!--n) { -- cgit v1.2.2 From 9f3f7910c67adfb520bbae3d8b16985439a97198 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Wed, 23 Apr 2008 14:37:30 -0400 Subject: forcedeth: realtek phy crossover detection This patch fixes an issue seen with the realtek 8201 phy. This phy has a problem with crossover detection and it needs to be disabled. The problem only arises on certain switches. Therefore, a module parameter has been added to allow enabling crossover detection if needed. The default will be set to disabled. Signed-off-by: Ayaz Abdulla Signed-off-by: Jeff Garzik --- drivers/net/forcedeth.c | 220 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 178 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 73d85b31fbdc..35f66d4a4595 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -483,16 +483,22 @@ union ring_type { #define DESC_VER_3 3 /* PHY defines */ -#define PHY_OUI_MARVELL 0x5043 -#define PHY_OUI_CICADA 0x03f1 -#define PHY_OUI_VITESSE 0x01c1 -#define PHY_OUI_REALTEK 0x0732 +#define PHY_OUI_MARVELL 0x5043 +#define PHY_OUI_CICADA 0x03f1 +#define PHY_OUI_VITESSE 0x01c1 +#define PHY_OUI_REALTEK 0x0732 +#define PHY_OUI_REALTEK2 0x0020 #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 #define PHYID2_OUI_SHFT 10 #define PHYID2_MODEL_MASK 0x03f0 -#define PHY_MODEL_MARVELL_E3016 0x220 +#define PHY_MODEL_REALTEK_8211 0x0110 +#define PHY_REV_MASK 0x0001 +#define PHY_REV_REALTEK_8211B 0x0000 +#define PHY_REV_REALTEK_8211C 0x0001 +#define PHY_MODEL_REALTEK_8201 0x0200 +#define PHY_MODEL_MARVELL_E3016 0x0220 #define PHY_MARVELL_E3016_INITMASK 0x0300 #define PHY_CICADA_INIT1 0x0f000 #define PHY_CICADA_INIT2 0x0e00 @@ -519,10 +525,18 @@ union ring_type { #define PHY_REALTEK_INIT_REG1 0x1f #define PHY_REALTEK_INIT_REG2 0x19 #define PHY_REALTEK_INIT_REG3 0x13 +#define PHY_REALTEK_INIT_REG4 0x14 +#define PHY_REALTEK_INIT_REG5 0x18 +#define PHY_REALTEK_INIT_REG6 0x11 #define PHY_REALTEK_INIT1 0x0000 #define PHY_REALTEK_INIT2 0x8e00 #define PHY_REALTEK_INIT3 0x0001 #define PHY_REALTEK_INIT4 0xad17 +#define PHY_REALTEK_INIT5 0xfb54 +#define PHY_REALTEK_INIT6 0xf5c7 +#define PHY_REALTEK_INIT7 0x1000 +#define PHY_REALTEK_INIT8 0x0003 +#define PHY_REALTEK_INIT_MSK1 0x0003 #define PHY_GIGABIT 0x0100 @@ -701,6 +715,7 @@ struct fe_priv { int wolenabled; unsigned int phy_oui; unsigned int phy_model; + unsigned int phy_rev; u16 gigabit; int intr_test; int recover_error; @@ -714,6 +729,7 @@ struct fe_priv { u32 txrxctl_bits; u32 vlanctl_bits; u32 driver_data; + u32 device_id; u32 register_size; int rx_csum; u32 mac_in_use; @@ -824,6 +840,16 @@ enum { }; static int dma_64bit = NV_DMA_64BIT_ENABLED; +/* + * Crossover Detection + * Realtek 8201 phy + some OEM boards do not work properly. + */ +enum { + NV_CROSSOVER_DETECTION_DISABLED, + NV_CROSSOVER_DETECTION_ENABLED +}; +static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; + static inline struct fe_priv *get_nvpriv(struct net_device *dev) { return netdev_priv(dev); @@ -1088,25 +1114,53 @@ static int phy_init(struct net_device *dev) } } if (np->phy_oui == PHY_OUI_REALTEK) { - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; + if (np->phy_model == PHY_MODEL_REALTEK_8211 && + np->phy_rev == PHY_REV_REALTEK_8211B) { + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; + if (np->phy_model == PHY_MODEL_REALTEK_8201) { + if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); + phy_reserved |= PHY_REALTEK_INIT7; + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } } } @@ -1246,26 +1300,71 @@ static int phy_init(struct net_device *dev) } } if (np->phy_oui == PHY_OUI_REALTEK) { - /* reset could have cleared these out, set them back */ - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; + if (np->phy_model == PHY_MODEL_REALTEK_8211 && + np->phy_rev == PHY_REV_REALTEK_8211B) { + /* reset could have cleared these out, set them back */ + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } } - if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { - printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; + if (np->phy_model == PHY_MODEL_REALTEK_8201) { + if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { + phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); + phy_reserved |= PHY_REALTEK_INIT7; + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); + phy_reserved &= ~PHY_REALTEK_INIT_MSK1; + phy_reserved |= PHY_REALTEK_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } } } @@ -5254,6 +5353,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* copy of driver data */ np->driver_data = id->driver_data; + /* copy of device id */ + np->device_id = id->device; /* handle different descriptor versions */ if (id->driver_data & DEV_HAS_HIGH_DMA) { @@ -5543,6 +5644,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i pci_name(pci_dev), id1, id2, phyaddr); np->phyaddr = phyaddr; np->phy_oui = id1 | id2; + + /* Realtek hardcoded phy id1 to all zero's on certain phys */ + if (np->phy_oui == PHY_OUI_REALTEK2) + np->phy_oui = PHY_OUI_REALTEK; + /* Setup phy revision for Realtek */ + if (np->phy_oui == PHY_OUI_REALTEK && np->phy_model == PHY_MODEL_REALTEK_8211) + np->phy_rev = mii_rw(dev, phyaddr, MII_RESV1, MII_READ) & PHY_REV_MASK; + break; } if (i == 33) { @@ -5621,6 +5730,28 @@ out: return err; } +static void nv_restore_phy(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + u16 phy_reserved, mii_control; + + if (np->phy_oui == PHY_OUI_REALTEK && + np->phy_model == PHY_MODEL_REALTEK_8201 && + phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { + mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3); + phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); + phy_reserved &= ~PHY_REALTEK_INIT_MSK1; + phy_reserved |= PHY_REALTEK_INIT8; + mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved); + mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1); + + /* restart auto negotiation */ + mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); + mii_rw(dev, np->phyaddr, MII_BMCR, mii_control); + } +} + static void __devexit nv_remove(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); @@ -5637,6 +5768,9 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); + /* restore any phy related changes */ + nv_restore_phy(dev); + /* free all structures */ free_rings(dev); iounmap(get_hwbase(dev)); @@ -5888,6 +6022,8 @@ module_param(msix, int, 0); MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0."); module_param(dma_64bit, int, 0); MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); +module_param(phy_cross, int, 0); +MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); -- cgit v1.2.2 From 78c6146f16d45f52c33ddb6b48c10fc6cfc53659 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 24 Apr 2008 23:33:06 -0700 Subject: tg3: sparse cleanup Fix the following sparse warning : drivers/net/tg3.c:4025:3: warning: context imbalance in 'tg3_restart_hw' - unexpected unlock Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc4c62b8e81a..e3f74c9f78bd 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4017,6 +4017,8 @@ static int tg3_halt(struct tg3 *, int, int); * Invoked with tp->lock held. */ static int tg3_restart_hw(struct tg3 *tp, int reset_phy) + __releases(tp->lock) + __acquires(tp->lock) { int err; -- cgit v1.2.2 From d4f73c8e459d355e10051174d859ffd0ef5764c0 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 24 Apr 2008 23:32:33 +0200 Subject: via-velocity: fix vlan receipt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vlans were using a single CAM register (see mac_set_vlan_cam) - setting the address filtering registers for vlans is not needed when there is no vlan The non-tagged interface is filtered out as soon as a tagged (!= 0) interface is created. Its traffic appears again when an zero-tagged interface is created. Tested on Via Epia SN (VT6130 chipset) with several vlans whose tag was above or beyond 255. Signed-off-by: Séguier Régis Acked-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/via-velocity.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index ed1afaf683a4..6b8d882d197b 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -605,7 +605,6 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, static void velocity_init_cam_filter(struct velocity_info *vptr) { struct mac_regs __iomem * regs = vptr->mac_regs; - unsigned short vid; /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); @@ -617,29 +616,33 @@ static void velocity_init_cam_filter(struct velocity_info *vptr) mac_set_vlan_cam_mask(regs, vptr->vCAMmask); mac_set_cam_mask(regs, vptr->mCAMmask); - /* Enable first VCAM */ + /* Enable VCAMs */ if (vptr->vlgrp) { - for (vid = 0; vid < VLAN_VID_MASK; vid++) { - if (vlan_group_get_device(vptr->vlgrp, vid)) { - /* If Tagging option is enabled and - VLAN ID is not zero, then - turn on MCFG_RTGOPT also */ - if (vid != 0) - WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); + unsigned int vid, i = 0; + + if (!vlan_group_get_device(vptr->vlgrp, 0)) + WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); - mac_set_vlan_cam(regs, 0, (u8 *) &vid); + for (vid = 1; (vid < VLAN_VID_MASK); vid++) { + if (vlan_group_get_device(vptr->vlgrp, vid)) { + mac_set_vlan_cam(regs, i, (u8 *) &vid); + vptr->vCAMmask[i / 8] |= 0x1 << (i % 8); + if (++i >= VCAM_SIZE) + break; } } - vptr->vCAMmask[0] |= 1; mac_set_vlan_cam_mask(regs, vptr->vCAMmask); - } else { - u16 temp = 0; - mac_set_vlan_cam(regs, 0, (u8 *) &temp); - temp = 1; - mac_set_vlan_cam_mask(regs, (u8 *) &temp); } } +static void velocity_vlan_rx_register(struct net_device *dev, + struct vlan_group *grp) +{ + struct velocity_info *vptr = netdev_priv(dev); + + vptr->vlgrp = grp; +} + static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { struct velocity_info *vptr = netdev_priv(dev); @@ -959,11 +962,13 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid; dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid; + dev->vlan_rx_register = velocity_vlan_rx_register; #ifdef VELOCITY_ZERO_COPY_SUPPORT dev->features |= NETIF_F_SG; #endif - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER; + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | + NETIF_F_HW_VLAN_RX; if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) dev->features |= NETIF_F_IP_CSUM; @@ -1597,8 +1602,13 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx) skb_put(skb, pkt_len - 4); skb->protocol = eth_type_trans(skb, vptr->dev); + if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) { + vlan_hwaccel_rx(skb, vptr->vlgrp, + swab16(le16_to_cpu(rd->rdesc1.PQTAG))); + } else + netif_rx(skb); + stats->rx_bytes += pkt_len; - netif_rx(skb); return 0; } -- cgit v1.2.2 From f946dffed6334f08da065a89ed65026ebf8b33b4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 25 Apr 2008 03:11:31 -0400 Subject: [netdrvr] tehuti: move ioctl perm check closer to function start Noticed by davem. Signed-off-by: Jeff Garzik --- drivers/net/tehuti.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index d2e1b219673d..e83b166aa6b9 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -649,6 +649,9 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); } + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + switch (data[0]) { case BDX_OP_READ: @@ -664,8 +667,6 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) break; case BDX_OP_WRITE: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; error = bdx_range_check(priv, data[1]); if (error < 0) return error; -- cgit v1.2.2 From d43fa1499622e3e561380c34e076aade954e2c2c Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 25 Apr 2008 09:32:26 +0200 Subject: [MTD] [NAND] AT91 hardware ECC compile fix for at91sam9263 / at91sam9260 The sam926x docs allegedly don't list an "ECC_PARITY" field, and the header files in the upstream kernel don't have it either. Masking with it was useless anyway, so just remove it. Signed-off-by: Richard Genoud Signed-off-by: David Woodhouse --- drivers/mtd/nand/at91_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index c3eb203a2ad0..09ebcc93ed3b 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -199,7 +199,7 @@ static int at91_nand_calculate(struct mtd_info *mtd, unsigned int ecc_value; /* get the first 2 ECC bytes */ - ecc_value = ecc_readl(host->ecc, PR) & AT91_ECC_PARITY; + ecc_value = ecc_readl(host->ecc, PR); ecc_code[eccpos[0]] = ecc_value & 0xFF; ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; -- cgit v1.2.2 From 2314488e81b6f8966d3ea607c4517a64bf58f283 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 24 Apr 2008 23:51:29 +0900 Subject: [MTD] [NAND] at91_nand: control NCE signal This driver did not control NCE signal during normal operations (only enable NCE on probing and disable NCE on removing). This patch make NCE signal inactive on idle state. Signed-off-by: Atsushi Nemoto Signed-off-by: David Woodhouse --- drivers/mtd/nand/at91_nand.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index 09ebcc93ed3b..414ceaecdb3a 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -101,6 +101,12 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *nand_chip = mtd->priv; struct at91_nand_host *host = nand_chip->priv; + if (host->board->enable_pin && (ctrl & NAND_CTRL_CHANGE)) { + if (ctrl & NAND_NCE) + at91_set_gpio_value(host->board->enable_pin, 0); + else + at91_set_gpio_value(host->board->enable_pin, 1); + } if (cmd == NAND_CMD_NONE) return; -- cgit v1.2.2 From afc4bca63941746f1d49394620d294074150e664 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 25 Apr 2008 12:07:31 +0800 Subject: [MTD] [NAND] bf5xx_nand: Avoid crash if bfin_mac is installed. http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=4053 Singed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: David Woodhouse --- drivers/mtd/nand/bf5xx_nand.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 1fbc24ca5836..e87a57297328 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -1,6 +1,6 @@ /* linux/drivers/mtd/nand/bf5xx_nand.c * - * Copyright 2006-2007 Analog Devices Inc. + * Copyright 2006-2008 Analog Devices Inc. * http://blackfin.uclinux.org/ * Bryan Wu * @@ -74,7 +74,7 @@ static int hardware_ecc = 1; static int hardware_ecc; #endif -static unsigned short bfin_nfc_pin_req[] = +static const unsigned short bfin_nfc_pin_req[] = {P_NAND_CE, P_NAND_RB, P_NAND_D0, @@ -581,12 +581,6 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) bfin_write_NFC_IRQSTAT(val); SSYNC(); - if (peripheral_request_list(bfin_nfc_pin_req, DRV_NAME)) { - printk(KERN_ERR DRV_NAME - ": Requesting Peripherals failed\n"); - return -EFAULT; - } - /* DMA initialization */ if (bf5xx_nand_dma_init(info)) err = -ENXIO; @@ -654,6 +648,12 @@ static int bf5xx_nand_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "(%p)\n", pdev); + if (peripheral_request_list(bfin_nfc_pin_req, DRV_NAME)) { + printk(KERN_ERR DRV_NAME + ": Requesting Peripherals failed\n"); + return -EFAULT; + } + if (!plat) { dev_err(&pdev->dev, "no platform specific information\n"); goto exit_error; -- cgit v1.2.2 From 2230b76b3838a37167f80487c694d8691248da9f Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Fri, 25 Apr 2008 12:07:32 +0800 Subject: [MTD] m25p80: add FAST_READ access support to M25Pxx Signed-off-by: Bryan Wu Signed-off-by: David Woodhouse --- drivers/mtd/devices/Kconfig | 7 +++++++ drivers/mtd/devices/m25p80.c | 31 +++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 811d56fd890f..35ed1103dbb2 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -77,6 +77,13 @@ config MTD_M25P80 if you want to specify device partitioning or to use a device which doesn't support the JEDEC ID instruction. +config M25PXX_USE_FAST_READ + bool "Use FAST_READ OPCode allowing SPI CLK <= 50MHz" + depends on MTD_M25P80 + default y + help + This option enables FAST_READ access supported by ST M25Pxx. + config MTD_SLRAM tristate "Uncached system RAM" help diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 60408c955a13..3f5041d39f24 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -33,7 +33,7 @@ /* Flash opcodes. */ #define OPCODE_WREN 0x06 /* Write enable */ #define OPCODE_RDSR 0x05 /* Read status register */ -#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */ +#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ @@ -52,7 +52,15 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_COUNT 100000 +#define CMD_SIZE 4 +#ifdef CONFIG_M25PXX_USE_FAST_READ +#define OPCODE_READ OPCODE_FAST_READ +#define FAST_READ_DUMMY_BYTE 1 +#else +#define OPCODE_READ OPCODE_NORM_READ +#define FAST_READ_DUMMY_BYTE 0 +#endif #ifdef CONFIG_MTD_PARTITIONS #define mtd_has_partitions() (1) @@ -68,7 +76,7 @@ struct m25p { struct mtd_info mtd; unsigned partitioned:1; u8 erase_opcode; - u8 command[4]; + u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE]; }; static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) @@ -167,7 +175,7 @@ static int erase_sector(struct m25p *flash, u32 offset) flash->command[2] = offset >> 8; flash->command[3] = offset; - spi_write(flash->spi, flash->command, sizeof(flash->command)); + spi_write(flash->spi, flash->command, CMD_SIZE); return 0; } @@ -253,8 +261,12 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, spi_message_init(&m); memset(t, 0, (sizeof t)); + /* NOTE: + * OPCODE_FAST_READ (if available) is faster. + * Should add 1 byte DUMMY_BYTE. + */ t[0].tx_buf = flash->command; - t[0].len = sizeof(flash->command); + t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE; spi_message_add_tail(&t[0], &m); t[1].rx_buf = buf; @@ -287,7 +299,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, spi_sync(flash->spi, &m); - *retlen = m.actual_length - sizeof(flash->command); + *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE; mutex_unlock(&flash->lock); @@ -325,7 +337,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, memset(t, 0, (sizeof t)); t[0].tx_buf = flash->command; - t[0].len = sizeof(flash->command); + t[0].len = CMD_SIZE; spi_message_add_tail(&t[0], &m); t[1].tx_buf = buf; @@ -354,7 +366,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, spi_sync(flash->spi, &m); - *retlen = m.actual_length - sizeof(flash->command); + *retlen = m.actual_length - CMD_SIZE; } else { u32 i; @@ -364,7 +376,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, t[1].len = page_size; spi_sync(flash->spi, &m); - *retlen = m.actual_length - sizeof(flash->command); + *retlen = m.actual_length - CMD_SIZE; /* write everything in PAGESIZE chunks */ for (i = page_size; i < len; i += page_size) { @@ -387,8 +399,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, spi_sync(flash->spi, &m); if (retlen) - *retlen += m.actual_length - - sizeof(flash->command); + *retlen += m.actual_length - CMD_SIZE; } } -- cgit v1.2.2 From 3887ed5231fb6f339f36c3a0297c996cd1a1dad9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 25 Apr 2008 12:07:33 +0800 Subject: [MTD] m25p80: Add Support for ATMEL AT25DF641 64-Megabit SPI Flash Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 3f5041d39f24..25efd331ef28 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -446,6 +446,7 @@ static struct flash_info __devinitdata m25p_data [] = { { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, }, { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, }, + { "at25df641", 0x1f4800, 64 * 1024, 128, SECT_4K, }, { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, }, { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, }, -- cgit v1.2.2 From 924362629bf5645aee5f49f8a0d0d5b193e65997 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 21:41:50 +0100 Subject: dm snapshot: fix chunksize sector conversion If a snapshot has a smaller chunksize than the page size the conversion to pages currently returns 0 instead of 1, causing: kernel BUG in mempool_resize. Signed-off-by: Mikulas Patocka Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon Cc: stable@kernel.org --- drivers/md/dm-exception-store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 5bbce29f143a..c7d305bfd838 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -131,7 +131,7 @@ struct pstore { static unsigned sectors_to_pages(unsigned sectors) { - return sectors / (PAGE_SIZE >> 9); + return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9); } static int alloc_area(struct pstore *ps) -- cgit v1.2.2 From 8ee2767a5903fde549fd3597690f64c8d951051a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 24 Apr 2008 21:42:36 +0100 Subject: dm snapshot: reduce default memory allocation Limit the amount of memory allocated per snapshot on systems with a large page size. (The larger default chunk size on these systems compensates for the smaller number of pages reserved.) Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon --- drivers/md/dm-snap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 4dc8a43c034b..08047fb1cac9 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -36,9 +36,9 @@ #define SNAPSHOT_COPY_PRIORITY 2 /* - * Each snapshot reserves this many pages for io + * Reserve 1MB for each snapshot initially (with minimum of 1 page). */ -#define SNAPSHOT_PAGES 256 +#define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) static struct workqueue_struct *ksnapd; static void flush_queued_bios(struct work_struct *work); -- cgit v1.2.2 From c12bfc923ee02de5611730ddec087c11b3947038 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 24 Apr 2008 21:42:44 +0100 Subject: dm raid1: use list_split_init Use shorter list_splice_init() for brevity. Signed-off-by: Robert P. J. Day Signed-off-by: Alasdair G Kergon --- drivers/md/dm-raid1.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 762cb086bb7f..64489e714c95 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -405,24 +405,22 @@ static void rh_update_states(struct region_hash *rh) write_lock_irq(&rh->hash_lock); spin_lock(&rh->region_lock); if (!list_empty(&rh->clean_regions)) { - list_splice(&rh->clean_regions, &clean); - INIT_LIST_HEAD(&rh->clean_regions); + list_splice_init(&rh->clean_regions, &clean); list_for_each_entry(reg, &clean, list) list_del(®->hash_list); } if (!list_empty(&rh->recovered_regions)) { - list_splice(&rh->recovered_regions, &recovered); - INIT_LIST_HEAD(&rh->recovered_regions); + list_splice_init(&rh->recovered_regions, &recovered); list_for_each_entry (reg, &recovered, list) list_del(®->hash_list); } if (!list_empty(&rh->failed_recovered_regions)) { - list_splice(&rh->failed_recovered_regions, &failed_recovered); - INIT_LIST_HEAD(&rh->failed_recovered_regions); + list_splice_init(&rh->failed_recovered_regions, + &failed_recovered); list_for_each_entry(reg, &failed_recovered, list) list_del(®->hash_list); -- cgit v1.2.2 From b7fd54a70f99061721e604d72d940541e5b2b168 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Thu, 24 Apr 2008 21:43:06 +0100 Subject: dm log: generalise name in messages Change dm-log.c messages from "mirror log" to "dirty region log" as a new dm target wants to share this code. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- drivers/md/dm-log.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 2a74b2142f50..34c25b0073ec 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2003 Sistina Software + * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. * * This file is released under the LGPL. */ @@ -12,7 +13,7 @@ #include "dm-log.h" #include "dm-io.h" -#define DM_MSG_PREFIX "mirror log" +#define DM_MSG_PREFIX "dirty region log" static LIST_HEAD(_log_types); static DEFINE_SPINLOCK(_lock); @@ -315,7 +316,7 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, int r; if (argc < 1 || argc > 2) { - DMWARN("wrong number of arguments to mirror log"); + DMWARN("wrong number of arguments to dirty region log"); return -EINVAL; } @@ -325,8 +326,8 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, else if (!strcmp(argv[1], "nosync")) sync = NOSYNC; else { - DMWARN("unrecognised sync argument to mirror log: %s", - argv[1]); + DMWARN("unrecognised sync argument to " + "dirty region log: %s", argv[1]); return -EINVAL; } } @@ -467,7 +468,7 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, struct dm_dev *dev; if (argc < 2 || argc > 3) { - DMWARN("wrong number of arguments to disk mirror log"); + DMWARN("wrong number of arguments to disk dirty region log"); return -EINVAL; } @@ -524,7 +525,7 @@ static int disk_resume(struct dirty_log *log) /* read the disk header */ r = read_header(lc); if (r) { - DMWARN("%s: Failed to read header on mirror log device", + DMWARN("%s: Failed to read header on dirty region log device", lc->log_dev->name); fail_log_device(lc); /* @@ -562,7 +563,7 @@ static int disk_resume(struct dirty_log *log) /* write the new header */ r = write_header(lc); if (r) { - DMWARN("%s: Failed to write header on mirror log device", + DMWARN("%s: Failed to write header on dirty region log device", lc->log_dev->name); fail_log_device(lc); } -- cgit v1.2.2 From 769aef30f0f505c44bbe9fcd2c911a052a386139 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Thu, 24 Apr 2008 21:43:09 +0100 Subject: dm log: move dirty region log code into separate module Move the dirty region log code into a separate module so other targets can share the code. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- drivers/md/Makefile | 4 ++-- drivers/md/dm-log.c | 9 ++++++++- drivers/md/dm-raid1.c | 10 +--------- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/md/Makefile b/drivers/md/Makefile index d9aa7edb8780..be4b069bbc58 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -6,7 +6,7 @@ dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ dm-ioctl.o dm-io.o kcopyd.o dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o dm-snapshot-objs := dm-snap.o dm-exception-store.o -dm-mirror-objs := dm-log.o dm-raid1.o +dm-mirror-objs := dm-raid1.o dm-rdac-objs := dm-mpath-rdac.o dm-hp-sw-objs := dm-mpath-hp-sw.o md-mod-objs := md.o bitmap.o @@ -39,7 +39,7 @@ obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o obj-$(CONFIG_DM_MULTIPATH_HP) += dm-hp-sw.o obj-$(CONFIG_DM_MULTIPATH_RDAC) += dm-rdac.o obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o -obj-$(CONFIG_DM_MIRROR) += dm-mirror.o +obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o obj-$(CONFIG_DM_ZERO) += dm-zero.o quiet_cmd_unroll = UNROLL $@ diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 34c25b0073ec..f6b20def2ac8 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -777,7 +777,7 @@ int __init dm_dirty_log_init(void) return r; } -void dm_dirty_log_exit(void) +void __exit dm_dirty_log_exit(void) { dm_unregister_dirty_log_type(&_disk_type); dm_unregister_dirty_log_type(&_core_type); @@ -787,3 +787,10 @@ EXPORT_SYMBOL(dm_register_dirty_log_type); EXPORT_SYMBOL(dm_unregister_dirty_log_type); EXPORT_SYMBOL(dm_create_dirty_log); EXPORT_SYMBOL(dm_destroy_dirty_log); + +module_init(dm_dirty_log_init); +module_exit(dm_dirty_log_exit); + +MODULE_DESCRIPTION(DM_NAME " dirty region log"); +MODULE_AUTHOR("Joe Thornber, Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 64489e714c95..c4ce01180b6f 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1862,15 +1862,9 @@ static int __init dm_mirror_init(void) { int r; - r = dm_dirty_log_init(); - if (r) - return r; - r = dm_register_target(&mirror_target); - if (r < 0) { + if (r < 0) DMERR("Failed to register mirror target"); - dm_dirty_log_exit(); - } return r; } @@ -1882,8 +1876,6 @@ static void __exit dm_mirror_exit(void) r = dm_unregister_target(&mirror_target); if (r < 0) DMERR("unregister failed %d", r); - - dm_dirty_log_exit(); } /* Module hooks */ -- cgit v1.2.2 From 72727bad544b4ce0a3f7853bfd7ae939f398007d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 21:43:11 +0100 Subject: dm snapshot: store pointer to target instance Save pointer to dm_target in dm_snapshot structure. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm-snap.c | 6 +++--- drivers/md/dm-snap.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 08047fb1cac9..08a8cbddb60d 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -536,7 +536,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->last_percent = 0; init_rwsem(&s->lock); spin_lock_init(&s->pe_lock); - s->table = ti->table; + s->ti = ti; /* Allocate hash table for COW data */ if (init_hash_tables(s)) { @@ -699,7 +699,7 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) s->valid = 0; - dm_table_event(s->table); + dm_table_event(s->ti->table); } static void get_pending_exception(struct dm_snap_pending_exception *pe) @@ -1060,7 +1060,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) goto next_snapshot; /* Nothing to do if writing beyond end of snapshot */ - if (bio->bi_sector >= dm_table_get_size(snap->table)) + if (bio->bi_sector >= dm_table_get_size(snap->ti->table)) goto next_snapshot; /* diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index 93bce5d49742..434d1dbe6bce 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h @@ -132,7 +132,7 @@ struct exception_store { struct dm_snapshot { struct rw_semaphore lock; - struct dm_table *table; + struct dm_target *ti; struct dm_dev *origin; struct dm_dev *cow; -- cgit v1.2.2 From e01fd7eeb00f8078103f4ed3e8ef64474c11f300 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 24 Apr 2008 21:43:14 +0100 Subject: dm io: rename error to error_bits Rename 'error' to 'error_bits' for clarity. Signed-off-by: Alasdair G Kergon --- drivers/md/dm-io.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 8f25f628ef16..c56c7eb86fe2 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -20,7 +20,7 @@ struct dm_io_client { /* FIXME: can we shrink this ? */ struct io { - unsigned long error; + unsigned long error_bits; atomic_t count; struct task_struct *sleeper; struct dm_io_client *client; @@ -107,14 +107,14 @@ static inline unsigned bio_get_region(struct bio *bio) static void dec_count(struct io *io, unsigned int region, int error) { if (error) - set_bit(region, &io->error); + set_bit(region, &io->error_bits); if (atomic_dec_and_test(&io->count)) { if (io->sleeper) wake_up_process(io->sleeper); else { - unsigned long r = io->error; + unsigned long r = io->error_bits; io_notify_fn fn = io->callback; void *context = io->context; @@ -357,7 +357,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, return -EIO; } - io.error = 0; + io.error_bits = 0; atomic_set(&io.count, 1); /* see dispatch_io() */ io.sleeper = current; io.client = client; @@ -378,9 +378,9 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, return -EINTR; if (error_bits) - *error_bits = io.error; + *error_bits = io.error_bits; - return io.error ? -EIO : 0; + return io.error_bits ? -EIO : 0; } static int async_io(struct dm_io_client *client, unsigned int num_regions, @@ -396,7 +396,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, } io = mempool_alloc(client->pool, GFP_NOIO); - io->error = 0; + io->error_bits = 0; atomic_set(&io->count, 1); /* see dispatch_io() */ io->sleeper = NULL; io->client = client; -- cgit v1.2.2 From 22a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Thu, 24 Apr 2008 21:43:17 +0100 Subject: dm io: clean interface Clean up the dm-io interface to prepare for publishing it in include/linux. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- drivers/md/dm-exception-store.c | 4 ++-- drivers/md/dm-io.c | 11 ++++++----- drivers/md/dm-io.h | 18 ++++++++++++------ drivers/md/dm-log.c | 2 +- drivers/md/dm-raid1.c | 8 ++++---- drivers/md/dm-snap.c | 2 +- drivers/md/kcopyd.c | 9 +++++---- drivers/md/kcopyd.h | 4 ++-- 8 files changed, 33 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index c7d305bfd838..6933301733df 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -159,7 +159,7 @@ static void free_area(struct pstore *ps) } struct mdata_req { - struct io_region *where; + struct dm_io_region *where; struct dm_io_request *io_req; struct work_struct work; int result; @@ -177,7 +177,7 @@ static void do_metadata(struct work_struct *work) */ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw, int metadata) { - struct io_region where = { + struct dm_io_region where = { .bdev = ps->snap->cow->bdev, .sector = ps->snap->chunk_size * chunk, .count = ps->snap->chunk_size, diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index c56c7eb86fe2..978c0414cf05 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -6,6 +6,7 @@ */ #include "dm-io.h" +#include "dm.h" #include #include @@ -271,7 +272,7 @@ static void km_dp_init(struct dpages *dp, void *data) /*----------------------------------------------------------------- * IO routines that accept a list of pages. *---------------------------------------------------------------*/ -static void do_region(int rw, unsigned int region, struct io_region *where, +static void do_region(int rw, unsigned region, struct dm_io_region *where, struct dpages *dp, struct io *io) { struct bio *bio; @@ -320,7 +321,7 @@ static void do_region(int rw, unsigned int region, struct io_region *where, } static void dispatch_io(int rw, unsigned int num_regions, - struct io_region *where, struct dpages *dp, + struct dm_io_region *where, struct dpages *dp, struct io *io, int sync) { int i; @@ -347,7 +348,7 @@ static void dispatch_io(int rw, unsigned int num_regions, } static int sync_io(struct dm_io_client *client, unsigned int num_regions, - struct io_region *where, int rw, struct dpages *dp, + struct dm_io_region *where, int rw, struct dpages *dp, unsigned long *error_bits) { struct io io; @@ -384,7 +385,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, } static int async_io(struct dm_io_client *client, unsigned int num_regions, - struct io_region *where, int rw, struct dpages *dp, + struct dm_io_region *where, int rw, struct dpages *dp, io_notify_fn fn, void *context) { struct io *io; @@ -438,7 +439,7 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp) * New collapsed (a)synchronous interface */ int dm_io(struct dm_io_request *io_req, unsigned num_regions, - struct io_region *where, unsigned long *sync_error_bits) + struct dm_io_region *where, unsigned long *sync_error_bits) { int r; struct dpages dp; diff --git a/drivers/md/dm-io.h b/drivers/md/dm-io.h index f647e2cceaa6..b6bf17ee2f61 100644 --- a/drivers/md/dm-io.h +++ b/drivers/md/dm-io.h @@ -1,15 +1,20 @@ /* * Copyright (C) 2003 Sistina Software + * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. + * + * Device-Mapper low-level I/O. * * This file is released under the GPL. */ -#ifndef _DM_IO_H -#define _DM_IO_H +#ifndef _LINUX_DM_IO_H +#define _LINUX_DM_IO_H + +#ifdef __KERNEL__ -#include "dm.h" +#include -struct io_region { +struct dm_io_region { struct block_device *bdev; sector_t sector; sector_t count; /* If this is zero the region is ignored. */ @@ -74,6 +79,7 @@ void dm_io_client_destroy(struct dm_io_client *client); * error occurred doing io to the corresponding region. */ int dm_io(struct dm_io_request *io_req, unsigned num_regions, - struct io_region *region, unsigned long *sync_error_bits); + struct dm_io_region *region, unsigned long *sync_error_bits); -#endif +#endif /* __KERNEL__ */ +#endif /* _LINUX_DM_IO_H */ diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index f6b20def2ac8..14f785fc308a 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -208,7 +208,7 @@ struct log_c { struct dm_dev *log_dev; struct log_header header; - struct io_region header_location; + struct dm_io_region header_location; struct log_header *disk_header; }; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index c4ce01180b6f..0d4e7e9653ff 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -788,7 +788,7 @@ static int recover(struct mirror_set *ms, struct region *reg) { int r; unsigned int i; - struct io_region from, to[KCOPYD_MAX_REGIONS], *dest; + struct dm_io_region from, to[KCOPYD_MAX_REGIONS], *dest; struct mirror *m; unsigned long flags = 0; @@ -907,7 +907,7 @@ static void map_bio(struct mirror *m, struct bio *bio) bio->bi_sector = map_sector(m, bio); } -static void map_region(struct io_region *io, struct mirror *m, +static void map_region(struct dm_io_region *io, struct mirror *m, struct bio *bio) { io->bdev = m->dev->bdev; @@ -949,7 +949,7 @@ static void read_callback(unsigned long error, void *context) /* Asynchronous read. */ static void read_async_bio(struct mirror *m, struct bio *bio) { - struct io_region io; + struct dm_io_region io; struct dm_io_request io_req = { .bi_rw = READ, .mem.type = DM_IO_BVEC, @@ -1105,7 +1105,7 @@ out: static void do_write(struct mirror_set *ms, struct bio *bio) { unsigned int i; - struct io_region io[ms->nr_mirrors], *dest = io; + struct dm_io_region io[ms->nr_mirrors], *dest = io; struct mirror *m; struct dm_io_request io_req = { .bi_rw = WRITE, diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 08a8cbddb60d..bab159b77742 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -824,7 +824,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) static void start_copy(struct dm_snap_pending_exception *pe) { struct dm_snapshot *s = pe->snap; - struct io_region src, dest; + struct dm_io_region src, dest; struct block_device *bdev = s->origin->bdev; sector_t dev_size; diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index e76b52ade690..21fea42c68c4 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -25,6 +25,7 @@ #include #include "kcopyd.h" +#include "dm.h" static struct workqueue_struct *_kcopyd_wq; static struct work_struct _kcopyd_work; @@ -175,13 +176,13 @@ struct kcopyd_job { * Either READ or WRITE */ int rw; - struct io_region source; + struct dm_io_region source; /* * The destinations for the transfer. */ unsigned int num_dests; - struct io_region dests[KCOPYD_MAX_REGIONS]; + struct dm_io_region dests[KCOPYD_MAX_REGIONS]; sector_t offset; unsigned int nr_pages; @@ -526,8 +527,8 @@ static void split_job(struct kcopyd_job *job) segment_complete(0, 0u, job); } -int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, - unsigned int num_dests, struct io_region *dests, +int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from, + unsigned int num_dests, struct dm_io_region *dests, unsigned int flags, kcopyd_notify_fn fn, void *context) { struct kcopyd_job *job; diff --git a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h index 4845f2a0c676..588f05dffbe1 100644 --- a/drivers/md/kcopyd.h +++ b/drivers/md/kcopyd.h @@ -35,8 +35,8 @@ void kcopyd_client_destroy(struct kcopyd_client *kc); typedef void (*kcopyd_notify_fn)(int read_err, unsigned long write_err, void *context); -int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, - unsigned int num_dests, struct io_region *dests, +int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from, + unsigned num_dests, struct dm_io_region *dests, unsigned int flags, kcopyd_notify_fn fn, void *context); #endif -- cgit v1.2.2 From eb69aca5d3370b81450d68edeebc2bb9a3eb9689 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Thu, 24 Apr 2008 21:43:19 +0100 Subject: dm kcopyd: clean interface Clean up the kcopyd interface to prepare for publishing it in include/linux. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- drivers/md/dm-raid1.c | 16 ++++++++-------- drivers/md/dm-snap.c | 8 ++++---- drivers/md/dm-snap.h | 2 +- drivers/md/kcopyd.c | 51 +++++++++++++++++++++++++-------------------------- drivers/md/kcopyd.h | 43 ++++++++++++++++++++++++------------------- 5 files changed, 62 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 0d4e7e9653ff..32c7c6d10939 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -133,7 +133,7 @@ struct mirror_set { struct dm_target *ti; struct list_head list; struct region_hash rh; - struct kcopyd_client *kcopyd_client; + struct dm_kcopyd_client *kcopyd_client; uint64_t features; spinlock_t lock; /* protects the lists */ @@ -788,7 +788,7 @@ static int recover(struct mirror_set *ms, struct region *reg) { int r; unsigned int i; - struct dm_io_region from, to[KCOPYD_MAX_REGIONS], *dest; + struct dm_io_region from, to[DM_KCOPYD_MAX_REGIONS], *dest; struct mirror *m; unsigned long flags = 0; @@ -820,9 +820,9 @@ static int recover(struct mirror_set *ms, struct region *reg) } /* hand to kcopyd */ - set_bit(KCOPYD_IGNORE_ERROR, &flags); - r = kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to, flags, - recovery_complete, reg); + set_bit(DM_KCOPYD_IGNORE_ERROR, &flags); + r = dm_kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to, + flags, recovery_complete, reg); return r; } @@ -1504,7 +1504,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) argc -= args_used; if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || - nr_mirrors < 2 || nr_mirrors > KCOPYD_MAX_REGIONS + 1) { + nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { ti->error = "Invalid number of mirrors"; dm_destroy_dirty_log(dl); return -EINVAL; @@ -1569,7 +1569,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto err_destroy_wq; } - r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client); + r = dm_kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client); if (r) goto err_destroy_wq; @@ -1588,7 +1588,7 @@ static void mirror_dtr(struct dm_target *ti) struct mirror_set *ms = (struct mirror_set *) ti->private; flush_workqueue(ms->kmirrord_wq); - kcopyd_client_destroy(ms->kcopyd_client); + dm_kcopyd_client_destroy(ms->kcopyd_client); destroy_workqueue(ms->kmirrord_wq); free_context(ms, ti, ms->nr_mirrors); } diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index bab159b77742..e1dcca99392e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -558,7 +558,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad4; } - r = kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); + r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); if (r) { ti->error = "Could not create kcopyd client"; goto bad5; @@ -591,7 +591,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) return 0; bad6: - kcopyd_client_destroy(s->kcopyd_client); + dm_kcopyd_client_destroy(s->kcopyd_client); bad5: s->store.destroy(&s->store); @@ -613,7 +613,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) static void __free_exceptions(struct dm_snapshot *s) { - kcopyd_client_destroy(s->kcopyd_client); + dm_kcopyd_client_destroy(s->kcopyd_client); s->kcopyd_client = NULL; exit_exception_table(&s->pending, pending_cache); @@ -839,7 +839,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) dest.count = src.count; /* Hand over to kcopyd */ - kcopyd_copy(s->kcopyd_client, + dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe); } diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index 434d1dbe6bce..24f9fb73b982 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h @@ -169,7 +169,7 @@ struct dm_snapshot { /* The on disk metadata handler */ struct exception_store store; - struct kcopyd_client *kcopyd_client; + struct dm_kcopyd_client *kcopyd_client; /* Queue of snapshot writes for ksnapd to flush */ struct bio_list queued_bios; diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index 21fea42c68c4..4f2c61acf7c6 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -9,9 +9,8 @@ * completion notification. */ -#include +#include #include - #include #include #include @@ -39,7 +38,7 @@ static void wake(void) * Each kcopyd client has its own little pool of preallocated * pages for kcopyd io. *---------------------------------------------------------------*/ -struct kcopyd_client { +struct dm_kcopyd_client { struct list_head list; spinlock_t lock; @@ -76,7 +75,7 @@ static void free_pl(struct page_list *pl) kfree(pl); } -static int kcopyd_get_pages(struct kcopyd_client *kc, +static int kcopyd_get_pages(struct dm_kcopyd_client *kc, unsigned int nr, struct page_list **pages) { struct page_list *pl; @@ -99,7 +98,7 @@ static int kcopyd_get_pages(struct kcopyd_client *kc, return 0; } -static void kcopyd_put_pages(struct kcopyd_client *kc, struct page_list *pl) +static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) { struct page_list *cursor; @@ -127,7 +126,7 @@ static void drop_pages(struct page_list *pl) } } -static int client_alloc_pages(struct kcopyd_client *kc, unsigned int nr) +static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) { unsigned int i; struct page_list *pl = NULL, *next; @@ -148,7 +147,7 @@ static int client_alloc_pages(struct kcopyd_client *kc, unsigned int nr) return 0; } -static void client_free_pages(struct kcopyd_client *kc) +static void client_free_pages(struct dm_kcopyd_client *kc) { BUG_ON(kc->nr_free_pages != kc->nr_pages); drop_pages(kc->pages); @@ -162,7 +161,7 @@ static void client_free_pages(struct kcopyd_client *kc) * ever having to do io (which could cause a deadlock). *---------------------------------------------------------------*/ struct kcopyd_job { - struct kcopyd_client *kc; + struct dm_kcopyd_client *kc; struct list_head list; unsigned long flags; @@ -182,7 +181,7 @@ struct kcopyd_job { * The destinations for the transfer. */ unsigned int num_dests; - struct dm_io_region dests[KCOPYD_MAX_REGIONS]; + struct dm_io_region dests[DM_KCOPYD_MAX_REGIONS]; sector_t offset; unsigned int nr_pages; @@ -192,7 +191,7 @@ struct kcopyd_job { * Set this to ensure you are notified when the job has * completed. 'context' is for callback to use. */ - kcopyd_notify_fn fn; + dm_kcopyd_notify_fn fn; void *context; /* @@ -295,8 +294,8 @@ static int run_complete_job(struct kcopyd_job *job) void *context = job->context; int read_err = job->read_err; unsigned long write_err = job->write_err; - kcopyd_notify_fn fn = job->fn; - struct kcopyd_client *kc = job->kc; + dm_kcopyd_notify_fn fn = job->fn; + struct dm_kcopyd_client *kc = job->kc; kcopyd_put_pages(kc, job->pages); mempool_free(job, _job_pool); @@ -318,7 +317,7 @@ static void complete_io(unsigned long error, void *context) else job->read_err = 1; - if (!test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) { + if (!test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { push(&_complete_jobs, job); wake(); return; @@ -470,7 +469,7 @@ static void segment_complete(int read_err, unsigned long write_err, * Only dispatch more work if there hasn't been an error. */ if ((!job->read_err && !job->write_err) || - test_bit(KCOPYD_IGNORE_ERROR, &job->flags)) { + test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { /* get the next chunk of work */ progress = job->progress; count = job->source.count - progress; @@ -527,9 +526,9 @@ static void split_job(struct kcopyd_job *job) segment_complete(0, 0u, job); } -int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from, - unsigned int num_dests, struct dm_io_region *dests, - unsigned int flags, kcopyd_notify_fn fn, void *context) +int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, + unsigned int num_dests, struct dm_io_region *dests, + unsigned int flags, dm_kcopyd_notify_fn fn, void *context) { struct kcopyd_job *job; @@ -570,6 +569,7 @@ int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from, return 0; } +EXPORT_SYMBOL(dm_kcopyd_copy); /* * Cancels a kcopyd job, eg. someone might be deactivating a @@ -589,14 +589,14 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) static DEFINE_MUTEX(_client_lock); static LIST_HEAD(_clients); -static void client_add(struct kcopyd_client *kc) +static void client_add(struct dm_kcopyd_client *kc) { mutex_lock(&_client_lock); list_add(&kc->list, &_clients); mutex_unlock(&_client_lock); } -static void client_del(struct kcopyd_client *kc) +static void client_del(struct dm_kcopyd_client *kc) { mutex_lock(&_client_lock); list_del(&kc->list); @@ -650,10 +650,11 @@ static void kcopyd_exit(void) mutex_unlock(&kcopyd_init_lock); } -int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result) +int dm_kcopyd_client_create(unsigned int nr_pages, + struct dm_kcopyd_client **result) { int r = 0; - struct kcopyd_client *kc; + struct dm_kcopyd_client *kc; r = kcopyd_init(); if (r) @@ -691,8 +692,9 @@ int kcopyd_client_create(unsigned int nr_pages, struct kcopyd_client **result) *result = kc; return 0; } +EXPORT_SYMBOL(dm_kcopyd_client_create); -void kcopyd_client_destroy(struct kcopyd_client *kc) +void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) { /* Wait for completion of all jobs submitted by this client. */ wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); @@ -703,7 +705,4 @@ void kcopyd_client_destroy(struct kcopyd_client *kc) kfree(kc); kcopyd_exit(); } - -EXPORT_SYMBOL(kcopyd_client_create); -EXPORT_SYMBOL(kcopyd_client_destroy); -EXPORT_SYMBOL(kcopyd_copy); +EXPORT_SYMBOL(dm_kcopyd_client_destroy); diff --git a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h index 588f05dffbe1..d3057846b0b0 100644 --- a/drivers/md/kcopyd.h +++ b/drivers/md/kcopyd.h @@ -1,29 +1,33 @@ /* - * Copyright (C) 2001 Sistina Software + * Copyright (C) 2001 - 2003 Sistina Software + * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. * - * This file is released under the GPL. + * kcopyd provides a simple interface for copying an area of one + * block-device to one or more other block-devices, either synchronous + * or with an asynchronous completion notification. * - * Kcopyd provides a simple interface for copying an area of one - * block-device to one or more other block-devices, with an asynchronous - * completion notification. + * This file is released under the GPL. */ -#ifndef DM_KCOPYD_H -#define DM_KCOPYD_H +#ifndef _LINUX_DM_KCOPYD_H +#define _LINUX_DM_KCOPYD_H + +#ifdef __KERNEL__ #include "dm-io.h" /* FIXME: make this configurable */ -#define KCOPYD_MAX_REGIONS 8 +#define DM_KCOPYD_MAX_REGIONS 8 -#define KCOPYD_IGNORE_ERROR 1 +#define DM_KCOPYD_IGNORE_ERROR 1 /* - * To use kcopyd you must first create a kcopyd client object. + * To use kcopyd you must first create a dm_kcopyd_client object. */ -struct kcopyd_client; -int kcopyd_client_create(unsigned int num_pages, struct kcopyd_client **result); -void kcopyd_client_destroy(struct kcopyd_client *kc); +struct dm_kcopyd_client; +int dm_kcopyd_client_create(unsigned num_pages, + struct dm_kcopyd_client **result); +void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); /* * Submit a copy job to kcopyd. This is built on top of the @@ -32,11 +36,12 @@ void kcopyd_client_destroy(struct kcopyd_client *kc); * read_err is a boolean, * write_err is a bitset, with 1 bit for each destination region */ -typedef void (*kcopyd_notify_fn)(int read_err, unsigned long write_err, - void *context); +typedef void (*dm_kcopyd_notify_fn)(int read_err, unsigned long write_err, + void *context); -int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from, - unsigned num_dests, struct dm_io_region *dests, - unsigned int flags, kcopyd_notify_fn fn, void *context); +int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, + unsigned num_dests, struct dm_io_region *dests, + unsigned flags, dm_kcopyd_notify_fn fn, void *context); -#endif +#endif /* __KERNEL__ */ +#endif /* _LINUX_DM_KCOPYD_H */ -- cgit v1.2.2 From 416cd17b1982217bca3dc41b9f00b0b38fdaadad Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Thu, 24 Apr 2008 21:43:35 +0100 Subject: dm log: clean interface Clean up the dm-log interface to prepare for publishing it in include/linux. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- drivers/md/dm-log.c | 89 ++++++++++++++++++++++++++------------------------- drivers/md/dm-log.h | 84 ++++++++++++++++++++++++------------------------ drivers/md/dm-raid1.c | 36 ++++++++++----------- drivers/md/dm.h | 6 ++++ 4 files changed, 112 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 14f785fc308a..b776701cc8fa 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -12,13 +12,14 @@ #include "dm-log.h" #include "dm-io.h" +#include "dm.h" #define DM_MSG_PREFIX "dirty region log" static LIST_HEAD(_log_types); static DEFINE_SPINLOCK(_lock); -int dm_register_dirty_log_type(struct dirty_log_type *type) +int dm_dirty_log_type_register(struct dm_dirty_log_type *type) { spin_lock(&_lock); type->use_count = 0; @@ -27,8 +28,9 @@ int dm_register_dirty_log_type(struct dirty_log_type *type) return 0; } +EXPORT_SYMBOL(dm_dirty_log_type_register); -int dm_unregister_dirty_log_type(struct dirty_log_type *type) +int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) { spin_lock(&_lock); @@ -41,10 +43,11 @@ int dm_unregister_dirty_log_type(struct dirty_log_type *type) return 0; } +EXPORT_SYMBOL(dm_dirty_log_type_unregister); -static struct dirty_log_type *_get_type(const char *type_name) +static struct dm_dirty_log_type *_get_type(const char *type_name) { - struct dirty_log_type *type; + struct dm_dirty_log_type *type; spin_lock(&_lock); list_for_each_entry (type, &_log_types, list) @@ -79,10 +82,10 @@ static struct dirty_log_type *_get_type(const char *type_name) * * Returns: dirty_log_type* on success, NULL on failure */ -static struct dirty_log_type *get_type(const char *type_name) +static struct dm_dirty_log_type *get_type(const char *type_name) { char *p, *type_name_dup; - struct dirty_log_type *type; + struct dm_dirty_log_type *type; type = _get_type(type_name); if (type) @@ -111,7 +114,7 @@ static struct dirty_log_type *get_type(const char *type_name) return type; } -static void put_type(struct dirty_log_type *type) +static void put_type(struct dm_dirty_log_type *type) { spin_lock(&_lock); if (!--type->use_count) @@ -119,11 +122,12 @@ static void put_type(struct dirty_log_type *type) spin_unlock(&_lock); } -struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, - unsigned int argc, char **argv) +struct dm_dirty_log *dm_dirty_log_create(const char *type_name, + struct dm_target *ti, + unsigned int argc, char **argv) { - struct dirty_log_type *type; - struct dirty_log *log; + struct dm_dirty_log_type *type; + struct dm_dirty_log *log; log = kmalloc(sizeof(*log), GFP_KERNEL); if (!log) @@ -144,13 +148,15 @@ struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *t return log; } +EXPORT_SYMBOL(dm_dirty_log_create); -void dm_destroy_dirty_log(struct dirty_log *log) +void dm_dirty_log_destroy(struct dm_dirty_log *log) { log->type->dtr(log); put_type(log->type); kfree(log); } +EXPORT_SYMBOL(dm_dirty_log_destroy); /*----------------------------------------------------------------- * Persistent and core logs share a lot of their implementation. @@ -216,7 +222,7 @@ struct log_c { * The touched member needs to be updated every time we access * one of the bitsets. */ -static inline int log_test_bit(uint32_t *bs, unsigned bit) +static inline int log_test_bit(uint32_t *bs, unsigned bit) { return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0; } @@ -303,7 +309,7 @@ static inline int write_header(struct log_c *log) * argv contains region_size followed optionally by [no]sync *--------------------------------------------------------------*/ #define BYTE_SHIFT 3 -static int create_log_context(struct dirty_log *log, struct dm_target *ti, +static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, unsigned int argc, char **argv, struct dm_dev *dev) { @@ -435,7 +441,7 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, return 0; } -static int core_ctr(struct dirty_log *log, struct dm_target *ti, +static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti, unsigned int argc, char **argv) { return create_log_context(log, ti, argc, argv, NULL); @@ -448,7 +454,7 @@ static void destroy_log_context(struct log_c *lc) kfree(lc); } -static void core_dtr(struct dirty_log *log) +static void core_dtr(struct dm_dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; @@ -461,7 +467,7 @@ static void core_dtr(struct dirty_log *log) * * argv contains log_device region_size followed optionally by [no]sync *--------------------------------------------------------------*/ -static int disk_ctr(struct dirty_log *log, struct dm_target *ti, +static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti, unsigned int argc, char **argv) { int r; @@ -486,7 +492,7 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, return 0; } -static void disk_dtr(struct dirty_log *log) +static void disk_dtr(struct dm_dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; @@ -515,7 +521,7 @@ static void fail_log_device(struct log_c *lc) dm_table_event(lc->ti->table); } -static int disk_resume(struct dirty_log *log) +static int disk_resume(struct dm_dirty_log *log) { int r; unsigned i; @@ -571,38 +577,38 @@ static int disk_resume(struct dirty_log *log) return r; } -static uint32_t core_get_region_size(struct dirty_log *log) +static uint32_t core_get_region_size(struct dm_dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; return lc->region_size; } -static int core_resume(struct dirty_log *log) +static int core_resume(struct dm_dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; lc->sync_search = 0; return 0; } -static int core_is_clean(struct dirty_log *log, region_t region) +static int core_is_clean(struct dm_dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; return log_test_bit(lc->clean_bits, region); } -static int core_in_sync(struct dirty_log *log, region_t region, int block) +static int core_in_sync(struct dm_dirty_log *log, region_t region, int block) { struct log_c *lc = (struct log_c *) log->context; return log_test_bit(lc->sync_bits, region); } -static int core_flush(struct dirty_log *log) +static int core_flush(struct dm_dirty_log *log) { /* no op */ return 0; } -static int disk_flush(struct dirty_log *log) +static int disk_flush(struct dm_dirty_log *log) { int r; struct log_c *lc = (struct log_c *) log->context; @@ -620,19 +626,19 @@ static int disk_flush(struct dirty_log *log) return r; } -static void core_mark_region(struct dirty_log *log, region_t region) +static void core_mark_region(struct dm_dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; log_clear_bit(lc, lc->clean_bits, region); } -static void core_clear_region(struct dirty_log *log, region_t region) +static void core_clear_region(struct dm_dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; log_set_bit(lc, lc->clean_bits, region); } -static int core_get_resync_work(struct dirty_log *log, region_t *region) +static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) { struct log_c *lc = (struct log_c *) log->context; @@ -655,7 +661,7 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) return 1; } -static void core_set_region_sync(struct dirty_log *log, region_t region, +static void core_set_region_sync(struct dm_dirty_log *log, region_t region, int in_sync) { struct log_c *lc = (struct log_c *) log->context; @@ -670,7 +676,7 @@ static void core_set_region_sync(struct dirty_log *log, region_t region, } } -static region_t core_get_sync_count(struct dirty_log *log) +static region_t core_get_sync_count(struct dm_dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; @@ -681,7 +687,7 @@ static region_t core_get_sync_count(struct dirty_log *log) if (lc->sync != DEFAULTSYNC) \ DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "") -static int core_status(struct dirty_log *log, status_type_t status, +static int core_status(struct dm_dirty_log *log, status_type_t status, char *result, unsigned int maxlen) { int sz = 0; @@ -701,7 +707,7 @@ static int core_status(struct dirty_log *log, status_type_t status, return sz; } -static int disk_status(struct dirty_log *log, status_type_t status, +static int disk_status(struct dm_dirty_log *log, status_type_t status, char *result, unsigned int maxlen) { int sz = 0; @@ -723,7 +729,7 @@ static int disk_status(struct dirty_log *log, status_type_t status, return sz; } -static struct dirty_log_type _core_type = { +static struct dm_dirty_log_type _core_type = { .name = "core", .module = THIS_MODULE, .ctr = core_ctr, @@ -741,7 +747,7 @@ static struct dirty_log_type _core_type = { .status = core_status, }; -static struct dirty_log_type _disk_type = { +static struct dm_dirty_log_type _disk_type = { .name = "disk", .module = THIS_MODULE, .ctr = disk_ctr, @@ -764,14 +770,14 @@ int __init dm_dirty_log_init(void) { int r; - r = dm_register_dirty_log_type(&_core_type); + r = dm_dirty_log_type_register(&_core_type); if (r) DMWARN("couldn't register core log"); - r = dm_register_dirty_log_type(&_disk_type); + r = dm_dirty_log_type_register(&_disk_type); if (r) { DMWARN("couldn't register disk type"); - dm_unregister_dirty_log_type(&_core_type); + dm_dirty_log_type_unregister(&_core_type); } return r; @@ -779,15 +785,10 @@ int __init dm_dirty_log_init(void) void __exit dm_dirty_log_exit(void) { - dm_unregister_dirty_log_type(&_disk_type); - dm_unregister_dirty_log_type(&_core_type); + dm_dirty_log_type_unregister(&_disk_type); + dm_dirty_log_type_unregister(&_core_type); } -EXPORT_SYMBOL(dm_register_dirty_log_type); -EXPORT_SYMBOL(dm_unregister_dirty_log_type); -EXPORT_SYMBOL(dm_create_dirty_log); -EXPORT_SYMBOL(dm_destroy_dirty_log); - module_init(dm_dirty_log_init); module_exit(dm_dirty_log_exit); diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h index 3fae87eb5963..2da48a857cb9 100644 --- a/drivers/md/dm-log.h +++ b/drivers/md/dm-log.h @@ -1,52 +1,58 @@ /* * Copyright (C) 2003 Sistina Software + * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. + * + * Device-Mapper dirty region log. * * This file is released under the LGPL. */ -#ifndef DM_DIRTY_LOG -#define DM_DIRTY_LOG +#ifndef _LINUX_DM_DIRTY_LOG +#define _LINUX_DM_DIRTY_LOG + +#ifdef __KERNEL__ -#include "dm.h" +#include +#include typedef sector_t region_t; -struct dirty_log_type; +struct dm_dirty_log_type; -struct dirty_log { - struct dirty_log_type *type; +struct dm_dirty_log { + struct dm_dirty_log_type *type; void *context; }; -struct dirty_log_type { +struct dm_dirty_log_type { struct list_head list; const char *name; struct module *module; - unsigned int use_count; + unsigned use_count; - int (*ctr)(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv); - void (*dtr)(struct dirty_log *log); + int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, + unsigned argc, char **argv); + void (*dtr)(struct dm_dirty_log *log); /* * There are times when we don't want the log to touch * the disk. */ - int (*presuspend)(struct dirty_log *log); - int (*postsuspend)(struct dirty_log *log); - int (*resume)(struct dirty_log *log); + int (*presuspend)(struct dm_dirty_log *log); + int (*postsuspend)(struct dm_dirty_log *log); + int (*resume)(struct dm_dirty_log *log); /* * Retrieves the smallest size of region that the log can * deal with. */ - uint32_t (*get_region_size)(struct dirty_log *log); + uint32_t (*get_region_size)(struct dm_dirty_log *log); - /* + /* * A predicate to say whether a region is clean or not. * May block. */ - int (*is_clean)(struct dirty_log *log, region_t region); + int (*is_clean)(struct dm_dirty_log *log, region_t region); /* * Returns: 0, 1, -EWOULDBLOCK, < 0 @@ -59,13 +65,14 @@ struct dirty_log_type { * passed to a daemon to deal with, since a daemon is * allowed to block. */ - int (*in_sync)(struct dirty_log *log, region_t region, int can_block); + int (*in_sync)(struct dm_dirty_log *log, region_t region, + int can_block); /* * Flush the current log state (eg, to disk). This * function may block. */ - int (*flush)(struct dirty_log *log); + int (*flush)(struct dm_dirty_log *log); /* * Mark an area as clean or dirty. These functions may @@ -73,8 +80,8 @@ struct dirty_log_type { * be extremely rare (eg, allocating another chunk of * memory for some reason). */ - void (*mark_region)(struct dirty_log *log, region_t region); - void (*clear_region)(struct dirty_log *log, region_t region); + void (*mark_region)(struct dm_dirty_log *log, region_t region); + void (*clear_region)(struct dm_dirty_log *log, region_t region); /* * Returns: <0 (error), 0 (no region), 1 (region) @@ -88,44 +95,39 @@ struct dirty_log_type { * tells you if an area is synchronised, the other * assigns recovery work. */ - int (*get_resync_work)(struct dirty_log *log, region_t *region); + int (*get_resync_work)(struct dm_dirty_log *log, region_t *region); /* * This notifies the log that the resync status of a region * has changed. It also clears the region from the recovering * list (if present). */ - void (*set_region_sync)(struct dirty_log *log, + void (*set_region_sync)(struct dm_dirty_log *log, region_t region, int in_sync); - /* + /* * Returns the number of regions that are in sync. - */ - region_t (*get_sync_count)(struct dirty_log *log); + */ + region_t (*get_sync_count)(struct dm_dirty_log *log); /* * Support function for mirror status requests. */ - int (*status)(struct dirty_log *log, status_type_t status_type, - char *result, unsigned int maxlen); + int (*status)(struct dm_dirty_log *log, status_type_t status_type, + char *result, unsigned maxlen); }; -int dm_register_dirty_log_type(struct dirty_log_type *type); -int dm_unregister_dirty_log_type(struct dirty_log_type *type); - +int dm_dirty_log_type_register(struct dm_dirty_log_type *type); +int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type); /* * Make sure you use these two functions, rather than calling * type->constructor/destructor() directly. */ -struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, - unsigned int argc, char **argv); -void dm_destroy_dirty_log(struct dirty_log *log); - -/* - * init/exit functions. - */ -int dm_dirty_log_init(void); -void dm_dirty_log_exit(void); +struct dm_dirty_log *dm_dirty_log_create(const char *type_name, + struct dm_target *ti, + unsigned argc, char **argv); +void dm_dirty_log_destroy(struct dm_dirty_log *log); -#endif +#endif /* __KERNEL__ */ +#endif /* _LINUX_DM_DIRTY_LOG_H */ diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 32c7c6d10939..5beeced4e522 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -74,7 +74,7 @@ struct region_hash { unsigned region_shift; /* holds persistent region state */ - struct dirty_log *log; + struct dm_dirty_log *log; /* hash table */ rwlock_t hash_lock; @@ -184,7 +184,7 @@ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); #define MIN_REGIONS 64 #define MAX_RECOVERY 1 static int rh_init(struct region_hash *rh, struct mirror_set *ms, - struct dirty_log *log, uint32_t region_size, + struct dm_dirty_log *log, uint32_t region_size, region_t nr_regions) { unsigned int nr_buckets, max_buckets; @@ -249,7 +249,7 @@ static void rh_exit(struct region_hash *rh) } if (rh->log) - dm_destroy_dirty_log(rh->log); + dm_dirty_log_destroy(rh->log); if (rh->region_pool) mempool_destroy(rh->region_pool); vfree(rh->buckets); @@ -831,7 +831,7 @@ static void do_recovery(struct mirror_set *ms) { int r; struct region *reg; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; /* * Start quiescing some regions. @@ -1017,7 +1017,7 @@ static void __bio_mark_nosync(struct mirror_set *ms, { unsigned long flags; struct region_hash *rh = &ms->rh; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; struct region *reg; region_t region = bio_to_region(rh, bio); int recovering = 0; @@ -1301,7 +1301,7 @@ static void do_mirror(struct work_struct *work) static struct mirror_set *alloc_context(unsigned int nr_mirrors, uint32_t region_size, struct dm_target *ti, - struct dirty_log *dl) + struct dm_dirty_log *dl) { size_t len; struct mirror_set *ms = NULL; @@ -1401,12 +1401,12 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti, /* * Create dirty log: log_type #log_params */ -static struct dirty_log *create_dirty_log(struct dm_target *ti, +static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, unsigned int argc, char **argv, unsigned int *args_used) { unsigned int param_count; - struct dirty_log *dl; + struct dm_dirty_log *dl; if (argc < 2) { ti->error = "Insufficient mirror log arguments"; @@ -1425,7 +1425,7 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - dl = dm_create_dirty_log(argv[0], ti, param_count, argv + 2); + dl = dm_dirty_log_create(argv[0], ti, param_count, argv + 2); if (!dl) { ti->error = "Error creating mirror dirty log"; return NULL; @@ -1433,7 +1433,7 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti, if (!_check_region_size(ti, dl->type->get_region_size(dl))) { ti->error = "Invalid region size"; - dm_destroy_dirty_log(dl); + dm_dirty_log_destroy(dl); return NULL; } @@ -1494,7 +1494,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) int r; unsigned int nr_mirrors, m, args_used; struct mirror_set *ms; - struct dirty_log *dl; + struct dm_dirty_log *dl; dl = create_dirty_log(ti, argc, argv, &args_used); if (!dl) @@ -1506,7 +1506,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { ti->error = "Invalid number of mirrors"; - dm_destroy_dirty_log(dl); + dm_dirty_log_destroy(dl); return -EINVAL; } @@ -1514,13 +1514,13 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (argc < nr_mirrors * 2) { ti->error = "Too few mirror arguments"; - dm_destroy_dirty_log(dl); + dm_dirty_log_destroy(dl); return -EINVAL; } ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl); if (!ms) { - dm_destroy_dirty_log(dl); + dm_dirty_log_destroy(dl); return -ENOMEM; } @@ -1732,7 +1732,7 @@ out: static void mirror_presuspend(struct dm_target *ti) { struct mirror_set *ms = (struct mirror_set *) ti->private; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; atomic_set(&ms->suspend, 1); @@ -1761,7 +1761,7 @@ static void mirror_presuspend(struct dm_target *ti) static void mirror_postsuspend(struct dm_target *ti) { struct mirror_set *ms = ti->private; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; if (log->type->postsuspend && log->type->postsuspend(log)) /* FIXME: need better error handling */ @@ -1771,7 +1771,7 @@ static void mirror_postsuspend(struct dm_target *ti) static void mirror_resume(struct dm_target *ti) { struct mirror_set *ms = ti->private; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; atomic_set(&ms->suspend, 0); if (log->type->resume && log->type->resume(log)) @@ -1809,7 +1809,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type, { unsigned int m, sz = 0; struct mirror_set *ms = (struct mirror_set *) ti->private; - struct dirty_log *log = ms->rh.log; + struct dm_dirty_log *log = ms->rh.log; char buffer[ms->nr_mirrors + 1]; switch (type) { diff --git a/drivers/md/dm.h b/drivers/md/dm.h index b4584a39383b..17f2d6a8b124 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -189,4 +189,10 @@ int dm_lock_for_deletion(struct mapped_device *md); void dm_kobject_uevent(struct mapped_device *md); +/* + * Dirty log + */ +int dm_dirty_log_init(void); +void dm_dirty_log_exit(void); + #endif -- cgit v1.2.2 From b8206bc3de0b0665d47655d270c18ea46aff5372 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 24 Apr 2008 21:43:38 +0100 Subject: dm log: move register functions Reorder a couple of functions in the file so the next patch is readable. Signed-off-by: Alasdair G Kergon --- drivers/md/dm-log.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index b776701cc8fa..82df73f67a0d 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -19,32 +19,6 @@ static LIST_HEAD(_log_types); static DEFINE_SPINLOCK(_lock); -int dm_dirty_log_type_register(struct dm_dirty_log_type *type) -{ - spin_lock(&_lock); - type->use_count = 0; - list_add(&type->list, &_log_types); - spin_unlock(&_lock); - - return 0; -} -EXPORT_SYMBOL(dm_dirty_log_type_register); - -int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) -{ - spin_lock(&_lock); - - if (type->use_count) - DMWARN("Attempt to unregister a log type that is still in use"); - else - list_del(&type->list); - - spin_unlock(&_lock); - - return 0; -} -EXPORT_SYMBOL(dm_dirty_log_type_unregister); - static struct dm_dirty_log_type *_get_type(const char *type_name) { struct dm_dirty_log_type *type; @@ -122,6 +96,32 @@ static void put_type(struct dm_dirty_log_type *type) spin_unlock(&_lock); } +int dm_dirty_log_type_register(struct dm_dirty_log_type *type) +{ + spin_lock(&_lock); + type->use_count = 0; + list_add(&type->list, &_log_types); + spin_unlock(&_lock); + + return 0; +} +EXPORT_SYMBOL(dm_dirty_log_type_register); + +int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) +{ + spin_lock(&_lock); + + if (type->use_count) + DMWARN("Attempt to unregister a log type that is still in use"); + else + list_del(&type->list); + + spin_unlock(&_lock); + + return 0; +} +EXPORT_SYMBOL(dm_dirty_log_type_unregister); + struct dm_dirty_log *dm_dirty_log_create(const char *type_name, struct dm_target *ti, unsigned int argc, char **argv) -- cgit v1.2.2 From 2a23aa1ddb1f0c9eef2c929c89565c387f6bf68b Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 24 Apr 2008 21:43:41 +0100 Subject: dm log: make module use tracking internal Remove internal module reference fields from the interface. Signed-off-by: Jonathan Brassow Signed-off-by: Alasdair G Kergon --- drivers/md/dm-log.c | 123 +++++++++++++++++++++++++++++++++++++++------------- drivers/md/dm-log.h | 2 - 2 files changed, 94 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 82df73f67a0d..e6b6a9d5fdd2 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -16,34 +16,51 @@ #define DM_MSG_PREFIX "dirty region log" +struct dm_dirty_log_internal { + struct dm_dirty_log_type *type; + + struct list_head list; + long use; +}; + static LIST_HEAD(_log_types); static DEFINE_SPINLOCK(_lock); -static struct dm_dirty_log_type *_get_type(const char *type_name) +static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name) { - struct dm_dirty_log_type *type; + struct dm_dirty_log_internal *log_type; + + list_for_each_entry(log_type, &_log_types, list) + if (!strcmp(name, log_type->type->name)) + return log_type; + + return NULL; +} + +static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name) +{ + struct dm_dirty_log_internal *log_type; spin_lock(&_lock); - list_for_each_entry (type, &_log_types, list) - if (!strcmp(type_name, type->name)) { - if (!type->use_count && !try_module_get(type->module)){ - spin_unlock(&_lock); - return NULL; - } - type->use_count++; - spin_unlock(&_lock); - return type; - } + + log_type = __find_dirty_log_type(name); + if (log_type) { + if (!log_type->use && !try_module_get(log_type->type->module)) + log_type = NULL; + else + log_type->use++; + } spin_unlock(&_lock); - return NULL; + + return log_type; } /* * get_type * @type_name * - * Attempt to retrieve the dirty_log_type by name. If not already + * Attempt to retrieve the dm_dirty_log_type by name. If not already * available, attempt to load the appropriate module. * * Log modules are named "dm-log-" followed by the 'type_name'. @@ -59,11 +76,14 @@ static struct dm_dirty_log_type *_get_type(const char *type_name) static struct dm_dirty_log_type *get_type(const char *type_name) { char *p, *type_name_dup; - struct dm_dirty_log_type *type; + struct dm_dirty_log_internal *log_type; - type = _get_type(type_name); - if (type) - return type; + if (!type_name) + return NULL; + + log_type = _get_dirty_log_type(type_name); + if (log_type) + return log_type->type; type_name_dup = kstrdup(type_name, GFP_KERNEL); if (!type_name_dup) { @@ -73,50 +93,95 @@ static struct dm_dirty_log_type *get_type(const char *type_name) } while (request_module("dm-log-%s", type_name_dup) || - !(type = _get_type(type_name))) { + !(log_type = _get_dirty_log_type(type_name))) { p = strrchr(type_name_dup, '-'); if (!p) break; p[0] = '\0'; } - if (!type) + if (!log_type) DMWARN("Module for logging type \"%s\" not found.", type_name); kfree(type_name_dup); - return type; + return log_type ? log_type->type : NULL; } static void put_type(struct dm_dirty_log_type *type) { + struct dm_dirty_log_internal *log_type; + + if (!type) + return; + spin_lock(&_lock); - if (!--type->use_count) + log_type = __find_dirty_log_type(type->name); + if (!log_type) + goto out; + + if (!--log_type->use) module_put(type->module); + + BUG_ON(log_type->use < 0); + +out: spin_unlock(&_lock); } +static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type) +{ + struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type), + GFP_KERNEL); + + if (log_type) + log_type->type = type; + + return log_type; +} + int dm_dirty_log_type_register(struct dm_dirty_log_type *type) { + struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type); + int r = 0; + + if (!log_type) + return -ENOMEM; + spin_lock(&_lock); - type->use_count = 0; - list_add(&type->list, &_log_types); + if (!__find_dirty_log_type(type->name)) + list_add(&log_type->list, &_log_types); + else { + kfree(log_type); + r = -EEXIST; + } spin_unlock(&_lock); - return 0; + return r; } EXPORT_SYMBOL(dm_dirty_log_type_register); int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) { + struct dm_dirty_log_internal *log_type; + spin_lock(&_lock); - if (type->use_count) - DMWARN("Attempt to unregister a log type that is still in use"); - else - list_del(&type->list); + log_type = __find_dirty_log_type(type->name); + if (!log_type) { + spin_unlock(&_lock); + return -EINVAL; + } + + if (log_type->use) { + spin_unlock(&_lock); + return -ETXTBSY; + } + + list_del(&log_type->list); spin_unlock(&_lock); + kfree(log_type); return 0; } diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h index 2da48a857cb9..600c5fb2daad 100644 --- a/drivers/md/dm-log.h +++ b/drivers/md/dm-log.h @@ -25,10 +25,8 @@ struct dm_dirty_log { }; struct dm_dirty_log_type { - struct list_head list; const char *name; struct module *module; - unsigned use_count; int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, unsigned argc, char **argv); -- cgit v1.2.2 From 8c0cbc2f79bb222d21b466422fde71fcc9bd37e3 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 21:43:44 +0100 Subject: dm kcopyd: per device Make one kcopyd thread per device. The original shared kcopyd could deadlock. Configuration: --- drivers/md/kcopyd.c | 132 +++++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index 4f2c61acf7c6..3fb6c8334a82 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -26,14 +26,6 @@ #include "kcopyd.h" #include "dm.h" -static struct workqueue_struct *_kcopyd_wq; -static struct work_struct _kcopyd_work; - -static void wake(void) -{ - queue_work(_kcopyd_wq, &_kcopyd_work); -} - /*----------------------------------------------------------------- * Each kcopyd client has its own little pool of preallocated * pages for kcopyd io. @@ -50,8 +42,30 @@ struct dm_kcopyd_client { wait_queue_head_t destroyq; atomic_t nr_jobs; + + struct workqueue_struct *kcopyd_wq; + struct work_struct kcopyd_work; + +/* + * We maintain three lists of jobs: + * + * i) jobs waiting for pages + * ii) jobs that have pages, and are waiting for the io to be issued. + * iii) jobs that have completed. + * + * All three of these are protected by job_lock. + */ + spinlock_t job_lock; + struct list_head complete_jobs; + struct list_head io_jobs; + struct list_head pages_jobs; }; +static void wake(struct dm_kcopyd_client *kc) +{ + queue_work(kc->kcopyd_wq, &kc->kcopyd_work); +} + static struct page_list *alloc_pl(void) { struct page_list *pl; @@ -209,21 +223,6 @@ struct kcopyd_job { static struct kmem_cache *_job_cache; static mempool_t *_job_pool; -/* - * We maintain three lists of jobs: - * - * i) jobs waiting for pages - * ii) jobs that have pages, and are waiting for the io to be issued. - * iii) jobs that have completed. - * - * All three of these are protected by job_lock. - */ -static DEFINE_SPINLOCK(_job_lock); - -static LIST_HEAD(_complete_jobs); -static LIST_HEAD(_io_jobs); -static LIST_HEAD(_pages_jobs); - static int jobs_init(void) { _job_cache = KMEM_CACHE(kcopyd_job, 0); @@ -241,10 +240,6 @@ static int jobs_init(void) static void jobs_exit(void) { - BUG_ON(!list_empty(&_complete_jobs)); - BUG_ON(!list_empty(&_io_jobs)); - BUG_ON(!list_empty(&_pages_jobs)); - mempool_destroy(_job_pool); kmem_cache_destroy(_job_cache); _job_pool = NULL; @@ -255,18 +250,19 @@ static void jobs_exit(void) * Functions to push and pop a job onto the head of a given job * list. */ -static struct kcopyd_job *pop(struct list_head *jobs) +static struct kcopyd_job *pop(struct list_head *jobs, + struct dm_kcopyd_client *kc) { struct kcopyd_job *job = NULL; unsigned long flags; - spin_lock_irqsave(&_job_lock, flags); + spin_lock_irqsave(&kc->job_lock, flags); if (!list_empty(jobs)) { job = list_entry(jobs->next, struct kcopyd_job, list); list_del(&job->list); } - spin_unlock_irqrestore(&_job_lock, flags); + spin_unlock_irqrestore(&kc->job_lock, flags); return job; } @@ -274,10 +270,11 @@ static struct kcopyd_job *pop(struct list_head *jobs) static void push(struct list_head *jobs, struct kcopyd_job *job) { unsigned long flags; + struct dm_kcopyd_client *kc = job->kc; - spin_lock_irqsave(&_job_lock, flags); + spin_lock_irqsave(&kc->job_lock, flags); list_add_tail(&job->list, jobs); - spin_unlock_irqrestore(&_job_lock, flags); + spin_unlock_irqrestore(&kc->job_lock, flags); } /* @@ -310,6 +307,7 @@ static int run_complete_job(struct kcopyd_job *job) static void complete_io(unsigned long error, void *context) { struct kcopyd_job *job = (struct kcopyd_job *) context; + struct dm_kcopyd_client *kc = job->kc; if (error) { if (job->rw == WRITE) @@ -318,21 +316,21 @@ static void complete_io(unsigned long error, void *context) job->read_err = 1; if (!test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { - push(&_complete_jobs, job); - wake(); + push(&kc->complete_jobs, job); + wake(kc); return; } } if (job->rw == WRITE) - push(&_complete_jobs, job); + push(&kc->complete_jobs, job); else { job->rw = WRITE; - push(&_io_jobs, job); + push(&kc->io_jobs, job); } - wake(); + wake(kc); } /* @@ -369,7 +367,7 @@ static int run_pages_job(struct kcopyd_job *job) r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages); if (!r) { /* this job is ready for io */ - push(&_io_jobs, job); + push(&job->kc->io_jobs, job); return 0; } @@ -384,12 +382,13 @@ static int run_pages_job(struct kcopyd_job *job) * Run through a list for as long as possible. Returns the count * of successful jobs. */ -static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) +static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc, + int (*fn) (struct kcopyd_job *)) { struct kcopyd_job *job; int r, count = 0; - while ((job = pop(jobs))) { + while ((job = pop(jobs, kc))) { r = fn(job); @@ -399,7 +398,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) job->write_err = (unsigned long) -1L; else job->read_err = 1; - push(&_complete_jobs, job); + push(&kc->complete_jobs, job); break; } @@ -421,8 +420,11 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) /* * kcopyd does this every time it's woken up. */ -static void do_work(struct work_struct *ignored) +static void do_work(struct work_struct *work) { + struct dm_kcopyd_client *kc = container_of(work, + struct dm_kcopyd_client, kcopyd_work); + /* * The order that these are called is *very* important. * complete jobs can free some pages for pages jobs. @@ -430,9 +432,9 @@ static void do_work(struct work_struct *ignored) * list. io jobs call wake when they complete and it all * starts again. */ - process_jobs(&_complete_jobs, run_complete_job); - process_jobs(&_pages_jobs, run_pages_job); - process_jobs(&_io_jobs, run_io_job); + process_jobs(&kc->complete_jobs, kc, run_complete_job); + process_jobs(&kc->pages_jobs, kc, run_pages_job); + process_jobs(&kc->io_jobs, kc, run_io_job); } /* @@ -442,9 +444,10 @@ static void do_work(struct work_struct *ignored) */ static void dispatch_job(struct kcopyd_job *job) { - atomic_inc(&job->kc->nr_jobs); - push(&_pages_jobs, job); - wake(); + struct dm_kcopyd_client *kc = job->kc; + atomic_inc(&kc->nr_jobs); + push(&kc->pages_jobs, job); + wake(kc); } #define SUB_JOB_SIZE 128 @@ -625,15 +628,7 @@ static int kcopyd_init(void) return r; } - _kcopyd_wq = create_singlethread_workqueue("kcopyd"); - if (!_kcopyd_wq) { - jobs_exit(); - mutex_unlock(&kcopyd_init_lock); - return -ENOMEM; - } - kcopyd_clients++; - INIT_WORK(&_kcopyd_work, do_work); mutex_unlock(&kcopyd_init_lock); return 0; } @@ -644,8 +639,6 @@ static void kcopyd_exit(void) kcopyd_clients--; if (!kcopyd_clients) { jobs_exit(); - destroy_workqueue(_kcopyd_wq); - _kcopyd_wq = NULL; } mutex_unlock(&kcopyd_init_lock); } @@ -662,15 +655,31 @@ int dm_kcopyd_client_create(unsigned int nr_pages, kc = kmalloc(sizeof(*kc), GFP_KERNEL); if (!kc) { + r = -ENOMEM; kcopyd_exit(); - return -ENOMEM; + return r; } spin_lock_init(&kc->lock); + spin_lock_init(&kc->job_lock); + INIT_LIST_HEAD(&kc->complete_jobs); + INIT_LIST_HEAD(&kc->io_jobs); + INIT_LIST_HEAD(&kc->pages_jobs); + + INIT_WORK(&kc->kcopyd_work, do_work); + kc->kcopyd_wq = create_singlethread_workqueue("kcopyd"); + if (!kc->kcopyd_wq) { + r = -ENOMEM; + kfree(kc); + kcopyd_exit(); + return r; + } + kc->pages = NULL; kc->nr_pages = kc->nr_free_pages = 0; r = client_alloc_pages(kc, nr_pages); if (r) { + destroy_workqueue(kc->kcopyd_wq); kfree(kc); kcopyd_exit(); return r; @@ -680,6 +689,7 @@ int dm_kcopyd_client_create(unsigned int nr_pages, if (IS_ERR(kc->io_client)) { r = PTR_ERR(kc->io_client); client_free_pages(kc); + destroy_workqueue(kc->kcopyd_wq); kfree(kc); kcopyd_exit(); return r; @@ -699,6 +709,10 @@ void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) /* Wait for completion of all jobs submitted by this client. */ wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); + BUG_ON(!list_empty(&kc->complete_jobs)); + BUG_ON(!list_empty(&kc->io_jobs)); + BUG_ON(!list_empty(&kc->pages_jobs)); + destroy_workqueue(kc->kcopyd_wq); dm_io_client_destroy(kc->io_client); client_free_pages(kc); client_del(kc); -- cgit v1.2.2 From 08d8757a4d52d21d825b9170af36f2696d1da1a8 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 21:43:46 +0100 Subject: dm kcopyd: private mempool Change the global mempool in kcopyd into a per-device mempool to avoid deadlock possibilities. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/kcopyd.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index 3fb6c8334a82..0b2907d59a3f 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -43,6 +43,8 @@ struct dm_kcopyd_client { wait_queue_head_t destroyq; atomic_t nr_jobs; + mempool_t *job_pool; + struct workqueue_struct *kcopyd_wq; struct work_struct kcopyd_work; @@ -221,7 +223,6 @@ struct kcopyd_job { #define MIN_JOBS 512 static struct kmem_cache *_job_cache; -static mempool_t *_job_pool; static int jobs_init(void) { @@ -229,20 +230,12 @@ static int jobs_init(void) if (!_job_cache) return -ENOMEM; - _job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); - if (!_job_pool) { - kmem_cache_destroy(_job_cache); - return -ENOMEM; - } - return 0; } static void jobs_exit(void) { - mempool_destroy(_job_pool); kmem_cache_destroy(_job_cache); - _job_pool = NULL; _job_cache = NULL; } @@ -295,7 +288,7 @@ static int run_complete_job(struct kcopyd_job *job) struct dm_kcopyd_client *kc = job->kc; kcopyd_put_pages(kc, job->pages); - mempool_free(job, _job_pool); + mempool_free(job, kc->job_pool); fn(read_err, write_err, context); if (atomic_dec_and_test(&kc->nr_jobs)) @@ -487,7 +480,8 @@ static void segment_complete(int read_err, unsigned long write_err, if (count) { int i; - struct kcopyd_job *sub_job = mempool_alloc(_job_pool, GFP_NOIO); + struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool, + GFP_NOIO); *sub_job = *job; sub_job->source.sector += progress; @@ -511,7 +505,7 @@ static void segment_complete(int read_err, unsigned long write_err, * after we've completed. */ job->fn(read_err, write_err, job->context); - mempool_free(job, _job_pool); + mempool_free(job, job->kc->job_pool); } } @@ -538,7 +532,7 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, /* * Allocate a new job. */ - job = mempool_alloc(_job_pool, GFP_NOIO); + job = mempool_alloc(kc->job_pool, GFP_NOIO); /* * set up for the read. @@ -666,10 +660,19 @@ int dm_kcopyd_client_create(unsigned int nr_pages, INIT_LIST_HEAD(&kc->io_jobs); INIT_LIST_HEAD(&kc->pages_jobs); + kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); + if (!kc->job_pool) { + r = -ENOMEM; + kfree(kc); + kcopyd_exit(); + return r; + } + INIT_WORK(&kc->kcopyd_work, do_work); kc->kcopyd_wq = create_singlethread_workqueue("kcopyd"); if (!kc->kcopyd_wq) { r = -ENOMEM; + mempool_destroy(kc->job_pool); kfree(kc); kcopyd_exit(); return r; @@ -680,6 +683,7 @@ int dm_kcopyd_client_create(unsigned int nr_pages, r = client_alloc_pages(kc, nr_pages); if (r) { destroy_workqueue(kc->kcopyd_wq); + mempool_destroy(kc->job_pool); kfree(kc); kcopyd_exit(); return r; @@ -690,6 +694,7 @@ int dm_kcopyd_client_create(unsigned int nr_pages, r = PTR_ERR(kc->io_client); client_free_pages(kc); destroy_workqueue(kc->kcopyd_wq); + mempool_destroy(kc->job_pool); kfree(kc); kcopyd_exit(); return r; @@ -716,6 +721,7 @@ void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) dm_io_client_destroy(kc->io_client); client_free_pages(kc); client_del(kc); + mempool_destroy(kc->job_pool); kfree(kc); kcopyd_exit(); } -- cgit v1.2.2 From 945fa4d283a3a472186c11028f6fea1e77a91d14 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 21:43:49 +0100 Subject: dm kcopyd: remove redundant client counting Remove client counting code that is no longer needed. Initialization and destruction is made globally from dm_init and dm_exit and is not based on client counts. Initialization allocates only one empty slab cache, so there is no negative impact from performing the initialization always, regardless of whether some client uses kcopyd or not. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 2 + drivers/md/dm.h | 3 ++ drivers/md/kcopyd.c | 122 +++++++++++----------------------------------------- 3 files changed, 29 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6617ce4af095..11f4ffedd646 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -204,6 +204,7 @@ static int (*_inits[])(void) __initdata = { dm_target_init, dm_linear_init, dm_stripe_init, + dm_kcopyd_init, dm_interface_init, }; @@ -212,6 +213,7 @@ static void (*_exits[])(void) = { dm_target_exit, dm_linear_exit, dm_stripe_exit, + dm_kcopyd_exit, dm_interface_exit, }; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 17f2d6a8b124..9a6023c9bc6b 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -195,4 +195,7 @@ void dm_kobject_uevent(struct mapped_device *md); int dm_dirty_log_init(void); void dm_dirty_log_exit(void); +int dm_kcopyd_init(void); +void dm_kcopyd_exit(void); + #endif diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index 0b2907d59a3f..17345844b03e 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c @@ -31,8 +31,6 @@ * pages for kcopyd io. *---------------------------------------------------------------*/ struct dm_kcopyd_client { - struct list_head list; - spinlock_t lock; struct page_list *pages; unsigned int nr_pages; @@ -224,7 +222,7 @@ struct kcopyd_job { static struct kmem_cache *_job_cache; -static int jobs_init(void) +int __init dm_kcopyd_init(void) { _job_cache = KMEM_CACHE(kcopyd_job, 0); if (!_job_cache) @@ -233,7 +231,7 @@ static int jobs_init(void) return 0; } -static void jobs_exit(void) +void dm_kcopyd_exit(void) { kmem_cache_destroy(_job_cache); _job_cache = NULL; @@ -581,78 +579,17 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) #endif /* 0 */ /*----------------------------------------------------------------- - * Unit setup + * Client setup *---------------------------------------------------------------*/ -static DEFINE_MUTEX(_client_lock); -static LIST_HEAD(_clients); - -static void client_add(struct dm_kcopyd_client *kc) -{ - mutex_lock(&_client_lock); - list_add(&kc->list, &_clients); - mutex_unlock(&_client_lock); -} - -static void client_del(struct dm_kcopyd_client *kc) -{ - mutex_lock(&_client_lock); - list_del(&kc->list); - mutex_unlock(&_client_lock); -} - -static DEFINE_MUTEX(kcopyd_init_lock); -static int kcopyd_clients = 0; - -static int kcopyd_init(void) -{ - int r; - - mutex_lock(&kcopyd_init_lock); - - if (kcopyd_clients) { - /* Already initialized. */ - kcopyd_clients++; - mutex_unlock(&kcopyd_init_lock); - return 0; - } - - r = jobs_init(); - if (r) { - mutex_unlock(&kcopyd_init_lock); - return r; - } - - kcopyd_clients++; - mutex_unlock(&kcopyd_init_lock); - return 0; -} - -static void kcopyd_exit(void) -{ - mutex_lock(&kcopyd_init_lock); - kcopyd_clients--; - if (!kcopyd_clients) { - jobs_exit(); - } - mutex_unlock(&kcopyd_init_lock); -} - int dm_kcopyd_client_create(unsigned int nr_pages, struct dm_kcopyd_client **result) { - int r = 0; + int r = -ENOMEM; struct dm_kcopyd_client *kc; - r = kcopyd_init(); - if (r) - return r; - kc = kmalloc(sizeof(*kc), GFP_KERNEL); - if (!kc) { - r = -ENOMEM; - kcopyd_exit(); - return r; - } + if (!kc) + return -ENOMEM; spin_lock_init(&kc->lock); spin_lock_init(&kc->job_lock); @@ -661,51 +598,42 @@ int dm_kcopyd_client_create(unsigned int nr_pages, INIT_LIST_HEAD(&kc->pages_jobs); kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); - if (!kc->job_pool) { - r = -ENOMEM; - kfree(kc); - kcopyd_exit(); - return r; - } + if (!kc->job_pool) + goto bad_slab; INIT_WORK(&kc->kcopyd_work, do_work); kc->kcopyd_wq = create_singlethread_workqueue("kcopyd"); - if (!kc->kcopyd_wq) { - r = -ENOMEM; - mempool_destroy(kc->job_pool); - kfree(kc); - kcopyd_exit(); - return r; - } + if (!kc->kcopyd_wq) + goto bad_workqueue; kc->pages = NULL; kc->nr_pages = kc->nr_free_pages = 0; r = client_alloc_pages(kc, nr_pages); - if (r) { - destroy_workqueue(kc->kcopyd_wq); - mempool_destroy(kc->job_pool); - kfree(kc); - kcopyd_exit(); - return r; - } + if (r) + goto bad_client_pages; kc->io_client = dm_io_client_create(nr_pages); if (IS_ERR(kc->io_client)) { r = PTR_ERR(kc->io_client); - client_free_pages(kc); - destroy_workqueue(kc->kcopyd_wq); - mempool_destroy(kc->job_pool); - kfree(kc); - kcopyd_exit(); - return r; + goto bad_io_client; } init_waitqueue_head(&kc->destroyq); atomic_set(&kc->nr_jobs, 0); - client_add(kc); *result = kc; return 0; + +bad_io_client: + client_free_pages(kc); +bad_client_pages: + destroy_workqueue(kc->kcopyd_wq); +bad_workqueue: + mempool_destroy(kc->job_pool); +bad_slab: + kfree(kc); + + return r; } EXPORT_SYMBOL(dm_kcopyd_client_create); @@ -720,9 +648,7 @@ void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) destroy_workqueue(kc->kcopyd_wq); dm_io_client_destroy(kc->io_client); client_free_pages(kc); - client_del(kc); mempool_destroy(kc->job_pool); kfree(kc); - kcopyd_exit(); } EXPORT_SYMBOL(dm_kcopyd_client_destroy); -- cgit v1.2.2 From 0da336e5fab75c712ba8c67f3135d5a20528465f Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 24 Apr 2008 21:43:52 +0100 Subject: dm: expose macros Make dm.h macros and inlines available in include/linux/device-mapper.h Signed-off-by: Alasdair G Kergon --- drivers/md/dm.h | 89 --------------------------------------------------------- 1 file changed, 89 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 9a6023c9bc6b..8c03b634e62e 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -16,67 +16,6 @@ #include #include -#define DM_NAME "device-mapper" - -#define DMERR(f, arg...) \ - printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) -#define DMERR_LIMIT(f, arg...) \ - do { \ - if (printk_ratelimit()) \ - printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " \ - f "\n", ## arg); \ - } while (0) - -#define DMWARN(f, arg...) \ - printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) -#define DMWARN_LIMIT(f, arg...) \ - do { \ - if (printk_ratelimit()) \ - printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " \ - f "\n", ## arg); \ - } while (0) - -#define DMINFO(f, arg...) \ - printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) -#define DMINFO_LIMIT(f, arg...) \ - do { \ - if (printk_ratelimit()) \ - printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f \ - "\n", ## arg); \ - } while (0) - -#ifdef CONFIG_DM_DEBUG -# define DMDEBUG(f, arg...) \ - printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg) -# define DMDEBUG_LIMIT(f, arg...) \ - do { \ - if (printk_ratelimit()) \ - printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX ": " f \ - "\n", ## arg); \ - } while (0) -#else -# define DMDEBUG(f, arg...) do {} while (0) -# define DMDEBUG_LIMIT(f, arg...) do {} while (0) -#endif - -#define DMEMIT(x...) sz += ((sz >= maxlen) ? \ - 0 : scnprintf(result + sz, maxlen - sz, x)) - -#define SECTOR_SHIFT 9 - -/* - * Definitions of return values from target end_io function. - */ -#define DM_ENDIO_INCOMPLETE 1 -#define DM_ENDIO_REQUEUE 2 - -/* - * Definitions of return values from target map function. - */ -#define DM_MAPIO_SUBMITTED 0 -#define DM_MAPIO_REMAPPED 1 -#define DM_MAPIO_REQUEUE DM_ENDIO_REQUEUE - /* * Suspend feature flags */ @@ -136,34 +75,6 @@ static inline int array_too_big(unsigned long fixed, unsigned long obj, return (num > (ULONG_MAX - fixed) / obj); } -/* - * Ceiling(n / sz) - */ -#define dm_div_up(n, sz) (((n) + (sz) - 1) / (sz)) - -#define dm_sector_div_up(n, sz) ( \ -{ \ - sector_t _r = ((n) + (sz) - 1); \ - sector_div(_r, (sz)); \ - _r; \ -} \ -) - -/* - * ceiling(n / size) * size - */ -#define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz)) - -static inline sector_t to_sector(unsigned long n) -{ - return (n >> 9); -} - -static inline unsigned long to_bytes(sector_t n) -{ - return (n << 9); -} - int dm_split_args(int *argc, char ***argvp, char *input); /* -- cgit v1.2.2 From 2d1e580afe23287871529ce54429e249809525a1 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 24 Apr 2008 21:55:00 +0100 Subject: dm kcopyd: rename Rename kcopyd.[ch] to dm-kcopyd.[ch]. Signed-off-by: Alasdair G Kergon --- drivers/md/dm-kcopyd.c | 654 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/md/dm-kcopyd.h | 47 ++++ drivers/md/kcopyd.c | 654 ------------------------------------------------- drivers/md/kcopyd.h | 47 ---- 4 files changed, 701 insertions(+), 701 deletions(-) create mode 100644 drivers/md/dm-kcopyd.c create mode 100644 drivers/md/dm-kcopyd.h delete mode 100644 drivers/md/kcopyd.c delete mode 100644 drivers/md/kcopyd.h (limited to 'drivers') diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c new file mode 100644 index 000000000000..17345844b03e --- /dev/null +++ b/drivers/md/dm-kcopyd.c @@ -0,0 +1,654 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * Copyright (C) 2006 Red Hat GmbH + * + * This file is released under the GPL. + * + * Kcopyd provides a simple interface for copying an area of one + * block-device to one or more other block-devices, with an asynchronous + * completion notification. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcopyd.h" +#include "dm.h" + +/*----------------------------------------------------------------- + * Each kcopyd client has its own little pool of preallocated + * pages for kcopyd io. + *---------------------------------------------------------------*/ +struct dm_kcopyd_client { + spinlock_t lock; + struct page_list *pages; + unsigned int nr_pages; + unsigned int nr_free_pages; + + struct dm_io_client *io_client; + + wait_queue_head_t destroyq; + atomic_t nr_jobs; + + mempool_t *job_pool; + + struct workqueue_struct *kcopyd_wq; + struct work_struct kcopyd_work; + +/* + * We maintain three lists of jobs: + * + * i) jobs waiting for pages + * ii) jobs that have pages, and are waiting for the io to be issued. + * iii) jobs that have completed. + * + * All three of these are protected by job_lock. + */ + spinlock_t job_lock; + struct list_head complete_jobs; + struct list_head io_jobs; + struct list_head pages_jobs; +}; + +static void wake(struct dm_kcopyd_client *kc) +{ + queue_work(kc->kcopyd_wq, &kc->kcopyd_work); +} + +static struct page_list *alloc_pl(void) +{ + struct page_list *pl; + + pl = kmalloc(sizeof(*pl), GFP_KERNEL); + if (!pl) + return NULL; + + pl->page = alloc_page(GFP_KERNEL); + if (!pl->page) { + kfree(pl); + return NULL; + } + + return pl; +} + +static void free_pl(struct page_list *pl) +{ + __free_page(pl->page); + kfree(pl); +} + +static int kcopyd_get_pages(struct dm_kcopyd_client *kc, + unsigned int nr, struct page_list **pages) +{ + struct page_list *pl; + + spin_lock(&kc->lock); + if (kc->nr_free_pages < nr) { + spin_unlock(&kc->lock); + return -ENOMEM; + } + + kc->nr_free_pages -= nr; + for (*pages = pl = kc->pages; --nr; pl = pl->next) + ; + + kc->pages = pl->next; + pl->next = NULL; + + spin_unlock(&kc->lock); + + return 0; +} + +static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) +{ + struct page_list *cursor; + + spin_lock(&kc->lock); + for (cursor = pl; cursor->next; cursor = cursor->next) + kc->nr_free_pages++; + + kc->nr_free_pages++; + cursor->next = kc->pages; + kc->pages = pl; + spin_unlock(&kc->lock); +} + +/* + * These three functions resize the page pool. + */ +static void drop_pages(struct page_list *pl) +{ + struct page_list *next; + + while (pl) { + next = pl->next; + free_pl(pl); + pl = next; + } +} + +static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) +{ + unsigned int i; + struct page_list *pl = NULL, *next; + + for (i = 0; i < nr; i++) { + next = alloc_pl(); + if (!next) { + if (pl) + drop_pages(pl); + return -ENOMEM; + } + next->next = pl; + pl = next; + } + + kcopyd_put_pages(kc, pl); + kc->nr_pages += nr; + return 0; +} + +static void client_free_pages(struct dm_kcopyd_client *kc) +{ + BUG_ON(kc->nr_free_pages != kc->nr_pages); + drop_pages(kc->pages); + kc->pages = NULL; + kc->nr_free_pages = kc->nr_pages = 0; +} + +/*----------------------------------------------------------------- + * kcopyd_jobs need to be allocated by the *clients* of kcopyd, + * for this reason we use a mempool to prevent the client from + * ever having to do io (which could cause a deadlock). + *---------------------------------------------------------------*/ +struct kcopyd_job { + struct dm_kcopyd_client *kc; + struct list_head list; + unsigned long flags; + + /* + * Error state of the job. + */ + int read_err; + unsigned long write_err; + + /* + * Either READ or WRITE + */ + int rw; + struct dm_io_region source; + + /* + * The destinations for the transfer. + */ + unsigned int num_dests; + struct dm_io_region dests[DM_KCOPYD_MAX_REGIONS]; + + sector_t offset; + unsigned int nr_pages; + struct page_list *pages; + + /* + * Set this to ensure you are notified when the job has + * completed. 'context' is for callback to use. + */ + dm_kcopyd_notify_fn fn; + void *context; + + /* + * These fields are only used if the job has been split + * into more manageable parts. + */ + struct mutex lock; + atomic_t sub_jobs; + sector_t progress; +}; + +/* FIXME: this should scale with the number of pages */ +#define MIN_JOBS 512 + +static struct kmem_cache *_job_cache; + +int __init dm_kcopyd_init(void) +{ + _job_cache = KMEM_CACHE(kcopyd_job, 0); + if (!_job_cache) + return -ENOMEM; + + return 0; +} + +void dm_kcopyd_exit(void) +{ + kmem_cache_destroy(_job_cache); + _job_cache = NULL; +} + +/* + * Functions to push and pop a job onto the head of a given job + * list. + */ +static struct kcopyd_job *pop(struct list_head *jobs, + struct dm_kcopyd_client *kc) +{ + struct kcopyd_job *job = NULL; + unsigned long flags; + + spin_lock_irqsave(&kc->job_lock, flags); + + if (!list_empty(jobs)) { + job = list_entry(jobs->next, struct kcopyd_job, list); + list_del(&job->list); + } + spin_unlock_irqrestore(&kc->job_lock, flags); + + return job; +} + +static void push(struct list_head *jobs, struct kcopyd_job *job) +{ + unsigned long flags; + struct dm_kcopyd_client *kc = job->kc; + + spin_lock_irqsave(&kc->job_lock, flags); + list_add_tail(&job->list, jobs); + spin_unlock_irqrestore(&kc->job_lock, flags); +} + +/* + * These three functions process 1 item from the corresponding + * job list. + * + * They return: + * < 0: error + * 0: success + * > 0: can't process yet. + */ +static int run_complete_job(struct kcopyd_job *job) +{ + void *context = job->context; + int read_err = job->read_err; + unsigned long write_err = job->write_err; + dm_kcopyd_notify_fn fn = job->fn; + struct dm_kcopyd_client *kc = job->kc; + + kcopyd_put_pages(kc, job->pages); + mempool_free(job, kc->job_pool); + fn(read_err, write_err, context); + + if (atomic_dec_and_test(&kc->nr_jobs)) + wake_up(&kc->destroyq); + + return 0; +} + +static void complete_io(unsigned long error, void *context) +{ + struct kcopyd_job *job = (struct kcopyd_job *) context; + struct dm_kcopyd_client *kc = job->kc; + + if (error) { + if (job->rw == WRITE) + job->write_err |= error; + else + job->read_err = 1; + + if (!test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { + push(&kc->complete_jobs, job); + wake(kc); + return; + } + } + + if (job->rw == WRITE) + push(&kc->complete_jobs, job); + + else { + job->rw = WRITE; + push(&kc->io_jobs, job); + } + + wake(kc); +} + +/* + * Request io on as many buffer heads as we can currently get for + * a particular job. + */ +static int run_io_job(struct kcopyd_job *job) +{ + int r; + struct dm_io_request io_req = { + .bi_rw = job->rw, + .mem.type = DM_IO_PAGE_LIST, + .mem.ptr.pl = job->pages, + .mem.offset = job->offset, + .notify.fn = complete_io, + .notify.context = job, + .client = job->kc->io_client, + }; + + if (job->rw == READ) + r = dm_io(&io_req, 1, &job->source, NULL); + else + r = dm_io(&io_req, job->num_dests, job->dests, NULL); + + return r; +} + +static int run_pages_job(struct kcopyd_job *job) +{ + int r; + + job->nr_pages = dm_div_up(job->dests[0].count + job->offset, + PAGE_SIZE >> 9); + r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages); + if (!r) { + /* this job is ready for io */ + push(&job->kc->io_jobs, job); + return 0; + } + + if (r == -ENOMEM) + /* can't complete now */ + return 1; + + return r; +} + +/* + * Run through a list for as long as possible. Returns the count + * of successful jobs. + */ +static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc, + int (*fn) (struct kcopyd_job *)) +{ + struct kcopyd_job *job; + int r, count = 0; + + while ((job = pop(jobs, kc))) { + + r = fn(job); + + if (r < 0) { + /* error this rogue job */ + if (job->rw == WRITE) + job->write_err = (unsigned long) -1L; + else + job->read_err = 1; + push(&kc->complete_jobs, job); + break; + } + + if (r > 0) { + /* + * We couldn't service this job ATM, so + * push this job back onto the list. + */ + push(jobs, job); + break; + } + + count++; + } + + return count; +} + +/* + * kcopyd does this every time it's woken up. + */ +static void do_work(struct work_struct *work) +{ + struct dm_kcopyd_client *kc = container_of(work, + struct dm_kcopyd_client, kcopyd_work); + + /* + * The order that these are called is *very* important. + * complete jobs can free some pages for pages jobs. + * Pages jobs when successful will jump onto the io jobs + * list. io jobs call wake when they complete and it all + * starts again. + */ + process_jobs(&kc->complete_jobs, kc, run_complete_job); + process_jobs(&kc->pages_jobs, kc, run_pages_job); + process_jobs(&kc->io_jobs, kc, run_io_job); +} + +/* + * If we are copying a small region we just dispatch a single job + * to do the copy, otherwise the io has to be split up into many + * jobs. + */ +static void dispatch_job(struct kcopyd_job *job) +{ + struct dm_kcopyd_client *kc = job->kc; + atomic_inc(&kc->nr_jobs); + push(&kc->pages_jobs, job); + wake(kc); +} + +#define SUB_JOB_SIZE 128 +static void segment_complete(int read_err, unsigned long write_err, + void *context) +{ + /* FIXME: tidy this function */ + sector_t progress = 0; + sector_t count = 0; + struct kcopyd_job *job = (struct kcopyd_job *) context; + + mutex_lock(&job->lock); + + /* update the error */ + if (read_err) + job->read_err = 1; + + if (write_err) + job->write_err |= write_err; + + /* + * Only dispatch more work if there hasn't been an error. + */ + if ((!job->read_err && !job->write_err) || + test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { + /* get the next chunk of work */ + progress = job->progress; + count = job->source.count - progress; + if (count) { + if (count > SUB_JOB_SIZE) + count = SUB_JOB_SIZE; + + job->progress += count; + } + } + mutex_unlock(&job->lock); + + if (count) { + int i; + struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool, + GFP_NOIO); + + *sub_job = *job; + sub_job->source.sector += progress; + sub_job->source.count = count; + + for (i = 0; i < job->num_dests; i++) { + sub_job->dests[i].sector += progress; + sub_job->dests[i].count = count; + } + + sub_job->fn = segment_complete; + sub_job->context = job; + dispatch_job(sub_job); + + } else if (atomic_dec_and_test(&job->sub_jobs)) { + + /* + * To avoid a race we must keep the job around + * until after the notify function has completed. + * Otherwise the client may try and stop the job + * after we've completed. + */ + job->fn(read_err, write_err, job->context); + mempool_free(job, job->kc->job_pool); + } +} + +/* + * Create some little jobs that will do the move between + * them. + */ +#define SPLIT_COUNT 8 +static void split_job(struct kcopyd_job *job) +{ + int i; + + atomic_set(&job->sub_jobs, SPLIT_COUNT); + for (i = 0; i < SPLIT_COUNT; i++) + segment_complete(0, 0u, job); +} + +int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, + unsigned int num_dests, struct dm_io_region *dests, + unsigned int flags, dm_kcopyd_notify_fn fn, void *context) +{ + struct kcopyd_job *job; + + /* + * Allocate a new job. + */ + job = mempool_alloc(kc->job_pool, GFP_NOIO); + + /* + * set up for the read. + */ + job->kc = kc; + job->flags = flags; + job->read_err = 0; + job->write_err = 0; + job->rw = READ; + + job->source = *from; + + job->num_dests = num_dests; + memcpy(&job->dests, dests, sizeof(*dests) * num_dests); + + job->offset = 0; + job->nr_pages = 0; + job->pages = NULL; + + job->fn = fn; + job->context = context; + + if (job->source.count < SUB_JOB_SIZE) + dispatch_job(job); + + else { + mutex_init(&job->lock); + job->progress = 0; + split_job(job); + } + + return 0; +} +EXPORT_SYMBOL(dm_kcopyd_copy); + +/* + * Cancels a kcopyd job, eg. someone might be deactivating a + * mirror. + */ +#if 0 +int kcopyd_cancel(struct kcopyd_job *job, int block) +{ + /* FIXME: finish */ + return -1; +} +#endif /* 0 */ + +/*----------------------------------------------------------------- + * Client setup + *---------------------------------------------------------------*/ +int dm_kcopyd_client_create(unsigned int nr_pages, + struct dm_kcopyd_client **result) +{ + int r = -ENOMEM; + struct dm_kcopyd_client *kc; + + kc = kmalloc(sizeof(*kc), GFP_KERNEL); + if (!kc) + return -ENOMEM; + + spin_lock_init(&kc->lock); + spin_lock_init(&kc->job_lock); + INIT_LIST_HEAD(&kc->complete_jobs); + INIT_LIST_HEAD(&kc->io_jobs); + INIT_LIST_HEAD(&kc->pages_jobs); + + kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); + if (!kc->job_pool) + goto bad_slab; + + INIT_WORK(&kc->kcopyd_work, do_work); + kc->kcopyd_wq = create_singlethread_workqueue("kcopyd"); + if (!kc->kcopyd_wq) + goto bad_workqueue; + + kc->pages = NULL; + kc->nr_pages = kc->nr_free_pages = 0; + r = client_alloc_pages(kc, nr_pages); + if (r) + goto bad_client_pages; + + kc->io_client = dm_io_client_create(nr_pages); + if (IS_ERR(kc->io_client)) { + r = PTR_ERR(kc->io_client); + goto bad_io_client; + } + + init_waitqueue_head(&kc->destroyq); + atomic_set(&kc->nr_jobs, 0); + + *result = kc; + return 0; + +bad_io_client: + client_free_pages(kc); +bad_client_pages: + destroy_workqueue(kc->kcopyd_wq); +bad_workqueue: + mempool_destroy(kc->job_pool); +bad_slab: + kfree(kc); + + return r; +} +EXPORT_SYMBOL(dm_kcopyd_client_create); + +void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) +{ + /* Wait for completion of all jobs submitted by this client. */ + wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); + + BUG_ON(!list_empty(&kc->complete_jobs)); + BUG_ON(!list_empty(&kc->io_jobs)); + BUG_ON(!list_empty(&kc->pages_jobs)); + destroy_workqueue(kc->kcopyd_wq); + dm_io_client_destroy(kc->io_client); + client_free_pages(kc); + mempool_destroy(kc->job_pool); + kfree(kc); +} +EXPORT_SYMBOL(dm_kcopyd_client_destroy); diff --git a/drivers/md/dm-kcopyd.h b/drivers/md/dm-kcopyd.h new file mode 100644 index 000000000000..d3057846b0b0 --- /dev/null +++ b/drivers/md/dm-kcopyd.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2001 - 2003 Sistina Software + * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. + * + * kcopyd provides a simple interface for copying an area of one + * block-device to one or more other block-devices, either synchronous + * or with an asynchronous completion notification. + * + * This file is released under the GPL. + */ + +#ifndef _LINUX_DM_KCOPYD_H +#define _LINUX_DM_KCOPYD_H + +#ifdef __KERNEL__ + +#include "dm-io.h" + +/* FIXME: make this configurable */ +#define DM_KCOPYD_MAX_REGIONS 8 + +#define DM_KCOPYD_IGNORE_ERROR 1 + +/* + * To use kcopyd you must first create a dm_kcopyd_client object. + */ +struct dm_kcopyd_client; +int dm_kcopyd_client_create(unsigned num_pages, + struct dm_kcopyd_client **result); +void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); + +/* + * Submit a copy job to kcopyd. This is built on top of the + * previous three fns. + * + * read_err is a boolean, + * write_err is a bitset, with 1 bit for each destination region + */ +typedef void (*dm_kcopyd_notify_fn)(int read_err, unsigned long write_err, + void *context); + +int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, + unsigned num_dests, struct dm_io_region *dests, + unsigned flags, dm_kcopyd_notify_fn fn, void *context); + +#endif /* __KERNEL__ */ +#endif /* _LINUX_DM_KCOPYD_H */ diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c deleted file mode 100644 index 17345844b03e..000000000000 --- a/drivers/md/kcopyd.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright (C) 2002 Sistina Software (UK) Limited. - * Copyright (C) 2006 Red Hat GmbH - * - * This file is released under the GPL. - * - * Kcopyd provides a simple interface for copying an area of one - * block-device to one or more other block-devices, with an asynchronous - * completion notification. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kcopyd.h" -#include "dm.h" - -/*----------------------------------------------------------------- - * Each kcopyd client has its own little pool of preallocated - * pages for kcopyd io. - *---------------------------------------------------------------*/ -struct dm_kcopyd_client { - spinlock_t lock; - struct page_list *pages; - unsigned int nr_pages; - unsigned int nr_free_pages; - - struct dm_io_client *io_client; - - wait_queue_head_t destroyq; - atomic_t nr_jobs; - - mempool_t *job_pool; - - struct workqueue_struct *kcopyd_wq; - struct work_struct kcopyd_work; - -/* - * We maintain three lists of jobs: - * - * i) jobs waiting for pages - * ii) jobs that have pages, and are waiting for the io to be issued. - * iii) jobs that have completed. - * - * All three of these are protected by job_lock. - */ - spinlock_t job_lock; - struct list_head complete_jobs; - struct list_head io_jobs; - struct list_head pages_jobs; -}; - -static void wake(struct dm_kcopyd_client *kc) -{ - queue_work(kc->kcopyd_wq, &kc->kcopyd_work); -} - -static struct page_list *alloc_pl(void) -{ - struct page_list *pl; - - pl = kmalloc(sizeof(*pl), GFP_KERNEL); - if (!pl) - return NULL; - - pl->page = alloc_page(GFP_KERNEL); - if (!pl->page) { - kfree(pl); - return NULL; - } - - return pl; -} - -static void free_pl(struct page_list *pl) -{ - __free_page(pl->page); - kfree(pl); -} - -static int kcopyd_get_pages(struct dm_kcopyd_client *kc, - unsigned int nr, struct page_list **pages) -{ - struct page_list *pl; - - spin_lock(&kc->lock); - if (kc->nr_free_pages < nr) { - spin_unlock(&kc->lock); - return -ENOMEM; - } - - kc->nr_free_pages -= nr; - for (*pages = pl = kc->pages; --nr; pl = pl->next) - ; - - kc->pages = pl->next; - pl->next = NULL; - - spin_unlock(&kc->lock); - - return 0; -} - -static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) -{ - struct page_list *cursor; - - spin_lock(&kc->lock); - for (cursor = pl; cursor->next; cursor = cursor->next) - kc->nr_free_pages++; - - kc->nr_free_pages++; - cursor->next = kc->pages; - kc->pages = pl; - spin_unlock(&kc->lock); -} - -/* - * These three functions resize the page pool. - */ -static void drop_pages(struct page_list *pl) -{ - struct page_list *next; - - while (pl) { - next = pl->next; - free_pl(pl); - pl = next; - } -} - -static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) -{ - unsigned int i; - struct page_list *pl = NULL, *next; - - for (i = 0; i < nr; i++) { - next = alloc_pl(); - if (!next) { - if (pl) - drop_pages(pl); - return -ENOMEM; - } - next->next = pl; - pl = next; - } - - kcopyd_put_pages(kc, pl); - kc->nr_pages += nr; - return 0; -} - -static void client_free_pages(struct dm_kcopyd_client *kc) -{ - BUG_ON(kc->nr_free_pages != kc->nr_pages); - drop_pages(kc->pages); - kc->pages = NULL; - kc->nr_free_pages = kc->nr_pages = 0; -} - -/*----------------------------------------------------------------- - * kcopyd_jobs need to be allocated by the *clients* of kcopyd, - * for this reason we use a mempool to prevent the client from - * ever having to do io (which could cause a deadlock). - *---------------------------------------------------------------*/ -struct kcopyd_job { - struct dm_kcopyd_client *kc; - struct list_head list; - unsigned long flags; - - /* - * Error state of the job. - */ - int read_err; - unsigned long write_err; - - /* - * Either READ or WRITE - */ - int rw; - struct dm_io_region source; - - /* - * The destinations for the transfer. - */ - unsigned int num_dests; - struct dm_io_region dests[DM_KCOPYD_MAX_REGIONS]; - - sector_t offset; - unsigned int nr_pages; - struct page_list *pages; - - /* - * Set this to ensure you are notified when the job has - * completed. 'context' is for callback to use. - */ - dm_kcopyd_notify_fn fn; - void *context; - - /* - * These fields are only used if the job has been split - * into more manageable parts. - */ - struct mutex lock; - atomic_t sub_jobs; - sector_t progress; -}; - -/* FIXME: this should scale with the number of pages */ -#define MIN_JOBS 512 - -static struct kmem_cache *_job_cache; - -int __init dm_kcopyd_init(void) -{ - _job_cache = KMEM_CACHE(kcopyd_job, 0); - if (!_job_cache) - return -ENOMEM; - - return 0; -} - -void dm_kcopyd_exit(void) -{ - kmem_cache_destroy(_job_cache); - _job_cache = NULL; -} - -/* - * Functions to push and pop a job onto the head of a given job - * list. - */ -static struct kcopyd_job *pop(struct list_head *jobs, - struct dm_kcopyd_client *kc) -{ - struct kcopyd_job *job = NULL; - unsigned long flags; - - spin_lock_irqsave(&kc->job_lock, flags); - - if (!list_empty(jobs)) { - job = list_entry(jobs->next, struct kcopyd_job, list); - list_del(&job->list); - } - spin_unlock_irqrestore(&kc->job_lock, flags); - - return job; -} - -static void push(struct list_head *jobs, struct kcopyd_job *job) -{ - unsigned long flags; - struct dm_kcopyd_client *kc = job->kc; - - spin_lock_irqsave(&kc->job_lock, flags); - list_add_tail(&job->list, jobs); - spin_unlock_irqrestore(&kc->job_lock, flags); -} - -/* - * These three functions process 1 item from the corresponding - * job list. - * - * They return: - * < 0: error - * 0: success - * > 0: can't process yet. - */ -static int run_complete_job(struct kcopyd_job *job) -{ - void *context = job->context; - int read_err = job->read_err; - unsigned long write_err = job->write_err; - dm_kcopyd_notify_fn fn = job->fn; - struct dm_kcopyd_client *kc = job->kc; - - kcopyd_put_pages(kc, job->pages); - mempool_free(job, kc->job_pool); - fn(read_err, write_err, context); - - if (atomic_dec_and_test(&kc->nr_jobs)) - wake_up(&kc->destroyq); - - return 0; -} - -static void complete_io(unsigned long error, void *context) -{ - struct kcopyd_job *job = (struct kcopyd_job *) context; - struct dm_kcopyd_client *kc = job->kc; - - if (error) { - if (job->rw == WRITE) - job->write_err |= error; - else - job->read_err = 1; - - if (!test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { - push(&kc->complete_jobs, job); - wake(kc); - return; - } - } - - if (job->rw == WRITE) - push(&kc->complete_jobs, job); - - else { - job->rw = WRITE; - push(&kc->io_jobs, job); - } - - wake(kc); -} - -/* - * Request io on as many buffer heads as we can currently get for - * a particular job. - */ -static int run_io_job(struct kcopyd_job *job) -{ - int r; - struct dm_io_request io_req = { - .bi_rw = job->rw, - .mem.type = DM_IO_PAGE_LIST, - .mem.ptr.pl = job->pages, - .mem.offset = job->offset, - .notify.fn = complete_io, - .notify.context = job, - .client = job->kc->io_client, - }; - - if (job->rw == READ) - r = dm_io(&io_req, 1, &job->source, NULL); - else - r = dm_io(&io_req, job->num_dests, job->dests, NULL); - - return r; -} - -static int run_pages_job(struct kcopyd_job *job) -{ - int r; - - job->nr_pages = dm_div_up(job->dests[0].count + job->offset, - PAGE_SIZE >> 9); - r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages); - if (!r) { - /* this job is ready for io */ - push(&job->kc->io_jobs, job); - return 0; - } - - if (r == -ENOMEM) - /* can't complete now */ - return 1; - - return r; -} - -/* - * Run through a list for as long as possible. Returns the count - * of successful jobs. - */ -static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc, - int (*fn) (struct kcopyd_job *)) -{ - struct kcopyd_job *job; - int r, count = 0; - - while ((job = pop(jobs, kc))) { - - r = fn(job); - - if (r < 0) { - /* error this rogue job */ - if (job->rw == WRITE) - job->write_err = (unsigned long) -1L; - else - job->read_err = 1; - push(&kc->complete_jobs, job); - break; - } - - if (r > 0) { - /* - * We couldn't service this job ATM, so - * push this job back onto the list. - */ - push(jobs, job); - break; - } - - count++; - } - - return count; -} - -/* - * kcopyd does this every time it's woken up. - */ -static void do_work(struct work_struct *work) -{ - struct dm_kcopyd_client *kc = container_of(work, - struct dm_kcopyd_client, kcopyd_work); - - /* - * The order that these are called is *very* important. - * complete jobs can free some pages for pages jobs. - * Pages jobs when successful will jump onto the io jobs - * list. io jobs call wake when they complete and it all - * starts again. - */ - process_jobs(&kc->complete_jobs, kc, run_complete_job); - process_jobs(&kc->pages_jobs, kc, run_pages_job); - process_jobs(&kc->io_jobs, kc, run_io_job); -} - -/* - * If we are copying a small region we just dispatch a single job - * to do the copy, otherwise the io has to be split up into many - * jobs. - */ -static void dispatch_job(struct kcopyd_job *job) -{ - struct dm_kcopyd_client *kc = job->kc; - atomic_inc(&kc->nr_jobs); - push(&kc->pages_jobs, job); - wake(kc); -} - -#define SUB_JOB_SIZE 128 -static void segment_complete(int read_err, unsigned long write_err, - void *context) -{ - /* FIXME: tidy this function */ - sector_t progress = 0; - sector_t count = 0; - struct kcopyd_job *job = (struct kcopyd_job *) context; - - mutex_lock(&job->lock); - - /* update the error */ - if (read_err) - job->read_err = 1; - - if (write_err) - job->write_err |= write_err; - - /* - * Only dispatch more work if there hasn't been an error. - */ - if ((!job->read_err && !job->write_err) || - test_bit(DM_KCOPYD_IGNORE_ERROR, &job->flags)) { - /* get the next chunk of work */ - progress = job->progress; - count = job->source.count - progress; - if (count) { - if (count > SUB_JOB_SIZE) - count = SUB_JOB_SIZE; - - job->progress += count; - } - } - mutex_unlock(&job->lock); - - if (count) { - int i; - struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool, - GFP_NOIO); - - *sub_job = *job; - sub_job->source.sector += progress; - sub_job->source.count = count; - - for (i = 0; i < job->num_dests; i++) { - sub_job->dests[i].sector += progress; - sub_job->dests[i].count = count; - } - - sub_job->fn = segment_complete; - sub_job->context = job; - dispatch_job(sub_job); - - } else if (atomic_dec_and_test(&job->sub_jobs)) { - - /* - * To avoid a race we must keep the job around - * until after the notify function has completed. - * Otherwise the client may try and stop the job - * after we've completed. - */ - job->fn(read_err, write_err, job->context); - mempool_free(job, job->kc->job_pool); - } -} - -/* - * Create some little jobs that will do the move between - * them. - */ -#define SPLIT_COUNT 8 -static void split_job(struct kcopyd_job *job) -{ - int i; - - atomic_set(&job->sub_jobs, SPLIT_COUNT); - for (i = 0; i < SPLIT_COUNT; i++) - segment_complete(0, 0u, job); -} - -int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, - unsigned int num_dests, struct dm_io_region *dests, - unsigned int flags, dm_kcopyd_notify_fn fn, void *context) -{ - struct kcopyd_job *job; - - /* - * Allocate a new job. - */ - job = mempool_alloc(kc->job_pool, GFP_NOIO); - - /* - * set up for the read. - */ - job->kc = kc; - job->flags = flags; - job->read_err = 0; - job->write_err = 0; - job->rw = READ; - - job->source = *from; - - job->num_dests = num_dests; - memcpy(&job->dests, dests, sizeof(*dests) * num_dests); - - job->offset = 0; - job->nr_pages = 0; - job->pages = NULL; - - job->fn = fn; - job->context = context; - - if (job->source.count < SUB_JOB_SIZE) - dispatch_job(job); - - else { - mutex_init(&job->lock); - job->progress = 0; - split_job(job); - } - - return 0; -} -EXPORT_SYMBOL(dm_kcopyd_copy); - -/* - * Cancels a kcopyd job, eg. someone might be deactivating a - * mirror. - */ -#if 0 -int kcopyd_cancel(struct kcopyd_job *job, int block) -{ - /* FIXME: finish */ - return -1; -} -#endif /* 0 */ - -/*----------------------------------------------------------------- - * Client setup - *---------------------------------------------------------------*/ -int dm_kcopyd_client_create(unsigned int nr_pages, - struct dm_kcopyd_client **result) -{ - int r = -ENOMEM; - struct dm_kcopyd_client *kc; - - kc = kmalloc(sizeof(*kc), GFP_KERNEL); - if (!kc) - return -ENOMEM; - - spin_lock_init(&kc->lock); - spin_lock_init(&kc->job_lock); - INIT_LIST_HEAD(&kc->complete_jobs); - INIT_LIST_HEAD(&kc->io_jobs); - INIT_LIST_HEAD(&kc->pages_jobs); - - kc->job_pool = mempool_create_slab_pool(MIN_JOBS, _job_cache); - if (!kc->job_pool) - goto bad_slab; - - INIT_WORK(&kc->kcopyd_work, do_work); - kc->kcopyd_wq = create_singlethread_workqueue("kcopyd"); - if (!kc->kcopyd_wq) - goto bad_workqueue; - - kc->pages = NULL; - kc->nr_pages = kc->nr_free_pages = 0; - r = client_alloc_pages(kc, nr_pages); - if (r) - goto bad_client_pages; - - kc->io_client = dm_io_client_create(nr_pages); - if (IS_ERR(kc->io_client)) { - r = PTR_ERR(kc->io_client); - goto bad_io_client; - } - - init_waitqueue_head(&kc->destroyq); - atomic_set(&kc->nr_jobs, 0); - - *result = kc; - return 0; - -bad_io_client: - client_free_pages(kc); -bad_client_pages: - destroy_workqueue(kc->kcopyd_wq); -bad_workqueue: - mempool_destroy(kc->job_pool); -bad_slab: - kfree(kc); - - return r; -} -EXPORT_SYMBOL(dm_kcopyd_client_create); - -void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc) -{ - /* Wait for completion of all jobs submitted by this client. */ - wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); - - BUG_ON(!list_empty(&kc->complete_jobs)); - BUG_ON(!list_empty(&kc->io_jobs)); - BUG_ON(!list_empty(&kc->pages_jobs)); - destroy_workqueue(kc->kcopyd_wq); - dm_io_client_destroy(kc->io_client); - client_free_pages(kc); - mempool_destroy(kc->job_pool); - kfree(kc); -} -EXPORT_SYMBOL(dm_kcopyd_client_destroy); diff --git a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h deleted file mode 100644 index d3057846b0b0..000000000000 --- a/drivers/md/kcopyd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Sistina Software - * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. - * - * kcopyd provides a simple interface for copying an area of one - * block-device to one or more other block-devices, either synchronous - * or with an asynchronous completion notification. - * - * This file is released under the GPL. - */ - -#ifndef _LINUX_DM_KCOPYD_H -#define _LINUX_DM_KCOPYD_H - -#ifdef __KERNEL__ - -#include "dm-io.h" - -/* FIXME: make this configurable */ -#define DM_KCOPYD_MAX_REGIONS 8 - -#define DM_KCOPYD_IGNORE_ERROR 1 - -/* - * To use kcopyd you must first create a dm_kcopyd_client object. - */ -struct dm_kcopyd_client; -int dm_kcopyd_client_create(unsigned num_pages, - struct dm_kcopyd_client **result); -void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); - -/* - * Submit a copy job to kcopyd. This is built on top of the - * previous three fns. - * - * read_err is a boolean, - * write_err is a bitset, with 1 bit for each destination region - */ -typedef void (*dm_kcopyd_notify_fn)(int read_err, unsigned long write_err, - void *context); - -int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, - unsigned num_dests, struct dm_io_region *dests, - unsigned flags, dm_kcopyd_notify_fn fn, void *context); - -#endif /* __KERNEL__ */ -#endif /* _LINUX_DM_KCOPYD_H */ -- cgit v1.2.2 From a765e20eeb423d0fa6a02ffab51141e53bbd93cb Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 24 Apr 2008 22:02:01 +0100 Subject: dm: move include files Publish the dm-io, dm-log and dm-kcopyd headers in include/linux. Signed-off-by: Alasdair G Kergon --- drivers/md/Makefile | 2 +- drivers/md/dm-exception-store.c | 4 +- drivers/md/dm-io.c | 2 +- drivers/md/dm-io.h | 85 -------------------------- drivers/md/dm-kcopyd.c | 2 +- drivers/md/dm-kcopyd.h | 47 -------------- drivers/md/dm-log.c | 4 +- drivers/md/dm-log.h | 131 ---------------------------------------- drivers/md/dm-raid1.c | 6 +- drivers/md/dm-snap.c | 2 +- 10 files changed, 11 insertions(+), 274 deletions(-) delete mode 100644 drivers/md/dm-io.h delete mode 100644 drivers/md/dm-kcopyd.h delete mode 100644 drivers/md/dm-log.h (limited to 'drivers') diff --git a/drivers/md/Makefile b/drivers/md/Makefile index be4b069bbc58..7be09eeea293 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -3,7 +3,7 @@ # dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ - dm-ioctl.o dm-io.o kcopyd.o + dm-ioctl.o dm-io.o dm-kcopyd.o dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-mirror-objs := dm-raid1.o diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 6933301733df..41f408068a7c 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -9,13 +9,13 @@ #include "dm.h" #include "dm-snap.h" -#include "dm-io.h" -#include "kcopyd.h" #include #include #include #include +#include +#include #define DM_MSG_PREFIX "snapshots" #define DM_CHUNK_SIZE_DEFAULT_SECTORS 32 /* 16KB */ diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 978c0414cf05..ed9c86cd053e 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -5,7 +5,6 @@ * This file is released under the GPL. */ -#include "dm-io.h" #include "dm.h" #include @@ -13,6 +12,7 @@ #include #include #include +#include struct dm_io_client { mempool_t *pool; diff --git a/drivers/md/dm-io.h b/drivers/md/dm-io.h deleted file mode 100644 index b6bf17ee2f61..000000000000 --- a/drivers/md/dm-io.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2003 Sistina Software - * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. - * - * Device-Mapper low-level I/O. - * - * This file is released under the GPL. - */ - -#ifndef _LINUX_DM_IO_H -#define _LINUX_DM_IO_H - -#ifdef __KERNEL__ - -#include - -struct dm_io_region { - struct block_device *bdev; - sector_t sector; - sector_t count; /* If this is zero the region is ignored. */ -}; - -struct page_list { - struct page_list *next; - struct page *page; -}; - -typedef void (*io_notify_fn)(unsigned long error, void *context); - -enum dm_io_mem_type { - DM_IO_PAGE_LIST,/* Page list */ - DM_IO_BVEC, /* Bio vector */ - DM_IO_VMA, /* Virtual memory area */ - DM_IO_KMEM, /* Kernel memory */ -}; - -struct dm_io_memory { - enum dm_io_mem_type type; - - union { - struct page_list *pl; - struct bio_vec *bvec; - void *vma; - void *addr; - } ptr; - - unsigned offset; -}; - -struct dm_io_notify { - io_notify_fn fn; /* Callback for asynchronous requests */ - void *context; /* Passed to callback */ -}; - -/* - * IO request structure - */ -struct dm_io_client; -struct dm_io_request { - int bi_rw; /* READ|WRITE - not READA */ - struct dm_io_memory mem; /* Memory to use for io */ - struct dm_io_notify notify; /* Synchronous if notify.fn is NULL */ - struct dm_io_client *client; /* Client memory handler */ -}; - -/* - * For async io calls, users can alternatively use the dm_io() function below - * and dm_io_client_create() to create private mempools for the client. - * - * Create/destroy may block. - */ -struct dm_io_client *dm_io_client_create(unsigned num_pages); -int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client); -void dm_io_client_destroy(struct dm_io_client *client); - -/* - * IO interface using private per-client pools. - * Each bit in the optional 'sync_error_bits' bitset indicates whether an - * error occurred doing io to the corresponding region. - */ -int dm_io(struct dm_io_request *io_req, unsigned num_regions, - struct dm_io_region *region, unsigned long *sync_error_bits); - -#endif /* __KERNEL__ */ -#endif /* _LINUX_DM_IO_H */ diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 17345844b03e..ee9583bee04d 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -22,8 +22,8 @@ #include #include #include +#include -#include "kcopyd.h" #include "dm.h" /*----------------------------------------------------------------- diff --git a/drivers/md/dm-kcopyd.h b/drivers/md/dm-kcopyd.h deleted file mode 100644 index d3057846b0b0..000000000000 --- a/drivers/md/dm-kcopyd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Sistina Software - * Copyright (C) 2004 - 2008 Red Hat, Inc. All rights reserved. - * - * kcopyd provides a simple interface for copying an area of one - * block-device to one or more other block-devices, either synchronous - * or with an asynchronous completion notification. - * - * This file is released under the GPL. - */ - -#ifndef _LINUX_DM_KCOPYD_H -#define _LINUX_DM_KCOPYD_H - -#ifdef __KERNEL__ - -#include "dm-io.h" - -/* FIXME: make this configurable */ -#define DM_KCOPYD_MAX_REGIONS 8 - -#define DM_KCOPYD_IGNORE_ERROR 1 - -/* - * To use kcopyd you must first create a dm_kcopyd_client object. - */ -struct dm_kcopyd_client; -int dm_kcopyd_client_create(unsigned num_pages, - struct dm_kcopyd_client **result); -void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); - -/* - * Submit a copy job to kcopyd. This is built on top of the - * previous three fns. - * - * read_err is a boolean, - * write_err is a bitset, with 1 bit for each destination region - */ -typedef void (*dm_kcopyd_notify_fn)(int read_err, unsigned long write_err, - void *context); - -int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, - unsigned num_dests, struct dm_io_region *dests, - unsigned flags, dm_kcopyd_notify_fn fn, void *context); - -#endif /* __KERNEL__ */ -#endif /* _LINUX_DM_KCOPYD_H */ diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index e6b6a9d5fdd2..67a6f31b7fc3 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -9,9 +9,9 @@ #include #include #include +#include +#include -#include "dm-log.h" -#include "dm-io.h" #include "dm.h" #define DM_MSG_PREFIX "dirty region log" diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h deleted file mode 100644 index 600c5fb2daad..000000000000 --- a/drivers/md/dm-log.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2003 Sistina Software - * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. - * - * Device-Mapper dirty region log. - * - * This file is released under the LGPL. - */ - -#ifndef _LINUX_DM_DIRTY_LOG -#define _LINUX_DM_DIRTY_LOG - -#ifdef __KERNEL__ - -#include -#include - -typedef sector_t region_t; - -struct dm_dirty_log_type; - -struct dm_dirty_log { - struct dm_dirty_log_type *type; - void *context; -}; - -struct dm_dirty_log_type { - const char *name; - struct module *module; - - int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, - unsigned argc, char **argv); - void (*dtr)(struct dm_dirty_log *log); - - /* - * There are times when we don't want the log to touch - * the disk. - */ - int (*presuspend)(struct dm_dirty_log *log); - int (*postsuspend)(struct dm_dirty_log *log); - int (*resume)(struct dm_dirty_log *log); - - /* - * Retrieves the smallest size of region that the log can - * deal with. - */ - uint32_t (*get_region_size)(struct dm_dirty_log *log); - - /* - * A predicate to say whether a region is clean or not. - * May block. - */ - int (*is_clean)(struct dm_dirty_log *log, region_t region); - - /* - * Returns: 0, 1, -EWOULDBLOCK, < 0 - * - * A predicate function to check the area given by - * [sector, sector + len) is in sync. - * - * If -EWOULDBLOCK is returned the state of the region is - * unknown, typically this will result in a read being - * passed to a daemon to deal with, since a daemon is - * allowed to block. - */ - int (*in_sync)(struct dm_dirty_log *log, region_t region, - int can_block); - - /* - * Flush the current log state (eg, to disk). This - * function may block. - */ - int (*flush)(struct dm_dirty_log *log); - - /* - * Mark an area as clean or dirty. These functions may - * block, though for performance reasons blocking should - * be extremely rare (eg, allocating another chunk of - * memory for some reason). - */ - void (*mark_region)(struct dm_dirty_log *log, region_t region); - void (*clear_region)(struct dm_dirty_log *log, region_t region); - - /* - * Returns: <0 (error), 0 (no region), 1 (region) - * - * The mirrord will need perform recovery on regions of - * the mirror that are in the NOSYNC state. This - * function asks the log to tell the caller about the - * next region that this machine should recover. - * - * Do not confuse this function with 'in_sync()', one - * tells you if an area is synchronised, the other - * assigns recovery work. - */ - int (*get_resync_work)(struct dm_dirty_log *log, region_t *region); - - /* - * This notifies the log that the resync status of a region - * has changed. It also clears the region from the recovering - * list (if present). - */ - void (*set_region_sync)(struct dm_dirty_log *log, - region_t region, int in_sync); - - /* - * Returns the number of regions that are in sync. - */ - region_t (*get_sync_count)(struct dm_dirty_log *log); - - /* - * Support function for mirror status requests. - */ - int (*status)(struct dm_dirty_log *log, status_type_t status_type, - char *result, unsigned maxlen); -}; - -int dm_dirty_log_type_register(struct dm_dirty_log_type *type); -int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type); - -/* - * Make sure you use these two functions, rather than calling - * type->constructor/destructor() directly. - */ -struct dm_dirty_log *dm_dirty_log_create(const char *type_name, - struct dm_target *ti, - unsigned argc, char **argv); -void dm_dirty_log_destroy(struct dm_dirty_log *log); - -#endif /* __KERNEL__ */ -#endif /* _LINUX_DM_DIRTY_LOG_H */ diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 5beeced4e522..6692e5a84bb1 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -7,9 +7,6 @@ #include "dm.h" #include "dm-bio-list.h" #include "dm-bio-record.h" -#include "dm-io.h" -#include "dm-log.h" -#include "kcopyd.h" #include #include @@ -22,6 +19,9 @@ #include #include #include +#include +#include +#include #define DM_MSG_PREFIX "raid1" #define DM_IO_PAGES 64 diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index e1dcca99392e..1ba8a47d61b1 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -18,10 +18,10 @@ #include #include #include +#include #include "dm-snap.h" #include "dm-bio-list.h" -#include "kcopyd.h" #define DM_MSG_PREFIX "snapshots" -- cgit v1.2.2 From a2aebe03be60ae4da03507a00d60211d5e0327c3 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 22:10:42 +0100 Subject: dm raid1: use timer This patch replaces the schedule() in the main kmirrord thread with a timer. The schedule() could introduce an unwanted delay when work is ready to be processed. The code instead calls wake() when there's work to be done immediately, and delayed_wake() after a failure to give a short delay before retrying. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm-raid1.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 6692e5a84bb1..3b9532fc294c 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -154,6 +154,9 @@ struct mirror_set { struct workqueue_struct *kmirrord_wq; struct work_struct kmirrord_work; + struct timer_list timer; + unsigned long timer_pending; + struct work_struct trigger_event; unsigned int nr_mirrors; @@ -178,6 +181,25 @@ static void wake(struct mirror_set *ms) queue_work(ms->kmirrord_wq, &ms->kmirrord_work); } +static void delayed_wake_fn(unsigned long data) +{ + struct mirror_set *ms = (struct mirror_set *) data; + + clear_bit(0, &ms->timer_pending); + wake(ms); +} + +static void delayed_wake(struct mirror_set *ms) +{ + if (test_and_set_bit(0, &ms->timer_pending)) + return; + + ms->timer.expires = jiffies + HZ / 5; + ms->timer.data = (unsigned long) ms; + ms->timer.function = delayed_wake_fn; + add_timer(&ms->timer); +} + /* FIXME move this */ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); @@ -1180,6 +1202,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) spin_lock_irq(&ms->lock); bio_list_merge(&ms->failures, &sync); spin_unlock_irq(&ms->lock); + wake(ms); } else while ((bio = bio_list_pop(&sync))) do_write(ms, bio); @@ -1239,7 +1262,7 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) bio_list_merge(&ms->failures, failures); spin_unlock_irq(&ms->lock); - wake(ms); + delayed_wake(ms); } static void trigger_event(struct work_struct *work) @@ -1253,7 +1276,7 @@ static void trigger_event(struct work_struct *work) /*----------------------------------------------------------------- * kmirrord *---------------------------------------------------------------*/ -static int _do_mirror(struct work_struct *work) +static void do_mirror(struct work_struct *work) { struct mirror_set *ms =container_of(work, struct mirror_set, kmirrord_work); @@ -1274,24 +1297,6 @@ static int _do_mirror(struct work_struct *work) do_reads(ms, &reads); do_writes(ms, &writes); do_failures(ms, &failures); - - return (ms->failures.head) ? 1 : 0; -} - -static void do_mirror(struct work_struct *work) -{ - /* - * If _do_mirror returns 1, we give it - * another shot. This helps for cases like - * 'suspend' where we call flush_workqueue - * and expect all work to be finished. If - * a failure happens during a suspend, we - * couldn't issue a 'wake' because it would - * not be honored. Therefore, we return '1' - * from _do_mirror, and retry here. - */ - while (_do_mirror(work)) - schedule(); } @@ -1545,6 +1550,8 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto err_free_context; } INIT_WORK(&ms->kmirrord_work, do_mirror); + init_timer(&ms->timer); + ms->timer_pending = 0; INIT_WORK(&ms->trigger_event, trigger_event); r = parse_features(ms, argc, argv, &args_used); @@ -1587,6 +1594,7 @@ static void mirror_dtr(struct dm_target *ti) { struct mirror_set *ms = (struct mirror_set *) ti->private; + del_timer_sync(&ms->timer); flush_workqueue(ms->kmirrord_wq); dm_kcopyd_client_destroy(ms->kcopyd_client); destroy_workqueue(ms->kmirrord_wq); -- cgit v1.2.2 From 7ff14a36159d947872870e7a3e9dcaebc46b23eb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 24 Apr 2008 22:10:47 +0100 Subject: dm: unplug queues in threads Remove an avoidable 3ms delay on some dm-raid1 and kcopyd I/O. It is specified that any submitted bio without BIO_RW_SYNC flag may plug the queue (i.e. block the requests from being dispatched to the physical device). The queue is unplugged when the caller calls blk_unplug() function. Usually, the sequence is that someone calls submit_bh to submit IO on a buffer. The IO plugs the queue and waits (to be possibly joined with other adjacent bios). Then, when the caller calls wait_on_buffer(), it unplugs the queue and submits the IOs to the disk. This was happenning: When doing O_SYNC writes, function fsync_buffers_list() submits a list of bios to dm_raid1, the bios are added to dm_raid1 write queue and kmirrord is woken up. fsync_buffers_list() calls wait_on_buffer(). That unplugs the queue, but there are no bios on the device queue as they are still in the dm_raid1 queue. wait_on_buffer() starts waiting until the IO is finished. kmirrord is scheduled, kmirrord takes bios and submits them to the devices. The submitted bio plugs the harddisk queue but there is no one to unplug it. (The process that called wait_on_buffer() is already sleeping.) So there is a 3ms timeout, after which the queues on the harddisks are unplugged and requests are processed. This 3ms timeout meant that in certain workloads (e.g. O_SYNC, 8kb writes), dm-raid1 is 10 times slower than md raid1. Every time we submit something asynchronously via dm_io, we must unplug the queue actually to send the request to the device. This patch adds an unplug call to kmirrord - while processing requests, it keeps the queue plugged (so that adjacent bios can be merged); when it finishes processing all the bios, it unplugs the queue to submit the bios. It also fixes kcopyd which has the same potential problem. All kcopyd requests are submitted with BIO_RW_SYNC. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon Acked-by: Jens Axboe --- drivers/md/dm-io.c | 11 ++++++++--- drivers/md/dm-kcopyd.c | 2 +- drivers/md/dm-raid1.c | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ed9c86cd053e..4789c42d9a3a 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -353,7 +353,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, { struct io io; - if (num_regions > 1 && rw != WRITE) { + if (num_regions > 1 && (rw & RW_MASK) != WRITE) { WARN_ON(1); return -EIO; } @@ -390,7 +390,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, { struct io *io; - if (num_regions > 1 && rw != WRITE) { + if (num_regions > 1 && (rw & RW_MASK) != WRITE) { WARN_ON(1); fn(1, context); return -EIO; @@ -436,7 +436,12 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp) } /* - * New collapsed (a)synchronous interface + * New collapsed (a)synchronous interface. + * + * If the IO is asynchronous (i.e. it has notify.fn), you must either unplug + * the queue with blk_unplug() some time later or set the BIO_RW_SYNC bit in + * io_req->bi_rw. If you fail to do one of these, the IO will be submitted to + * the disk after q->unplug_delay, which defaults to 3ms in blk-settings.c. */ int dm_io(struct dm_io_request *io_req, unsigned num_regions, struct dm_io_region *where, unsigned long *sync_error_bits) diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index ee9583bee04d..996802b8a452 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -332,7 +332,7 @@ static int run_io_job(struct kcopyd_job *job) { int r; struct dm_io_request io_req = { - .bi_rw = job->rw, + .bi_rw = job->rw | (1 << BIO_RW_SYNC), .mem.type = DM_IO_PAGE_LIST, .mem.ptr.pl = job->pages, .mem.offset = job->offset, diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 3b9532fc294c..ff05fe893083 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1297,6 +1297,8 @@ static void do_mirror(struct work_struct *work) do_reads(ms, &reads); do_writes(ms, &writes); do_failures(ms, &failures); + + dm_table_unplug_all(ms->ti->table); } -- cgit v1.2.2 From e8488d08586e6df7fab3db7881631bb13619311b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 24 Apr 2008 22:10:51 +0100 Subject: dm table: drop void suspend_targets return void returning functions returned the return value of another void returning function... Spotted by sparse. Signed-off-by: Adrian Bunk Signed-off-by: Alasdair G Kergon --- drivers/md/dm-table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index e75b1437b58b..fc261c81d736 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -954,7 +954,7 @@ void dm_table_presuspend_targets(struct dm_table *t) if (!t) return; - return suspend_targets(t, 0); + suspend_targets(t, 0); } void dm_table_postsuspend_targets(struct dm_table *t) @@ -962,7 +962,7 @@ void dm_table_postsuspend_targets(struct dm_table *t) if (!t) return; - return suspend_targets(t, 1); + suspend_targets(t, 1); } int dm_table_resume_targets(struct dm_table *t) -- cgit v1.2.2 From 4fdfe401e9d7e30029972d568c667234c0c1d828 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 24 Apr 2008 22:10:56 +0100 Subject: dm table: remove unused dm_create_error_table dm_create_error_table() was added in kernel 2.6.18 and never used... Signed-off-by: Adrian Bunk Signed-off-by: Alasdair G Kergon --- drivers/md/dm-table.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index fc261c81d736..51be53344214 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -245,44 +245,6 @@ int dm_table_create(struct dm_table **result, int mode, return 0; } -int dm_create_error_table(struct dm_table **result, struct mapped_device *md) -{ - struct dm_table *t; - sector_t dev_size = 1; - int r; - - /* - * Find current size of device. - * Default to 1 sector if inactive. - */ - t = dm_get_table(md); - if (t) { - dev_size = dm_table_get_size(t); - dm_table_put(t); - } - - r = dm_table_create(&t, FMODE_READ, 1, md); - if (r) - return r; - - r = dm_table_add_target(t, "error", 0, dev_size, NULL); - if (r) - goto out; - - r = dm_table_complete(t); - if (r) - goto out; - - *result = t; - -out: - if (r) - dm_table_put(t); - - return r; -} -EXPORT_SYMBOL_GPL(dm_create_error_table); - static void free_devices(struct list_head *devices) { struct list_head *tmp, *next; -- cgit v1.2.2 From cf13ab8e02d452e2236d0b5fda9972b3b7f503cb Mon Sep 17 00:00:00 2001 From: Frederik Deweerdt Date: Thu, 24 Apr 2008 22:10:59 +0100 Subject: dm: remove md argument from specific_minor The small patch below: - Removes the unused md argument from both specific_minor() and next_free_minor() - Folds kmalloc + memset(0) into a single kzalloc call in alloc_dev() This has been compile tested on x86. Signed-off-by: Frederik Deweerdt Signed-off-by: Alasdair G Kergon --- drivers/md/dm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 11f4ffedd646..372369b1cc20 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -924,7 +924,7 @@ static void free_minor(int minor) /* * See if the device with a specific minor # is free. */ -static int specific_minor(struct mapped_device *md, int minor) +static int specific_minor(int minor) { int r, m; @@ -957,7 +957,7 @@ out: return r; } -static int next_free_minor(struct mapped_device *md, int *minor) +static int next_free_minor(int *minor) { int r, m; @@ -968,9 +968,8 @@ static int next_free_minor(struct mapped_device *md, int *minor) spin_lock(&_minor_lock); r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); - if (r) { + if (r) goto out; - } if (m >= (1 << MINORBITS)) { idr_remove(&_minor_idr, m); @@ -993,7 +992,7 @@ static struct block_device_operations dm_blk_dops; static struct mapped_device *alloc_dev(int minor) { int r; - struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); + struct mapped_device *md = kzalloc(sizeof(*md), GFP_KERNEL); void *old_md; if (!md) { @@ -1006,13 +1005,12 @@ static struct mapped_device *alloc_dev(int minor) /* get a minor number for the dev */ if (minor == DM_ANY_MINOR) - r = next_free_minor(md, &minor); + r = next_free_minor(&minor); else - r = specific_minor(md, minor); + r = specific_minor(minor); if (r < 0) goto bad_minor; - memset(md, 0, sizeof(*md)); init_rwsem(&md->io_lock); mutex_init(&md->suspend_lock); spin_lock_init(&md->pushback_lock); -- cgit v1.2.2 From cc9429bcb6e36e9f2c51e4e47b95740e472c4c2d Mon Sep 17 00:00:00 2001 From: Pieter Palmers Date: Wed, 19 Mar 2008 22:10:59 +0100 Subject: ieee1394: rawiso: requeue packet for transmission after skipped cycle As it seems, some host controllers have issues that can cause them to skip cycles now and then when using large packets. I suspect that this is due to DMA not succeeding in time. If the transmit fifo can't contain more than one packet (big packets), the DMA should provide a new packet each cycle (125us). I am under the impression that my current PCI express test system can't guarantee this. In any case, the patch tries to provide a workaround as follows: The DMA program descriptors are modified such that when an error occurs, the DMA engine retries the descriptor the next cycle instead of stalling. This way no data is lost. The side effect of this is that packets are sent with one cycle delay. This however might not be that much of a problem for certain protocols (e.g. AM824). If they use padding packets for e.g. rate matching they can drop one of those to resync the streams. The amount of skips between two userspace wakeups is counted. This number is then propagated to userspace through the upper 16 bits of the 'dropped' parameter. This allows unmodified userspace applications due to the following: 1) libraw simply passes this dropped parameter to the user application 2) the meaning of the dropped parameter is: if it's nonzero, something bad has happened. The actual value of the parameter at this moment does not have a specific meaning. A libraw client can then retrieve the number of skipped cycles and account for them if needed. Signed-off-by: Pieter Palmers Signed-off-by: Stefan Richter --- drivers/ieee1394/iso.h | 2 ++ drivers/ieee1394/ohci1394.c | 34 ++++++++++++++++++++++++++++++++++ drivers/ieee1394/raw1394.c | 7 ++++++- 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h index b94e55e6eaa5..b5de5f21ef78 100644 --- a/drivers/ieee1394/iso.h +++ b/drivers/ieee1394/iso.h @@ -123,6 +123,8 @@ struct hpsb_iso { /* how many times the buffer has overflowed or underflowed */ atomic_t overflows; + /* how many cycles were skipped for a given context */ + atomic_t skips; /* Current number of bytes lost in discarded packets */ int bytes_discarded; diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 0690469fcecf..e509e13cb7a7 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -1723,6 +1723,8 @@ struct ohci_iso_xmit { struct dma_prog_region prog; struct ohci1394_iso_tasklet task; int task_active; + int last_cycle; + atomic_t skips; u32 ContextControlSet; u32 ContextControlClear; @@ -1759,6 +1761,8 @@ static int ohci_iso_xmit_init(struct hpsb_iso *iso) iso->hostdata = xmit; xmit->ohci = iso->host->hostdata; xmit->task_active = 0; + xmit->last_cycle = -1; + atomic_set(&iso->skips, 0); dma_prog_region_init(&xmit->prog); @@ -1856,6 +1860,26 @@ static void ohci_iso_xmit_task(unsigned long data) /* parse cycle */ cycle = le32_to_cpu(cmd->output_last.status) & 0x1FFF; + if (xmit->last_cycle > -1) { + int cycle_diff = cycle - xmit->last_cycle; + int skip; + + /* unwrap */ + if (cycle_diff < 0) { + cycle_diff += 8000; + if (cycle_diff < 0) + PRINT(KERN_ERR, "bogus cycle diff %d\n", + cycle_diff); + } + + skip = cycle_diff - 1; + if (skip > 0) { + DBGMSG("skipped %d cycles without packet loss", skip); + atomic_add(skip, &iso->skips); + } + } + xmit->last_cycle = cycle; + /* tell the subsystem the packet has gone out */ hpsb_iso_packet_sent(iso, cycle, event != 0x11); @@ -1943,6 +1967,16 @@ static int ohci_iso_xmit_queue(struct hpsb_iso *iso, struct hpsb_iso_packet_info prev->output_last.branchAddress = cpu_to_le32( dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3); + /* + * Link the skip address to this descriptor itself. This causes a + * context to skip a cycle whenever lost cycles or FIFO overruns occur, + * without dropping the data at that point the application should then + * decide whether this is an error condition or not. Some protocols + * can deal with this by dropping some rate-matching padding packets. + */ + next->output_more_immediate.branchAddress = + prev->output_last.branchAddress; + /* disable interrupt, unless required by the IRQ interval */ if (prev_i % iso->irq_interval) { prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */ diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 04e96ba56e09..567dafc2369d 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2356,13 +2356,16 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_status *stat) { + int overflows = atomic_read(&iso->overflows); + int skips = atomic_read(&iso->skips); + stat->config.data_buf_size = iso->buf_size; stat->config.buf_packets = iso->buf_packets; stat->config.channel = iso->channel; stat->config.speed = iso->speed; stat->config.irq_interval = iso->irq_interval; stat->n_packets = hpsb_iso_n_ready(iso); - stat->overflows = atomic_read(&iso->overflows); + stat->overflows = ((skips & 0xFFFF) << 16) | ((overflows & 0xFFFF)); stat->xmit_cycle = iso->xmit_cycle; } @@ -2437,6 +2440,8 @@ static int raw1394_iso_get_status(struct file_info *fi, void __user * uaddr) /* reset overflow counter */ atomic_set(&iso->overflows, 0); + /* reset skip counter */ + atomic_set(&iso->skips, 0); return 0; } -- cgit v1.2.2 From e38649702ea64fdbbab3dd459bf8558142dd3bc4 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Thu, 24 Apr 2008 09:02:04 +0200 Subject: ieee1394: silence defined but not used warning in non-modular builds Currently the kernel will issue the following warning: drivers/ieee1394/raw1394.c:2938: warning: 'raw1394_id_table' defined but not used Add #ifdef MODULE guards around the declaration. Signed-off-by: Tony Breeds Ditto with dv1394_id_table and video1394_id_table. Signed-off-by: Stefan Richter --- drivers/ieee1394/dv1394.c | 2 ++ drivers/ieee1394/raw1394.c | 2 ++ drivers/ieee1394/video1394.c | 2 ++ 3 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 6228fadacd38..9d19aec5820a 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -2167,6 +2167,7 @@ static const struct file_operations dv1394_fops= /* * Export information about protocols/devices supported by this driver. */ +#ifdef MODULE static struct ieee1394_device_id dv1394_id_table[] = { { .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, @@ -2177,6 +2178,7 @@ static struct ieee1394_device_id dv1394_id_table[] = { }; MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table); +#endif /* MODULE */ static struct hpsb_protocol_driver dv1394_driver = { .name = "dv1394", diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 567dafc2369d..ec2a0adbedb2 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2940,6 +2940,7 @@ static int raw1394_release(struct inode *inode, struct file *file) /* * Export information about protocols/devices supported by this driver. */ +#ifdef MODULE static struct ieee1394_device_id raw1394_id_table[] = { { .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, @@ -2961,6 +2962,7 @@ static struct ieee1394_device_id raw1394_id_table[] = { }; MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); +#endif /* MODULE */ static struct hpsb_protocol_driver raw1394_driver = { .name = "raw1394", diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index e03024eeeac1..e24772d336e1 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1293,6 +1293,7 @@ static const struct file_operations video1394_fops= /* * Export information about protocols/devices supported by this driver. */ +#ifdef MODULE static struct ieee1394_device_id video1394_id_table[] = { { .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, @@ -1313,6 +1314,7 @@ static struct ieee1394_device_id video1394_id_table[] = { }; MODULE_DEVICE_TABLE(ieee1394, video1394_id_table); +#endif /* MODULE */ static struct hpsb_protocol_driver video1394_driver = { .name = VIDEO1394_DRIVER_NAME, -- cgit v1.2.2