diff options
Diffstat (limited to 'drivers')
97 files changed, 5547 insertions, 4594 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index e7da9fa724e..050323fd79e 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -80,6 +80,8 @@ source "drivers/rtc/Kconfig" source "drivers/dma/Kconfig" +source "drivers/auxdisplay/Kconfig" + source "drivers/kvm/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index f28dcb4ec8b..3a718f51350 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_ATA) += ata/ obj-$(CONFIG_FUSION) += message/ obj-$(CONFIG_IEEE1394) += ieee1394/ obj-y += cdrom/ +obj-y += auxdisplay/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ obj-$(CONFIG_PCCARD) += pcmcia/ diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 5aab7bd473a..8fccf018f16 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -912,7 +912,6 @@ static int start_rx(struct atm_dev *dev) free_page((unsigned long) eni_dev->free_list); return -ENOMEM; } - memset(eni_dev->rx_map,0,PAGE_SIZE); eni_dev->rx_mult = DEFAULT_RX_MULT; eni_dev->fast = eni_dev->last_fast = NULL; eni_dev->slow = eni_dev->last_slow = NULL; diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig new file mode 100644 index 00000000000..0300e7f54cc --- /dev/null +++ b/drivers/auxdisplay/Kconfig @@ -0,0 +1,109 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# +# Auxiliary display drivers configuration. +# + +menu "Auxiliary Display support" + +config KS0108 + tristate "KS0108 LCD Controller" + depends on PARPORT_PC + default n + ---help--- + If you have a LCD controlled by one or more KS0108 + controllers, say Y. You will need also another more specific + driver for your LCD. + + Depends on Parallel Port support. If you say Y at + parport, you will be able to compile this as a module (M) + and built-in as well (Y). + + To compile this as a module, choose M here: + the module will be called ks0108. + + If unsure, say N. + +config KS0108_PORT + hex "Parallel port where the LCD is connected" + depends on KS0108 + default 0x378 + ---help--- + The address of the parallel port where the LCD is connected. + + The first standard parallel port address is 0x378. + The second standard parallel port address is 0x278. + The third standard parallel port address is 0x3BC. + + You can specify a different address if you need. + + If you don't know what I'm talking about, load the parport module, + and execute "dmesg" or "cat /proc/ioports". You can see there how + many parallel ports are present and which address each one has. + + Usually you only need to use 0x378. + + If you compile this as a module, you can still override this + using the module parameters. + +config KS0108_DELAY + int "Delay between each control writing (microseconds)" + depends on KS0108 + default "2" + ---help--- + Amount of time the ks0108 should wait between each control write + to the parallel port. + + If your driver seems to miss random writings, increment this. + + If you don't know what I'm talking about, ignore it. + + If you compile this as a module, you can still override this + value using the module parameters. + +config CFAG12864B + tristate "CFAG12864B LCD" + depends on X86 + depends on FB + depends on KS0108 + default n + ---help--- + If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series, + say Y. You also need the ks0108 LCD Controller driver. + + For help about how to wire your LCD to the parallel port, + check Documentation/auxdisplay/cfag12864b + + Depends on the x86 arch and the framebuffer support. + + The LCD framebuffer driver can be attached to a console. + It will work fine. However, you can't attach it to the fbdev driver + of the xorg server. + + To compile this as a module, choose M here: + the modules will be called cfag12864b and cfag12864bfb. + + If unsure, say N. + +config CFAG12864B_RATE + int "Refresh rate (hertz)" + depends on CFAG12864B + default "20" + ---help--- + Refresh rate of the LCD. + + As the LCD is not memory mapped, the driver has to make the work by + software. This means you should be careful setting this value higher. + If your CPUs are really slow or you feel the system is slowed down, + decrease the value. + + Be careful modifying this value to a very high value: + You can freeze the computer, or the LCD maybe can't draw as fast as you + are requesting. + + If you don't know what I'm talking about, ignore it. + + If you compile this as a module, you can still override this + value using the module parameters. +endmenu diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile new file mode 100644 index 00000000000..8a8936a468b --- /dev/null +++ b/drivers/auxdisplay/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the kernel auxiliary displays device drivers. +# + +obj-$(CONFIG_KS0108) += ks0108.o +obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c new file mode 100644 index 00000000000..889583dfc1a --- /dev/null +++ b/drivers/auxdisplay/cfag12864b.c @@ -0,0 +1,383 @@ +/* + * Filename: cfag12864b.c + * Version: 0.1.0 + * Description: cfag12864b LCD driver + * License: GPLv2 + * Depends: ks0108 + * + * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com> + * Date: 2006-10-31 + * + * 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. + * + * 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 <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/cdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/jiffies.h> +#include <linux/mutex.h> +#include <linux/uaccess.h> +#include <linux/vmalloc.h> +#include <linux/workqueue.h> +#include <linux/ks0108.h> +#include <linux/cfag12864b.h> + + +#define CFAG12864B_NAME "cfag12864b" + +/* + * Module Parameters + */ + +static unsigned int cfag12864b_rate = CONFIG_CFAG12864B_RATE; +module_param(cfag12864b_rate, uint, S_IRUGO); +MODULE_PARM_DESC(cfag12864b_rate, + "Refresh rate (hertzs)"); + +unsigned int cfag12864b_getrate(void) +{ + return cfag12864b_rate; +} + +/* + * cfag12864b Commands + * + * E = Enable signal + * Everytime E switch from low to high, + * cfag12864b/ks0108 reads the command/data. + * + * CS1 = First ks0108controller. + * If high, the first ks0108 controller receives commands/data. + * + * CS2 = Second ks0108 controller + * If high, the second ks0108 controller receives commands/data. + * + * DI = Data/Instruction + * If low, cfag12864b will expect commands. + * If high, cfag12864b will expect data. + * + */ + +#define bit(n) (((unsigned char)1)<<(n)) + +#define CFAG12864B_BIT_E (0) +#define CFAG12864B_BIT_CS1 (2) +#define CFAG12864B_BIT_CS2 (1) +#define CFAG12864B_BIT_DI (3) + +static unsigned char cfag12864b_state; + +static void cfag12864b_set(void) +{ + ks0108_writecontrol(cfag12864b_state); +} + +static void cfag12864b_setbit(unsigned char state, unsigned char n) +{ + if (state) + cfag12864b_state |= bit(n); + else + cfag12864b_state &= ~bit(n); +} + +static void cfag12864b_e(unsigned char state) +{ + cfag12864b_setbit(state, CFAG12864B_BIT_E); + cfag12864b_set(); +} + +static void cfag12864b_cs1(unsigned char state) +{ + cfag12864b_setbit(state, CFAG12864B_BIT_CS1); +} + +static void cfag12864b_cs2(unsigned char state) +{ + cfag12864b_setbit(state, CFAG12864B_BIT_CS2); +} + +static void cfag12864b_di(unsigned char state) +{ + cfag12864b_setbit(state, CFAG12864B_BIT_DI); +} + +static void cfag12864b_setcontrollers(unsigned char first, + unsigned char second) +{ + if (first) + cfag12864b_cs1(0); + else + cfag12864b_cs1(1); + + if (second) + cfag12864b_cs2(0); + else + cfag12864b_cs2(1); +} + +static void cfag12864b_controller(unsigned char which) +{ + if (which == 0) + cfag12864b_setcontrollers(1, 0); + else if (which == 1) + cfag12864b_setcontrollers(0, 1); +} + +static void cfag12864b_displaystate(unsigned char state) +{ + cfag12864b_di(0); + cfag12864b_e(1); + ks0108_displaystate(state); + cfag12864b_e(0); +} + +static void cfag12864b_address(unsigned char address) +{ + cfag12864b_di(0); + cfag12864b_e(1); + ks0108_address(address); + cfag12864b_e(0); +} + +static void cfag12864b_page(unsigned char page) +{ + cfag12864b_di(0); + cfag12864b_e(1); + ks0108_page(page); + cfag12864b_e(0); +} + +static void cfag12864b_startline(unsigned char startline) +{ + cfag12864b_di(0); + cfag12864b_e(1); + ks0108_startline(startline); + cfag12864b_e(0); +} + +static void cfag12864b_writebyte(unsigned char byte) +{ + cfag12864b_di(1); + cfag12864b_e(1); + ks0108_writedata(byte); + cfag12864b_e(0); +} + +static void cfag12864b_nop(void) +{ + cfag12864b_startline(0); +} + +/* + * cfag12864b Internal Commands + */ + +static void cfag12864b_on(void) +{ + cfag12864b_setcontrollers(1, 1); + cfag12864b_displaystate(1); +} + +static void cfag12864b_off(void) +{ + cfag12864b_setcontrollers(1, 1); + cfag12864b_displaystate(0); +} + +static void cfag12864b_clear(void) +{ + unsigned char i, j; + + cfag12864b_setcontrollers(1, 1); + for (i = 0; i < CFAG12864B_PAGES; i++) { + cfag12864b_page(i); + cfag12864b_address(0); + for (j = 0; j < CFAG12864B_ADDRESSES; j++) + cfag12864b_writebyte(0); + } +} + +/* + * Update work + */ + +unsigned char *cfag12864b_buffer; +static unsigned char *cfag12864b_cache; +static DEFINE_MUTEX(cfag12864b_mutex); +static unsigned char cfag12864b_updating; +static void cfag12864b_update(struct work_struct *delayed_work); +static struct workqueue_struct *cfag12864b_workqueue; +static DECLARE_DELAYED_WORK(cfag12864b_work, cfag12864b_update); + +static void cfag12864b_queue(void) +{ + queue_delayed_work(cfag12864b_workqueue, &cfag12864b_work, + HZ / cfag12864b_rate); +} + +unsigned char cfag12864b_enable(void) +{ + unsigned char ret; + + mutex_lock(&cfag12864b_mutex); + + if (!cfag12864b_updating) { + cfag12864b_updating = 1; + cfag12864b_queue(); + ret = 0; + } else + ret = 1; + + mutex_unlock(&cfag12864b_mutex); + + return ret; +} + +void cfag12864b_disable(void) +{ + mutex_lock(&cfag12864b_mutex); + + if (cfag12864b_updating) { + cfag12864b_updating = 0; + cancel_delayed_work(&cfag12864b_work); + flush_workqueue(cfag12864b_workqueue); + } + + mutex_unlock(&cfag12864b_mutex); +} + +unsigned char cfag12864b_isenabled(void) +{ + return cfag12864b_updating; +} + +static void cfag12864b_update(struct work_struct *work) +{ + unsigned char c; + unsigned short i, j, k, b; + + if (memcmp(cfag12864b_cache, cfag12864b_buffer, CFAG12864B_SIZE)) { + for (i = 0; i < CFAG12864B_CONTROLLERS; i++) { + cfag12864b_controller(i); + cfag12864b_nop(); + for (j = 0; j < CFAG12864B_PAGES; j++) { + cfag12864b_page(j); + cfag12864b_nop(); + cfag12864b_address(0); + cfag12864b_nop(); + for (k = 0; k < CFAG12864B_ADDRESSES; k++) { + for (c = 0, b = 0; b < 8; b++) + if (cfag12864b_buffer + [i * CFAG12864B_ADDRESSES / 8 + + k / 8 + (j * 8 + b) * + CFAG12864B_WIDTH / 8] + & bit(k % 8)) + c |= bit(b); + cfag12864b_writebyte(c); + } + } + } + + memcpy(cfag12864b_cache, cfag12864b_buffer, CFAG12864B_SIZE); + } + + if (cfag12864b_updating) + cfag12864b_queue(); +} + +/* + * cfag12864b Exported Symbols + */ + +EXPORT_SYMBOL_GPL(cfag12864b_buffer); +EXPORT_SYMBOL_GPL(cfag12864b_getrate); +EXPORT_SYMBOL_GPL(cfag12864b_enable); +EXPORT_SYMBOL_GPL(cfag12864b_disable); +EXPORT_SYMBOL_GPL(cfag12864b_isenabled); + +/* + * Module Init & Exit + */ + +static int __init cfag12864b_init(void) +{ + int ret = -EINVAL; + + if (PAGE_SIZE < CFAG12864B_SIZE) { + printk(KERN_ERR CFAG12864B_NAME ": ERROR: " + "page size (%i) < cfag12864b size (%i)\n", + (unsigned int)PAGE_SIZE, CFAG12864B_SIZE); + ret = -ENOMEM; + goto none; + } + + cfag12864b_buffer = (unsigned char *) __get_free_page(GFP_KERNEL); + if (cfag12864b_buffer == NULL) { + printk(KERN_ERR CFAG12864B_NAME ": ERROR: " + "can't get a free page\n"); + ret = -ENOMEM; + goto none; + } + + cfag12864b_cache = kmalloc(sizeof(unsigned char) * + CFAG12864B_SIZE, GFP_KERNEL); + if (cfag12864b_buffer == NULL) { + printk(KERN_ERR CFAG12864B_NAME ": ERROR: " + "can't alloc cache buffer (%i bytes)\n", + CFAG12864B_SIZE); + ret = -ENOMEM; + goto bufferalloced; + } + + cfag12864b_workqueue = create_singlethread_workqueue(CFAG12864B_NAME); + if (cfag12864b_workqueue == NULL) + goto cachealloced; + + memset(cfag12864b_buffer, 0, CFAG12864B_SIZE); + + cfag12864b_clear(); + cfag12864b_on(); + + return 0; + +cachealloced: + kfree(cfag12864b_cache); + +bufferalloced: + free_page((unsigned long) cfag12864b_buffer); + +none: + return ret; +} + +static void __exit cfag12864b_exit(void) +{ + cfag12864b_disable(); + cfag12864b_off(); + destroy_workqueue(cfag12864b_workqueue); + kfree(cfag12864b_cache); + free_page((unsigned long) cfag12864b_buffer); +} + +module_init(cfag12864b_init); +module_exit(cfag12864b_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>"); +MODULE_DESCRIPTION("cfag12864b LCD driver"); diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c new file mode 100644 index 00000000000..94765e78315 --- /dev/null +++ b/drivers/auxdisplay/cfag12864bfb.c @@ -0,0 +1,180 @@ +/* + * Filename: cfag12864bfb.c + * Version: 0.1.0 + * Description: cfag12864b LCD framebuffer driver + * License: GPLv2 + * Depends: cfag12864b + * + * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com> + * Date: 2006-10-31 + * + * 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. + * + * 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 <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/mm.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/uaccess.h> +#include <linux/cfag12864b.h> + +#define CFAG12864BFB_NAME "cfag12864bfb" + +static struct fb_fix_screeninfo cfag12864bfb_fix __initdata = { + .id = "cfag12864b", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO10, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, + .line_length = CFAG12864B_WIDTH / 8, + .accel = FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo cfag12864bfb_var __initdata = { + .xres = CFAG12864B_WIDTH, + .yres = CFAG12864B_HEIGHT, + .xres_virtual = CFAG12864B_WIDTH, + .yres_virtual = CFAG12864B_HEIGHT, + .bits_per_pixel = 1, + .red = { 0, 1, 0 }, + .green = { 0, 1, 0 }, + .blue = { 0, 1, 0 }, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + return vm_insert_page(vma, vma->vm_start, + virt_to_page(cfag12864b_buffer)); +} + +static struct fb_ops cfag12864bfb_ops = { + .owner = THIS_MODULE, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = cfag12864bfb_mmap, +}; + +static int __init cfag12864bfb_probe(struct platform_device *device) +{ + int ret = -EINVAL; + struct fb_info *info = framebuffer_alloc(0, &device->dev); + + if (!info) + goto none; + + info->screen_base = (char __iomem *) cfag12864b_buffer; + info->screen_size = CFAG12864B_SIZE; + info->fbops = &cfag12864bfb_ops; + info->fix = cfag12864bfb_fix; + info->var = cfag12864bfb_var; + info->pseudo_palette = NULL; + info->par = NULL; + info->flags = FBINFO_FLAG_DEFAULT; + + if (register_framebuffer(info) < 0) + goto fballoced; + + platform_set_drvdata(device, info); + + printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, + info->fix.id); + + return 0; + +fballoced: + framebuffer_release(info); + +none: + return ret; +} + +static int cfag12864bfb_remove(struct platform_device *device) +{ + struct fb_info *info = platform_get_drvdata(device); + + if (info) { + unregister_framebuffer(info); + framebuffer_release(info); + } + + return 0; +} + +static struct platform_driver cfag12864bfb_driver = { + .probe = cfag12864bfb_probe, + .remove = cfag12864bfb_remove, + .driver = { + .name = CFAG12864BFB_NAME, + }, +}; + +static struct platform_device *cfag12864bfb_device; + +static int __init cfag12864bfb_init(void) +{ + int ret; + + if (cfag12864b_enable()) { + printk(KERN_ERR CFAG12864BFB_NAME ": ERROR: " + "can't enable cfag12864b refreshing (being used)\n"); + return -ENODEV; + } + + ret = platform_driver_register(&cfag12864bfb_driver); + + if (!ret) { + cfag12864bfb_device = + platform_device_alloc(CFAG12864BFB_NAME, 0); + + if (cfag12864bfb_device) + ret = platform_device_add(cfag12864bfb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(cfag12864bfb_device); + platform_driver_unregister(&cfag12864bfb_driver); + } + } + + return ret; +} + +static void __exit cfag12864bfb_exit(void) +{ + platform_device_unregister(cfag12864bfb_device); + platform_driver_unregister(&cfag12864bfb_driver); + cfag12864b_disable(); +} + +module_init(cfag12864bfb_init); +module_exit(cfag12864bfb_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>"); +MODULE_DESCRIPTION("cfag12864b LCD framebuffer driver"); diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c new file mode 100644 index 00000000000..a637575b910 --- /dev/null +++ b/drivers/auxdisplay/ks0108.c @@ -0,0 +1,166 @@ +/* + * Filename: ks0108.c + * Version: 0.1.0 + * Description: ks0108 LCD Controller driver + * License: GPLv2 + * Depends: parport + * + * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com> + * Date: 2006-10-31 + * + * 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. + * + * 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 <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/fs.h> +#include <linux/io.h> +#include <linux/parport.h> +#include <linux/uaccess.h> +#include <linux/ks0108.h> + +#define KS0108_NAME "ks0108" + +/* + * Module Parameters + */ + +static unsigned int ks0108_port = CONFIG_KS0108_PORT; +module_param(ks0108_port, uint, S_IRUGO); +MODULE_PARM_DESC(ks0108_port, "Parallel port where the LCD is connected"); + +static unsigned int ks0108_delay = CONFIG_KS0108_DELAY; +module_param(ks0108_delay, uint, S_IRUGO); +MODULE_PARM_DESC(ks0108_delay, "Delay between each control writing (microseconds)"); + +/* + * Device + */ + +static struct parport *ks0108_parport; +static struct pardevice *ks0108_pardevice; + +/* + * ks0108 Exported Commands (don't lock) + * + * You _should_ lock in the top driver: This functions _should not_ + * get race conditions in any way. Locking for each byte here would be + * so slow and useless. + * + * There are not bit definitions because they are not flags, + * just arbitrary combinations defined by the documentation for each + * function in the ks0108 LCD controller. If you want to know what means + * a specific combination, look at the function's name. + * + * The ks0108_writecontrol bits need to be reverted ^(0,1,3) because + * the parallel port also revert them using a "not" logic gate. + */ + +#define bit(n) (((unsigned char)1)<<(n)) + +void ks0108_writedata(unsigned char byte) +{ + parport_write_data(ks0108_parport, byte); +} + +void ks0108_writecontrol(unsigned char byte) +{ + udelay(ks0108_delay); + parport_write_control(ks0108_parport, byte ^ (bit(0) | bit(1) | bit(3))); +} + +void ks0108_displaystate(unsigned char state) +{ + ks0108_writedata((state ? bit(0) : 0) | bit(1) | bit(2) | bit(3) | bit(4) | bit(5)); +} + +void ks0108_startline(unsigned char startline) +{ + ks0108_writedata(min(startline,(unsigned char)63) | bit(6) | bit(7)); +} + +void ks0108_address(unsigned char address) +{ + ks0108_writedata(min(address,(unsigned char)63) | bit(6)); +} + +void ks0108_page(unsigned char page) +{ + ks0108_writedata(min(page,(unsigned char)7) | bit(3) | bit(4) | bit(5) | bit(7)); +} + +EXPORT_SYMBOL_GPL(ks0108_writedata); +EXPORT_SYMBOL_GPL(ks0108_writecontrol); +EXPORT_SYMBOL_GPL(ks0108_displaystate); +EXPORT_SYMBOL_GPL(ks0108_startline); +EXPORT_SYMBOL_GPL(ks0108_address); +EXPORT_SYMBOL_GPL(ks0108_page); + +/* + * Module Init & Exit + */ + +static int __init ks0108_init(void) +{ + int result; + int ret = -EINVAL; + + ks0108_parport = parport_find_base(ks0108_port); + if (ks0108_parport == NULL) { + printk(KERN_ERR KS0108_NAME ": ERROR: " + "parport didn't find %i port\n", ks0108_port); + goto none; + } + + ks0108_pardevice = parport_register_device(ks0108_parport, KS0108_NAME, + NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (ks0108_pardevice == NULL) { + printk(KERN_ERR KS0108_NAME ": ERROR: " + "parport didn't register new device\n"); + goto none; + } + + result = parport_claim(ks0108_pardevice); + if (result != 0) { + printk(KERN_ERR KS0108_NAME ": ERROR: " + "can't claim %i parport, maybe in use\n", ks0108_port); + ret = result; + goto registered; + } + + return 0; + +registered: + parport_unregister_device(ks0108_pardevice); + +none: + return ret; +} + +static void __exit ks0108_exit(void) +{ + parport_release(ks0108_pardevice); + parport_unregister_device(ks0108_pardevice); +} + +module_init(ks0108_init); +module_exit(ks0108_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>"); +MODULE_DESCRIPTION("ks0108 LCD Controller driver"); + diff --git a/drivers/base/node.c b/drivers/base/node.c index 001e6f6b9c1..475e33f76e0 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -40,13 +40,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) int n; int nid = dev->id; struct sysinfo i; - unsigned long inactive; - unsigned long active; - unsigned long free; si_meminfo_node(&i, nid); - __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); - n = sprintf(buf, "\n" "Node %d MemTotal: %8lu kB\n" @@ -74,8 +69,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) nid, K(i.totalram), nid, K(i.freeram), nid, K(i.totalram - i.freeram), - nid, K(active), - nid, K(inactive), + nid, node_page_state(nid, NR_ACTIVE), + nid, node_page_state(nid, NR_INACTIVE), #ifdef CONFIG_HIGHMEM nid, K(i.totalhigh), nid, K(i.freehigh), diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 7c72f104567..7b2fa3d8f61 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -177,7 +177,7 @@ static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller) DAC960_Failure prints a standardized error message, and then returns false. */ -static boolean DAC960_Failure(DAC960_Controller_T *Controller, +static bool DAC960_Failure(DAC960_Controller_T *Controller, unsigned char *ErrorMessage) { DAC960_Error("While configuring DAC960 PCI RAID Controller at\n", @@ -206,7 +206,7 @@ static boolean DAC960_Failure(DAC960_Controller_T *Controller, that are passed in. */ -static boolean init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf, +static bool init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf, size_t len) { void *cpu_addr; @@ -250,7 +250,7 @@ static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle) failure. */ -static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller) +static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller) { int CommandAllocationLength, CommandAllocationGroupSize; int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount; @@ -790,7 +790,7 @@ static void DAC960_ExecuteCommand(DAC960_Command_T *Command) on failure. */ -static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller, +static bool DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller, DAC960_V1_CommandOpcode_T CommandOpcode, dma_addr_t DataDMA) { @@ -814,7 +814,7 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller, on failure. */ -static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller, +static bool DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller, DAC960_V1_CommandOpcode_T CommandOpcode, unsigned char CommandOpcode2, dma_addr_t DataDMA) @@ -840,7 +840,7 @@ static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller, on failure. */ -static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller, +static bool DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller, DAC960_V1_CommandOpcode_T CommandOpcode, unsigned char Channel, unsigned char TargetID, @@ -870,7 +870,7 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller, Return data in The controller's HealthStatusBuffer, which is dma-able memory */ -static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller) +static bool DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller) { DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; @@ -908,7 +908,7 @@ static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller) memory buffer. */ -static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller) +static bool DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller) { DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; @@ -946,7 +946,7 @@ static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller) Data is returned in the controller's V2.NewLogicalDeviceInformation */ -static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller, +static bool DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller, unsigned short LogicalDeviceNumber) { DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); @@ -997,7 +997,7 @@ static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller, */ -static boolean DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller, +static bool DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller, unsigned char Channel, unsigned char TargetID, unsigned char LogicalUnit) @@ -1082,7 +1082,7 @@ static void DAC960_V2_ConstructNewUnitSerialNumber( memory buffer. */ -static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller, +static bool DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller, int Channel, int TargetID, int LogicalUnit) { DAC960_Command_T *Command; @@ -1110,7 +1110,7 @@ static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Control success and false on failure. */ -static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller, +static bool DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller, DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode, DAC960_V2_OperationDevice_T OperationDevice) @@ -1142,7 +1142,7 @@ static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller, other dma mapped memory. */ -static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T +static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller) { void __iomem *ControllerBaseAddress = Controller->BaseAddress; @@ -1348,7 +1348,7 @@ skip_mailboxes: the structures that are contained in that region. */ -static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T +static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller) { void __iomem *ControllerBaseAddress = Controller->BaseAddress; @@ -1525,7 +1525,7 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T from DAC960 V1 Firmware Controllers and initializes the Controller structure. */ -static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T +static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T *Controller) { DAC960_V1_Enquiry2_T *Enquiry2; @@ -1766,7 +1766,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T from DAC960 V2 Firmware Controllers and initializes the Controller structure. */ -static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T +static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T *Controller) { DAC960_V2_ControllerInfo_T *ControllerInfo = @@ -1897,7 +1897,7 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T for Controller. */ -static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T +static bool DAC960_ReportControllerConfiguration(DAC960_Controller_T *Controller) { DAC960_Info("Configuring Mylex %s PCI RAID Controller\n", @@ -1946,7 +1946,7 @@ static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T Controller. */ -static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T +static bool DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T *Controller) { struct dma_loaf local_dma; @@ -2094,7 +2094,7 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T device connected to Controller. */ -static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T +static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T *Controller) { unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0; @@ -2218,7 +2218,7 @@ static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T Information for DAC960 V1 Firmware Controllers. */ -static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T +static bool DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T *Controller) { int LogicalDriveNumber, Channel, TargetID; @@ -2315,7 +2315,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T Information for DAC960 V2 Firmware Controllers. */ -static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T +static bool DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T *Controller) { int PhysicalDeviceIndex, LogicalDriveNumber; @@ -2500,7 +2500,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T associated with Controller. */ -static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) +static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) { int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber; int n; @@ -2581,7 +2581,7 @@ static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller) It returns true for fatal errors and false otherwise. */ -static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller, +static bool DAC960_ReportErrorStatus(DAC960_Controller_T *Controller, unsigned char ErrorStatus, unsigned char Parameter0, unsigned char Parameter1) @@ -3047,7 +3047,7 @@ Failure: DAC960_InitializeController initializes Controller. */ -static boolean +static bool DAC960_InitializeController(DAC960_Controller_T *Controller) { if (DAC960_ReadControllerConfiguration(Controller) && @@ -3444,8 +3444,8 @@ static void DAC960_RequestFunction(struct request_queue *RequestQueue) individual Buffer. */ -static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, - boolean SuccessfulIO) +static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, + bool SuccessfulIO) { struct request *Request = Command->Request; int UpToDate; @@ -3571,7 +3571,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command) else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - boolean normal_completion; + bool normal_completion; #ifdef FORCE_RETRY_FAILURE_DEBUG static int retry_count = 1; #endif @@ -4658,7 +4658,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - boolean normal_completion; + bool normal_completion; #ifdef FORCE_RETRY_FAILURE_DEBUG static int retry_count = 1; @@ -5631,7 +5631,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData) &Controller->V2.ControllerInformation; unsigned int StatusChangeCounter = Controller->V2.HealthStatusBuffer->StatusChangeCounter; - boolean ForceMonitoringCommand = false; + bool ForceMonitoringCommand = false; if (time_after(jiffies, Controller->SecondaryMonitoringTime + DAC960_SecondaryMonitoringInterval)) { @@ -5695,7 +5695,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData) necessary. It returns true if there is enough room and false otherwise. */ -static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller, +static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller, unsigned int ByteCount) { unsigned char *NewStatusBuffer; @@ -5743,7 +5743,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel, ...) { static unsigned char Buffer[DAC960_LineBufferSize]; - static boolean BeginningOfLine = true; + static bool BeginningOfLine = true; va_list Arguments; int Length = 0; va_start(Arguments, Controller); @@ -5836,7 +5836,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel, Channel and TargetID and returns true on success and false on failure. */ -static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller, +static bool DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller, char *UserCommandString, unsigned char *Channel, unsigned char *TargetID) @@ -5869,7 +5869,7 @@ static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller, returns true on success and false on failure. */ -static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller, +static bool DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller, char *UserCommandString, unsigned char *LogicalDriveNumber) { @@ -5950,7 +5950,7 @@ static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller, Controllers. */ -static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller, +static bool DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller, unsigned char *UserCommand) { DAC960_Command_T *Command; @@ -6165,7 +6165,7 @@ failure: on failure. */ -static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command, +static bool DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command, unsigned char Channel, unsigned char TargetID, unsigned short @@ -6212,7 +6212,7 @@ static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command, Controllers. */ -static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, +static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, unsigned char *UserCommand) { DAC960_Command_T *Command; diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h index 6148073532b..f5e2436c39a 100644 --- a/drivers/block/DAC960.h +++ b/drivers/block/DAC960.h @@ -68,13 +68,6 @@ #define DAC690_V2_PciDmaMask 0xffffffffffffffffULL /* - Define a Boolean data type. -*/ - -typedef bool boolean; - - -/* Define a 32/64 bit I/O Address data type. */ @@ -139,25 +132,25 @@ typedef struct DAC960_SCSI_Inquiry unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ - boolean RMB:1; /* Byte 1 Bit 7 */ + bool RMB:1; /* Byte 1 Bit 7 */ unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ unsigned char :2; /* Byte 3 Bits 4-5 */ - boolean TrmIOP:1; /* Byte 3 Bit 6 */ - boolean AENC:1; /* Byte 3 Bit 7 */ + bool TrmIOP:1; /* Byte 3 Bit 6 */ + bool AENC:1; /* Byte 3 Bit 7 */ unsigned char AdditionalLength; /* Byte 4 */ unsigned char :8; /* Byte 5 */ unsigned char :8; /* Byte 6 */ - boolean SftRe:1; /* Byte 7 Bit 0 */ - boolean CmdQue:1; /* Byte 7 Bit 1 */ - boolean :1; /* Byte 7 Bit 2 */ - boolean Linked:1; /* Byte 7 Bit 3 */ - boolean Sync:1; /* Byte 7 Bit 4 */ - boolean WBus16:1; /* Byte 7 Bit 5 */ - boolean WBus32:1; /* Byte 7 Bit 6 */ - boolean RelAdr:1; /* Byte 7 Bit 7 */ + bool SftRe:1; /* Byte 7 Bit 0 */ + bool CmdQue:1; /* Byte 7 Bit 1 */ + bool :1; /* Byte 7 Bit 2 */ + bool Linked:1; /* Byte 7 Bit 3 */ + bool Sync:1; /* Byte 7 Bit 4 */ + bool WBus16:1; /* Byte 7 Bit 5 */ + bool WBus32:1; /* Byte 7 Bit 6 */ + bool RelAdr:1; /* Byte 7 Bit 7 */ unsigned char VendorIdentification[8]; /* Bytes 8-15 */ unsigned char ProductIdentification[16]; /* Bytes 16-31 */ unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ @@ -215,13 +208,13 @@ DAC960_SCSI_RequestSenseKey_T; typedef struct DAC960_SCSI_RequestSense { unsigned char ErrorCode:7; /* Byte 0 Bits 0-6 */ - boolean Valid:1; /* Byte 0 Bit 7 */ + bool Valid:1; /* Byte 0 Bit 7 */ unsigned char SegmentNumber; /* Byte 1 */ DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 2 Bits 0-3 */ unsigned char :1; /* Byte 2 Bit 4 */ - boolean ILI:1; /* Byte 2 Bit 5 */ - boolean EOM:1; /* Byte 2 Bit 6 */ - boolean Filemark:1; /* Byte 2 Bit 7 */ + bool ILI:1; /* Byte 2 Bit 5 */ + bool EOM:1; /* Byte 2 Bit 6 */ + bool Filemark:1; /* Byte 2 Bit 7 */ unsigned char Information[4]; /* Bytes 3-6 */ unsigned char AdditionalSenseLength; /* Byte 7 */ unsigned char CommandSpecificInformation[4]; /* Bytes 8-11 */ @@ -381,8 +374,8 @@ typedef struct DAC960_V1_Enquiry unsigned int LogicalDriveSizes[32]; /* Bytes 4-131 */ unsigned short FlashAge; /* Bytes 132-133 */ struct { - boolean DeferredWriteError:1; /* Byte 134 Bit 0 */ - boolean BatteryLow:1; /* Byte 134 Bit 1 */ + bool DeferredWriteError:1; /* Byte 134 Bit 0 */ + bool BatteryLow:1; /* Byte 134 Bit 1 */ unsigned char :6; /* Byte 134 Bits 2-7 */ } StatusFlags; unsigned char :8; /* Byte 135 */ @@ -410,7 +403,7 @@ typedef struct DAC960_V1_Enquiry unsigned char RebuildCount; /* Byte 150 */ struct { unsigned char :3; /* Byte 151 Bits 0-2 */ - boolean BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */ + bool BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */ unsigned char :3; /* Byte 151 Bits 4-6 */ unsigned char :1; /* Byte 151 Bit 7 */ } MiscFlags; @@ -492,8 +485,8 @@ typedef struct DAC960_V1_Enquiry2 DAC960_V1_ErrorCorrection_ECC = 0x2, DAC960_V1_ErrorCorrection_Last = 0x7 } __attribute__ ((packed)) ErrorCorrection:3; /* Byte 40 Bits 3-5 */ - boolean FastPageMode:1; /* Byte 40 Bit 6 */ - boolean LowPowerMemory:1; /* Byte 40 Bit 7 */ + bool FastPageMode:1; /* Byte 40 Bit 6 */ + bool LowPowerMemory:1; /* Byte 40 Bit 7 */ unsigned char :8; /* Bytes 41 */ } MemoryType; unsigned short ClockSpeed; /* Bytes 42-43 */ @@ -538,7 +531,7 @@ typedef struct DAC960_V1_Enquiry2 DAC960_V1_Ultra = 0x1, DAC960_V1_Ultra2 = 0x2 } __attribute__ ((packed)) BusSpeed:2; /* Byte 106 Bits 2-3 */ - boolean Differential:1; /* Byte 106 Bit 4 */ + bool Differential:1; /* Byte 106 Bit 4 */ unsigned char :3; /* Byte 106 Bits 5-7 */ } SCSICapability; unsigned char :8; /* Byte 107 */ @@ -554,10 +547,10 @@ typedef struct DAC960_V1_Enquiry2 } __attribute__ ((packed)) FaultManagementType; /* Byte 114 */ unsigned char :8; /* Byte 115 */ struct { - boolean Clustering:1; /* Byte 116 Bit 0 */ - boolean MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */ - boolean ReadAhead:1; /* Byte 116 Bit 2 */ - boolean BackgroundInitialization:1; /* Byte 116 Bit 3 */ + bool Clustering:1; /* Byte 116 Bit 0 */ + bool MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */ + bool ReadAhead:1; /* Byte 116 Bit 2 */ + bool BackgroundInitialization:1; /* Byte 116 Bit 3 */ unsigned int :28; /* Bytes 116-119 */ } FirmwareFeatures; unsigned int :32; /* Bytes 120-123 */ @@ -589,7 +582,7 @@ typedef struct DAC960_V1_LogicalDriveInformation unsigned int LogicalDriveSize; /* Bytes 0-3 */ DAC960_V1_LogicalDriveState_T LogicalDriveState; /* Byte 4 */ unsigned char RAIDLevel:7; /* Byte 5 Bits 0-6 */ - boolean WriteBack:1; /* Byte 5 Bit 7 */ + bool WriteBack:1; /* Byte 5 Bit 7 */ unsigned short :16; /* Bytes 6-7 */ } DAC960_V1_LogicalDriveInformation_T; @@ -630,13 +623,13 @@ typedef struct DAC960_V1_EventLogEntry unsigned char :2; /* Byte 3 Bits 6-7 */ unsigned short SequenceNumber; /* Bytes 4-5 */ unsigned char ErrorCode:7; /* Byte 6 Bits 0-6 */ - boolean Valid:1; /* Byte 6 Bit 7 */ + bool Valid:1; /* Byte 6 Bit 7 */ unsigned char SegmentNumber; /* Byte 7 */ DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 8 Bits 0-3 */ unsigned char :1; /* Byte 8 Bit 4 */ - boolean ILI:1; /* Byte 8 Bit 5 */ - boolean EOM:1; /* Byte 8 Bit 6 */ - boolean Filemark:1; /* Byte 8 Bit 7 */ + bool ILI:1; /* Byte 8 Bit 5 */ + bool EOM:1; /* Byte 8 Bit 6 */ + bool Filemark:1; /* Byte 8 Bit 7 */ unsigned char Information[4]; /* Bytes 9-12 */ unsigned char AdditionalSenseLength; /* Byte 13 */ unsigned char CommandSpecificInformation[4]; /* Bytes 14-17 */ @@ -670,7 +663,7 @@ DAC960_V1_PhysicalDeviceState_T; typedef struct DAC960_V1_DeviceState { - boolean Present:1; /* Byte 0 Bit 0 */ + bool Present:1; /* Byte 0 Bit 0 */ unsigned char :7; /* Byte 0 Bits 1-7 */ enum { DAC960_V1_OtherType = 0x0, @@ -678,12 +671,12 @@ typedef struct DAC960_V1_DeviceState DAC960_V1_SequentialType = 0x2, DAC960_V1_CDROM_or_WORM_Type = 0x3 } __attribute__ ((packed)) DeviceType:2; /* Byte 1 Bits 0-1 */ - boolean :1; /* Byte 1 Bit 2 */ - boolean Fast20:1; /* Byte 1 Bit 3 */ - boolean Sync:1; /* Byte 1 Bit 4 */ - boolean Fast:1; /* Byte 1 Bit 5 */ - boolean Wide:1; /* Byte 1 Bit 6 */ - boolean TaggedQueuingSupported:1; /* Byte 1 Bit 7 */ + bool :1; /* Byte 1 Bit 2 */ + bool Fast20:1; /* Byte 1 Bit 3 */ + bool Sync:1; /* Byte 1 Bit 4 */ + bool Fast:1; /* Byte 1 Bit 5 */ + bool Wide:1; /* Byte 1 Bit 6 */ + bool TaggedQueuingSupported:1; /* Byte 1 Bit 7 */ DAC960_V1_PhysicalDeviceState_T DeviceState; /* Byte 2 */ unsigned char :8; /* Byte 3 */ unsigned char SynchronousMultiplier; /* Byte 4 */ @@ -765,15 +758,15 @@ DAC960_V1_ErrorTable_T; typedef struct DAC960_V1_Config2 { unsigned char :1; /* Byte 0 Bit 0 */ - boolean ActiveNegationEnabled:1; /* Byte 0 Bit 1 */ + bool ActiveNegationEnabled:1; /* Byte 0 Bit 1 */ unsigned char :5; /* Byte 0 Bits 2-6 */ - boolean NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */ - boolean StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */ - boolean HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */ - boolean NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */ + bool NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */ + bool StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */ + bool HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */ + bool NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */ unsigned char :2; /* Byte 1 Bits 3-4 */ - boolean AEMI_ARM:1; /* Byte 1 Bit 5 */ - boolean AEMI_OFM:1; /* Byte 1 Bit 6 */ + bool AEMI_ARM:1; /* Byte 1 Bit 5 */ + bool AEMI_OFM:1; /* Byte 1 Bit 6 */ unsigned char :1; /* Byte 1 Bit 7 */ enum { DAC960_V1_OEMID_Mylex = 0x00, @@ -787,13 +780,13 @@ typedef struct DAC960_V1_Config2 unsigned char PhysicalSector; /* Byte 4 */ unsigned char LogicalSector; /* Byte 5 */ unsigned char BlockFactor; /* Byte 6 */ - boolean ReadAheadEnabled:1; /* Byte 7 Bit 0 */ - boolean LowBIOSDelay:1; /* Byte 7 Bit 1 */ + bool ReadAheadEnabled:1; /* Byte 7 Bit 0 */ + bool LowBIOSDelay:1; /* Byte 7 Bit 1 */ unsigned char :2; /* Byte 7 Bits 2-3 */ - boolean ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */ + bool ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */ unsigned char :1; /* Byte 7 Bit 5 */ - boolean ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */ - boolean EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */ + bool ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */ + bool EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */ unsigned char DefaultRebuildRate; /* Byte 8 */ unsigned char :8; /* Byte 9 */ unsigned char BlocksPerCacheLine; /* Byte 10 */ @@ -805,10 +798,10 @@ typedef struct DAC960_V1_Config2 DAC960_V1_Sync_5MHz = 0x2, DAC960_V1_Sync_10or20MHz = 0x3 /* Byte 11 Bits 0-1 */ } __attribute__ ((packed)) Speed:2; - boolean Force8Bit:1; /* Byte 11 Bit 2 */ - boolean DisableFast20:1; /* Byte 11 Bit 3 */ + bool Force8Bit:1; /* Byte 11 Bit 2 */ + bool DisableFast20:1; /* Byte 11 Bit 3 */ unsigned char :3; /* Byte 11 Bits 4-6 */ - boolean EnableTaggedQueuing:1; /* Byte 11 Bit 7 */ + bool EnableTaggedQueuing:1; /* Byte 11 Bit 7 */ } __attribute__ ((packed)) ChannelParameters[6]; /* Bytes 12-17 */ unsigned char SCSIInitiatorID; /* Byte 18 */ unsigned char :8; /* Byte 19 */ @@ -819,8 +812,8 @@ typedef struct DAC960_V1_Config2 unsigned char SimultaneousDeviceSpinUpCount; /* Byte 21 */ unsigned char SecondsDelayBetweenSpinUps; /* Byte 22 */ unsigned char Reserved1[29]; /* Bytes 23-51 */ - boolean BIOSDisabled:1; /* Byte 52 Bit 0 */ - boolean CDROMBootEnabled:1; /* Byte 52 Bit 1 */ + bool BIOSDisabled:1; /* Byte 52 Bit 0 */ + bool CDROMBootEnabled:1; /* Byte 52 Bit 1 */ unsigned char :3; /* Byte 52 Bits 2-4 */ enum { DAC960_V1_Geometry_128_32 = 0x0, @@ -849,7 +842,7 @@ typedef struct DAC960_V1_DCDB DAC960_V1_DCDB_DataTransferSystemToDevice = 2, DAC960_V1_DCDB_IllegalDataTransfer = 3 } __attribute__ ((packed)) Direction:2; /* Byte 1 Bits 0-1 */ - boolean EarlyStatus:1; /* Byte 1 Bit 2 */ + bool EarlyStatus:1; /* Byte 1 Bit 2 */ unsigned char :1; /* Byte 1 Bit 3 */ enum { DAC960_V1_DCDB_Timeout_24_hours = 0, @@ -857,8 +850,8 @@ typedef struct DAC960_V1_DCDB DAC960_V1_DCDB_Timeout_60_seconds = 2, DAC960_V1_DCDB_Timeout_10_minutes = 3 } __attribute__ ((packed)) Timeout:2; /* Byte 1 Bits 4-5 */ - boolean NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */ - boolean DisconnectPermitted:1; /* Byte 1 Bit 7 */ + bool NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */ + bool DisconnectPermitted:1; /* Byte 1 Bit 7 */ unsigned short TransferLength; /* Bytes 2-3 */ DAC960_BusAddress32_T BusAddress; /* Bytes 4-7 */ unsigned char CDBLength:4; /* Byte 8 Bits 0-3 */ @@ -920,7 +913,7 @@ typedef union DAC960_V1_CommandMailbox DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */ unsigned char Dummy1[5]; /* Bytes 2-6 */ unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */ - boolean AutoRestore:1; /* Byte 7 Bit 7 */ + bool AutoRestore:1; /* Byte 7 Bit 7 */ unsigned char Dummy2[8]; /* Bytes 8-15 */ } __attribute__ ((packed)) Type3C; struct { @@ -1070,9 +1063,9 @@ typedef struct DAC960_V2_MemoryType DAC960_V2_MemoryType_SDRAM = 0x04, DAC960_V2_MemoryType_Last = 0x1F } __attribute__ ((packed)) MemoryType:5; /* Byte 0 Bits 0-4 */ - boolean :1; /* Byte 0 Bit 5 */ - boolean MemoryParity:1; /* Byte 0 Bit 6 */ - boolean MemoryECC:1; /* Byte 0 Bit 7 */ + bool :1; /* Byte 0 Bit 5 */ + bool MemoryParity:1; /* Byte 0 Bit 6 */ + bool MemoryECC:1; /* Byte 0 Bit 7 */ } DAC960_V2_MemoryType_T; @@ -1187,13 +1180,13 @@ typedef struct DAC960_V2_ControllerInfo unsigned char OEM_Code; /* Byte 131 */ unsigned char VendorName[16]; /* Bytes 132-147 */ /* Other Physical/Controller/Operation Information */ - boolean BBU_Present:1; /* Byte 148 Bit 0 */ - boolean ActiveActiveClusteringMode:1; /* Byte 148 Bit 1 */ + bool BBU_Present:1; /* Byte 148 Bit 0 */ + bool ActiveActiveClusteringMode:1; /* Byte 148 Bit 1 */ unsigned char :6; /* Byte 148 Bits 2-7 */ unsigned char :8; /* Byte 149 */ unsigned short :16; /* Bytes 150-151 */ /* Physical Device Scan Information */ - boolean PhysicalScanActive:1; /* Byte 152 Bit 0 */ + bool PhysicalScanActive:1; /* Byte 152 Bit 0 */ unsigned char :7; /* Byte 152 Bits 1-7 */ unsigned char PhysicalDeviceChannelNumber; /* Byte 153 */ unsigned char PhysicalDeviceTargetID; /* Byte 154 */ @@ -1305,8 +1298,8 @@ typedef struct DAC960_V2_ControllerInfo unsigned int FreeIOP; /* Bytes 468-471 */ unsigned short MaximumCombLengthInBlocks; /* Bytes 472-473 */ unsigned short NumberOfConfigurationGroups; /* Bytes 474-475 */ - boolean InstallationAbortStatus:1; /* Byte 476 Bit 0 */ - boolean MaintenanceModeStatus:1; /* Byte 476 Bit 1 */ + bool InstallationAbortStatus:1; /* Byte 476 Bit 0 */ + bool MaintenanceModeStatus:1; /* Byte 476 Bit 1 */ unsigned int :24; /* Bytes 476-479 */ unsigned char Reserved10[32]; /* Bytes 480-511 */ unsigned char Reserved11[512]; /* Bytes 512-1023 */ @@ -1357,33 +1350,33 @@ typedef struct DAC960_V2_LogicalDeviceInfo DAC960_V2_IntelligentWriteCacheEnabled = 0x3, DAC960_V2_WriteCache_Last = 0x7 } __attribute__ ((packed)) WriteCache:3; /* Byte 8 Bits 3-5 */ - boolean :1; /* Byte 8 Bit 6 */ - boolean LogicalDeviceInitialized:1; /* Byte 8 Bit 7 */ + bool :1; /* Byte 8 Bit 6 */ + bool LogicalDeviceInitialized:1; /* Byte 8 Bit 7 */ } LogicalDeviceControl; /* Byte 8 */ /* Logical Device Operations Status */ - boolean ConsistencyCheckInProgress:1; /* Byte 9 Bit 0 */ - boolean RebuildInProgress:1; /* Byte 9 Bit 1 */ - boolean BackgroundInitializationInProgress:1; /* Byte 9 Bit 2 */ - boolean ForegroundInitializationInProgress:1; /* Byte 9 Bit 3 */ - boolean DataMigrationInProgress:1; /* Byte 9 Bit 4 */ - boolean PatrolOperationInProgress:1; /* Byte 9 Bit 5 */ + bool ConsistencyCheckInProgress:1; /* Byte 9 Bit 0 */ + bool RebuildInProgress:1; /* Byte 9 Bit 1 */ + bool BackgroundInitializationInProgress:1; /* Byte 9 Bit 2 */ + bool ForegroundInitializationInProgress:1; /* Byte 9 Bit 3 */ + bool DataMigrationInProgress:1; /* Byte 9 Bit 4 */ + bool PatrolOperationInProgress:1; /* Byte 9 Bit 5 */ unsigned char :2; /* Byte 9 Bits 6-7 */ unsigned char RAID5WriteUpdate; /* Byte 10 */ unsigned char RAID5Algorithm; /* Byte 11 */ unsigned short LogicalDeviceNumber; /* Bytes 12-13 */ /* BIOS Info */ - boolean BIOSDisabled:1; /* Byte 14 Bit 0 */ - boolean CDROMBootEnabled:1; /* Byte 14 Bit 1 */ - boolean DriveCoercionEnabled:1; /* Byte 14 Bit 2 */ - boolean WriteSameDisabled:1; /* Byte 14 Bit 3 */ - boolean HBA_ModeEnabled:1; /* Byte 14 Bit 4 */ + bool BIOSDisabled:1; /* Byte 14 Bit 0 */ + bool CDROMBootEnabled:1; /* Byte 14 Bit 1 */ + bool DriveCoercionEnabled:1; /* Byte 14 Bit 2 */ + bool WriteSameDisabled:1; /* Byte 14 Bit 3 */ + bool HBA_ModeEnabled:1; /* Byte 14 Bit 4 */ enum { DAC960_V2_Geometry_128_32 = 0x0, DAC960_V2_Geometry_255_63 = 0x1, DAC960_V2_Geometry_Reserved1 = 0x2, DAC960_V2_Geometry_Reserved2 = 0x3 } __attribute__ ((packed)) DriveGeometry:2; /* Byte 14 Bits 5-6 */ - boolean SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */ + bool SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */ unsigned char :8; /* Byte 15 */ /* Error Counters */ unsigned short SoftErrors; /* Bytes 16-17 */ @@ -1446,13 +1439,13 @@ typedef struct DAC960_V2_PhysicalDeviceInfo unsigned char TargetID; /* Byte 2 */ unsigned char LogicalUnit; /* Byte 3 */ /* Configuration Status Bits */ - boolean PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */ - boolean PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */ - boolean PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */ + bool PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */ + bool PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */ + bool PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */ unsigned char :5; /* Byte 4 Bits 3-7 */ /* Multiple Host/Controller Status Bits */ - boolean RemoteHostSystemDead:1; /* Byte 5 Bit 0 */ - boolean RemoteControllerDead:1; /* Byte 5 Bit 1 */ + bool RemoteHostSystemDead:1; /* Byte 5 Bit 0 */ + bool RemoteControllerDead:1; /* Byte 5 Bit 1 */ unsigned char :6; /* Byte 5 Bits 2-7 */ DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState; /* Byte 6 */ unsigned char NegotiatedDataWidthBits; /* Byte 7 */ @@ -1464,12 +1457,12 @@ typedef struct DAC960_V2_PhysicalDeviceInfo unsigned char NetworkAddress[16]; /* Bytes 16-31 */ unsigned short MaximumTags; /* Bytes 32-33 */ /* Physical Device Operations Status */ - boolean ConsistencyCheckInProgress:1; /* Byte 34 Bit 0 */ - boolean RebuildInProgress:1; /* Byte 34 Bit 1 */ - boolean MakingDataConsistentInProgress:1; /* Byte 34 Bit 2 */ - boolean PhysicalDeviceInitializationInProgress:1; /* Byte 34 Bit 3 */ - boolean DataMigrationInProgress:1; /* Byte 34 Bit 4 */ - boolean PatrolOperationInProgress:1; /* Byte 34 Bit 5 */ + bool ConsistencyCheckInProgress:1; /* Byte 34 Bit 0 */ + bool RebuildInProgress:1; /* Byte 34 Bit 1 */ + bool MakingDataConsistentInProgress:1; /* Byte 34 Bit 2 */ + bool PhysicalDeviceInitializationInProgress:1; /* Byte 34 Bit 3 */ + bool DataMigrationInProgress:1; /* Byte 34 Bit 4 */ + bool PatrolOperationInProgress:1; /* Byte 34 Bit 5 */ unsigned char :2; /* Byte 34 Bits 6-7 */ unsigned char LongOperationStatus; /* Byte 35 */ unsigned char ParityErrors; /* Byte 36 */ @@ -1555,14 +1548,14 @@ DAC960_V2_Event_T; typedef struct DAC960_V2_CommandControlBits { - boolean ForceUnitAccess:1; /* Byte 0 Bit 0 */ - boolean DisablePageOut:1; /* Byte 0 Bit 1 */ - boolean :1; /* Byte 0 Bit 2 */ - boolean AdditionalScatterGatherListMemory:1; /* Byte 0 Bit 3 */ - boolean DataTransferControllerToHost:1; /* Byte 0 Bit 4 */ - boolean :1; /* Byte 0 Bit 5 */ - boolean NoAutoRequestSense:1; /* Byte 0 Bit 6 */ - boolean DisconnectProhibited:1; /* Byte 0 Bit 7 */ + bool ForceUnitAccess:1; /* Byte 0 Bit 0 */ + bool DisablePageOut:1; /* Byte 0 Bit 1 */ + bool :1; /* Byte 0 Bit 2 */ + bool AdditionalScatterGatherListMemory:1; /* Byte 0 Bit 3 */ + bool DataTransferControllerToHost:1; /* Byte 0 Bit 4 */ + bool :1; /* Byte 0 Bit 5 */ + bool NoAutoRequestSense:1; /* Byte 0 Bit 6 */ + bool DisconnectProhibited:1; /* Byte 0 Bit 7 */ } DAC960_V2_CommandControlBits_T; @@ -1825,8 +1818,8 @@ typedef union DAC960_V2_CommandMailbox DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */ unsigned char RequestSenseSize; /* Byte 20 */ unsigned char IOCTL_Opcode; /* Byte 21 */ - boolean RestoreConsistency:1; /* Byte 22 Bit 0 */ - boolean InitializedAreaOnly:1; /* Byte 22 Bit 1 */ + bool RestoreConsistency:1; /* Byte 22 Bit 0 */ + bool InitializedAreaOnly:1; /* Byte 22 Bit 1 */ unsigned char :6; /* Byte 22 Bits 2-7 */ unsigned char Reserved[9]; /* Bytes 23-31 */ DAC960_V2_DataTransferMemoryAddress_T @@ -2190,7 +2183,7 @@ typedef union DAC960_V1_StatusMailbox struct { DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 0 */ unsigned char :7; /* Byte 1 Bits 0-6 */ - boolean Valid:1; /* Byte 1 Bit 7 */ + bool Valid:1; /* Byte 1 Bit 7 */ DAC960_V1_CommandStatus_T CommandStatus; /* Bytes 2-3 */ } Fields; } @@ -2322,12 +2315,12 @@ typedef struct DAC960_Controller unsigned long ShutdownMonitoringTimer; unsigned long LastProgressReportTime; unsigned long LastCurrentStatusTime; - boolean ControllerInitialized; - boolean MonitoringCommandDeferred; - boolean EphemeralProgressMessage; - boolean DriveSpinUpMessageDisplayed; - boolean MonitoringAlertMode; - boolean SuppressEnclosureMessages; + bool ControllerInitialized; + bool MonitoringCommandDeferred; + bool EphemeralProgressMessage; + bool DriveSpinUpMessageDisplayed; + bool MonitoringAlertMode; + bool SuppressEnclosureMessages; struct timer_list MonitoringTimer; struct gendisk *disks[DAC960_MaxLogicalDrives]; struct pci_pool *ScatterGatherPool; @@ -2342,11 +2335,11 @@ typedef struct DAC960_Controller DAC960_Command_T InitialCommand; DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth]; struct proc_dir_entry *ControllerProcEntry; - boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives]; + bool LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives]; void (*QueueCommand)(DAC960_Command_T *Command); - boolean (*ReadControllerConfiguration)(struct DAC960_Controller *); - boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *); - boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *); + bool (*ReadControllerConfiguration)(struct DAC960_Controller *); + bool (*ReadDeviceConfiguration)(struct DAC960_Controller *); + bool (*ReportDeviceConfiguration)(struct DAC960_Controller *); void (*QueueReadWriteCommand)(DAC960_Command_T *Command); union { struct { @@ -2359,21 +2352,21 @@ typedef struct DAC960_Controller unsigned short OldEventLogSequenceNumber; unsigned short DeviceStateChannel; unsigned short DeviceStateTargetID; - boolean DualModeMemoryMailboxInterface; - boolean BackgroundInitializationStatusSupported; - boolean SAFTE_EnclosureManagementEnabled; - boolean NeedLogicalDriveInformation; - boolean NeedErrorTableInformation; - boolean NeedDeviceStateInformation; - boolean NeedDeviceInquiryInformation; - boolean NeedDeviceSerialNumberInformation; - boolean NeedRebuildProgress; - boolean NeedConsistencyCheckProgress; - boolean NeedBackgroundInitializationStatus; - boolean StartDeviceStateScan; - boolean RebuildProgressFirst; - boolean RebuildFlagPending; - boolean RebuildStatusPending; + bool DualModeMemoryMailboxInterface; + bool BackgroundInitializationStatusSupported; + bool SAFTE_EnclosureManagementEnabled; + bool NeedLogicalDriveInformation; + bool NeedErrorTableInformation; + bool NeedDeviceStateInformation; + bool NeedDeviceInquiryInformation; + bool NeedDeviceSerialNumberInformation; + bool NeedRebuildProgress; + bool NeedConsistencyCheckProgress; + bool NeedBackgroundInitializationStatus; + bool StartDeviceStateScan; + bool RebuildProgressFirst; + bool RebuildFlagPending; + bool RebuildStatusPending; dma_addr_t FirstCommandMailboxDMA; DAC960_V1_CommandMailbox_T *FirstCommandMailbox; @@ -2432,17 +2425,17 @@ typedef struct DAC960_Controller dma_addr_t NewInquiryUnitSerialNumberDMA; int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; - boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; + bool DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets]; } V1; struct { unsigned int StatusChangeCounter; unsigned int NextEventSequenceNumber; unsigned int PhysicalDeviceIndex; - boolean NeedLogicalDeviceInformation; - boolean NeedPhysicalDeviceInformation; - boolean NeedDeviceSerialNumberInformation; - boolean StartLogicalDeviceInformationScan; - boolean StartPhysicalDeviceInformationScan; + bool NeedLogicalDeviceInformation; + bool NeedPhysicalDeviceInformation; + bool NeedDeviceSerialNumberInformation; + bool StartLogicalDeviceInformationScan; + bool StartPhysicalDeviceInformationScan; struct pci_pool *RequestSensePool; dma_addr_t FirstCommandMailboxDMA; @@ -2487,7 +2480,7 @@ typedef struct DAC960_Controller DAC960_V2_PhysicalDevice_T LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives]; - boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives]; + bool LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives]; } V2; } FW; unsigned char ProgressBuffer[DAC960_ProgressBufferSize]; @@ -2572,17 +2565,17 @@ typedef union DAC960_GEM_InboundDoorBellRegister unsigned int All; struct { unsigned int :24; - boolean HardwareMailboxNewCommand:1; - boolean AcknowledgeHardwareMailboxStatus:1; - boolean GenerateInterrupt:1; - boolean ControllerReset:1; - boolean MemoryMailboxNewCommand:1; + bool HardwareMailboxNewCommand:1; + bool AcknowledgeHardwareMailboxStatus:1; + bool GenerateInterrupt:1; + bool ControllerReset:1; + bool MemoryMailboxNewCommand:1; unsigned int :3; } Write; struct { unsigned int :24; - boolean HardwareMailboxFull:1; - boolean InitializationInProgress:1; + bool HardwareMailboxFull:1; + bool InitializationInProgress:1; unsigned int :6; } Read; } @@ -2596,14 +2589,14 @@ typedef union DAC960_GEM_OutboundDoorBellRegister unsigned int All; struct { unsigned int :24; - boolean AcknowledgeHardwareMailboxInterrupt:1; - boolean AcknowledgeMemoryMailboxInterrupt:1; + bool AcknowledgeHardwareMailboxInterrupt:1; + bool AcknowledgeMemoryMailboxInterrupt:1; unsigned int :6; } Write; struct { unsigned int :24; - boolean HardwareMailboxStatusAvailable:1; - boolean MemoryMailboxStatusAvailable:1; + bool HardwareMailboxStatusAvailable:1; + bool MemoryMailboxStatusAvailable:1; unsigned int :6; } Read; } @@ -2635,7 +2628,7 @@ typedef union DAC960_GEM_ErrorStatusRegister struct { unsigned int :24; unsigned int :5; - boolean ErrorStatusPending:1; + bool ErrorStatusPending:1; unsigned int :2; } Bits; } @@ -2697,7 +2690,7 @@ void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -2707,7 +2700,7 @@ boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -2748,7 +2741,7 @@ void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -2758,7 +2751,7 @@ boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseA } static inline -boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -2790,7 +2783,7 @@ void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; InterruptMaskRegister.All = @@ -2834,7 +2827,7 @@ DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2); } -static inline boolean +static inline bool DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, @@ -2882,16 +2875,16 @@ typedef union DAC960_BA_InboundDoorBellRegister { unsigned char All; struct { - boolean HardwareMailboxNewCommand:1; /* Bit 0 */ - boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - boolean GenerateInterrupt:1; /* Bit 2 */ - boolean ControllerReset:1; /* Bit 3 */ - boolean MemoryMailboxNewCommand:1; /* Bit 4 */ + bool HardwareMailboxNewCommand:1; /* Bit 0 */ + bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ + bool GenerateInterrupt:1; /* Bit 2 */ + bool ControllerReset:1; /* Bit 3 */ + bool MemoryMailboxNewCommand:1; /* Bit 4 */ unsigned char :3; /* Bits 5-7 */ } Write; struct { - boolean HardwareMailboxEmpty:1; /* Bit 0 */ - boolean InitializationNotInProgress:1; /* Bit 1 */ + bool HardwareMailboxEmpty:1; /* Bit 0 */ + bool InitializationNotInProgress:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -2906,13 +2899,13 @@ typedef union DAC960_BA_OutboundDoorBellRegister { unsigned char All; struct { - boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ + bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ + bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Write; struct { - boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */ - boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */ + bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ + bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -2928,8 +2921,8 @@ typedef union DAC960_BA_InterruptMaskRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean DisableInterrupts:1; /* Bit 2 */ - boolean DisableInterruptsI2O:1; /* Bit 3 */ + bool DisableInterrupts:1; /* Bit 2 */ + bool DisableInterruptsI2O:1; /* Bit 3 */ unsigned int :4; /* Bits 4-7 */ } Bits; } @@ -2945,7 +2938,7 @@ typedef union DAC960_BA_ErrorStatusRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean ErrorStatusPending:1; /* Bit 2 */ + bool ErrorStatusPending:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -3008,7 +3001,7 @@ void DAC960_BA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3017,7 +3010,7 @@ boolean DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3057,7 +3050,7 @@ void DAC960_BA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3066,7 +3059,7 @@ boolean DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd } static inline -boolean DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3097,7 +3090,7 @@ void DAC960_BA_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister; InterruptMaskRegister.All = @@ -3140,7 +3133,7 @@ DAC960_BA_ReadCommandStatus(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2); } -static inline boolean +static inline bool DAC960_BA_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, @@ -3188,16 +3181,16 @@ typedef union DAC960_LP_InboundDoorBellRegister { unsigned char All; struct { - boolean HardwareMailboxNewCommand:1; /* Bit 0 */ - boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - boolean GenerateInterrupt:1; /* Bit 2 */ - boolean ControllerReset:1; /* Bit 3 */ - boolean MemoryMailboxNewCommand:1; /* Bit 4 */ + bool HardwareMailboxNewCommand:1; /* Bit 0 */ + bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ + bool GenerateInterrupt:1; /* Bit 2 */ + bool ControllerReset:1; /* Bit 3 */ + bool MemoryMailboxNewCommand:1; /* Bit 4 */ unsigned char :3; /* Bits 5-7 */ } Write; struct { - boolean HardwareMailboxFull:1; /* Bit 0 */ - boolean InitializationInProgress:1; /* Bit 1 */ + bool HardwareMailboxFull:1; /* Bit 0 */ + bool InitializationInProgress:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -3212,13 +3205,13 @@ typedef union DAC960_LP_OutboundDoorBellRegister { unsigned char All; struct { - boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ + bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ + bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Write; struct { - boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */ - boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */ + bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ + bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -3234,7 +3227,7 @@ typedef union DAC960_LP_InterruptMaskRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean DisableInterrupts:1; /* Bit 2 */ + bool DisableInterrupts:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -3250,7 +3243,7 @@ typedef union DAC960_LP_ErrorStatusRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean ErrorStatusPending:1; /* Bit 2 */ + bool ErrorStatusPending:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -3313,7 +3306,7 @@ void DAC960_LP_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3322,7 +3315,7 @@ boolean DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3362,7 +3355,7 @@ void DAC960_LP_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3371,7 +3364,7 @@ boolean DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd } static inline -boolean DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3400,7 +3393,7 @@ void DAC960_LP_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister; InterruptMaskRegister.All = @@ -3442,7 +3435,7 @@ DAC960_LP_ReadCommandStatus(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2); } -static inline boolean +static inline bool DAC960_LP_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, @@ -3502,16 +3495,16 @@ typedef union DAC960_LA_InboundDoorBellRegister { unsigned char All; struct { - boolean HardwareMailboxNewCommand:1; /* Bit 0 */ - boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - boolean GenerateInterrupt:1; /* Bit 2 */ - boolean ControllerReset:1; /* Bit 3 */ - boolean MemoryMailboxNewCommand:1; /* Bit 4 */ + bool HardwareMailboxNewCommand:1; /* Bit 0 */ + bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ + bool GenerateInterrupt:1; /* Bit 2 */ + bool ControllerReset:1; /* Bit 3 */ + bool MemoryMailboxNewCommand:1; /* Bit 4 */ unsigned char :3; /* Bits 5-7 */ } Write; struct { - boolean HardwareMailboxEmpty:1; /* Bit 0 */ - boolean InitializationNotInProgress:1; /* Bit 1 */ + bool HardwareMailboxEmpty:1; /* Bit 0 */ + bool InitializationNotInProgress:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -3526,13 +3519,13 @@ typedef union DAC960_LA_OutboundDoorBellRegister { unsigned char All; struct { - boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ + bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ + bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Write; struct { - boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */ - boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */ + bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ + bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -3548,7 +3541,7 @@ typedef union DAC960_LA_InterruptMaskRegister unsigned char All; struct { unsigned char :2; /* Bits 0-1 */ - boolean DisableInterrupts:1; /* Bit 2 */ + bool DisableInterrupts:1; /* Bit 2 */ unsigned char :5; /* Bits 3-7 */ } Bits; } @@ -3564,7 +3557,7 @@ typedef union DAC960_LA_ErrorStatusRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean ErrorStatusPending:1; /* Bit 2 */ + bool ErrorStatusPending:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -3627,7 +3620,7 @@ void DAC960_LA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3636,7 +3629,7 @@ boolean DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3676,7 +3669,7 @@ void DAC960_LA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3685,7 +3678,7 @@ boolean DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd } static inline -boolean DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -3714,7 +3707,7 @@ void DAC960_LA_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister; InterruptMaskRegister.All = @@ -3763,7 +3756,7 @@ DAC960_LA_ReadStatusRegister(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset); } -static inline boolean +static inline bool DAC960_LA_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, @@ -3822,16 +3815,16 @@ typedef union DAC960_PG_InboundDoorBellRegister { unsigned int All; struct { - boolean HardwareMailboxNewCommand:1; /* Bit 0 */ - boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ - boolean GenerateInterrupt:1; /* Bit 2 */ - boolean ControllerReset:1; /* Bit 3 */ - boolean MemoryMailboxNewCommand:1; /* Bit 4 */ + bool HardwareMailboxNewCommand:1; /* Bit 0 */ + bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */ + bool GenerateInterrupt:1; /* Bit 2 */ + bool ControllerReset:1; /* Bit 3 */ + bool MemoryMailboxNewCommand:1; /* Bit 4 */ unsigned int :27; /* Bits 5-31 */ } Write; struct { - boolean HardwareMailboxFull:1; /* Bit 0 */ - boolean InitializationInProgress:1; /* Bit 1 */ + bool HardwareMailboxFull:1; /* Bit 0 */ + bool InitializationInProgress:1; /* Bit 1 */ unsigned int :30; /* Bits 2-31 */ } Read; } @@ -3846,13 +3839,13 @@ typedef union DAC960_PG_OutboundDoorBellRegister { unsigned int All; struct { - boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ - boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ + bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */ + bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */ unsigned int :30; /* Bits 2-31 */ } Write; struct { - boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */ - boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */ + bool HardwareMailboxStatusAvailable:1; /* Bit 0 */ + bool MemoryMailboxStatusAvailable:1; /* Bit 1 */ unsigned int :30; /* Bits 2-31 */ } Read; } @@ -3868,7 +3861,7 @@ typedef union DAC960_PG_InterruptMaskRegister unsigned int All; struct { unsigned int MessageUnitInterruptMask1:2; /* Bits 0-1 */ - boolean DisableInterrupts:1; /* Bit 2 */ + bool DisableInterrupts:1; /* Bit 2 */ unsigned int MessageUnitInterruptMask2:5; /* Bits 3-7 */ unsigned int Reserved0:24; /* Bits 8-31 */ } Bits; @@ -3885,7 +3878,7 @@ typedef union DAC960_PG_ErrorStatusRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean ErrorStatusPending:1; /* Bit 2 */ + bool ErrorStatusPending:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -3948,7 +3941,7 @@ void DAC960_PG_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3957,7 +3950,7 @@ boolean DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -3997,7 +3990,7 @@ void DAC960_PG_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -4006,7 +3999,7 @@ boolean DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd } static inline -boolean DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -4039,7 +4032,7 @@ void DAC960_PG_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister; InterruptMaskRegister.All = @@ -4088,7 +4081,7 @@ DAC960_PG_ReadStatusRegister(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset); } -static inline boolean +static inline bool DAC960_PG_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, @@ -4147,15 +4140,15 @@ typedef union DAC960_PD_InboundDoorBellRegister { unsigned char All; struct { - boolean NewCommand:1; /* Bit 0 */ - boolean AcknowledgeStatus:1; /* Bit 1 */ - boolean GenerateInterrupt:1; /* Bit 2 */ - boolean ControllerReset:1; /* Bit 3 */ + bool NewCommand:1; /* Bit 0 */ + bool AcknowledgeStatus:1; /* Bit 1 */ + bool GenerateInterrupt:1; /* Bit 2 */ + bool ControllerReset:1; /* Bit 3 */ unsigned char :4; /* Bits 4-7 */ } Write; struct { - boolean MailboxFull:1; /* Bit 0 */ - boolean InitializationInProgress:1; /* Bit 1 */ + bool MailboxFull:1; /* Bit 0 */ + bool InitializationInProgress:1; /* Bit 1 */ unsigned char :6; /* Bits 2-7 */ } Read; } @@ -4170,11 +4163,11 @@ typedef union DAC960_PD_OutboundDoorBellRegister { unsigned char All; struct { - boolean AcknowledgeInterrupt:1; /* Bit 0 */ + bool AcknowledgeInterrupt:1; /* Bit 0 */ unsigned char :7; /* Bits 1-7 */ } Write; struct { - boolean StatusAvailable:1; /* Bit 0 */ + bool StatusAvailable:1; /* Bit 0 */ unsigned char :7; /* Bits 1-7 */ } Read; } @@ -4189,7 +4182,7 @@ typedef union DAC960_PD_InterruptEnableRegister { unsigned char All; struct { - boolean EnableInterrupts:1; /* Bit 0 */ + bool EnableInterrupts:1; /* Bit 0 */ unsigned char :7; /* Bits 1-7 */ } Bits; } @@ -4205,7 +4198,7 @@ typedef union DAC960_PD_ErrorStatusRegister unsigned char All; struct { unsigned int :2; /* Bits 0-1 */ - boolean ErrorStatusPending:1; /* Bit 2 */ + bool ErrorStatusPending:1; /* Bit 2 */ unsigned int :5; /* Bits 3-7 */ } Bits; } @@ -4258,7 +4251,7 @@ void DAC960_PD_ControllerReset(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress) +bool DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress) { DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -4267,7 +4260,7 @@ boolean DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress) +bool DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress) { DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister; InboundDoorBellRegister.All = @@ -4286,7 +4279,7 @@ void DAC960_PD_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress) +bool DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress) { DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister; OutboundDoorBellRegister.All = @@ -4315,7 +4308,7 @@ void DAC960_PD_DisableInterrupts(void __iomem *ControllerBaseAddress) } static inline -boolean DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress) +bool DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress) { DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister; InterruptEnableRegister.All = @@ -4350,7 +4343,7 @@ DAC960_PD_ReadStatusRegister(void __iomem *ControllerBaseAddress) return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset); } -static inline boolean +static inline bool DAC960_PD_ReadErrorStatus(void __iomem *ControllerBaseAddress, unsigned char *ErrorStatus, unsigned char *Parameter0, diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 58c1debf86f..cacb1c816e3 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -417,8 +417,10 @@ config BLK_DEV_INITRD etc. See <file:Documentation/initrd.txt> for details. If RAM disk support (BLK_DEV_RAM) is also included, this - also enables initial RAM disk (initrd) support. + also enables initial RAM disk (initrd) support and adds + 15 Kbytes (more on some other architectures) to the kernel size. + If unsure say Y. config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig index c0d2854dd09..28cf3082d44 100644 --- a/drivers/block/paride/Kconfig +++ b/drivers/block/paride/Kconfig @@ -2,14 +2,8 @@ # PARIDE configuration # # PARIDE doesn't need PARPORT, but if PARPORT is configured as a module, -# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option -# controls the choices given to the user ... +# PARIDE must also be a module. # PARIDE only supports PC style parports. Tough for USB or other parports... -config PARIDE_PARPORT - tristate - depends on PARIDE!=n - default m if PARPORT_PC=m - default y if PARPORT_PC!=m comment "Parallel IDE high-level drivers" depends on PARIDE diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 62462190e07..c0e89490e3d 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -190,15 +190,6 @@ static struct attribute *kobj_pkt_attrs_wqueue[] = { NULL }; -/* declares a char buffer[64] _dbuf, copies data from - * _b with length _l into it and ensures that _dbuf ends - * with a \0 character. - */ -#define DECLARE_BUF_AS_STRING(_dbuf, _b, _l) \ - char _dbuf[64]; int dlen = (_l) < 0 ? 0 : (_l); \ - if (dlen >= sizeof(_dbuf)) dlen = sizeof(_dbuf)-1; \ - memcpy(_dbuf, _b, dlen); _dbuf[dlen] = 0 - static ssize_t kobj_pkt_show(struct kobject *kobj, struct attribute *attr, char *data) { @@ -264,9 +255,8 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, { struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd; int val; - DECLARE_BUF_AS_STRING(dbuf, data, len); /* ensure sscanf scans a string */ - if (strcmp(attr->name, "reset") == 0 && dlen > 0) { + if (strcmp(attr->name, "reset") == 0 && len > 0) { pd->stats.pkt_started = 0; pd->stats.pkt_ended = 0; pd->stats.secs_w = 0; @@ -274,7 +264,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, pd->stats.secs_r = 0; } else if (strcmp(attr->name, "congestion_off") == 0 - && sscanf(dbuf, "%d", &val) == 1) { + && sscanf(data, "%d", &val) == 1) { spin_lock(&pd->lock); pd->write_congestion_off = val; init_write_congestion_marks(&pd->write_congestion_off, @@ -282,7 +272,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, spin_unlock(&pd->lock); } else if (strcmp(attr->name, "congestion_on") == 0 - && sscanf(dbuf, "%d", &val) == 1) { + && sscanf(data, "%d", &val) == 1) { spin_lock(&pd->lock); pd->write_congestion_on = val; init_write_congestion_marks(&pd->write_congestion_off, @@ -369,8 +359,7 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, size_t count) { unsigned int major, minor; - DECLARE_BUF_AS_STRING(dbuf, buf, count); - if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) { + if (sscanf(buf, "%u:%u", &major, &minor) == 2) { pkt_setup_dev(MKDEV(major, minor), NULL); return count; } @@ -381,8 +370,7 @@ static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf, size_t count) { unsigned int major, minor; - DECLARE_BUF_AS_STRING(dbuf, buf, count); - if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) { + if (sscanf(buf, "%u:%u", &major, &minor) == 2) { pkt_remove_dev(MKDEV(major, minor)); return count; } @@ -1377,7 +1365,7 @@ try_next_bio: && pd->bio_queue_size <= pd->write_congestion_off); spin_unlock(&pd->lock); if (wakeup) - blk_clear_queue_congested(pd->disk->queue, WRITE); + clear_bdi_congested(&pd->disk->queue->backing_dev_info, WRITE); pkt->sleep_time = max(PACKET_WAIT_TIME, 1); pkt_set_state(pkt, PACKET_WAITING_STATE); @@ -2598,7 +2586,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio) spin_lock(&pd->lock); if (pd->write_congestion_on > 0 && pd->bio_queue_size >= pd->write_congestion_on) { - blk_set_queue_congested(q, WRITE); + set_bdi_congested(&q->backing_dev_info, WRITE); do { spin_unlock(&pd->lock); congestion_wait(WRITE, HZ); diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d08bb4ee130..d0a6dc53213 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -191,7 +191,7 @@ config MOXA_INTELLIO module will be called moxa. config MOXA_SMARTIO - tristate "Moxa SmartIO support" + tristate "Moxa SmartIO support (OBSOLETE)" depends on SERIAL_NONSTANDARD help Say Y here if you have a Moxa SmartIO multiport serial card. @@ -202,7 +202,7 @@ config MOXA_SMARTIO here. config MOXA_SMARTIO_NEW - tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)" + tristate "Moxa SmartIO support v. 2.0" depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) help Say Y here if you have a Moxa SmartIO multiport serial card and/or diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index feb4ac802a0..0e2b72f2b88 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -527,10 +527,8 @@ static void do_softint(unsigned long private_) if (!tty) return; - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } /* @@ -904,8 +902,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count if (!info->xmit.buf) return 0; - local_save_flags(flags); - local_irq_disable(); + local_irq_save(flags); while (1) { c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, @@ -968,7 +965,6 @@ static void rs_flush_buffer(struct tty_struct *tty) local_irq_save(flags); info->xmit.head = info->xmit.tail = 0; local_irq_restore(flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 3ffa0807754..363beb16572 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -4488,7 +4488,6 @@ static void cy_flush_buffer(struct tty_struct *tty) CY_UNLOCK(info, flags); } tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); } /* cy_flush_buffer */ /* diff --git a/drivers/char/epca.c b/drivers/char/epca.c index a0f822c9d74..88fc24fc439 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -844,7 +844,6 @@ static void pc_flush_buffer(struct tty_struct *tty) fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0); memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } /* End pc_flush_buffer */ @@ -1795,7 +1794,6 @@ static void doevent(int crd) { /* Begin if LOWWAIT */ ch->statusflags &= ~LOWWAIT; tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); } /* End if LOWWAIT */ } else if (event & EMPTYTX_IND) { /* Begin EMPTYTX_IND */ /* This event is generated by setup_empty_event */ @@ -1803,7 +1801,6 @@ static void doevent(int crd) if (ch->statusflags & EMPTYWAIT) { /* Begin if EMPTYWAIT */ ch->statusflags &= ~EMPTYWAIT; tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); } /* End if EMPTYWAIT */ } /* End EMPTYTX_IND */ } /* End if valid tty */ diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index e769811e741..337bbcdcf13 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -382,7 +382,6 @@ void gs_flush_buffer(struct tty_struct *tty) port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; spin_unlock_irqrestore (&port->driver_lock, flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); func_exit (); } diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index 78045767ec3..88b9d338da5 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c @@ -1373,15 +1373,7 @@ ip2_owake( PTTY tp) ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, (1 << TTY_DO_WRITE_WAKEUP) ); - wake_up_interruptible ( &tp->write_wait ); - if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) - && tp->ldisc.write_wakeup ) - { - (tp->ldisc.write_wakeup) ( tp ); - - ip2trace (CHANN, ITRC_SICMD, 11, 0 ); - - } + tty_wakeup(tp); } static inline void diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 53582b53da9..3aff5e99b67 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -406,13 +406,14 @@ static void clean_up_interface_data(ipmi_smi_t intf) free_smi_msg_list(&intf->waiting_msgs); free_recv_msg_list(&intf->waiting_events); - /* Wholesale remove all the entries from the list in the - * interface and wait for RCU to know that none are in use. */ + /* + * Wholesale remove all the entries from the list in the + * interface and wait for RCU to know that none are in use. + */ mutex_lock(&intf->cmd_rcvrs_mutex); - list_add_rcu(&list, &intf->cmd_rcvrs); - list_del_rcu(&intf->cmd_rcvrs); + INIT_LIST_HEAD(&list); + list_splice_init_rcu(&intf->cmd_rcvrs, &list, synchronize_rcu); mutex_unlock(&intf->cmd_rcvrs_mutex); - synchronize_rcu(); list_for_each_entry_safe(rcvr, rcvr2, &list, link) kfree(rcvr); @@ -451,7 +452,7 @@ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) mutex_lock(&ipmi_interfaces_mutex); /* Build a list of things to deliver. */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { + list_for_each_entry(intf, &ipmi_interfaces, link) { if (intf->intf_num == -1) continue; e = kmalloc(sizeof(*e), GFP_KERNEL); @@ -1886,7 +1887,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, kfree(entry); rv = -ENOMEM; } else { - file->nlink = 1; file->data = data; file->read_proc = read_proc; file->write_proc = write_proc; @@ -2760,9 +2760,15 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, synchronize_rcu(); kref_put(&intf->refcount, intf_free); } else { - /* After this point the interface is legal to use. */ + /* + * Keep memory order straight for RCU readers. Make + * sure everything else is committed to memory before + * setting intf_num to mark the interface valid. + */ + smp_wmb(); intf->intf_num = i; mutex_unlock(&ipmi_interfaces_mutex); + /* After this point the interface is legal to use. */ call_smi_watchers(i, intf->si_dev); mutex_unlock(&smi_watchers_mutex); } @@ -3923,6 +3929,14 @@ static void send_panic_events(char *str) /* Interface was not ready yet. */ continue; + /* + * intf_num is used as an marker to tell if the + * interface is valid. Thus we need a read barrier to + * make sure data fetched before checking intf_num + * won't be used. + */ + smp_rmb(); + /* First job here is to figure out where to send the OEM events. There's no way in IPMI to send OEM events using an event send command, so we have to diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 01084abffdd..43ab9edc76f 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -183,7 +183,7 @@ static DEFINE_TIMER(tx, isicom_tx, 0, 0); /* baud index mappings from linux defns to isi */ static signed char linuxb_to_isib[] = { - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21 }; struct isi_board { @@ -213,8 +213,6 @@ struct isi_port { struct tty_struct * tty; wait_queue_head_t close_wait; wait_queue_head_t open_wait; - struct work_struct hangup_tq; - struct work_struct bh_tqueue; unsigned char * xmit_buf; int xmit_head; int xmit_tail; @@ -510,7 +508,7 @@ static void isicom_tx(unsigned long _data) if (port->xmit_cnt <= 0) port->status &= ~ISI_TXOK; if (port->xmit_cnt <= WAKEUP_CHARS) - schedule_work(&port->bh_tqueue); + tty_wakeup(tty); unlock_card(&isi_card[card]); } @@ -524,21 +522,6 @@ sched_again: mod_timer(&tx, jiffies + msecs_to_jiffies(10)); } -/* Interrupt handlers */ - - -static void isicom_bottomhalf(struct work_struct *work) -{ - struct isi_port *port = container_of(work, struct isi_port, bh_tqueue); - struct tty_struct *tty = port->tty; - - if (!tty) - return; - - tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -} - /* * Main interrupt handler routine */ @@ -557,6 +540,11 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) return IRQ_NONE; base = card->base; + + /* did the card interrupt us? */ + if (!(inw(base + 0x0e) & 0x02)) + return IRQ_NONE; + spin_lock(&card->card_lock); /* @@ -581,6 +569,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) port = card->ports + channel; if (!(port->flags & ASYNC_INITIALIZED)) { outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); return IRQ_HANDLED; } @@ -609,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) pr_dbg("interrupt: DCD->low.\n" ); port->status &= ~ISI_DCD; - schedule_work(&port->hangup_tq); + tty_hangup(tty); } } else if (header & ISI_DCD) { /* Carrier has been detected */ @@ -631,7 +620,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) /* start tx ing */ port->status |= (ISI_TXOK | ISI_CTS); - schedule_work(&port->bh_tqueue); + tty_wakeup(tty); } } else if (!(header & ISI_CTS)) { port->tty->hw_stopped = 1; @@ -695,6 +684,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) tty_flip_buffer_push(tty); } outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); return IRQ_HANDLED; } @@ -720,7 +710,8 @@ static void isicom_config_port(struct isi_port *port) * respectively. */ - if (baud < 1 || baud > 2) + /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ + if (baud < 1 || baud > 4) port->tty->termios->c_cflag &= ~CBAUDEX; else baud += 15; @@ -736,6 +727,10 @@ static void isicom_config_port(struct isi_port *port) baud++; /* 57.6 Kbps */ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) baud +=2; /* 115 Kbps */ + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + baud += 3; /* 230 kbps*/ + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + baud += 4; /* 460 kbps*/ } if (linuxb_to_isib[baud] == -1) { /* hang up */ @@ -1460,17 +1455,6 @@ static void isicom_start(struct tty_struct *tty) port->status |= ISI_TXOK; } -/* hangup et all */ -static void do_isicom_hangup(struct work_struct *work) -{ - struct isi_port *port = container_of(work, struct isi_port, hangup_tq); - struct tty_struct *tty; - - tty = port->tty; - if (tty) - tty_hangup(tty); -} - static void isicom_hangup(struct tty_struct *tty) { struct isi_port *port = tty->driver_data; @@ -1503,7 +1487,6 @@ static void isicom_flush_buffer(struct tty_struct *tty) port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; spin_unlock_irqrestore(&card->card_lock, flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } @@ -1536,7 +1519,7 @@ static int __devinit reset_card(struct pci_dev *pdev, { struct isi_board *board = pci_get_drvdata(pdev); unsigned long base = board->base; - unsigned int portcount = 0; + unsigned int sig, portcount = 0; int retval = 0; dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1, @@ -1544,27 +1527,35 @@ static int __devinit reset_card(struct pci_dev *pdev, inw(base + 0x8); - mdelay(10); + msleep(10); outw(0, base + 0x8); /* Reset */ - msleep(3000); + msleep(1000); - *signature = inw(base + 0x4) & 0xff; + sig = inw(base + 0x4) & 0xff; + + if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd && + sig != 0xee) { + dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible " + "bad I/O Port Address 0x%lx).\n", card + 1, base); + dev_dbg(&pdev->dev, "Sig=0x%x\n", sig); + retval = -EIO; + goto end; + } + + msleep(10); portcount = inw(base + 0x2); - if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) && - (portcount != 4) && (portcount != 8))) { - dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", - inw(base + 0x2), inw(base + 0xe)); - dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure " - "(Possible bad I/O Port Address 0x%lx).\n", - card + 1, base); + if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && + portcount != 8 && portcount != 16)) { + dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.", + card + 1); retval = -EIO; goto end; } - switch (*signature) { + switch (sig) { case 0xa5: case 0xbb: case 0xdd: @@ -1572,16 +1563,13 @@ static int __devinit reset_card(struct pci_dev *pdev, board->shift_count = 12; break; case 0xcc: + case 0xee: board->port_count = 16; board->shift_count = 11; break; - default: - dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible " - "bad I/O Port Address 0x%lx).\n", card + 1, base); - dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature); - retval = -EIO; } dev_info(&pdev->dev, "-Done\n"); + *signature = sig; end: return retval; @@ -1757,7 +1745,7 @@ end: /* * Insmod can set static symbols so keep these static */ -static int card; +static unsigned int card_count; static int __devinit isicom_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1767,7 +1755,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, u8 pciirq; struct isi_board *board = NULL; - if (card >= BOARD_COUNT) + if (card_count >= BOARD_COUNT) goto err; ioaddr = pci_resource_start(pdev, 3); @@ -1785,7 +1773,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, board->index = index; board->base = ioaddr; board->irq = pciirq; - card++; + card_count++; pci_set_drvdata(pdev, board); @@ -1795,7 +1783,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, "will be disabled.\n", board->base, board->base + 15, index + 1); retval = -EBUSY; - goto err; + goto errdec; } retval = request_irq(board->irq, isicom_interrupt, @@ -1824,8 +1812,10 @@ errunri: free_irq(board->irq, board); errunrr: pci_release_region(pdev, 3); -err: +errdec: board->base = 0; + card_count--; +err: return retval; } @@ -1839,6 +1829,8 @@ static void __devexit isicom_remove(struct pci_dev *pdev) free_irq(board->irq, board); pci_release_region(pdev, 3); + board->base = 0; + card_count--; } static int __init isicom_init(void) @@ -1846,8 +1838,6 @@ static int __init isicom_init(void) int retval, idx, channel; struct isi_port *port; - card = 0; - for(idx = 0; idx < BOARD_COUNT; idx++) { port = &isi_ports[idx * 16]; isi_card[idx].ports = port; @@ -1858,8 +1848,6 @@ static int __init isicom_init(void) port->channel = channel; port->close_delay = 50 * HZ/100; port->closing_wait = 3000 * HZ/100; - INIT_WORK(&port->hangup_tq, do_isicom_hangup); - INIT_WORK(&port->bh_tqueue, isicom_bottomhalf); port->status = 0; init_waitqueue_head(&port->open_wait); init_waitqueue_head(&port->close_wait); diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 68645d35187..7b279d1de4a 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -2424,7 +2424,6 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) if (tty != NULL) { tty_wakeup(tty); EBRDENABLE(brdp); - wake_up_interruptible(&tty->write_wait); } } diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7a6c1c0b7a9..c654a3e0c69 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -595,15 +595,9 @@ static void fn_spawn_con(struct vc_data *vc) static void fn_SAK(struct vc_data *vc) { - struct tty_struct *tty = vc->vc_tty; - - /* - * SAK should also work in all raw modes and reset - * them properly. - */ - if (tty) - do_SAK(tty); - reset_vc(vc); + struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; + PREPARE_WORK(SAK_work, vc_SAK); + schedule_work(SAK_work); } static void fn_null(struct vc_data *vc) diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index f391a24a1b4..7dbaee8d940 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -11,15 +11,6 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -55,36 +46,20 @@ #include <asm/io.h> #include <asm/uaccess.h> -#define MOXA_VERSION "5.1k" +#define MOXA_VERSION "5.1k" -#define MOXAMAJOR 172 -#define MOXACUMAJOR 173 +#define MOXAMAJOR 172 +#define MOXACUMAJOR 173 -#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2) -#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2) - -#define MAX_BOARDS 4 /* Don't change this value */ +#define MAX_BOARDS 4 /* Don't change this value */ #define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ -#define MAX_PORTS 128 /* Don't change this value */ +#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD) /* * Define the Moxa PCI vendor and device IDs. */ -#define MOXA_BUS_TYPE_ISA 0 -#define MOXA_BUS_TYPE_PCI 1 - -#ifndef PCI_VENDOR_ID_MOXA -#define PCI_VENDOR_ID_MOXA 0x1393 -#endif -#ifndef PCI_DEVICE_ID_CP204J -#define PCI_DEVICE_ID_CP204J 0x2040 -#endif -#ifndef PCI_DEVICE_ID_C218 -#define PCI_DEVICE_ID_C218 0x2180 -#endif -#ifndef PCI_DEVICE_ID_C320 -#define PCI_DEVICE_ID_C320 0x3200 -#endif +#define MOXA_BUS_TYPE_ISA 0 +#define MOXA_BUS_TYPE_PCI 1 enum { MOXA_BOARD_C218_PCI = 1, @@ -105,47 +80,56 @@ static char *moxa_brdname[] = #ifdef CONFIG_PCI static struct pci_device_id moxa_pcibrds[] = { - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, MOXA_BOARD_C218_PCI }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, MOXA_BOARD_C320_PCI }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID, - 0, 0, MOXA_BOARD_CP204J }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218), + .driver_data = MOXA_BOARD_C218_PCI }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320), + .driver_data = MOXA_BOARD_C320_PCI }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J), + .driver_data = MOXA_BOARD_CP204J }, { 0 } }; MODULE_DEVICE_TABLE(pci, moxa_pcibrds); #endif /* CONFIG_PCI */ -typedef struct _moxa_isa_board_conf { +struct moxa_isa_board_conf { int boardType; int numPorts; unsigned long baseAddr; -} moxa_isa_board_conf; +}; -static moxa_isa_board_conf moxa_isa_boards[] = +static struct moxa_isa_board_conf moxa_isa_boards[] = { /* {MOXA_BOARD_C218_ISA,8,0xDC000}, */ }; -typedef struct _moxa_pci_devinfo { - ushort busNum; - ushort devNum; - struct pci_dev *pdev; -} moxa_pci_devinfo; - -typedef struct _moxa_board_conf { +static struct moxa_board_conf { int boardType; int numPorts; unsigned long baseAddr; int busType; - moxa_pci_devinfo pciInfo; -} moxa_board_conf; -static moxa_board_conf moxa_boards[MAX_BOARDS]; -static void __iomem *moxaBaseAddr[MAX_BOARDS]; -static int loadstat[MAX_BOARDS]; + int loadstat; + + void __iomem *basemem; + void __iomem *intNdx; + void __iomem *intPend; + void __iomem *intTable; +} moxa_boards[MAX_BOARDS]; + +struct mxser_mstatus { + tcflag_t cflag; + int cts; + int dsr; + int ri; + int dcd; +}; + +struct moxaq_str { + int inq; + int outq; +}; -struct moxa_str { +struct moxa_port { int type; int port; int close_delay; @@ -159,18 +143,18 @@ struct moxa_str { int cflag; wait_queue_head_t open_wait; wait_queue_head_t close_wait; - struct work_struct tqueue; -}; -struct mxser_mstatus { - tcflag_t cflag; - int cts; - int dsr; - int ri; - int dcd; -}; + struct timer_list emptyTimer; -static struct mxser_mstatus GMStatus[MAX_PORTS]; + char chkPort; + char lineCtrl; + void __iomem *tableAddr; + long curBaud; + char DCDState; + char lowChkFlag; + + ushort breakCnt; +}; /* statusflags */ #define TXSTOPPED 0x1 @@ -178,25 +162,17 @@ static struct mxser_mstatus GMStatus[MAX_PORTS]; #define EMPTYWAIT 0x4 #define THROTTLE 0x8 -/* event */ -#define MOXA_EVENT_HANGUP 1 - #define SERIAL_DO_RESTART - -#define SERIAL_TYPE_NORMAL 1 - #define WAKEUP_CHARS 256 -#define PORTNO(x) ((x)->index) - static int verbose = 0; static int ttymajor = MOXAMAJOR; /* Variables for insmod */ #ifdef MODULE -static int baseaddr[] = {0, 0, 0, 0}; -static int type[] = {0, 0, 0, 0}; -static int numports[] = {0, 0, 0, 0}; +static int baseaddr[4]; +static int type[4]; +static int numports[4]; #endif MODULE_AUTHOR("William Chen"); @@ -210,19 +186,9 @@ module_param_array(numports, int, NULL, 0); module_param(ttymajor, int, 0); module_param(verbose, bool, 0644); -static struct tty_driver *moxaDriver; -static struct moxa_str moxaChannels[MAX_PORTS]; -static unsigned char *moxaXmitBuff; -static int moxaTimer_on; -static struct timer_list moxaTimer; -static int moxaEmptyTimer_on[MAX_PORTS]; -static struct timer_list moxaEmptyTimer[MAX_PORTS]; -static struct semaphore moxaBuffSem; - /* * static functions: */ -static void do_moxa_softint(struct work_struct *); static int moxa_open(struct tty_struct *, struct file *); static void moxa_close(struct tty_struct *, struct file *); static int moxa_write(struct tty_struct *, const unsigned char *, int); @@ -244,11 +210,11 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, static void moxa_poll(unsigned long); static void set_tty_param(struct tty_struct *); static int block_till_ready(struct tty_struct *, struct file *, - struct moxa_str *); + struct moxa_port *); static void setup_empty_event(struct tty_struct *); static void check_xmit_empty(unsigned long); -static void shut_down(struct moxa_str *); -static void receive_data(struct moxa_str *); +static void shut_down(struct moxa_port *); +static void receive_data(struct moxa_port *); /* * moxa board interface functions: */ @@ -278,8 +244,8 @@ static void MoxaPortTxDisable(int); static void MoxaPortTxEnable(int); static int MoxaPortResetBrkCnt(int); static void MoxaPortSendBreak(int, int); -static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *); -static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *); +static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); +static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); static void MoxaSetFifo(int port, int enable); static const struct tty_operations moxa_ops = { @@ -302,12 +268,41 @@ static const struct tty_operations moxa_ops = { .tiocmset = moxa_tiocmset, }; +static struct tty_driver *moxaDriver; +static struct moxa_port moxa_ports[MAX_PORTS]; +static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); static DEFINE_SPINLOCK(moxa_lock); #ifdef CONFIG_PCI -static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) +static int __devinit moxa_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { - board->baseAddr = pci_resource_start (p, 2); + struct moxa_board_conf *board; + unsigned int i; + int board_type = ent->driver_data; + int retval; + + retval = pci_enable_device(pdev); + if (retval) + goto err; + + for (i = 0; i < MAX_BOARDS; i++) + if (moxa_boards[i].basemem == NULL) + break; + + retval = -ENODEV; + if (i >= MAX_BOARDS) { + if (verbose) + printk("More than %d MOXA Intellio family boards " + "found. Board is ignored.\n", MAX_BOARDS); + goto err; + } + + board = &moxa_boards[i]; + board->basemem = pci_iomap(pdev, 2, 0x4000); + if (board->basemem == NULL) + goto err; + board->boardType = board_type; switch (board_type) { case MOXA_BOARD_C218_ISA: @@ -323,27 +318,40 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf break; } board->busType = MOXA_BUS_TYPE_PCI; - board->pciInfo.busNum = p->bus->number; - board->pciInfo.devNum = p->devfn >> 3; - board->pciInfo.pdev = p; - /* don't lose the reference in the next pci_get_device iteration */ - pci_dev_get(p); + + pci_set_drvdata(pdev, board); return (0); +err: + return retval; } + +static void __devexit moxa_pci_remove(struct pci_dev *pdev) +{ + struct moxa_board_conf *brd = pci_get_drvdata(pdev); + + pci_iounmap(pdev, brd->basemem); + brd->basemem = NULL; +} + +static struct pci_driver moxa_pci_driver = { + .name = "moxa", + .id_table = moxa_pcibrds, + .probe = moxa_pci_probe, + .remove = __devexit_p(moxa_pci_remove) +}; #endif /* CONFIG_PCI */ static int __init moxa_init(void) { - int i, numBoards; - struct moxa_str *ch; + int i, numBoards, retval = 0; + struct moxa_port *ch; printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); moxaDriver = alloc_tty_driver(MAX_PORTS + 1); if (!moxaDriver) return -ENOMEM; - init_MUTEX(&moxaBuffSem); moxaDriver->owner = THIS_MODULE; moxaDriver->name = "ttyMX"; moxaDriver->major = ttymajor; @@ -351,40 +359,25 @@ static int __init moxa_init(void) moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; moxaDriver->subtype = SERIAL_TYPE_NORMAL; moxaDriver->init_termios = tty_std_termios; - moxaDriver->init_termios.c_iflag = 0; - moxaDriver->init_termios.c_oflag = 0; moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; - moxaDriver->init_termios.c_lflag = 0; moxaDriver->init_termios.c_ispeed = 9600; moxaDriver->init_termios.c_ospeed = 9600; moxaDriver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(moxaDriver, &moxa_ops); - moxaXmitBuff = NULL; - - for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { + for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) { ch->type = PORT_16550A; ch->port = i; - INIT_WORK(&ch->tqueue, do_moxa_softint); - ch->tty = NULL; ch->close_delay = 5 * HZ / 10; ch->closing_wait = 30 * HZ; - ch->count = 0; - ch->blocked_open = 0; ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; init_waitqueue_head(&ch->open_wait); init_waitqueue_head(&ch->close_wait); - } - for (i = 0; i < MAX_BOARDS; i++) { - moxa_boards[i].boardType = 0; - moxa_boards[i].numPorts = 0; - moxa_boards[i].baseAddr = 0; - moxa_boards[i].busType = 0; - moxa_boards[i].pciInfo.busNum = 0; - moxa_boards[i].pciInfo.devNum = 0; + setup_timer(&ch->emptyTimer, check_xmit_empty, + (unsigned long)ch); } - MoxaDriverInit(); + printk("Tty devices major number = %d\n", ttymajor); if (tty_register_driver(moxaDriver)) { @@ -392,18 +385,8 @@ static int __init moxa_init(void) put_tty_driver(moxaDriver); return -1; } - for (i = 0; i < MAX_PORTS; i++) { - init_timer(&moxaEmptyTimer[i]); - moxaEmptyTimer[i].function = check_xmit_empty; - moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i]; - moxaEmptyTimer_on[i] = 0; - } - init_timer(&moxaTimer); - moxaTimer.function = moxa_poll; - moxaTimer.expires = jiffies + (HZ / 50); - moxaTimer_on = 1; - add_timer(&moxaTimer); + mod_timer(&moxaTimer, jiffies + HZ / 50); /* Find the boards defined in source code */ numBoards = 0; @@ -451,35 +434,22 @@ static int __init moxa_init(void) } } #endif - /* Find PCI boards here */ + #ifdef CONFIG_PCI - { - struct pci_dev *p = NULL; - int n = ARRAY_SIZE(moxa_pcibrds) - 1; - i = 0; - while (i < n) { - while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) - { - if (pci_enable_device(p)) - continue; - if (numBoards >= MAX_BOARDS) { - if (verbose) - printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); - } else { - moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data, - &moxa_boards[numBoards]); - numBoards++; - } - } - i++; - } + retval = pci_register_driver(&moxa_pci_driver); + if (retval) { + printk(KERN_ERR "Can't register moxa pci driver!\n"); + if (numBoards) + retval = 0; } #endif + for (i = 0; i < numBoards; i++) { - moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000); + moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr, + 0x4000); } - return (0); + return retval; } static void __exit moxa_exit(void) @@ -489,23 +459,22 @@ static void __exit moxa_exit(void) if (verbose) printk("Unloading module moxa ...\n"); - if (moxaTimer_on) - del_timer(&moxaTimer); + del_timer_sync(&moxaTimer); for (i = 0; i < MAX_PORTS; i++) - if (moxaEmptyTimer_on[i]) - del_timer(&moxaEmptyTimer[i]); + del_timer_sync(&moxa_ports[i].emptyTimer); if (tty_unregister_driver(moxaDriver)) printk("Couldn't unregister MOXA Intellio family serial driver\n"); put_tty_driver(moxaDriver); - for (i = 0; i < MAX_BOARDS; i++) { - if (moxaBaseAddr[i]) - iounmap(moxaBaseAddr[i]); - if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) - pci_dev_put(moxa_boards[i].pciInfo.pdev); - } +#ifdef CONFIG_PCI + pci_unregister_driver(&moxa_pci_driver); +#endif + + for (i = 0; i < MAX_BOARDS; i++) + if (moxa_boards[i].basemem) + iounmap(moxa_boards[i].basemem); if (verbose) printk("Done\n"); @@ -514,28 +483,13 @@ static void __exit moxa_exit(void) module_init(moxa_init); module_exit(moxa_exit); -static void do_moxa_softint(struct work_struct *work) -{ - struct moxa_str *ch = container_of(work, struct moxa_str, tqueue); - struct tty_struct *tty; - - if (ch && (tty = ch->tty)) { - if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) { - tty_hangup(tty); /* FIXME: module removal race here - AKPM */ - wake_up_interruptible(&ch->open_wait); - ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; - } - } -} - static int moxa_open(struct tty_struct *tty, struct file *filp) { - struct moxa_str *ch; + struct moxa_port *ch; int port; int retval; - unsigned long page; - port = PORTNO(tty); + port = tty->index; if (port == MAX_PORTS) { return (0); } @@ -543,23 +497,8 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) tty->driver_data = NULL; return (-ENODEV); } - down(&moxaBuffSem); - if (!moxaXmitBuff) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - up(&moxaBuffSem); - return (-ENOMEM); - } - /* This test is guarded by the BuffSem so no longer needed - delete me in 2.5 */ - if (moxaXmitBuff) - free_page(page); - else - moxaXmitBuff = (unsigned char *) page; - } - up(&moxaBuffSem); - ch = &moxaChannels[port]; + ch = &moxa_ports[port]; ch->count++; tty->driver_data = ch; ch->tty = tty; @@ -585,10 +524,10 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) static void moxa_close(struct tty_struct *tty, struct file *filp) { - struct moxa_str *ch; + struct moxa_port *ch; int port; - port = PORTNO(tty); + port = tty->index; if (port == MAX_PORTS) { return; } @@ -605,7 +544,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) if (tty_hung_up_p(filp)) { return; } - ch = (struct moxa_str *) tty->driver_data; + ch = (struct moxa_port *) tty->driver_data; if ((tty->count == 1) && (ch->count != 1)) { printk("moxa_close: bad serial port count; tty->count is 1, " @@ -626,8 +565,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) if (ch->asyncflags & ASYNC_INITIALIZED) { setup_empty_event(tty); tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ - moxaEmptyTimer_on[ch->port] = 0; - del_timer(&moxaEmptyTimer[ch->port]); + del_timer_sync(&moxa_ports[ch->port].emptyTimer); } shut_down(ch); MoxaPortFlushData(port, 2); @@ -652,11 +590,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) static int moxa_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct moxa_str *ch; + struct moxa_port *ch; int len, port; unsigned long flags; - ch = (struct moxa_str *) tty->driver_data; + ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return (0); port = ch->port; @@ -675,11 +613,11 @@ static int moxa_write(struct tty_struct *tty, static int moxa_write_room(struct tty_struct *tty) { - struct moxa_str *ch; + struct moxa_port *ch; if (tty->stopped) return (0); - ch = (struct moxa_str *) tty->driver_data; + ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return (0); return (MoxaPortTxFree(ch->port)); @@ -687,7 +625,7 @@ static int moxa_write_room(struct tty_struct *tty) static void moxa_flush_buffer(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return; @@ -698,7 +636,7 @@ static void moxa_flush_buffer(struct tty_struct *tty) static int moxa_chars_in_buffer(struct tty_struct *tty) { int chars; - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; /* * Sigh...I have to check if driver_data is NULL here, because @@ -730,17 +668,16 @@ static void moxa_flush_chars(struct tty_struct *tty) static void moxa_put_char(struct tty_struct *tty, unsigned char c) { - struct moxa_str *ch; + struct moxa_port *ch; int port; unsigned long flags; - ch = (struct moxa_str *) tty->driver_data; + ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return; port = ch->port; spin_lock_irqsave(&moxa_lock, flags); - moxaXmitBuff[0] = c; - MoxaPortWriteData(port, moxaXmitBuff, 1); + MoxaPortWriteData(port, &c, 1); spin_unlock_irqrestore(&moxa_lock, flags); /************************************************ if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) @@ -750,11 +687,11 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c) static int moxa_tiocmget(struct tty_struct *tty, struct file *file) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; int port; int flag = 0, dtr, rts; - port = PORTNO(tty); + port = tty->index; if ((port != MAX_PORTS) && (!ch)) return (-EINVAL); @@ -776,11 +713,11 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file) static int moxa_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; int port; int dtr, rts; - port = PORTNO(tty); + port = tty->index; if ((port != MAX_PORTS) && (!ch)) return (-EINVAL); @@ -800,12 +737,12 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, static int moxa_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; register int port; void __user *argp = (void __user *)arg; int retval; - port = PORTNO(tty); + port = tty->index; if ((port != MAX_PORTS) && (!ch)) return (-EINVAL); @@ -853,14 +790,14 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, static void moxa_throttle(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; ch->statusflags |= THROTTLE; } static void moxa_unthrottle(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; ch->statusflags &= ~THROTTLE; } @@ -868,7 +805,7 @@ static void moxa_unthrottle(struct tty_struct *tty) static void moxa_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return; @@ -880,7 +817,7 @@ static void moxa_set_termios(struct tty_struct *tty, static void moxa_stop(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return; @@ -891,7 +828,7 @@ static void moxa_stop(struct tty_struct *tty) static void moxa_start(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; if (ch == NULL) return; @@ -905,7 +842,7 @@ static void moxa_start(struct tty_struct *tty) static void moxa_hangup(struct tty_struct *tty) { - struct moxa_str *ch = (struct moxa_str *) tty->driver_data; + struct moxa_port *ch = (struct moxa_port *) tty->driver_data; moxa_flush_buffer(tty); shut_down(ch); @@ -919,24 +856,20 @@ static void moxa_hangup(struct tty_struct *tty) static void moxa_poll(unsigned long ignored) { register int card; - struct moxa_str *ch; + struct moxa_port *ch; struct tty_struct *tp; int i, ports; - moxaTimer_on = 0; del_timer(&moxaTimer); if (MoxaDriverPoll() < 0) { - moxaTimer.function = moxa_poll; - moxaTimer.expires = jiffies + (HZ / 50); - moxaTimer_on = 1; - add_timer(&moxaTimer); + mod_timer(&moxaTimer, jiffies + HZ / 50); return; } for (card = 0; card < MAX_BOARDS; card++) { if ((ports = MoxaPortsOfCard(card)) <= 0) continue; - ch = &moxaChannels[card * MAX_PORTS_PER_BOARD]; + ch = &moxa_ports[card * MAX_PORTS_PER_BOARD]; for (i = 0; i < ports; i++, ch++) { if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) continue; @@ -962,18 +895,16 @@ static void moxa_poll(unsigned long ignored) if (MoxaPortDCDON(ch->port)) wake_up_interruptible(&ch->open_wait); else { - set_bit(MOXA_EVENT_HANGUP, &ch->event); - schedule_work(&ch->tqueue); + tty_hangup(tp); + wake_up_interruptible(&ch->open_wait); + ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; } } } } } - moxaTimer.function = moxa_poll; - moxaTimer.expires = jiffies + (HZ / 50); - moxaTimer_on = 1; - add_timer(&moxaTimer); + mod_timer(&moxaTimer, jiffies + HZ / 50); } /******************************************************************************/ @@ -981,10 +912,10 @@ static void moxa_poll(unsigned long ignored) static void set_tty_param(struct tty_struct *tty) { register struct ktermios *ts; - struct moxa_str *ch; + struct moxa_port *ch; int rts, cts, txflow, rxflow, xany; - ch = (struct moxa_str *) tty->driver_data; + ch = (struct moxa_port *) tty->driver_data; ts = tty->termios; if (ts->c_cflag & CLOCAL) ch->asyncflags &= ~ASYNC_CHECK_CD; @@ -1004,7 +935,7 @@ static void set_tty_param(struct tty_struct *tty) } static int block_till_ready(struct tty_struct *tty, struct file *filp, - struct moxa_str *ch) + struct moxa_port *ch) { DECLARE_WAITQUEUE(wait,current); unsigned long flags; @@ -1095,40 +1026,33 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, static void setup_empty_event(struct tty_struct *tty) { - struct moxa_str *ch = tty->driver_data; + struct moxa_port *ch = tty->driver_data; unsigned long flags; spin_lock_irqsave(&moxa_lock, flags); ch->statusflags |= EMPTYWAIT; - moxaEmptyTimer_on[ch->port] = 0; - del_timer(&moxaEmptyTimer[ch->port]); - moxaEmptyTimer[ch->port].expires = jiffies + HZ; - moxaEmptyTimer_on[ch->port] = 1; - add_timer(&moxaEmptyTimer[ch->port]); + mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); spin_unlock_irqrestore(&moxa_lock, flags); } static void check_xmit_empty(unsigned long data) { - struct moxa_str *ch; + struct moxa_port *ch; - ch = (struct moxa_str *) data; - moxaEmptyTimer_on[ch->port] = 0; - del_timer(&moxaEmptyTimer[ch->port]); + ch = (struct moxa_port *) data; + del_timer_sync(&moxa_ports[ch->port].emptyTimer); if (ch->tty && (ch->statusflags & EMPTYWAIT)) { if (MoxaPortTxQueue(ch->port) == 0) { ch->statusflags &= ~EMPTYWAIT; tty_wakeup(ch->tty); return; } - moxaEmptyTimer[ch->port].expires = jiffies + HZ; - moxaEmptyTimer_on[ch->port] = 1; - add_timer(&moxaEmptyTimer[ch->port]); + mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); } else ch->statusflags &= ~EMPTYWAIT; } -static void shut_down(struct moxa_str *ch) +static void shut_down(struct moxa_port *ch) { struct tty_struct *tp; @@ -1148,7 +1072,7 @@ static void shut_down(struct moxa_str *ch) ch->asyncflags &= ~ASYNC_INITIALIZED; } -static void receive_data(struct moxa_str *ch) +static void receive_data(struct moxa_port *ch) { struct tty_struct *tp; struct ktermios *ts; @@ -1465,35 +1389,21 @@ static void receive_data(struct moxa_str *ch) /* * Query */ -#define QueryPort MAX_PORTS - - struct mon_str { int tick; int rxcnt[MAX_PORTS]; int txcnt[MAX_PORTS]; }; -typedef struct mon_str mon_st; #define DCD_changed 0x01 #define DCD_oldstate 0x80 static unsigned char moxaBuff[10240]; -static void __iomem *moxaIntNdx[MAX_BOARDS]; -static void __iomem *moxaIntPend[MAX_BOARDS]; -static void __iomem *moxaIntTable[MAX_BOARDS]; -static char moxaChkPort[MAX_PORTS]; -static char moxaLineCtrl[MAX_PORTS]; -static void __iomem *moxaTableAddr[MAX_PORTS]; -static long moxaCurBaud[MAX_PORTS]; -static char moxaDCDState[MAX_PORTS]; -static char moxaLowChkFlag[MAX_PORTS]; static int moxaLowWaterChk; static int moxaCard; -static mon_st moxaLog; -static int moxaFuncTout; -static ushort moxaBreakCnt[MAX_PORTS]; +static struct mon_str moxaLog; +static int moxaFuncTout = HZ / 2; static void moxadelay(int); static void moxafunc(void __iomem *, int, ushort); @@ -1514,16 +1424,18 @@ static int moxaloadc320(int, void __iomem *, int, int *); *****************************************************************************/ void MoxaDriverInit(void) { - int i; + struct moxa_port *p; + unsigned int i; moxaFuncTout = HZ / 2; /* 500 mini-seconds */ moxaCard = 0; moxaLog.tick = 0; moxaLowWaterChk = 0; for (i = 0; i < MAX_PORTS; i++) { - moxaChkPort[i] = 0; - moxaLowChkFlag[i] = 0; - moxaLineCtrl[i] = 0; + p = &moxa_ports[i]; + p->chkPort = 0; + p->lowChkFlag = 0; + p->lineCtrl = 0; moxaLog.rxcnt[i] = 0; moxaLog.txcnt[i] = 0; } @@ -1545,19 +1457,12 @@ void MoxaDriverInit(void) #define MOXA_GET_CUMAJOR (MOXA + 64) #define MOXA_GETMSTATUS (MOXA + 65) - -struct moxaq_str { - int inq; - int outq; -}; - struct dl_str { char __user *buf; int len; int cardno; }; -static struct moxaq_str temp_queue[MAX_PORTS]; static struct dl_str dltmp; void MoxaPortFlushData(int port, int mode) @@ -1565,10 +1470,10 @@ void MoxaPortFlushData(int port, int mode) void __iomem *ofsAddr; if ((mode < 0) || (mode > 2)) return; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; moxafunc(ofsAddr, FC_FlushQueue, mode); if (mode != 1) { - moxaLowChkFlag[port] = 0; + moxa_ports[port].lowChkFlag = 0; low_water_check(ofsAddr); } } @@ -1580,7 +1485,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) int MoxaPortTxQueue(int), MoxaPortRxQueue(int); void __user *argp = (void __user *)arg; - if (port == QueryPort) { + if (port == MAX_PORTS) { if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) && (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) && (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) && @@ -1590,7 +1495,8 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) } switch (cmd) { case MOXA_GET_CONF: - if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf))) + if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * + sizeof(struct moxa_board_conf))) return -EFAULT; return (0); case MOXA_INIT_DRIVER: @@ -1599,23 +1505,27 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) return (0); case MOXA_GETDATACOUNT: moxaLog.tick = jiffies; - if(copy_to_user(argp, &moxaLog, sizeof(mon_st))) + if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str))) return -EFAULT; return (0); case MOXA_FLUSH_QUEUE: MoxaPortFlushData(port, arg); return (0); - case MOXA_GET_IOQUEUE: - for (i = 0; i < MAX_PORTS; i++) { - if (moxaChkPort[i]) { - temp_queue[i].inq = MoxaPortRxQueue(i); - temp_queue[i].outq = MoxaPortTxQueue(i); + case MOXA_GET_IOQUEUE: { + struct moxaq_str __user *argm = argp; + struct moxaq_str tmp; + + for (i = 0; i < MAX_PORTS; i++, argm++) { + memset(&tmp, 0, sizeof(tmp)); + if (moxa_ports[i].chkPort) { + tmp.inq = MoxaPortRxQueue(i); + tmp.outq = MoxaPortTxQueue(i); } + if (copy_to_user(argm, &tmp, sizeof(tmp))) + return -EFAULT; } - if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS)) - return -EFAULT; return (0); - case MOXA_GET_OQUEUE: + } case MOXA_GET_OQUEUE: i = MoxaPortTxQueue(port); return put_user(i, (unsigned long __user *)argp); case MOXA_GET_IQUEUE: @@ -1630,33 +1540,36 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) if(copy_to_user(argp, &i, sizeof(int))) return -EFAULT; return 0; - case MOXA_GETMSTATUS: - for (i = 0; i < MAX_PORTS; i++) { - GMStatus[i].ri = 0; - GMStatus[i].dcd = 0; - GMStatus[i].dsr = 0; - GMStatus[i].cts = 0; - if (!moxaChkPort[i]) { - continue; + case MOXA_GETMSTATUS: { + struct mxser_mstatus __user *argm = argp; + struct mxser_mstatus tmp; + struct moxa_port *p; + + for (i = 0; i < MAX_PORTS; i++, argm++) { + p = &moxa_ports[i]; + memset(&tmp, 0, sizeof(tmp)); + if (!p->chkPort) { + goto copy; } else { - status = MoxaPortLineStatus(moxaChannels[i].port); + status = MoxaPortLineStatus(p->port); if (status & 1) - GMStatus[i].cts = 1; + tmp.cts = 1; if (status & 2) - GMStatus[i].dsr = 1; + tmp.dsr = 1; if (status & 4) - GMStatus[i].dcd = 1; + tmp.dcd = 1; } - if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios) - GMStatus[i].cflag = moxaChannels[i].cflag; + if (!p->tty || !p->tty->termios) + tmp.cflag = p->cflag; else - GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag; + tmp.cflag = p->tty->termios->c_cflag; +copy: + if (copy_to_user(argm, &tmp, sizeof(tmp))) + return -EFAULT; } - if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS)) - return -EFAULT; return 0; - default: + } default: return (-ENOIOCTLCMD); case MOXA_LOAD_BIOS: case MOXA_FIND_BOARD: @@ -1694,6 +1607,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) int MoxaDriverPoll(void) { + struct moxa_board_conf *brd; register ushort temp; register int card; void __iomem *ofsAddr; @@ -1703,43 +1617,44 @@ int MoxaDriverPoll(void) if (moxaCard == 0) return (-1); for (card = 0; card < MAX_BOARDS; card++) { - if (loadstat[card] == 0) + brd = &moxa_boards[card]; + if (brd->loadstat == 0) continue; - if ((ports = moxa_boards[card].numPorts) == 0) + if ((ports = brd->numPorts) == 0) continue; - if (readb(moxaIntPend[card]) == 0xff) { - ip = moxaIntTable[card] + readb(moxaIntNdx[card]); + if (readb(brd->intPend) == 0xff) { + ip = brd->intTable + readb(brd->intNdx); p = card * MAX_PORTS_PER_BOARD; ports <<= 1; for (port = 0; port < ports; port += 2, p++) { if ((temp = readw(ip + port)) != 0) { writew(0, ip + port); - ofsAddr = moxaTableAddr[p]; + ofsAddr = moxa_ports[p].tableAddr; if (temp & IntrTx) writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat); if (temp & IntrBreak) { - moxaBreakCnt[p]++; + moxa_ports[p].breakCnt++; } if (temp & IntrLine) { if (readb(ofsAddr + FlagStat) & DCD_state) { - if ((moxaDCDState[p] & DCD_oldstate) == 0) - moxaDCDState[p] = (DCD_oldstate | + if ((moxa_ports[p].DCDState & DCD_oldstate) == 0) + moxa_ports[p].DCDState = (DCD_oldstate | DCD_changed); } else { - if (moxaDCDState[p] & DCD_oldstate) - moxaDCDState[p] = DCD_changed; + if (moxa_ports[p].DCDState & DCD_oldstate) + moxa_ports[p].DCDState = DCD_changed; } } } } - writeb(0, moxaIntPend[card]); + writeb(0, brd->intPend); } if (moxaLowWaterChk) { p = card * MAX_PORTS_PER_BOARD; for (port = 0; port < ports; port++, p++) { - if (moxaLowChkFlag[p]) { - moxaLowChkFlag[p] = 0; - ofsAddr = moxaTableAddr[p]; + if (moxa_ports[p].lowChkFlag) { + moxa_ports[p].lowChkFlag = 0; + ofsAddr = moxa_ports[p].tableAddr; low_water_check(ofsAddr); } } @@ -1767,9 +1682,7 @@ int MoxaPortsOfCard(int cardno) * 2. MoxaPortEnable(int port); * * 3. MoxaPortDisable(int port); * * 4. MoxaPortGetMaxBaud(int port); * - * 5. MoxaPortGetCurBaud(int port); * * 6. MoxaPortSetBaud(int port, long baud); * - * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); * * 8. MoxaPortSetTermio(int port, unsigned char *termio); * * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); * * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * @@ -1780,18 +1693,12 @@ int MoxaPortsOfCard(int cardno) * 15. MoxaPortFlushData(int port, int mode); * * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * * 17. MoxaPortReadData(int port, struct tty_struct *tty); * - * 18. MoxaPortTxBufSize(int port); * - * 19. MoxaPortRxBufSize(int port); * * 20. MoxaPortTxQueue(int port); * * 21. MoxaPortTxFree(int port); * * 22. MoxaPortRxQueue(int port); * - * 23. MoxaPortRxFree(int port); * * 24. MoxaPortTxDisable(int port); * * 25. MoxaPortTxEnable(int port); * - * 26. MoxaPortGetBrkCnt(int port); * * 27. MoxaPortResetBrkCnt(int port); * - * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); * - * 29. MoxaPortIsTxHold(int port); * * 30. MoxaPortSendBreak(int port, int ticks); * *****************************************************************************/ /* @@ -1878,15 +1785,6 @@ int MoxaPortsOfCard(int cardno) * 38400/57600/115200 bps * * - * Function 9: Get the current baud rate of this port. - * Syntax: - * long MoxaPortGetCurBaud(int port); - * int port : port number (0 - 127) - * - * return: 0 : this port is invalid - * 50 - 115200 bps - * - * * Function 10: Setting baud rate of this port. * Syntax: * long MoxaPortSetBaud(int port, long baud); @@ -1900,18 +1798,6 @@ int MoxaPortsOfCard(int cardno) * baud rate will be the maximun baud rate. * * - * Function 11: Setting the data-bits/stop-bits/parity of this port - * Syntax: - * int MoxaPortSetMode(int port, int databits, int stopbits, int parity); - * int port : port number (0 - 127) - * int databits : data bits (8/7/6/5) - * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits) - int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space) - * - * return: -1 : invalid parameter - * 0 : setting O.K. - * - * * Function 12: Configure the port. * Syntax: * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud); @@ -2016,22 +1902,6 @@ int MoxaPortsOfCard(int cardno) * return: 0 - length : real read data length * * - * Function 22: Get the Tx buffer size of this port - * Syntax: - * int MoxaPortTxBufSize(int port); - * int port : port number (0 - 127) - * - * return: .. : Tx buffer size - * - * - * Function 23: Get the Rx buffer size of this port - * Syntax: - * int MoxaPortRxBufSize(int port); - * int port : port number (0 - 127) - * - * return: .. : Rx buffer size - * - * * Function 24: Get the Tx buffer current queued data bytes * Syntax: * int MoxaPortTxQueue(int port); @@ -2056,14 +1926,6 @@ int MoxaPortsOfCard(int cardno) * return: .. : Rx buffer current queued data bytes * * - * Function 27: Get the Rx buffer current free space - * Syntax: - * int MoxaPortRxFree(int port); - * int port : port number (0 - 127) - * - * return: .. : Rx buffer current free space - * - * * Function 28: Disable port data transmission. * Syntax: * void MoxaPortTxDisable(int port); @@ -2076,14 +1938,6 @@ int MoxaPortsOfCard(int cardno) * int port : port number (0 - 127) * * - * Function 30: Get the received BREAK signal count. - * Syntax: - * int MoxaPortGetBrkCnt(int port); - * int port : port number (0 - 127) - * - * return: 0 - .. : BREAK signal count - * - * * Function 31: Get the received BREAK signal count and reset it. * Syntax: * int MoxaPortResetBrkCnt(int port); @@ -2092,25 +1946,6 @@ int MoxaPortsOfCard(int cardno) * return: 0 - .. : BREAK signal count * * - * Function 32: Set the S/W flow control new XON/XOFF value, default - * XON is 0x11 & XOFF is 0x13. - * Syntax: - * void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); - * int port : port number (0 - 127) - * int xonValue : new XON value (0 - 255) - * int xoffValue : new XOFF value (0 - 255) - * - * - * Function 33: Check this port's transmission is hold by remote site - * because the flow control. - * Syntax: - * int MoxaPortIsTxHold(int port); - * int port : port number (0 - 127) - * - * return: 0 : normal - * 1 : hold by remote site - * - * * Function 34: Send out a BREAK signal. * Syntax: * void MoxaPortSendBreak(int port, int ms100); @@ -2125,7 +1960,7 @@ int MoxaPortIsValid(int port) if (moxaCard == 0) return (0); - if (moxaChkPort[port] == 0) + if (moxa_ports[port].chkPort == 0) return (0); return (1); } @@ -2136,9 +1971,9 @@ void MoxaPortEnable(int port) int MoxaPortLineStatus(int); short lowwater = 512; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; writew(lowwater, ofsAddr + Low_water); - moxaBreakCnt[port] = 0; + moxa_ports[port].breakCnt = 0; if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { moxafunc(ofsAddr, FC_SetBreakIrq, 0); @@ -2155,7 +1990,7 @@ void MoxaPortEnable(int port) void MoxaPortDisable(int port) { - void __iomem *ofsAddr = moxaTableAddr[port]; + void __iomem *ofsAddr = moxa_ports[port].tableAddr; moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); @@ -2181,7 +2016,7 @@ long MoxaPortSetBaud(int port, long baud) if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0)) return (0); - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; if (baud > max) baud = max; if (max == 38400L) @@ -2193,7 +2028,7 @@ long MoxaPortSetBaud(int port, long baud) val = clock / baud; moxafunc(ofsAddr, FC_SetBaud, val); baud = clock / val; - moxaCurBaud[port] = baud; + moxa_ports[port].curBaud = baud; return (baud); } @@ -2203,9 +2038,9 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) tcflag_t cflag; tcflag_t mode = 0; - if (moxaChkPort[port] == 0 || termio == 0) + if (moxa_ports[port].chkPort == 0 || termio == 0) return (-1); - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; cflag = termio->c_cflag; /* termio->c_cflag */ mode = termio->c_cflag & CSIZE; @@ -2259,13 +2094,13 @@ int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState) if (!MoxaPortIsValid(port)) return (-1); if (dtrState) { - if (moxaLineCtrl[port] & DTR_ON) + if (moxa_ports[port].lineCtrl & DTR_ON) *dtrState = 1; else *dtrState = 0; } if (rtsState) { - if (moxaLineCtrl[port] & RTS_ON) + if (moxa_ports[port].lineCtrl & RTS_ON) *rtsState = 1; else *rtsState = 0; @@ -2278,13 +2113,13 @@ void MoxaPortLineCtrl(int port, int dtr, int rts) void __iomem *ofsAddr; int mode; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; mode = 0; if (dtr) mode |= DTR_ON; if (rts) mode |= RTS_ON; - moxaLineCtrl[port] = mode; + moxa_ports[port].lineCtrl = mode; moxafunc(ofsAddr, FC_LineControl, mode); } @@ -2293,7 +2128,7 @@ void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int tx void __iomem *ofsAddr; int mode; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; mode = 0; if (rts) mode |= RTS_FlowCtl; @@ -2313,7 +2148,7 @@ int MoxaPortLineStatus(int port) void __iomem *ofsAddr; int val; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { moxafunc(ofsAddr, FC_LineStatus, 0); @@ -2324,11 +2159,11 @@ int MoxaPortLineStatus(int port) val &= 0x0B; if (val & 8) { val |= 4; - if ((moxaDCDState[port] & DCD_oldstate) == 0) - moxaDCDState[port] = (DCD_oldstate | DCD_changed); + if ((moxa_ports[port].DCDState & DCD_oldstate) == 0) + moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed); } else { - if (moxaDCDState[port] & DCD_oldstate) - moxaDCDState[port] = DCD_changed; + if (moxa_ports[port].DCDState & DCD_oldstate) + moxa_ports[port].DCDState = DCD_changed; } val &= 7; return (val); @@ -2338,10 +2173,10 @@ int MoxaPortDCDChange(int port) { int n; - if (moxaChkPort[port] == 0) + if (moxa_ports[port].chkPort == 0) return (0); - n = moxaDCDState[port]; - moxaDCDState[port] &= ~DCD_changed; + n = moxa_ports[port].DCDState; + moxa_ports[port].DCDState &= ~DCD_changed; n &= DCD_changed; return (n); } @@ -2350,32 +2185,15 @@ int MoxaPortDCDON(int port) { int n; - if (moxaChkPort[port] == 0) + if (moxa_ports[port].chkPort == 0) return (0); - if (moxaDCDState[port] & DCD_oldstate) + if (moxa_ports[port].DCDState & DCD_oldstate) n = 1; else n = 0; return (n); } - -/* - int MoxaDumpMem(int port, unsigned char * buffer, int len) - { - int i; - unsigned long baseAddr,ofsAddr,ofs; - - baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; - ofs = baseAddr + DynPage_addr + pageofs; - if (len > 0x2000L) - len = 0x2000L; - for (i = 0; i < len; i++) - buffer[i] = readb(ofs+i); - } - */ - - int MoxaPortWriteData(int port, unsigned char * buffer, int len) { int c, total, i; @@ -2385,8 +2203,8 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len) ushort pageno, pageofs, bufhead; void __iomem *baseAddr, *ofsAddr, *ofs; - ofsAddr = moxaTableAddr[port]; - baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; + ofsAddr = moxa_ports[port].tableAddr; + baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem; tx_mask = readw(ofsAddr + TX_mask); spage = readw(ofsAddr + Page_txb); epage = readw(ofsAddr + EndPage_txb); @@ -2448,8 +2266,8 @@ int MoxaPortReadData(int port, struct tty_struct *tty) ushort pageno, bufhead; void __iomem *baseAddr, *ofsAddr, *ofs; - ofsAddr = moxaTableAddr[port]; - baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; + ofsAddr = moxa_ports[port].tableAddr; + baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem; head = readw(ofsAddr + RXrptr); tail = readw(ofsAddr + RXwptr); rx_mask = readw(ofsAddr + RX_mask); @@ -2504,7 +2322,7 @@ int MoxaPortReadData(int port, struct tty_struct *tty) } if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) { moxaLowWaterChk = 1; - moxaLowChkFlag[port] = 1; + moxa_ports[port].lowChkFlag = 1; } return (total); } @@ -2516,7 +2334,7 @@ int MoxaPortTxQueue(int port) ushort rptr, wptr, mask; int len; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; rptr = readw(ofsAddr + TXrptr); wptr = readw(ofsAddr + TXwptr); mask = readw(ofsAddr + TX_mask); @@ -2530,7 +2348,7 @@ int MoxaPortTxFree(int port) ushort rptr, wptr, mask; int len; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; rptr = readw(ofsAddr + TXrptr); wptr = readw(ofsAddr + TXwptr); mask = readw(ofsAddr + TX_mask); @@ -2544,7 +2362,7 @@ int MoxaPortRxQueue(int port) ushort rptr, wptr, mask; int len; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; rptr = readw(ofsAddr + RXrptr); wptr = readw(ofsAddr + RXwptr); mask = readw(ofsAddr + RX_mask); @@ -2557,7 +2375,7 @@ void MoxaPortTxDisable(int port) { void __iomem *ofsAddr; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; moxafunc(ofsAddr, FC_SetXoffState, Magic_code); } @@ -2565,7 +2383,7 @@ void MoxaPortTxEnable(int port) { void __iomem *ofsAddr; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; moxafunc(ofsAddr, FC_SetXonState, Magic_code); } @@ -2573,8 +2391,8 @@ void MoxaPortTxEnable(int port) int MoxaPortResetBrkCnt(int port) { ushort cnt; - cnt = moxaBreakCnt[port]; - moxaBreakCnt[port] = 0; + cnt = moxa_ports[port].breakCnt; + moxa_ports[port].breakCnt = 0; return (cnt); } @@ -2583,7 +2401,7 @@ void MoxaPortSendBreak(int port, int ms100) { void __iomem *ofsAddr; - ofsAddr = moxaTableAddr[port]; + ofsAddr = moxa_ports[port].tableAddr; if (ms100) { moxafunc(ofsAddr, FC_SendBreak, Magic_code); moxadelay(ms100 * (HZ / 10)); @@ -2594,7 +2412,7 @@ void MoxaPortSendBreak(int port, int ms100) moxafunc(ofsAddr, FC_StopBreak, Magic_code); } -static int moxa_get_serial_info(struct moxa_str *info, +static int moxa_get_serial_info(struct moxa_port *info, struct serial_struct __user *retinfo) { struct serial_struct tmp; @@ -2616,7 +2434,7 @@ static int moxa_get_serial_info(struct moxa_str *info, } -static int moxa_set_serial_info(struct moxa_str *info, +static int moxa_set_serial_info(struct moxa_port *info, struct serial_struct __user *new_info) { struct serial_struct new_serial; @@ -2713,7 +2531,7 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; - baseAddr = moxaBaseAddr[cardno]; + baseAddr = moxa_boards[cardno].basemem; writeb(HW_reset, baseAddr + Control_reg); /* reset */ moxadelay(1); /* delay 10 ms */ for (i = 0; i < 4096; i++) @@ -2729,7 +2547,7 @@ static int moxafindcard(int cardno) void __iomem *baseAddr; ushort tmp; - baseAddr = moxaBaseAddr[cardno]; + baseAddr = moxa_boards[cardno].basemem; switch (moxa_boards[cardno].boardType) { case MOXA_BOARD_C218_ISA: case MOXA_BOARD_C218_PCI: @@ -2762,7 +2580,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len) return -EINVAL; if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; - baseAddr = moxaBaseAddr[cardno]; + baseAddr = moxa_boards[cardno].basemem; writew(len - 7168 - 2, baseAddr + C320bapi_len); writeb(1, baseAddr + Control_reg); /* Select Page 1 */ for (i = 0; i < 7168; i++) @@ -2780,7 +2598,7 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; - baseAddr = moxaBaseAddr[cardno]; + baseAddr = moxa_boards[cardno].basemem; switch (moxa_boards[cardno].boardType) { case MOXA_BOARD_C218_ISA: case MOXA_BOARD_C218_PCI: @@ -2790,11 +2608,13 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) return (retval); port = cardno * MAX_PORTS_PER_BOARD; for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { - moxaChkPort[port] = 1; - moxaCurBaud[port] = 9600L; - moxaDCDState[port] = 0; - moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; - ofsAddr = moxaTableAddr[port]; + struct moxa_port *p = &moxa_ports[port]; + + p->chkPort = 1; + p->curBaud = 9600L; + p->DCDState = 0; + p->tableAddr = baseAddr + Extern_table + Extern_size * i; + ofsAddr = p->tableAddr; writew(C218rx_mask, ofsAddr + RX_mask); writew(C218tx_mask, ofsAddr + TX_mask); writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); @@ -2812,11 +2632,13 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) return (retval); port = cardno * MAX_PORTS_PER_BOARD; for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { - moxaChkPort[port] = 1; - moxaCurBaud[port] = 9600L; - moxaDCDState[port] = 0; - moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; - ofsAddr = moxaTableAddr[port]; + struct moxa_port *p = &moxa_ports[port]; + + p->chkPort = 1; + p->curBaud = 9600L; + p->DCDState = 0; + p->tableAddr = baseAddr + Extern_table + Extern_size * i; + ofsAddr = p->tableAddr; if (moxa_boards[cardno].numPorts == 8) { writew(C320p8rx_mask, ofsAddr + RX_mask); writew(C320p8tx_mask, ofsAddr + TX_mask); @@ -2852,7 +2674,7 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) } break; } - loadstat[cardno] = 1; + moxa_boards[cardno].loadstat = 1; return (0); } @@ -2926,9 +2748,9 @@ static int moxaloadc218(int cardno, void __iomem *baseAddr, int len) return (-1); } moxaCard = 1; - moxaIntNdx[cardno] = baseAddr + IRQindex; - moxaIntPend[cardno] = baseAddr + IRQpending; - moxaIntTable[cardno] = baseAddr + IRQtable; + moxa_boards[cardno].intNdx = baseAddr + IRQindex; + moxa_boards[cardno].intPend = baseAddr + IRQpending; + moxa_boards[cardno].intTable = baseAddr + IRQtable; return (0); } @@ -3021,25 +2843,15 @@ static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPor if (readw(baseAddr + Magic_no) != Magic_code) return (-102); moxaCard = 1; - moxaIntNdx[cardno] = baseAddr + IRQindex; - moxaIntPend[cardno] = baseAddr + IRQpending; - moxaIntTable[cardno] = baseAddr + IRQtable; + moxa_boards[cardno].intNdx = baseAddr + IRQindex; + moxa_boards[cardno].intPend = baseAddr + IRQpending; + moxa_boards[cardno].intTable = baseAddr + IRQtable; return (0); } -#if 0 -long MoxaPortGetCurBaud(int port) -{ - - if (moxaChkPort[port] == 0) - return (0); - return (moxaCurBaud[port]); -} -#endif /* 0 */ - static void MoxaSetFifo(int port, int enable) { - void __iomem *ofsAddr = moxaTableAddr[port]; + void __iomem *ofsAddr = moxa_ports[port].tableAddr; if (!enable) { moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); @@ -3049,132 +2861,3 @@ static void MoxaSetFifo(int port, int enable) moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16); } } - -#if 0 -int MoxaPortSetMode(int port, int databits, int stopbits, int parity) -{ - void __iomem *ofsAddr; - int val; - - val = 0; - switch (databits) { - case 5: - val |= 0; - break; - case 6: - val |= 1; - break; - case 7: - val |= 2; - break; - case 8: - val |= 3; - break; - default: - return (-1); - } - switch (stopbits) { - case 0: - val |= 0; - break; /* stop bits 1.5 */ - case 1: - val |= 0; - break; - case 2: - val |= 4; - break; - default: - return (-1); - } - switch (parity) { - case 0: - val |= 0x00; - break; /* None */ - case 1: - val |= 0x08; - break; /* Odd */ - case 2: - val |= 0x18; - break; /* Even */ - case 3: - val |= 0x28; - break; /* Mark */ - case 4: - val |= 0x38; - break; /* Space */ - default: - return (-1); - } - ofsAddr = moxaTableAddr[port]; - moxafunc(ofsAddr, FC_SetMode, val); - return (0); -} - -int MoxaPortTxBufSize(int port) -{ - void __iomem *ofsAddr; - int size; - - ofsAddr = moxaTableAddr[port]; - size = readw(ofsAddr + TX_mask); - return (size); -} - -int MoxaPortRxBufSize(int port) -{ - void __iomem *ofsAddr; - int size; - - ofsAddr = moxaTableAddr[port]; - size = readw(ofsAddr + RX_mask); - return (size); -} - -int MoxaPortRxFree(int port) -{ - void __iomem *ofsAddr; - ushort rptr, wptr, mask; - int len; - - ofsAddr = moxaTableAddr[port]; - rptr = readw(ofsAddr + RXrptr); - wptr = readw(ofsAddr + RXwptr); - mask = readw(ofsAddr + RX_mask); - len = mask - ((wptr - rptr) & mask); - return (len); -} -int MoxaPortGetBrkCnt(int port) -{ - return (moxaBreakCnt[port]); -} - -void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue) -{ - void __iomem *ofsAddr; - - ofsAddr = moxaTableAddr[port]; - writew(xonValue, ofsAddr + FuncArg); - writew(xoffValue, ofsAddr + FuncArg1); - writew(FC_SetXonXoff, ofsAddr + FuncCode); - wait_finish(ofsAddr); -} - -int MoxaPortIsTxHold(int port) -{ - void __iomem *ofsAddr; - int val; - - ofsAddr = moxaTableAddr[port]; - if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || - (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { - moxafunc(ofsAddr, FC_GetCCSR, 0); - val = readw(ofsAddr + FuncArg); - if (val & 0x04) - return (1); - } else { - if (readw(ofsAddr + FlagStat) & Tx_flowOff) - return (1); - } - return (0); -} -#endif diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 83f604b1929..a61fb6da5d0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -321,8 +321,6 @@ struct mxser_struct { unsigned long event; int count; /* # of fd on device */ int blocked_open; /* # of blocked opens */ - long session; /* Session of opening process */ - long pgrp; /* pgrp of opening process */ unsigned char *xmit_buf; int xmit_head; int xmit_tail; @@ -1001,15 +999,12 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) mxser_change_speed(info, NULL); } - info->session = process_session(current); - info->pgrp = process_group(current); - /* status = mxser_get_msr(info->base, 0, info->port); mxser_check_modem_status(info, status); */ -/* unmark here for very high baud rate (ex. 921600 bps) used */ + /* unmark here for very high baud rate (ex. 921600 bps) used */ tty->low_latency = 1; return 0; } @@ -1254,9 +1249,7 @@ static void mxser_flush_buffer(struct tty_struct *tty) spin_unlock_irqrestore(&info->slock, flags); /* above added by shinhay */ - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup) (tty); + tty_wakeup(tty); } static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h index 7e188a4d602..9fe28497eae 100644 --- a/drivers/char/mxser.h +++ b/drivers/char/mxser.h @@ -439,12 +439,4 @@ #define READ_MOXA_MUST_GDL(baseio) inb((baseio)+MOXA_MUST_GDL_REGISTER) - -#ifndef INIT_WORK -#define INIT_WORK(_work, _func, _data){ \ - _data->tqueue.routine = _func;\ - _data->tqueue.data = _data;\ - } -#endif - #endif diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 1bb030b3a51..9af07e4999d 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c @@ -49,22 +49,25 @@ #include "mxser_new.h" -#define MXSER_VERSION "2.0" +#define MXSER_VERSION "2.0.1" /* 1.9.15 */ #define MXSERMAJOR 174 #define MXSERCUMAJOR 175 -#define MXSER_EVENT_TXLOW 1 - #define MXSER_BOARDS 4 /* Max. boards */ #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ #define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) -#define MXSER_ISR_PASS_LIMIT 99999L +#define MXSER_ISR_PASS_LIMIT 100 #define MXSER_ERR_IOADDR -1 #define MXSER_ERR_IRQ -2 #define MXSER_ERR_IRQ_CONFLIT -3 #define MXSER_ERR_VECTOR -4 +/*CheckIsMoxaMust return value*/ +#define MOXA_OTHER_UART 0x00 +#define MOXA_MUST_MU150_HWID 0x01 +#define MOXA_MUST_MU860_HWID 0x02 + #define WAKEUP_CHARS 256 #define UART_MCR_AFE 0x20 @@ -176,6 +179,18 @@ static struct pci_device_id mxser_pcibrds[] = { }; MODULE_DEVICE_TABLE(pci, mxser_pcibrds); +static int mxvar_baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 +}; +static unsigned int mxvar_baud_table1[] = { + 0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, + B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600 +}; +#define BAUD_TABLE_NO ARRAY_SIZE(mxvar_baud_table) + +#define B_SPEC B2000000 + static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 }; static int ttymajor = MXSERMAJOR; static int calloutmajor = MXSERCUMAJOR; @@ -237,8 +252,7 @@ struct mxser_port { long realbaud; int type; /* UART type */ int flags; /* defined in tty.h */ - long session; /* Session of opening process */ - long pgrp; /* pgrp of opening process */ + int speed; int x_char; /* xon/xoff character */ int IER; /* Interrupt Enable Register */ @@ -267,14 +281,11 @@ struct mxser_port { int xmit_cnt; struct ktermios normal_termios; - struct ktermios callout_termios; struct mxser_mon mon_data; spinlock_t slock; - struct work_struct tqueue; wait_queue_head_t open_wait; - wait_queue_head_t close_wait; wait_queue_head_t delta_msr_wait; }; @@ -313,10 +324,9 @@ static int mxvar_diagflag; static unsigned char mxser_msr[MXSER_PORTS + 1]; static struct mxser_mon_ext mon_data_ext; static int mxser_set_baud_method[MXSER_PORTS + 1]; -static spinlock_t gm_lock; #ifdef CONFIG_PCI -static int CheckIsMoxaMust(int io) +static int __devinit CheckIsMoxaMust(int io) { u8 oldmcr, hwid; int i; @@ -360,15 +370,6 @@ static void process_txrx_fifo(struct mxser_port *info) } } -static void mxser_do_softint(struct work_struct *work) -{ - struct mxser_port *info = container_of(work, struct mxser_port, tqueue); - struct tty_struct *tty = info->tty; - - if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) - tty_wakeup(tty); -} - static unsigned char mxser_get_msr(int baseaddr, int mode, int port) { unsigned char status = 0; @@ -456,10 +457,10 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, static int mxser_set_baud(struct mxser_port *info, long newspd) { + unsigned int i; int quot = 0; unsigned char cval; int ret = 0; - unsigned long flags; if (!info->tty || !info->tty->termios) return ret; @@ -471,29 +472,34 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) return 0; info->realbaud = newspd; - if (newspd == 134) { - quot = (2 * info->baud_base / 269); - } else if (newspd) { - quot = info->baud_base / newspd; - if (quot == 0) - quot = 1; + for (i = 0; i < BAUD_TABLE_NO; i++) + if (newspd == mxvar_baud_table[i]) + break; + if (i == BAUD_TABLE_NO) { + quot = info->baud_base / info->speed; + if (info->speed <= 0 || info->speed > info->max_baud) + quot = 0; } else { - quot = 0; + if (newspd == 134) { + quot = (2 * info->baud_base / 269); + } else if (newspd) { + quot = info->baud_base / newspd; + if (quot == 0) + quot = 1; + } else { + quot = 0; + } } info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); info->timeout += HZ / 50; /* Add .02 seconds of slop */ if (quot) { - spin_lock_irqsave(&info->slock, flags); info->MCR |= UART_MCR_DTR; outb(info->MCR, info->ioaddr + UART_MCR); - spin_unlock_irqrestore(&info->slock, flags); } else { - spin_lock_irqsave(&info->slock, flags); info->MCR &= ~UART_MCR_DTR; outb(info->MCR, info->ioaddr + UART_MCR); - spin_unlock_irqrestore(&info->slock, flags); return ret; } @@ -505,6 +511,18 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */ outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ + if (i == BAUD_TABLE_NO) { + quot = info->baud_base % info->speed; + quot *= 8; + if ((quot % info->speed) > (info->speed / 2)) { + quot /= info->speed; + quot++; + } else { + quot /= info->speed; + } + SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot); + } else + SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0); return ret; } @@ -520,7 +538,6 @@ static int mxser_change_speed(struct mxser_port *info, int ret = 0; unsigned char status; long baud; - unsigned long flags; if (!info->tty || !info->tty->termios) return ret; @@ -529,7 +546,10 @@ static int mxser_change_speed(struct mxser_port *info, return ret; if (mxser_set_baud_method[info->tty->index] == 0) { - baud = tty_get_baud_rate(info->tty); + if ((cflag & CBAUD) == B_SPEC) + baud = info->speed; + else + baud = tty_get_baud_rate(info->tty); mxser_set_baud(info, baud); } @@ -612,8 +632,8 @@ static int mxser_change_speed(struct mxser_port *info, outb(info->IER, info->ioaddr + UART_IER); } - set_bit(MXSER_EVENT_TXLOW, &info->event); - schedule_work(&info->tqueue); } + tty_wakeup(info->tty); + } } else { if (!(status & UART_MSR_CTS)) { info->tty->hw_stopped = 1; @@ -668,7 +688,6 @@ static int mxser_change_speed(struct mxser_port *info, } } if (info->board->chip_flag) { - spin_lock_irqsave(&info->slock, flags); SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty)); SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty)); if (I_IXON(info->tty)) { @@ -681,7 +700,6 @@ static int mxser_change_speed(struct mxser_port *info, } else { DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); } - spin_unlock_irqrestore(&info->slock, flags); } @@ -708,7 +726,6 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { if (status & UART_MSR_DCD) wake_up_interruptible(&port->open_wait); - schedule_work(&port->tqueue); } if (port->flags & ASYNC_CTS_FLOW) { @@ -724,8 +741,7 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) outb(port->IER, port->ioaddr + UART_IER); } - set_bit(MXSER_EVENT_TXLOW, &port->event); - schedule_work(&port->tqueue); + tty_wakeup(port->tty); } } else { if (!(status & UART_MSR_CTS)) { @@ -836,10 +852,10 @@ static int mxser_startup(struct mxser_port *info) /* * and set the speed of the serial port */ - spin_unlock_irqrestore(&info->slock, flags); mxser_change_speed(info, NULL); - info->flags |= ASYNC_INITIALIZED; + spin_unlock_irqrestore(&info->slock, flags); + return 0; } @@ -909,11 +925,9 @@ static void mxser_shutdown(struct mxser_port *info) static int mxser_open(struct tty_struct *tty, struct file *filp) { struct mxser_port *info; + unsigned long flags; int retval, line; - /* initialize driver_data in case something fails */ - tty->driver_data = NULL; - line = tty->index; if (line == MXSER_PORTS) return 0; @@ -928,7 +942,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) /* * Start up serial port */ + spin_lock_irqsave(&info->slock, flags); info->count++; + spin_unlock_irqrestore(&info->slock, flags); retval = mxser_startup(info); if (retval) return retval; @@ -937,17 +953,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) if (retval) return retval; - if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver->subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->normal_termios; - else - *tty->termios = info->callout_termios; - mxser_change_speed(info, NULL); - } - - info->session = process_session(current); - info->pgrp = process_group(current); - /* unmark here for very high baud rate (ex. 921600 bps) used */ tty->low_latency = 1; return 0; @@ -1054,8 +1059,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) } info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - } static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) @@ -1222,6 +1225,7 @@ static int mxser_set_serial_info(struct mxser_port *info, struct serial_struct __user *new_info) { struct serial_struct new_serial; + unsigned long sl_flags; unsigned int flags; int retval = 0; @@ -1264,8 +1268,11 @@ static int mxser_set_serial_info(struct mxser_port *info, process_txrx_fifo(info); if (info->flags & ASYNC_INITIALIZED) { - if (flags != (info->flags & ASYNC_SPD_MASK)) + if (flags != (info->flags & ASYNC_SPD_MASK)) { + spin_lock_irqsave(&info->slock, sl_flags); mxser_change_speed(info, NULL); + spin_unlock_irqrestore(&info->slock, sl_flags); + } } else retval = mxser_startup(info); @@ -1373,11 +1380,10 @@ static int mxser_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int mxser_program_mode(int port) +static int __init mxser_program_mode(int port) { int id, i, j, n; - spin_lock(&gm_lock); outb(0, port); outb(0, port); outb(0, port); @@ -1385,7 +1391,6 @@ static int mxser_program_mode(int port) (void)inb(port); outb(0, port); (void)inb(port); - spin_unlock(&gm_lock); id = inb(port + 1) & 0x1F; if ((id != C168_ASIC_ID) && @@ -1410,7 +1415,7 @@ static int mxser_program_mode(int port) return id; } -static void mxser_normal_mode(int port) +static void __init mxser_normal_mode(int port) { int i, n; @@ -1443,7 +1448,7 @@ static void mxser_normal_mode(int port) #define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ #define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ #define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ -static int mxser_read_register(int port, unsigned short *regs) +static int __init mxser_read_register(int port, unsigned short *regs) { int i, k, value, id; unsigned int j; @@ -1644,6 +1649,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, struct serial_icounter_struct __user *p_cuser; unsigned long templ; unsigned long flags; + unsigned int i; void __user *argp = (void __user *)arg; int retval; @@ -1682,6 +1688,36 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, return 0; } + if (cmd == MOXA_SET_SPECIAL_BAUD_RATE) { + int speed; + + if (get_user(speed, (int __user *)argp)) + return -EFAULT; + if (speed <= 0 || speed > info->max_baud) + return -EFAULT; + if (!info->tty || !info->tty->termios || !info->ioaddr) + return 0; + info->tty->termios->c_cflag &= ~(CBAUD | CBAUDEX); + for (i = 0; i < BAUD_TABLE_NO; i++) + if (speed == mxvar_baud_table[i]) + break; + if (i == BAUD_TABLE_NO) { + info->tty->termios->c_cflag |= B_SPEC; + } else if (speed != 0) + info->tty->termios->c_cflag |= mxvar_baud_table1[i]; + + info->speed = speed; + spin_lock_irqsave(&info->slock, flags); + mxser_change_speed(info, NULL); + spin_unlock_irqrestore(&info->slock, flags); + + return 0; + } else if (cmd == MOXA_GET_SPECIAL_BAUD_RATE) { + if (copy_to_user(argp, &info->speed, sizeof(int))) + return -EFAULT; + return 0; + } + if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT && test_bit(TTY_IO_ERROR, &tty->flags)) return -EIO; @@ -1799,7 +1835,9 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, long baud; if (get_user(baud, (long __user *)argp)) return -EFAULT; + spin_lock_irqsave(&info->slock, flags); mxser_set_baud(info, baud); + spin_unlock_irqrestore(&info->slock, flags); return 0; } case MOXA_ASPP_GETBAUD: @@ -1976,7 +2014,9 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi if ((tty->termios->c_cflag != old_termios->c_cflag) || (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { + spin_lock_irqsave(&info->slock, flags); mxser_change_speed(info, old_termios); + spin_unlock_irqrestore(&info->slock, flags); if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { @@ -2066,7 +2106,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) /* * This routine is called by tty_hangup() when a hangup is signaled. */ -void mxser_hangup(struct tty_struct *tty) +static void mxser_hangup(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; @@ -2105,9 +2145,6 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) int cnt = 0; int recv_room; int max = 256; - unsigned long flags; - - spin_lock_irqsave(&port->slock, flags); recv_room = tty->receive_room; if ((recv_room == 0) && (!port->ldisc_stop_rx)) @@ -2169,7 +2206,8 @@ intr_old: } else if (*status & UART_LSR_OE) { flag = TTY_OVERRUN; port->icount.overrun++; - } + } else + flag = TTY_BREAK; } tty_insert_flip_char(tty, ch, flag); cnt++; @@ -2191,7 +2229,6 @@ end_intr: mxvar_log.rxcnt[port->tty->index] += cnt; port->mon_data.rxcnt += cnt; port->mon_data.up_rxcnt += cnt; - spin_unlock_irqrestore(&port->slock, flags); tty_flip_buffer_push(tty); } @@ -2199,9 +2236,6 @@ end_intr: static void mxser_transmit_chars(struct mxser_port *port) { int count, cnt; - unsigned long flags; - - spin_lock_irqsave(&port->slock, flags); if (port->x_char) { outb(port->x_char, port->ioaddr + UART_TX); @@ -2210,11 +2244,11 @@ static void mxser_transmit_chars(struct mxser_port *port) port->mon_data.txcnt++; port->mon_data.up_txcnt++; port->icount.tx++; - goto unlock; + return; } if (port->xmit_buf == 0) - goto unlock; + return; if ((port->xmit_cnt <= 0) || port->tty->stopped || (port->tty->hw_stopped && @@ -2222,7 +2256,7 @@ static void mxser_transmit_chars(struct mxser_port *port) (!port->board->chip_flag))) { port->IER &= ~UART_IER_THRI; outb(port->IER, port->ioaddr + UART_IER); - goto unlock; + return; } cnt = port->xmit_cnt; @@ -2240,16 +2274,13 @@ static void mxser_transmit_chars(struct mxser_port *port) port->mon_data.up_txcnt += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt); - if (port->xmit_cnt < WAKEUP_CHARS) { - set_bit(MXSER_EVENT_TXLOW, &port->event); - schedule_work(&port->tqueue); - } + if (port->xmit_cnt < WAKEUP_CHARS) + tty_wakeup(port->tty); + if (port->xmit_cnt <= 0) { port->IER &= ~UART_IER_THRI; outb(port->IER, port->ioaddr + UART_IER); } -unlock: - spin_unlock_irqrestore(&port->slock, flags); } /* @@ -2261,8 +2292,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) struct mxser_board *brd = NULL; struct mxser_port *port; int max, irqbits, bits, msr; - int pass_counter = 0; - unsigned int int_cnt; + unsigned int int_cnt, pass_counter = 0; int handled = IRQ_NONE; for (i = 0; i < MXSER_BOARDS; i++) @@ -2276,7 +2306,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) if (brd == NULL) goto irq_stop; max = brd->info->nports; - while (1) { + while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { irqbits = inb(brd->vector) & brd->vector_mask; if (irqbits == brd->vector_mask) break; @@ -2290,12 +2320,16 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) port = &brd->ports[i]; int_cnt = 0; + spin_lock(&port->slock); do { iir = inb(port->ioaddr + UART_IIR); if (iir & UART_IIR_NO_INT) break; iir &= MOXA_MUST_IIR_MASK; - if (!port->tty) { + if (!port->tty || + (port->flags & ASYNC_CLOSING) || + !(port->flags & + ASYNC_INITIALIZED)) { status = inb(port->ioaddr + UART_LSR); outb(0x27, port->ioaddr + UART_FCR); inb(port->ioaddr + UART_MSR); @@ -2341,9 +2375,8 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) mxser_transmit_chars(port); } } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); + spin_unlock(&port->slock); } - if (pass_counter++ > MXSER_ISR_PASS_LIMIT) - break; /* Prevent infinite loops */ } irq_stop: @@ -2385,7 +2418,6 @@ static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev, #ifdef CONFIG_PCI pci_release_region(pdev, 2); pci_release_region(pdev, 3); - pci_dev_put(pdev); #endif } else { release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); @@ -2420,11 +2452,10 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, info->custom_divisor = info->baud_base * 16; info->close_delay = 5 * HZ / 10; info->closing_wait = 30 * HZ; - INIT_WORK(&info->tqueue, mxser_do_softint); info->normal_termios = mxvar_sdriver->init_termios; init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); init_waitqueue_head(&info->delta_msr_wait); + info->speed = 9600; memset(&info->mon_data, 0, sizeof(struct mxser_mon)); info->err_shadow = 0; spin_lock_init(&info->slock); @@ -2433,22 +2464,17 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, outb(inb(info->ioaddr + UART_IER) & 0xf0, info->ioaddr + UART_IER); } - /* - * Allocate the IRQ if necessary - */ - retval = request_irq(brd->irq, mxser_interrupt, - (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : - IRQF_DISABLED, "mxser", brd); + retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", + brd); if (retval) { printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " "conflict with another device.\n", brd->info->name, brd->irq); /* We hold resources, we need to release them. */ mxser_release_res(brd, pdev, 0); - return retval; } - return 0; + return retval; } static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) @@ -2633,8 +2659,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev, } /* mxser_initbrd will hook ISR. */ - if (mxser_initbrd(brd, pdev) < 0) - goto err_relvec; + retval = mxser_initbrd(brd, pdev); + if (retval) + goto err_null; for (i = 0; i < brd->info->nports; i++) tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); @@ -2642,10 +2669,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, brd); return 0; -err_relvec: - pci_release_region(pdev, 3); err_relio: pci_release_region(pdev, 2); +err_null: brd->info = NULL; err: return retval; @@ -2663,6 +2689,7 @@ static void __devexit mxser_remove(struct pci_dev *pdev) tty_unregister_device(mxvar_sdriver, brd->idx + i); mxser_release_res(brd, pdev, 1); + brd->info = NULL; } static struct pci_driver mxser_driver = { @@ -2684,7 +2711,6 @@ static int __init mxser_module_init(void) mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); if (!mxvar_sdriver) return -ENOMEM; - spin_lock_init(&gm_lock); printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", MXSER_VERSION); diff --git a/drivers/char/mxser_new.h b/drivers/char/mxser_new.h index a08f0ecb09b..d42f7766c65 100644 --- a/drivers/char/mxser_new.h +++ b/drivers/char/mxser_new.h @@ -26,18 +26,8 @@ #define RS422_MODE 2 #define RS485_4WIRE_MODE 3 #define OP_MODE_MASK 3 -// above add by Victor Yu. 01-05-2004 - -#define TTY_THRESHOLD_THROTTLE 128 - -#define LO_WATER (TTY_FLIPBUF_SIZE) -#define HI_WATER (TTY_FLIPBUF_SIZE*2*3/4) - -// added by James. 03-11-2004. -#define MOXA_SDS_GETICOUNTER (MOXA + 68) -#define MOXA_SDS_RSTICOUNTER (MOXA + 69) -// (above) added by James. +#define MOXA_SDS_RSTICOUNTER (MOXA + 69) #define MOXA_ASPP_OQUEUE (MOXA + 70) #define MOXA_ASPP_SETBAUD (MOXA + 71) #define MOXA_ASPP_GETBAUD (MOXA + 72) @@ -45,7 +35,8 @@ #define MOXA_ASPP_LSTATUS (MOXA + 74) #define MOXA_ASPP_MON_EXT (MOXA + 75) #define MOXA_SET_BAUD_METHOD (MOXA + 76) - +#define MOXA_SET_SPECIAL_BAUD_RATE (MOXA + 77) +#define MOXA_GET_SPECIAL_BAUD_RATE (MOXA + 78) /* --------------------------------------------------- */ @@ -55,51 +46,46 @@ #define NPPI_NOTIFY_SW_OVERRUN 0x08 #define NPPI_NOTIFY_BREAK 0x10 -#define NPPI_NOTIFY_CTSHOLD 0x01 // Tx hold by CTS low -#define NPPI_NOTIFY_DSRHOLD 0x02 // Tx hold by DSR low -#define NPPI_NOTIFY_XOFFHOLD 0x08 // Tx hold by Xoff received -#define NPPI_NOTIFY_XOFFXENT 0x10 // Xoff Sent - -//CheckIsMoxaMust return value -#define MOXA_OTHER_UART 0x00 -#define MOXA_MUST_MU150_HWID 0x01 -#define MOXA_MUST_MU860_HWID 0x02 - -// follow just for Moxa Must chip define. -// -// when LCR register (offset 0x03) write following value, -// the Must chip will enter enchance mode. And write value -// on EFR (offset 0x02) bit 6,7 to change bank. +#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ +#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ +#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ +#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ + +/* follow just for Moxa Must chip define. */ +/* */ +/* when LCR register (offset 0x03) write following value, */ +/* the Must chip will enter enchance mode. And write value */ +/* on EFR (offset 0x02) bit 6,7 to change bank. */ #define MOXA_MUST_ENTER_ENCHANCE 0xBF -// when enhance mode enable, access on general bank register +/* when enhance mode enable, access on general bank register */ #define MOXA_MUST_GDL_REGISTER 0x07 #define MOXA_MUST_GDL_MASK 0x7F #define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 -#define MOXA_MUST_LSR_RERR 0x80 // error in receive FIFO -// enchance register bank select and enchance mode setting register -// when LCR register equal to 0xBF +#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ +/* enchance register bank select and enchance mode setting register */ +/* when LCR register equal to 0xBF */ #define MOXA_MUST_EFR_REGISTER 0x02 -// enchance mode enable +/* enchance mode enable */ #define MOXA_MUST_EFR_EFRB_ENABLE 0x10 -// enchance reister bank set 0, 1, 2 +/* enchance reister bank set 0, 1, 2 */ #define MOXA_MUST_EFR_BANK0 0x00 #define MOXA_MUST_EFR_BANK1 0x40 #define MOXA_MUST_EFR_BANK2 0x80 #define MOXA_MUST_EFR_BANK3 0xC0 #define MOXA_MUST_EFR_BANK_MASK 0xC0 -// set XON1 value register, when LCR=0xBF and change to bank0 +/* set XON1 value register, when LCR=0xBF and change to bank0 */ #define MOXA_MUST_XON1_REGISTER 0x04 -// set XON2 value register, when LCR=0xBF and change to bank0 +/* set XON2 value register, when LCR=0xBF and change to bank0 */ #define MOXA_MUST_XON2_REGISTER 0x05 -// set XOFF1 value register, when LCR=0xBF and change to bank0 +/* set XOFF1 value register, when LCR=0xBF and change to bank0 */ #define MOXA_MUST_XOFF1_REGISTER 0x06 -// set XOFF2 value register, when LCR=0xBF and change to bank0 +/* set XOFF2 value register, when LCR=0xBF and change to bank0 */ #define MOXA_MUST_XOFF2_REGISTER 0x07 #define MOXA_MUST_RBRTL_REGISTER 0x04 @@ -111,32 +97,32 @@ #define MOXA_MUST_ECR_REGISTER 0x06 #define MOXA_MUST_CSR_REGISTER 0x07 -// good data mode enable +/* good data mode enable */ #define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 -// only good data put into RxFIFO +/* only good data put into RxFIFO */ #define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 -// enable CTS interrupt +/* enable CTS interrupt */ #define MOXA_MUST_IER_ECTSI 0x80 -// enable RTS interrupt +/* enable RTS interrupt */ #define MOXA_MUST_IER_ERTSI 0x40 -// enable Xon/Xoff interrupt +/* enable Xon/Xoff interrupt */ #define MOXA_MUST_IER_XINT 0x20 -// enable GDA interrupt +/* enable GDA interrupt */ #define MOXA_MUST_IER_EGDAI 0x10 #define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) -// GDA interrupt pending +/* GDA interrupt pending */ #define MOXA_MUST_IIR_GDA 0x1C #define MOXA_MUST_IIR_RDA 0x04 #define MOXA_MUST_IIR_RTO 0x0C #define MOXA_MUST_IIR_LSR 0x06 -// recieved Xon/Xoff or specical interrupt pending +/* recieved Xon/Xoff or specical interrupt pending */ #define MOXA_MUST_IIR_XSC 0x10 -// RTS/CTS change state interrupt pending +/* RTS/CTS change state interrupt pending */ #define MOXA_MUST_IIR_RTSCTS 0x20 #define MOXA_MUST_IIR_MASK 0x3E @@ -144,307 +130,164 @@ #define MOXA_MUST_MCR_XON_ANY 0x80 #define MOXA_MUST_MCR_TX_XON 0x08 - -// software flow control on chip mask value +/* software flow control on chip mask value */ #define MOXA_MUST_EFR_SF_MASK 0x0F -// send Xon1/Xoff1 +/* send Xon1/Xoff1 */ #define MOXA_MUST_EFR_SF_TX1 0x08 -// send Xon2/Xoff2 +/* send Xon2/Xoff2 */ #define MOXA_MUST_EFR_SF_TX2 0x04 -// send Xon1,Xon2/Xoff1,Xoff2 +/* send Xon1,Xon2/Xoff1,Xoff2 */ #define MOXA_MUST_EFR_SF_TX12 0x0C -// don't send Xon/Xoff +/* don't send Xon/Xoff */ #define MOXA_MUST_EFR_SF_TX_NO 0x00 -// Tx software flow control mask +/* Tx software flow control mask */ #define MOXA_MUST_EFR_SF_TX_MASK 0x0C -// don't receive Xon/Xoff +/* don't receive Xon/Xoff */ #define MOXA_MUST_EFR_SF_RX_NO 0x00 -// receive Xon1/Xoff1 +/* receive Xon1/Xoff1 */ #define MOXA_MUST_EFR_SF_RX1 0x02 -// receive Xon2/Xoff2 +/* receive Xon2/Xoff2 */ #define MOXA_MUST_EFR_SF_RX2 0x01 -// receive Xon1,Xon2/Xoff1,Xoff2 +/* receive Xon1,Xon2/Xoff1,Xoff2 */ #define MOXA_MUST_EFR_SF_RX12 0x03 -// Rx software flow control mask +/* Rx software flow control mask */ #define MOXA_MUST_EFR_SF_RX_MASK 0x03 -//#define MOXA_MUST_MIN_XOFFLIMIT 66 -//#define MOXA_MUST_MIN_XONLIMIT 20 -//#define ID1_RX_TRIG 120 - - -#define CHECK_MOXA_MUST_XOFFLIMIT(info) { \ - if ( (info)->IsMoxaMustChipFlag && \ - (info)->HandFlow.XoffLimit < MOXA_MUST_MIN_XOFFLIMIT ) { \ - (info)->HandFlow.XoffLimit = MOXA_MUST_MIN_XOFFLIMIT; \ - (info)->HandFlow.XonLimit = MOXA_MUST_MIN_XONLIMIT; \ - } \ -} - -#define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ +#define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_XON1_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define SET_MOXA_MUST_XON1_VALUE(baseio, Value) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK0; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ + __efr |= MOXA_MUST_EFR_BANK0; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) -#define SET_MOXA_MUST_XON2_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ +#define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK0; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_XON2_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK0; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ + __efr |= MOXA_MUST_EFR_BANK0; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ outb((u8)(Value), (baseio)+MOXA_MUST_XOFF1_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) -#define SET_MOXA_MUST_XOFF2_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK0; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_XOFF2_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_RBRTL_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_RBRTL_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_RBRTH_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_RBRTH_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_RBRTI_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_RBRTI_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_THRTL_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb((u8)(Value), (baseio)+MOXA_MUST_THRTL_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -//#define MOXA_MUST_RBRL_VALUE 4 -#define SET_MOXA_MUST_FIFO_VALUE(info) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((info)->ioaddr+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR); \ +#define SET_MOXA_MUST_FIFO_VALUE(info) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((info)->ioaddr+UART_LCR); \ + outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR);\ __efr = inb((info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK1; \ + __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ + __efr |= MOXA_MUST_EFR_BANK1; \ outb(__efr, (info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ - outb((u8)((info)->rx_high_water), (info)->ioaddr+MOXA_MUST_RBRTH_REGISTER); \ - outb((u8)((info)->rx_trigger), (info)->ioaddr+MOXA_MUST_RBRTI_REGISTER); \ - outb((u8)((info)->rx_low_water), (info)->ioaddr+MOXA_MUST_RBRTL_REGISTER); \ - outb(__oldlcr, (info)->ioaddr+UART_LCR); \ -} - - - -#define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + outb((u8)((info)->rx_high_water), (info)->ioaddr+ \ + MOXA_MUST_RBRTH_REGISTER); \ + outb((u8)((info)->rx_trigger), (info)->ioaddr+ \ + MOXA_MUST_RBRTI_REGISTER); \ + outb((u8)((info)->rx_low_water), (info)->ioaddr+ \ + MOXA_MUST_RBRTL_REGISTER); \ + outb(__oldlcr, (info)->ioaddr+UART_LCR); \ +} while (0) + +#define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK2; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ + __efr |= MOXA_MUST_EFR_BANK2; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) -#define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ - __efr |= MOXA_MUST_EFR_BANK2; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_MASK; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_JUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ +#define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_MASK; \ - __efr |= MOXA_MUST_EFR_SF_TX1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ + __efr |= MOXA_MUST_EFR_BANK2; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ - __efr |= MOXA_MUST_EFR_SF_TX1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_SF_MASK; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define SET_MOXA_MUST_JUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ + __efr |= MOXA_MUST_EFR_SF_TX1; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_MASK; \ - __efr |= MOXA_MUST_EFR_SF_RX1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ - __efr |= MOXA_MUST_EFR_SF_RX1; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ + __efr |= MOXA_MUST_EFR_SF_RX1; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) + +#define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \ + u8 __oldlcr, __efr; \ + __oldlcr = inb((baseio)+UART_LCR); \ outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define ENABLE_MOXA_MUST_TX_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ - u8 __oldlcr, __efr; \ - __oldlcr = inb((baseio)+UART_LCR); \ - outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ - __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ - __efr &= ~MOXA_MUST_EFR_SF_MASK; \ - __efr |= (MOXA_MUST_EFR_SF_RX1|MOXA_MUST_EFR_SF_TX1); \ - outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ - outb(__oldlcr, (baseio)+UART_LCR); \ -} - -#define ENABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \ - u8 __oldmcr; \ - __oldmcr = inb((baseio)+UART_MCR); \ - __oldmcr |= MOXA_MUST_MCR_XON_ANY; \ - outb(__oldmcr, (baseio)+UART_MCR); \ -} - -#define DISABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \ - u8 __oldmcr; \ - __oldmcr = inb((baseio)+UART_MCR); \ - __oldmcr &= ~MOXA_MUST_MCR_XON_ANY; \ - outb(__oldmcr, (baseio)+UART_MCR); \ -} - -#define READ_MOXA_MUST_GDL(baseio) inb((baseio)+MOXA_MUST_GDL_REGISTER) - - -#ifndef INIT_WORK -#define INIT_WORK(_work, _func, _data){ \ - _data->tqueue.routine = _func;\ - _data->tqueue.data = _data;\ - } -#endif + __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ + __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ + outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ + outb(__oldlcr, (baseio)+UART_LCR); \ +} while (0) #endif diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index dc6d4184145..fab1b7d4285 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c @@ -60,62 +60,56 @@ #include <linux/slab.h> #include <linux/tty.h> #include <linux/errno.h> -#include <linux/string.h> /* used in new tty drivers */ -#include <linux/signal.h> /* used in new tty drivers */ +#include <linux/string.h> /* used in new tty drivers */ +#include <linux/signal.h> /* used in new tty drivers */ #include <linux/ioctl.h> #include <linux/n_r3964.h> #include <linux/poll.h> #include <linux/init.h> #include <asm/uaccess.h> - -//#define DEBUG_QUEUE +/*#define DEBUG_QUEUE*/ /* Log successful handshake and protocol operations */ -//#define DEBUG_PROTO_S +/*#define DEBUG_PROTO_S*/ /* Log handshake and protocol errors: */ -//#define DEBUG_PROTO_E +/*#define DEBUG_PROTO_E*/ /* Log Linediscipline operations (open, close, read, write...): */ -//#define DEBUG_LDISC +/*#define DEBUG_LDISC*/ /* Log module and memory operations (init, cleanup; kmalloc, kfree): */ -//#define DEBUG_MODUL +/*#define DEBUG_MODUL*/ /* Macro helpers for debug output: */ -#define TRACE(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE(format, args...) printk("r3964: " format "\n" , ## args) #ifdef DEBUG_MODUL -#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args) #else -#define TRACE_M(fmt, arg...) /**/ +#define TRACE_M(fmt, arg...) do {} while (0) #endif - #ifdef DEBUG_PROTO_S -#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args) #else -#define TRACE_PS(fmt, arg...) /**/ +#define TRACE_PS(fmt, arg...) do {} while (0) #endif - #ifdef DEBUG_PROTO_E -#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args) #else -#define TRACE_PE(fmt, arg...) /**/ +#define TRACE_PE(fmt, arg...) do {} while (0) #endif - #ifdef DEBUG_LDISC -#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args) #else -#define TRACE_L(fmt, arg...) /**/ +#define TRACE_L(fmt, arg...) do {} while (0) #endif - #ifdef DEBUG_QUEUE -#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args); +#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args) #else -#define TRACE_Q(fmt, arg...) /**/ +#define TRACE_Q(fmt, arg...) do {} while (0) #endif - static void add_tx_queue(struct r3964_info *, struct r3964_block_header *); static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code); static void put_char(struct r3964_info *pInfo, unsigned char ch); @@ -126,937 +120,830 @@ static void receive_char(struct r3964_info *pInfo, const unsigned char c); static void receive_error(struct r3964_info *pInfo, const char flag); static void on_timeout(unsigned long priv); static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg); -static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf); +static int read_telegram(struct r3964_info *pInfo, struct pid *pid, + unsigned char __user * buf); static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct r3964_block_header *pBlock); -static struct r3964_message* remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient); -static void remove_client_block(struct r3964_info *pInfo, - struct r3964_client_info *pClient); + int error_code, struct r3964_block_header *pBlock); +static struct r3964_message *remove_msg(struct r3964_info *pInfo, + struct r3964_client_info *pClient); +static void remove_client_block(struct r3964_info *pInfo, + struct r3964_client_info *pClient); -static int r3964_open(struct tty_struct *tty); +static int r3964_open(struct tty_struct *tty); static void r3964_close(struct tty_struct *tty); static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - unsigned char __user *buf, size_t nr); -static ssize_t r3964_write(struct tty_struct * tty, struct file * file, - const unsigned char * buf, size_t nr); -static int r3964_ioctl(struct tty_struct * tty, struct file * file, - unsigned int cmd, unsigned long arg); -static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old); -static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, - struct poll_table_struct *wait); + unsigned char __user * buf, size_t nr); +static ssize_t r3964_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t nr); +static int r3964_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); +static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, + struct poll_table_struct *wait); static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count); + char *fp, int count); static struct tty_ldisc tty_ldisc_N_R3964 = { - .owner = THIS_MODULE, - .magic = TTY_LDISC_MAGIC, - .name = "R3964", - .open = r3964_open, - .close = r3964_close, - .read = r3964_read, - .write = r3964_write, - .ioctl = r3964_ioctl, + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "R3964", + .open = r3964_open, + .close = r3964_close, + .read = r3964_read, + .write = r3964_write, + .ioctl = r3964_ioctl, .set_termios = r3964_set_termios, - .poll = r3964_poll, + .poll = r3964_poll, .receive_buf = r3964_receive_buf, }; - - static void dump_block(const unsigned char *block, unsigned int length) { - unsigned int i,j; - char linebuf[16*3+1]; - - for(i=0;i<length;i+=16) - { - for(j=0;(j<16) && (j+i<length);j++) - { - sprintf(linebuf+3*j,"%02x ",block[i+j]); - } - linebuf[3*j]='\0'; - TRACE_PS("%s",linebuf); - } + unsigned int i, j; + char linebuf[16 * 3 + 1]; + + for (i = 0; i < length; i += 16) { + for (j = 0; (j < 16) && (j + i < length); j++) { + sprintf(linebuf + 3 * j, "%02x ", block[i + j]); + } + linebuf[3 * j] = '\0'; + TRACE_PS("%s", linebuf); + } } - - - /************************************************************* * Driver initialisation *************************************************************/ - /************************************************************* * Module support routines *************************************************************/ static void __exit r3964_exit(void) { - int status; - - TRACE_M ("cleanup_module()"); - - status=tty_unregister_ldisc(N_R3964); - - if(status!=0) - { - printk(KERN_ERR "r3964: error unregistering linediscipline: %d\n", status); - } - else - { - TRACE_L("linediscipline successfully unregistered"); - } - + int status; + + TRACE_M("cleanup_module()"); + + status = tty_unregister_ldisc(N_R3964); + + if (status != 0) { + printk(KERN_ERR "r3964: error unregistering linediscipline: " + "%d\n", status); + } else { + TRACE_L("linediscipline successfully unregistered"); + } } static int __init r3964_init(void) { - int status; - - printk ("r3964: Philips r3964 Driver $Revision: 1.10 $\n"); - - /* - * Register the tty line discipline - */ - - status = tty_register_ldisc (N_R3964, &tty_ldisc_N_R3964); - if (status == 0) - { - TRACE_L("line discipline %d registered", N_R3964); - TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, - tty_ldisc_N_R3964.num); - TRACE_L("open=%p", tty_ldisc_N_R3964.open); - TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964); - } - else - { - printk (KERN_ERR "r3964: error registering line discipline: %d\n", status); - } - return status; + int status; + + printk("r3964: Philips r3964 Driver $Revision: 1.10 $\n"); + + /* + * Register the tty line discipline + */ + + status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964); + if (status == 0) { + TRACE_L("line discipline %d registered", N_R3964); + TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, + tty_ldisc_N_R3964.num); + TRACE_L("open=%p", tty_ldisc_N_R3964.open); + TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964); + } else { + printk(KERN_ERR "r3964: error registering line discipline: " + "%d\n", status); + } + return status; } module_init(r3964_init); module_exit(r3964_exit); - /************************************************************* * Protocol implementation routines *************************************************************/ -static void add_tx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader) +static void add_tx_queue(struct r3964_info *pInfo, + struct r3964_block_header *pHeader) { - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); - - pHeader->next = NULL; - - if(pInfo->tx_last == NULL) - { - pInfo->tx_first = pInfo->tx_last = pHeader; - } - else - { - pInfo->tx_last->next = pHeader; - pInfo->tx_last = pHeader; - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - TRACE_Q("add_tx_queue %p, length %d, tx_first = %p", - pHeader, pHeader->length, pInfo->tx_first ); + unsigned long flags; + + spin_lock_irqsave(&pInfo->lock, flags); + + pHeader->next = NULL; + + if (pInfo->tx_last == NULL) { + pInfo->tx_first = pInfo->tx_last = pHeader; + } else { + pInfo->tx_last->next = pHeader; + pInfo->tx_last = pHeader; + } + + spin_unlock_irqrestore(&pInfo->lock, flags); + + TRACE_Q("add_tx_queue %p, length %d, tx_first = %p", + pHeader, pHeader->length, pInfo->tx_first); } static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) { - struct r3964_block_header *pHeader; - unsigned long flags; + struct r3964_block_header *pHeader; + unsigned long flags; #ifdef DEBUG_QUEUE - struct r3964_block_header *pDump; + struct r3964_block_header *pDump; #endif - - pHeader = pInfo->tx_first; - if(pHeader==NULL) - return; + pHeader = pInfo->tx_first; + + if (pHeader == NULL) + return; #ifdef DEBUG_QUEUE - printk("r3964: remove_from_tx_queue: %p, length %u - ", - pHeader, pHeader->length ); - for(pDump=pHeader;pDump;pDump=pDump->next) - printk("%p ", pDump); - printk("\n"); + printk("r3964: remove_from_tx_queue: %p, length %u - ", + pHeader, pHeader->length); + for (pDump = pHeader; pDump; pDump = pDump->next) + printk("%p ", pDump); + printk("\n"); #endif + if (pHeader->owner) { + if (error_code) { + add_msg(pHeader->owner, R3964_MSG_ACK, 0, + error_code, NULL); + } else { + add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length, + error_code, NULL); + } + wake_up_interruptible(&pInfo->read_wait); + } + + spin_lock_irqsave(&pInfo->lock, flags); + + pInfo->tx_first = pHeader->next; + if (pInfo->tx_first == NULL) { + pInfo->tx_last = NULL; + } + + spin_unlock_irqrestore(&pInfo->lock, flags); + + kfree(pHeader); + TRACE_M("remove_from_tx_queue - kfree %p", pHeader); - if(pHeader->owner) - { - if(error_code) - { - add_msg(pHeader->owner, R3964_MSG_ACK, 0, - error_code, NULL); - } - else - { - add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length, - error_code, NULL); - } - wake_up_interruptible (&pInfo->read_wait); - } - - spin_lock_irqsave(&pInfo->lock, flags); - - pInfo->tx_first = pHeader->next; - if(pInfo->tx_first==NULL) - { - pInfo->tx_last = NULL; - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - kfree(pHeader); - TRACE_M("remove_from_tx_queue - kfree %p",pHeader); - - TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p", - pInfo->tx_first, pInfo->tx_last ); + TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p", + pInfo->tx_first, pInfo->tx_last); } -static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader) +static void add_rx_queue(struct r3964_info *pInfo, + struct r3964_block_header *pHeader) { - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); - - pHeader->next = NULL; - - if(pInfo->rx_last == NULL) - { - pInfo->rx_first = pInfo->rx_last = pHeader; - } - else - { - pInfo->rx_last->next = pHeader; - pInfo->rx_last = pHeader; - } - pInfo->blocks_in_rx_queue++; - - spin_unlock_irqrestore(&pInfo->lock, flags); - - TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d", - pHeader, pHeader->length, - pInfo->rx_first, pInfo->blocks_in_rx_queue); + unsigned long flags; + + spin_lock_irqsave(&pInfo->lock, flags); + + pHeader->next = NULL; + + if (pInfo->rx_last == NULL) { + pInfo->rx_first = pInfo->rx_last = pHeader; + } else { + pInfo->rx_last->next = pHeader; + pInfo->rx_last = pHeader; + } + pInfo->blocks_in_rx_queue++; + + spin_unlock_irqrestore(&pInfo->lock, flags); + + TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d", + pHeader, pHeader->length, + pInfo->rx_first, pInfo->blocks_in_rx_queue); } static void remove_from_rx_queue(struct r3964_info *pInfo, - struct r3964_block_header *pHeader) + struct r3964_block_header *pHeader) { - unsigned long flags; - struct r3964_block_header *pFind; - - if(pHeader==NULL) - return; - - TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", - pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue ); - TRACE_Q("remove_from_rx_queue: %p, length %u", - pHeader, pHeader->length ); - - spin_lock_irqsave(&pInfo->lock, flags); - - if(pInfo->rx_first == pHeader) - { - /* Remove the first block in the linked list: */ - pInfo->rx_first = pHeader->next; - - if(pInfo->rx_first==NULL) - { - pInfo->rx_last = NULL; - } - pInfo->blocks_in_rx_queue--; - } - else - { - /* Find block to remove: */ - for(pFind=pInfo->rx_first; pFind; pFind=pFind->next) - { - if(pFind->next == pHeader) - { - /* Got it. */ - pFind->next = pHeader->next; - pInfo->blocks_in_rx_queue--; - if(pFind->next==NULL) - { - /* Oh, removed the last one! */ - pInfo->rx_last = pFind; - } - break; - } - } - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - kfree(pHeader); - TRACE_M("remove_from_rx_queue - kfree %p",pHeader); - - TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", - pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue ); + unsigned long flags; + struct r3964_block_header *pFind; + + if (pHeader == NULL) + return; + + TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", + pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); + TRACE_Q("remove_from_rx_queue: %p, length %u", + pHeader, pHeader->length); + + spin_lock_irqsave(&pInfo->lock, flags); + + if (pInfo->rx_first == pHeader) { + /* Remove the first block in the linked list: */ + pInfo->rx_first = pHeader->next; + + if (pInfo->rx_first == NULL) { + pInfo->rx_last = NULL; + } + pInfo->blocks_in_rx_queue--; + } else { + /* Find block to remove: */ + for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) { + if (pFind->next == pHeader) { + /* Got it. */ + pFind->next = pHeader->next; + pInfo->blocks_in_rx_queue--; + if (pFind->next == NULL) { + /* Oh, removed the last one! */ + pInfo->rx_last = pFind; + } + break; + } + } + } + + spin_unlock_irqrestore(&pInfo->lock, flags); + + kfree(pHeader); + TRACE_M("remove_from_rx_queue - kfree %p", pHeader); + + TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", + pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); } static void put_char(struct r3964_info *pInfo, unsigned char ch) { - struct tty_struct *tty = pInfo->tty; + struct tty_struct *tty = pInfo->tty; - if(tty==NULL) - return; + if (tty == NULL) + return; - if(tty->driver->put_char) - { - tty->driver->put_char(tty, ch); - } - pInfo->bcc ^= ch; + if (tty->driver->put_char) { + tty->driver->put_char(tty, ch); + } + pInfo->bcc ^= ch; } static void flush(struct r3964_info *pInfo) { - struct tty_struct *tty = pInfo->tty; + struct tty_struct *tty = pInfo->tty; - if(tty==NULL) - return; + if (tty == NULL) + return; - if(tty->driver->flush_chars) - { - tty->driver->flush_chars(tty); - } + if (tty->driver->flush_chars) { + tty->driver->flush_chars(tty); + } } static void trigger_transmit(struct r3964_info *pInfo) { - unsigned long flags; - + unsigned long flags; - spin_lock_irqsave(&pInfo->lock, flags); + spin_lock_irqsave(&pInfo->lock, flags); - if((pInfo->state == R3964_IDLE) && (pInfo->tx_first!=NULL)) - { - pInfo->state = R3964_TX_REQUEST; - pInfo->nRetry=0; - pInfo->flags &= ~R3964_ERROR; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); + if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) { + pInfo->state = R3964_TX_REQUEST; + pInfo->nRetry = 0; + pInfo->flags &= ~R3964_ERROR; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - spin_unlock_irqrestore(&pInfo->lock, flags); + spin_unlock_irqrestore(&pInfo->lock, flags); - TRACE_PS("trigger_transmit - sent STX"); + TRACE_PS("trigger_transmit - sent STX"); - put_char(pInfo, STX); - flush(pInfo); + put_char(pInfo, STX); + flush(pInfo); - pInfo->bcc = 0; - } - else - { - spin_unlock_irqrestore(&pInfo->lock, flags); - } + pInfo->bcc = 0; + } else { + spin_unlock_irqrestore(&pInfo->lock, flags); + } } static void retry_transmit(struct r3964_info *pInfo) { - if(pInfo->nRetry<R3964_MAX_RETRIES) - { - TRACE_PE("transmission failed. Retry #%d", - pInfo->nRetry); - pInfo->bcc = 0; - put_char(pInfo, STX); - flush(pInfo); - pInfo->state = R3964_TX_REQUEST; - pInfo->nRetry++; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - } - else - { - TRACE_PE("transmission failed after %d retries", - R3964_MAX_RETRIES); - - remove_from_tx_queue(pInfo, R3964_TX_FAIL); - - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state = R3964_IDLE; - - trigger_transmit(pInfo); - } + if (pInfo->nRetry < R3964_MAX_RETRIES) { + TRACE_PE("transmission failed. Retry #%d", pInfo->nRetry); + pInfo->bcc = 0; + put_char(pInfo, STX); + flush(pInfo); + pInfo->state = R3964_TX_REQUEST; + pInfo->nRetry++; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); + } else { + TRACE_PE("transmission failed after %d retries", + R3964_MAX_RETRIES); + + remove_from_tx_queue(pInfo, R3964_TX_FAIL); + + put_char(pInfo, NAK); + flush(pInfo); + pInfo->state = R3964_IDLE; + + trigger_transmit(pInfo); + } } - static void transmit_block(struct r3964_info *pInfo) { - struct tty_struct *tty = pInfo->tty; - struct r3964_block_header *pBlock = pInfo->tx_first; - int room=0; - - if((tty==NULL) || (pBlock==NULL)) - { - return; - } - - if(tty->driver->write_room) - room=tty->driver->write_room(tty); - - TRACE_PS("transmit_block %p, room %d, length %d", - pBlock, room, pBlock->length); - - while(pInfo->tx_position < pBlock->length) - { - if(room<2) - break; - - if(pBlock->data[pInfo->tx_position]==DLE) - { - /* send additional DLE char: */ - put_char(pInfo, DLE); - } - put_char(pInfo, pBlock->data[pInfo->tx_position++]); - - room--; - } - - if((pInfo->tx_position == pBlock->length) && (room>=3)) - { - put_char(pInfo, DLE); - put_char(pInfo, ETX); - if(pInfo->flags & R3964_BCC) - { - put_char(pInfo, pInfo->bcc); - } - pInfo->state = R3964_WAIT_FOR_TX_ACK; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - } - flush(pInfo); + struct tty_struct *tty = pInfo->tty; + struct r3964_block_header *pBlock = pInfo->tx_first; + int room = 0; + + if ((tty == NULL) || (pBlock == NULL)) { + return; + } + + if (tty->driver->write_room) + room = tty->driver->write_room(tty); + + TRACE_PS("transmit_block %p, room %d, length %d", + pBlock, room, pBlock->length); + + while (pInfo->tx_position < pBlock->length) { + if (room < 2) + break; + + if (pBlock->data[pInfo->tx_position] == DLE) { + /* send additional DLE char: */ + put_char(pInfo, DLE); + } + put_char(pInfo, pBlock->data[pInfo->tx_position++]); + + room--; + } + + if ((pInfo->tx_position == pBlock->length) && (room >= 3)) { + put_char(pInfo, DLE); + put_char(pInfo, ETX); + if (pInfo->flags & R3964_BCC) { + put_char(pInfo, pInfo->bcc); + } + pInfo->state = R3964_WAIT_FOR_TX_ACK; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); + } + flush(pInfo); } static void on_receive_block(struct r3964_info *pInfo) { - unsigned int length; - struct r3964_client_info *pClient; - struct r3964_block_header *pBlock; - - length=pInfo->rx_position; - - /* compare byte checksum characters: */ - if(pInfo->flags & R3964_BCC) - { - if(pInfo->bcc!=pInfo->last_rx) - { - TRACE_PE("checksum error - got %x but expected %x", - pInfo->last_rx, pInfo->bcc); - pInfo->flags |= R3964_CHECKSUM; - } - } - - /* check for errors (parity, overrun,...): */ - if(pInfo->flags & R3964_ERROR) - { - TRACE_PE("on_receive_block - transmission failed error %x", - pInfo->flags & R3964_ERROR); - - put_char(pInfo, NAK); - flush(pInfo); - if(pInfo->nRetry<R3964_MAX_RETRIES) - { - pInfo->state=R3964_WAIT_FOR_RX_REPEAT; - pInfo->nRetry++; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC); - } - else - { - TRACE_PE("on_receive_block - failed after max retries"); - pInfo->state=R3964_IDLE; - } - return; - } - - - /* received block; submit DLE: */ - put_char(pInfo, DLE); - flush(pInfo); - del_timer_sync(&pInfo->tmr); - TRACE_PS(" rx success: got %d chars", length); - - /* prepare struct r3964_block_header: */ - pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL); - TRACE_M("on_receive_block - kmalloc %p",pBlock); - - if(pBlock==NULL) - return; - - pBlock->length = length; - pBlock->data = ((unsigned char*)pBlock)+sizeof(struct r3964_block_header); - pBlock->locks = 0; - pBlock->next = NULL; - pBlock->owner = NULL; - - memcpy(pBlock->data, pInfo->rx_buf, length); - - /* queue block into rx_queue: */ - add_rx_queue(pInfo, pBlock); - - /* notify attached client processes: */ - for(pClient=pInfo->firstClient; pClient; pClient=pClient->next) - { - if(pClient->sig_flags & R3964_SIG_DATA) - { - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, pBlock); - } - } - wake_up_interruptible (&pInfo->read_wait); - - pInfo->state = R3964_IDLE; - - trigger_transmit(pInfo); -} + unsigned int length; + struct r3964_client_info *pClient; + struct r3964_block_header *pBlock; + + length = pInfo->rx_position; + + /* compare byte checksum characters: */ + if (pInfo->flags & R3964_BCC) { + if (pInfo->bcc != pInfo->last_rx) { + TRACE_PE("checksum error - got %x but expected %x", + pInfo->last_rx, pInfo->bcc); + pInfo->flags |= R3964_CHECKSUM; + } + } + + /* check for errors (parity, overrun,...): */ + if (pInfo->flags & R3964_ERROR) { + TRACE_PE("on_receive_block - transmission failed error %x", + pInfo->flags & R3964_ERROR); + + put_char(pInfo, NAK); + flush(pInfo); + if (pInfo->nRetry < R3964_MAX_RETRIES) { + pInfo->state = R3964_WAIT_FOR_RX_REPEAT; + pInfo->nRetry++; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC); + } else { + TRACE_PE("on_receive_block - failed after max retries"); + pInfo->state = R3964_IDLE; + } + return; + } + + /* received block; submit DLE: */ + put_char(pInfo, DLE); + flush(pInfo); + del_timer_sync(&pInfo->tmr); + TRACE_PS(" rx success: got %d chars", length); + + /* prepare struct r3964_block_header: */ + pBlock = kmalloc(length + sizeof(struct r3964_block_header), + GFP_KERNEL); + TRACE_M("on_receive_block - kmalloc %p", pBlock); + + if (pBlock == NULL) + return; + + pBlock->length = length; + pBlock->data = ((unsigned char *)pBlock) + + sizeof(struct r3964_block_header); + pBlock->locks = 0; + pBlock->next = NULL; + pBlock->owner = NULL; + + memcpy(pBlock->data, pInfo->rx_buf, length); + + /* queue block into rx_queue: */ + add_rx_queue(pInfo, pBlock); + + /* notify attached client processes: */ + for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { + if (pClient->sig_flags & R3964_SIG_DATA) { + add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, + pBlock); + } + } + wake_up_interruptible(&pInfo->read_wait); + pInfo->state = R3964_IDLE; + + trigger_transmit(pInfo); +} static void receive_char(struct r3964_info *pInfo, const unsigned char c) { - switch(pInfo->state) - { - case R3964_TX_REQUEST: - if(c==DLE) - { - TRACE_PS("TX_REQUEST - got DLE"); - - pInfo->state = R3964_TRANSMITTING; - pInfo->tx_position = 0; - - transmit_block(pInfo); - } - else if(c==STX) - { - if(pInfo->nRetry==0) - { - TRACE_PE("TX_REQUEST - init conflict"); - if(pInfo->priority == R3964_SLAVE) - { - goto start_receiving; - } - } - else - { - TRACE_PE("TX_REQUEST - secondary init conflict!?" - " Switching to SLAVE mode for next rx."); - goto start_receiving; - } - } - else - { - TRACE_PE("TX_REQUEST - char != DLE: %x", c); - retry_transmit(pInfo); - } - break; - case R3964_TRANSMITTING: - if(c==NAK) - { - TRACE_PE("TRANSMITTING - got NAK"); - retry_transmit(pInfo); - } - else - { - TRACE_PE("TRANSMITTING - got invalid char"); - - pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - } - break; - case R3964_WAIT_FOR_TX_ACK: - if(c==DLE) - { - TRACE_PS("WAIT_FOR_TX_ACK - got DLE"); - remove_from_tx_queue(pInfo, R3964_OK); - - pInfo->state = R3964_IDLE; - trigger_transmit(pInfo); - } - else - { - retry_transmit(pInfo); - } - break; - case R3964_WAIT_FOR_RX_REPEAT: - /* FALLTROUGH */ - case R3964_IDLE: - if(c==STX) - { - /* Prevent rx_queue from overflow: */ - if(pInfo->blocks_in_rx_queue >= R3964_MAX_BLOCKS_IN_RX_QUEUE) - { - TRACE_PE("IDLE - got STX but no space in rx_queue!"); - pInfo->state=R3964_WAIT_FOR_RX_BUF; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_NO_BUF); - break; - } + switch (pInfo->state) { + case R3964_TX_REQUEST: + if (c == DLE) { + TRACE_PS("TX_REQUEST - got DLE"); + + pInfo->state = R3964_TRANSMITTING; + pInfo->tx_position = 0; + + transmit_block(pInfo); + } else if (c == STX) { + if (pInfo->nRetry == 0) { + TRACE_PE("TX_REQUEST - init conflict"); + if (pInfo->priority == R3964_SLAVE) { + goto start_receiving; + } + } else { + TRACE_PE("TX_REQUEST - secondary init " + "conflict!? Switching to SLAVE mode " + "for next rx."); + goto start_receiving; + } + } else { + TRACE_PE("TX_REQUEST - char != DLE: %x", c); + retry_transmit(pInfo); + } + break; + case R3964_TRANSMITTING: + if (c == NAK) { + TRACE_PE("TRANSMITTING - got NAK"); + retry_transmit(pInfo); + } else { + TRACE_PE("TRANSMITTING - got invalid char"); + + pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); + } + break; + case R3964_WAIT_FOR_TX_ACK: + if (c == DLE) { + TRACE_PS("WAIT_FOR_TX_ACK - got DLE"); + remove_from_tx_queue(pInfo, R3964_OK); + + pInfo->state = R3964_IDLE; + trigger_transmit(pInfo); + } else { + retry_transmit(pInfo); + } + break; + case R3964_WAIT_FOR_RX_REPEAT: + /* FALLTROUGH */ + case R3964_IDLE: + if (c == STX) { + /* Prevent rx_queue from overflow: */ + if (pInfo->blocks_in_rx_queue >= + R3964_MAX_BLOCKS_IN_RX_QUEUE) { + TRACE_PE("IDLE - got STX but no space in " + "rx_queue!"); + pInfo->state = R3964_WAIT_FOR_RX_BUF; + mod_timer(&pInfo->tmr, + jiffies + R3964_TO_NO_BUF); + break; + } start_receiving: - /* Ok, start receiving: */ - TRACE_PS("IDLE - got STX"); - pInfo->rx_position = 0; - pInfo->last_rx = 0; - pInfo->flags &= ~R3964_ERROR; - pInfo->state=R3964_RECEIVING; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - pInfo->nRetry = 0; - put_char(pInfo, DLE); - flush(pInfo); - pInfo->bcc = 0; - } - break; - case R3964_RECEIVING: - if(pInfo->rx_position < RX_BUF_SIZE) - { - pInfo->bcc ^= c; - - if(c==DLE) - { - if(pInfo->last_rx==DLE) - { - pInfo->last_rx = 0; - goto char_to_buf; - } - pInfo->last_rx = DLE; - break; - } - else if((c==ETX) && (pInfo->last_rx==DLE)) - { - if(pInfo->flags & R3964_BCC) - { - pInfo->state = R3964_WAIT_FOR_BCC; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - } - else - { - on_receive_block(pInfo); - } - } - else - { - pInfo->last_rx = c; + /* Ok, start receiving: */ + TRACE_PS("IDLE - got STX"); + pInfo->rx_position = 0; + pInfo->last_rx = 0; + pInfo->flags &= ~R3964_ERROR; + pInfo->state = R3964_RECEIVING; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); + pInfo->nRetry = 0; + put_char(pInfo, DLE); + flush(pInfo); + pInfo->bcc = 0; + } + break; + case R3964_RECEIVING: + if (pInfo->rx_position < RX_BUF_SIZE) { + pInfo->bcc ^= c; + + if (c == DLE) { + if (pInfo->last_rx == DLE) { + pInfo->last_rx = 0; + goto char_to_buf; + } + pInfo->last_rx = DLE; + break; + } else if ((c == ETX) && (pInfo->last_rx == DLE)) { + if (pInfo->flags & R3964_BCC) { + pInfo->state = R3964_WAIT_FOR_BCC; + mod_timer(&pInfo->tmr, + jiffies + R3964_TO_ZVZ); + } else { + on_receive_block(pInfo); + } + } else { + pInfo->last_rx = c; char_to_buf: - pInfo->rx_buf[pInfo->rx_position++] = c; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - } - } - /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */ - break; - case R3964_WAIT_FOR_BCC: - pInfo->last_rx = c; - on_receive_block(pInfo); - break; - } + pInfo->rx_buf[pInfo->rx_position++] = c; + mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); + } + } + /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */ + break; + case R3964_WAIT_FOR_BCC: + pInfo->last_rx = c; + on_receive_block(pInfo); + break; + } } static void receive_error(struct r3964_info *pInfo, const char flag) { - switch (flag) - { - case TTY_NORMAL: - break; - case TTY_BREAK: - TRACE_PE("received break") - pInfo->flags |= R3964_BREAK; - break; - case TTY_PARITY: - TRACE_PE("parity error") - pInfo->flags |= R3964_PARITY; - break; - case TTY_FRAME: - TRACE_PE("frame error") - pInfo->flags |= R3964_FRAME; - break; - case TTY_OVERRUN: - TRACE_PE("frame overrun") - pInfo->flags |= R3964_OVERRUN; - break; - default: - TRACE_PE("receive_error - unknown flag %d", flag); - pInfo->flags |= R3964_UNKNOWN; - break; - } + switch (flag) { + case TTY_NORMAL: + break; + case TTY_BREAK: + TRACE_PE("received break"); + pInfo->flags |= R3964_BREAK; + break; + case TTY_PARITY: + TRACE_PE("parity error"); + pInfo->flags |= R3964_PARITY; + break; + case TTY_FRAME: + TRACE_PE("frame error"); + pInfo->flags |= R3964_FRAME; + break; + case TTY_OVERRUN: + TRACE_PE("frame overrun"); + pInfo->flags |= R3964_OVERRUN; + break; + default: + TRACE_PE("receive_error - unknown flag %d", flag); + pInfo->flags |= R3964_UNKNOWN; + break; + } } static void on_timeout(unsigned long priv) { - struct r3964_info *pInfo = (void *)priv; - - switch(pInfo->state) - { - case R3964_TX_REQUEST: - TRACE_PE("TX_REQUEST - timeout"); - retry_transmit(pInfo); - break; - case R3964_WAIT_ZVZ_BEFORE_TX_RETRY: - put_char(pInfo, NAK); - flush(pInfo); - retry_transmit(pInfo); - break; - case R3964_WAIT_FOR_TX_ACK: - TRACE_PE("WAIT_FOR_TX_ACK - timeout"); - retry_transmit(pInfo); - break; - case R3964_WAIT_FOR_RX_BUF: - TRACE_PE("WAIT_FOR_RX_BUF - timeout"); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state=R3964_IDLE; - break; - case R3964_RECEIVING: - TRACE_PE("RECEIVING - timeout after %d chars", - pInfo->rx_position); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state=R3964_IDLE; - break; - case R3964_WAIT_FOR_RX_REPEAT: - TRACE_PE("WAIT_FOR_RX_REPEAT - timeout"); - pInfo->state=R3964_IDLE; - break; - case R3964_WAIT_FOR_BCC: - TRACE_PE("WAIT_FOR_BCC - timeout"); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state=R3964_IDLE; - break; - } + struct r3964_info *pInfo = (void *)priv; + + switch (pInfo->state) { + case R3964_TX_REQUEST: + TRACE_PE("TX_REQUEST - timeout"); + retry_transmit(pInfo); + break; + case R3964_WAIT_ZVZ_BEFORE_TX_RETRY: + put_char(pInfo, NAK); + flush(pInfo); + retry_transmit(pInfo); + break; + case R3964_WAIT_FOR_TX_ACK: + TRACE_PE("WAIT_FOR_TX_ACK - timeout"); + retry_transmit(pInfo); + break; + case R3964_WAIT_FOR_RX_BUF: + TRACE_PE("WAIT_FOR_RX_BUF - timeout"); + put_char(pInfo, NAK); + flush(pInfo); + pInfo->state = R3964_IDLE; + break; + case R3964_RECEIVING: + TRACE_PE("RECEIVING - timeout after %d chars", + pInfo->rx_position); + put_char(pInfo, NAK); + flush(pInfo); + pInfo->state = R3964_IDLE; + break; + case R3964_WAIT_FOR_RX_REPEAT: + TRACE_PE("WAIT_FOR_RX_REPEAT - timeout"); + pInfo->state = R3964_IDLE; + break; + case R3964_WAIT_FOR_BCC: + TRACE_PE("WAIT_FOR_BCC - timeout"); + put_char(pInfo, NAK); + flush(pInfo); + pInfo->state = R3964_IDLE; + break; + } } -static struct r3964_client_info *findClient( - struct r3964_info *pInfo, struct pid *pid) +static struct r3964_client_info *findClient(struct r3964_info *pInfo, + struct pid *pid) { - struct r3964_client_info *pClient; - - for(pClient=pInfo->firstClient; pClient; pClient=pClient->next) - { - if(pClient->pid == pid) - { - return pClient; - } - } - return NULL; + struct r3964_client_info *pClient; + + for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { + if (pClient->pid == pid) { + return pClient; + } + } + return NULL; } static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) { - struct r3964_client_info *pClient; - struct r3964_client_info **ppClient; - struct r3964_message *pMsg; - - if((arg & R3964_SIG_ALL)==0) - { - /* Remove client from client list */ - for(ppClient=&pInfo->firstClient; *ppClient; ppClient=&(*ppClient)->next) - { - pClient = *ppClient; - - if(pClient->pid == pid) - { - TRACE_PS("removing client %d from client list", pid_nr(pid)); - *ppClient = pClient->next; - while(pClient->msg_count) - { - pMsg=remove_msg(pInfo, pClient); - if(pMsg) - { - kfree(pMsg); - TRACE_M("enable_signals - msg kfree %p",pMsg); - } - } - put_pid(pClient->pid); - kfree(pClient); - TRACE_M("enable_signals - kfree %p",pClient); - return 0; - } - } - return -EINVAL; - } - else - { - pClient=findClient(pInfo, pid); - if(pClient) - { - /* update signal options */ - pClient->sig_flags=arg; - } - else - { - /* add client to client list */ - pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL); - TRACE_M("enable_signals - kmalloc %p",pClient); - if(pClient==NULL) - return -ENOMEM; - - TRACE_PS("add client %d to client list", pid_nr(pid)); - spin_lock_init(&pClient->lock); - pClient->sig_flags=arg; - pClient->pid = get_pid(pid); - pClient->next=pInfo->firstClient; - pClient->first_msg = NULL; - pClient->last_msg = NULL; - pClient->next_block_to_read = NULL; - pClient->msg_count = 0; - pInfo->firstClient=pClient; - } - } - - return 0; + struct r3964_client_info *pClient; + struct r3964_client_info **ppClient; + struct r3964_message *pMsg; + + if ((arg & R3964_SIG_ALL) == 0) { + /* Remove client from client list */ + for (ppClient = &pInfo->firstClient; *ppClient; + ppClient = &(*ppClient)->next) { + pClient = *ppClient; + + if (pClient->pid == pid) { + TRACE_PS("removing client %d from client list", + pid_nr(pid)); + *ppClient = pClient->next; + while (pClient->msg_count) { + pMsg = remove_msg(pInfo, pClient); + if (pMsg) { + kfree(pMsg); + TRACE_M("enable_signals - msg " + "kfree %p", pMsg); + } + } + put_pid(pClient->pid); + kfree(pClient); + TRACE_M("enable_signals - kfree %p", pClient); + return 0; + } + } + return -EINVAL; + } else { + pClient = findClient(pInfo, pid); + if (pClient) { + /* update signal options */ + pClient->sig_flags = arg; + } else { + /* add client to client list */ + pClient = kmalloc(sizeof(struct r3964_client_info), + GFP_KERNEL); + TRACE_M("enable_signals - kmalloc %p", pClient); + if (pClient == NULL) + return -ENOMEM; + + TRACE_PS("add client %d to client list", pid_nr(pid)); + spin_lock_init(&pClient->lock); + pClient->sig_flags = arg; + pClient->pid = get_pid(pid); + pClient->next = pInfo->firstClient; + pClient->first_msg = NULL; + pClient->last_msg = NULL; + pClient->next_block_to_read = NULL; + pClient->msg_count = 0; + pInfo->firstClient = pClient; + } + } + + return 0; } -static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf) +static int read_telegram(struct r3964_info *pInfo, struct pid *pid, + unsigned char __user * buf) { - struct r3964_client_info *pClient; - struct r3964_block_header *block; - - if(!buf) - { - return -EINVAL; - } - - pClient=findClient(pInfo,pid); - if(pClient==NULL) - { - return -EINVAL; - } - - block=pClient->next_block_to_read; - if(!block) - { - return 0; - } - else - { - if (copy_to_user (buf, block->data, block->length)) - return -EFAULT; - - remove_client_block(pInfo, pClient); - return block->length; - } - - return -EINVAL; + struct r3964_client_info *pClient; + struct r3964_block_header *block; + + if (!buf) { + return -EINVAL; + } + + pClient = findClient(pInfo, pid); + if (pClient == NULL) { + return -EINVAL; + } + + block = pClient->next_block_to_read; + if (!block) { + return 0; + } else { + if (copy_to_user(buf, block->data, block->length)) + return -EFAULT; + + remove_client_block(pInfo, pClient); + return block->length; + } + + return -EINVAL; } static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct r3964_block_header *pBlock) + int error_code, struct r3964_block_header *pBlock) { - struct r3964_message *pMsg; - unsigned long flags; - - if(pClient->msg_count<R3964_MAX_MSG_COUNT-1) - { + struct r3964_message *pMsg; + unsigned long flags; + + if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) { queue_the_message: - pMsg = kmalloc(sizeof(struct r3964_message), - error_code?GFP_ATOMIC:GFP_KERNEL); - TRACE_M("add_msg - kmalloc %p",pMsg); - if(pMsg==NULL) { - return; - } - - spin_lock_irqsave(&pClient->lock, flags); - - pMsg->msg_id = msg_id; - pMsg->arg = arg; - pMsg->error_code = error_code; - pMsg->block = pBlock; - pMsg->next = NULL; - - if(pClient->last_msg==NULL) - { - pClient->first_msg=pClient->last_msg=pMsg; - } - else - { - pClient->last_msg->next = pMsg; - pClient->last_msg=pMsg; - } - - pClient->msg_count++; - - if(pBlock!=NULL) - { - pBlock->locks++; - } - spin_unlock_irqrestore(&pClient->lock, flags); - } - else - { - if((pClient->last_msg->msg_id == R3964_MSG_ACK) - && (pClient->last_msg->error_code==R3964_OVERFLOW)) - { - pClient->last_msg->arg++; - TRACE_PE("add_msg - inc prev OVERFLOW-msg"); - } - else - { - msg_id = R3964_MSG_ACK; - arg = 0; - error_code = R3964_OVERFLOW; - pBlock = NULL; - TRACE_PE("add_msg - queue OVERFLOW-msg"); - goto queue_the_message; - } - } - /* Send SIGIO signal to client process: */ - if(pClient->sig_flags & R3964_USE_SIGIO) - { - kill_pid(pClient->pid, SIGIO, 1); - } + pMsg = kmalloc(sizeof(struct r3964_message), + error_code ? GFP_ATOMIC : GFP_KERNEL); + TRACE_M("add_msg - kmalloc %p", pMsg); + if (pMsg == NULL) { + return; + } + + spin_lock_irqsave(&pClient->lock, flags); + + pMsg->msg_id = msg_id; + pMsg->arg = arg; + pMsg->error_code = error_code; + pMsg->block = pBlock; + pMsg->next = NULL; + + if (pClient->last_msg == NULL) { + pClient->first_msg = pClient->last_msg = pMsg; + } else { + pClient->last_msg->next = pMsg; + pClient->last_msg = pMsg; + } + + pClient->msg_count++; + + if (pBlock != NULL) { + pBlock->locks++; + } + spin_unlock_irqrestore(&pClient->lock, flags); + } else { + if ((pClient->last_msg->msg_id == R3964_MSG_ACK) + && (pClient->last_msg->error_code == R3964_OVERFLOW)) { + pClient->last_msg->arg++; + TRACE_PE("add_msg - inc prev OVERFLOW-msg"); + } else { + msg_id = R3964_MSG_ACK; + arg = 0; + error_code = R3964_OVERFLOW; + pBlock = NULL; + TRACE_PE("add_msg - queue OVERFLOW-msg"); + goto queue_the_message; + } + } + /* Send SIGIO signal to client process: */ + if (pClient->sig_flags & R3964_USE_SIGIO) { + kill_pid(pClient->pid, SIGIO, 1); + } } static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient) + struct r3964_client_info *pClient) { - struct r3964_message *pMsg=NULL; - unsigned long flags; - - if(pClient->first_msg) - { - spin_lock_irqsave(&pClient->lock, flags); - - pMsg = pClient->first_msg; - pClient->first_msg = pMsg->next; - if(pClient->first_msg==NULL) - { - pClient->last_msg = NULL; - } - - pClient->msg_count--; - if(pMsg->block) - { - remove_client_block(pInfo, pClient); - pClient->next_block_to_read = pMsg->block; - } - spin_unlock_irqrestore(&pClient->lock, flags); - } - return pMsg; + struct r3964_message *pMsg = NULL; + unsigned long flags; + + if (pClient->first_msg) { + spin_lock_irqsave(&pClient->lock, flags); + + pMsg = pClient->first_msg; + pClient->first_msg = pMsg->next; + if (pClient->first_msg == NULL) { + pClient->last_msg = NULL; + } + + pClient->msg_count--; + if (pMsg->block) { + remove_client_block(pInfo, pClient); + pClient->next_block_to_read = pMsg->block; + } + spin_unlock_irqrestore(&pClient->lock, flags); + } + return pMsg; } -static void remove_client_block(struct r3964_info *pInfo, - struct r3964_client_info *pClient) +static void remove_client_block(struct r3964_info *pInfo, + struct r3964_client_info *pClient) { - struct r3964_block_header *block; - - TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); - - block=pClient->next_block_to_read; - if(block) - { - block->locks--; - if(block->locks==0) - { - remove_from_rx_queue(pInfo, block); - } - } - pClient->next_block_to_read = NULL; -} + struct r3964_block_header *block; + + TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); + block = pClient->next_block_to_read; + if (block) { + block->locks--; + if (block->locks == 0) { + remove_from_rx_queue(pInfo, block); + } + } + pClient->next_block_to_read = NULL; +} /************************************************************* * Line discipline routines @@ -1064,342 +951,320 @@ static void remove_client_block(struct r3964_info *pInfo, static int r3964_open(struct tty_struct *tty) { - struct r3964_info *pInfo; - - TRACE_L("open"); - TRACE_L("tty=%p, PID=%d, disc_data=%p", - tty, current->pid, tty->disc_data); - - pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL); - TRACE_M("r3964_open - info kmalloc %p",pInfo); - - if(!pInfo) - { - printk(KERN_ERR "r3964: failed to alloc info structure\n"); - return -ENOMEM; - } - - pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); - TRACE_M("r3964_open - rx_buf kmalloc %p",pInfo->rx_buf); - - if(!pInfo->rx_buf) - { - printk(KERN_ERR "r3964: failed to alloc receive buffer\n"); - kfree(pInfo); - TRACE_M("r3964_open - info kfree %p",pInfo); - return -ENOMEM; - } - - pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL); - TRACE_M("r3964_open - tx_buf kmalloc %p",pInfo->tx_buf); - - if(!pInfo->tx_buf) - { - printk(KERN_ERR "r3964: failed to alloc transmit buffer\n"); - kfree(pInfo->rx_buf); - TRACE_M("r3964_open - rx_buf kfree %p",pInfo->rx_buf); - kfree(pInfo); - TRACE_M("r3964_open - info kfree %p",pInfo); - return -ENOMEM; - } - - spin_lock_init(&pInfo->lock); - pInfo->tty = tty; - init_waitqueue_head (&pInfo->read_wait); - pInfo->priority = R3964_MASTER; - pInfo->rx_first = pInfo->rx_last = NULL; - pInfo->tx_first = pInfo->tx_last = NULL; - pInfo->rx_position = 0; - pInfo->tx_position = 0; - pInfo->last_rx = 0; - pInfo->blocks_in_rx_queue = 0; - pInfo->firstClient=NULL; - pInfo->state=R3964_IDLE; - pInfo->flags = R3964_DEBUG; - pInfo->nRetry = 0; - - tty->disc_data = pInfo; - tty->receive_room = 65536; - - init_timer(&pInfo->tmr); - pInfo->tmr.data = (unsigned long)pInfo; - pInfo->tmr.function = on_timeout; - - return 0; + struct r3964_info *pInfo; + + TRACE_L("open"); + TRACE_L("tty=%p, PID=%d, disc_data=%p", + tty, current->pid, tty->disc_data); + + pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL); + TRACE_M("r3964_open - info kmalloc %p", pInfo); + + if (!pInfo) { + printk(KERN_ERR "r3964: failed to alloc info structure\n"); + return -ENOMEM; + } + + pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); + TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf); + + if (!pInfo->rx_buf) { + printk(KERN_ERR "r3964: failed to alloc receive buffer\n"); + kfree(pInfo); + TRACE_M("r3964_open - info kfree %p", pInfo); + return -ENOMEM; + } + + pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL); + TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf); + + if (!pInfo->tx_buf) { + printk(KERN_ERR "r3964: failed to alloc transmit buffer\n"); + kfree(pInfo->rx_buf); + TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf); + kfree(pInfo); + TRACE_M("r3964_open - info kfree %p", pInfo); + return -ENOMEM; + } + + spin_lock_init(&pInfo->lock); + pInfo->tty = tty; + init_waitqueue_head(&pInfo->read_wait); + pInfo->priority = R3964_MASTER; + pInfo->rx_first = pInfo->rx_last = NULL; + pInfo->tx_first = pInfo->tx_last = NULL; + pInfo->rx_position = 0; + pInfo->tx_position = 0; + pInfo->last_rx = 0; + pInfo->blocks_in_rx_queue = 0; + pInfo->firstClient = NULL; + pInfo->state = R3964_IDLE; + pInfo->flags = R3964_DEBUG; + pInfo->nRetry = 0; + + tty->disc_data = pInfo; + tty->receive_room = 65536; + + init_timer(&pInfo->tmr); + pInfo->tmr.data = (unsigned long)pInfo; + pInfo->tmr.function = on_timeout; + + return 0; } static void r3964_close(struct tty_struct *tty) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - struct r3964_client_info *pClient, *pNext; - struct r3964_message *pMsg; - struct r3964_block_header *pHeader, *pNextHeader; - unsigned long flags; - - TRACE_L("close"); - - /* - * Make sure that our task queue isn't activated. If it - * is, take it out of the linked list. - */ - del_timer_sync(&pInfo->tmr); - - /* Remove client-structs and message queues: */ - pClient=pInfo->firstClient; - while(pClient) - { - pNext=pClient->next; - while(pClient->msg_count) - { - pMsg=remove_msg(pInfo, pClient); - if(pMsg) - { - kfree(pMsg); - TRACE_M("r3964_close - msg kfree %p",pMsg); - } - } - put_pid(pClient->pid); - kfree(pClient); - TRACE_M("r3964_close - client kfree %p",pClient); - pClient=pNext; - } - /* Remove jobs from tx_queue: */ - spin_lock_irqsave(&pInfo->lock, flags); - pHeader=pInfo->tx_first; - pInfo->tx_first=pInfo->tx_last=NULL; + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + struct r3964_client_info *pClient, *pNext; + struct r3964_message *pMsg; + struct r3964_block_header *pHeader, *pNextHeader; + unsigned long flags; + + TRACE_L("close"); + + /* + * Make sure that our task queue isn't activated. If it + * is, take it out of the linked list. + */ + del_timer_sync(&pInfo->tmr); + + /* Remove client-structs and message queues: */ + pClient = pInfo->firstClient; + while (pClient) { + pNext = pClient->next; + while (pClient->msg_count) { + pMsg = remove_msg(pInfo, pClient); + if (pMsg) { + kfree(pMsg); + TRACE_M("r3964_close - msg kfree %p", pMsg); + } + } + put_pid(pClient->pid); + kfree(pClient); + TRACE_M("r3964_close - client kfree %p", pClient); + pClient = pNext; + } + /* Remove jobs from tx_queue: */ + spin_lock_irqsave(&pInfo->lock, flags); + pHeader = pInfo->tx_first; + pInfo->tx_first = pInfo->tx_last = NULL; spin_unlock_irqrestore(&pInfo->lock, flags); - - while(pHeader) - { - pNextHeader=pHeader->next; - kfree(pHeader); - pHeader=pNextHeader; + + while (pHeader) { + pNextHeader = pHeader->next; + kfree(pHeader); + pHeader = pNextHeader; } - /* Free buffers: */ - wake_up_interruptible(&pInfo->read_wait); - kfree(pInfo->rx_buf); - TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf); - kfree(pInfo->tx_buf); - TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf); - kfree(pInfo); - TRACE_M("r3964_close - info kfree %p",pInfo); + /* Free buffers: */ + wake_up_interruptible(&pInfo->read_wait); + kfree(pInfo->rx_buf); + TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf); + kfree(pInfo->tx_buf); + TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf); + kfree(pInfo); + TRACE_M("r3964_close - info kfree %p", pInfo); } static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - unsigned char __user *buf, size_t nr) + unsigned char __user * buf, size_t nr) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - struct r3964_client_info *pClient; - struct r3964_message *pMsg; - struct r3964_client_message theMsg; - DECLARE_WAITQUEUE (wait, current); - - int count; - - TRACE_L("read()"); - - pClient=findClient(pInfo, task_pid(current)); - if(pClient) - { - pMsg = remove_msg(pInfo, pClient); - if(pMsg==NULL) - { - /* no messages available. */ - if (file->f_flags & O_NONBLOCK) - { - return -EAGAIN; - } - /* block until there is a message: */ - add_wait_queue(&pInfo->read_wait, &wait); + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + struct r3964_client_info *pClient; + struct r3964_message *pMsg; + struct r3964_client_message theMsg; + DECLARE_WAITQUEUE(wait, current); + + int count; + + TRACE_L("read()"); + + pClient = findClient(pInfo, task_pid(current)); + if (pClient) { + pMsg = remove_msg(pInfo, pClient); + if (pMsg == NULL) { + /* no messages available. */ + if (file->f_flags & O_NONBLOCK) { + return -EAGAIN; + } + /* block until there is a message: */ + add_wait_queue(&pInfo->read_wait, &wait); repeat: - current->state = TASK_INTERRUPTIBLE; - pMsg = remove_msg(pInfo, pClient); - if (!pMsg && !signal_pending(current)) - { - schedule(); - goto repeat; - } - current->state = TASK_RUNNING; - remove_wait_queue(&pInfo->read_wait, &wait); - } - - /* If we still haven't got a message, we must have been signalled */ - - if (!pMsg) return -EINTR; - - /* deliver msg to client process: */ - theMsg.msg_id = pMsg->msg_id; - theMsg.arg = pMsg->arg; - theMsg.error_code = pMsg->error_code; - count = sizeof(struct r3964_client_message); - - kfree(pMsg); - TRACE_M("r3964_read - msg kfree %p",pMsg); - - if (copy_to_user(buf,&theMsg, count)) - return -EFAULT; - - TRACE_PS("read - return %d", count); - return count; - } - return -EPERM; + current->state = TASK_INTERRUPTIBLE; + pMsg = remove_msg(pInfo, pClient); + if (!pMsg && !signal_pending(current)) { + schedule(); + goto repeat; + } + current->state = TASK_RUNNING; + remove_wait_queue(&pInfo->read_wait, &wait); + } + + /* If we still haven't got a message, we must have been signalled */ + + if (!pMsg) + return -EINTR; + + /* deliver msg to client process: */ + theMsg.msg_id = pMsg->msg_id; + theMsg.arg = pMsg->arg; + theMsg.error_code = pMsg->error_code; + count = sizeof(struct r3964_client_message); + + kfree(pMsg); + TRACE_M("r3964_read - msg kfree %p", pMsg); + + if (copy_to_user(buf, &theMsg, count)) + return -EFAULT; + + TRACE_PS("read - return %d", count); + return count; + } + return -EPERM; } -static ssize_t r3964_write(struct tty_struct * tty, struct file * file, +static ssize_t r3964_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - struct r3964_block_header *pHeader; - struct r3964_client_info *pClient; - unsigned char *new_data; - - TRACE_L("write request, %d characters", count); + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + struct r3964_block_header *pHeader; + struct r3964_client_info *pClient; + unsigned char *new_data; + + TRACE_L("write request, %d characters", count); /* * Verify the pointers */ - if(!pInfo) - return -EIO; + if (!pInfo) + return -EIO; /* * Ensure that the caller does not wish to send too much. */ - if (count > R3964_MTU) - { - if (pInfo->flags & R3964_DEBUG) - { - TRACE_L (KERN_WARNING - "r3964_write: truncating user packet " - "from %u to mtu %d", count, R3964_MTU); - } - count = R3964_MTU; - } + if (count > R3964_MTU) { + if (pInfo->flags & R3964_DEBUG) { + TRACE_L(KERN_WARNING "r3964_write: truncating user " + "packet from %u to mtu %d", count, R3964_MTU); + } + count = R3964_MTU; + } /* * Allocate a buffer for the data and copy it from the buffer with header prepended */ - new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL); - TRACE_M("r3964_write - kmalloc %p",new_data); - if (new_data == NULL) { - if (pInfo->flags & R3964_DEBUG) - { - printk (KERN_ERR - "r3964_write: no memory\n"); - } - return -ENOSPC; - } - - pHeader = (struct r3964_block_header *)new_data; - pHeader->data = new_data + sizeof(struct r3964_block_header); - pHeader->length = count; - pHeader->locks = 0; - pHeader->owner = NULL; - - pClient=findClient(pInfo, task_pid(current)); - if(pClient) - { - pHeader->owner = pClient; - } - - memcpy(pHeader->data, data, count); /* We already verified this */ - - if(pInfo->flags & R3964_DEBUG) - { - dump_block(pHeader->data, count); - } + new_data = kmalloc(count + sizeof(struct r3964_block_header), + GFP_KERNEL); + TRACE_M("r3964_write - kmalloc %p", new_data); + if (new_data == NULL) { + if (pInfo->flags & R3964_DEBUG) { + printk(KERN_ERR "r3964_write: no memory\n"); + } + return -ENOSPC; + } + + pHeader = (struct r3964_block_header *)new_data; + pHeader->data = new_data + sizeof(struct r3964_block_header); + pHeader->length = count; + pHeader->locks = 0; + pHeader->owner = NULL; + + pClient = findClient(pInfo, task_pid(current)); + if (pClient) { + pHeader->owner = pClient; + } + + memcpy(pHeader->data, data, count); /* We already verified this */ + + if (pInfo->flags & R3964_DEBUG) { + dump_block(pHeader->data, count); + } /* * Add buffer to transmit-queue: */ - add_tx_queue(pInfo, pHeader); - trigger_transmit(pInfo); - - return 0; + add_tx_queue(pInfo, pHeader); + trigger_transmit(pInfo); + + return 0; } -static int r3964_ioctl(struct tty_struct * tty, struct file * file, - unsigned int cmd, unsigned long arg) +static int r3964_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - if(pInfo==NULL) - return -EINVAL; - switch(cmd) - { - case R3964_ENABLE_SIGNALS: - return enable_signals(pInfo, task_pid(current), arg); - case R3964_SETPRIORITY: - if(arg<R3964_MASTER || arg>R3964_SLAVE) - return -EINVAL; - pInfo->priority = arg & 0xff; - return 0; - case R3964_USE_BCC: - if(arg) - pInfo->flags |= R3964_BCC; - else - pInfo->flags &= ~R3964_BCC; - return 0; - case R3964_READ_TELEGRAM: - return read_telegram(pInfo, task_pid(current), (unsigned char __user *)arg); - default: - return -ENOIOCTLCMD; - } + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + if (pInfo == NULL) + return -EINVAL; + switch (cmd) { + case R3964_ENABLE_SIGNALS: + return enable_signals(pInfo, task_pid(current), arg); + case R3964_SETPRIORITY: + if (arg < R3964_MASTER || arg > R3964_SLAVE) + return -EINVAL; + pInfo->priority = arg & 0xff; + return 0; + case R3964_USE_BCC: + if (arg) + pInfo->flags |= R3964_BCC; + else + pInfo->flags &= ~R3964_BCC; + return 0; + case R3964_READ_TELEGRAM: + return read_telegram(pInfo, task_pid(current), + (unsigned char __user *)arg); + default: + return -ENOIOCTLCMD; + } } -static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old) +static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old) { - TRACE_L("set_termios"); + TRACE_L("set_termios"); } /* Called without the kernel lock held - fine */ -static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, - struct poll_table_struct *wait) +static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, + struct poll_table_struct *wait) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - struct r3964_client_info *pClient; - struct r3964_message *pMsg=NULL; - unsigned long flags; - int result = POLLOUT; - - TRACE_L("POLL"); - - pClient=findClient(pInfo, task_pid(current)); - if(pClient) - { - poll_wait(file, &pInfo->read_wait, wait); - spin_lock_irqsave(&pInfo->lock, flags); - pMsg=pClient->first_msg; - spin_unlock_irqrestore(&pInfo->lock, flags); - if(pMsg) - result |= POLLIN | POLLRDNORM; - } - else - { - result = -EINVAL; - } - return result; + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + struct r3964_client_info *pClient; + struct r3964_message *pMsg = NULL; + unsigned long flags; + int result = POLLOUT; + + TRACE_L("POLL"); + + pClient = findClient(pInfo, task_pid(current)); + if (pClient) { + poll_wait(file, &pInfo->read_wait, wait); + spin_lock_irqsave(&pInfo->lock, flags); + pMsg = pClient->first_msg; + spin_unlock_irqrestore(&pInfo->lock, flags); + if (pMsg) + result |= POLLIN | POLLRDNORM; + } else { + result = -EINVAL; + } + return result; } static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + char *fp, int count) { - struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; - const unsigned char *p; - char *f, flags = 0; - int i; - - for (i=count, p = cp, f = fp; i; i--, p++) { - if (f) - flags = *f++; - if(flags==TTY_NORMAL) - { - receive_char(pInfo, *p); - } - else - { - receive_error(pInfo, flags); - } - - } + struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data; + const unsigned char *p; + char *f, flags = 0; + int i; + + for (i = count, p = cp, f = fp; i; i--, p++) { + if (f) + flags = *f++; + if (flags == TTY_NORMAL) { + receive_char(pInfo, *p); + } else { + receive_error(pInfo, flags); + } + + } } MODULE_LICENSE("GPL"); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index f108c136800..4ab2c98f978 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -887,10 +887,8 @@ static void bh_transmit(MGSLPC_INFO *info) if (debug_level >= DEBUG_LEVEL_BH) printk("bh_transmit() entry on %s\n", info->device_name); - if (tty) { + if (tty) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } static void bh_status(MGSLPC_INFO *info) diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 645e20a06ec..1f0d7c60c94 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -154,7 +154,7 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, goto out; } - if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS) { + if (rq.raw_minor <= 0 || rq.raw_minor >= MAX_RAW_MINORS) { err = -EINVAL; goto out; } diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index eeda40c5e18..ebc76342712 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c @@ -162,13 +162,8 @@ void RIOTxEnable(char *en) rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) { - rio_dprintk(RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....", (int) (PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)), PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); - if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && PortP->gs.tty->ldisc.write_wakeup) - (PortP->gs.tty->ldisc.write_wakeup) (PortP->gs.tty); - rio_dprintk(RIO_DEBUG_INTR, "(%d/%d)\n", PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); - wake_up_interruptible(&PortP->gs.tty->write_wait); - } + if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) + tty_wakeup(PortP->gs.tty); } diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index e2a94bfb2a4..70145254fb9 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1229,7 +1229,6 @@ static void rc_flush_buffer(struct tty_struct *tty) port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; restore_flags(flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } @@ -1570,10 +1569,8 @@ static void do_softint(struct work_struct *ugly_api) if(!(tty = port->tty)) return; - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } static const struct tty_operations riscom_ops = { diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index e94a62e30fc..106f225e745 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -474,7 +474,6 @@ static void rp_do_transmit(struct r_port *info) if (info->xmit_cnt < WAKEUP_CHARS) { tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); #ifdef ROCKETPORT_HAVE_POLL_WAIT wake_up_interruptible(&tty->poll_wait); #endif @@ -1772,7 +1771,6 @@ static int rp_write(struct tty_struct *tty, end: if (info->xmit_cnt < WAKEUP_CHARS) { tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); #ifdef ROCKETPORT_HAVE_POLL_WAIT wake_up_interruptible(&tty->poll_wait); #endif @@ -1841,7 +1839,6 @@ static void rp_flush_buffer(struct tty_struct *tty) info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; spin_unlock_irqrestore(&info->slock, flags); - wake_up_interruptible(&tty->write_wait); #ifdef ROCKETPORT_HAVE_POLL_WAIT wake_up_interruptible(&tty->poll_wait); #endif diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index af50d32ae2c..5fd314adc1f 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -111,12 +111,13 @@ u_char initial_console_speed; /* This is the per-port data structure */ struct cyclades_port cy_port[] = { - /* CARD# */ - {-1 }, /* ttyS0 */ - {-1 }, /* ttyS1 */ - {-1 }, /* ttyS2 */ - {-1 }, /* ttyS3 */ + /* CARD# */ + {-1}, /* ttyS0 */ + {-1}, /* ttyS1 */ + {-1}, /* ttyS2 */ + {-1}, /* ttyS3 */ }; + #define NR_PORTS ARRAY_SIZE(cy_port) /* @@ -128,42 +129,46 @@ struct cyclades_port cy_port[] = { * HI VHI */ static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, - 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000, - 0}; + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, + 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, + 0 +}; #if 0 -static char baud_co[] = { /* 25 MHz clock option table */ - /* value => 00 01 02 03 04 */ - /* divide by 8 32 128 512 2048 */ - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static char baud_co[] = { /* 25 MHz clock option table */ + /* value => 00 01 02 03 04 */ + /* divide by 8 32 128 512 2048 */ + 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, + 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; -static char baud_bpr[] = { /* 25 MHz baud rate period table */ - 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, - 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15}; +static char baud_bpr[] = { /* 25 MHz baud rate period table */ + 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, + 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 +}; #endif /* I think 166 brd clocks 2401 at 20MHz.... */ /* These values are written directly to tcor, and >> 5 for writing to rcor */ -static u_char baud_co[] = { /* 20 MHz clock option table */ - 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40, - 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static u_char baud_co[] = { /* 20 MHz clock option table */ + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40, + 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; /* These values written directly to tbpr/rbpr */ -static u_char baud_bpr[] = { /* 20 MHz baud rate period table */ - 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81, - 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10}; - -static u_char baud_cor4[] = { /* receive threshold */ - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07}; - +static u_char baud_bpr[] = { /* 20 MHz baud rate period table */ + 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81, + 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10 +}; +static u_char baud_cor4[] = { /* receive threshold */ + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07 +}; static void shutdown(struct cyclades_port *); -static int startup (struct cyclades_port *); +static int startup(struct cyclades_port *); static void cy_throttle(struct tty_struct *); static void cy_unthrottle(struct tty_struct *); static void config_setup(struct cyclades_port *); @@ -174,16 +179,16 @@ static void show_status(int); #ifdef CONFIG_REMOTE_DEBUG static void debug_setup(void); -void queueDebugChar (int c); +void queueDebugChar(int c); int getDebugChar(void); #define DEBUG_PORT 1 #define DEBUG_LEN 256 typedef struct { - int in; - int out; - unsigned char buf[DEBUG_LEN]; + int in; + int out; + unsigned char buf[DEBUG_LEN]; } debugq; debugq debugiq; @@ -196,7 +201,7 @@ debugq debugiq; * delay, but this wild guess will do for now. */ -void my_udelay (long us) +void my_udelay(long us) { u_char x; volatile u_char *p = &x; @@ -207,62 +212,73 @@ void my_udelay (long us) x |= *p; } -static inline int -serial_paranoia_check(struct cyclades_port *info, char *name, - const char *routine) +static inline int serial_paranoia_check(struct cyclades_port *info, char *name, + const char *routine) { #ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null cyclades_port for (%s) in %s\n"; - static const char *badrange = - "Warning: cyclades_port out of range for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - - if( (long)info < (long)(&cy_port[0]) - || (long)(&cy_port[NR_PORTS]) < (long)info ){ - printk(badrange, name, routine); - return 1; - } - - if (info->magic != CYCLADES_MAGIC) { - printk(badmagic, name, routine); - return 1; - } + if (!info) { + printk("Warning: null cyclades_port for (%s) in %s\n", name, + routine); + return 1; + } + + if ((long)info < (long)(&cy_port[0]) + || (long)(&cy_port[NR_PORTS]) < (long)info) { + printk("Warning: cyclades_port out of range for (%s) in %s\n", + name, routine); + return 1; + } + + if (info->magic != CYCLADES_MAGIC) { + printk("Warning: bad magic number for serial struct (%s) in " + "%s\n", name, routine); + return 1; + } #endif return 0; -} /* serial_paranoia_check */ +} /* serial_paranoia_check */ #if 0 /* The following diagnostic routines allow the driver to spew information on the screen, even (especially!) during interrupts. */ -void -SP(char *data){ - unsigned long flags; - local_irq_save(flags); - console_print(data); - local_irq_restore(flags); +void SP(char *data) +{ + unsigned long flags; + local_irq_save(flags); + console_print(data); + local_irq_restore(flags); } + char scrn[2]; -void -CP(char data){ - unsigned long flags; - local_irq_save(flags); - scrn[0] = data; - console_print(scrn); - local_irq_restore(flags); -}/* CP */ +void CP(char data) +{ + unsigned long flags; + local_irq_save(flags); + scrn[0] = data; + console_print(scrn); + local_irq_restore(flags); +} /* CP */ -void CP1(int data) { (data<10)? CP(data+'0'): CP(data+'A'-10); }/* CP1 */ -void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }/* CP2 */ -void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }/* CP4 */ -void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */ +void CP1(int data) +{ + (data < 10) ? CP(data + '0') : CP(data + 'A' - 10); +} /* CP1 */ +void CP2(int data) +{ + CP1((data >> 4) & 0x0f); + CP1(data & 0x0f); +} /* CP2 */ +void CP4(int data) +{ + CP2((data >> 8) & 0xff); + CP2(data & 0xff); +} /* CP4 */ +void CP8(long data) +{ + CP4((data >> 16) & 0xffff); + CP4(data & 0xffff); +} /* CP8 */ #endif /* This routine waits up to 1000 micro-seconds for the previous @@ -270,87 +286,78 @@ void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */ new command. An error is returned if the previous command didn't finish within the time limit. */ -u_short -write_cy_cmd(volatile u_char *base_addr, u_char cmd) +u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd) { - unsigned long flags; - volatile int i; + unsigned long flags; + volatile int i; - local_irq_save(flags); + local_irq_save(flags); /* Check to see that the previous command has completed */ - for(i = 0 ; i < 100 ; i++){ - if (base_addr[CyCCR] == 0){ - break; - } - my_udelay(10L); + for (i = 0; i < 100; i++) { + if (base_addr[CyCCR] == 0) { + break; + } + my_udelay(10L); } /* if the CCR never cleared, the previous command - didn't finish within the "reasonable time" */ - if ( i == 10 ) { - local_irq_restore(flags); - return (-1); + didn't finish within the "reasonable time" */ + if (i == 10) { + local_irq_restore(flags); + return (-1); } /* Issue the new command */ base_addr[CyCCR] = cmd; - local_irq_restore(flags); - return(0); -} /* write_cy_cmd */ - + local_irq_restore(flags); + return (0); +} /* write_cy_cmd */ /* cy_start and cy_stop provide software output flow control as a function of XON/XOFF, software CTS, and other such stuff. */ -static void -cy_stop(struct tty_struct *tty) +static void cy_stop(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + unsigned long flags; #ifdef SERIAL_DEBUG_OTHER - printk("cy_stop %s\n", tty->name); /* */ + printk("cy_stop %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_stop")) - return; - - channel = info->line; + if (serial_paranoia_check(info, tty->name, "cy_stop")) + return; - local_irq_save(flags); - base_addr[CyCAR] = (u_char)(channel); /* index channel */ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - local_irq_restore(flags); + channel = info->line; - return; -} /* cy_stop */ + local_irq_save(flags); + base_addr[CyCAR] = (u_char) (channel); /* index channel */ + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + local_irq_restore(flags); +} /* cy_stop */ -static void -cy_start(struct tty_struct *tty) +static void cy_start(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + unsigned long flags; #ifdef SERIAL_DEBUG_OTHER - printk("cy_start %s\n", tty->name); /* */ + printk("cy_start %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_start")) - return; - - channel = info->line; + if (serial_paranoia_check(info, tty->name, "cy_start")) + return; - local_irq_save(flags); - base_addr[CyCAR] = (u_char)(channel); - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); - - return; -} /* cy_start */ + channel = info->line; + local_irq_save(flags); + base_addr[CyCAR] = (u_char) (channel); + base_addr[CyIER] |= CyTxMpty; + local_irq_restore(flags); +} /* cy_start */ /* * This routine is used by the interrupt handler to schedule @@ -358,332 +365,332 @@ cy_start(struct tty_struct *tty) * (also known as the "bottom half"). This can be called any * number of times for any channel without harm. */ -static inline void -cy_sched_event(struct cyclades_port *info, int event) +static inline void cy_sched_event(struct cyclades_port *info, int event) { - info->event |= 1 << event; /* remember what kind of event and who */ - schedule_work(&info->tqueue); -} /* cy_sched_event */ - + info->event |= 1 << event; /* remember what kind of event and who */ + schedule_work(&info->tqueue); +} /* cy_sched_event */ /* The real interrupt service routines are called whenever the card wants its hand held--chars received, out buffer empty, modem change, etc. */ -static irqreturn_t -cd2401_rxerr_interrupt(int irq, void *dev_id) +static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id) { - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - unsigned char err, rfoc; - int channel; - char data; - - /* determine the channel and change to that context */ - channel = (u_short ) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - if ((err = base_addr[CyRISR]) & CyTIMEOUT) { - /* This is a receive timeout interrupt, ignore it */ - base_addr[CyREOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* Read a byte of data if there is any - assume the error - * is associated with this character */ + struct tty_struct *tty; + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + unsigned char err, rfoc; + int channel; + char data; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + + if ((err = base_addr[CyRISR]) & CyTIMEOUT) { + /* This is a receive timeout interrupt, ignore it */ + base_addr[CyREOIR] = CyNOTRANS; + return IRQ_HANDLED; + } - if ((rfoc = base_addr[CyRFOC]) != 0) - data = base_addr[CyRDR]; - else - data = 0; + /* Read a byte of data if there is any - assume the error + * is associated with this character */ - /* if there is nowhere to put the data, discard it */ - if(info->tty == 0) { + if ((rfoc = base_addr[CyRFOC]) != 0) + data = base_addr[CyRDR]; + else + data = 0; + + /* if there is nowhere to put the data, discard it */ + if (info->tty == 0) { + base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; + return IRQ_HANDLED; + } else { /* there is an open port for this data */ + tty = info->tty; + if (err & info->ignore_status_mask) { + base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; + return IRQ_HANDLED; + } + if (tty_buffer_request_room(tty, 1) != 0) { + if (err & info->read_status_mask) { + if (err & CyBREAK) { + tty_insert_flip_char(tty, data, + TTY_BREAK); + if (info->flags & ASYNC_SAK) { + do_SAK(tty); + } + } else if (err & CyFRAME) { + tty_insert_flip_char(tty, data, + TTY_FRAME); + } else if (err & CyPARITY) { + tty_insert_flip_char(tty, data, + TTY_PARITY); + } else if (err & CyOVERRUN) { + tty_insert_flip_char(tty, 0, + TTY_OVERRUN); + /* + If the flip buffer itself is + overflowing, we still loose + the next incoming character. + */ + if (tty_buffer_request_room(tty, 1) != + 0) { + tty_insert_flip_char(tty, data, + TTY_FRAME); + } + /* These two conditions may imply */ + /* a normal read should be done. */ + /* else if(data & CyTIMEOUT) */ + /* else if(data & CySPECHAR) */ + } else { + tty_insert_flip_char(tty, 0, + TTY_NORMAL); + } + } else { + tty_insert_flip_char(tty, data, TTY_NORMAL); + } + } else { + /* there was a software buffer overrun + and nothing could be done about it!!! */ + } + } + tty_schedule_flip(tty); + /* end of service */ base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; return IRQ_HANDLED; - } - else { /* there is an open port for this data */ - tty = info->tty; - if(err & info->ignore_status_mask){ - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; - } - if (tty_buffer_request_room(tty, 1) != 0){ - if (err & info->read_status_mask){ - if(err & CyBREAK){ - tty_insert_flip_char(tty, data, TTY_BREAK); - if (info->flags & ASYNC_SAK){ - do_SAK(tty); - } - }else if(err & CyFRAME){ - tty_insert_flip_char(tty, data, TTY_FRAME); - }else if(err & CyPARITY){ - tty_insert_flip_char(tty, data, TTY_PARITY); - }else if(err & CyOVERRUN){ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - /* - If the flip buffer itself is - overflowing, we still loose - the next incoming character. - */ - if (tty_buffer_request_room(tty, 1) != 0){ - tty_insert_flip_char(tty, data, TTY_FRAME); - } - /* These two conditions may imply */ - /* a normal read should be done. */ - /* else if(data & CyTIMEOUT) */ - /* else if(data & CySPECHAR) */ - }else{ - tty_insert_flip_char(tty, 0, TTY_NORMAL); - } - }else{ - tty_insert_flip_char(tty, data, TTY_NORMAL); - } - }else{ - /* there was a software buffer overrun - and nothing could be done about it!!! */ - } - } - tty_schedule_flip(tty); - /* end of service */ - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rxerr_interrupt */ - -static irqreturn_t -cd2401_modem_interrupt(int irq, void *dev_id) +} /* cy_rxerr_interrupt */ + +static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id) { - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int mdm_change; - int mdm_status; - - - /* determine the channel and change to that context */ - channel = (u_short ) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - mdm_change = base_addr[CyMISR]; - mdm_status = base_addr[CyMSVR1]; - - if(info->tty == 0){ /* nowhere to put the data, ignore it */ - ; - }else{ - if((mdm_change & CyDCD) - && (info->flags & ASYNC_CHECK_CD)){ - if(mdm_status & CyDCD){ + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + int mdm_change; + int mdm_status; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + + mdm_change = base_addr[CyMISR]; + mdm_status = base_addr[CyMSVR1]; + + if (info->tty == 0) { /* nowhere to put the data, ignore it */ + ; + } else { + if ((mdm_change & CyDCD) + && (info->flags & ASYNC_CHECK_CD)) { + if (mdm_status & CyDCD) { /* CP('!'); */ - cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP); - } else { + cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP); + } else { /* CP('@'); */ - cy_sched_event(info, Cy_EVENT_HANGUP); - } - } - if((mdm_change & CyCTS) - && (info->flags & ASYNC_CTS_FLOW)){ - if(info->tty->stopped){ - if(mdm_status & CyCTS){ - /* !!! cy_start isn't used because... */ - info->tty->stopped = 0; - base_addr[CyIER] |= CyTxMpty; - cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); + cy_sched_event(info, Cy_EVENT_HANGUP); + } } - }else{ - if(!(mdm_status & CyCTS)){ - /* !!! cy_stop isn't used because... */ - info->tty->stopped = 1; - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); + if ((mdm_change & CyCTS) + && (info->flags & ASYNC_CTS_FLOW)) { + if (info->tty->stopped) { + if (mdm_status & CyCTS) { + /* !!! cy_start isn't used because... */ + info->tty->stopped = 0; + base_addr[CyIER] |= CyTxMpty; + cy_sched_event(info, + Cy_EVENT_WRITE_WAKEUP); + } + } else { + if (!(mdm_status & CyCTS)) { + /* !!! cy_stop isn't used because... */ + info->tty->stopped = 1; + base_addr[CyIER] &= + ~(CyTxMpty | CyTxRdy); + } + } + } + if (mdm_status & CyDSR) { } - } - } - if(mdm_status & CyDSR){ } - } - base_addr[CyMEOIR] = 0; - return IRQ_HANDLED; -} /* cy_modem_interrupt */ + base_addr[CyMEOIR] = 0; + return IRQ_HANDLED; +} /* cy_modem_interrupt */ -static irqreturn_t -cd2401_tx_interrupt(int irq, void *dev_id) +static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id) { - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int char_count, saved_cnt; - int outch; + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + int char_count, saved_cnt; + int outch; - /* determine the channel and change to that context */ - channel = (u_short ) (base_addr[CyLICR] >> 2); + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); #ifdef CONFIG_REMOTE_DEBUG - if (channel == DEBUG_PORT) { - panic ("TxInt on debug port!!!"); - } + if (channel == DEBUG_PORT) { + panic("TxInt on debug port!!!"); + } #endif - info = &cy_port[channel]; + info = &cy_port[channel]; - /* validate the port number (as configured and open) */ - if( (channel < 0) || (NR_PORTS <= channel) ){ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - info->last_active = jiffies; - if(info->tty == 0){ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - if (info->xmit_cnt < WAKEUP_CHARS) { - cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); - } - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* load the on-chip space available for outbound data */ - saved_cnt = char_count = base_addr[CyTFTC]; - - if(info->x_char) { /* send special char */ - outch = info->x_char; - base_addr[CyTDR] = outch; - char_count--; - info->x_char = 0; - } - - if (info->x_break){ - /* The Cirrus chip requires the "Embedded Transmit - Commands" of start break, delay, and end break - sequences to be sent. The duration of the - break is given in TICs, which runs at HZ - (typically 100) and the PPR runs at 200 Hz, - so the delay is duration * 200/HZ, and thus a - break can run from 1/100 sec to about 5/4 sec. - Need to check these values - RGH 141095. - */ - base_addr[CyTDR] = 0; /* start break */ - base_addr[CyTDR] = 0x81; - base_addr[CyTDR] = 0; /* delay a bit */ - base_addr[CyTDR] = 0x82; - base_addr[CyTDR] = info->x_break*200/HZ; - base_addr[CyTDR] = 0; /* terminate break */ - base_addr[CyTDR] = 0x83; - char_count -= 7; - info->x_break = 0; - } - - while (char_count > 0){ - if (!info->xmit_cnt){ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - break; - } - if (info->xmit_buf == 0){ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - break; - } - if (info->tty->stopped || info->tty->hw_stopped){ - base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy); - break; - } - /* Because the Embedded Transmit Commands have been - enabled, we must check to see if the escape - character, NULL, is being sent. If it is, we - must ensure that there is room for it to be - doubled in the output stream. Therefore we - no longer advance the pointer when the character - is fetched, but rather wait until after the check - for a NULL output character. (This is necessary - because there may not be room for the two chars - needed to send a NULL. - */ - outch = info->xmit_buf[info->xmit_tail]; - if( outch ){ - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); - base_addr[CyTDR] = outch; - char_count--; - }else{ - if(char_count > 1){ - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); + /* validate the port number (as configured and open) */ + if ((channel < 0) || (NR_PORTS <= channel)) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + base_addr[CyTEOIR] = CyNOTRANS; + return IRQ_HANDLED; + } + info->last_active = jiffies; + if (info->tty == 0) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + if (info->xmit_cnt < WAKEUP_CHARS) { + cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); + } + base_addr[CyTEOIR] = CyNOTRANS; + return IRQ_HANDLED; + } + + /* load the on-chip space available for outbound data */ + saved_cnt = char_count = base_addr[CyTFTC]; + + if (info->x_char) { /* send special char */ + outch = info->x_char; base_addr[CyTDR] = outch; - base_addr[CyTDR] = 0; char_count--; - char_count--; - }else{ - break; - } + info->x_char = 0; } - } - if (info->xmit_cnt < WAKEUP_CHARS) { - cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); - } - base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_tx_interrupt */ + if (info->x_break) { + /* The Cirrus chip requires the "Embedded Transmit + Commands" of start break, delay, and end break + sequences to be sent. The duration of the + break is given in TICs, which runs at HZ + (typically 100) and the PPR runs at 200 Hz, + so the delay is duration * 200/HZ, and thus a + break can run from 1/100 sec to about 5/4 sec. + Need to check these values - RGH 141095. + */ + base_addr[CyTDR] = 0; /* start break */ + base_addr[CyTDR] = 0x81; + base_addr[CyTDR] = 0; /* delay a bit */ + base_addr[CyTDR] = 0x82; + base_addr[CyTDR] = info->x_break * 200 / HZ; + base_addr[CyTDR] = 0; /* terminate break */ + base_addr[CyTDR] = 0x83; + char_count -= 7; + info->x_break = 0; + } + + while (char_count > 0) { + if (!info->xmit_cnt) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + if (info->xmit_buf == 0) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + if (info->tty->stopped || info->tty->hw_stopped) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + /* Because the Embedded Transmit Commands have been + enabled, we must check to see if the escape + character, NULL, is being sent. If it is, we + must ensure that there is room for it to be + doubled in the output stream. Therefore we + no longer advance the pointer when the character + is fetched, but rather wait until after the check + for a NULL output character. (This is necessary + because there may not be room for the two chars + needed to send a NULL. + */ + outch = info->xmit_buf[info->xmit_tail]; + if (outch) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) + & (PAGE_SIZE - 1); + base_addr[CyTDR] = outch; + char_count--; + } else { + if (char_count > 1) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) + & (PAGE_SIZE - 1); + base_addr[CyTDR] = outch; + base_addr[CyTDR] = 0; + char_count--; + char_count--; + } else { + break; + } + } + } + + if (info->xmit_cnt < WAKEUP_CHARS) { + cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); + } + base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; + return IRQ_HANDLED; +} /* cy_tx_interrupt */ -static irqreturn_t -cd2401_rx_interrupt(int irq, void *dev_id) +static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) { - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - char data; - int char_count; - int save_cnt; - int len; - - /* determine the channel and change to that context */ - channel = (u_short ) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - save_cnt = char_count = base_addr[CyRFOC]; + struct tty_struct *tty; + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + char data; + int char_count; + int save_cnt; + int len; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + save_cnt = char_count = base_addr[CyRFOC]; #ifdef CONFIG_REMOTE_DEBUG - if (channel == DEBUG_PORT) { - while (char_count--) { - data = base_addr[CyRDR]; - queueDebugChar(data); - } - } - else + if (channel == DEBUG_PORT) { + while (char_count--) { + data = base_addr[CyRDR]; + queueDebugChar(data); + } + } else #endif - /* if there is nowhere to put the data, discard it */ - if(info->tty == 0){ - while(char_count--){ - data = base_addr[CyRDR]; - } - }else{ /* there is an open port for this data */ - tty = info->tty; - /* load # characters available from the chip */ + /* if there is nowhere to put the data, discard it */ + if (info->tty == 0) { + while (char_count--) { + data = base_addr[CyRDR]; + } + } else { /* there is an open port for this data */ + tty = info->tty; + /* load # characters available from the chip */ #ifdef CYCLOM_ENABLE_MONITORING - ++info->mon.int_count; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; -#endif - len = tty_buffer_request_room(tty, char_count); - while(len--){ - data = base_addr[CyRDR]; - tty_insert_flip_char(tty, data, TTY_NORMAL); + ++info->mon.int_count; + info->mon.char_count += char_count; + if (char_count > info->mon.char_max) + info->mon.char_max = char_count; + info->mon.char_last = char_count; +#endif + len = tty_buffer_request_room(tty, char_count); + while (len--) { + data = base_addr[CyRDR]; + tty_insert_flip_char(tty, data, TTY_NORMAL); #ifdef CYCLOM_16Y_HACK - udelay(10L); + udelay(10L); #endif - } - tty_schedule_flip(tty); - } - /* end of service */ - base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rx_interrupt */ + } + tty_schedule_flip(tty); + } + /* end of service */ + base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; + return IRQ_HANDLED; +} /* cy_rx_interrupt */ /* * This routine is used to handle the "bottom half" processing for the @@ -705,192 +712,188 @@ cd2401_rx_interrupt(int irq, void *dev_id) * structure) to the bottom half of the driver. Previous kernels * had to poll every port to see if that port needed servicing. */ -static void -do_softint(struct work_struct *ugly_api) +static void do_softint(struct work_struct *ugly_api) { - struct cyclades_port *info = container_of(ugly_api, struct cyclades_port, tqueue); - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; + struct cyclades_port *info = + container_of(ugly_api, struct cyclades_port, tqueue); + struct tty_struct *tty; - if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { - tty_hangup(info->tty); - wake_up_interruptible(&info->open_wait); - info->flags &= ~ASYNC_NORMAL_ACTIVE; - } - if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { - wake_up_interruptible(&info->open_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { - tty_wakeup(tty); - } -} /* do_softint */ + tty = info->tty; + if (!tty) + return; + if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { + tty_hangup(info->tty); + wake_up_interruptible(&info->open_wait); + info->flags &= ~ASYNC_NORMAL_ACTIVE; + } + if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { + wake_up_interruptible(&info->open_wait); + } + if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { + tty_wakeup(tty); + } +} /* do_softint */ /* This is called whenever a port becomes active; interrupts are enabled and DTR & RTS are turned on. */ -static int -startup(struct cyclades_port * info) +static int startup(struct cyclades_port *info) { - unsigned long flags; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; + unsigned long flags; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; - if (info->flags & ASYNC_INITIALIZED){ - return 0; - } + if (info->flags & ASYNC_INITIALIZED) { + return 0; + } - if (!info->type){ - if (info->tty){ - set_bit(TTY_IO_ERROR, &info->tty->flags); + if (!info->type) { + if (info->tty) { + set_bit(TTY_IO_ERROR, &info->tty->flags); + } + return 0; } - return 0; - } - if (!info->xmit_buf){ - info->xmit_buf = (unsigned char *) get_zeroed_page (GFP_KERNEL); - if (!info->xmit_buf){ - return -ENOMEM; + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); + if (!info->xmit_buf) { + return -ENOMEM; + } } - } - config_setup(info); + config_setup(info); - channel = info->line; + channel = info->line; #ifdef SERIAL_DEBUG_OPEN - printk("startup channel %d\n", channel); + printk("startup channel %d\n", channel); #endif - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; - write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR); + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); - base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */ + base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ base_addr[CyMSVR1] = CyRTS; /* CP('S');CP('1'); */ base_addr[CyMSVR2] = CyDTR; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif base_addr[CyIER] |= CyRxData; info->flags |= ASYNC_INITIALIZED; - if (info->tty){ - clear_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->tty) { + clear_bit(TTY_IO_ERROR, &info->tty->flags); } info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); + local_irq_restore(flags); #ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); + printk(" done\n"); #endif - return 0; -} /* startup */ + return 0; +} /* startup */ -void -start_xmit( struct cyclades_port *info ) +void start_xmit(struct cyclades_port *info) { - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; - channel = info->line; - local_irq_save(flags); + channel = info->line; + local_irq_save(flags); base_addr[CyCAR] = channel; base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* start_xmit */ + local_irq_restore(flags); +} /* start_xmit */ /* * This routine shuts down a serial port; interrupts are disabled, * and DTR is dropped if the hangup on close termio flag is on. */ -static void -shutdown(struct cyclades_port * info) +static void shutdown(struct cyclades_port *info) { - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; - if (!(info->flags & ASYNC_INITIALIZED)){ + if (!(info->flags & ASYNC_INITIALIZED)) { /* CP('$'); */ - return; - } + return; + } - channel = info->line; + channel = info->line; #ifdef SERIAL_DEBUG_OPEN - printk("shutdown channel %d\n", channel); + printk("shutdown channel %d\n", channel); #endif - /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE - SENT BEFORE DROPPING THE LINE !!! (Perhaps - set some flag that is read when XMTY happens.) - Other choices are to delay some fixed interval - or schedule some later processing. - */ - local_irq_save(flags); - if (info->xmit_buf){ - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = NULL; + /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE + SENT BEFORE DROPPING THE LINE !!! (Perhaps + set some flag that is read when XMTY happens.) + Other choices are to delay some fixed interval + or schedule some later processing. + */ + local_irq_save(flags); + if (info->xmit_buf) { + free_page((unsigned long)info->xmit_buf); + info->xmit_buf = NULL; } - base_addr[CyCAR] = (u_char)channel; + base_addr[CyCAR] = (u_char) channel; if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { - base_addr[CyMSVR1] = 0; + base_addr[CyMSVR1] = 0; /* CP('C');CP('1'); */ - base_addr[CyMSVR2] = 0; + base_addr[CyMSVR2] = 0; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif - } - write_cy_cmd(base_addr,CyDIS_RCVR); - /* it may be appropriate to clear _XMIT at - some later date (after testing)!!! */ + } + write_cy_cmd(base_addr, CyDIS_RCVR); + /* it may be appropriate to clear _XMIT at + some later date (after testing)!!! */ - if (info->tty){ - set_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->tty) { + set_bit(TTY_IO_ERROR, &info->tty->flags); } info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); + local_irq_restore(flags); #ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); + printk(" done\n"); #endif - return; -} /* shutdown */ +} /* shutdown */ /* * This routine finds or computes the various line characteristics. */ -static void -config_setup(struct cyclades_port * info) +static void config_setup(struct cyclades_port *info) { - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - unsigned cflag; - int i; - unsigned char ti, need_init_chan = 0; - - if (!info->tty || !info->tty->termios){ - return; - } - if (info->line == -1){ - return; - } - cflag = info->tty->termios->c_cflag; - - /* baud rate */ - i = cflag & CBAUD; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned cflag; + int i; + unsigned char ti, need_init_chan = 0; + + if (!info->tty || !info->tty->termios) { + return; + } + if (info->line == -1) { + return; + } + cflag = info->tty->termios->c_cflag; + + /* baud rate */ + i = cflag & CBAUD; #ifdef CBAUDEX /* Starting with kernel 1.1.65, there is direct support for higher baud rates. The following code supports those @@ -900,120 +903,123 @@ config_setup(struct cyclades_port * info) is still the possibility of supporting 75 kbit/sec with the Cyclades board.) */ - if (i & CBAUDEX) { - if (i == B57600) - i = 16; - else if(i == B115200) - i = 18; + if (i & CBAUDEX) { + if (i == B57600) + i = 16; + else if (i == B115200) + i = 18; #ifdef B78600 - else if(i == B78600) - i = 17; + else if (i == B78600) + i = 17; #endif - else - info->tty->termios->c_cflag &= ~CBAUDEX; - } -#endif - if (i == 15) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - i += 1; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - i += 3; - } - /* Don't ever change the speed of the console port. It will - * run at the speed specified in bootinfo, or at 19.2K */ - /* Actually, it should run at whatever speed 166Bug was using */ - /* Note info->timeout isn't used at present */ - if (info != serial_console_info) { - info->tbpr = baud_bpr[i]; /* Tx BPR */ - info->tco = baud_co[i]; /* Tx CO */ - info->rbpr = baud_bpr[i]; /* Rx BPR */ - info->rco = baud_co[i] >> 5; /* Rx CO */ - if (baud_table[i] == 134) { - info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; - /* get it right for 134.5 baud */ - } else if (baud_table[i]) { - info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2; - /* this needs to be propagated into the card info */ + else + info->tty->termios->c_cflag &= ~CBAUDEX; + } +#endif + if (i == 15) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + i += 1; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + i += 3; + } + /* Don't ever change the speed of the console port. It will + * run at the speed specified in bootinfo, or at 19.2K */ + /* Actually, it should run at whatever speed 166Bug was using */ + /* Note info->timeout isn't used at present */ + if (info != serial_console_info) { + info->tbpr = baud_bpr[i]; /* Tx BPR */ + info->tco = baud_co[i]; /* Tx CO */ + info->rbpr = baud_bpr[i]; /* Rx BPR */ + info->rco = baud_co[i] >> 5; /* Rx CO */ + if (baud_table[i] == 134) { + info->timeout = + (info->xmit_fifo_size * HZ * 30 / 269) + 2; + /* get it right for 134.5 baud */ + } else if (baud_table[i]) { + info->timeout = + (info->xmit_fifo_size * HZ * 15 / baud_table[i]) + + 2; + /* this needs to be propagated into the card info */ + } else { + info->timeout = 0; + } + } + /* By tradition (is it a standard?) a baud rate of zero + implies the line should be/has been closed. A bit + later in this routine such a test is performed. */ + + /* byte size and parity */ + info->cor7 = 0; + info->cor6 = 0; + info->cor5 = 0; + info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */ + /* Following two lines added 101295, RGH. */ + /* It is obviously wrong to access CyCORx, and not info->corx here, + * try and remember to fix it later! */ + channel = info->line; + base_addr[CyCAR] = (u_char) channel; + if (C_CLOCAL(info->tty)) { + if (base_addr[CyIER] & CyMdmCh) + base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */ + /* ignore 1->0 modem transitions */ + if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD); + /* ignore 0->1 modem transitions */ + if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD); } else { - info->timeout = 0; - } - } - /* By tradition (is it a standard?) a baud rate of zero - implies the line should be/has been closed. A bit - later in this routine such a test is performed. */ - - /* byte size and parity */ - info->cor7 = 0; - info->cor6 = 0; - info->cor5 = 0; - info->cor4 = (info->default_threshold - ? info->default_threshold - : baud_cor4[i]); /* receive threshold */ - /* Following two lines added 101295, RGH. */ - /* It is obviously wrong to access CyCORx, and not info->corx here, - * try and remember to fix it later! */ - channel = info->line; - base_addr[CyCAR] = (u_char)channel; - if (C_CLOCAL(info->tty)) { - if (base_addr[CyIER] & CyMdmCh) - base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */ - /* ignore 1->0 modem transitions */ - if (base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD)) - base_addr[CyCOR4] &= ~(CyDSR|CyCTS|CyDCD); - /* ignore 0->1 modem transitions */ - if (base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD)) - base_addr[CyCOR5] &= ~(CyDSR|CyCTS|CyDCD); - } else { - if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh) - base_addr[CyIER] |= CyMdmCh; /* with modem intr */ - /* act on 1->0 modem transitions */ - if ((base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD)) - base_addr[CyCOR4] |= CyDSR|CyCTS|CyDCD; - /* act on 0->1 modem transitions */ - if ((base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD)) - base_addr[CyCOR5] |= CyDSR|CyCTS|CyDCD; - } - info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP; - info->cor2 = CyETC; - switch(cflag & CSIZE){ - case CS5: - info->cor1 = Cy_5_BITS; - break; - case CS6: - info->cor1 = Cy_6_BITS; - break; - case CS7: - info->cor1 = Cy_7_BITS; - break; - case CS8: - info->cor1 = Cy_8_BITS; - break; - } - if (cflag & PARENB){ - if (cflag & PARODD){ - info->cor1 |= CyPARITY_O; - }else{ - info->cor1 |= CyPARITY_E; - } - }else{ - info->cor1 |= CyPARITY_NONE; - } - - /* CTS flow control flag */ + if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh) + base_addr[CyIER] |= CyMdmCh; /* with modem intr */ + /* act on 1->0 modem transitions */ + if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) != + (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD; + /* act on 0->1 modem transitions */ + if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) != + (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD; + } + info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP; + info->cor2 = CyETC; + switch (cflag & CSIZE) { + case CS5: + info->cor1 = Cy_5_BITS; + break; + case CS6: + info->cor1 = Cy_6_BITS; + break; + case CS7: + info->cor1 = Cy_7_BITS; + break; + case CS8: + info->cor1 = Cy_8_BITS; + break; + } + if (cflag & PARENB) { + if (cflag & PARODD) { + info->cor1 |= CyPARITY_O; + } else { + info->cor1 |= CyPARITY_E; + } + } else { + info->cor1 |= CyPARITY_NONE; + } + + /* CTS flow control flag */ #if 0 - /* Don't complcate matters for now! RGH 141095 */ - if (cflag & CRTSCTS){ - info->flags |= ASYNC_CTS_FLOW; - info->cor2 |= CyCtsAE; - }else{ - info->flags &= ~ASYNC_CTS_FLOW; - info->cor2 &= ~CyCtsAE; - } -#endif - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else - info->flags |= ASYNC_CHECK_CD; + /* Don't complcate matters for now! RGH 141095 */ + if (cflag & CRTSCTS) { + info->flags |= ASYNC_CTS_FLOW; + info->cor2 |= CyCtsAE; + } else { + info->flags &= ~ASYNC_CTS_FLOW; + info->cor2 &= ~CyCtsAE; + } +#endif + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else + info->flags |= ASYNC_CHECK_CD; /*********************************************** The hardware option, CyRtsAO, presents RTS when @@ -1025,149 +1031,146 @@ config_setup(struct cyclades_port * info) cable. Contact Marcio Saito for details. ***********************************************/ - channel = info->line; + channel = info->line; - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; /* CyCMR set once only in mvme167_init_serial() */ if (base_addr[CyLICR] != channel << 2) - base_addr[CyLICR] = channel << 2; + base_addr[CyLICR] = channel << 2; if (base_addr[CyLIVR] != 0x5c) - base_addr[CyLIVR] = 0x5c; + base_addr[CyLIVR] = 0x5c; - /* tx and rx baud rate */ + /* tx and rx baud rate */ if (base_addr[CyCOR1] != info->cor1) - need_init_chan = 1; + need_init_chan = 1; if (base_addr[CyTCOR] != info->tco) - base_addr[CyTCOR] = info->tco; + base_addr[CyTCOR] = info->tco; if (base_addr[CyTBPR] != info->tbpr) - base_addr[CyTBPR] = info->tbpr; + base_addr[CyTBPR] = info->tbpr; if (base_addr[CyRCOR] != info->rco) - base_addr[CyRCOR] = info->rco; + base_addr[CyRCOR] = info->rco; if (base_addr[CyRBPR] != info->rbpr) - base_addr[CyRBPR] = info->rbpr; + base_addr[CyRBPR] = info->rbpr; /* set line characteristics according configuration */ if (base_addr[CySCHR1] != START_CHAR(info->tty)) - base_addr[CySCHR1] = START_CHAR(info->tty); + base_addr[CySCHR1] = START_CHAR(info->tty); if (base_addr[CySCHR2] != STOP_CHAR(info->tty)) - base_addr[CySCHR2] = STOP_CHAR(info->tty); + base_addr[CySCHR2] = STOP_CHAR(info->tty); if (base_addr[CySCRL] != START_CHAR(info->tty)) - base_addr[CySCRL] = START_CHAR(info->tty); + base_addr[CySCRL] = START_CHAR(info->tty); if (base_addr[CySCRH] != START_CHAR(info->tty)) - base_addr[CySCRH] = START_CHAR(info->tty); + base_addr[CySCRH] = START_CHAR(info->tty); if (base_addr[CyCOR1] != info->cor1) - base_addr[CyCOR1] = info->cor1; + base_addr[CyCOR1] = info->cor1; if (base_addr[CyCOR2] != info->cor2) - base_addr[CyCOR2] = info->cor2; + base_addr[CyCOR2] = info->cor2; if (base_addr[CyCOR3] != info->cor3) - base_addr[CyCOR3] = info->cor3; + base_addr[CyCOR3] = info->cor3; if (base_addr[CyCOR4] != info->cor4) - base_addr[CyCOR4] = info->cor4; + base_addr[CyCOR4] = info->cor4; if (base_addr[CyCOR5] != info->cor5) - base_addr[CyCOR5] = info->cor5; + base_addr[CyCOR5] = info->cor5; if (base_addr[CyCOR6] != info->cor6) - base_addr[CyCOR6] = info->cor6; + base_addr[CyCOR6] = info->cor6; if (base_addr[CyCOR7] != info->cor7) - base_addr[CyCOR7] = info->cor7; + base_addr[CyCOR7] = info->cor7; if (need_init_chan) - write_cy_cmd(base_addr,CyINIT_CHAN); + write_cy_cmd(base_addr, CyINIT_CHAN); - base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */ + base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ /* 2ms default rx timeout */ ti = info->default_timeout ? info->default_timeout : 0x02; if (base_addr[CyRTPRL] != ti) - base_addr[CyRTPRL] = ti; + base_addr[CyRTPRL] = ti; if (base_addr[CyRTPRH] != 0) - base_addr[CyRTPRH] = 0; + base_addr[CyRTPRH] = 0; /* Set up RTS here also ????? RGH 141095 */ - if(i == 0){ /* baud rate is zero, turn off line */ - if ((base_addr[CyMSVR2] & CyDTR) == CyDTR) - base_addr[CyMSVR2] = 0; + if (i == 0) { /* baud rate is zero, turn off line */ + if ((base_addr[CyMSVR2] & CyDTR) == CyDTR) + base_addr[CyMSVR2] = 0; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif - }else{ - if ((base_addr[CyMSVR2] & CyDTR) != CyDTR) - base_addr[CyMSVR2] = CyDTR; + } else { + if ((base_addr[CyMSVR2] & CyDTR) != CyDTR) + base_addr[CyMSVR2] = CyDTR; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif } - if (info->tty){ - clear_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->tty) { + clear_bit(TTY_IO_ERROR, &info->tty->flags); } - local_irq_restore(flags); - -} /* config_setup */ + local_irq_restore(flags); +} /* config_setup */ -static void -cy_put_char(struct tty_struct *tty, unsigned char ch) +static void cy_put_char(struct tty_struct *tty, unsigned char ch) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; #ifdef SERIAL_DEBUG_IO - printk("cy_put_char %s(0x%02x)\n", tty->name, ch); + printk("cy_put_char %s(0x%02x)\n", tty->name, ch); #endif - if (serial_paranoia_check(info, tty->name, "cy_put_char")) - return; + if (serial_paranoia_check(info, tty->name, "cy_put_char")) + return; - if (!info->xmit_buf) - return; + if (!info->xmit_buf) + return; - local_irq_save(flags); + local_irq_save(flags); if (info->xmit_cnt >= PAGE_SIZE - 1) { - local_irq_restore(flags); - return; + local_irq_restore(flags); + return; } info->xmit_buf[info->xmit_head++] = ch; info->xmit_head &= PAGE_SIZE - 1; info->xmit_cnt++; - local_irq_restore(flags); -} /* cy_put_char */ - + local_irq_restore(flags); +} /* cy_put_char */ -static void -cy_flush_chars(struct tty_struct *tty) +static void cy_flush_chars(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + #ifdef SERIAL_DEBUG_IO - printk("cy_flush_chars %s\n", tty->name); /* */ + printk("cy_flush_chars %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) - return; + if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) + return; - if (info->xmit_cnt <= 0 || tty->stopped - || tty->hw_stopped || !info->xmit_buf) - return; + if (info->xmit_cnt <= 0 || tty->stopped + || tty->hw_stopped || !info->xmit_buf) + return; - channel = info->line; + channel = info->line; - local_irq_save(flags); + local_irq_save(flags); base_addr[CyCAR] = channel; base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* cy_flush_chars */ - + local_irq_restore(flags); +} /* cy_flush_chars */ /* This routine gets called when tty_write has put something into the write_queue. If the port is not already transmitting stuff, @@ -1175,650 +1178,616 @@ cy_flush_chars(struct tty_struct *tty) routine will then ensure that the characters are sent. If the port is already active, there is no need to kick it. */ -static int -cy_write(struct tty_struct * tty, - const unsigned char *buf, int count) +static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; - int c, total = 0; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; + int c, total = 0; #ifdef SERIAL_DEBUG_IO - printk("cy_write %s\n", tty->name); /* */ + printk("cy_write %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_write")){ - return 0; - } - - if (!info->xmit_buf){ - return 0; - } - - while (1) { - local_irq_save(flags); - c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - local_irq_restore(flags); - break; - } - - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt += c; - local_irq_restore(flags); - - buf += c; - count -= c; - total += c; - } - - if (info->xmit_cnt - && !tty->stopped - && !tty->hw_stopped ) { - start_xmit(info); - } - return total; -} /* cy_write */ + if (serial_paranoia_check(info, tty->name, "cy_write")) { + return 0; + } + if (!info->xmit_buf) { + return 0; + } -static int -cy_write_room(struct tty_struct *tty) + while (1) { + local_irq_save(flags); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + local_irq_restore(flags); + break; + } + + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = + (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + local_irq_restore(flags); + + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + start_xmit(info); + } + return total; +} /* cy_write */ + +static int cy_write_room(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - int ret; - + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int ret; + #ifdef SERIAL_DEBUG_IO - printk("cy_write_room %s\n", tty->name); /* */ + printk("cy_write_room %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_write_room")) - return 0; - ret = PAGE_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} /* cy_write_room */ - + if (serial_paranoia_check(info, tty->name, "cy_write_room")) + return 0; + ret = PAGE_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} /* cy_write_room */ -static int -cy_chars_in_buffer(struct tty_struct *tty) +static int cy_chars_in_buffer(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + #ifdef SERIAL_DEBUG_IO - printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */ + printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) - return 0; - - return info->xmit_cnt; -} /* cy_chars_in_buffer */ + if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} /* cy_chars_in_buffer */ -static void -cy_flush_buffer(struct tty_struct *tty) +static void cy_flush_buffer(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; - + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; + #ifdef SERIAL_DEBUG_IO - printk("cy_flush_buffer %s\n", tty->name); /* */ + printk("cy_flush_buffer %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) - return; - local_irq_save(flags); + if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) + return; + local_irq_save(flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); - tty_wakeup(tty); -} /* cy_flush_buffer */ - + local_irq_restore(flags); + tty_wakeup(tty); +} /* cy_flush_buffer */ /* This routine is called by the upper-layer tty layer to signal that incoming characters should be throttled or that the throttle should be released. */ -static void -cy_throttle(struct tty_struct * tty) +static void cy_throttle(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; #ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_throttle %s\n", tty->name); + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); + printk("cy_throttle %s\n", tty->name); #endif - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){ - return; - } + if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { + return; + } - if (I_IXOFF(tty)) { - info->x_char = STOP_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } + if (I_IXOFF(tty)) { + info->x_char = STOP_CHAR(tty); + /* Should use the "Send Special Character" feature!!! */ + } - channel = info->line; + channel = info->line; - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; base_addr[CyMSVR1] = 0; - local_irq_restore(flags); - - return; -} /* cy_throttle */ - + local_irq_restore(flags); +} /* cy_throttle */ -static void -cy_unthrottle(struct tty_struct * tty) +static void cy_unthrottle(struct tty_struct *tty) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; #ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_unthrottle %s\n", tty->name); + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); + printk("cy_unthrottle %s\n", tty->name); #endif - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){ - return; - } + if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { + return; + } - if (I_IXOFF(tty)) { - info->x_char = START_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } + if (I_IXOFF(tty)) { + info->x_char = START_CHAR(tty); + /* Should use the "Send Special Character" feature!!! */ + } - channel = info->line; + channel = info->line; - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); - - return; -} /* cy_unthrottle */ + local_irq_restore(flags); +} /* cy_unthrottle */ static int -get_serial_info(struct cyclades_port * info, - struct serial_struct __user * retinfo) +get_serial_info(struct cyclades_port *info, + struct serial_struct __user * retinfo) { - struct serial_struct tmp; + struct serial_struct tmp; /* CP('g'); */ - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = info->type; - tmp.line = info->line; - tmp.port = info->line; - tmp.irq = 0; - tmp.flags = info->flags; - tmp.baud_base = 0; /*!!!*/ - tmp.close_delay = info->close_delay; - tmp.custom_divisor = 0; /*!!!*/ - tmp.hub6 = 0; /*!!!*/ - return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; -} /* get_serial_info */ + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = info->line; + tmp.irq = 0; + tmp.flags = info->flags; + tmp.baud_base = 0; /*!!! */ + tmp.close_delay = info->close_delay; + tmp.custom_divisor = 0; /*!!! */ + tmp.hub6 = 0; /*!!! */ + return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; +} /* get_serial_info */ static int -set_serial_info(struct cyclades_port * info, - struct serial_struct __user * new_info) +set_serial_info(struct cyclades_port *info, + struct serial_struct __user * new_info) { - struct serial_struct new_serial; - struct cyclades_port old_info; + struct serial_struct new_serial; + struct cyclades_port old_info; /* CP('s'); */ - if (!new_info) - return -EFAULT; - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - old_info = *info; + if (!new_info) + return -EFAULT; + if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) + return -EFAULT; + old_info = *info; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != + (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + goto check_and_exit; + } - if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != - (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) - return -EPERM; - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - goto check_and_exit; - } + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + info->flags = ((info->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->close_delay = new_serial.close_delay; - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ +check_and_exit: + if (info->flags & ASYNC_INITIALIZED) { + config_setup(info); + return 0; + } + return startup(info); +} /* set_serial_info */ - info->flags = ((info->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->close_delay = new_serial.close_delay; +static int cy_tiocmget(struct tty_struct *tty, struct file *file) +{ + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int channel; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long flags; + unsigned char status; + channel = info->line; -check_and_exit: - if (info->flags & ASYNC_INITIALIZED){ - config_setup(info); - return 0; - }else{ - return startup(info); - } -} /* set_serial_info */ + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + status = base_addr[CyMSVR1] | base_addr[CyMSVR2]; + local_irq_restore(flags); -static int -cy_tiocmget(struct tty_struct *tty, struct file *file) -{ - struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - unsigned long flags; - unsigned char status; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; - status = base_addr[CyMSVR1] | base_addr[CyMSVR2]; - local_irq_restore(flags); - - return ((status & CyRTS) ? TIOCM_RTS : 0) - | ((status & CyDTR) ? TIOCM_DTR : 0) - | ((status & CyDCD) ? TIOCM_CAR : 0) - | ((status & CyDSR) ? TIOCM_DSR : 0) - | ((status & CyCTS) ? TIOCM_CTS : 0); -} /* cy_tiocmget */ + return ((status & CyRTS) ? TIOCM_RTS : 0) + | ((status & CyDTR) ? TIOCM_DTR : 0) + | ((status & CyDCD) ? TIOCM_CAR : 0) + | ((status & CyDSR) ? TIOCM_DSR : 0) + | ((status & CyCTS) ? TIOCM_CTS : 0); +} /* cy_tiocmget */ static int cy_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { - struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - unsigned long flags; - - channel = info->line; - - if (set & TIOCM_RTS){ - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int channel; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long flags; + + channel = info->line; + + if (set & TIOCM_RTS) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); + local_irq_restore(flags); } - if (set & TIOCM_DTR){ - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + if (set & TIOCM_DTR) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; /* CP('S');CP('2'); */ - base_addr[CyMSVR2] = CyDTR; + base_addr[CyMSVR2] = CyDTR; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif - local_irq_restore(flags); + local_irq_restore(flags); } - if (clear & TIOCM_RTS){ - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + if (clear & TIOCM_RTS) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; base_addr[CyMSVR1] = 0; - local_irq_restore(flags); + local_irq_restore(flags); } - if (clear & TIOCM_DTR){ - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + if (clear & TIOCM_DTR) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; /* CP('C');CP('2'); */ - base_addr[CyMSVR2] = 0; + base_addr[CyMSVR2] = 0; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); #endif - local_irq_restore(flags); + local_irq_restore(flags); } - return 0; -} /* set_modem_info */ - -static void -send_break( struct cyclades_port * info, int duration) -{ /* Let the transmit ISR take care of this (since it - requires stuffing characters into the output stream). - */ - info->x_break = duration; - if (!info->xmit_cnt ) { - start_xmit(info); - } -} /* send_break */ + return 0; +} /* set_modem_info */ + +static void send_break(struct cyclades_port *info, int duration) +{ /* Let the transmit ISR take care of this (since it + requires stuffing characters into the output stream). + */ + info->x_break = duration; + if (!info->xmit_cnt) { + start_xmit(info); + } +} /* send_break */ static int -get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) +get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) { - if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) - return -EFAULT; - info->mon.int_count = 0; - info->mon.char_count = 0; - info->mon.char_max = 0; - info->mon.char_last = 0; - return 0; + if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) + return -EFAULT; + info->mon.int_count = 0; + info->mon.char_count = 0; + info->mon.char_max = 0; + info->mon.char_last = 0; + return 0; } -static int -set_threshold(struct cyclades_port * info, unsigned long __user *arg) +static int set_threshold(struct cyclades_port *info, unsigned long __user * arg) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - unsigned long value; - int channel; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - info->cor4 &= ~CyREC_FIFO; - info->cor4 |= value & CyREC_FIFO; - base_addr[CyCOR4] = info->cor4; - return 0; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long value; + int channel; + + if (get_user(value, arg)) + return -EFAULT; + + channel = info->line; + info->cor4 &= ~CyREC_FIFO; + info->cor4 |= value & CyREC_FIFO; + base_addr[CyCOR4] = info->cor4; + return 0; } static int -get_threshold(struct cyclades_port * info, unsigned long __user *value) +get_threshold(struct cyclades_port *info, unsigned long __user * value) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyCOR4] & CyREC_FIFO; - return put_user(tmp,value); + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long tmp; + + channel = info->line; + + tmp = base_addr[CyCOR4] & CyREC_FIFO; + return put_user(tmp, value); } static int -set_default_threshold(struct cyclades_port * info, unsigned long __user *arg) +set_default_threshold(struct cyclades_port *info, unsigned long __user * arg) { - unsigned long value; + unsigned long value; - if (get_user(value, arg)) - return -EFAULT; + if (get_user(value, arg)) + return -EFAULT; - info->default_threshold = value & 0x0f; - return 0; + info->default_threshold = value & 0x0f; + return 0; } static int -get_default_threshold(struct cyclades_port * info, unsigned long __user *value) +get_default_threshold(struct cyclades_port *info, unsigned long __user * value) { - return put_user(info->default_threshold,value); + return put_user(info->default_threshold, value); } -static int -set_timeout(struct cyclades_port * info, unsigned long __user *arg) +static int set_timeout(struct cyclades_port *info, unsigned long __user * arg) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - unsigned long value; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - - base_addr[CyRTPRL] = value & 0xff; - base_addr[CyRTPRH] = (value >> 8) & 0xff; - return 0; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long value; + + if (get_user(value, arg)) + return -EFAULT; + + channel = info->line; + + base_addr[CyRTPRL] = value & 0xff; + base_addr[CyRTPRH] = (value >> 8) & 0xff; + return 0; } -static int -get_timeout(struct cyclades_port * info, unsigned long __user *value) +static int get_timeout(struct cyclades_port *info, unsigned long __user * value) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyRTPRL]; - return put_user(tmp,value); + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long tmp; + + channel = info->line; + + tmp = base_addr[CyRTPRL]; + return put_user(tmp, value); } -static int -set_default_timeout(struct cyclades_port * info, unsigned long value) +static int set_default_timeout(struct cyclades_port *info, unsigned long value) { - info->default_timeout = value & 0xff; - return 0; + info->default_timeout = value & 0xff; + return 0; } static int -get_default_timeout(struct cyclades_port * info, unsigned long __user *value) +get_default_timeout(struct cyclades_port *info, unsigned long __user * value) { - return put_user(info->default_timeout,value); + return put_user(info->default_timeout, value); } static int -cy_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) +cy_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { - unsigned long val; - struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; - int ret_val = 0; - void __user *argp = (void __user *)arg; + unsigned long val; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int ret_val = 0; + void __user *argp = (void __user *)arg; #ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ -#endif - - switch (cmd) { - case CYGETMON: - ret_val = get_mon_info(info, argp); - break; - case CYGETTHRESH: - ret_val = get_threshold(info, argp); - break; - case CYSETTHRESH: - ret_val = set_threshold(info, argp); - break; - case CYGETDEFTHRESH: - ret_val = get_default_threshold(info, argp); - break; - case CYSETDEFTHRESH: - ret_val = set_default_threshold(info, argp); - break; - case CYGETTIMEOUT: - ret_val = get_timeout(info, argp); - break; - case CYSETTIMEOUT: - ret_val = set_timeout(info, argp); - break; - case CYGETDEFTIMEOUT: - ret_val = get_default_timeout(info, argp); - break; - case CYSETDEFTIMEOUT: - ret_val = set_default_timeout(info, (unsigned long)arg); - break; - case TCSBRK: /* SVID version: non-zero arg --> no break */ - ret_val = tty_check_change(tty); - if (ret_val) - break; - tty_wait_until_sent(tty,0); - if (!arg) - send_break(info, HZ/4); /* 1/4 second */ - break; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - ret_val = tty_check_change(tty); - if (ret_val) + printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ +#endif + + switch (cmd) { + case CYGETMON: + ret_val = get_mon_info(info, argp); + break; + case CYGETTHRESH: + ret_val = get_threshold(info, argp); + break; + case CYSETTHRESH: + ret_val = set_threshold(info, argp); + break; + case CYGETDEFTHRESH: + ret_val = get_default_threshold(info, argp); + break; + case CYSETDEFTHRESH: + ret_val = set_default_threshold(info, argp); + break; + case CYGETTIMEOUT: + ret_val = get_timeout(info, argp); + break; + case CYSETTIMEOUT: + ret_val = set_timeout(info, argp); + break; + case CYGETDEFTIMEOUT: + ret_val = get_default_timeout(info, argp); + break; + case CYSETDEFTIMEOUT: + ret_val = set_default_timeout(info, (unsigned long)arg); + break; + case TCSBRK: /* SVID version: non-zero arg --> no break */ + ret_val = tty_check_change(tty); + if (ret_val) + break; + tty_wait_until_sent(tty, 0); + if (!arg) + send_break(info, HZ / 4); /* 1/4 second */ + break; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + ret_val = tty_check_change(tty); + if (ret_val) + break; + tty_wait_until_sent(tty, 0); + send_break(info, arg ? arg * (HZ / 10) : HZ / 4); break; - tty_wait_until_sent(tty,0); - send_break(info, arg ? arg*(HZ/10) : HZ/4); - break; /* The following commands are incompletely implemented!!! */ - case TIOCGSOFTCAR: - ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); - break; - case TIOCSSOFTCAR: - ret_val = get_user(val, (unsigned long __user *) argp); - if (ret_val) - break; - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); - break; - case TIOCGSERIAL: - ret_val = get_serial_info(info, argp); - break; - case TIOCSSERIAL: - ret_val = set_serial_info(info, argp); - break; - default: - ret_val = -ENOIOCTLCMD; - } + case TIOCGSOFTCAR: + ret_val = + put_user(C_CLOCAL(tty) ? 1 : 0, + (unsigned long __user *)argp); + break; + case TIOCSSOFTCAR: + ret_val = get_user(val, (unsigned long __user *)argp); + if (ret_val) + break; + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); + break; + case TIOCGSERIAL: + ret_val = get_serial_info(info, argp); + break; + case TIOCSSERIAL: + ret_val = set_serial_info(info, argp); + break; + default: + ret_val = -ENOIOCTLCMD; + } #ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl done\n"); + printk("cy_ioctl done\n"); #endif - return ret_val; -} /* cy_ioctl */ - + return ret_val; +} /* cy_ioctl */ - - -static void -cy_set_termios(struct tty_struct *tty, struct ktermios * old_termios) +static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; #ifdef SERIAL_DEBUG_OTHER - printk("cy_set_termios %s\n", tty->name); + printk("cy_set_termios %s\n", tty->name); #endif - if (tty->termios->c_cflag == old_termios->c_cflag) - return; - config_setup(info); + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + config_setup(info); - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->stopped = 0; - cy_start(tty); - } + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->stopped = 0; + cy_start(tty); + } #ifdef tytso_patch_94Nov25_1726 - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&info->open_wait); #endif +} /* cy_set_termios */ - return; -} /* cy_set_termios */ - - -static void -cy_close(struct tty_struct * tty, struct file * filp) +static void cy_close(struct tty_struct *tty, struct file *filp) { - struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; /* CP('C'); */ #ifdef SERIAL_DEBUG_OTHER - printk("cy_close %s\n", tty->name); + printk("cy_close %s\n", tty->name); #endif - if (!info - || serial_paranoia_check(info, tty->name, "cy_close")){ - return; - } + if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { + return; + } #ifdef SERIAL_DEBUG_OPEN - printk("cy_close %s, count = %d\n", tty->name, info->count); -#endif - - if ((tty->count == 1) && (info->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. Info->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("cy_close: bad serial port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; - } + printk("cy_close %s, count = %d\n", tty->name, info->count); +#endif + + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("cy_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1); + printk("cyc: %d: decrementing count to %d\n", __LINE__, + info->count - 1); #endif - if (--info->count < 0) { - printk("cy_close: bad serial port count for ttys%d: %d\n", - info->line, info->count); + if (--info->count < 0) { + printk("cy_close: bad serial port count for ttys%d: %d\n", + info->line, info->count); #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); + printk("cyc: %d: setting count to 0\n", __LINE__); #endif - info->count = 0; - } - if (info->count) - return; - info->flags |= ASYNC_CLOSING; - if (info->flags & ASYNC_INITIALIZED) - tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - tty_ldisc_flush(tty); - info->event = 0; - info->tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs(info->close_delay)); + info->count = 0; } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); + if (info->count) + return; + info->flags |= ASYNC_CLOSING; + if (info->flags & ASYNC_INITIALIZED) + tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ + shutdown(info); + if (tty->driver->flush_buffer) + tty->driver->flush_buffer(tty); + tty_ldisc_flush(tty); + info->event = 0; + info->tty = NULL; + if (info->blocked_open) { + if (info->close_delay) { + msleep_interruptible(jiffies_to_msecs + (info->close_delay)); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); #ifdef SERIAL_DEBUG_OTHER - printk("cy_close done\n"); + printk("cy_close done\n"); #endif - - return; -} /* cy_close */ +} /* cy_close */ /* * cy_hangup() --- called by tty_hangup() when a hangup is signaled. */ -void -cy_hangup(struct tty_struct *tty) +void cy_hangup(struct tty_struct *tty) { - struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; - + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + #ifdef SERIAL_DEBUG_OTHER - printk("cy_hangup %s\n", tty->name); /* */ + printk("cy_hangup %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_hangup")) - return; - - shutdown(info); + if (serial_paranoia_check(info, tty->name, "cy_hangup")) + return; + + shutdown(info); #if 0 - info->event = 0; - info->count = 0; + info->event = 0; + info->count = 0; #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); + printk("cyc: %d: setting count to 0\n", __LINE__); #endif - info->tty = 0; + info->tty = 0; #endif - info->flags &= ~ASYNC_NORMAL_ACTIVE; - wake_up_interruptible(&info->open_wait); -} /* cy_hangup */ - - + info->flags &= ~ASYNC_NORMAL_ACTIVE; + wake_up_interruptible(&info->open_wait); +} /* cy_hangup */ /* * ------------------------------------------------------------ @@ -1827,177 +1796,180 @@ cy_hangup(struct tty_struct *tty) */ static int -block_til_ready(struct tty_struct *tty, struct file * filp, - struct cyclades_port *info) +block_til_ready(struct tty_struct *tty, struct file *filp, + struct cyclades_port *info) { - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; - int channel; - int retval; - volatile u_char *base_addr = (u_char *)BASE_ADDR; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (info->flags & ASYNC_CLOSING) { - interruptible_sleep_on(&info->close_wait); - if (info->flags & ASYNC_HUP_NOTIFY){ - return -EAGAIN; - }else{ - return -ERESTARTSYS; - } - } - - /* - * If non-blocking mode is set, then make the check up front - * and then exit. - */ - if (filp->f_flags & O_NONBLOCK) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * cy_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int channel; + int retval; + volatile u_char *base_addr = (u_char *) BASE_ADDR; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ASYNC_CLOSING) { + interruptible_sleep_on(&info->close_wait); + if (info->flags & ASYNC_HUP_NOTIFY) { + return -EAGAIN; + } else { + return -ERESTARTSYS; + } + } + + /* + * If non-blocking mode is set, then make the check up front + * and then exit. + */ + if (filp->f_flags & O_NONBLOCK) { + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * cy_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); #ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: %s, count = %d\n", - tty->name, info->count);/**/ + printk("block_til_ready before block: %s, count = %d\n", + tty->name, info->count); + /**/ #endif - info->count--; + info->count--; #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count); + printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count); #endif - info->blocked_open++; + info->blocked_open++; - channel = info->line; + channel = info->line; - while (1) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; - base_addr[CyMSVR1] = CyRTS; + while (1) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = CyRTS; /* CP('S');CP('4'); */ - base_addr[CyMSVR2] = CyDTR; + base_addr[CyMSVR2] = CyDTR; #ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) - || !(info->flags & ASYNC_INITIALIZED) ){ - if (info->flags & ASYNC_HUP_NOTIFY) { - retval = -EAGAIN; - }else{ - retval = -ERESTARTSYS; - } - break; - } - local_irq_save(flags); - base_addr[CyCAR] = (u_char)channel; + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + local_irq_restore(flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) + || !(info->flags & ASYNC_INITIALIZED)) { + if (info->flags & ASYNC_HUP_NOTIFY) { + retval = -EAGAIN; + } else { + retval = -ERESTARTSYS; + } + break; + } + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; /* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */ - if (!(info->flags & ASYNC_CLOSING) - && (C_CLOCAL(tty) - || (base_addr[CyMSVR1] & CyDCD))) { - local_irq_restore(flags); - break; - } - local_irq_restore(flags); - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } + if (!(info->flags & ASYNC_CLOSING) + && (C_CLOCAL(tty) + || (base_addr[CyMSVR1] & CyDCD))) { + local_irq_restore(flags); + break; + } + local_irq_restore(flags); + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } #ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: %s, count = %d\n", - tty->name, info->count);/**/ -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)){ - info->count++; + printk("block_til_ready blocking: %s, count = %d\n", + tty->name, info->count); + /**/ +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) { + info->count++; #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); + printk("cyc: %d: incrementing count to %d\n", __LINE__, + info->count); #endif - } - info->blocked_open--; + } + info->blocked_open--; #ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: %s, count = %d\n", - tty->name, info->count);/**/ + printk("block_til_ready after blocking: %s, count = %d\n", + tty->name, info->count); + /**/ #endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} /* block_til_ready */ + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} /* block_til_ready */ /* * This routine is called whenever a serial port is opened. It * performs the serial-specific initialization for the tty structure. */ -int -cy_open(struct tty_struct *tty, struct file * filp) +int cy_open(struct tty_struct *tty, struct file *filp) { - struct cyclades_port *info; - int retval, line; + struct cyclades_port *info; + int retval, line; /* CP('O'); */ - line = tty->index; - if ((line < 0) || (NR_PORTS <= line)){ - return -ENODEV; - } - info = &cy_port[line]; - if (info->line < 0){ - return -ENODEV; - } + line = tty->index; + if ((line < 0) || (NR_PORTS <= line)) { + return -ENODEV; + } + info = &cy_port[line]; + if (info->line < 0) { + return -ENODEV; + } #ifdef SERIAL_DEBUG_OTHER - printk("cy_open %s\n", tty->name); /* */ + printk("cy_open %s\n", tty->name); /* */ #endif - if (serial_paranoia_check(info, tty->name, "cy_open")){ - return -ENODEV; - } + if (serial_paranoia_check(info, tty->name, "cy_open")) { + return -ENODEV; + } #ifdef SERIAL_DEBUG_OPEN - printk("cy_open %s, count = %d\n", tty->name, info->count);/**/ + printk("cy_open %s, count = %d\n", tty->name, info->count); + /**/ #endif - info->count++; + info->count++; #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); + printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); #endif - tty->driver_data = info; - info->tty = tty; + tty->driver_data = info; + info->tty = tty; - /* - * Start up serial port - */ - retval = startup(info); - if (retval){ - return retval; - } + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + return retval; + } - retval = block_til_ready(tty, filp, info); - if (retval) { + retval = block_til_ready(tty, filp, info); + if (retval) { #ifdef SERIAL_DEBUG_OPEN - printk("cy_open returning after block_til_ready with %d\n", - retval); + printk("cy_open returning after block_til_ready with %d\n", + retval); #endif - return retval; - } - + return retval; + } #ifdef SERIAL_DEBUG_OPEN - printk("cy_open done\n");/**/ + printk("cy_open done\n"); + /**/ #endif - return 0; -} /* cy_open */ - - + return 0; +} /* cy_open */ /* * --------------------------------------------------------------------- @@ -2012,11 +1984,10 @@ cy_open(struct tty_struct *tty, struct file * filp) * number, and identifies which options were configured into this * driver. */ -static void -show_version(void) +static void show_version(void) { - printk("MVME166/167 cd2401 driver\n"); -} /* show_version */ + printk("MVME166/167 cd2401 driver\n"); +} /* show_version */ /* initialize chips on card -- return number of valid chips (which is number of ports/4) */ @@ -2030,10 +2001,9 @@ show_version(void) * ... I wonder what I should do if this fails ... */ -void -mvme167_serial_console_setup(int cflag) +void mvme167_serial_console_setup(int cflag) { - volatile unsigned char* base_addr = (u_char *)BASE_ADDR; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; int ch; u_char spd; u_char rcor, rbpr, badspeed = 0; @@ -2062,21 +2032,21 @@ mvme167_serial_console_setup(int cflag) /* OK, we have chosen a speed, now reset and reinitialise */ - my_udelay(20000L); /* Allow time for any active o/p to complete */ - if(base_addr[CyCCR] != 0x00){ - local_irq_restore(flags); - /* printk(" chip is never idle (CCR != 0)\n"); */ - return; - } + my_udelay(20000L); /* Allow time for any active o/p to complete */ + if (base_addr[CyCCR] != 0x00) { + local_irq_restore(flags); + /* printk(" chip is never idle (CCR != 0)\n"); */ + return; + } - base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */ - my_udelay(1000L); + base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */ + my_udelay(1000L); - if(base_addr[CyGFRCR] == 0x00){ - local_irq_restore(flags); - /* printk(" chip is not responding (GFRCR stayed 0)\n"); */ - return; - } + if (base_addr[CyGFRCR] == 0x00) { + local_irq_restore(flags); + /* printk(" chip is not responding (GFRCR stayed 0)\n"); */ + return; + } /* * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms @@ -2085,9 +2055,9 @@ mvme167_serial_console_setup(int cflag) base_addr[CyTPR] = 10; - base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */ - base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */ - base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */ + base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */ + base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */ + base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */ /* * Attempt to set up all channels to something reasonable, and @@ -2095,11 +2065,11 @@ mvme167_serial_console_setup(int cflag) * the ammount of fiddling we have to do in normal running. */ - for (ch = 3; ch >= 0 ; ch--) { - base_addr[CyCAR] = (u_char)ch; + for (ch = 3; ch >= 0; ch--) { + base_addr[CyCAR] = (u_char) ch; base_addr[CyIER] = 0; base_addr[CyCMR] = CyASYNC; - base_addr[CyLICR] = (u_char)ch << 2; + base_addr[CyLICR] = (u_char) ch << 2; base_addr[CyLIVR] = 0x5c; base_addr[CyTCOR] = baud_co[spd]; base_addr[CyTBPR] = baud_bpr[spd]; @@ -2118,29 +2088,30 @@ mvme167_serial_console_setup(int cflag) base_addr[CyCOR7] = 0; base_addr[CyRTPRL] = 2; base_addr[CyRTPRH] = 0; - base_addr[CyMSVR1] = 0; - base_addr[CyMSVR2] = 0; - write_cy_cmd(base_addr,CyINIT_CHAN|CyDIS_RCVR|CyDIS_XMTR); + base_addr[CyMSVR1] = 0; + base_addr[CyMSVR2] = 0; + write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR); } /* * Now do specials for channel zero.... */ - base_addr[CyMSVR1] = CyRTS; - base_addr[CyMSVR2] = CyDTR; + base_addr[CyMSVR1] = CyRTS; + base_addr[CyMSVR2] = CyDTR; base_addr[CyIER] = CyRxData; - write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR); + write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); local_irq_restore(flags); my_udelay(20000L); /* Let it all settle down */ - printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]); + printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]); if (badspeed) - printk(" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n", - rcor >> 5, rbpr); -} /* serial_console_init */ + printk + (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n", + rcor >> 5, rbpr); +} /* serial_console_init */ static const struct tty_operations cy_ops = { .open = cy_open, @@ -2161,6 +2132,7 @@ static const struct tty_operations cy_ops = { .tiocmget = cy_tiocmget, .tiocmset = cy_tiocmset, }; + /* The serial driver boot-time initialization code! Hardware I/O ports are mapped to character special devices on a first found, first allocated manner. That is, this code searches @@ -2177,214 +2149,214 @@ static const struct tty_operations cy_ops = { If there are more cards with more ports than have been statically allocated above, a warning is printed and the extra ports are ignored. */ -static int __init -serial167_init(void) +static int __init serial167_init(void) { - struct cyclades_port *info; - int ret = 0; - int good_ports = 0; - int port_num = 0; - int index; - int DefSpeed; + struct cyclades_port *info; + int ret = 0; + int good_ports = 0; + int port_num = 0; + int index; + int DefSpeed; #ifdef notyet - struct sigaction sa; + struct sigaction sa; #endif - if (!(mvme16x_config &MVME16x_CONFIG_GOT_CD2401)) - return 0; + if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401)) + return 0; - cy_serial_driver = alloc_tty_driver(NR_PORTS); - if (!cy_serial_driver) - return -ENOMEM; + cy_serial_driver = alloc_tty_driver(NR_PORTS); + if (!cy_serial_driver) + return -ENOMEM; #if 0 -scrn[1] = '\0'; + scrn[1] = '\0'; #endif - show_version(); + show_version(); - /* Has "console=0,9600n8" been used in bootinfo to change speed? */ - if (serial_console_cflag) - DefSpeed = serial_console_cflag & 0017; - else { - DefSpeed = initial_console_speed; - serial_console_info = &cy_port[0]; - serial_console_cflag = DefSpeed | CS8; + /* Has "console=0,9600n8" been used in bootinfo to change speed? */ + if (serial_console_cflag) + DefSpeed = serial_console_cflag & 0017; + else { + DefSpeed = initial_console_speed; + serial_console_info = &cy_port[0]; + serial_console_cflag = DefSpeed | CS8; #if 0 - serial_console = 64; /*callout_driver.minor_start*/ -#endif - } - - /* Initialize the tty_driver structure */ - - cy_serial_driver->owner = THIS_MODULE; - cy_serial_driver->name = "ttyS"; - cy_serial_driver->major = TTY_MAJOR; - cy_serial_driver->minor_start = 64; - cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; - cy_serial_driver->init_termios = tty_std_termios; - cy_serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(cy_serial_driver, &cy_ops); + serial_console = 64; /*callout_driver.minor_start */ +#endif + } - ret = tty_register_driver(cy_serial_driver); - if (ret) { - printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; - } + /* Initialize the tty_driver structure */ - port_num = 0; - info = cy_port; - for (index = 0; index < 1; index++) { + cy_serial_driver->owner = THIS_MODULE; + cy_serial_driver->name = "ttyS"; + cy_serial_driver->major = TTY_MAJOR; + cy_serial_driver->minor_start = 64; + cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; + cy_serial_driver->init_termios = tty_std_termios; + cy_serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(cy_serial_driver, &cy_ops); + + ret = tty_register_driver(cy_serial_driver); + if (ret) { + printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n"); + put_tty_driver(cy_serial_driver); + return ret; + } - good_ports = 4; + port_num = 0; + info = cy_port; + for (index = 0; index < 1; index++) { - if(port_num < NR_PORTS){ - while( good_ports-- && port_num < NR_PORTS){ + good_ports = 4; + + if (port_num < NR_PORTS) { + while (good_ports-- && port_num < NR_PORTS) { /*** initialize port ***/ - info->magic = CYCLADES_MAGIC; - info->type = PORT_CIRRUS; - info->card = index; - info->line = port_num; - info->flags = STD_COM_FLAGS; - info->tty = NULL; - info->xmit_fifo_size = 12; - info->cor1 = CyPARITY_NONE|Cy_8_BITS; - info->cor2 = CyETC; - info->cor3 = Cy_1_STOP; - info->cor4 = 0x08; /* _very_ small receive threshold */ - info->cor5 = 0; - info->cor6 = 0; - info->cor7 = 0; - info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */ - info->tco = baud_co[DefSpeed]; /* Tx CO */ - info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */ - info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ - info->close_delay = 0; - info->x_char = 0; - info->event = 0; - info->count = 0; + info->magic = CYCLADES_MAGIC; + info->type = PORT_CIRRUS; + info->card = index; + info->line = port_num; + info->flags = STD_COM_FLAGS; + info->tty = NULL; + info->xmit_fifo_size = 12; + info->cor1 = CyPARITY_NONE | Cy_8_BITS; + info->cor2 = CyETC; + info->cor3 = Cy_1_STOP; + info->cor4 = 0x08; /* _very_ small receive threshold */ + info->cor5 = 0; + info->cor6 = 0; + info->cor7 = 0; + info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */ + info->tco = baud_co[DefSpeed]; /* Tx CO */ + info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */ + info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ + info->close_delay = 0; + info->x_char = 0; + info->event = 0; + info->count = 0; #ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); -#endif - info->blocked_open = 0; - info->default_threshold = 0; - info->default_timeout = 0; - INIT_WORK(&info->tqueue, do_softint); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - /* info->session */ - /* info->pgrp */ + printk("cyc: %d: setting count to 0\n", + __LINE__); +#endif + info->blocked_open = 0; + info->default_threshold = 0; + info->default_timeout = 0; + INIT_WORK(&info->tqueue, do_softint); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + /* info->session */ + /* info->pgrp */ /*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/ - info->read_status_mask = CyTIMEOUT| CySPECHAR| CyBREAK - | CyPARITY| CyFRAME| CyOVERRUN; - /* info->timeout */ - - printk("ttyS%d ", info->line); - port_num++;info++; - if(!(port_num & 7)){ - printk("\n "); + info->read_status_mask = + CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY | + CyFRAME | CyOVERRUN; + /* info->timeout */ + + printk("ttyS%d ", info->line); + port_num++; + info++; + if (!(port_num & 7)) { + printk("\n "); + } + } } - } - } - printk("\n"); - } - while( port_num < NR_PORTS){ - info->line = -1; - port_num++;info++; - } + printk("\n"); + } + while (port_num < NR_PORTS) { + info->line = -1; + port_num++; + info++; + } #ifdef CONFIG_REMOTE_DEBUG - debug_setup(); -#endif - ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0, - "cd2401_errors", cd2401_rxerr_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_errors IRQ"); - goto cleanup_serial_driver; - } - - ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0, - "cd2401_modem", cd2401_modem_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_modem IRQ"); - goto cleanup_irq_cd2401_errors; - } - - ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0, - "cd2401_txints", cd2401_tx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_txints IRQ"); - goto cleanup_irq_cd2401_modem; - } - - ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0, - "cd2401_rxints", cd2401_rx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_rxints IRQ"); - goto cleanup_irq_cd2401_txints; - } - - /* Now we have registered the interrupt handlers, allow the interrupts */ - - pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */ - pcc2chip[PccSCCTICR] = 0x15; - pcc2chip[PccSCCRICR] = 0x15; - - pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */ - - return 0; + debug_setup(); +#endif + ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0, + "cd2401_errors", cd2401_rxerr_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_errors IRQ"); + goto cleanup_serial_driver; + } + + ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0, + "cd2401_modem", cd2401_modem_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_modem IRQ"); + goto cleanup_irq_cd2401_errors; + } + + ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0, + "cd2401_txints", cd2401_tx_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_txints IRQ"); + goto cleanup_irq_cd2401_modem; + } + + ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0, + "cd2401_rxints", cd2401_rx_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_rxints IRQ"); + goto cleanup_irq_cd2401_txints; + } + + /* Now we have registered the interrupt handlers, allow the interrupts */ + + pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */ + pcc2chip[PccSCCTICR] = 0x15; + pcc2chip[PccSCCRICR] = 0x15; + + pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */ + + return 0; cleanup_irq_cd2401_txints: - free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt); + free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt); cleanup_irq_cd2401_modem: - free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt); + free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt); cleanup_irq_cd2401_errors: - free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt); + free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt); cleanup_serial_driver: - if (tty_unregister_driver(cy_serial_driver)) - printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; -} /* serial167_init */ + if (tty_unregister_driver(cy_serial_driver)) + printk(KERN_ERR + "Couldn't unregister MVME166/7 serial driver\n"); + put_tty_driver(cy_serial_driver); + return ret; +} /* serial167_init */ module_init(serial167_init); - #ifdef CYCLOM_SHOW_STATUS -static void -show_status(int line_num) +static void show_status(int line_num) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int channel; - struct cyclades_port * info; - unsigned long flags; - - info = &cy_port[line_num]; - channel = info->line; - printk(" channel %d\n", channel);/**/ - - printk(" cy_port\n"); - printk(" card line flags = %d %d %x\n", - info->card, info->line, info->flags); - printk(" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n", - (long)info->tty, info->read_status_mask, - info->timeout, info->xmit_fifo_size); - printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n", - info->cor1, info->cor2, info->cor3, info->cor4, info->cor5, - info->cor6, info->cor7); - printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", - info->tbpr, info->tco, info->rbpr, info->rco); - printk(" close_delay event count = %d %d %d\n", - info->close_delay, info->event, info->count); - printk(" x_char blocked_open = %x %x\n", - info->x_char, info->blocked_open); - printk(" open_wait = %lx %lx %lx\n", - (long)info->open_wait); - - - local_irq_save(flags); + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + struct cyclades_port *info; + unsigned long flags; + + info = &cy_port[line_num]; + channel = info->line; + printk(" channel %d\n", channel); + /**/ printk(" cy_port\n"); + printk(" card line flags = %d %d %x\n", + info->card, info->line, info->flags); + printk + (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n", + (long)info->tty, info->read_status_mask, info->timeout, + info->xmit_fifo_size); + printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n", + info->cor1, info->cor2, info->cor3, info->cor4, info->cor5, + info->cor6, info->cor7); + printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco, + info->rbpr, info->rco); + printk(" close_delay event count = %d %d %d\n", info->close_delay, + info->event, info->count); + printk(" x_char blocked_open = %x %x\n", info->x_char, + info->blocked_open); + printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait); + + local_irq_save(flags); /* Global Registers */ @@ -2398,7 +2370,7 @@ show_status(int line_num) printk(" CyMIR %x\n", base_addr[CyMIR]); printk(" CyTPR %x\n", base_addr[CyTPR]); - base_addr[CyCAR] = (u_char)channel; + base_addr[CyCAR] = (u_char) channel; /* Virtual Registers */ @@ -2442,11 +2414,10 @@ show_status(int line_num) printk(" CyTBPR %x\n", base_addr[CyTBPR]); printk(" CyTCOR %x\n", base_addr[CyTCOR]); - local_irq_restore(flags); -} /* show_status */ + local_irq_restore(flags); +} /* show_status */ #endif - #if 0 /* Dummy routine in mvme16x/config.c for now */ @@ -2459,61 +2430,67 @@ void console_setup(char *str, int *ints) int cflag = 0; /* Sanity check. */ - if (ints[0] > 3 || ints[1] > 3) return; + if (ints[0] > 3 || ints[1] > 3) + return; /* Get baud, bits and parity */ baud = 2400; bits = 8; parity = 'n'; - if (ints[2]) baud = ints[2]; + if (ints[2]) + baud = ints[2]; if ((s = strchr(str, ','))) { do { s++; - } while(*s >= '0' && *s <= '9'); - if (*s) parity = *s++; - if (*s) bits = *s - '0'; + } while (*s >= '0' && *s <= '9'); + if (*s) + parity = *s++; + if (*s) + bits = *s - '0'; } /* Now construct a cflag setting. */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 9600: - cflag |= B9600; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 2400: - default: - cflag |= B2400; - break; + switch (baud) { + case 1200: + cflag |= B1200; + break; + case 9600: + cflag |= B9600; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 2400: + default: + cflag |= B2400; + break; } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; + switch (bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; + switch (parity) { + case 'o': + case 'O': + cflag |= PARODD; + break; + case 'e': + case 'E': + cflag |= PARENB; + break; } serial_console_info = &cy_port[ints[1]]; serial_console_cflag = cflag; - serial_console = ints[1] + 64; /*callout_driver.minor_start*/ + serial_console = ints[1] + 64; /*callout_driver.minor_start */ } #endif @@ -2532,9 +2509,10 @@ void console_setup(char *str, int *ints) * The console must be locked when we get here. */ -void serial167_console_write(struct console *co, const char *str, unsigned count) +void serial167_console_write(struct console *co, const char *str, + unsigned count) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; unsigned long flags; volatile u_char sink; u_char ier; @@ -2547,7 +2525,7 @@ void serial167_console_write(struct console *co, const char *str, unsigned count /* Ensure transmitter is enabled! */ port = 0; - base_addr[CyCAR] = (u_char)port; + base_addr[CyCAR] = (u_char) port; while (base_addr[CyCCR]) ; base_addr[CyCCR] = CyENB_XMTR; @@ -2556,8 +2534,7 @@ void serial167_console_write(struct console *co, const char *str, unsigned count base_addr[CyIER] = CyTxMpty; while (1) { - if (pcc2chip[PccSCCTICR] & 0x20) - { + if (pcc2chip[PccSCCTICR] & 0x20) { /* We have a Tx int. Acknowledge it */ sink = pcc2chip[PccTPIACKR]; if ((base_addr[CyLICR] >> 2) == port) { @@ -2571,18 +2548,15 @@ void serial167_console_write(struct console *co, const char *str, unsigned count str++; i++; do_lf = 0; - } - else if (*str == '\n') { + } else if (*str == '\n') { base_addr[CyTDR] = '\r'; do_lf = 1; - } - else { + } else { base_addr[CyTDR] = *str++; i++; } base_addr[CyTEOIR] = 0; - } - else + } else base_addr[CyTEOIR] = CyNOTRANS; } } @@ -2592,45 +2566,44 @@ void serial167_console_write(struct console *co, const char *str, unsigned count local_irq_restore(flags); } -static struct tty_driver *serial167_console_device(struct console *c, int *index) +static struct tty_driver *serial167_console_device(struct console *c, + int *index) { *index = c->index; return cy_serial_driver; } - static int __init serial167_console_setup(struct console *co, char *options) { return 0; } - static struct console sercons = { - .name = "ttyS", - .write = serial167_console_write, - .device = serial167_console_device, - .setup = serial167_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "ttyS", + .write = serial167_console_write, + .device = serial167_console_device, + .setup = serial167_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; - static int __init serial167_console_init(void) { if (vme_brdtype == VME_TYPE_MVME166 || - vme_brdtype == VME_TYPE_MVME167 || - vme_brdtype == VME_TYPE_MVME177) { + vme_brdtype == VME_TYPE_MVME167 || + vme_brdtype == VME_TYPE_MVME177) { mvme167_serial_console_setup(0); register_console(&sercons); } return 0; } + console_initcall(serial167_console_init); #ifdef CONFIG_REMOTE_DEBUG -void putDebugChar (int c) +void putDebugChar(int c) { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; unsigned long flags; volatile u_char sink; u_char ier; @@ -2641,7 +2614,7 @@ void putDebugChar (int c) /* Ensure transmitter is enabled! */ port = DEBUG_PORT; - base_addr[CyCAR] = (u_char)port; + base_addr[CyCAR] = (u_char) port; while (base_addr[CyCCR]) ; base_addr[CyCCR] = CyENB_XMTR; @@ -2650,16 +2623,14 @@ void putDebugChar (int c) base_addr[CyIER] = CyTxMpty; while (1) { - if (pcc2chip[PccSCCTICR] & 0x20) - { + if (pcc2chip[PccSCCTICR] & 0x20) { /* We have a Tx int. Acknowledge it */ sink = pcc2chip[PccTPIACKR]; if ((base_addr[CyLICR] >> 2) == port) { base_addr[CyTDR] = c; base_addr[CyTEOIR] = 0; break; - } - else + } else base_addr[CyTEOIR] = CyNOTRANS; } } @@ -2671,7 +2642,7 @@ void putDebugChar (int c) int getDebugChar() { - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; unsigned long flags; volatile u_char sink; u_char ier; @@ -2693,7 +2664,7 @@ int getDebugChar() /* Ensure receiver is enabled! */ port = DEBUG_PORT; - base_addr[CyCAR] = (u_char)port; + base_addr[CyCAR] = (u_char) port; #if 0 while (base_addr[CyCCR]) ; @@ -2703,31 +2674,30 @@ int getDebugChar() base_addr[CyIER] = CyRxData; while (1) { - if (pcc2chip[PccSCCRICR] & 0x20) - { + if (pcc2chip[PccSCCRICR] & 0x20) { /* We have a Rx int. Acknowledge it */ sink = pcc2chip[PccRPIACKR]; if ((base_addr[CyLICR] >> 2) == port) { int cnt = base_addr[CyRFOC]; - while (cnt-- > 0) - { + while (cnt-- > 0) { c = base_addr[CyRDR]; if (c == 0) - printk ("!! debug char is null (cnt=%d) !!", cnt); + printk + ("!! debug char is null (cnt=%d) !!", + cnt); else - queueDebugChar (c); + queueDebugChar(c); } base_addr[CyREOIR] = 0; i = debugiq.out; if (i == debugiq.in) - panic ("Debug input queue empty!"); + panic("Debug input queue empty!"); c = debugiq.buf[i]; if (++i == DEBUG_LEN) i = 0; debugiq.out = i; break; - } - else + } else base_addr[CyREOIR] = CyNOTRANS; } } @@ -2739,7 +2709,7 @@ int getDebugChar() return (c); } -void queueDebugChar (int c) +void queueDebugChar(int c) { int i; @@ -2751,73 +2721,71 @@ void queueDebugChar (int c) debugiq.in = i; } -static void -debug_setup() +static void debug_setup() { - unsigned long flags; - volatile unsigned char *base_addr = (u_char *)BASE_ADDR; - int i, cflag; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int i, cflag; - cflag = B19200; + cflag = B19200; - local_irq_save(flags); + local_irq_save(flags); - for (i = 0; i < 4; i++) - { - base_addr[CyCAR] = i; - base_addr[CyLICR] = i << 2; - } + for (i = 0; i < 4; i++) { + base_addr[CyCAR] = i; + base_addr[CyLICR] = i << 2; + } - debugiq.in = debugiq.out = 0; + debugiq.in = debugiq.out = 0; - base_addr[CyCAR] = DEBUG_PORT; + base_addr[CyCAR] = DEBUG_PORT; - /* baud rate */ - i = cflag & CBAUD; + /* baud rate */ + i = cflag & CBAUD; - base_addr[CyIER] = 0; + base_addr[CyIER] = 0; - base_addr[CyCMR] = CyASYNC; - base_addr[CyLICR] = DEBUG_PORT << 2; - base_addr[CyLIVR] = 0x5c; + base_addr[CyCMR] = CyASYNC; + base_addr[CyLICR] = DEBUG_PORT << 2; + base_addr[CyLIVR] = 0x5c; - /* tx and rx baud rate */ + /* tx and rx baud rate */ - base_addr[CyTCOR] = baud_co[i]; - base_addr[CyTBPR] = baud_bpr[i]; - base_addr[CyRCOR] = baud_co[i] >> 5; - base_addr[CyRBPR] = baud_bpr[i]; + base_addr[CyTCOR] = baud_co[i]; + base_addr[CyTBPR] = baud_bpr[i]; + base_addr[CyRCOR] = baud_co[i] >> 5; + base_addr[CyRBPR] = baud_bpr[i]; - /* set line characteristics according configuration */ + /* set line characteristics according configuration */ - base_addr[CySCHR1] = 0; - base_addr[CySCHR2] = 0; - base_addr[CySCRL] = 0; - base_addr[CySCRH] = 0; - base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE; - base_addr[CyCOR2] = 0; - base_addr[CyCOR3] = Cy_1_STOP; - base_addr[CyCOR4] = baud_cor4[i]; - base_addr[CyCOR5] = 0; - base_addr[CyCOR6] = 0; - base_addr[CyCOR7] = 0; + base_addr[CySCHR1] = 0; + base_addr[CySCHR2] = 0; + base_addr[CySCRL] = 0; + base_addr[CySCRH] = 0; + base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE; + base_addr[CyCOR2] = 0; + base_addr[CyCOR3] = Cy_1_STOP; + base_addr[CyCOR4] = baud_cor4[i]; + base_addr[CyCOR5] = 0; + base_addr[CyCOR6] = 0; + base_addr[CyCOR7] = 0; - write_cy_cmd(base_addr,CyINIT_CHAN); - write_cy_cmd(base_addr,CyENB_RCVR); + write_cy_cmd(base_addr, CyINIT_CHAN); + write_cy_cmd(base_addr, CyENB_RCVR); - base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */ + base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */ - base_addr[CyRTPRL] = 2; - base_addr[CyRTPRH] = 0; + base_addr[CyRTPRL] = 2; + base_addr[CyRTPRH] = 0; - base_addr[CyMSVR1] = CyRTS; - base_addr[CyMSVR2] = CyDTR; + base_addr[CyMSVR1] = CyRTS; + base_addr[CyMSVR2] = CyDTR; - base_addr[CyIER] = CyRxData; + base_addr[CyIER] = CyRxData; - local_irq_restore(flags); + local_irq_restore(flags); -} /* debug_setup */ +} /* debug_setup */ #endif diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 20946f5127e..92043c8f235 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -2350,10 +2350,8 @@ static void do_softint(struct work_struct *work) return; } - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) tty_wakeup(tty); - //wake_up_interruptible(&tty->write_wait); - } func_exit(); } diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 3fa625db9e4..bf76db1342c 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -1148,10 +1148,8 @@ static void mgsl_bh_transmit(struct mgsl_struct *info) printk( "%s(%d):mgsl_bh_transmit() entry on %s\n", __FILE__,__LINE__,info->device_name); - if (tty) { + if (tty) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } /* if transmitter idle and loopmode_send_done_requested * then start echoing RxD to TxD @@ -2340,7 +2338,6 @@ static void mgsl_flush_buffer(struct tty_struct *tty) del_timer(&info->tx_timer); spin_unlock_irqrestore(&info->irq_spinlock,flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 792c79c315e..54af763518f 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1045,7 +1045,6 @@ static void flush_buffer(struct tty_struct *tty) info->tx_count = 0; spin_unlock_irqrestore(&info->lock,flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } @@ -1933,10 +1932,8 @@ static void bh_transmit(struct slgt_info *info) struct tty_struct *tty = info->tty; DBGBH(("%s bh_transmit\n", info->device_name)); - if (tty) { + if (tty) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } static void dsr_change(struct slgt_info *info) diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 8f4d67afe5b..ebde4e55233 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -1258,7 +1258,6 @@ static void flush_buffer(struct tty_struct *tty) del_timer(&info->tx_timer); spin_unlock_irqrestore(&info->lock,flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } @@ -2127,10 +2126,8 @@ void bh_transmit(SLMP_INFO *info) printk( "%s(%d):%s bh_transmit() entry\n", __FILE__,__LINE__,info->device_name); - if (tty) { + if (tty) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } void bh_status(SLMP_INFO *info) diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 7fd3cd5ddf2..3757610b783 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -88,9 +88,9 @@ static struct sysrq_key_op sysrq_loglevel_op = { #ifdef CONFIG_VT static void sysrq_handle_SAK(int key, struct tty_struct *tty) { - if (tty) - do_SAK(tty); - reset_vc(vc_cons[fg_console].d); + struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; + PREPARE_WORK(SAK_work, vc_SAK); + schedule_work(SAK_work); } static struct sysrq_key_op sysrq_SAK_op = { .handler = sysrq_handle_SAK, diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index 07067c31c4e..c346ec5a3dc 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c @@ -68,6 +68,7 @@ #include <linux/init.h> #include <linux/stat.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/toshiba.h> @@ -298,12 +299,10 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, * Print the information for /proc/toshiba */ #ifdef CONFIG_PROC_FS -static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) +static int proc_toshiba_show(struct seq_file *m, void *v) { - char *temp; int key; - temp = buffer; key = tosh_fn_status(); /* Arguments @@ -314,8 +313,7 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) 4) BIOS date (in SCI date format) 5) Fn Key status */ - - temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", + seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", tosh_id, (tosh_sci & 0xff00)>>8, tosh_sci & 0xff, @@ -323,9 +321,21 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) tosh_bios & 0xff, tosh_date, key); + return 0; +} - return temp-buffer; +static int proc_toshiba_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_toshiba_show, NULL); } + +static const struct file_operations proc_toshiba_fops = { + .owner = THIS_MODULE, + .open = proc_toshiba_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif @@ -508,10 +518,15 @@ static int __init toshiba_init(void) return retval; #ifdef CONFIG_PROC_FS - /* register the proc entry */ - if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) { - misc_deregister(&tosh_device); - return -ENOMEM; + { + struct proc_dir_entry *pde; + + pde = create_proc_entry("toshiba", 0, NULL); + if (!pde) { + misc_deregister(&tosh_device); + return -ENOMEM; + } + pde->proc_fops = &proc_toshiba_fops; } #endif diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 47a6eacb10b..558ca927e32 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -154,7 +154,7 @@ static int tty_release(struct inode *, struct file *); int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int tty_fasync(int fd, struct file * filp, int on); -static void release_mem(struct tty_struct *tty, int idx); +static void release_tty(struct tty_struct *tty, int idx); /** * alloc_tty_struct - allocate a tty object @@ -1612,7 +1612,6 @@ void start_tty(struct tty_struct *tty) /* If we have a running line discipline it may need kicking */ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); } EXPORT_SYMBOL(start_tty); @@ -2003,7 +2002,7 @@ static int init_dev(struct tty_driver *driver, int idx, /* * All structures have been allocated, so now we install them. - * Failures after this point use release_mem to clean up, so + * Failures after this point use release_tty to clean up, so * there's no need to null out the local pointers. */ if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) { @@ -2024,8 +2023,8 @@ static int init_dev(struct tty_driver *driver, int idx, /* * Structures all installed ... call the ldisc open routines. - * If we fail here just call release_mem to clean up. No need - * to decrement the use counts, as release_mem doesn't care. + * If we fail here just call release_tty to clean up. No need + * to decrement the use counts, as release_tty doesn't care. */ if (tty->ldisc.open) { @@ -2095,17 +2094,17 @@ fail_no_mem: retval = -ENOMEM; goto end_init; - /* call the tty release_mem routine to clean out this slot */ + /* call the tty release_tty routine to clean out this slot */ release_mem_out: if (printk_ratelimit()) printk(KERN_INFO "init_dev: ldisc open failed, " "clearing slot %d\n", idx); - release_mem(tty, idx); + release_tty(tty, idx); goto end_init; } /** - * release_mem - release tty structure memory + * release_one_tty - release tty structure memory * * Releases memory associated with a tty structure, and clears out the * driver table slots. This function is called when a device is no longer @@ -2117,37 +2116,14 @@ release_mem_out: * of ttys that the driver keeps. * FIXME: should we require tty_mutex is held here ?? */ - -static void release_mem(struct tty_struct *tty, int idx) +static void release_one_tty(struct tty_struct *tty, int idx) { - struct tty_struct *o_tty; - struct ktermios *tp; int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; - - if ((o_tty = tty->link) != NULL) { - if (!devpts) - o_tty->driver->ttys[idx] = NULL; - if (o_tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { - tp = o_tty->termios; - if (!devpts) - o_tty->driver->termios[idx] = NULL; - kfree(tp); - - tp = o_tty->termios_locked; - if (!devpts) - o_tty->driver->termios_locked[idx] = NULL; - kfree(tp); - } - o_tty->magic = 0; - o_tty->driver->refcount--; - file_list_lock(); - list_del_init(&o_tty->tty_files); - file_list_unlock(); - free_tty_struct(o_tty); - } + struct ktermios *tp; if (!devpts) tty->driver->ttys[idx] = NULL; + if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { tp = tty->termios; if (!devpts) @@ -2160,15 +2136,39 @@ static void release_mem(struct tty_struct *tty, int idx) kfree(tp); } + tty->magic = 0; tty->driver->refcount--; + file_list_lock(); list_del_init(&tty->tty_files); file_list_unlock(); - module_put(tty->driver->owner); + free_tty_struct(tty); } +/** + * release_tty - release tty structure memory + * + * Release both @tty and a possible linked partner (think pty pair), + * and decrement the refcount of the backing module. + * + * Locking: + * tty_mutex - sometimes only + * takes the file list lock internally when working on the list + * of ttys that the driver keeps. + * FIXME: should we require tty_mutex is held here ?? + */ +static void release_tty(struct tty_struct *tty, int idx) +{ + struct tty_driver *driver = tty->driver; + + if (tty->link) + release_one_tty(tty->link, idx); + release_one_tty(tty, idx); + module_put(driver->owner); +} + /* * Even releasing the tty structures is a tricky business.. We have * to be very careful that the structures are all released at the @@ -2436,10 +2436,10 @@ static void release_dev(struct file * filp) tty_set_termios_ldisc(o_tty,N_TTY); } /* - * The release_mem function takes care of the details of clearing + * The release_tty function takes care of the details of clearing * the slots and preserving the termios structure. */ - release_mem(tty, idx); + release_tty(tty, idx); #ifdef CONFIG_UNIX98_PTYS /* Make this pty number available for reallocation */ @@ -3324,10 +3324,8 @@ int tty_ioctl(struct inode * inode, struct file * file, * Nasty bug: do_SAK is being called in interrupt context. This can * deadlock. We punt it up to process context. AKPM - 16Mar2001 */ -static void __do_SAK(struct work_struct *work) +void __do_SAK(struct tty_struct *tty) { - struct tty_struct *tty = - container_of(work, struct tty_struct, SAK_work); #ifdef TTY_SOFT_SAK tty_hangup(tty); #else @@ -3394,6 +3392,13 @@ static void __do_SAK(struct work_struct *work) #endif } +static void do_SAK_work(struct work_struct *work) +{ + struct tty_struct *tty = + container_of(work, struct tty_struct, SAK_work); + __do_SAK(tty); +} + /* * The tq handling here is a little racy - tty->SAK_work may already be queued. * Fortunately we don't need to worry, because if ->SAK_work is already queued, @@ -3404,7 +3409,7 @@ void do_SAK(struct tty_struct *tty) { if (!tty) return; - PREPARE_WORK(&tty->SAK_work, __do_SAK); + PREPARE_WORK(&tty->SAK_work, do_SAK_work); schedule_work(&tty->SAK_work); } diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index dee47f40c6a..fd471cb3338 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -225,7 +225,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); /** * tty_termios_encode_baud_rate - * @termios: termios structure + * @termios: ktermios structure holding user requested state * @ispeed: input speed * @ospeed: output speed * @@ -233,7 +233,10 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); * used as a library helper for drivers os that they can report back * the actual speed selected when it differs from the speed requested * - * For now input and output speed must agree. + * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour + * we need to carefully set the bits when the user does not get the + * desired speed. We allow small margins and preserve as much of possible + * of the input intent to keep compatiblity. * * Locking: Caller should hold termios lock. This is already held * when calling this function from the driver termios handler. @@ -242,32 +245,44 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) { int i = 0; - int ifound = 0, ofound = 0; + int ifound = -1, ofound = -1; + int iclose = ibaud/50, oclose = obaud/50; + int ibinput = 0; termios->c_ispeed = ibaud; termios->c_ospeed = obaud; + /* If the user asked for a precise weird speed give a precise weird + answer. If they asked for a Bfoo speed they many have problems + digesting non-exact replies so fuzz a bit */ + + if ((termios->c_cflag & CBAUD) == BOTHER) + oclose = 0; + if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER) + iclose = 0; + if ((termios->c_cflag >> IBSHIFT) & CBAUD) + ibinput = 1; /* An input speed was specified */ + termios->c_cflag &= ~CBAUD; - /* Identical speed means no input encoding (ie B0 << IBSHIFT)*/ - if (termios->c_ispeed == termios->c_ospeed) - ifound = 1; do { - if (obaud == baud_table[i]) { + if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { termios->c_cflag |= baud_bits[i]; - ofound = 1; - /* So that if ibaud == obaud we don't set it */ - continue; + ofound = i; } - if (ibaud == baud_table[i]) { - termios->c_cflag |= (baud_bits[i] << IBSHIFT); - ifound = 1; + if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { + /* For the case input == output don't set IBAUD bits if the user didn't do so */ + if (ofound != i || ibinput) + termios->c_cflag |= (baud_bits[i] << IBSHIFT); + ifound = i; } } while(++i < n_baud_table); - if (!ofound) + if (ofound == -1) termios->c_cflag |= BOTHER; - if (!ifound) + /* Set exact input bits only if the input and output differ or the + user already did */ + if (ifound == -1 && (ibaud != obaud || ibinput)) termios->c_cflag |= (BOTHER << IBSHIFT); } diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 06c32a3e3ca..13299b8fdbd 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -136,9 +136,6 @@ const struct consw *conswitchp; #define DEFAULT_BELL_PITCH 750 #define DEFAULT_BELL_DURATION (HZ/8) -extern void vcs_make_sysfs(struct tty_struct *tty); -extern void vcs_remove_sysfs(struct tty_struct *tty); - struct vc vc_cons [MAX_NR_CONSOLES]; #ifndef VT_SINGLE_DRIVER diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index dc8368ebb1a..3a5d301e783 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -672,7 +672,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, vc->vt_mode = tmp; /* the frsig is ignored, so we set it to 0 */ vc->vt_mode.frsig = 0; - put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current)))); + put_pid(vc->vt_pid); + vc->vt_pid = get_pid(task_pid(current)); /* no switch is required -- saw@shade.msu.ru */ vc->vt_newvt = -1; release_console_sem(); @@ -1063,12 +1064,35 @@ void reset_vc(struct vc_data *vc) vc->vt_mode.relsig = 0; vc->vt_mode.acqsig = 0; vc->vt_mode.frsig = 0; - put_pid(xchg(&vc->vt_pid, NULL)); + put_pid(vc->vt_pid); + vc->vt_pid = NULL; vc->vt_newvt = -1; if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */ reset_palette(vc); } +void vc_SAK(struct work_struct *work) +{ + struct vc *vc_con = + container_of(work, struct vc, SAK_work); + struct vc_data *vc; + struct tty_struct *tty; + + acquire_console_sem(); + vc = vc_con->d; + if (vc) { + tty = vc->vc_tty; + /* + * SAK should also work in all raw modes and reset + * them properly. + */ + if (tty) + __do_SAK(tty); + reset_vc(vc); + } + release_console_sem(); +} + /* * Performs the back end of a vt switch */ diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 5c261e1f92b..d8806e4f182 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -233,6 +233,8 @@ edd_show_interface(struct edd_device *edev, char *buf) /** * edd_show_raw_data() - copies raw data to buffer for userspace to parse + * @edev: target edd_device + * @buf: output buffer * * Returns: number of bytes written, or -EINVAL on failure */ @@ -634,8 +636,8 @@ static decl_subsys(edd,&ktype_edd,NULL); /** * edd_dev_is_type() - is this EDD device a 'type' device? - * @edev - * @type - a host bus or interface identifier string per the EDD spec + * @edev: target edd_device + * @type: a host bus or interface identifier string per the EDD spec * * Returns 1 (TRUE) if it is a 'type' device, 0 otherwise. */ @@ -657,7 +659,7 @@ edd_dev_is_type(struct edd_device *edev, const char *type) /** * edd_get_pci_dev() - finds pci_dev that matches edev - * @edev - edd_device + * @edev: edd_device * * Returns pci_dev if found, or NULL */ diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index aa049dab3d9..ad49bd823eb 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -413,7 +413,6 @@ void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void while (p->name != NULL) { ent = create_proc_entry(p->name, p->mode, dir); if (!ent) return; - ent->nlink = 1; ent->data = data; ent->read_proc = p->read_proc; ent->write_proc = p->write_proc; diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 9291a86ca05..6ebfa27e4e1 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -134,14 +134,13 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) return ERR_PTR(-EINVAL); - my_cq = kmem_cache_alloc(cq_cache, GFP_KERNEL); + my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); if (!my_cq) { ehca_err(device, "Out of memory for ehca_cq struct device=%p", device); return ERR_PTR(-ENOMEM); } - memset(my_cq, 0, sizeof(struct ehca_cq)); memset(¶m, 0, sizeof(struct ehca_alloc_cq_parms)); spin_lock_init(&my_cq->spinlock); diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index cfb362a1029..d22ab563633 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -53,9 +53,8 @@ static struct ehca_mr *ehca_mr_new(void) { struct ehca_mr *me; - me = kmem_cache_alloc(mr_cache, GFP_KERNEL); + me = kmem_cache_zalloc(mr_cache, GFP_KERNEL); if (me) { - memset(me, 0, sizeof(struct ehca_mr)); spin_lock_init(&me->mrlock); } else ehca_gen_err("alloc failed"); @@ -72,9 +71,8 @@ static struct ehca_mw *ehca_mw_new(void) { struct ehca_mw *me; - me = kmem_cache_alloc(mw_cache, GFP_KERNEL); + me = kmem_cache_zalloc(mw_cache, GFP_KERNEL); if (me) { - memset(me, 0, sizeof(struct ehca_mw)); spin_lock_init(&me->mwlock); } else ehca_gen_err("alloc failed"); diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index d5345e5b3cd..79d0591a804 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c @@ -50,14 +50,13 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, { struct ehca_pd *pd; - pd = kmem_cache_alloc(pd_cache, GFP_KERNEL); + pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL); if (!pd) { ehca_err(device, "device=%p context=%p out of memory", device, context); return ERR_PTR(-ENOMEM); } - memset(pd, 0, sizeof(struct ehca_pd)); pd->ownpid = current->tgid; /* diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 95efef921f1..df0516f2437 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -450,13 +450,12 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, if (pd->uobject && udata) context = pd->uobject->context; - my_qp = kmem_cache_alloc(qp_cache, GFP_KERNEL); + my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); if (!my_qp) { ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); return ERR_PTR(-ENOMEM); } - memset(my_qp, 0, sizeof(struct ehca_qp)); memset (&parms, 0, sizeof(struct ehca_alloc_qp_parms)); spin_lock_init(&my_qp->spinlock_s); spin_lock_init(&my_qp->spinlock_r); diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index f68dbe6f7f0..7b7a546323c 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c @@ -151,7 +151,6 @@ static int ns558_isa_probe(int io) return -ENOMEM; } - memset(ns558, 0, sizeof(struct ns558)); ns558->io = io; ns558->size = 1 << i; ns558->gameport = port; diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index b5e7f9c7d74..63e51dd6deb 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -257,10 +257,10 @@ static inline void dump_urb(enum debuglevel level, const char *tag, urb->transfer_flags); gig_dbg(level, " transfer_buffer=0x%08lx[%d], actual_length=%d, " - "bandwidth=%d, setup_packet=0x%08lx,", + "setup_packet=0x%08lx,", (unsigned long) urb->transfer_buffer, urb->transfer_buffer_length, urb->actual_length, - urb->bandwidth, (unsigned long) urb->setup_packet); + (unsigned long) urb->setup_packet); gig_dbg(level, " start_frame=%d, number_of_packets=%d, interval=%d, " "error_count=%d,", diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 458b6462f93..f13de20947e 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -599,19 +599,9 @@ out: static void if_wake(unsigned long data) { struct cardstate *cs = (struct cardstate *) data; - struct tty_struct *tty; - - tty = cs->tty; - if (!tty) - return; - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) { - gig_dbg(DEBUG_IF, "write wakeup call"); - tty->ldisc.write_wakeup(tty); - } - wake_up_interruptible(&tty->write_wait); + if (cs->tty) + tty_wakeup(cs->tty); } /*** interface to common ***/ diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index fc80afe555b..ea5f30d4a5a 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1261,7 +1261,6 @@ isdn_tty_flush_buffer(struct tty_struct *tty) } isdn_tty_cleanup_xmit(info); info->xmit_count = 0; - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); } diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 8ca75e52f63..eb6653f69ce 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -516,7 +516,6 @@ static int __init via_pmu_dev_init(void) proc_get_irqstats, NULL); proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root); if (proc_pmu_options) { - proc_pmu_options->nlink = 1; proc_pmu_options->read_proc = proc_read_options; proc_pmu_options->write_proc = proc_write_options; } diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 059704fbb75..5554adaa58f 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -666,7 +666,7 @@ static void bitmap_file_put(struct bitmap *bitmap) if (file) { struct inode *inode = file->f_path.dentry->d_inode; - invalidate_inode_pages(inode->i_mapping); + invalidate_mapping_pages(inode->i_mapping, 0, -1); fput(file); } } diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 862a984c215..e10a9ee25fc 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -562,7 +562,6 @@ jpg_fbuffer_alloc (struct file *file) jpg_fbuffer_free(file); return -ENOBUFS; } - memset((void *) mem, 0, PAGE_SIZE); fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem; fh->jpg_buffers.buffer[i].frag_tab_bus = virt_to_bus((void *) mem); diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index ea9d5f233c8..6a51e99a807 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -72,11 +72,9 @@ static int hdpu_nexus_probe(struct platform_device *pdev) printk("Could not map slot id\n"); hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); hdpu_slot_id->read_proc = hdpu_slot_id_read; - hdpu_slot_id->nlink = 1; hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); hdpu_chassis_id->read_proc = hdpu_chassis_id_read; - hdpu_chassis_id->nlink = 1; return 0; } diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index b995a15b752..6a5a05d1f39 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -309,7 +309,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) ret = -ENODEV; goto out_pci; } - if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs), + if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs), "ioc4_misc")) { printk(KERN_WARNING "%s: Unable to request IOC4 misc region " @@ -379,7 +379,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) return 0; out_misc_region: - release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); + release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); out_pci: kfree(idd); out_idd: @@ -418,7 +418,7 @@ ioc4_remove(struct pci_dev *pdev) "Device removal may be incomplete.\n", __FUNCTION__, pci_name(idd->idd_pdev)); } - release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); + release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); /* Disable IOC4 and relinquish */ pci_disable_device(pdev); diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 4bf1fea5e2c..7522f76b15e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -22,9 +22,6 @@ #include "sdhci.h" #define DRIVER_NAME "sdhci" -#define DRIVER_VERSION "0.12" - -#define BUGMAIL "<sdhci-devel@list.drzeus.cx>" #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) @@ -154,8 +151,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) /* hw clears the bit when it's done */ while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { if (timeout == 0) { - printk(KERN_ERR "%s: Reset 0x%x never completed. " - "Please report this to " BUGMAIL ".\n", + printk(KERN_ERR "%s: Reset 0x%x never completed.\n", mmc_hostname(host->mmc), (int)mask); sdhci_dumpregs(host); return; @@ -474,12 +470,11 @@ static void sdhci_finish_data(struct sdhci_host *host) if ((data->error == MMC_ERR_NONE) && blocks) { printk(KERN_ERR "%s: Controller signalled completion even " - "though there were blocks left. Please report this " - "to " BUGMAIL ".\n", mmc_hostname(host->mmc)); + "though there were blocks left.\n", + mmc_hostname(host->mmc)); data->error = MMC_ERR_FAILED; } else if (host->size != 0) { - printk(KERN_ERR "%s: %d bytes were left untransferred. " - "Please report this to " BUGMAIL ".\n", + printk(KERN_ERR "%s: %d bytes were left untransferred.\n", mmc_hostname(host->mmc), host->size); data->error = MMC_ERR_FAILED; } @@ -526,8 +521,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { if (timeout == 0) { printk(KERN_ERR "%s: Controller never released " - "inhibit bit(s). Please report this to " - BUGMAIL ".\n", mmc_hostname(host->mmc)); + "inhibit bit(s).\n", mmc_hostname(host->mmc)); sdhci_dumpregs(host); cmd->error = MMC_ERR_FAILED; tasklet_schedule(&host->finish_tasklet); @@ -548,8 +542,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) sdhci_set_transfer_mode(host, cmd->data); if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { - printk(KERN_ERR "%s: Unsupported response type! " - "Please report this to " BUGMAIL ".\n", + printk(KERN_ERR "%s: Unsupported response type!\n", mmc_hostname(host->mmc)); cmd->error = MMC_ERR_INVALID; tasklet_schedule(&host->finish_tasklet); @@ -647,9 +640,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL)) & SDHCI_CLOCK_INT_STABLE)) { if (timeout == 0) { - printk(KERN_ERR "%s: Internal clock never stabilised. " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Internal clock never " + "stabilised.\n", mmc_hostname(host->mmc)); sdhci_dumpregs(host); return; } @@ -899,9 +891,8 @@ static void sdhci_timeout_timer(unsigned long data) spin_lock_irqsave(&host->lock, flags); if (host->mrq) { - printk(KERN_ERR "%s: Timeout waiting for hardware interrupt. " - "Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Timeout waiting for hardware " + "interrupt.\n", mmc_hostname(host->mmc)); sdhci_dumpregs(host); if (host->data) { @@ -935,8 +926,6 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) printk(KERN_ERR "%s: Got command interrupt even though no " "command operation was in progress.\n", mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); sdhci_dumpregs(host); return; } @@ -972,8 +961,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) printk(KERN_ERR "%s: Got data interrupt even though no " "data operation was in progress.\n", mmc_hostname(host->mmc)); - printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n", - mmc_hostname(host->mmc)); sdhci_dumpregs(host); return; @@ -1045,8 +1032,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) intmask &= SDHCI_INT_BUS_POWER; if (intmask) { - printk(KERN_ERR "%s: Unexpected interrupt 0x%08x. Please " - "report this to " BUGMAIL ".\n", + printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", mmc_hostname(host->mmc), intmask); sdhci_dumpregs(host); @@ -1528,8 +1514,7 @@ static struct pci_driver sdhci_driver = { static int __init sdhci_drv_init(void) { printk(KERN_INFO DRIVER_NAME - ": Secure Digital Host Controller Interface driver, " - DRIVER_VERSION "\n"); + ": Secure Digital Host Controller Interface driver\n"); printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); return pci_register_driver(&sdhci_driver); @@ -1551,7 +1536,6 @@ module_param(debug_quirks, uint, 0444); MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>"); MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)"); diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index e65f8a0a934..0581d09c58f 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c @@ -36,8 +36,8 @@ module_param(fixed_timeout, bool, 0644); #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ #define TIFM_MMCSD_READ 0x8000 -#define TIFM_MMCSD_DATAMASK 0x001d /* set bits: EOFB, BRS, CB, EOC */ -#define TIFM_MMCSD_ERRMASK 0x41e0 /* set bits: CERR, CCRC, CTO, DCRC, DTO */ +#define TIFM_MMCSD_DATAMASK 0x401d /* set bits: CERR, EOFB, BRS, CB, EOC */ +#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ @@ -242,7 +242,7 @@ change_state: case IDLE: return; case CMD: - if (host_status & TIFM_MMCSD_EOC) { + if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { tifm_sd_fetch_resp(cmd, sock); if (cmd->data) { host->state = BRS; @@ -341,10 +341,7 @@ static void tifm_sd_signal_irq(struct tifm_dev *sock, goto done; if (host_status & TIFM_MMCSD_ERRMASK) { - if (host_status & TIFM_MMCSD_CERR) - error_code = MMC_ERR_FAILED; - else if (host_status - & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) + if (host_status & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) error_code = MMC_ERR_TIMEOUT; else if (host_status & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index a44d8777ab9..05ccfc43168 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -42,7 +42,6 @@ #include "wbsd.h" #define DRIVER_NAME "wbsd" -#define DRIVER_VERSION "1.6" #define DBG(x...) \ pr_debug(DRIVER_NAME ": " x) @@ -344,7 +343,6 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) memcpy(sgbuf, dmabuf, size); else memcpy(sgbuf, dmabuf, sg[i].length); - kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ); dmabuf += sg[i].length; if (size < sg[i].length) @@ -2101,8 +2099,7 @@ static int __init wbsd_drv_init(void) int result; printk(KERN_INFO DRIVER_NAME - ": Winbond W83L51xD SD/MMC card interface driver, " - DRIVER_VERSION "\n"); + ": Winbond W83L51xD SD/MMC card interface driver\n"); printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); #ifdef CONFIG_PNP @@ -2166,7 +2163,6 @@ module_param(dma, int, 0444); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>"); MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); -MODULE_VERSION(DRIVER_VERSION); #ifdef CONFIG_PNP MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)"); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 6d917a4daa9..f9f2ce7806b 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -278,7 +278,8 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) kfree(dev->mtd.name); if (dev->blkdev) { - invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); + invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, + 0, -1); close_bdev_excl(dev->blkdev); } diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c6de566188e..0986f6c843e 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -83,7 +83,7 @@ struct ppp_file { int dead; /* unit/channel has been shut down */ }; -#define PF_TO_X(pf, X) ((X *)((char *)(pf) - offsetof(X, file))) +#define PF_TO_X(pf, X) container_of(pf, X, file) #define PF_TO_PPP(pf) PF_TO_X(pf, struct ppp) #define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel) diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 8dac2ba82bb..9a731c101d1 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -252,7 +252,6 @@ static int __init led_create_procfs(void) proc_pdc_root->owner = THIS_MODULE; ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root); if (!ent) return -1; - ent->nlink = 1; ent->data = (void *)LED_NOLCD; /* LED */ ent->read_proc = led_proc_read; ent->write_proc = led_proc_write; @@ -262,7 +261,6 @@ static int __init led_create_procfs(void) { ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root); if (!ent) return -1; - ent->nlink = 1; ent->data = (void *)LED_HASLCD; /* LCD */ ent->read_proc = led_proc_read; ent->write_proc = led_proc_write; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 3cfb0a3575e..5ea5bc70cb8 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -4,7 +4,7 @@ config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI - depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 + depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64 help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 6b8c4cfd02a..31a633f6554 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -1,4 +1,3 @@ -extern struct bus_type pnp_bus_type; extern spinlock_t pnp_lock; void *pnp_alloc(long size); int pnp_interface_attach_device(struct pnp_dev *dev); diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 95b79685a9d..3c2ab8394e3 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -530,7 +530,6 @@ pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_de dev_id = kzalloc(sizeof (struct pnp_id), GFP_KERNEL); if (!dev_id) return NULL; - memset(dev_id, 0, sizeof(struct pnp_id)); pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id); memcpy(&dev_id->id, id, 7); pnp_add_id(dev_id, dev); diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 7bf7b2c8824..f935c1f71a5 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -326,14 +326,17 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, &rdev->dst_ops); - if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops) - && do_enum) { - rio_set_device_id(port, destid, hopcount, next_destid); - rdev->destid = next_destid++; - if (next_destid == port->host_deviceid) - next_destid++; + if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { + if (do_enum) { + rio_set_device_id(port, destid, hopcount, next_destid); + rdev->destid = next_destid++; + if (next_destid == port->host_deviceid) + next_destid++; + } else + rdev->destid = rio_get_device_id(port, destid, hopcount); } else - rdev->destid = rio_get_device_id(port, destid, hopcount); + /* Switch device has an associated destID */ + rdev->destid = RIO_INVALID_DESTID; /* If a PE has both switch and other functions, show it as a switch */ if (rio_is_switch(rdev)) { @@ -347,7 +350,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, } rswitch->switchid = next_switchid; rswitch->hopcount = hopcount; - rswitch->destid = 0xffff; + rswitch->destid = destid; /* Initialize switch route table */ for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++) rswitch->route_table[rdid] = RIO_INVALID_ROUTE; @@ -422,7 +425,7 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) /** * rio_route_add_entry- Add a route entry to a switch routing table * @mport: Master port to send transaction - * @rdev: Switch device + * @rswitch: Switch device * @table: Routing table ID * @route_destid: Destination ID to be routed * @route_port: Port number to be routed @@ -434,18 +437,18 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL * on failure. */ -static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev, +static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table, u16 route_destid, u8 route_port) { - return rdev->rswitch->add_entry(mport, rdev->rswitch->destid, - rdev->rswitch->hopcount, table, + return rswitch->add_entry(mport, rswitch->destid, + rswitch->hopcount, table, route_destid, route_port); } /** * rio_route_get_entry- Read a route entry in a switch routing table * @mport: Master port to send transaction - * @rdev: Switch device + * @rswitch: Switch device * @table: Routing table ID * @route_destid: Destination ID to be routed * @route_port: Pointer to read port number into @@ -458,11 +461,11 @@ static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev, * on failure. */ static int -rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table, +rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table, u16 route_destid, u8 * route_port) { - return rdev->rswitch->get_entry(mport, rdev->rswitch->destid, - rdev->rswitch->hopcount, table, + return rswitch->get_entry(mport, rswitch->destid, + rswitch->hopcount, table, route_destid, route_port); } @@ -552,6 +555,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, int port_num; int num_ports; int cur_destid; + int sw_destid; + int sw_inport; struct rio_dev *rdev; u16 destid; int tmp; @@ -594,15 +599,17 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, if (rio_is_switch(rdev)) { next_switchid++; + sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount); + rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, + port->host_deviceid, sw_inport); + rdev->rswitch->route_table[port->host_deviceid] = sw_inport; for (destid = 0; destid < next_destid; destid++) { - rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE, - destid, rio_get_swpinfo_inport(port, - RIO_ANY_DESTID, - hopcount)); - rdev->rswitch->route_table[destid] = - rio_get_swpinfo_inport(port, RIO_ANY_DESTID, - hopcount); + if (destid == port->host_deviceid) + continue; + rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, + destid, sw_inport); + rdev->rswitch->route_table[destid] = sw_inport; } num_ports = @@ -610,9 +617,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, pr_debug( "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", rio_name(rdev), rdev->vid, rdev->did, num_ports); + sw_destid = next_destid; for (port_num = 0; port_num < num_ports; port_num++) { - if (rio_get_swpinfo_inport - (port, RIO_ANY_DESTID, hopcount) == port_num) + if (sw_inport == port_num) continue; cur_destid = next_destid; @@ -622,7 +629,7 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, pr_debug( "RIO: scanning device on port %d\n", port_num); - rio_route_add_entry(port, rdev, + rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, RIO_ANY_DESTID, port_num); @@ -633,7 +640,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, if (next_destid > cur_destid) { for (destid = cur_destid; destid < next_destid; destid++) { - rio_route_add_entry(port, rdev, + if (destid == port->host_deviceid) + continue; + rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, destid, port_num); @@ -641,10 +650,18 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, route_table[destid] = port_num; } - rdev->rswitch->destid = cur_destid; } } } + + /* Check for empty switch */ + if (next_destid == sw_destid) { + next_destid++; + if (next_destid == port->host_deviceid) + next_destid++; + } + + rdev->rswitch->destid = sw_destid; } else pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", rio_name(rdev), rdev->vid, rdev->did); @@ -721,7 +738,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, port_num); for (ndestid = 0; ndestid < RIO_ANY_DESTID; ndestid++) { - rio_route_get_entry(port, rdev, + rio_route_get_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, ndestid, &route_port); @@ -798,6 +815,44 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port) } /** + * rio_update_route_tables- Updates route tables in switches + * @port: Master port associated with the RIO network + * + * For each enumerated device, ensure that each switch in a system + * has correct routing entries. Add routes for devices that where + * unknown dirung the first enumeration pass through the switch. + */ +static void rio_update_route_tables(struct rio_mport *port) +{ + struct rio_dev *rdev; + struct rio_switch *rswitch; + u8 sport; + u16 destid; + + list_for_each_entry(rdev, &rio_devices, global_list) { + + destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid; + + list_for_each_entry(rswitch, &rio_switches, node) { + + if (rio_is_switch(rdev) && (rdev->rswitch == rswitch)) + continue; + + if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { + + sport = rio_get_swpinfo_inport(port, + rswitch->destid, rswitch->hopcount); + + if (rswitch->add_entry) { + rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, sport); + rswitch->route_table[destid] = sport; + } + } + } + } +} + +/** * rio_enum_mport- Start enumeration through a master port * @mport: Master port to send transactions * @@ -838,6 +893,7 @@ int rio_enum_mport(struct rio_mport *mport) rc = -EBUSY; goto out; } + rio_update_route_tables(mport); rio_clear_locks(mport); } else { printk(KERN_INFO "RIO: master port %d link inactive\n", @@ -865,8 +921,8 @@ static void rio_build_route_tables(void) if (rio_is_switch(rdev)) for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { if (rio_route_get_entry - (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i, - &sport) < 0) + (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE, + i, &sport) < 0) continue; rdev->rswitch->route_table[i] = sport; } diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 09660e2ab05..4bbca500d3d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1,4 +1,4 @@ -\# +# # RTC class/drivers configuration # @@ -95,6 +95,29 @@ config RTC_INTF_DEV_UIE_EMUL comment "RTC drivers" depends on RTC_CLASS +# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h> +# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a +# global rtc_lock ... it's not yet just another platform_device. + +config RTC_DRV_CMOS + tristate "PC-style 'CMOS' real time clock" + depends on RTC_CLASS && (X86_PC || ALPHA || ARM26 || ARM \ + || M32R || ATARI || POWERPC) + help + Say "yes" here to get direct support for the real time clock + found in every PC or ACPI-based system, and some other boards. + Specifically the original MC146818, compatibles like those in + PC south bridges, the DS12887 or M48T86, some multifunction + or LPC bus chips, and so on. + + Your system will need to define the platform device used by + this driver, otherwise it won't be accessible. This means + you can safely enable this driver if you don't know whether + or not your board has this kind of hardware. + + This driver can also be built as a module. If so, the module + will be called rtc-cmos. + config RTC_DRV_X1205 tristate "Xicor/Intersil X1205" depends on RTC_CLASS && I2C diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index e6beedacc96..92bfe1b3a5f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o +obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c new file mode 100644 index 00000000000..85bf795abdc --- /dev/null +++ b/drivers/rtc/rtc-cmos.c @@ -0,0 +1,725 @@ +/* + * RTC class driver for "CMOS RTC": PCs, ACPI, etc + * + * Copyright (C) 1996 Paul Gortmaker (drivers/char/rtc.c) + * Copyright (C) 2006 David Brownell (convert to new framework) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* + * The original "cmos clock" chip was an MC146818 chip, now obsolete. + * That defined the register interface now provided by all PCs, some + * non-PC systems, and incorporated into ACPI. Modern PC chipsets + * integrate an MC146818 clone in their southbridge, and boards use + * that instead of discrete clones like the DS12887 or M48T86. There + * are also clones that connect using the LPC bus. + * + * That register API is also used directly by various other drivers + * (notably for integrated NVRAM), infrastructure (x86 has code to + * bypass the RTC framework, directly reading the RTC during boot + * and updating minutes/seconds for systems using NTP synch) and + * utilities (like userspace 'hwclock', if no /dev node exists). + * + * So **ALL** calls to CMOS_READ and CMOS_WRITE must be done with + * interrupts disabled, holding the global rtc_lock, to exclude those + * other drivers and utilities on correctly configured systems. + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/mod_devicetable.h> + +/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ +#include <asm-generic/rtc.h> + + +struct cmos_rtc { + struct rtc_device *rtc; + struct device *dev; + int irq; + struct resource *iomem; + + u8 suspend_ctrl; + + /* newer hardware extends the original register set */ + u8 day_alrm; + u8 mon_alrm; + u8 century; +}; + +/* both platform and pnp busses use negative numbers for invalid irqs */ +#define is_valid_irq(n) ((n) >= 0) + +static const char driver_name[] = "rtc_cmos"; + +/*----------------------------------------------------------------*/ + +static int cmos_read_time(struct device *dev, struct rtc_time *t) +{ + /* REVISIT: if the clock has a "century" register, use + * that instead of the heuristic in get_rtc_time(). + * That'll make Y3K compatility (year > 2070) easy! + */ + get_rtc_time(t); + return 0; +} + +static int cmos_set_time(struct device *dev, struct rtc_time *t) +{ + /* REVISIT: set the "century" register if available + * + * NOTE: this ignores the issue whereby updating the seconds + * takes effect exactly 500ms after we write the register. + * (Also queueing and other delays before we get this far.) + */ + return set_rtc_time(t); +} + +static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char rtc_control; + + if (!is_valid_irq(cmos->irq)) + return -EIO; + + /* Basic alarms only support hour, minute, and seconds fields. + * Some also support day and month, for alarms up to a year in + * the future. + */ + t->time.tm_mday = -1; + t->time.tm_mon = -1; + + spin_lock_irq(&rtc_lock); + t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); + t->time.tm_min = CMOS_READ(RTC_MINUTES_ALARM); + t->time.tm_hour = CMOS_READ(RTC_HOURS_ALARM); + + if (cmos->day_alrm) { + t->time.tm_mday = CMOS_READ(cmos->day_alrm); + if (!t->time.tm_mday) + t->time.tm_mday = -1; + + if (cmos->mon_alrm) { + t->time.tm_mon = CMOS_READ(cmos->mon_alrm); + if (!t->time.tm_mon) + t->time.tm_mon = -1; + } + } + + rtc_control = CMOS_READ(RTC_CONTROL); + spin_unlock_irq(&rtc_lock); + + /* REVISIT this assumes PC style usage: always BCD */ + + if (((unsigned)t->time.tm_sec) < 0x60) + t->time.tm_sec = BCD2BIN(t->time.tm_sec); + else + t->time.tm_sec = -1; + if (((unsigned)t->time.tm_min) < 0x60) + t->time.tm_min = BCD2BIN(t->time.tm_min); + else + t->time.tm_min = -1; + if (((unsigned)t->time.tm_hour) < 0x24) + t->time.tm_hour = BCD2BIN(t->time.tm_hour); + else + t->time.tm_hour = -1; + + if (cmos->day_alrm) { + if (((unsigned)t->time.tm_mday) <= 0x31) + t->time.tm_mday = BCD2BIN(t->time.tm_mday); + else + t->time.tm_mday = -1; + if (cmos->mon_alrm) { + if (((unsigned)t->time.tm_mon) <= 0x12) + t->time.tm_mon = BCD2BIN(t->time.tm_mon) - 1; + else + t->time.tm_mon = -1; + } + } + t->time.tm_year = -1; + + t->enabled = !!(rtc_control & RTC_AIE); + t->pending = 0; + + return 0; +} + +static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char mon, mday, hrs, min, sec; + unsigned char rtc_control, rtc_intr; + + if (!is_valid_irq(cmos->irq)) + return -EIO; + + /* REVISIT this assumes PC style usage: always BCD */ + + /* Writing 0xff means "don't care" or "match all". */ + + mon = t->time.tm_mon; + mon = (mon < 12) ? BIN2BCD(mon) : 0xff; + mon++; + + mday = t->time.tm_mday; + mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; + + hrs = t->time.tm_hour; + hrs = (hrs < 24) ? BIN2BCD(hrs) : 0xff; + + min = t->time.tm_min; + min = (min < 60) ? BIN2BCD(min) : 0xff; + + sec = t->time.tm_sec; + sec = (sec < 60) ? BIN2BCD(sec) : 0xff; + + spin_lock_irq(&rtc_lock); + + /* next rtc irq must not be from previous alarm setting */ + rtc_control = CMOS_READ(RTC_CONTROL); + rtc_control &= ~RTC_AIE; + CMOS_WRITE(rtc_control, RTC_CONTROL); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + if (rtc_intr) + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); + + /* update alarm */ + CMOS_WRITE(hrs, RTC_HOURS_ALARM); + CMOS_WRITE(min, RTC_MINUTES_ALARM); + CMOS_WRITE(sec, RTC_SECONDS_ALARM); + + /* the system may support an "enhanced" alarm */ + if (cmos->day_alrm) { + CMOS_WRITE(mday, cmos->day_alrm); + if (cmos->mon_alrm) + CMOS_WRITE(mon, cmos->mon_alrm); + } + + if (t->enabled) { + rtc_control |= RTC_AIE; + CMOS_WRITE(rtc_control, RTC_CONTROL); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + if (rtc_intr) + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); + } + + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int cmos_set_freq(struct device *dev, int freq) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + int f; + unsigned long flags; + + if (!is_valid_irq(cmos->irq)) + return -ENXIO; + + /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ + f = ffs(freq); + if (f != 0) { + if (f-- > 16 || freq != (1 << f)) + return -EINVAL; + f = 16 - f; + } + + spin_lock_irqsave(&rtc_lock, flags); + CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); + spin_unlock_irqrestore(&rtc_lock, flags); + + return 0; +} + +#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) + +static int +cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char rtc_control, rtc_intr; + unsigned long flags; + + switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: + case RTC_UIE_OFF: + case RTC_UIE_ON: + case RTC_PIE_OFF: + case RTC_PIE_ON: + if (!is_valid_irq(cmos->irq)) + return -EINVAL; + break; + default: + return -ENOIOCTLCMD; + } + + spin_lock_irqsave(&rtc_lock, flags); + rtc_control = CMOS_READ(RTC_CONTROL); + switch (cmd) { + case RTC_AIE_OFF: /* alarm off */ + rtc_control &= ~RTC_AIE; + break; + case RTC_AIE_ON: /* alarm on */ + rtc_control |= RTC_AIE; + break; + case RTC_UIE_OFF: /* update off */ + rtc_control &= ~RTC_UIE; + break; + case RTC_UIE_ON: /* update on */ + rtc_control |= RTC_UIE; + break; + case RTC_PIE_OFF: /* periodic off */ + rtc_control &= ~RTC_PIE; + break; + case RTC_PIE_ON: /* periodic on */ + rtc_control |= RTC_PIE; + break; + } + CMOS_WRITE(rtc_control, RTC_CONTROL); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + if (rtc_intr) + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); + spin_unlock_irqrestore(&rtc_lock, flags); + return 0; +} + +#else +#define cmos_rtc_ioctl NULL +#endif + +#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) + +static int cmos_procfs(struct device *dev, struct seq_file *seq) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char rtc_control, valid; + + spin_lock_irq(&rtc_lock); + rtc_control = CMOS_READ(RTC_CONTROL); + valid = CMOS_READ(RTC_VALID); + spin_unlock_irq(&rtc_lock); + + /* NOTE: at least ICH6 reports battery status using a different + * (non-RTC) bit; and SQWE is ignored on many current systems. + */ + return seq_printf(seq, + "periodic_IRQ\t: %s\n" + "update_IRQ\t: %s\n" + // "square_wave\t: %s\n" + // "BCD\t\t: %s\n" + "DST_enable\t: %s\n" + "periodic_freq\t: %d\n" + "batt_status\t: %s\n", + (rtc_control & RTC_PIE) ? "yes" : "no", + (rtc_control & RTC_UIE) ? "yes" : "no", + // (rtc_control & RTC_SQWE) ? "yes" : "no", + // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", + (rtc_control & RTC_DST_EN) ? "yes" : "no", + cmos->rtc->irq_freq, + (valid & RTC_VRT) ? "okay" : "dead"); +} + +#else +#define cmos_procfs NULL +#endif + +static const struct rtc_class_ops cmos_rtc_ops = { + .ioctl = cmos_rtc_ioctl, + .read_time = cmos_read_time, + .set_time = cmos_set_time, + .read_alarm = cmos_read_alarm, + .set_alarm = cmos_set_alarm, + .proc = cmos_procfs, + .irq_set_freq = cmos_set_freq, +}; + +/*----------------------------------------------------------------*/ + +static struct cmos_rtc cmos_rtc; + +static irqreturn_t cmos_interrupt(int irq, void *p) +{ + u8 irqstat; + + spin_lock(&rtc_lock); + irqstat = CMOS_READ(RTC_INTR_FLAGS); + spin_unlock(&rtc_lock); + + if (irqstat) { + /* NOTE: irqstat may have e.g. RTC_PF set + * even when RTC_PIE is clear... + */ + rtc_update_irq(p, 1, irqstat); + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + +#ifdef CONFIG_PNPACPI +#define is_pnpacpi() 1 +#define INITSECTION + +#else +#define is_pnpacpi() 0 +#define INITSECTION __init +#endif + +static int INITSECTION +cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) +{ + struct cmos_rtc_board_info *info = dev->platform_data; + int retval = 0; + unsigned char rtc_control; + + /* there can be only one ... */ + if (cmos_rtc.dev) + return -EBUSY; + + if (!ports) + return -ENODEV; + + cmos_rtc.irq = rtc_irq; + cmos_rtc.iomem = ports; + + /* For ACPI systems the info comes from the FADT. On others, + * board specific setup provides it as appropriate. + */ + if (info) { + cmos_rtc.day_alrm = info->rtc_day_alarm; + cmos_rtc.mon_alrm = info->rtc_mon_alarm; + cmos_rtc.century = info->rtc_century; + } + + cmos_rtc.rtc = rtc_device_register(driver_name, dev, + &cmos_rtc_ops, THIS_MODULE); + if (IS_ERR(cmos_rtc.rtc)) + return PTR_ERR(cmos_rtc.rtc); + + cmos_rtc.dev = dev; + dev_set_drvdata(dev, &cmos_rtc); + + /* platform and pnp busses handle resources incompatibly. + * + * REVISIT for non-x86 systems we may need to handle io memory + * resources: ioremap them, and request_mem_region(). + */ + if (is_pnpacpi()) { + retval = request_resource(&ioport_resource, ports); + if (retval < 0) { + dev_dbg(dev, "i/o registers already in use\n"); + goto cleanup0; + } + } + rename_region(ports, cmos_rtc.rtc->class_dev.class_id); + + spin_lock_irq(&rtc_lock); + + /* force periodic irq to CMOS reset default of 1024Hz; + * + * REVISIT it's been reported that at least one x86_64 ALI mobo + * doesn't use 32KHz here ... for portability we might need to + * do something about other clock frequencies. + */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); + cmos_rtc.rtc->irq_freq = 1024; + + /* disable irqs. + * + * NOTE after changing RTC_xIE bits we always read INTR_FLAGS; + * allegedly some older rtcs need that to handle irqs properly + */ + rtc_control = CMOS_READ(RTC_CONTROL); + rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE); + CMOS_WRITE(rtc_control, RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + + spin_unlock_irq(&rtc_lock); + + /* FIXME teach the alarm code how to handle binary mode; + * <asm-generic/rtc.h> doesn't know 12-hour mode either. + */ + if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY))) { + dev_dbg(dev, "only 24-hr BCD mode supported\n"); + retval = -ENXIO; + goto cleanup1; + } + + if (is_valid_irq(rtc_irq)) + retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, + cmos_rtc.rtc->class_dev.class_id, + &cmos_rtc.rtc->class_dev); + if (retval < 0) { + dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); + goto cleanup1; + } + + /* REVISIT optionally make 50 or 114 bytes NVRAM available, + * like rtc-ds1553, rtc-ds1742 ... this will often include + * registers for century, and day/month alarm. + */ + + pr_info("%s: alarms up to one %s%s\n", + cmos_rtc.rtc->class_dev.class_id, + is_valid_irq(rtc_irq) + ? (cmos_rtc.mon_alrm + ? "year" + : (cmos_rtc.day_alrm + ? "month" : "day")) + : "no", + cmos_rtc.century ? ", y3k" : "" + ); + + return 0; + +cleanup1: + rename_region(ports, NULL); +cleanup0: + rtc_device_unregister(cmos_rtc.rtc); + return retval; +} + +static void cmos_do_shutdown(void) +{ + unsigned char rtc_control; + + spin_lock_irq(&rtc_lock); + rtc_control = CMOS_READ(RTC_CONTROL); + rtc_control &= ~(RTC_PIE|RTC_AIE|RTC_UIE); + CMOS_WRITE(rtc_control, RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + spin_unlock_irq(&rtc_lock); +} + +static void __exit cmos_do_remove(struct device *dev) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + + cmos_do_shutdown(); + + if (is_pnpacpi()) + release_resource(cmos->iomem); + rename_region(cmos->iomem, NULL); + + if (is_valid_irq(cmos->irq)) + free_irq(cmos->irq, &cmos_rtc.rtc->class_dev); + + rtc_device_unregister(cmos_rtc.rtc); + + cmos_rtc.dev = NULL; + dev_set_drvdata(dev, NULL); +} + +#ifdef CONFIG_PM + +static int cmos_suspend(struct device *dev, pm_message_t mesg) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + int do_wake = device_may_wakeup(dev); + unsigned char tmp, irqstat; + + /* only the alarm might be a wakeup event source */ + spin_lock_irq(&rtc_lock); + cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); + if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { + if (do_wake) + tmp &= ~(RTC_PIE|RTC_UIE); + else + tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE); + CMOS_WRITE(tmp, RTC_CONTROL); + irqstat = CMOS_READ(RTC_INTR_FLAGS); + } else + irqstat = 0; + spin_unlock_irq(&rtc_lock); + + if (irqstat) + rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat); + + /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE) + * ... it'd be best if we could do that under rtc_lock. + */ + + pr_debug("%s: suspend%s, ctrl %02x\n", + cmos_rtc.rtc->class_dev.class_id, + (tmp & RTC_AIE) ? ", alarm may wake" : "", + tmp); + + return 0; +} + +static int cmos_resume(struct device *dev) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char tmp = cmos->suspend_ctrl; + + /* REVISIT: a mechanism to resync the system clock (jiffies) + * on resume should be portable between platforms ... + */ + + /* re-enable any irqs previously active */ + if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { + + /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */ + + spin_lock_irq(&rtc_lock); + CMOS_WRITE(tmp, RTC_CONTROL); + tmp = CMOS_READ(RTC_INTR_FLAGS); + spin_unlock_irq(&rtc_lock); + if (tmp) + rtc_update_irq(&cmos->rtc->class_dev, 1, tmp); + } + + pr_debug("%s: resume, ctrl %02x\n", + cmos_rtc.rtc->class_dev.class_id, + cmos->suspend_ctrl); + + + return 0; +} + +#else +#define cmos_suspend NULL +#define cmos_resume NULL +#endif + +/*----------------------------------------------------------------*/ + +/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, + * the device node may alternatively be created as a PNP device. + */ + +#ifdef CONFIG_PNPACPI + +#include <linux/pnp.h> + +static int __devinit +cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) +{ + /* REVISIT paranoia argues for a shutdown notifier, since PNP + * drivers can't provide shutdown() methods to disable IRQs. + * Or better yet, fix PNP to allow those methods... + */ + return cmos_do_probe(&pnp->dev, + &pnp->res.port_resource[0], + pnp->res.irq_resource[0].start); +} + +static void __exit cmos_pnp_remove(struct pnp_dev *pnp) +{ + cmos_do_remove(&pnp->dev); +} + +#ifdef CONFIG_PM + +static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) +{ + return cmos_suspend(&pnp->dev, mesg); +} + +static int cmos_pnp_resume(struct pnp_dev *pnp) +{ + return cmos_resume(&pnp->dev); +} + +#else +#define cmos_pnp_suspend NULL +#define cmos_pnp_resume NULL +#endif + + +static const struct pnp_device_id rtc_ids[] = { + { .id = "PNP0b00", }, + { .id = "PNP0b01", }, + { .id = "PNP0b02", }, + { }, +}; +MODULE_DEVICE_TABLE(pnp, rtc_ids); + +static struct pnp_driver cmos_pnp_driver = { + .name = (char *) driver_name, + .id_table = rtc_ids, + .probe = cmos_pnp_probe, + .remove = __exit_p(cmos_pnp_remove), + + /* flag ensures resume() gets called, and stops syslog spam */ + .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, + .suspend = cmos_pnp_suspend, + .resume = cmos_pnp_resume, +}; + +static int __init cmos_init(void) +{ + return pnp_register_driver(&cmos_pnp_driver); +} +module_init(cmos_init); + +static void __exit cmos_exit(void) +{ + pnp_unregister_driver(&cmos_pnp_driver); +} +module_exit(cmos_exit); + +#else /* no PNPACPI */ + +/*----------------------------------------------------------------*/ + +/* Platform setup should have set up an RTC device, when PNPACPI is + * unavailable ... this is the normal case, common even on PCs. + */ + +static int __init cmos_platform_probe(struct platform_device *pdev) +{ + return cmos_do_probe(&pdev->dev, + platform_get_resource(pdev, IORESOURCE_IO, 0), + platform_get_irq(pdev, 0)); +} + +static int __exit cmos_platform_remove(struct platform_device *pdev) +{ + cmos_do_remove(&pdev->dev); + return 0; +} + +static void cmos_platform_shutdown(struct platform_device *pdev) +{ + cmos_do_shutdown(); +} + +static struct platform_driver cmos_platform_driver = { + .remove = __exit_p(cmos_platform_remove), + .shutdown = cmos_platform_shutdown, + .driver = { + .name = (char *) driver_name, + .suspend = cmos_suspend, + .resume = cmos_resume, + } +}; + +static int __init cmos_init(void) +{ + return platform_driver_probe(&cmos_platform_driver, + cmos_platform_probe); +} +module_init(cmos_init); + +static void __exit cmos_exit(void) +{ + platform_driver_unregister(&cmos_platform_driver); +} +module_exit(cmos_exit); + + +#endif /* !PNPACPI */ + +MODULE_AUTHOR("David Brownell"); +MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); +MODULE_LICENSE("GPL"); diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index b9e59bc9435..2c785148d21 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -1063,7 +1063,6 @@ int __init zcrypt_api_init(void) rc = -ENOMEM; goto out_misc; } - zcrypt_entry->nlink = 1; zcrypt_entry->data = NULL; zcrypt_entry->read_proc = zcrypt_status_read; zcrypt_entry->write_proc = zcrypt_status_write; diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index b97dd15bdb9..ecca1046714 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1511,8 +1511,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) LCS_DBF_TEXT(5, trace, "txbuffcb"); /* Put buffer back to pool. */ lcs_release_buffer(channel, buffer); - card = (struct lcs_card *) - ((char *) channel - offsetof(struct lcs_card, write)); + card = container_of(channel, struct lcs_card, write); if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev)) netif_wake_queue(card->dev); spin_lock(&card->lock); @@ -1810,8 +1809,7 @@ lcs_get_frames_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) LCS_DBF_TEXT(4, trace, "-eiogpkt"); return; } - card = (struct lcs_card *) - ((char *) channel - offsetof(struct lcs_card, read)); + card = container_of(channel, struct lcs_card, read); offset = 0; while (lcs_hdr->offset != 0) { if (lcs_hdr->offset <= 0 || diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index 98fcbb3d556..6349dd617f8 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/pci.h> +#include <linux/device.h> #include <asm/system.h> #include <asm/sbus.h> @@ -17,13 +18,25 @@ #include <asm/bpp.h> #include <asm/irq.h> +static ssize_t +show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) +{ + struct sbus_dev *sbus; + + sbus = to_sbus_device(dev); + + return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name); +} + +static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL); + struct sbus_bus *sbus_root; static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) { unsigned long base; void *pval; - int len; + int len, err; sdev->prom_node = dp->node; strcpy(sdev->prom_name, dp->name); @@ -66,6 +79,9 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde if (of_device_register(&sdev->ofdev) != 0) printk(KERN_DEBUG "sbus: device registration error for %s!\n", dp->path_component_name); + + /* WE HAVE BEEN INVADED BY ALIENS! */ + err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr); } static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index b432fd20dad..93b41f45638 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -3099,7 +3099,6 @@ allocate_cmd (Scsi_Cmnd *cmd) { real = get_zeroed_page(GFP_ATOMIC); if (real == 0) return NULL; - memset((void *)real, 0, 4096); cache_push(virt_to_phys((void *)real), 4096); cache_clear(virt_to_phys((void *)real), 4096); kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER); diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index da94e126ca8..0cd7eed9196 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -1052,10 +1052,9 @@ static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb; unsigned long flags; - ascb = kmem_cache_alloc(asd_ascb_cache, gfp_flags); + ascb = kmem_cache_zalloc(asd_ascb_cache, gfp_flags); if (ascb) { - memset(ascb, 0, sizeof(*ascb)); ascb->dma_scb.size = sizeof(struct scb); ascb->dma_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool, gfp_flags, diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0f9b6c27541..9f7482d0b59 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -388,10 +388,9 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, int err = 0; int write = (data_direction == DMA_TO_DEVICE); - sioc = kmem_cache_alloc(scsi_io_context_cache, gfp); + sioc = kmem_cache_zalloc(scsi_io_context_cache, gfp); if (!sioc) return DRIVER_ERROR << 24; - memset(sioc, 0, sizeof(*sioc)); req = blk_get_request(sdev->request_queue, write, gfp); if (!req) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 5261f0af8b1..2964ca9df5a 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -920,12 +920,16 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) #ifdef __i386__ outb(0xff, 0x080); #endif - scratch2 = serial_inp(up, UART_IER); + /* + * Mask out IER[7:4] bits for test as some UARTs (e.g. TL + * 16C754B) allow only to modify them if an EFR bit is set. + */ + scratch2 = serial_inp(up, UART_IER) & 0x0f; serial_outp(up, UART_IER, 0x0F); #ifdef __i386__ outb(0, 0x080); #endif - scratch3 = serial_inp(up, UART_IER); + scratch3 = serial_inp(up, UART_IER) & 0x0f; serial_outp(up, UART_IER, scratch); if (scratch2 != 0 || scratch3 != 0x0F) { /* diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 52e2e64c664..a2dac378bda 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -679,6 +679,13 @@ static struct pci_serial_quirk pci_serial_quirks[] = { */ { .vendor = PCI_VENDOR_ID_PLX, + .device = PCI_DEVICE_ID_PLX_9030, + .subvendor = PCI_SUBVENDOR_ID_PERLE, + .subdevice = PCI_ANY_ID, + .setup = pci_default_setup, + }, + { + .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050, .subvendor = PCI_SUBVENDOR_ID_EXSYS, .subdevice = PCI_SUBDEVICE_ID_EXSYS_4055, @@ -936,6 +943,7 @@ enum pci_board_num_t { pbn_b2_1_115200, pbn_b2_2_115200, + pbn_b2_4_115200, pbn_b2_8_115200, pbn_b2_1_460800, @@ -1249,6 +1257,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 115200, .uart_offset = 8, }, + [pbn_b2_4_115200] = { + .flags = FL_BASE2, + .num_ports = 4, + .base_baud = 115200, + .uart_offset = 8, + }, [pbn_b2_8_115200] = { .flags = FL_BASE2, .num_ports = 8, @@ -1990,6 +2004,10 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_panacom2 }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, + PCI_VENDOR_ID_ESDGMBH, + PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0, + pbn_b2_4_115200 }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_CHASE_PCIFAST, PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0, @@ -2379,6 +2397,15 @@ static struct pci_device_id serial_pci_tbl[] = { pbn_b2_2_115200 }, /* + * Perle PCI-RAS cards + */ + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, + PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4, + 0, 0, pbn_b2_4_921600 }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, + PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, + 0, 0, pbn_b2_8_921600 }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL */ diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2978c09860e..5cc6b91f840 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -916,6 +916,11 @@ config SERIAL_TXX9 config HAS_TXX9_SERIAL bool +config SERIAL_TXX9_NR_UARTS + int "Maximum number of TMPTX39XX/49XX SIO ports" + depends on SERIAL_TXX9 + default "6" + config SERIAL_TXX9_CONSOLE bool "TMPTX39XX/49XX SIO Console support" depends on SERIAL_TXX9=y diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 42b050c46ab..312bef6bd58 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c @@ -3173,12 +3173,8 @@ do_softint(void *private_) if (!tty) return; - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) + tty_wakeup(tty); } static int @@ -3798,11 +3794,7 @@ rs_flush_buffer(struct tty_struct *tty) info->xmit.head = info->xmit.tail = 0; restore_flags(flags); - wake_up_interruptible(&tty->write_wait); - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); + tty_wakeup(tty); } /* diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index c862f67c985..f540212e740 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -2685,7 +2685,7 @@ static int ioc4_serial_remove_one(struct ioc4_driver_data *idd) free_irq(control->ic_irq, soft); if (soft->is_ioc4_serial_addr) { iounmap(soft->is_ioc4_serial_addr); - release_region((unsigned long) + release_mem_region((unsigned long) soft->is_ioc4_serial_addr, sizeof(struct ioc4_serial)); } @@ -2790,7 +2790,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) /* request serial registers */ tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET; - if (!request_region(tmp_addr1, sizeof(struct ioc4_serial), + if (!request_mem_region(tmp_addr1, sizeof(struct ioc4_serial), "sioc4_uart")) { printk(KERN_WARNING "ioc4 (%p): unable to get request region for " @@ -2889,7 +2889,7 @@ out3: out2: if (serial) iounmap(serial); - release_region(tmp_addr1, sizeof(struct ioc4_serial)); + release_mem_region(tmp_addr1, sizeof(struct ioc4_serial)); out1: return ret; diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 7186a82c475..f4440d32931 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -37,6 +37,7 @@ * 1.06 Do not insert a char caused previous overrun. * Fix some spin_locks. * Do not call uart_add_one_port for absent ports. + * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -58,9 +59,8 @@ #include <linux/mutex.h> #include <asm/io.h> -#include <asm/irq.h> -static char *serial_version = "1.06"; +static char *serial_version = "1.07"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -88,12 +88,7 @@ static char *serial_name = "TX39/49 Serial driver"; /* * Number of serial ports */ -#ifdef ENABLE_SERIAL_TXX9_PCI -#define NR_PCI_BOARDS 4 -#define UART_NR (4 + NR_PCI_BOARDS) -#else -#define UART_NR 4 -#endif +#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) @@ -987,6 +982,7 @@ int __init early_serial_txx9_setup(struct uart_port *port) } #ifdef ENABLE_SERIAL_TXX9_PCI +#ifdef CONFIG_PM /** * serial_txx9_suspend_port - suspend one serial port * @line: serial line number @@ -1008,6 +1004,7 @@ static void serial_txx9_resume_port(int line) { uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); } +#endif static DEFINE_MUTEX(serial_txx9_mutex); @@ -1118,6 +1115,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev) } } +#ifdef CONFIG_PM static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state) { int line = (int)(long)pci_get_drvdata(dev); @@ -1142,11 +1140,10 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev) } return 0; } +#endif -static struct pci_device_id serial_txx9_pci_tbl[] = { - { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, 0 }, +static const struct pci_device_id serial_txx9_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC) }, { 0, } }; @@ -1154,8 +1151,10 @@ static struct pci_driver serial_txx9_pci_driver = { .name = "serial_txx9", .probe = pciserial_txx9_init_one, .remove = __devexit_p(pciserial_txx9_remove_one), +#ifdef CONFIG_PM .suspend = pciserial_txx9_suspend_one, .resume = pciserial_txx9_resume_one, +#endif .id_table = serial_txx9_pci_tbl, }; diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index cd6b65333b7..2dd6eed50aa 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -654,7 +654,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) ret = -ENODEV; goto out_pci; } - if (!request_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) { + if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) { printk(KERN_WARNING "%s: Unable to request IOC3 region " "for pci_dev %s.\n", @@ -744,7 +744,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) return 0; out_misc_region: - release_region(idd->pma, IOC3_PCI_SIZE); + release_mem_region(idd->pma, IOC3_PCI_SIZE); out_pci: kfree(idd); out_idd: @@ -785,7 +785,7 @@ static void ioc3_remove(struct pci_dev *pdev) if(idd->dual_irq) free_irq(idd->irq_eth, (void *)idd); iounmap(idd->vma); - release_region(idd->pma, IOC3_PCI_SIZE); + release_mem_region(idd->pma, IOC3_PCI_SIZE); /* Disable IOC3 and relinquish */ pci_disable_device(pdev); diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index fc319727366..3d72aa5cfc7 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -626,10 +626,8 @@ static void do_softint(unsigned long private_) if (!tty) return; - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } } static int zs_startup(struct dec_serial * info) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index f04a29a4664..c6b6479fa4d 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1953,7 +1953,7 @@ static void invalidate_sub(struct lun *curlun) struct inode *inode = filp->f_path.dentry->d_inode; unsigned long rc; - rc = invalidate_inode_pages(inode->i_mapping); + rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc); } diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 408c3380d60..6ec8cf1a3cc 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1419,7 +1419,6 @@ int __devinit rndis_init (void) return -EIO; } - rndis_connect_state [i]->nlink = 1; rndis_connect_state [i]->write_proc = rndis_proc_write; rndis_connect_state [i]->read_proc = rndis_proc_read; rndis_connect_state [i]->data = (void *) diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index 282d82efc0b..f0ffb8907f2 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c @@ -2163,9 +2163,8 @@ static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid) maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); + sb_desc = kmem_cache_zalloc(usb_desc_cache, SLAB_FLAG); assert(sb_desc != NULL); - memset(sb_desc, 0, sizeof(USB_SB_Desc_t)); if (usb_pipeout(urb->pipe)) { diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 2cbb239e63f..68e66b33e72 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -624,12 +624,10 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, { struct urb_priv *urbp; - urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC); + urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_ATOMIC); if (!urbp) return NULL; - memset((void *)urbp, 0, sizeof(*urbp)); - urbp->urb = urb; urb->hcpriv = urbp; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 0b0fb51bad3..d78692c01cf 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -616,15 +616,7 @@ static void digi_wakeup_write_lock(struct work_struct *work) static void digi_wakeup_write( struct usb_serial_port *port ) { - - struct tty_struct *tty = port->tty; - - - /* wake up port processes */ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ - tty_wakeup(tty); + tty_wakeup(port->tty); } diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index da514cb785b..dd0b66a6ed5 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -182,13 +182,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) struct keyspan_pda_private *priv = container_of(work, struct keyspan_pda_private, wakeup_work); struct usb_serial_port *port = priv->port; - struct tty_struct *tty = port->tty; - /* wake up port processes */ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ - tty_wakeup(tty); + tty_wakeup(port->tty); } static void keyspan_pda_request_unthrottle(struct work_struct *work) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 6109c6704a7..2d588fb8257 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -269,18 +269,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) tty = mos7720_port->port->tty; - if (tty && mos7720_port->open) { - /* let the tty driver wakeup if it has a special * - * write_wakeup function */ - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - - /* tell the tty driver that something has changed */ - wake_up_interruptible(&tty->write_wait); - } - - /* schedule_work(&mos7720_port->port->work); */ + if (tty && mos7720_port->open) + tty_wakeup(tty); } /* diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index b2264a87617..c6cca859af4 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -755,18 +755,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) tty = mos7840_port->port->tty; - if (tty && mos7840_port->open) { - /* let the tty driver wakeup if it has a special * - * write_wakeup function */ - - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) - && tty->ldisc.write_wakeup) { - (tty->ldisc.write_wakeup) (tty); - } - - /* tell the tty driver that something has changed */ - wake_up_interruptible(&tty->write_wait); - } + if (tty && mos7840_port->open) + tty_wakeup(tty); } diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h index 0b07f6ae336..48066ef3af0 100644 --- a/drivers/video/sa1100fb.h +++ b/drivers/video/sa1100fb.h @@ -110,9 +110,7 @@ struct sa1100fb_info { #endif }; -#define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member))) - -#define TO_INF(ptr,member) __type_entry(ptr,struct sa1100fb_info,member) +#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member) #define SA1100_PALETTE_MODE_VAL(bpp) (((bpp) & 0x018) << 9) |