aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/accessibility/Kconfig23
-rw-r--r--drivers/accessibility/Makefile1
-rw-r--r--drivers/accessibility/braille/Makefile1
-rw-r--r--drivers/accessibility/braille/braille_console.c397
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/block/brd.c19
-rw-r--r--drivers/bluetooth/hci_ldisc.c13
-rw-r--r--drivers/char/agp/agp.h2
-rw-r--r--drivers/char/amiserial.c30
-rw-r--r--drivers/char/applicom.c4
-rw-r--r--drivers/char/consolemap.c1
-rw-r--r--drivers/char/cyclades.c432
-rw-r--r--drivers/char/drm/drmP.h8
-rw-r--r--drivers/char/drm/drm_sysfs.c2
-rw-r--r--drivers/char/drm/i830_dma.c18
-rw-r--r--drivers/char/drm/i830_drv.h2
-rw-r--r--drivers/char/drm/i830_irq.c8
-rw-r--r--drivers/char/drm/i915_dma.c4
-rw-r--r--drivers/char/drm/i915_drv.h2
-rw-r--r--drivers/char/drm/radeon_cp.c2
-rw-r--r--drivers/char/ds1286.c3
-rw-r--r--drivers/char/epca.c315
-rw-r--r--drivers/char/esp.c611
-rw-r--r--drivers/char/generic_serial.c18
-rw-r--r--drivers/char/hpet.c10
-rw-r--r--drivers/char/hvsi.c52
-rw-r--r--drivers/char/ip2/i2ellis.c194
-rw-r--r--drivers/char/ip2/i2ellis.h58
-rw-r--r--drivers/char/ip2/i2hw.h6
-rw-r--r--drivers/char/ip2/i2lib.c141
-rw-r--r--drivers/char/ip2/i2os.h127
-rw-r--r--drivers/char/ip2/ip2main.c89
-rw-r--r--drivers/char/isicom.c171
-rw-r--r--drivers/char/istallion.c22
-rw-r--r--drivers/char/keyboard.c4
-rw-r--r--drivers/char/mmtimer.c400
-rw-r--r--drivers/char/moxa.c2999
-rw-r--r--drivers/char/moxa.h304
-rw-r--r--drivers/char/mxser.c346
-rw-r--r--drivers/char/mxser.h137
-rw-r--r--drivers/char/n_hdlc.c35
-rw-r--r--drivers/char/n_r3964.c33
-rw-r--r--drivers/char/n_tty.c160
-rw-r--r--drivers/char/nozomi.c17
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c23
-rw-r--r--drivers/char/pty.c32
-rw-r--r--drivers/char/rio/cirrus.h210
-rw-r--r--drivers/char/rio/rio_linux.c10
-rw-r--r--drivers/char/rio/rio_linux.h6
-rw-r--r--drivers/char/rio/riocmd.c19
-rw-r--r--drivers/char/rio/rioctrl.c37
-rw-r--r--drivers/char/rio/riointr.c5
-rw-r--r--drivers/char/rio/rioparam.c70
-rw-r--r--drivers/char/rio/riotty.c25
-rw-r--r--drivers/char/riscom8.c706
-rw-r--r--drivers/char/rocket.c43
-rw-r--r--drivers/char/serial167.c25
-rw-r--r--drivers/char/snsc.c18
-rw-r--r--drivers/char/snsc_event.c6
-rw-r--r--drivers/char/sonypi.c2
-rw-r--r--drivers/char/specialix.c111
-rw-r--r--drivers/char/stallion.c17
-rw-r--r--drivers/char/sx.c35
-rw-r--r--drivers/char/synclink.c31
-rw-r--r--drivers/char/synclink_gt.c80
-rw-r--r--drivers/char/synclinkmp.c41
-rw-r--r--drivers/char/tty_io.c372
-rw-r--r--drivers/char/tty_ioctl.c126
-rw-r--r--drivers/char/viocons.c12
-rw-r--r--drivers/char/vt.c21
-rw-r--r--drivers/char/vt_ioctl.c452
-rw-r--r--drivers/gpio/gpiolib.c4
-rw-r--r--drivers/hwmon/ads7828.c2
-rw-r--r--drivers/input/serio/serport.c2
-rw-r--r--drivers/isdn/capi/capi.c9
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c15
-rw-r--r--drivers/isdn/i4l/isdn_tty.c30
-rw-r--r--drivers/md/md.c112
-rw-r--r--drivers/md/raid1.c27
-rw-r--r--drivers/md/raid10.c29
-rw-r--r--drivers/md/raid5.c33
-rw-r--r--drivers/media/common/Makefile1
-rw-r--r--drivers/media/video/bt8xx/bttvp.h2
-rw-r--r--drivers/media/video/usbvideo/vicam.c6
-rw-r--r--drivers/mfd/asic3.c6
-rw-r--r--drivers/mfd/sm501.c4
-rw-r--r--drivers/net/fec_mpc52xx.c23
-rw-r--r--drivers/net/hamradio/6pack.c36
-rw-r--r--drivers/net/hamradio/mkiss.c15
-rw-r--r--drivers/net/irda/irtty-sir.c95
-rw-r--r--drivers/net/ppp_async.c9
-rw-r--r--drivers/net/ppp_synctty.c9
-rw-r--r--drivers/net/slip.c13
-rw-r--r--drivers/net/wan/pc300_tty.c24
-rw-r--r--drivers/net/wan/x25_asy.c279
-rw-r--r--drivers/net/wireless/strip.c66
-rw-r--r--drivers/parport/ieee1284.c4
-rw-r--r--drivers/parport/parport_gsc.c4
-rw-r--r--drivers/parport/parport_pc.c8
-rw-r--r--drivers/s390/char/con3215.c5
-rw-r--r--drivers/s390/char/sclp_tty.c4
-rw-r--r--drivers/s390/char/sclp_vt220.c6
-rw-r--r--drivers/s390/char/tty3270.c3
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/uctrl.c4
-rw-r--r--drivers/serial/68328serial.c21
-rw-r--r--drivers/serial/68360serial.c28
-rw-r--r--drivers/serial/8250_early.c2
-rw-r--r--drivers/serial/Kconfig43
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/bfin_5xx.c4
-rw-r--r--drivers/serial/bfin_sport_uart.c614
-rw-r--r--drivers/serial/bfin_sport_uart.h63
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/crisv10.c31
-rw-r--r--drivers/serial/ioc3_serial.c36
-rw-r--r--drivers/serial/ioc4_serial.c32
-rw-r--r--drivers/serial/kgdboc.c6
-rw-r--r--drivers/serial/mcfserial.c22
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/netx-serial.c1
-rw-r--r--drivers/serial/s3c2410.c6
-rw-r--r--drivers/serial/sa1100.c4
-rw-r--r--drivers/serial/serial_core.c54
-rw-r--r--drivers/serial/sh-sci.c2
-rw-r--r--drivers/serial/sn_console.c2
-rw-r--r--drivers/serial/uartlite.c2
-rw-r--r--drivers/serial/ucc_uart.c4
-rw-r--r--drivers/spi/atmel_spi.c29
-rw-r--r--drivers/usb/gadget/serial.c10
-rw-r--r--drivers/usb/serial/digi_acceleport.c3
-rw-r--r--drivers/usb/serial/usb-serial.c129
-rw-r--r--drivers/usb/serial/whiteheat.c4
-rw-r--r--drivers/video/Kconfig5
-rw-r--r--drivers/video/pxafb.c1297
-rw-r--r--drivers/video/pxafb.h70
-rw-r--r--drivers/w1/w1_log.h2
141 files changed, 7258 insertions, 5929 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 80f0ec91e2c..59f33fa6af3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,6 +84,8 @@ source "drivers/memstick/Kconfig"
source "drivers/leds/Kconfig"
+source "drivers/accessibility/Kconfig"
+
source "drivers/infiniband/Kconfig"
source "drivers/edac/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index e5e394a7e6c..f65deda72d6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/
+obj-$(CONFIG_ACCESSIBILITY) += accessibility/
obj-$(CONFIG_ISDN) += isdn/
obj-$(CONFIG_EDAC) += edac/
obj-$(CONFIG_MCA) += mca/
diff --git a/drivers/accessibility/Kconfig b/drivers/accessibility/Kconfig
new file mode 100644
index 00000000000..1264c4b9809
--- /dev/null
+++ b/drivers/accessibility/Kconfig
@@ -0,0 +1,23 @@
+menuconfig ACCESSIBILITY
+ bool "Accessibility support"
+ ---help---
+ Enable a submenu where accessibility items may be enabled.
+
+ If unsure, say N.
+
+if ACCESSIBILITY
+config A11Y_BRAILLE_CONSOLE
+ bool "Console on braille device"
+ depends on VT
+ depends on SERIAL_CORE_CONSOLE
+ ---help---
+ Enables console output on a braille device connected to a 8250
+ serial port. For now only the VisioBraille device is supported.
+
+ To actually enable it, you need to pass option
+ console=brl,ttyS0
+ to the kernel. Options are the same as for serial console.
+
+ If unsure, say N.
+
+endif # ACCESSIBILITY
diff --git a/drivers/accessibility/Makefile b/drivers/accessibility/Makefile
new file mode 100644
index 00000000000..72b01a46546
--- /dev/null
+++ b/drivers/accessibility/Makefile
@@ -0,0 +1 @@
+obj-y += braille/
diff --git a/drivers/accessibility/braille/Makefile b/drivers/accessibility/braille/Makefile
new file mode 100644
index 00000000000..2e9f16c9134
--- /dev/null
+++ b/drivers/accessibility/braille/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille_console.o
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
new file mode 100644
index 00000000000..0a5f6b2114c
--- /dev/null
+++ b/drivers/accessibility/braille/braille_console.c
@@ -0,0 +1,397 @@
+/*
+ * Minimalistic braille device kernel support.
+ *
+ * By default, shows console messages on the braille device.
+ * Pressing Insert switches to VC browsing.
+ *
+ * Copyright (C) Samuel Thibault <samuel.thibault@ens-lyon.org>
+ *
+ * This program is free software ; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY ; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the program ; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/autoconf.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/console.h>
+#include <linux/notifier.h>
+
+#include <linux/selection.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+
+#include <linux/keyboard.h>
+#include <linux/kbd_kern.h>
+#include <linux/input.h>
+
+MODULE_AUTHOR("samuel.thibault@ens-lyon.org");
+MODULE_DESCRIPTION("braille device");
+MODULE_LICENSE("GPL");
+
+/*
+ * Braille device support part.
+ */
+
+/* Emit various sounds */
+static int sound;
+module_param(sound, bool, 0);
+MODULE_PARM_DESC(sound, "emit sounds");
+
+static void beep(unsigned int freq)
+{
+ if (sound)
+ kd_mksound(freq, HZ/10);
+}
+
+/* mini console */
+#define WIDTH 40
+#define BRAILLE_KEY KEY_INSERT
+static u16 console_buf[WIDTH];
+static int console_cursor;
+
+/* mini view of VC */
+static int vc_x, vc_y, lastvc_x, lastvc_y;
+
+/* show console ? (or show VC) */
+static int console_show = 1;
+/* pending newline ? */
+static int console_newline = 1;
+static int lastVC = -1;
+
+static struct console *braille_co;
+
+/* Very VisioBraille-specific */
+static void braille_write(u16 *buf)
+{
+ static u16 lastwrite[WIDTH];
+ unsigned char data[1 + 1 + 2*WIDTH + 2 + 1], csum = 0, *c;
+ u16 out;
+ int i;
+
+ if (!braille_co)
+ return;
+
+ if (!memcmp(lastwrite, buf, WIDTH * sizeof(*buf)))
+ return;
+ memcpy(lastwrite, buf, WIDTH * sizeof(*buf));
+
+#define SOH 1
+#define STX 2
+#define ETX 2
+#define EOT 4
+#define ENQ 5
+ data[0] = STX;
+ data[1] = '>';
+ csum ^= '>';
+ c = &data[2];
+ for (i = 0; i < WIDTH; i++) {
+ out = buf[i];
+ if (out >= 0x100)
+ out = '?';
+ else if (out == 0x00)
+ out = ' ';
+ csum ^= out;
+ if (out <= 0x05) {
+ *c++ = SOH;
+ out |= 0x40;
+ }
+ *c++ = out;
+ }
+
+ if (csum <= 0x05) {
+ *c++ = SOH;
+ csum |= 0x40;
+ }
+ *c++ = csum;
+ *c++ = ETX;
+
+ braille_co->write(braille_co, data, c - data);
+}
+
+/* Follow the VC cursor*/
+static void vc_follow_cursor(struct vc_data *vc)
+{
+ vc_x = vc->vc_x - (vc->vc_x % WIDTH);
+ vc_y = vc->vc_y;
+ lastvc_x = vc->vc_x;
+ lastvc_y = vc->vc_y;
+}
+
+/* Maybe the VC cursor moved, if so follow it */
+static void vc_maybe_cursor_moved(struct vc_data *vc)
+{
+ if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y)
+ vc_follow_cursor(vc);
+}
+
+/* Show portion of VC at vc_x, vc_y */
+static void vc_refresh(struct vc_data *vc)
+{
+ u16 buf[WIDTH];
+ int i;
+
+ for (i = 0; i < WIDTH; i++) {
+ u16 glyph = screen_glyph(vc,
+ 2 * (vc_x + i) + vc_y * vc->vc_size_row);
+ buf[i] = inverse_translate(vc, glyph, 1);
+ }
+ braille_write(buf);
+}
+
+/*
+ * Link to keyboard
+ */
+
+static int keyboard_notifier_call(struct notifier_block *blk,
+ unsigned long code, void *_param)
+{
+ struct keyboard_notifier_param *param = _param;
+ struct vc_data *vc = param->vc;
+ int ret = NOTIFY_OK;
+
+ if (!param->down)
+ return ret;
+
+ switch (code) {
+ case KBD_KEYCODE:
+ if (console_show) {
+ if (param->value == BRAILLE_KEY) {
+ console_show = 0;
+ beep(880);
+ vc_maybe_cursor_moved(vc);
+ vc_refresh(vc);
+ ret = NOTIFY_STOP;
+ }
+ } else {
+ ret = NOTIFY_STOP;
+ switch (param->value) {
+ case KEY_INSERT:
+ beep(440);
+ console_show = 1;
+ lastVC = -1;
+ braille_write(console_buf);
+ break;
+ case KEY_LEFT:
+ if (vc_x > 0) {
+ vc_x -= WIDTH;
+ if (vc_x < 0)
+ vc_x = 0;
+ } else if (vc_y >= 1) {
+ beep(880);
+ vc_y--;
+ vc_x = vc->vc_cols-WIDTH;
+ } else
+ beep(220);
+ break;
+ case KEY_RIGHT:
+ if (vc_x + WIDTH < vc->vc_cols) {
+ vc_x += WIDTH;
+ } else if (vc_y + 1 < vc->vc_rows) {
+ beep(880);
+ vc_y++;
+ vc_x = 0;
+ } else
+ beep(220);
+ break;
+ case KEY_DOWN:
+ if (vc_y + 1 < vc->vc_rows)
+ vc_y++;
+ else
+ beep(220);
+ break;
+ case KEY_UP:
+ if (vc_y >= 1)
+ vc_y--;
+ else
+ beep(220);
+ break;
+ case KEY_HOME:
+ vc_follow_cursor(vc);
+ break;
+ case KEY_PAGEUP:
+ vc_x = 0;
+ vc_y = 0;
+ break;
+ case KEY_PAGEDOWN:
+ vc_x = 0;
+ vc_y = vc->vc_rows-1;
+ break;
+ default:
+ ret = NOTIFY_OK;
+ break;
+ }
+ if (ret == NOTIFY_STOP)
+ vc_refresh(vc);
+ }
+ break;
+ case KBD_POST_KEYSYM:
+ {
+ unsigned char type = KTYP(param->value) - 0xf0;
+ if (type == KT_SPEC) {
+ unsigned char val = KVAL(param->value);
+ int on_off = -1;
+
+ switch (val) {
+ case KVAL(K_CAPS):
+ on_off = vc_kbd_led(kbd_table + fg_console,
+ VC_CAPSLOCK);
+ break;
+ case KVAL(K_NUM):
+ on_off = vc_kbd_led(kbd_table + fg_console,
+ VC_NUMLOCK);
+ break;
+ case KVAL(K_HOLD):
+ on_off = vc_kbd_led(kbd_table + fg_console,
+ VC_SCROLLOCK);
+ break;
+ }
+ if (on_off == 1)
+ beep(880);
+ else if (on_off == 0)
+ beep(440);
+ }
+ }
+ case KBD_UNBOUND_KEYCODE:
+ case KBD_UNICODE:
+ case KBD_KEYSYM:
+ /* Unused */
+ break;
+ }
+ return ret;
+}
+
+static struct notifier_block keyboard_notifier_block = {
+ .notifier_call = keyboard_notifier_call,
+};
+
+static int vt_notifier_call(struct notifier_block *blk,
+ unsigned long code, void *_param)
+{
+ struct vt_notifier_param *param = _param;
+ struct vc_data *vc = param->vc;
+ switch (code) {
+ case VT_ALLOCATE:
+ break;
+ case VT_DEALLOCATE:
+ break;
+ case VT_WRITE:
+ {
+ unsigned char c = param->c;
+ if (vc->vc_num != fg_console)
+ break;
+ switch (c) {
+ case '\b':
+ case 127:
+ if (console_cursor > 0) {
+ console_cursor--;
+ console_buf[console_cursor] = ' ';
+ }
+ break;
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ console_newline = 1;
+ break;
+ case '\t':
+ c = ' ';
+ /* Fallthrough */
+ default:
+ if (c < 32)
+ /* Ignore other control sequences */
+ break;
+ if (console_newline) {
+ memset(console_buf, 0, sizeof(console_buf));
+ console_cursor = 0;
+ console_newline = 0;
+ }
+ if (console_cursor == WIDTH)
+ memmove(console_buf, &console_buf[1],
+ (WIDTH-1) * sizeof(*console_buf));
+ else
+ console_cursor++;
+ console_buf[console_cursor-1] = c;
+ break;
+ }
+ if (console_show)
+ braille_write(console_buf);
+ else {
+ vc_maybe_cursor_moved(vc);
+ vc_refresh(vc);
+ }
+ break;
+ }
+ case VT_UPDATE:
+ /* Maybe a VT switch, flush */
+ if (console_show) {
+ if (vc->vc_num != lastVC) {
+ lastVC = vc->vc_num;
+ memset(console_buf, 0, sizeof(console_buf));
+ console_cursor = 0;
+ braille_write(console_buf);
+ }
+ } else {
+ vc_maybe_cursor_moved(vc);
+ vc_refresh(vc);
+ }
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block vt_notifier_block = {
+ .notifier_call = vt_notifier_call,
+};
+
+/*
+ * Called from printk.c when console=brl is given
+ */
+
+int braille_register_console(struct console *console, int index,
+ char *console_options, char *braille_options)
+{
+ int ret;
+ if (!console_options)
+ /* Only support VisioBraille for now */
+ console_options = "57600o8";
+ if (braille_co)
+ return -ENODEV;
+ if (console->setup) {
+ ret = console->setup(console, console_options);
+ if (ret != 0)
+ return ret;
+ }
+ console->flags |= CON_ENABLED;
+ console->index = index;
+ braille_co = console;
+ return 0;
+}
+
+int braille_unregister_console(struct console *console)
+{
+ if (braille_co != console)
+ return -EINVAL;
+ braille_co = NULL;
+ return 0;
+}
+
+static int __init braille_init(void)
+{
+ register_keyboard_notifier(&keyboard_notifier_block);
+ register_vt_notifier(&vt_notifier_block);
+ return 0;
+}
+
+console_initcall(braille_init);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 12fde2d03d6..39f3d1b3a21 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -77,6 +77,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
"Node %d PageTables: %8lu kB\n"
"Node %d NFS_Unstable: %8lu kB\n"
"Node %d Bounce: %8lu kB\n"
+ "Node %d WritebackTmp: %8lu kB\n"
"Node %d Slab: %8lu kB\n"
"Node %d SReclaimable: %8lu kB\n"
"Node %d SUnreclaim: %8lu kB\n",
@@ -99,6 +100,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
nid, K(node_page_state(nid, NR_PAGETABLE)),
nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
nid, K(node_page_state(nid, NR_BOUNCE)),
+ nid, K(node_page_state(nid, NR_WRITEBACK_TEMP)),
nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index e8e38faeafd..a196ef7f147 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -387,10 +387,14 @@ static struct block_device_operations brd_fops = {
*/
static int rd_nr;
int rd_size = CONFIG_BLK_DEV_RAM_SIZE;
+static int max_part;
+static int part_shift;
module_param(rd_nr, int, 0);
MODULE_PARM_DESC(rd_nr, "Maximum number of brd devices");
module_param(rd_size, int, 0);
MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");
+module_param(max_part, int, 0);
+MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk");
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR);
@@ -435,11 +439,11 @@ static struct brd_device *brd_alloc(int i)
blk_queue_max_sectors(brd->brd_queue, 1024);
blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
- disk = brd->brd_disk = alloc_disk(1);
+ disk = brd->brd_disk = alloc_disk(1 << part_shift);
if (!disk)
goto out_free_queue;
disk->major = RAMDISK_MAJOR;
- disk->first_minor = i;
+ disk->first_minor = i << part_shift;
disk->fops = &brd_fops;
disk->private_data = brd;
disk->queue = brd->brd_queue;
@@ -523,7 +527,12 @@ static int __init brd_init(void)
* themselves and have kernel automatically instantiate actual
* device on-demand.
*/
- if (rd_nr > 1UL << MINORBITS)
+
+ part_shift = 0;
+ if (max_part > 0)
+ part_shift = fls(max_part);
+
+ if (rd_nr > 1UL << (MINORBITS - part_shift))
return -EINVAL;
if (rd_nr) {
@@ -531,7 +540,7 @@ static int __init brd_init(void)
range = rd_nr;
} else {
nr = CONFIG_BLK_DEV_RAM_COUNT;
- range = 1UL << MINORBITS;
+ range = 1UL << (MINORBITS - part_shift);
}
if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
@@ -570,7 +579,7 @@ static void __exit brd_exit(void)
unsigned long range;
struct brd_device *brd, *next;
- range = rd_nr ? rd_nr : 1UL << MINORBITS;
+ range = rd_nr ? rd_nr : 1UL << (MINORBITS - part_shift);
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
brd_del_one(brd);
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 7e31d5f1bc8..e5cd856a2fe 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -143,7 +143,7 @@ restart:
int len;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- len = tty->driver->write(tty, skb->data, skb->len);
+ len = tty->ops->write(tty, skb->data, skb->len);
hdev->stat.byte_tx += len;
skb_pull(skb, len);
@@ -190,8 +190,7 @@ static int hci_uart_flush(struct hci_dev *hdev)
/* Flush any pending characters in the driver and discipline. */
tty_ldisc_flush(tty);
- if (tty->driver && tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
hu->proto->flush(hu);
@@ -285,9 +284,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
-
- if (tty->driver && tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
return 0;
}
@@ -373,9 +370,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
- if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
- tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ tty_unthrottle(tty);
}
static int hci_uart_register_dev(struct hci_uart *hu)
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index c69f79598e4..99e6a406efb 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -35,7 +35,7 @@
//#define AGP_DEBUG 1
#ifdef AGP_DEBUG
-#define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __FUNCTION__ , ## y)
+#define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __func__ , ## y)
#else
#define DBG(x,y...) do { } while (0)
#endif
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 3d468f502d2..37457e5a4f2 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -832,33 +832,34 @@ static void change_speed(struct async_struct *info,
local_irq_restore(flags);
}
-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+static int rs_put_char(struct tty_struct *tty, unsigned char ch)
{
struct async_struct *info;
unsigned long flags;
if (!tty)
- return;
+ return 0;
info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
- return;
+ return 0;
if (!info->xmit.buf)
- return;
+ return 0;
local_irq_save(flags);
if (CIRC_SPACE(info->xmit.head,
info->xmit.tail,
SERIAL_XMIT_SIZE) == 0) {
local_irq_restore(flags);
- return;
+ return 0;
}
info->xmit.buf[info->xmit.head++] = ch;
info->xmit.head &= SERIAL_XMIT_SIZE-1;
local_irq_restore(flags);
+ return 1;
}
static void rs_flush_chars(struct tty_struct *tty)
@@ -1074,6 +1075,7 @@ static int get_serial_info(struct async_struct * info,
if (!retinfo)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
+ lock_kernel();
tmp.type = state->type;
tmp.line = state->line;
tmp.port = state->port;
@@ -1084,6 +1086,7 @@ static int get_serial_info(struct async_struct * info,
tmp.close_delay = state->close_delay;
tmp.closing_wait = state->closing_wait;
tmp.custom_divisor = state->custom_divisor;
+ unlock_kernel();
if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
return -EFAULT;
return 0;
@@ -1099,13 +1102,17 @@ static int set_serial_info(struct async_struct * info,
if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
return -EFAULT;
+
+ lock_kernel();
state = info->state;
old_state = *state;
change_irq = new_serial.irq != state->irq;
change_port = (new_serial.port != state->port);
- if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size))
+ if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) {
+ unlock_kernel();
return -EINVAL;
+ }
if (!serial_isroot()) {
if ((new_serial.baud_base != state->baud_base) ||
@@ -1122,8 +1129,10 @@ static int set_serial_info(struct async_struct * info,
goto check_and_exit;
}
- if (new_serial.baud_base < 9600)
+ if (new_serial.baud_base < 9600) {
+ unlock_kernel();
return -EINVAL;
+ }
/*
* OK, past this point, all the error checking has been done.
@@ -1157,6 +1166,7 @@ check_and_exit:
}
} else
retval = startup(info);
+ unlock_kernel();
return retval;
}
@@ -1496,8 +1506,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
rs_wait_until_sent(tty, info->timeout);
}
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ rs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
@@ -1530,6 +1539,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
return; /* Just in case.... */
orig_jiffies = jiffies;
+
+ lock_kernel();
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
@@ -1570,6 +1581,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
__set_current_state(TASK_RUNNING);
+ unlock_kernel();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index a7c4990b5b6..31d08b641f5 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -199,7 +199,7 @@ static int __init applicom_init(void)
if (pci_enable_device(dev))
return -EIO;
- RamIO = ioremap(pci_resource_start(dev, 0), LEN_RAM_IO);
+ RamIO = ioremap_nocache(pci_resource_start(dev, 0), LEN_RAM_IO);
if (!RamIO) {
printk(KERN_INFO "ac.o: Failed to ioremap PCI memory "
@@ -254,7 +254,7 @@ static int __init applicom_init(void)
/* Now try the specified ISA cards */
for (i = 0; i < MAX_ISA_BOARD; i++) {
- RamIO = ioremap(mem + (LEN_RAM_IO * i), LEN_RAM_IO);
+ RamIO = ioremap_nocache(mem + (LEN_RAM_IO * i), LEN_RAM_IO);
if (!RamIO) {
printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1);
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 6b104e45a32..4246b8e36cb 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -277,6 +277,7 @@ u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
return p->inverse_translations[m][glyph];
}
}
+EXPORT_SYMBOL_GPL(inverse_translate);
static void update_user_maps(void)
{
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index e4f579c3e24..ef73e72daed 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -21,7 +21,6 @@
*
* This version supports shared IRQ's (only for PCI boards).
*
- * $Log: cyclades.c,v $
* Prevent users from opening non-existing Z ports.
*
* Revision 2.3.2.8 2000/07/06 18:14:16 ivan
@@ -62,7 +61,7 @@
* Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined;
*
* Revision 2.3.2.2 1999/10/01 11:27:43 ivan
- * Fixed bug in cyz_poll that would make all ports but port 0
+ * Fixed bug in cyz_poll that would make all ports but port 0
* unable to transmit/receive data (Cyclades-Z only);
* Implemented logic to prevent the RX buffer from being stuck with data
* due to a driver / firmware race condition in interrupt op mode
@@ -83,25 +82,25 @@
* Revision 2.3.1.1 1999/07/15 16:45:53 ivan
* Removed CY_PROC conditional compilation;
* Implemented SMP-awareness for the driver;
- * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off]
+ * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off]
* functions;
* The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs
* (irq=NN) as parameters (only for ISA boards);
- * Fixed bug in set_line_char that would prevent the Cyclades-Z
+ * Fixed bug in set_line_char that would prevent the Cyclades-Z
* ports from being configured at speeds above 115.2Kbps;
* Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
* switching from working properly;
- * The driver now only prints IRQ info for the Cyclades-Z if it's
+ * The driver now only prints IRQ info for the Cyclades-Z if it's
* configured to work in interrupt mode;
*
* Revision 2.2.2.3 1999/06/28 11:13:29 ivan
* Added support for interrupt mode operation for the Z cards;
* Removed the driver inactivity control for the Z;
- * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
+ * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
* the Z firmware is not loaded yet;
- * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
+ * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
* same functionality;
- * Implemented workaround for IRQ setting loss on the PCI configuration
+ * Implemented workaround for IRQ setting loss on the PCI configuration
* registers after a PCI bridge EEPROM reload (affects PLX9060 only);
*
* Revision 2.2.2.2 1999/05/14 17:18:15 ivan
@@ -112,22 +111,22 @@
* BREAK implementation changed in order to make use of the 'break_ctl'
* TTY facility;
* Fixed typo in TTY structure field 'driver_name';
- * Included a PCI bridge reset and EEPROM reload in the board
+ * Included a PCI bridge reset and EEPROM reload in the board
* initialization code (for both Y and Z series).
*
* Revision 2.2.2.1 1999/04/08 16:17:43 ivan
- * Fixed a bug in cy_wait_until_sent that was preventing the port to be
+ * Fixed a bug in cy_wait_until_sent that was preventing the port to be
* closed properly after a SIGINT;
* Module usage counter scheme revisited;
* Added support to the upcoming Y PCI boards (i.e., support to additional
* PCI Device ID's).
- *
+ *
* Revision 2.2.1.10 1999/01/20 16:14:29 ivan
* Removed all unnecessary page-alignement operations in ioremap calls
* (ioremap is currently safe for these operations).
*
* Revision 2.2.1.9 1998/12/30 18:18:30 ivan
- * Changed access to PLX PCI bridge registers from I/O to MMIO, in
+ * Changed access to PLX PCI bridge registers from I/O to MMIO, in
* order to make PLX9050-based boards work with certain motherboards.
*
* Revision 2.2.1.8 1998/11/13 12:46:20 ivan
@@ -148,7 +147,7 @@
* Fixed Cyclom-4Yo hardware detection bug.
*
* Revision 2.2.1.4 1998/08/04 11:02:50 ivan
- * /proc/cyclades implementation with great collaboration of
+ * /proc/cyclades implementation with great collaboration of
* Marc Lewis <marc@blarg.net>;
* cyy_interrupt was changed to avoid occurrence of kernel oopses
* during PPP operation.
@@ -157,7 +156,7 @@
* General code review in order to comply with 2.1 kernel standards;
* data loss prevention for slow devices revisited (cy_wait_until_sent
* was created);
- * removed conditional compilation for new/old PCI structure support
+ * removed conditional compilation for new/old PCI structure support
* (now the driver only supports the new PCI structure).
*
* Revision 2.2.1.1 1998/03/19 16:43:12 ivan
@@ -168,7 +167,7 @@
* cleaned up the data loss fix;
* fixed XON/XOFF handling once more (Cyclades-Z);
* general review of the driver routines;
- * introduction of a mechanism to prevent data loss with slow
+ * introduction of a mechanism to prevent data loss with slow
* printers, by forcing a delay before closing the port.
*
* Revision 2.1.1.2 1998/02/17 16:50:00 ivan
@@ -182,12 +181,12 @@
* Code review for the module cleanup routine;
* fixed RTS and DTR status report for new CD1400's in get_modem_info;
* includes anonymous changes regarding signal_pending.
- *
+ *
* Revision 2.1 1997/11/01 17:42:41 ivan
* Changes in the driver to support Alpha systems (except 8Zo V_1);
* BREAK fix for the Cyclades-Z boards;
* driver inactivity control by FW implemented;
- * introduction of flag that allows driver to take advantage of
+ * introduction of flag that allows driver to take advantage of
* a special CD1400 feature related to HW flow control;
* added support for the CD1400 rev. J (Cyclom-Y boards);
* introduction of ioctls to:
@@ -196,17 +195,17 @@
* - adjust the polling interval (Cyclades-Z);
*
* Revision 1.36.4.33 1997/06/27 19:00:00 ivan
- * Fixes related to kernel version conditional
+ * Fixes related to kernel version conditional
* compilation.
- *
+ *
* Revision 1.36.4.32 1997/06/14 19:30:00 ivan
- * Compatibility issues between kernels 2.0.x and
+ * Compatibility issues between kernels 2.0.x and
* 2.1.x (mainly related to clear_bit function).
- *
+ *
* Revision 1.36.4.31 1997/06/03 15:30:00 ivan
- * Changes to define the memory window according to the
+ * Changes to define the memory window according to the
* board type.
- *
+ *
* Revision 1.36.4.30 1997/05/16 15:30:00 daniel
* Changes to support new cycladesZ boards.
*
@@ -624,7 +623,7 @@
#undef CY_PCI_DEBUG
/*
- * Include section
+ * Include section
*/
#include <linux/module.h>
#include <linux/errno.h>
@@ -649,9 +648,9 @@
#include <linux/firmware.h>
#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/irq.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -668,10 +667,10 @@ static void cy_send_xchar(struct tty_struct *tty, char ch);
((readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
-#define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \
+#define ISZLOADED(card) (((ZO_V1 == readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->mail_box_0)) || \
Z_FPGA_CHECK(card)) && \
- (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \
+ (ZFIRM_ID == readl(&((struct FIRM_ID __iomem *) \
((card).base_addr+ID_ADDRESS))->signature)))
#ifndef SERIAL_XMIT_SIZE
@@ -809,12 +808,12 @@ static char baud_cor3[] = { /* receive threshold */
/*
* The Cyclades driver implements HW flow control as any serial driver.
- * The cyclades_port structure member rflow and the vector rflow_thr
- * allows us to take advantage of a special feature in the CD1400 to avoid
- * data loss even when the system interrupt latency is too high. These flags
- * are to be used only with very special applications. Setting these flags
- * requires the use of a special cable (DTR and RTS reversed). In the new
- * CD1400-based boards (rev. 6.00 or later), there is no need for special
+ * The cyclades_port structure member rflow and the vector rflow_thr
+ * allows us to take advantage of a special feature in the CD1400 to avoid
+ * data loss even when the system interrupt latency is too high. These flags
+ * are to be used only with very special applications. Setting these flags
+ * requires the use of a special cable (DTR and RTS reversed). In the new
+ * CD1400-based boards (rev. 6.00 or later), there is no need for special
* cables.
*/
@@ -841,14 +840,22 @@ static int cy_chip_offset[] = { 0x0000,
#ifdef CONFIG_PCI
static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, /* PCI > 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, /* 4Y PCI < 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, /* 4Y PCI > 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, /* 8Y PCI < 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, /* 8Y PCI > 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, /* Z PCI < 1Mb */
- { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, /* Z PCI > 1Mb */
+ /* PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
+ /* PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) },
+ /* 4Y PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) },
+ /* 4Y PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) },
+ /* 8Y PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) },
+ /* 8Y PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) },
+ /* Z PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) },
+ /* Z PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) },
{ } /* end of table */
};
MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
@@ -905,15 +912,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
This function is only called from inside spinlock-protected code.
*/
-static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
+static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
{
unsigned int i;
/* Check to see that the previous command has completed */
for (i = 0; i < 100; i++) {
- if (readb(base_addr + (CyCCR << index)) == 0) {
+ if (readb(base_addr + (CyCCR << index)) == 0)
break;
- }
udelay(10L);
}
/* if the CCR never cleared, the previous command
@@ -929,7 +935,7 @@ static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
#ifdef CONFIG_ISA
/* ISA interrupt detection code */
-static unsigned detect_isa_irq(void __iomem * address)
+static unsigned detect_isa_irq(void __iomem *address)
{
int irq;
unsigned long irqs, flags;
@@ -1038,7 +1044,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
if (info->flags & ASYNC_SAK)
do_SAK(tty);
} else if (data & CyFRAME) {
- tty_insert_flip_char( tty,
+ tty_insert_flip_char(tty,
readb(base_addr + (CyRDSR <<
index)), TTY_FRAME);
info->icount.rx++;
@@ -1320,7 +1326,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq);
+ printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",
+ irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
@@ -1375,12 +1382,12 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
/***********************************************************/
/********* End of block of Cyclom-Y specific code **********/
-/******** Start of block of Cyclades-Z specific code *********/
+/******** Start of block of Cyclades-Z specific code *******/
/***********************************************************/
static int
cyz_fetch_msg(struct cyclades_card *cinfo,
- __u32 * channel, __u8 * cmd, __u32 * param)
+ __u32 *channel, __u8 *cmd, __u32 *param)
{
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -1388,9 +1395,8 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
unsigned long loc_doorbell;
firm_id = cinfo->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo)) {
+ if (!ISZLOADED(*cinfo))
return -1;
- }
zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
@@ -1418,9 +1424,9 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
unsigned int index;
firm_id = cinfo->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*cinfo)) {
+ if (!ISZLOADED(*cinfo))
return -1;
- }
+
zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
@@ -1428,9 +1434,8 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
pci_doorbell =
&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
while ((readl(pci_doorbell) & 0xff) != 0) {
- if (index++ == 1000) {
+ if (index++ == 1000)
return (int)(readl(pci_doorbell) & 0xff);
- }
udelay(50L);
}
cy_writel(&board_ctrl->hcmd_channel, channel);
@@ -1504,7 +1509,8 @@ static void cyz_handle_rx(struct cyclades_port *info,
while (len--) {
data = readb(cinfo->base_addr + rx_bufaddr +
new_rx_get);
- new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1);
+ new_rx_get = (new_rx_get + 1) &
+ (rx_bufsize - 1);
tty_insert_flip_char(tty, data, TTY_NORMAL);
info->idle_stats.recv_bytes++;
info->icount.rx++;
@@ -1636,7 +1642,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
special_count = 0;
delta_count = 0;
info = &cinfo->ports[channel];
- if ((tty = info->tty) == NULL)
+ tty = info->tty;
+ if (tty == NULL)
continue;
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
@@ -1732,7 +1739,8 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id)
if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq);
+ printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",
+ irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
@@ -1851,9 +1859,8 @@ static int startup(struct cyclades_port *info)
}
if (!info->type) {
- if (info->tty) {
+ if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- }
free_page(page);
goto errout;
}
@@ -1904,9 +1911,8 @@ static int startup(struct cyclades_port *info)
readb(base_addr + (CySRER << index)) | CyRxData);
info->flags |= ASYNC_INITIALIZED;
- if (info->tty) {
+ if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
- }
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
info->breakon = info->breakoff = 0;
memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -1925,9 +1931,8 @@ static int startup(struct cyclades_port *info)
base_addr = card->base_addr;
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card)) {
+ if (!ISZLOADED(*card))
return -ENODEV;
- }
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
@@ -1990,9 +1995,8 @@ static int startup(struct cyclades_port *info)
/* enable send, recv, modem !!! */
info->flags |= ASYNC_INITIALIZED;
- if (info->tty) {
+ if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
- }
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
info->breakon = info->breakoff = 0;
memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -2061,9 +2065,8 @@ static void shutdown(struct cyclades_port *info)
void __iomem *base_addr;
int chip, channel, index;
- if (!(info->flags & ASYNC_INITIALIZED)) {
+ if (!(info->flags & ASYNC_INITIALIZED))
return;
- }
card = info->card;
channel = info->line - card->first_line;
@@ -2105,9 +2108,8 @@ static void shutdown(struct cyclades_port *info)
/* it may be appropriate to clear _XMIT at
some later date (after testing)!!! */
- if (info->tty) {
+ if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- }
info->flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
@@ -2124,9 +2126,8 @@ static void shutdown(struct cyclades_port *info)
#endif
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card)) {
+ if (!ISZLOADED(*card))
return;
- }
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
@@ -2157,9 +2158,8 @@ static void shutdown(struct cyclades_port *info)
#endif
}
- if (info->tty) {
+ if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
- }
info->flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
@@ -2204,7 +2204,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
* If non-blocking mode is set, then make the check up front
* and then exit.
*/
- if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+ if ((filp->f_flags & O_NONBLOCK) ||
+ (tty->flags & (1 << TTY_IO_ERROR))) {
info->flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -2301,7 +2302,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
return -EINVAL;
}
- zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff);
+ zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)
+ & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
@@ -2378,9 +2380,9 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
int retval;
line = tty->index;
- if ((tty->index < 0) || (NR_PORTS <= line)) {
+ if (tty->index < 0 || NR_PORTS <= line)
return -ENODEV;
- }
+
for (i = 0; i < NR_CARDS; i++)
if (line < cy_card[i].first_line + cy_card[i].nports &&
line >= cy_card[i].first_line)
@@ -2388,9 +2390,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
if (i >= NR_CARDS)
return -ENODEV;
info = &cy_card[i].ports[line - cy_card[i].first_line];
- if (info->line < 0) {
+ if (info->line < 0)
return -ENODEV;
- }
/* If the card's firmware hasn't been loaded,
treat it as absent from the system. This
@@ -2456,9 +2457,9 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
#endif
tty->driver_data = info;
info->tty = tty;
- if (serial_paranoia_check(info, tty->name, "cy_open")) {
+ if (serial_paranoia_check(info, tty->name, "cy_open"))
return -ENODEV;
- }
+
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
info->count);
@@ -2482,9 +2483,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
* Start up serial port
*/
retval = startup(info);
- if (retval) {
+ if (retval)
return retval;
- }
retval = block_til_ready(tty, filp, info);
if (retval) {
@@ -2522,6 +2522,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
return; /* Just in case.... */
orig_jiffies = jiffies;
+ lock_kernel();
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
@@ -2573,11 +2574,47 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
}
/* Run one more char cycle */
msleep_interruptible(jiffies_to_msecs(char_time * 5));
+ unlock_kernel();
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
#endif
}
+static void cy_flush_buffer(struct tty_struct *tty)
+{
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int channel, retval;
+ unsigned long flags;
+
+#ifdef CY_DEBUG_IO
+ printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
+#endif
+
+ if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
+ return;
+
+ card = info->card;
+ channel = info->line - card->first_line;
+
+ spin_lock_irqsave(&card->card_lock, flags);
+ info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+ spin_unlock_irqrestore(&card->card_lock, flags);
+
+ if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
+ buffers as well */
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
+ if (retval != 0) {
+ printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
+ "was %x\n", info->line, retval);
+ }
+ spin_unlock_irqrestore(&card->card_lock, flags);
+ }
+ tty_wakeup(tty);
+} /* cy_flush_buffer */
+
+
/*
* This routine is called when a particular tty device is closed.
*/
@@ -2591,9 +2628,8 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
#endif
- if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
+ if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
return;
- }
card = info->card;
@@ -2641,9 +2677,9 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
*/
tty->closing = 1;
spin_unlock_irqrestore(&card->card_lock, flags);
- if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
+ if (info->closing_wait != CY_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, info->closing_wait);
- }
+
spin_lock_irqsave(&card->card_lock, flags);
if (!IS_CYC_Z(*card)) {
@@ -2657,15 +2693,16 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) & ~CyRxData);
if (info->flags & ASYNC_INITIALIZED) {
- /* Waiting for on-board buffers to be empty before closing
- the port */
+ /* Waiting for on-board buffers to be empty before
+ closing the port */
spin_unlock_irqrestore(&card->card_lock, flags);
cy_wait_until_sent(tty, info->timeout);
spin_lock_irqsave(&card->card_lock, flags);
}
} else {
#ifdef Z_WAKE
- /* Waiting for on-board buffers to be empty before closing the port */
+ /* Waiting for on-board buffers to be empty before closing
+ the port */
void __iomem *base_addr = card->base_addr;
struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
struct ZFW_CTRL __iomem *zfw_ctrl =
@@ -2689,8 +2726,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&card->card_lock, flags);
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ cy_flush_buffer(tty);
tty_ldisc_flush(tty);
spin_lock_irqsave(&card->card_lock, flags);
@@ -2738,17 +2774,16 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_write")) {
+ if (serial_paranoia_check(info, tty->name, "cy_write"))
return 0;
- }
if (!info->xmit_buf)
return 0;
spin_lock_irqsave(&info->card->card_lock, flags);
while (1) {
- c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
- (int)(SERIAL_XMIT_SIZE - info->xmit_head)));
+ c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1));
+ c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head));
if (c <= 0)
break;
@@ -2766,9 +2801,9 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
info->idle_stats.xmit_bytes += ret;
info->idle_stats.xmit_idle = jiffies;
- if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+ if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped)
start_xmit(info);
- }
+
return ret;
} /* cy_write */
@@ -2779,7 +2814,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
* done stuffing characters into the driver. If there is no room
* in the queue, the character is ignored.
*/
-static void cy_put_char(struct tty_struct *tty, unsigned char ch)
+static int cy_put_char(struct tty_struct *tty, unsigned char ch)
{
struct cyclades_port *info = tty->driver_data;
unsigned long flags;
@@ -2789,15 +2824,15 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
#endif
if (serial_paranoia_check(info, tty->name, "cy_put_char"))
- return;
+ return 0;
if (!info->xmit_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->card->card_lock, flags);
if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
spin_unlock_irqrestore(&info->card->card_lock, flags);
- return;
+ return 0;
}
info->xmit_buf[info->xmit_head++] = ch;
@@ -2806,11 +2841,12 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
info->idle_stats.xmit_bytes++;
info->idle_stats.xmit_idle = jiffies;
spin_unlock_irqrestore(&info->card->card_lock, flags);
+ return 1;
} /* cy_put_char */
/*
* This routine is called by the kernel after it has written a
- * series of characters to the tty device using put_char().
+ * series of characters to the tty device using put_char().
*/
static void cy_flush_chars(struct tty_struct *tty)
{
@@ -2882,6 +2918,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
int char_count;
__u32 tx_put, tx_get, tx_bufsize;
+ lock_kernel();
firm_id = card->base_addr + ID_ADDRESS;
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
@@ -2899,6 +2936,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
info->line, info->xmit_cnt + char_count);
#endif
+ unlock_kernel();
return info->xmit_cnt + char_count;
}
#endif /* Z_EXT_CHARS_IN_BUFFER */
@@ -2950,12 +2988,12 @@ static void set_line_char(struct cyclades_port *info)
int baud, baud_rate = 0;
int i;
- if (!info->tty || !info->tty->termios) {
+ if (!info->tty || !info->tty->termios)
return;
- }
- if (info->line == -1) {
+
+ if (info->line == -1)
return;
- }
+
cflag = info->tty->termios->c_cflag;
iflag = info->tty->termios->c_iflag;
@@ -2994,13 +3032,11 @@ static void set_line_char(struct cyclades_port *info)
}
/* find the baud index */
for (i = 0; i < 20; i++) {
- if (baud == baud_table[i]) {
+ if (baud == baud_table[i])
break;
- }
}
- if (i == 20) {
+ if (i == 20)
i = 19; /* CD1400_MAX_SPEED */
- }
if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
@@ -3059,18 +3095,16 @@ static void set_line_char(struct cyclades_port *info)
info->cor1 = Cy_8_BITS;
break;
}
- if (cflag & CSTOPB) {
+ if (cflag & CSTOPB)
info->cor1 |= Cy_2_STOP;
- }
+
if (cflag & PARENB) {
- if (cflag & PARODD) {
+ if (cflag & PARODD)
info->cor1 |= CyPARITY_O;
- } else {
+ else
info->cor1 |= CyPARITY_E;
- }
- } else {
+ } else
info->cor1 |= CyPARITY_NONE;
- }
/* CTS flow control flag */
if (cflag & CRTSCTS) {
@@ -3123,7 +3157,8 @@ static void set_line_char(struct cyclades_port *info)
cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
CyCOR3ch, index);
- cy_writeb(base_addr + (CyCAR << index), (u_char) channel); /* !!! Is this needed? */
+ /* !!! Is this needed? */
+ cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
cy_writeb(base_addr + (CyRTPR << index),
(info->default_timeout ? info->default_timeout : 0x02));
/* 10ms rx timeout */
@@ -3191,9 +3226,8 @@ static void set_line_char(struct cyclades_port *info)
#endif
}
- if (info->tty) {
+ if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
- }
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
@@ -3206,9 +3240,8 @@ static void set_line_char(struct cyclades_port *info)
int retval;
firm_id = card->base_addr + ID_ADDRESS;
- if (!ISZLOADED(*card)) {
+ if (!ISZLOADED(*card))
return;
- }
zfw_ctrl = card->base_addr +
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
@@ -3268,14 +3301,12 @@ static void set_line_char(struct cyclades_port *info)
readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
}
if (cflag & PARENB) {
- if (cflag & PARODD) {
+ if (cflag & PARODD)
cy_writel(&ch_ctrl->comm_parity, C_PR_ODD);
- } else {
+ else
cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN);
- }
- } else {
+ } else
cy_writel(&ch_ctrl->comm_parity, C_PR_NONE);
- }
/* CTS flow control flag */
if (cflag & CRTSCTS) {
@@ -3305,11 +3336,10 @@ static void set_line_char(struct cyclades_port *info)
}
/* CD sensitivity */
- if (cflag & CLOCAL) {
+ if (cflag & CLOCAL)
info->flags &= ~ASYNC_CHECK_CD;
- } else {
+ else
info->flags |= ASYNC_CHECK_CD;
- }
if (baud == 0) { /* baud rate is zero, turn off line */
cy_writel(&ch_ctrl->rs_control,
@@ -3325,21 +3355,20 @@ static void set_line_char(struct cyclades_port *info)
#endif
}
- retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
"was %x\n", info->line, retval);
}
- if (info->tty) {
+ if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
- }
}
} /* set_line_char */
static int
get_serial_info(struct cyclades_port *info,
- struct serial_struct __user * retinfo)
+ struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
struct cyclades_card *cinfo = info->card;
@@ -3363,7 +3392,7 @@ get_serial_info(struct cyclades_port *info,
static int
set_serial_info(struct cyclades_port *info,
- struct serial_struct __user * new_info)
+ struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
struct cyclades_port old_info;
@@ -3417,7 +3446,7 @@ check_and_exit:
* transmit holding register is empty. This functionality
* allows an RS485 driver to be written in user space.
*/
-static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
+static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
{
struct cyclades_card *card;
int chip, channel, index;
@@ -3461,9 +3490,11 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
struct BOARD_CTRL __iomem *board_ctrl;
struct CH_CTRL __iomem *ch_ctrl;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
+ lock_kernel();
+
card = info->card;
channel = info->line - card->first_line;
if (!IS_CYC_Z(*card)) {
@@ -3506,10 +3537,12 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
} else {
result = 0;
+ unlock_kernel();
return -ENODEV;
}
}
+ unlock_kernel();
return result;
} /* cy_tiomget */
@@ -3528,7 +3561,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
struct CH_CTRL __iomem *ch_ctrl;
int retval;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
card = info->card;
@@ -3727,8 +3760,8 @@ static void cy_break(struct tty_struct *tty, int break_state)
spin_unlock_irqrestore(&card->card_lock, flags);
} /* cy_break */
-static int
-get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
+static int get_mon_info(struct cyclades_port *info,
+ struct cyclades_monitor __user *mon)
{
if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
@@ -3767,8 +3800,8 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
return 0;
} /* set_threshold */
-static int
-get_threshold(struct cyclades_port *info, unsigned long __user * value)
+static int get_threshold(struct cyclades_port *info,
+ unsigned long __user *value)
{
struct cyclades_card *card;
void __iomem *base_addr;
@@ -3789,15 +3822,15 @@ get_threshold(struct cyclades_port *info, unsigned long __user * value)
return 0;
} /* get_threshold */
-static int
-set_default_threshold(struct cyclades_port *info, unsigned long value)
+static int set_default_threshold(struct cyclades_port *info,
+ unsigned long value)
{
info->default_threshold = value & 0x0f;
return 0;
} /* set_default_threshold */
-static int
-get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
+static int get_default_threshold(struct cyclades_port *info,
+ unsigned long __user *value)
{
return put_user(info->default_threshold, value);
} /* get_default_threshold */
@@ -3824,7 +3857,8 @@ static int set_timeout(struct cyclades_port *info, unsigned long value)
return 0;
} /* set_timeout */
-static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
+static int get_timeout(struct cyclades_port *info,
+ unsigned long __user *value)
{
struct cyclades_card *card;
void __iomem *base_addr;
@@ -3851,8 +3885,8 @@ static int set_default_timeout(struct cyclades_port *info, unsigned long value)
return 0;
} /* set_default_timeout */
-static int
-get_default_timeout(struct cyclades_port *info, unsigned long __user * value)
+static int get_default_timeout(struct cyclades_port *info,
+ unsigned long __user *value)
{
return put_user(info->default_timeout, value);
} /* get_default_timeout */
@@ -3880,6 +3914,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
info->line, cmd, arg);
#endif
+ lock_kernel();
switch (cmd) {
case CYGETMON:
@@ -3936,7 +3971,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
break;
#endif /* CONFIG_CYZ_INTR */
case CYSETWAIT:
- info->closing_wait = (unsigned short)arg *HZ / 100;
+ info->closing_wait = (unsigned short)arg * HZ / 100;
ret_val = 0;
break;
case CYGETWAIT:
@@ -3988,47 +4023,47 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
p_cuser = argp;
ret_val = put_user(cnow.cts, &p_cuser->cts);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.dsr, &p_cuser->dsr);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.rng, &p_cuser->rng);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.dcd, &p_cuser->dcd);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.rx, &p_cuser->rx);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.tx, &p_cuser->tx);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.frame, &p_cuser->frame);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.overrun, &p_cuser->overrun);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.parity, &p_cuser->parity);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.brk, &p_cuser->brk);
if (ret_val)
- return ret_val;
+ break;
ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
if (ret_val)
- return ret_val;
+ break;
ret_val = 0;
break;
default:
ret_val = -ENOIOCTLCMD;
}
+ unlock_kernel();
#ifdef CY_DEBUG_OTHER
printk(KERN_DEBUG "cyc:cy_ioctl done\n");
#endif
-
return ret_val;
} /* cy_ioctl */
@@ -4113,9 +4148,8 @@ static void cy_throttle(struct tty_struct *tty)
tty->ldisc.chars_in_buffer(tty), info->line);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_throttle")) {
+ if (serial_paranoia_check(info, tty->name, "cy_throttle"))
return;
- }
card = info->card;
@@ -4169,12 +4203,11 @@ static void cy_unthrottle(struct tty_struct *tty)
char buf[64];
printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
- tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line);
+ tty_name(tty, buf), tty_chars_in_buffer(tty), info->line);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) {
+ if (serial_paranoia_check(info, tty->name, "cy_unthrottle"))
return;
- }
if (I_IXOFF(tty)) {
if (info->x_char)
@@ -4269,47 +4302,14 @@ static void cy_start(struct tty_struct *tty)
base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
spin_lock_irqsave(&cinfo->card_lock, flags);
- cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */
+ cy_writeb(base_addr + (CyCAR << index),
+ (u_char) (channel & 0x0003)); /* index channel */
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) | CyTxRdy);
spin_unlock_irqrestore(&cinfo->card_lock, flags);
}
} /* cy_start */
-static void cy_flush_buffer(struct tty_struct *tty)
-{
- struct cyclades_port *info = tty->driver_data;
- struct cyclades_card *card;
- int channel, retval;
- unsigned long flags;
-
-#ifdef CY_DEBUG_IO
- printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
-#endif
-
- if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
- return;
-
- card = info->card;
- channel = info->line - card->first_line;
-
- spin_lock_irqsave(&card->card_lock, flags);
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- spin_unlock_irqrestore(&card->card_lock, flags);
-
- if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
- buffers as well */
- spin_lock_irqsave(&card->card_lock, flags);
- retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
- if (retval != 0) {
- printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
- "was %x\n", info->line, retval);
- }
- spin_unlock_irqrestore(&card->card_lock, flags);
- }
- tty_wakeup(tty);
-} /* cy_flush_buffer */
-
/*
* cy_hangup() --- called by tty_hangup() when a hangup is signaled.
*/
@@ -4406,10 +4406,11 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
info->cor3 = 0x08; /* _very_ small rcv threshold */
chip_number = (port - cinfo->first_line) / 4;
- if ((info->chip_rev = readb(cinfo->base_addr +
- (cy_chip_offset[chip_number] <<
- index) + (CyGFRCR << index))) >=
- CD1400_REV_J) {
+ info->chip_rev = readb(cinfo->base_addr +
+ (cy_chip_offset[chip_number] << index) +
+ (CyGFRCR << index));
+
+ if (info->chip_rev >= CD1400_REV_J) {
/* It is a CD1400 rev. J or later */
info->tbpr = baud_bpr_60[13]; /* Tx BPR */
info->tco = baud_co_60[13]; /* Tx CO */
@@ -4454,7 +4455,8 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
/* Cy_ClrIntr is 0x1800 */
udelay(500L);
- for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; chip_number++) {
+ for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD;
+ chip_number++) {
base_addr =
true_base_addr + (cy_chip_offset[chip_number] << index);
mdelay(1);
@@ -4555,12 +4557,11 @@ static int __init cy_detect_isa(void)
/* scan the address table probing for Cyclom-Y/ISA boards */
for (i = 0; i < NR_ISA_ADDRS; i++) {
unsigned int isa_address = cy_isa_addresses[i];
- if (isa_address == 0x0000) {
+ if (isa_address == 0x0000)
return nboard;
- }
/* probe for CD1400... */
- cy_isa_address = ioremap(isa_address, CyISA_Ywin);
+ cy_isa_address = ioremap_nocache(isa_address, CyISA_Ywin);
if (cy_isa_address == NULL) {
printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
"address\n");
@@ -4847,12 +4848,10 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
if (mailbox != 0) {
/* set window to last 512K of RAM */
cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE);
- //sleep(1);
for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
cy_writeb(tmp, 255);
/* set window to beginning of RAM */
cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
- //sleep(1);
}
retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL);
@@ -5382,7 +5381,8 @@ static void __exit cy_cleanup_module(void)
del_timer_sync(&cyz_timerlist);
#endif /* CONFIG_CYZ_INTR */
- if ((e1 = tty_unregister_driver(cy_serial_driver)))
+ e1 = tty_unregister_driver(cy_serial_driver);
+ if (e1)
printk(KERN_ERR "failed to unregister Cyclades serial "
"driver(%d)\n", e1);
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index ecee3547a13..213b3ca3468 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -160,7 +160,7 @@ struct drm_device;
* \param arg arguments
*/
#define DRM_ERROR(fmt, arg...) \
- printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg)
+ printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg)
/**
* Memory error output.
@@ -170,7 +170,7 @@ struct drm_device;
* \param arg arguments
*/
#define DRM_MEM_ERROR(area, fmt, arg...) \
- printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
+ printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __func__, \
drm_mem_stats[area].name , ##arg)
#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
@@ -187,7 +187,7 @@ struct drm_device;
if ( drm_debug ) \
printk(KERN_DEBUG \
"[" DRM_NAME ":%s] " fmt , \
- __FUNCTION__ , ##arg); \
+ __func__ , ##arg); \
} while (0)
#else
#define DRM_DEBUG(fmt, arg...) do { } while (0)
@@ -238,7 +238,7 @@ do { \
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
dev->lock.file_priv != file_priv ) { \
DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\
- __FUNCTION__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
+ __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
dev->lock.file_priv, file_priv ); \
return -EINVAL; \
} \
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 7a1d9a782dd..9a32169e88f 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -34,7 +34,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
struct drm_minor *drm_minor = to_drm_minor(dev);
struct drm_device *drm_dev = drm_minor->dev;
- printk(KERN_ERR "%s\n", __FUNCTION__);
+ printk(KERN_ERR "%s\n", __func__);
if (drm_dev->driver->suspend)
return drm_dev->driver->suspend(drm_dev, state);
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 60c9376be48..a86ab30b462 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -692,7 +692,7 @@ static void i830EmitState(struct drm_device * dev)
drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
- DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
+ DRM_DEBUG("%s %x\n", __func__, dirty);
if (dirty & I830_UPLOAD_BUFFERS) {
i830EmitDestVerified(dev, sarea_priv->BufferState);
@@ -1043,7 +1043,7 @@ static void i830_dma_dispatch_flip(struct drm_device * dev)
RING_LOCALS;
DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
+ __func__,
dev_priv->current_page,
dev_priv->sarea_priv->pf_current_page);
@@ -1206,7 +1206,7 @@ static void i830_dma_quiescent(struct drm_device * dev)
OUT_RING(0);
ADVANCE_LP_RING();
- i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
}
static int i830_flush_queue(struct drm_device * dev)
@@ -1223,7 +1223,7 @@ static int i830_flush_queue(struct drm_device * dev)
OUT_RING(0);
ADVANCE_LP_RING();
- i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
for (i = 0; i < dma->buf_count; i++) {
struct drm_buf *buf = dma->buflist[i];
@@ -1344,7 +1344,7 @@ static void i830_do_init_pageflip(struct drm_device * dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
@@ -1354,7 +1354,7 @@ static int i830_do_cleanup_pageflip(struct drm_device * dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
if (dev_priv->current_page != 0)
i830_dma_dispatch_flip(dev);
@@ -1367,7 +1367,7 @@ static int i830_flip_bufs(struct drm_device *dev, void *data,
{
drm_i830_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1437,7 +1437,7 @@ static int i830_getparam(struct drm_device *dev, void *data,
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
@@ -1464,7 +1464,7 @@ static int i830_setparam(struct drm_device *dev, void *data,
drm_i830_setparam_t *param = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index 4caba8c5445..b5bf8cc0fda 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -158,7 +158,7 @@ extern int i830_driver_device_is_agp(struct drm_device * dev);
if (I830_VERBOSE) \
printk("BEGIN_LP_RING(%d)\n", (n)); \
if (dev_priv->ring.space < n*4) \
- i830_wait_ring(dev, n*4, __FUNCTION__); \
+ i830_wait_ring(dev, n*4, __func__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
index a33db5f0967..91ec2bb497e 100644
--- a/drivers/char/drm/i830_irq.c
+++ b/drivers/char/drm/i830_irq.c
@@ -58,7 +58,7 @@ static int i830_emit_irq(struct drm_device * dev)
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
atomic_inc(&dev_priv->irq_emitted);
@@ -77,7 +77,7 @@ static int i830_wait_irq(struct drm_device * dev, int irq_nr)
unsigned long end = jiffies + HZ * 3;
int ret = 0;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
return 0;
@@ -124,7 +124,7 @@ int i830_irq_emit(struct drm_device *dev, void *data,
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
@@ -147,7 +147,7 @@ int i830_irq_wait(struct drm_device *dev, void *data,
drm_i830_irq_wait_t *irqwait = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index ef7bf143a80..f47e46e3529 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -194,7 +194,7 @@ static int i915_dma_resume(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("%s\n", __func__);
if (!dev_priv->sarea) {
DRM_ERROR("can not find sarea!\n");
@@ -609,7 +609,7 @@ static int i915_quiescent(struct drm_device * dev)
drm_i915_private_t *dev_priv = dev->dev_private;
i915_kernel_lost_context(dev);
- return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
}
static int i915_flush_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index c614d78b3df..db7001f2256 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -272,7 +272,7 @@ extern void i915_mem_release(struct drm_device * dev,
if (I915_VERBOSE) \
DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
if (dev_priv->ring.space < (n)*4) \
- i915_wait_ring(dev, (n)*4, __FUNCTION__); \
+ i915_wait_ring(dev, (n)*4, __func__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 9072e4a1894..f6f6c92bf77 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -894,7 +894,7 @@ static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
#if RADEON_FIFO_DEBUG
static void radeon_status(drm_radeon_private_t * dev_priv)
{
- printk("%s:\n", __FUNCTION__);
+ printk("%s:\n", __func__);
printk("RBBM_STATUS = 0x%08x\n",
(unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
printk("CP_RB_RTPR = 0x%08x\n",
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index 59146e3365b..ea35ab2c990 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -39,6 +39,7 @@
#include <linux/spinlock.h>
#include <linux/bcd.h>
#include <linux/proc_fs.h>
+#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -451,7 +452,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
*/
if (ds1286_is_updating() != 0)
- while (jiffies - uip_watchdog < 2*HZ/100)
+ while (time_before(jiffies, uip_watchdog + 2*HZ/100))
barrier();
/*
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index ffd747c5dff..60a4df7dac1 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -38,8 +38,8 @@
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include "digiPCI.h"
@@ -73,7 +73,8 @@ static int invalid_lilo_config;
*/
static DEFINE_SPINLOCK(epca_lock);
-/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. */
+/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted
+ to 7 below. */
static struct board_info boards[MAXBOARDS];
static struct tty_driver *pc_driver;
@@ -157,13 +158,12 @@ static void epca_error(int, char *);
static void pc_close(struct tty_struct *, struct file *);
static void shutdown(struct channel *);
static void pc_hangup(struct tty_struct *);
-static void pc_put_char(struct tty_struct *, unsigned char);
static int pc_write_room(struct tty_struct *);
static int pc_chars_in_buffer(struct tty_struct *);
static void pc_flush_buffer(struct tty_struct *);
static void pc_flush_chars(struct tty_struct *);
static int block_til_ready(struct tty_struct *, struct file *,
- struct channel *);
+ struct channel *);
static int pc_open(struct tty_struct *, struct file *);
static void post_fep_init(unsigned int crd);
static void epcapoll(unsigned long);
@@ -175,18 +175,18 @@ static unsigned termios2digi_c(struct channel *ch, unsigned);
static void epcaparam(struct tty_struct *, struct channel *);
static void receive_data(struct channel *);
static int pc_ioctl(struct tty_struct *, struct file *,
- unsigned int, unsigned long);
+ unsigned int, unsigned long);
static int info_ioctl(struct tty_struct *, struct file *,
- unsigned int, unsigned long);
+ unsigned int, unsigned long);
static void pc_set_termios(struct tty_struct *, struct ktermios *);
static void do_softint(struct work_struct *work);
static void pc_stop(struct tty_struct *);
static void pc_start(struct tty_struct *);
-static void pc_throttle(struct tty_struct * tty);
+static void pc_throttle(struct tty_struct *tty);
static void pc_unthrottle(struct tty_struct *tty);
static void digi_send_break(struct channel *ch, int msec);
static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
-void epca_setup(char *, int *);
+static void epca_setup(char *, int *);
static int pc_write(struct tty_struct *, const unsigned char *, int);
static int pc_init(void);
@@ -243,7 +243,7 @@ static void assertmemoff(struct channel *ch)
/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */
static void pcxem_memwinon(struct board_info *b, unsigned int win)
{
- outb_p(FEPWIN|win, b->port + 1);
+ outb_p(FEPWIN | win, b->port + 1);
}
static void pcxem_memwinoff(struct board_info *b, unsigned int win)
@@ -253,7 +253,7 @@ static void pcxem_memwinoff(struct board_info *b, unsigned int win)
static void pcxem_globalwinon(struct channel *ch)
{
- outb_p( FEPWIN, (int)ch->board->port + 1);
+ outb_p(FEPWIN, (int)ch->board->port + 1);
}
static void pcxem_rxwinon(struct channel *ch)
@@ -394,7 +394,7 @@ static struct channel *verifyChannel(struct tty_struct *tty)
*/
if (tty) {
struct channel *ch = (struct channel *)tty->driver_data;
- if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) {
+ if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) {
if (ch->magic == EPCA_MAGIC)
return ch;
}
@@ -414,7 +414,7 @@ static void pc_sched_event(struct channel *ch, int event)
static void epca_error(int line, char *msg)
{
- printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg);
+ printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg);
}
static void pc_close(struct tty_struct *tty, struct file *filp)
@@ -425,7 +425,8 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if (tty_hung_up_p(filp)) {
spin_unlock_irqrestore(&epca_lock, flags);
@@ -440,7 +441,6 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&epca_lock, flags);
return;
}
-
/* Port open only once go ahead with shutdown & reset */
BUG_ON(ch->count < 0);
@@ -455,12 +455,13 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&epca_lock, flags);
if (ch->asyncflags & ASYNC_INITIALIZED) {
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the
+ transmit buffer empties */
setup_empty_event(tty, ch);
- tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+ /* 30 seconds timeout */
+ tty_wait_until_sent(tty, 3000);
}
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ pc_flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(ch);
@@ -477,7 +478,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
wake_up_interruptible(&ch->open_wait);
}
ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
- ASYNC_CLOSING);
+ ASYNC_CLOSING);
wake_up_interruptible(&ch->close_wait);
}
}
@@ -524,16 +525,15 @@ static void shutdown(struct channel *ch)
static void pc_hangup(struct tty_struct *tty)
{
struct channel *ch;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ pc_flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(ch);
@@ -548,7 +548,7 @@ static void pc_hangup(struct tty_struct *tty)
}
static int pc_write(struct tty_struct *tty,
- const unsigned char *buf, int bytesAvailable)
+ const unsigned char *buf, int bytesAvailable)
{
unsigned int head, tail;
int dataLen;
@@ -572,7 +572,8 @@ static int pc_write(struct tty_struct *tty,
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return 0;
/* Make a pointer to the channel data structure found on the board. */
@@ -645,26 +646,19 @@ static int pc_write(struct tty_struct *tty,
return amountCopied;
}
-static void pc_put_char(struct tty_struct *tty, unsigned char c)
-{
- pc_write(tty, &c, 1);
-}
-
static int pc_write_room(struct tty_struct *tty)
{
- int remain;
+ int remain = 0;
struct channel *ch;
unsigned long flags;
unsigned int head, tail;
struct board_chan __iomem *bc;
-
- remain = 0;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
@@ -676,8 +670,8 @@ static int pc_write_room(struct tty_struct *tty)
tail = readw(&bc->tout);
/* Wrap tail if necessary */
tail &= (ch->txbufsize - 1);
-
- if ((remain = tail - head - 1) < 0 )
+ remain = tail - head - 1;
+ if (remain < 0)
remain += ch->txbufsize;
if (remain && (ch->statusflags & LOWWAIT) == 0) {
@@ -699,12 +693,12 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
unsigned long flags;
struct channel *ch;
struct board_chan __iomem *bc;
-
/*
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return 0;
spin_lock_irqsave(&epca_lock, flags);
@@ -715,7 +709,8 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
head = readw(&bc->tin);
ctail = readw(&ch->mailbox->cout);
- if (tail == head && readw(&ch->mailbox->cin) == ctail && readb(&bc->tbusy) == 0)
+ if (tail == head && readw(&ch->mailbox->cin) == ctail &&
+ readb(&bc->tbusy) == 0)
chars = 0;
else { /* Begin if some space on the card has been used */
head = readw(&bc->tin) & (ch->txbufsize - 1);
@@ -725,7 +720,8 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
* pc_write_room here we are finding the amount of bytes in the
* buffer filled. Not the amount of bytes empty.
*/
- if ((remain = tail - head - 1) < 0 )
+ remain = tail - head - 1;
+ if (remain < 0)
remain += ch->txbufsize;
chars = (int)(ch->txbufsize - remain);
/*
@@ -736,7 +732,7 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
* transmit buffer empties.
*/
if (!(ch->statusflags & EMPTYWAIT))
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
} /* End if some space on the card has been used */
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
@@ -754,7 +750,8 @@ static void pc_flush_buffer(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) == NULL)
+ ch = verifyChannel(tty);
+ if (ch == NULL)
return;
spin_lock_irqsave(&epca_lock, flags);
@@ -775,23 +772,25 @@ static void pc_flush_chars(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
/*
* If not already set and the transmitter is busy setup an
* event to indicate when the transmit empties.
*/
- if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))
- setup_empty_event(tty,ch);
+ if ((ch->statusflags & TXBUSY) &&
+ !(ch->statusflags & EMPTYWAIT))
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
}
}
static int block_til_ready(struct tty_struct *tty,
- struct file *filp, struct channel *ch)
+ struct file *filp, struct channel *ch)
{
- DECLARE_WAITQUEUE(wait,current);
+ DECLARE_WAITQUEUE(wait, current);
int retval, do_clocal = 0;
unsigned long flags;
@@ -839,8 +838,7 @@ static int block_til_ready(struct tty_struct *tty,
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED))
- {
+ !(ch->asyncflags & ASYNC_INITIALIZED)) {
if (ch->asyncflags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
@@ -880,7 +878,7 @@ static int block_til_ready(struct tty_struct *tty,
return 0;
}
-static int pc_open(struct tty_struct *tty, struct file * filp)
+static int pc_open(struct tty_struct *tty, struct file *filp)
{
struct channel *ch;
unsigned long flags;
@@ -923,7 +921,8 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
return(-ENODEV);
}
- if ((bc = ch->brdchan) == 0) {
+ bc = ch->brdchan;
+ if (bc == NULL) {
tty->driver_data = NULL;
return -ENODEV;
}
@@ -964,7 +963,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
* The below routine generally sets up parity, baud, flow control
* issues, etc.... It effect both control flags and input flags.
*/
- epcaparam(tty,ch);
+ epcaparam(tty, ch);
ch->asyncflags |= ASYNC_INITIALIZED;
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
@@ -1002,8 +1001,8 @@ static void __exit epca_module_exit(void)
del_timer_sync(&epca_timer);
- if (tty_unregister_driver(pc_driver) || tty_unregister_driver(pc_info))
- {
+ if (tty_unregister_driver(pc_driver) ||
+ tty_unregister_driver(pc_info)) {
printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n");
return;
}
@@ -1034,7 +1033,6 @@ static const struct tty_operations pc_ops = {
.flush_buffer = pc_flush_buffer,
.chars_in_buffer = pc_chars_in_buffer,
.flush_chars = pc_flush_chars,
- .put_char = pc_put_char,
.ioctl = pc_ioctl,
.set_termios = pc_set_termios,
.stop = pc_stop,
@@ -1044,7 +1042,7 @@ static const struct tty_operations pc_ops = {
.hangup = pc_hangup,
};
-static int info_open(struct tty_struct *tty, struct file * filp)
+static int info_open(struct tty_struct *tty, struct file *filp)
{
return 0;
}
@@ -1099,7 +1097,7 @@ static int __init pc_init(void)
* Set up interrupt, we will worry about memory allocation in
* post_fep_init.
*/
- printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION);
+ printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION);
/*
* NOTE : This code assumes that the number of ports found in the
@@ -1252,7 +1250,7 @@ static int __init pc_init(void)
if ((board_id & 0x30) == 0x30)
bd->memory_seg = 0x8000;
} else
- printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);
+ printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port);
break;
}
}
@@ -1326,12 +1324,12 @@ static void post_fep_init(unsigned int crd)
*/
/* PCI cards are already remapped at this point ISA are not */
bd->numports = readw(bd->re_map_membase + XEMPORTS);
- epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");
+ epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports");
nbdevs += (bd->numports);
} else {
/* Fix up the mappings for ISA/EISA etc */
/* FIXME: 64K - can we be smarter ? */
- bd->re_map_membase = ioremap(bd->membase, 0x10000);
+ bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000);
}
if (crd != 0)
@@ -1362,7 +1360,8 @@ static void post_fep_init(unsigned int crd)
* XEPORTS (address 0xc22) points at the number of channels the card
* supports. (For 64XE, XI, XEM, and XR use 0xc02)
*/
- if ((bd->type == PCXEVE || bd->type == PCXE) && (readw(memaddr + XEPORTS) < 3))
+ if ((bd->type == PCXEVE || bd->type == PCXE) &&
+ (readw(memaddr + XEPORTS) < 3))
shrinkmem = 1;
if (bd->type < PCIXEM)
if (!request_region((int)bd->port, 4, board_desc[bd->type]))
@@ -1461,10 +1460,12 @@ static void post_fep_init(unsigned int crd)
case PCXEVE:
case PCXE:
- ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4)
+ & 0x1fff);
ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
- ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
- ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
+ ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4)
+ & 0x1fff);
+ ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9);
break;
case PCXI:
@@ -1518,8 +1519,9 @@ static void post_fep_init(unsigned int crd)
}
printk(KERN_INFO
- "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
- VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);
+ "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
+ VERSION, board_desc[bd->type], (long)bd->port,
+ (long)bd->membase, bd->numports);
memwinoff(bd, 0);
}
@@ -1527,7 +1529,7 @@ static void epcapoll(unsigned long ignored)
{
unsigned long flags;
int crd;
- volatile unsigned int head, tail;
+ unsigned int head, tail;
struct channel *ch;
struct board_info *bd;
@@ -1593,7 +1595,9 @@ static void doevent(int crd)
chan0 = card_ptr[crd];
epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
assertgwinon(chan0);
- while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) { /* Begin while something in event queue */
+ while ((tail = readw(&chan0->mailbox->eout)) !=
+ (head = readw(&chan0->mailbox->ein))) {
+ /* Begin while something in event queue */
assertgwinon(chan0);
eventbuf = bd->re_map_membase + tail + ISTART;
/* Get the channel the event occurred on */
@@ -1617,7 +1621,8 @@ static void doevent(int crd)
goto next;
}
- if ((bc = ch->brdchan) == NULL)
+ bc = ch->brdchan;
+ if (bc == NULL)
goto next;
if (event & DATA_IND) { /* Begin DATA_IND */
@@ -1629,10 +1634,11 @@ static void doevent(int crd)
/* A modem signal change has been indicated */
ch->imodem = mstat;
if (ch->asyncflags & ASYNC_CHECK_CD) {
- if (mstat & ch->dcd) /* We are now receiving dcd */
+ /* We are now receiving dcd */
+ if (mstat & ch->dcd)
wake_up_interruptible(&ch->open_wait);
- else
- pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */
+ else /* No dcd; hangup */
+ pc_sched_event(ch, EPCA_EVENT_HANGUP);
}
}
tty = ch->tty;
@@ -1647,7 +1653,8 @@ static void doevent(int crd)
tty_wakeup(tty);
}
} else if (event & EMPTYTX_IND) {
- /* This event is generated by setup_empty_event */
+ /* This event is generated by
+ setup_empty_event */
ch->statusflags &= ~TXBUSY;
if (ch->statusflags & EMPTYWAIT) {
ch->statusflags &= ~EMPTYWAIT;
@@ -1655,7 +1662,7 @@ static void doevent(int crd)
}
}
}
- next:
+next:
globalwinon(ch);
BUG_ON(!bc);
writew(1, &bc->idata);
@@ -1665,7 +1672,7 @@ static void doevent(int crd)
}
static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
- int byte2, int ncmds, int bytecmd)
+ int byte2, int ncmds, int bytecmd)
{
unchar __iomem *memaddr;
unsigned int head, cmdTail, cmdStart, cmdMax;
@@ -1690,8 +1697,10 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
memaddr = ch->board->re_map_membase;
if (head >= (cmdMax - cmdStart) || (head & 03)) {
- printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", __LINE__, cmd, head);
- printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", __LINE__, cmdMax, cmdStart);
+ printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n",
+ __LINE__, cmd, head);
+ printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n",
+ __LINE__, cmdMax, cmdStart);
return;
}
if (bytecmd) {
@@ -1770,7 +1779,7 @@ static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
{
unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
- INPCK | ISTRIP|IXON|IXANY|IXOFF);
+ INPCK | ISTRIP | IXON | IXANY | IXOFF);
if (ch->digiext.digi_flags & DIGI_AIXON)
res |= IAIXON;
return res;
@@ -1838,7 +1847,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
unsigned mval, hflow, cflag, iflag;
bc = ch->brdchan;
- epcaassert(bc !=0, "bc out of range");
+ epcaassert(bc != NULL, "bc out of range");
assertgwinon(ch);
ts = tty->termios;
@@ -1884,8 +1893,10 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
* Command sets channels iflag structure on the board. Such
* things as input soft flow control, handling of parity
* errors, and break handling are all set here.
+ *
+ * break handling, parity handling, input stripping,
+ * flow control chars
*/
- /* break handling, parity handling, input stripping, flow control chars */
fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
}
/*
@@ -1981,7 +1992,7 @@ static void receive_data(struct channel *ch)
return;
/* If CREAD bit is off or device not open, set TX tail to head */
- if (!tty || !ts || !(ts->c_cflag & CREAD)) {
+ if (!tty || !ts || !(ts->c_cflag & CREAD)) {
writew(head, &bc->rout);
return;
}
@@ -1991,18 +2002,21 @@ static void receive_data(struct channel *ch)
if (readb(&bc->orun)) {
writeb(0, &bc->orun);
- printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name);
+ printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",
+ tty->name);
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
rxwinon(ch);
- while (bytesAvailable > 0) { /* Begin while there is data on the card */
+ while (bytesAvailable > 0) {
+ /* Begin while there is data on the card */
wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
/*
* Even if head has wrapped around only report the amount of
* data to be equal to the size - tail. Remember memcpy can't
* automaticly wrap around the receive buffer.
*/
- dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable;
+ dataToRead = (wrapgap < bytesAvailable) ? wrapgap
+ : bytesAvailable;
/* Make sure we don't overflow the buffer */
dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
if (dataToRead == 0)
@@ -2153,14 +2167,14 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file,
* The below routine generally sets up parity, baud, flow control
* issues, etc.... It effect both control flags and input flags.
*/
- epcaparam(tty,ch);
+ epcaparam(tty, ch);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
return 0;
}
-static int pc_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int pc_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
digiflow_t dflow;
int retval;
@@ -2175,7 +2189,6 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
bc = ch->brdchan;
else
return -EINVAL;
-
/*
* For POSIX compliance we need to add more ioctls. See tty_ioctl.c in
* /usr/src/linux/drivers/char for a good example. In particular think
@@ -2186,9 +2199,10 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
retval = tty_check_change(tty);
if (retval)
return retval;
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit
+ buffer empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
if (!arg)
@@ -2198,29 +2212,14 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
retval = tty_check_change(tty);
if (retval)
return retval;
-
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit buffer
+ empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
return 0;
- case TIOCGSOFTCAR:
- if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))
- return -EFAULT;
- return 0;
- case TIOCSSOFTCAR:
- {
- unsigned int value;
-
- if (get_user(value, (unsigned __user *)argp))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (value ? CLOCAL : 0));
- return 0;
- }
case TIOCMODG:
mflag = pc_tiocmget(tty, file);
if (put_user(mflag, (unsigned long __user *)argp))
@@ -2253,10 +2252,12 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
break;
case DIGI_SETAW:
case DIGI_SETAF:
+ lock_kernel();
if (cmd == DIGI_SETAW) {
- /* Setup an event to indicate when the transmit buffer empties */
+ /* Setup an event to indicate when the transmit
+ buffer empties */
spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
+ setup_empty_event(tty, ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wait_until_sent(tty, 0);
} else {
@@ -2264,6 +2265,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
}
+ unlock_kernel();
/* Fall Thru */
case DIGI_SETA:
if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
@@ -2285,7 +2287,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
* control issues, etc.... It effect both control flags and
* input flags.
*/
- epcaparam(tty,ch);
+ epcaparam(tty, ch);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
break;
@@ -2321,18 +2323,21 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
if (copy_from_user(&dflow, argp, sizeof(dflow)))
return -EFAULT;
- if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */
+ if (dflow.startc != startc || dflow.stopc != stopc) {
+ /* Begin if setflow toggled */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
if (cmd == DIGI_SETFLOW) {
ch->fepstartc = ch->startc = dflow.startc;
ch->fepstopc = ch->stopc = dflow.stopc;
- fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
+ fepcmd(ch, SONOFFC, ch->fepstartc,
+ ch->fepstopc, 0, 1);
} else {
ch->fepstartca = ch->startca = dflow.startc;
ch->fepstopca = ch->stopca = dflow.stopc;
- fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
+ fepcmd(ch, SAUXONOFFC, ch->fepstartca,
+ ch->fepstopca, 0, 1);
}
if (ch->statusflags & TXSTOPPED)
@@ -2356,7 +2361,9 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
+ ch = verifyChannel(tty);
+
+ if (ch != NULL) { /* Begin if channel valid */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
epcaparam(tty, ch);
@@ -2383,7 +2390,7 @@ static void do_softint(struct work_struct *work)
if (tty && tty->driver_data) {
if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
- tty_hangup(tty); /* FIXME: module removal race here - AKPM */
+ tty_hangup(tty);
wake_up_interruptible(&ch->open_wait);
ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
}
@@ -2403,9 +2410,11 @@ static void pc_stop(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
- if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */
+ if ((ch->statusflags & TXSTOPPED) == 0) {
+ /* Begin if transmit stop requested */
globalwinon(ch);
/* STOP transmitting now !! */
fepcmd(ch, PAUSETX, 0, 0, 0, 0);
@@ -2423,11 +2432,14 @@ static void pc_start(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
- /* Just in case output was resumed because of a change in Digi-flow */
- if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */
+ /* Just in case output was resumed because of a change
+ in Digi-flow */
+ if (ch->statusflags & TXSTOPPED) {
+ /* Begin transmit resume requested */
struct board_chan __iomem *bc;
globalwinon(ch);
bc = ch->brdchan;
@@ -2457,7 +2469,8 @@ static void pc_throttle(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if ((ch->statusflags & RXSTOPPED) == 0) {
globalwinon(ch);
@@ -2477,8 +2490,10 @@ static void pc_unthrottle(struct tty_struct *tty)
* verifyChannel returns the channel from the tty struct if it is
* valid. This serves as a sanity check.
*/
- if ((ch = verifyChannel(tty)) != NULL) {
- /* Just in case output was resumed because of a change in Digi-flow */
+ ch = verifyChannel(tty);
+ if (ch != NULL) {
+ /* Just in case output was resumed because of a change
+ in Digi-flow */
spin_lock_irqsave(&epca_lock, flags);
if (ch->statusflags & RXSTOPPED) {
globalwinon(ch);
@@ -2490,7 +2505,7 @@ static void pc_unthrottle(struct tty_struct *tty)
}
}
-void digi_send_break(struct channel *ch, int msec)
+static void digi_send_break(struct channel *ch, int msec)
{
unsigned long flags;
@@ -2523,7 +2538,7 @@ static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
memoff(ch);
}
-void epca_setup(char *str, int *ints)
+static void epca_setup(char *str, int *ints)
{
struct board_info board;
int index, loop, last;
@@ -2552,14 +2567,16 @@ void epca_setup(char *str, int *ints)
* instructing the driver to ignore epcaconfig.) For
* this reason we check for 2.
*/
- if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */
+ if (board.status == 2) {
+ /* Begin ignore epcaconfig as well as lilo cmd line */
nbdevs = 0;
num_cards = 0;
return;
} /* End ignore epcaconfig as well as lilo cmd line */
if (board.status > 2) {
- printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status);
+ printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n",
+ board.status);
invalid_lilo_config = 1;
setup_error_code |= INVALID_BOARD_STATUS;
return;
@@ -2613,7 +2630,8 @@ void epca_setup(char *str, int *ints)
case 6:
board.membase = ints[index];
if (ints[index] <= 0) {
- printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
+ printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",
+ (unsigned int)board.membase);
invalid_lilo_config = 1;
setup_error_code |= INVALID_MEM_BASE;
return;
@@ -2744,7 +2762,7 @@ void epca_setup(char *str, int *ints)
t2++;
if (*t2) {
- printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str);
+ printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str);
invalid_lilo_config = 1;
setup_error_code |= INVALID_MEM_BASE;
return;
@@ -2766,7 +2784,7 @@ void epca_setup(char *str, int *ints)
/* I should REALLY validate the stuff here */
/* Copies our local copy of board into boards */
- memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board));
+ memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board));
/* Does this get called once per lilo arg are what ? */
printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
num_cards, board_desc[board.type],
@@ -2807,9 +2825,9 @@ static int __devinit epca_init_one(struct pci_dev *pdev,
if (board_idx >= MAXBOARDS)
goto err_out;
- addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx);
+ addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx);
if (!addr) {
- printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n",
+ printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n",
epca_info_tbl[info_idx].bar_idx);
goto err_out;
}
@@ -2820,28 +2838,29 @@ static int __devinit epca_init_one(struct pci_dev *pdev,
boards[board_idx].port = addr + PCI_IO_OFFSET;
boards[board_idx].membase = addr;
- if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) {
- printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
+ if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) {
+ printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out;
}
- boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000);
+ boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET,
+ 0x200000);
if (!boards[board_idx].re_map_port) {
- printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
+ printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out_free_pciio;
}
- if (!request_mem_region (addr, 0x200000, "epca")) {
- printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
+ if (!request_mem_region(addr, 0x200000, "epca")) {
+ printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
0x200000, addr);
goto err_out_free_iounmap;
}
- boards[board_idx].re_map_membase = ioremap(addr, 0x200000);
+ boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000);
if (!boards[board_idx].re_map_membase) {
- printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
+ printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
0x200000, addr + PCI_IO_OFFSET);
goto err_out_free_memregion;
}
@@ -2858,11 +2877,11 @@ static int __devinit epca_init_one(struct pci_dev *pdev,
return 0;
err_out_free_memregion:
- release_mem_region (addr, 0x200000);
+ release_mem_region(addr, 0x200000);
err_out_free_iounmap:
- iounmap (boards[board_idx].re_map_port);
+ iounmap(boards[board_idx].re_map_port);
err_out_free_pciio:
- release_mem_region (addr + PCI_IO_OFFSET, 0x200000);
+ release_mem_region(addr + PCI_IO_OFFSET, 0x200000);
err_out:
return -ENODEV;
}
@@ -2878,9 +2897,9 @@ static struct pci_device_id epca_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
-int __init init_PCI (void)
+static int __init init_PCI(void)
{
- memset (&epca_driver, 0, sizeof (epca_driver));
+ memset(&epca_driver, 0, sizeof(epca_driver));
epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl;
epca_driver.probe = epca_init_one;
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index f3fe6206734..84840ba13ff 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -8,7 +8,7 @@
* Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now
* much more extensible to support other serial cards based on the
* 16450/16550A UART's. Added support for the AST FourPort and the
- * Accent Async board.
+ * Accent Async board.
*
* set_serial_info fixed to set the flags, custom divisor, and uart
* type fields. Fix suggested by Michael K. Johnson 12/12/92.
@@ -61,11 +61,11 @@
#include <linux/bitops.h>
#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/dma.h>
#include <linux/slab.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/hayesesp.h>
@@ -127,8 +127,10 @@ static struct tty_driver *esp_driver;
#undef SERIAL_DEBUG_FLOW
#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- tty->name, (info->flags), serial_driver.refcount,info->count,tty->count,s)
+#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ tty->name, info->flags, \
+ serial_driver.refcount, \
+ info->count, tty->count, s)
#else
#define DBG_CNT(s)
#endif
@@ -189,7 +191,7 @@ static inline void serial_out(struct esp_struct *info, int offset,
*/
static void rs_stop(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_stop"))
@@ -206,12 +208,12 @@ static void rs_stop(struct tty_struct *tty)
static void rs_start(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
-
+
if (serial_paranoia_check(info, tty->name, "rs_start"))
return;
-
+
spin_lock_irqsave(&info->lock, flags);
if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
info->IER |= UART_IER_THRI;
@@ -233,7 +235,7 @@ static void rs_start(struct tty_struct *tty)
* rs_interrupt() should try to keep the interrupt handler as fast as
* possible. After you are done making modifications, it is not a bad
* idea to do:
- *
+ *
* gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
*
* and look at the resulting assemble code in serial.s.
@@ -290,7 +292,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
}
status_mask = (info->read_status_mask >> 2) & 0x07;
-
+
for (i = 0; i < num_bytes - 1; i += 2) {
*((unsigned short *)(pio_buf->data + i)) =
inw(info->port + UART_ESI_RX);
@@ -325,8 +327,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
flag = TTY_BREAK;
if (info->flags & ASYNC_SAK)
do_SAK(tty);
- }
- else if (err_buf->data[i] & 0x02)
+ } else if (err_buf->data[i] & 0x02)
flag = TTY_FRAME;
else if (err_buf->data[i] & 0x01)
flag = TTY_PARITY;
@@ -341,23 +342,29 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
release_pio_buffer(err_buf);
}
-static inline void receive_chars_dma(struct esp_struct *info, int num_bytes)
+static void program_isa_dma(int dma, int dir, unsigned long addr, int len)
{
unsigned long flags;
+
+ flags = claim_dma_lock();
+ disable_dma(dma);
+ clear_dma_ff(dma);
+ set_dma_mode(dma, dir);
+ set_dma_addr(dma, addr);
+ set_dma_count(dma, len);
+ enable_dma(dma);
+ release_dma_lock(flags);
+}
+
+static void receive_chars_dma(struct esp_struct *info, int num_bytes)
+{
info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
dma_bytes = num_bytes;
info->stat_flags |= ESP_STAT_DMA_RX;
-
- flags=claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, DMA_MODE_READ);
- set_dma_addr(dma, isa_virt_to_bus(dma_buffer));
- set_dma_count(dma, dma_bytes);
- enable_dma(dma);
- release_dma_lock(flags);
-
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
+
+ program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer),
+ dma_bytes);
+ serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
}
static inline void receive_chars_dma_done(struct esp_struct *info,
@@ -366,22 +373,22 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
struct tty_struct *tty = info->tty;
int num_bytes;
unsigned long flags;
-
- flags=claim_dma_lock();
+
+ flags = claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
info->stat_flags &= ~ESP_STAT_DMA_RX;
num_bytes = dma_bytes - get_dma_residue(dma);
release_dma_lock(flags);
-
+
info->icount.rx += num_bytes;
if (num_bytes > 0) {
tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
status &= (0x1c & info->read_status_mask);
-
+
/* Is the status significant or do we throw the last byte ? */
if (!(status & info->ignore_status_mask)) {
int statflag = 0;
@@ -393,13 +400,13 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
do_SAK(tty);
} else if (status & 0x08) {
statflag = TTY_FRAME;
- (info->icount.frame)++;
- }
- else if (status & 0x04) {
+ info->icount.frame++;
+ } else if (status & 0x04) {
statflag = TTY_PARITY;
- (info->icount.parity)++;
+ info->icount.parity++;
}
- tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag);
+ tty_insert_flip_char(tty, dma_buffer[num_bytes - 1],
+ statflag);
}
tty_schedule_flip(tty);
}
@@ -484,8 +491,6 @@ static inline void transmit_chars_pio(struct esp_struct *info,
/* Caller must hold info->lock */
static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
{
- unsigned long flags;
-
dma_bytes = num_bytes;
if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
@@ -517,26 +522,18 @@ static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
}
info->stat_flags |= ESP_STAT_DMA_TX;
-
- flags=claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, DMA_MODE_WRITE);
- set_dma_addr(dma, isa_virt_to_bus(dma_buffer));
- set_dma_count(dma, dma_bytes);
- enable_dma(dma);
- release_dma_lock(flags);
-
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
+
+ program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer),
+ dma_bytes);
+ serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
}
static inline void transmit_chars_dma_done(struct esp_struct *info)
{
int num_bytes;
unsigned long flags;
-
- flags=claim_dma_lock();
+ flags = claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
@@ -547,27 +544,21 @@ static inline void transmit_chars_dma_done(struct esp_struct *info)
if (dma_bytes != num_bytes) {
dma_bytes -= num_bytes;
memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes);
-
- flags=claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, DMA_MODE_WRITE);
- set_dma_addr(dma, isa_virt_to_bus(dma_buffer));
- set_dma_count(dma, dma_bytes);
- enable_dma(dma);
- release_dma_lock(flags);
-
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
+
+ program_isa_dma(dma, DMA_MODE_WRITE,
+ isa_virt_to_bus(dma_buffer), dma_bytes);
+
+ serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
} else {
dma_bytes = 0;
info->stat_flags &= ~ESP_STAT_DMA_TX;
}
}
-static inline void check_modem_status(struct esp_struct *info)
+static void check_modem_status(struct esp_struct *info)
{
int status;
-
+
serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
status = serial_in(info, UART_ESI_STAT2);
@@ -588,7 +579,7 @@ static inline void check_modem_status(struct esp_struct *info)
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
printk("ttys%d CD now %s...", info->line,
(status & UART_MSR_DCD) ? "on" : "off");
-#endif
+#endif
if (status & UART_MSR_DCD)
wake_up_interruptible(&info->open_wait);
else {
@@ -605,7 +596,7 @@ static inline void check_modem_status(struct esp_struct *info)
*/
static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
{
- struct esp_struct * info;
+ struct esp_struct *info;
unsigned err_status;
unsigned int scratch;
@@ -617,7 +608,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
scratch = serial_in(info, UART_ESI_SID);
spin_lock(&info->lock);
-
+
if (!info->tty) {
spin_unlock(&info->lock);
return IRQ_NONE;
@@ -637,7 +628,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
if (err_status & 0x80) /* Start break */
wake_up_interruptible(&info->break_wait);
}
-
+
if ((scratch & 0x88) || /* DMA completed or timed out */
(err_status & 0x1c) /* receive error */) {
if (info->stat_flags & ESP_STAT_DMA_RX)
@@ -667,7 +658,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
receive_chars_dma(info, num_bytes);
}
}
-
+
if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
(scratch & 0x02) && (info->IER & UART_IER_THRI)) {
if ((info->xmit_cnt <= 0) || info->tty->stopped) {
@@ -722,11 +713,11 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
* ---------------------------------------------------------------
*/
-static inline void esp_basic_init(struct esp_struct * info)
+static void esp_basic_init(struct esp_struct *info)
{
/* put ESPC in enhanced mode */
serial_out(info, UART_ESI_CMD1, ESI_SET_MODE);
-
+
if (info->stat_flags & ESP_STAT_NEVER_DMA)
serial_out(info, UART_ESI_CMD2, 0x01);
else
@@ -783,13 +774,13 @@ static inline void esp_basic_init(struct esp_struct * info)
serial_out(info, UART_ESI_CMD2, 0xff);
}
-static int startup(struct esp_struct * info)
+static int startup(struct esp_struct *info)
{
unsigned long flags;
- int retval=0;
- unsigned int num_chars;
+ int retval = 0;
+ unsigned int num_chars;
- spin_lock_irqsave(&info->lock, flags);
+ spin_lock_irqsave(&info->lock, flags);
if (info->flags & ASYNC_INITIALIZED)
goto out;
@@ -802,7 +793,8 @@ static int startup(struct esp_struct * info)
}
#ifdef SERIAL_DEBUG_OPEN
- printk("starting up ttys%d (irq %d)...", info->line, info->irq);
+ printk(KERN_DEBUG "starting up ttys%d (irq %d)...",
+ info->line, info->irq);
#endif
/* Flush the RX buffer. Using the ESI flush command may cause */
@@ -863,7 +855,7 @@ static int startup(struct esp_struct * info)
dma_buffer = NULL;
info->stat_flags |= ESP_STAT_USE_PIO;
}
-
+
}
info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
@@ -872,7 +864,7 @@ static int startup(struct esp_struct * info)
serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
serial_out(info, UART_ESI_CMD2, UART_MCR);
serial_out(info, UART_ESI_CMD2, info->MCR);
-
+
/*
* Finally, enable interrupts
*/
@@ -881,7 +873,7 @@ static int startup(struct esp_struct * info)
UART_IER_DMA_TC;
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
serial_out(info, UART_ESI_CMD2, info->IER);
-
+
if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
@@ -900,7 +892,7 @@ static int startup(struct esp_struct * info)
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
info->tty->alt_speed = 460800;
}
-
+
/*
* set the speed of the serial port
*/
@@ -918,7 +910,7 @@ out_unlocked:
* This routine will shutdown a serial port; interrupts are disabled, and
* DTR is dropped if the hangup on close termio flag is on.
*/
-static void shutdown(struct esp_struct * info)
+static void shutdown(struct esp_struct *info)
{
unsigned long flags, f;
@@ -929,7 +921,7 @@ static void shutdown(struct esp_struct * info)
printk("Shutting down serial port %d (irq %d)....", info->line,
info->irq);
#endif
-
+
spin_lock_irqsave(&info->lock, flags);
/*
* clear delta_msr_wait queue to avoid mem leaks: we may free the irq
@@ -941,14 +933,14 @@ static void shutdown(struct esp_struct * info)
/* stop a DMA transfer on the port being closed */
/* DMA lock is higher priority always */
if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) {
- f=claim_dma_lock();
+ f = claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
release_dma_lock(f);
-
+
dma_bytes = 0;
}
-
+
/*
* Free the IRQ
*/
@@ -970,7 +962,7 @@ static void shutdown(struct esp_struct * info)
free_pages((unsigned long)dma_buffer,
get_order(DMA_BUFFER_SZ));
dma_buffer = NULL;
- }
+ }
}
if (info->xmit_buf) {
@@ -992,7 +984,7 @@ static void shutdown(struct esp_struct * info)
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
-
+
info->flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&info->lock, flags);
}
@@ -1005,7 +997,7 @@ static void change_speed(struct esp_struct *info)
{
unsigned short port;
int quot = 0;
- unsigned cflag,cval;
+ unsigned cflag, cval;
int baud, bits;
unsigned char flow1 = 0, flow2 = 0;
unsigned long flags;
@@ -1014,14 +1006,14 @@ static void change_speed(struct esp_struct *info)
return;
cflag = info->tty->termios->c_cflag;
port = info->port;
-
+
/* byte size and parity */
switch (cflag & CSIZE) {
- case CS5: cval = 0x00; bits = 7; break;
- case CS6: cval = 0x01; bits = 8; break;
- case CS7: cval = 0x02; bits = 9; break;
- case CS8: cval = 0x03; bits = 10; break;
- default: cval = 0x00; bits = 7; break;
+ case CS5: cval = 0x00; bits = 7; break;
+ case CS6: cval = 0x01; bits = 8; break;
+ case CS7: cval = 0x02; bits = 9; break;
+ case CS8: cval = 0x03; bits = 10; break;
+ default: cval = 0x00; bits = 7; break;
}
if (cflag & CSTOPB) {
cval |= 0x04;
@@ -1037,14 +1029,12 @@ static void change_speed(struct esp_struct *info)
if (cflag & CMSPAR)
cval |= UART_LCR_SPAR;
#endif
-
baud = tty_get_baud_rate(info->tty);
if (baud == 38400 &&
- ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
quot = info->custom_divisor;
else {
- if (baud == 134)
- /* Special case since 134 is really 134.5 */
+ if (baud == 134) /* Special case since 134 is really 134.5 */
quot = (2*BASE_BAUD / 269);
else if (baud)
quot = BASE_BAUD / baud;
@@ -1052,7 +1042,12 @@ static void change_speed(struct esp_struct *info)
/* If the quotient is ever zero, default to 9600 bps */
if (!quot)
quot = BASE_BAUD / 9600;
-
+
+ if (baud) {
+ /* Actual rate */
+ baud = BASE_BAUD/quot;
+ tty_encode_baud_rate(info->tty, baud, baud);
+ }
info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
/* CTS flow control flag and modem status interrupts */
@@ -1066,10 +1061,8 @@ static void change_speed(struct esp_struct *info)
info->flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
info->flags &= ~ASYNC_CHECK_CD;
- else {
+ else
info->flags |= ASYNC_CHECK_CD;
- /* info->IER |= UART_IER_MSI; */
- }
/*
* Set up parity check flag
@@ -1079,7 +1072,7 @@ static void change_speed(struct esp_struct *info)
info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
info->read_status_mask |= UART_LSR_BI;
-
+
info->ignore_status_mask = 0;
#if 0
/* This should be safe, but for some broken bits of hardware... */
@@ -1092,7 +1085,7 @@ static void change_speed(struct esp_struct *info)
info->ignore_status_mask |= UART_LSR_BI;
info->read_status_mask |= UART_LSR_BI;
/*
- * If we're ignore parity and break indicators, ignore
+ * If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
if (I_IGNPAR(info->tty)) {
@@ -1130,19 +1123,19 @@ static void change_speed(struct esp_struct *info)
serial_out(info, UART_ESI_CMD2, 0x10);
serial_out(info, UART_ESI_CMD2, 0x21);
switch (cflag & CSIZE) {
- case CS5:
- serial_out(info, UART_ESI_CMD2, 0x1f);
- break;
- case CS6:
- serial_out(info, UART_ESI_CMD2, 0x3f);
- break;
- case CS7:
- case CS8:
- serial_out(info, UART_ESI_CMD2, 0x7f);
- break;
- default:
- serial_out(info, UART_ESI_CMD2, 0xff);
- break;
+ case CS5:
+ serial_out(info, UART_ESI_CMD2, 0x1f);
+ break;
+ case CS6:
+ serial_out(info, UART_ESI_CMD2, 0x3f);
+ break;
+ case CS7:
+ case CS8:
+ serial_out(info, UART_ESI_CMD2, 0x7f);
+ break;
+ default:
+ serial_out(info, UART_ESI_CMD2, 0xff);
+ break;
}
}
@@ -1156,31 +1149,34 @@ static void change_speed(struct esp_struct *info)
spin_unlock_irqrestore(&info->lock, flags);
}
-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+static int rs_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
+ int ret = 0;
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
- return;
+ return 0;
if (!info->xmit_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->lock, flags);
if (info->xmit_cnt < ESP_XMIT_SIZE - 1) {
info->xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= ESP_XMIT_SIZE-1;
info->xmit_cnt++;
+ ret = 1;
}
spin_unlock_irqrestore(&info->lock, flags);
+ return ret;
}
static void rs_flush_chars(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
-
+
if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
return;
@@ -1198,11 +1194,11 @@ out:
spin_unlock_irqrestore(&info->lock, flags);
}
-static int rs_write(struct tty_struct * tty,
+static int rs_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
int c, t, ret = 0;
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_write"))
@@ -1210,19 +1206,19 @@ static int rs_write(struct tty_struct * tty,
if (!info->xmit_buf)
return 0;
-
+
while (1) {
/* Thanks to R. Wolff for suggesting how to do this with */
/* interrupts enabled */
c = count;
t = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-
+
if (t < c)
c = t;
t = ESP_XMIT_SIZE - info->xmit_head;
-
+
if (t < c)
c = t;
@@ -1252,10 +1248,10 @@ static int rs_write(struct tty_struct * tty,
static int rs_write_room(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
int ret;
unsigned long flags;
-
+
if (serial_paranoia_check(info, tty->name, "rs_write_room"))
return 0;
@@ -1270,8 +1266,8 @@ static int rs_write_room(struct tty_struct *tty)
static int rs_chars_in_buffer(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
-
+ struct esp_struct *info = tty->driver_data;
+
if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
return 0;
return info->xmit_cnt;
@@ -1279,9 +1275,9 @@ static int rs_chars_in_buffer(struct tty_struct *tty)
static void rs_flush_buffer(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
-
+
if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
return;
spin_lock_irqsave(&info->lock, flags);
@@ -1293,20 +1289,20 @@ static void rs_flush_buffer(struct tty_struct *tty)
/*
* ------------------------------------------------------------
* rs_throttle()
- *
+ *
* This routine is called by the upper-layer tty layer to signal that
* incoming characters should be throttled.
* ------------------------------------------------------------
*/
-static void rs_throttle(struct tty_struct * tty)
+static void rs_throttle(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
-
+
printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
+ tty_chars_in_buffer(tty));
#endif
if (serial_paranoia_check(info, tty->name, "rs_throttle"))
@@ -1321,20 +1317,20 @@ static void rs_throttle(struct tty_struct * tty)
spin_unlock_irqrestore(&info->lock, flags);
}
-static void rs_unthrottle(struct tty_struct * tty)
+static void rs_unthrottle(struct tty_struct *tty)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
-
- printk("unthrottle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
+
+ printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf),
+ tty_chars_in_buffer(tty));
#endif
if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
return;
-
+
spin_lock_irqsave(&info->lock, flags);
info->IER |= UART_IER_RDI;
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
@@ -1350,11 +1346,12 @@ static void rs_unthrottle(struct tty_struct * tty)
* ------------------------------------------------------------
*/
-static int get_serial_info(struct esp_struct * info,
+static int get_serial_info(struct esp_struct *info,
struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
-
+
+ lock_kernel();
memset(&tmp, 0, sizeof(tmp));
tmp.type = PORT_16550A;
tmp.line = info->line;
@@ -1367,20 +1364,22 @@ static int get_serial_info(struct esp_struct * info,
tmp.closing_wait = info->closing_wait;
tmp.custom_divisor = info->custom_divisor;
tmp.hub6 = 0;
- if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+ unlock_kernel();
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
return 0;
}
-static int get_esp_config(struct esp_struct * info,
+static int get_esp_config(struct esp_struct *info,
struct hayes_esp_config __user *retinfo)
{
struct hayes_esp_config tmp;
-
+
if (!retinfo)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
+ lock_kernel();
tmp.rx_timeout = info->config.rx_timeout;
tmp.rx_trigger = info->config.rx_trigger;
tmp.tx_trigger = info->config.tx_trigger;
@@ -1388,11 +1387,12 @@ static int get_esp_config(struct esp_struct * info,
tmp.flow_on = info->config.flow_on;
tmp.pio_threshold = info->config.pio_threshold;
tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma);
+ unlock_kernel();
return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
}
-static int set_serial_info(struct esp_struct * info,
+static int set_serial_info(struct esp_struct *info,
struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
@@ -1401,7 +1401,7 @@ static int set_serial_info(struct esp_struct * info,
int retval = 0;
struct esp_struct *current_async;
- if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
return -EFAULT;
old_info = *info;
@@ -1422,7 +1422,7 @@ static int set_serial_info(struct esp_struct * info,
return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) {
- if (change_irq ||
+ if (change_irq ||
(new_serial.close_delay != info->close_delay) ||
((new_serial.flags & ~ASYNC_USR_MASK) !=
(info->flags & ~ASYNC_USR_MASK)))
@@ -1507,8 +1507,8 @@ static int set_serial_info(struct esp_struct * info,
return retval;
}
-static int set_esp_config(struct esp_struct * info,
- struct hayes_esp_config __user * new_info)
+static int set_esp_config(struct esp_struct *info,
+ struct hayes_esp_config __user *new_info)
{
struct hayes_esp_config new_config;
unsigned int change_dma;
@@ -1550,7 +1550,6 @@ static int set_esp_config(struct esp_struct * info,
if (new_config.dma_channel) {
/* PIO mode to DMA mode transition OR */
/* change current DMA channel */
-
current_async = ports;
while (current_async) {
@@ -1559,16 +1558,15 @@ static int set_esp_config(struct esp_struct * info,
return -EBUSY;
} else if (current_async->count)
return -EBUSY;
-
- current_async =
- current_async->next_port;
+
+ current_async = current_async->next_port;
}
shutdown(info);
dma = new_config.dma_channel;
info->stat_flags &= ~ESP_STAT_NEVER_DMA;
-
- /* all ports must use the same DMA channel */
+
+ /* all ports must use the same DMA channel */
spin_lock_irqsave(&info->lock, flags);
current_async = ports;
@@ -1580,7 +1578,6 @@ static int set_esp_config(struct esp_struct * info,
spin_unlock_irqrestore(&info->lock, flags);
} else {
/* DMA mode to PIO mode only */
-
if (info->count > 1)
return -EBUSY;
@@ -1596,8 +1593,6 @@ static int set_esp_config(struct esp_struct * info,
if ((new_config.flow_off != info->config.flow_off) ||
(new_config.flow_on != info->config.flow_on)) {
- unsigned long flags;
-
info->config.flow_off = new_config.flow_off;
info->config.flow_on = new_config.flow_on;
@@ -1612,8 +1607,6 @@ static int set_esp_config(struct esp_struct * info,
if ((new_config.rx_trigger != info->config.rx_trigger) ||
(new_config.tx_trigger != info->config.tx_trigger)) {
- unsigned long flags;
-
info->config.rx_trigger = new_config.rx_trigger;
info->config.tx_trigger = new_config.tx_trigger;
spin_lock_irqsave(&info->lock, flags);
@@ -1628,8 +1621,6 @@ static int set_esp_config(struct esp_struct * info,
}
if (new_config.rx_timeout != info->config.rx_timeout) {
- unsigned long flags;
-
info->config.rx_timeout = new_config.rx_timeout;
spin_lock_irqsave(&info->lock, flags);
@@ -1657,9 +1648,9 @@ static int set_esp_config(struct esp_struct * info,
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
+ * allows an RS485 driver to be written in user space.
*/
-static int get_lsr_info(struct esp_struct * info, unsigned int __user *value)
+static int get_lsr_info(struct esp_struct *info, unsigned int __user *value)
{
unsigned char status;
unsigned int result;
@@ -1670,17 +1661,17 @@ static int get_lsr_info(struct esp_struct * info, unsigned int __user *value)
status = serial_in(info, UART_ESI_STAT1);
spin_unlock_irqrestore(&info->lock, flags);
result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- return put_user(result,value);
+ return put_user(result, value);
}
static int esp_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned char control, status;
unsigned long flags;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
@@ -1703,10 +1694,10 @@ static int esp_tiocmget(struct tty_struct *tty, struct file *file)
static int esp_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
@@ -1736,9 +1727,9 @@ static int esp_tiocmset(struct tty_struct *tty, struct file *file,
*/
static void esp_break(struct tty_struct *tty, int break_state)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
-
+
if (serial_paranoia_check(info, tty->name, "esp_break"))
return;
@@ -1758,14 +1749,15 @@ static void esp_break(struct tty_struct *tty, int break_state)
}
}
-static int rs_ioctl(struct tty_struct *tty, struct file * file,
+static int rs_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
struct async_icount cprev, cnow; /* kernel counter temps */
struct serial_icounter_struct __user *p_cuser; /* user space */
void __user *argp = (void __user *)arg;
unsigned long flags;
+ int ret;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
@@ -1778,97 +1770,93 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
}
-
- switch (cmd) {
- case TIOCGSERIAL:
- return get_serial_info(info, argp);
- case TIOCSSERIAL:
- return set_serial_info(info, argp);
- case TIOCSERCONFIG:
- /* do not reconfigure after initial configuration */
- return 0;
-
- case TIOCSERGWILD:
- return put_user(0L, (unsigned long __user *)argp);
- case TIOCSERGETLSR: /* Get line status register */
- return get_lsr_info(info, argp);
-
- case TIOCSERSWILD:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return 0;
-
- /*
- * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
- * - mask passed in arg for lines of interest
- * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
- * Caller should use TIOCGICOUNT to see which one it was
- */
- case TIOCMIWAIT:
+ switch (cmd) {
+ case TIOCGSERIAL:
+ return get_serial_info(info, argp);
+ case TIOCSSERIAL:
+ lock_kernel();
+ ret = set_serial_info(info, argp);
+ unlock_kernel();
+ return ret;
+ case TIOCSERGWILD:
+ return put_user(0L, (unsigned long __user *)argp);
+ case TIOCSERGETLSR: /* Get line status register */
+ return get_lsr_info(info, argp);
+ case TIOCSERSWILD:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return 0;
+ /*
+ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+ * - mask passed in arg for lines of interest
+ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+ * Caller should use TIOCGICOUNT to see which one it was
+ */
+ case TIOCMIWAIT:
+ spin_lock_irqsave(&info->lock, flags);
+ cprev = info->icount; /* note the counters on entry */
+ spin_unlock_irqrestore(&info->lock, flags);
+ while (1) {
+ /* FIXME: convert to new style wakeup */
+ interruptible_sleep_on(&info->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
spin_lock_irqsave(&info->lock, flags);
- cprev = info->icount; /* note the counters on entry */
+ cnow = info->icount; /* atomic copy */
spin_unlock_irqrestore(&info->lock, flags);
- while (1) {
- /* FIXME: convert to new style wakeup */
- interruptible_sleep_on(&info->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- spin_lock_irqsave(&info->lock, flags);
- cnow = info->icount; /* atomic copy */
- spin_unlock_irqrestore(&info->lock, flags);
- if (cnow.rng == cprev.rng &&
- cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd &&
- cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
- if (((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts)) ) {
- return 0;
- }
- cprev = cnow;
+ if (cnow.rng == cprev.rng &&
+ cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd &&
+ cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) &&
+ (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) &&
+ (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) &&
+ (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) &&
+ (cnow.cts != cprev.cts))) {
+ return 0;
}
- /* NOTREACHED */
-
- /*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
- case TIOCGICOUNT:
- spin_lock_irqsave(&info->lock, flags);
- cnow = info->icount;
- spin_unlock_irqrestore(&info->lock, flags);
- p_cuser = argp;
- if (put_user(cnow.cts, &p_cuser->cts) ||
- put_user(cnow.dsr, &p_cuser->dsr) ||
- put_user(cnow.rng, &p_cuser->rng) ||
- put_user(cnow.dcd, &p_cuser->dcd))
- return -EFAULT;
-
+ cprev = cnow;
+ }
+ /* NOTREACHED */
+ /*
+ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+ * Return: write counters to the user passed counter struct
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+ case TIOCGICOUNT:
+ spin_lock_irqsave(&info->lock, flags);
+ cnow = info->icount;
+ spin_unlock_irqrestore(&info->lock, flags);
+ p_cuser = argp;
+ if (put_user(cnow.cts, &p_cuser->cts) ||
+ put_user(cnow.dsr, &p_cuser->dsr) ||
+ put_user(cnow.rng, &p_cuser->rng) ||
+ put_user(cnow.dcd, &p_cuser->dcd))
+ return -EFAULT;
return 0;
case TIOCGHAYESESP:
return get_esp_config(info, argp);
case TIOCSHAYESESP:
- return set_esp_config(info, argp);
-
- default:
- return -ENOIOCTLCMD;
- }
+ lock_kernel();
+ ret = set_esp_config(info, argp);
+ unlock_kernel();
+ return ret;
+ default:
+ return -ENOIOCTLCMD;
+ }
return 0;
}
static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
change_speed(info);
@@ -1905,32 +1893,33 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
/*
* ------------------------------------------------------------
* rs_close()
- *
+ *
* This routine is called when the serial port gets closed. First, we
* wait for the last remaining data to be sent. Then, we unlink its
* async structure from the interrupt chain if necessary, and we free
* that IRQ if nothing is left in the chain.
* ------------------------------------------------------------
*/
-static void rs_close(struct tty_struct *tty, struct file * filp)
+static void rs_close(struct tty_struct *tty, struct file *filp)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long flags;
if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
return;
-
+
spin_lock_irqsave(&info->lock, flags);
-
+
if (tty_hung_up_p(filp)) {
DBG_CNT("before DEC-hung");
goto out;
}
-
+
#ifdef SERIAL_DEBUG_OPEN
- printk("rs_close ttys%d, count = %d\n", info->line, info->count);
+ printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
+ info->line, info->count);
#endif
- if ((tty->count == 1) && (info->count != 1)) {
+ 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
@@ -1938,12 +1927,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
- printk("rs_close: bad serial port count; tty->count is 1, "
- "info->count is %d\n", info->count);
+ printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->count is %d\n", info->count);
info->count = 1;
}
if (--info->count < 0) {
- printk("rs_close: bad serial port count for ttys%d: %d\n",
+ printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
info->line, info->count);
info->count = 0;
}
@@ -1955,7 +1943,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
spin_unlock_irqrestore(&info->lock, flags);
/*
- * Now we wait for the transmit buffer to clear; and we notify
+ * Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
@@ -1990,16 +1978,14 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
rs_wait_until_sent(tty, info->timeout);
}
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ rs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
info->tty = NULL;
if (info->blocked_open) {
- if (info->close_delay) {
+ 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);
@@ -2012,7 +1998,7 @@ out:
static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
{
- struct esp_struct *info = (struct esp_struct *)tty->driver_data;
+ struct esp_struct *info = tty->driver_data;
unsigned long orig_jiffies, char_time;
unsigned long flags;
@@ -2036,10 +2022,10 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
msleep_interruptible(jiffies_to_msecs(char_time));
if (signal_pending(current))
- break;
+ return;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
- break;
+ return;
spin_lock_irqsave(&info->lock, flags);
serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
@@ -2054,11 +2040,11 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
*/
static void esp_hangup(struct tty_struct *tty)
{
- struct esp_struct * info = (struct esp_struct *)tty->driver_data;
-
+ struct esp_struct *info = tty->driver_data;
+
if (serial_paranoia_check(info, tty->name, "esp_hangup"))
return;
-
+
rs_flush_buffer(tty);
shutdown(info);
info->count = 0;
@@ -2072,7 +2058,7 @@ static void esp_hangup(struct tty_struct *tty)
* esp_open() and friends
* ------------------------------------------------------------
*/
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
struct esp_struct *info)
{
DECLARE_WAITQUEUE(wait, current);
@@ -2121,11 +2107,11 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
retval = 0;
add_wait_queue(&info->open_wait, &wait);
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready before block: ttys%d, count = %d\n",
+ printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
info->line, info->count);
#endif
spin_lock_irqsave(&info->lock, flags);
- if (!tty_hung_up_p(filp))
+ if (!tty_hung_up_p(filp))
info->count--;
info->blocked_open++;
while (1) {
@@ -2147,7 +2133,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (info->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
#else
retval = -EAGAIN;
#endif
@@ -2166,7 +2152,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
break;
}
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready blocking: ttys%d, count = %d\n",
+ printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
info->line, info->count);
#endif
spin_unlock_irqrestore(&info->lock, flags);
@@ -2180,14 +2166,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
info->blocked_open--;
spin_unlock_irqrestore(&info->lock, flags);
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready after blocking: ttys%d, count = %d\n",
+ printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
info->line, info->count);
#endif
if (retval)
return retval;
info->flags |= ASYNC_NORMAL_ACTIVE;
return 0;
-}
+}
/*
* This routine is called whenever a serial port is opened. It
@@ -2195,7 +2181,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
* the IRQ chain. It also performs the serial-specific
* initialization for the tty structure.
*/
-static int esp_open(struct tty_struct *tty, struct file * filp)
+static int esp_open(struct tty_struct *tty, struct file *filp)
{
struct esp_struct *info;
int retval, line;
@@ -2218,7 +2204,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
}
#ifdef SERIAL_DEBUG_OPEN
- printk("esp_open %s, count = %d\n", tty->name, info->count);
+ printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->count);
#endif
spin_lock_irqsave(&info->lock, flags);
info->count++;
@@ -2226,7 +2212,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
info->tty = tty;
spin_unlock_irqrestore(&info->lock, flags);
-
+
/*
* Start up serial port
*/
@@ -2237,14 +2223,13 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
retval = block_til_ready(tty, filp, info);
if (retval) {
#ifdef SERIAL_DEBUG_OPEN
- printk("esp_open returning after block_til_ready with %d\n",
+ printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n",
retval);
#endif
return retval;
}
-
#ifdef SERIAL_DEBUG_OPEN
- printk("esp_open %s successful...", tty->name);
+ printk(KERN_DEBUG "esp_open %s successful...", tty->name);
#endif
return 0;
}
@@ -2262,10 +2247,10 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
* number, and identifies which options were configured into this
* driver.
*/
-
-static inline void show_serial_version(void)
+
+static void show_serial_version(void)
{
- printk(KERN_INFO "%s version %s (DMA %u)\n",
+ printk(KERN_INFO "%s version %s (DMA %u)\n",
serial_name, serial_version, dma);
}
@@ -2273,7 +2258,7 @@ static inline void show_serial_version(void)
* This routine is called by espserial_init() to initialize a specific serial
* port.
*/
-static inline int autoconfig(struct esp_struct * info)
+static int autoconfig(struct esp_struct *info)
{
int port_detected = 0;
unsigned long flags;
@@ -2349,14 +2334,14 @@ static const struct tty_operations esp_ops = {
static int __init espserial_init(void)
{
int i, offset;
- struct esp_struct * info;
+ struct esp_struct *info;
struct esp_struct *last_primary = NULL;
- int esp[] = {0x100,0x140,0x180,0x200,0x240,0x280,0x300,0x380};
+ int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 };
esp_driver = alloc_tty_driver(NR_PORTS);
if (!esp_driver)
return -ENOMEM;
-
+
for (i = 0; i < NR_PRIMARY; i++) {
if (irq[i] != 0) {
if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) ||
@@ -2378,20 +2363,20 @@ static int __init espserial_init(void)
if ((flow_off < 1) || (flow_off > 1023))
flow_off = 1016;
-
+
if ((flow_on < 1) || (flow_on > 1023))
flow_on = 944;
if ((rx_timeout < 0) || (rx_timeout > 255))
rx_timeout = 128;
-
+
if (flow_on >= flow_off)
flow_on = flow_off - 1;
show_serial_version();
/* Initialize the tty_driver structure */
-
+
esp_driver->owner = THIS_MODULE;
esp_driver->name = "ttyP";
esp_driver->major = ESP_IN_MAJOR;
@@ -2401,10 +2386,11 @@ static int __init espserial_init(void)
esp_driver->init_termios = tty_std_termios;
esp_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ esp_driver->init_termios.c_ispeed = 9600;
+ esp_driver->init_termios.c_ospeed = 9600;
esp_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(esp_driver, &esp_ops);
- if (tty_register_driver(esp_driver))
- {
+ if (tty_register_driver(esp_driver)) {
printk(KERN_ERR "Couldn't register esp serial driver");
put_tty_driver(esp_driver);
return 1;
@@ -2412,8 +2398,7 @@ static int __init espserial_init(void)
info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
- if (!info)
- {
+ if (!info) {
printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
tty_unregister_driver(esp_driver);
put_tty_driver(esp_driver);
@@ -2476,10 +2461,8 @@ static int __init espserial_init(void)
info->stat_flags |= ESP_STAT_NEVER_DMA;
info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
- if (!info)
- {
- printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
-
+ if (!info) {
+ printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
/* allow use of the already detected ports */
return 0;
}
@@ -2503,22 +2486,20 @@ static int __init espserial_init(void)
return 0;
}
-static void __exit espserial_exit(void)
+static void __exit espserial_exit(void)
{
int e1;
struct esp_struct *temp_async;
struct esp_pio_buffer *pio_buf;
- /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
- if ((e1 = tty_unregister_driver(esp_driver)))
- printk("SERIAL: failed to unregister serial driver (%d)\n",
- e1);
+ e1 = tty_unregister_driver(esp_driver);
+ if (e1)
+ printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1);
put_tty_driver(esp_driver);
while (ports) {
- if (ports->port) {
+ if (ports->port)
release_region(ports->port, REGION_SIZE);
- }
temp_async = ports->next_port;
kfree(ports);
ports = temp_async;
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 7ed7da1d99c..252f73e4859 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -40,27 +40,27 @@ static int gs_debug;
#define gs_dprintk(f, str...) /* nothing */
#endif
-#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__)
-#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__)
+#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__)
+#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__)
#define RS_EVENT_WRITE_WAKEUP 1
module_param(gs_debug, int, 0644);
-void gs_put_char(struct tty_struct * tty, unsigned char ch)
+int gs_put_char(struct tty_struct * tty, unsigned char ch)
{
struct gs_port *port;
func_enter ();
- if (!tty) return;
+ if (!tty) return 0;
port = tty->driver_data;
- if (!port) return;
+ if (!port) return 0;
- if (! (port->flags & ASYNC_INITIALIZED)) return;
+ if (! (port->flags & ASYNC_INITIALIZED)) return 0;
/* Take a lock on the serial tranmit buffer! */
mutex_lock(& port->port_write_mutex);
@@ -68,7 +68,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
/* Sorry, buffer is full, drop character. Update statistics???? -- REW */
mutex_unlock(&port->port_write_mutex);
- return;
+ return 0;
}
port->xmit_buf[port->xmit_head++] = ch;
@@ -77,6 +77,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
mutex_unlock(&port->port_write_mutex);
func_exit ();
+ return 1;
}
@@ -586,8 +587,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
port->flags &= ~GS_ACTIVE;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ gs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 1399971be68..e7fb0bca366 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -308,7 +308,7 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
- __FUNCTION__);
+ __func__);
return -EAGAIN;
}
@@ -748,7 +748,7 @@ int hpet_alloc(struct hpet_data *hdp)
*/
if (hpet_is_known(hdp)) {
printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
- __FUNCTION__);
+ __func__);
return 0;
}
@@ -869,7 +869,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
if (hpet_is_known(hdp)) {
printk(KERN_DEBUG "%s: 0x%lx is busy\n",
- __FUNCTION__, hdp->hd_phys_address);
+ __func__, hdp->hd_phys_address);
iounmap(hdp->hd_address);
return AE_ALREADY_EXISTS;
}
@@ -886,7 +886,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
if (hpet_is_known(hdp)) {
printk(KERN_DEBUG "%s: 0x%lx is busy\n",
- __FUNCTION__, hdp->hd_phys_address);
+ __func__, hdp->hd_phys_address);
iounmap(hdp->hd_address);
return AE_ALREADY_EXISTS;
}
@@ -925,7 +925,7 @@ static int hpet_acpi_add(struct acpi_device *device)
return -ENODEV;
if (!data.hd_address || !data.hd_nirqs) {
- printk("%s: no address or irqs in _CRS\n", __FUNCTION__);
+ printk("%s: no address or irqs in _CRS\n", __func__);
return -ENODEV;
}
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index d5a752da322..59c6f9ab94e 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -246,7 +246,7 @@ static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to)
{
int remaining = (int)(hp->inbuf_end - read_to);
- pr_debug("%s: %i chars remain\n", __FUNCTION__, remaining);
+ pr_debug("%s: %i chars remain\n", __func__, remaining);
if (read_to != hp->inbuf)
memmove(hp->inbuf, read_to, remaining);
@@ -365,7 +365,7 @@ static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno)
packet.u.version = HVSI_VERSION;
packet.query_seqno = query_seqno+1;
- pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len);
+ pr_debug("%s: sending %i bytes\n", __func__, packet.len);
dbg_dump_hex((uint8_t*)&packet, packet.len);
wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
@@ -437,7 +437,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
return NULL;
if (overflow > 0) {
- pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __FUNCTION__);
+ pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
datalen = TTY_THRESHOLD_THROTTLE;
}
@@ -448,7 +448,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
* we still have more data to deliver, so we need to save off the
* overflow and send it later
*/
- pr_debug("%s: deferring overflow\n", __FUNCTION__);
+ pr_debug("%s: deferring overflow\n", __func__);
memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow);
hp->n_throttle = overflow;
}
@@ -474,11 +474,11 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
if (chunklen == 0) {
- pr_debug("%s: 0-length read\n", __FUNCTION__);
+ pr_debug("%s: 0-length read\n", __func__);
return 0;
}
- pr_debug("%s: got %i bytes\n", __FUNCTION__, chunklen);
+ pr_debug("%s: got %i bytes\n", __func__, chunklen);
dbg_dump_hex(hp->inbuf_end, chunklen);
hp->inbuf_end += chunklen;
@@ -495,7 +495,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
continue;
}
- pr_debug("%s: handling %i-byte packet\n", __FUNCTION__,
+ pr_debug("%s: handling %i-byte packet\n", __func__,
len_packet(packet));
dbg_dump_packet(packet);
@@ -526,7 +526,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
packet += len_packet(packet);
if (*hangup || *handshake) {
- pr_debug("%s: hangup or handshake\n", __FUNCTION__);
+ pr_debug("%s: hangup or handshake\n", __func__);
/*
* we need to send the hangup now before receiving any more data.
* If we get "data, hangup, data", we can't deliver the second
@@ -543,7 +543,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
static void hvsi_send_overflow(struct hvsi_struct *hp)
{
- pr_debug("%s: delivering %i bytes overflow\n", __FUNCTION__,
+ pr_debug("%s: delivering %i bytes overflow\n", __func__,
hp->n_throttle);
hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
@@ -563,7 +563,7 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
unsigned long flags;
int again = 1;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
while (again) {
spin_lock_irqsave(&hp->lock, flags);
@@ -647,7 +647,7 @@ static int hvsi_query(struct hvsi_struct *hp, uint16_t verb)
packet.seqno = atomic_inc_return(&hp->seqno);
packet.verb = verb;
- pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len);
+ pr_debug("%s: sending %i bytes\n", __func__, packet.len);
dbg_dump_hex((uint8_t*)&packet, packet.len);
wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
@@ -674,7 +674,7 @@ static int hvsi_get_mctrl(struct hvsi_struct *hp)
return ret;
}
- pr_debug("%s: mctrl 0x%x\n", __FUNCTION__, hp->mctrl);
+ pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl);
return 0;
}
@@ -694,7 +694,7 @@ static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl)
if (mctrl & TIOCM_DTR)
packet.word = HVSI_TSDTR;
- pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len);
+ pr_debug("%s: sending %i bytes\n", __func__, packet.len);
dbg_dump_hex((uint8_t*)&packet, packet.len);
wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
@@ -790,7 +790,7 @@ static void hvsi_close_protocol(struct hvsi_struct *hp)
packet.len = 6;
packet.verb = VSV_CLOSE_PROTOCOL;
- pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len);
+ pr_debug("%s: sending %i bytes\n", __func__, packet.len);
dbg_dump_hex((uint8_t*)&packet, packet.len);
hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
@@ -803,7 +803,7 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
int line = tty->index;
int ret;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
if (line < 0 || line >= hvsi_count)
return -ENODEV;
@@ -868,7 +868,7 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
struct hvsi_struct *hp = tty->driver_data;
unsigned long flags;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
if (tty_hung_up_p(filp))
return;
@@ -920,7 +920,7 @@ static void hvsi_hangup(struct tty_struct *tty)
struct hvsi_struct *hp = tty->driver_data;
unsigned long flags;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
spin_lock_irqsave(&hp->lock, flags);
@@ -942,7 +942,7 @@ static void hvsi_push(struct hvsi_struct *hp)
n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf);
if (n > 0) {
/* success */
- pr_debug("%s: wrote %i chars\n", __FUNCTION__, n);
+ pr_debug("%s: wrote %i chars\n", __func__, n);
hp->n_outbuf = 0;
} else if (n == -EIO) {
__set_state(hp, HVSI_FSP_DIED);
@@ -965,7 +965,7 @@ static void hvsi_write_worker(struct work_struct *work)
spin_lock_irqsave(&hp->lock, flags);
- pr_debug("%s: %i chars in buffer\n", __FUNCTION__, hp->n_outbuf);
+ pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
if (!is_open(hp)) {
/*
@@ -983,7 +983,7 @@ static void hvsi_write_worker(struct work_struct *work)
schedule_delayed_work(&hp->writer, 10);
else {
#ifdef DEBUG
- pr_debug("%s: outbuf emptied after %li jiffies\n", __FUNCTION__,
+ pr_debug("%s: outbuf emptied after %li jiffies\n", __func__,
jiffies - start_j);
start_j = 0;
#endif /* DEBUG */
@@ -1020,11 +1020,11 @@ static int hvsi_write(struct tty_struct *tty,
spin_lock_irqsave(&hp->lock, flags);
- pr_debug("%s: %i chars in buffer\n", __FUNCTION__, hp->n_outbuf);
+ pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
if (!is_open(hp)) {
/* we're either closing or not yet open; don't accept data */
- pr_debug("%s: not open\n", __FUNCTION__);
+ pr_debug("%s: not open\n", __func__);
goto out;
}
@@ -1058,7 +1058,7 @@ out:
spin_unlock_irqrestore(&hp->lock, flags);
if (total != origcount)
- pr_debug("%s: wanted %i, only wrote %i\n", __FUNCTION__, origcount,
+ pr_debug("%s: wanted %i, only wrote %i\n", __func__, origcount,
total);
return total;
@@ -1072,7 +1072,7 @@ static void hvsi_throttle(struct tty_struct *tty)
{
struct hvsi_struct *hp = (struct hvsi_struct *)tty->driver_data;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE);
}
@@ -1083,7 +1083,7 @@ static void hvsi_unthrottle(struct tty_struct *tty)
unsigned long flags;
int shouldflip = 0;
- pr_debug("%s\n", __FUNCTION__);
+ pr_debug("%s\n", __func__);
spin_lock_irqsave(&hp->lock, flags);
if (hp->n_throttle) {
@@ -1302,7 +1302,7 @@ static int __init hvsi_console_init(void)
hp->virq = irq_create_mapping(NULL, irq[0]);
if (hp->virq == NO_IRQ) {
printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
- __FUNCTION__, irq[0]);
+ __func__, irq[0]);
continue;
}
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
index 61ef013b844..3601017f58c 100644
--- a/drivers/char/ip2/i2ellis.c
+++ b/drivers/char/ip2/i2ellis.c
@@ -53,7 +53,7 @@ static int ii2Safe; // Safe I/O address for delay routine
static int iiDelayed; // Set when the iiResetDelay function is
// called. Cleared when ANY board is reset.
-static rwlock_t Dl_spinlock;
+static DEFINE_RWLOCK(Dl_spinlock);
//********
//* Code *
@@ -82,7 +82,6 @@ static rwlock_t Dl_spinlock;
static void
iiEllisInit(void)
{
- LOCK_INIT(&Dl_spinlock);
}
//******************************************************************************
@@ -132,7 +131,7 @@ iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay )
|| (address & 0x7)
)
{
- COMPLETE(pB,I2EE_BADADDR);
+ I2_COMPLETE(pB, I2EE_BADADDR);
}
// Initialize accelerators
@@ -152,7 +151,7 @@ iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay )
pB->i2eValid = I2E_MAGIC;
pB->i2eState = II_STATE_COLD;
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -177,12 +176,12 @@ iiReset(i2eBordStrPtr pB)
// Magic number should be set, else even the address is suspect
if (pB->i2eValid != I2E_MAGIC)
{
- COMPLETE(pB, I2EE_BADMAGIC);
+ I2_COMPLETE(pB, I2EE_BADMAGIC);
}
- OUTB(pB->i2eBase + FIFO_RESET, 0); // Any data will do
+ outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */
iiDelay(pB, 50); // Pause between resets
- OUTB(pB->i2eBase + FIFO_RESET, 0); // Second reset
+ outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */
// We must wait before even attempting to read anything from the FIFO: the
// board's P.O.S.T may actually attempt to read and write its end of the
@@ -203,7 +202,7 @@ iiReset(i2eBordStrPtr pB)
// Ensure anything which would have been of use to standard loadware is
// blanked out, since board has now forgotten everything!.
- pB->i2eUsingIrq = IRQ_UNDEFINED; // Not set up to use an interrupt yet
+ pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */
pB->i2eWaitingForEmptyFifo = 0;
pB->i2eOutMailWaiting = 0;
pB->i2eChannelPtr = NULL;
@@ -215,7 +214,7 @@ iiReset(i2eBordStrPtr pB)
pB->i2eFatalTrap = NULL;
pB->i2eFatal = 0;
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -235,14 +234,14 @@ static int
iiResetDelay(i2eBordStrPtr pB)
{
if (pB->i2eValid != I2E_MAGIC) {
- COMPLETE(pB, I2EE_BADMAGIC);
+ I2_COMPLETE(pB, I2EE_BADMAGIC);
}
if (pB->i2eState != II_STATE_RESET) {
- COMPLETE(pB, I2EE_BADSTATE);
+ I2_COMPLETE(pB, I2EE_BADSTATE);
}
iiDelay(pB,2000); /* Now we wait for two seconds. */
iiDelayed = 1; /* Delay has been called: ok to initialize */
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -273,12 +272,12 @@ iiInitialize(i2eBordStrPtr pB)
if (pB->i2eValid != I2E_MAGIC)
{
- COMPLETE(pB, I2EE_BADMAGIC);
+ I2_COMPLETE(pB, I2EE_BADMAGIC);
}
if (pB->i2eState != II_STATE_RESET || !iiDelayed)
{
- COMPLETE(pB, I2EE_BADSTATE);
+ I2_COMPLETE(pB, I2EE_BADSTATE);
}
// In case there is a failure short of our completely reading the power-up
@@ -291,13 +290,12 @@ iiInitialize(i2eBordStrPtr pB)
for (itemp = 0; itemp < sizeof(porStr); itemp++)
{
// We expect the entire message is ready.
- if (HAS_NO_INPUT(pB))
- {
+ if (!I2_HAS_INPUT(pB)) {
pB->i2ePomSize = itemp;
- COMPLETE(pB, I2EE_PORM_SHORT);
+ I2_COMPLETE(pB, I2EE_PORM_SHORT);
}
- pB->i2ePom.c[itemp] = c = BYTE_FROM(pB);
+ pB->i2ePom.c[itemp] = c = inb(pB->i2eData);
// We check the magic numbers as soon as they are supposed to be read
// (rather than after) to minimize effect of reading something we
@@ -306,22 +304,22 @@ iiInitialize(i2eBordStrPtr pB)
(itemp == POR_2_INDEX && c != POR_MAGIC_2))
{
pB->i2ePomSize = itemp+1;
- COMPLETE(pB, I2EE_BADMAGIC);
+ I2_COMPLETE(pB, I2EE_BADMAGIC);
}
}
pB->i2ePomSize = itemp;
// Ensure that this was all the data...
- if (HAS_INPUT(pB))
- COMPLETE(pB, I2EE_PORM_LONG);
+ if (I2_HAS_INPUT(pB))
+ I2_COMPLETE(pB, I2EE_PORM_LONG);
// For now, we'll fail to initialize if P.O.S.T reports bad chip mapper:
// Implying we will not be able to download any code either: That's ok: the
// condition is pretty explicit.
if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER)
{
- COMPLETE(pB, I2EE_POSTERR);
+ I2_COMPLETE(pB, I2EE_POSTERR);
}
// Determine anything which must be done differently depending on the family
@@ -332,7 +330,7 @@ iiInitialize(i2eBordStrPtr pB)
pB->i2eFifoStyle = FIFO_II;
pB->i2eFifoSize = 512; // 512 bytes, always
- pB->i2eDataWidth16 = NO;
+ pB->i2eDataWidth16 = false;
pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit
// slot, we do allow it to be done (documentation!)
@@ -354,7 +352,7 @@ iiInitialize(i2eBordStrPtr pB)
// should always be consistent for IntelliPort-II. Ditto below...
if (pB->i2ePom.e.porPorts1 != 4)
{
- COMPLETE(pB, I2EE_INCONSIST);
+ I2_COMPLETE(pB, I2EE_INCONSIST);
}
break;
@@ -364,7 +362,7 @@ iiInitialize(i2eBordStrPtr pB)
pB->i2eChannelMap[0] = 0xff; // Eight port
if (pB->i2ePom.e.porPorts1 != 8)
{
- COMPLETE(pB, I2EE_INCONSIST);
+ I2_COMPLETE(pB, I2EE_INCONSIST);
}
break;
@@ -373,7 +371,7 @@ iiInitialize(i2eBordStrPtr pB)
pB->i2eChannelMap[0] = 0x3f; // Six Port
if (pB->i2ePom.e.porPorts1 != 6)
{
- COMPLETE(pB, I2EE_INCONSIST);
+ I2_COMPLETE(pB, I2EE_INCONSIST);
}
break;
}
@@ -402,7 +400,7 @@ iiInitialize(i2eBordStrPtr pB)
if (itemp < 8 || itemp > 15)
{
- COMPLETE(pB, I2EE_INCONSIST);
+ I2_COMPLETE(pB, I2EE_INCONSIST);
}
pB->i2eFifoSize = (1 << itemp);
@@ -450,26 +448,26 @@ iiInitialize(i2eBordStrPtr pB)
switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) )
{
case POR_BUS_SLOT16 | POR_BUS_DIP16:
- pB->i2eDataWidth16 = YES;
+ pB->i2eDataWidth16 = true;
pB->i2eMaxIrq = 15;
break;
case POR_BUS_SLOT16:
- pB->i2eDataWidth16 = NO;
+ pB->i2eDataWidth16 = false;
pB->i2eMaxIrq = 15;
break;
case 0:
case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care.
default:
- pB->i2eDataWidth16 = NO;
+ pB->i2eDataWidth16 = false;
pB->i2eMaxIrq = 7;
break;
}
break; // POR_ID_FIIEX case
default: // Unknown type of board
- COMPLETE(pB, I2EE_BAD_FAMILY);
+ I2_COMPLETE(pB, I2EE_BAD_FAMILY);
break;
} // End the switch based on family
@@ -483,17 +481,14 @@ iiInitialize(i2eBordStrPtr pB)
{
case POR_BUS_T_ISA:
case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok.
- pB->i2eChangeIrq = YES;
- break;
case POR_BUS_T_MCA:
case POR_BUS_T_EISA:
- pB->i2eChangeIrq = NO;
break;
default:
- COMPLETE(pB, I2EE_BADBUS);
+ I2_COMPLETE(pB, I2EE_BADBUS);
}
- if (pB->i2eDataWidth16 == YES)
+ if (pB->i2eDataWidth16)
{
pB->i2eWriteBuf = iiWriteBuf16;
pB->i2eReadBuf = iiReadBuf16;
@@ -529,7 +524,7 @@ iiInitialize(i2eBordStrPtr pB)
break;
default:
- COMPLETE(pB, I2EE_INCONSIST);
+ I2_COMPLETE(pB, I2EE_INCONSIST);
}
// Initialize state information.
@@ -549,7 +544,7 @@ iiInitialize(i2eBordStrPtr pB)
// Everything is ok now, return with good status/
pB->i2eValid = I2E_MAGIC;
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -658,7 +653,7 @@ ii2DelayIO(unsigned int mseconds)
while(mseconds--) {
int i = ii2DelValue;
while ( i-- ) {
- INB ( ii2Safe );
+ inb(ii2Safe);
}
}
}
@@ -709,11 +704,11 @@ iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count)
{
// Rudimentary sanity checking here.
if (pB->i2eValid != I2E_MAGIC)
- COMPLETE(pB, I2EE_INVALID);
+ I2_COMPLETE(pB, I2EE_INVALID);
- OUTSW ( pB->i2eData, address, count);
+ I2_OUTSW(pB->i2eData, address, count);
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -738,11 +733,11 @@ iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count)
{
/* Rudimentary sanity checking here */
if (pB->i2eValid != I2E_MAGIC)
- COMPLETE(pB, I2EE_INVALID);
+ I2_COMPLETE(pB, I2EE_INVALID);
- OUTSB ( pB->i2eData, address, count );
+ I2_OUTSB(pB->i2eData, address, count);
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -767,11 +762,11 @@ iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count)
{
// Rudimentary sanity checking here.
if (pB->i2eValid != I2E_MAGIC)
- COMPLETE(pB, I2EE_INVALID);
+ I2_COMPLETE(pB, I2EE_INVALID);
- INSW ( pB->i2eData, address, count);
+ I2_INSW(pB->i2eData, address, count);
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -796,11 +791,11 @@ iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count)
{
// Rudimentary sanity checking here.
if (pB->i2eValid != I2E_MAGIC)
- COMPLETE(pB, I2EE_INVALID);
+ I2_COMPLETE(pB, I2EE_INVALID);
- INSB ( pB->i2eData, address, count);
+ I2_INSB(pB->i2eData, address, count);
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
//******************************************************************************
@@ -820,7 +815,7 @@ iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count)
static unsigned short
iiReadWord16(i2eBordStrPtr pB)
{
- return (unsigned short)( INW(pB->i2eData) );
+ return inw(pB->i2eData);
}
//******************************************************************************
@@ -842,9 +837,9 @@ iiReadWord8(i2eBordStrPtr pB)
{
unsigned short urs;
- urs = INB ( pB->i2eData );
+ urs = inb(pB->i2eData);
- return ( ( INB ( pB->i2eData ) << 8 ) | urs );
+ return (inb(pB->i2eData) << 8) | urs;
}
//******************************************************************************
@@ -865,7 +860,7 @@ iiReadWord8(i2eBordStrPtr pB)
static void
iiWriteWord16(i2eBordStrPtr pB, unsigned short value)
{
- WORD_TO(pB, (int)value);
+ outw((int)value, pB->i2eData);
}
//******************************************************************************
@@ -886,8 +881,8 @@ iiWriteWord16(i2eBordStrPtr pB, unsigned short value)
static void
iiWriteWord8(i2eBordStrPtr pB, unsigned short value)
{
- BYTE_TO(pB, (char)value);
- BYTE_TO(pB, (char)(value >> 8) );
+ outb((char)value, pB->i2eData);
+ outb((char)(value >> 8), pB->i2eData);
}
//******************************************************************************
@@ -939,30 +934,30 @@ iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay)
// interrupts of any kind.
- WRITE_LOCK_IRQSAVE(&Dl_spinlock,flags)
- OUTB(pB->i2ePointer, SEL_COMMAND);
- OUTB(pB->i2ePointer, SEL_CMD_SH);
+ write_lock_irqsave(&Dl_spinlock, flags);
+ outb(SEL_COMMAND, pB->i2ePointer);
+ outb(SEL_CMD_SH, pB->i2ePointer);
- itemp = INB(pB->i2eStatus);
+ itemp = inb(pB->i2eStatus);
- OUTB(pB->i2ePointer, SEL_COMMAND);
- OUTB(pB->i2ePointer, SEL_CMD_UNSH);
+ outb(SEL_COMMAND, pB->i2ePointer);
+ outb(SEL_CMD_UNSH, pB->i2ePointer);
if (itemp & ST_IN_EMPTY)
{
- UPDATE_FIFO_ROOM(pB);
- WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags)
- COMPLETE(pB, I2EE_GOOD);
+ I2_UPDATE_FIFO_ROOM(pB);
+ write_unlock_irqrestore(&Dl_spinlock, flags);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
- WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags)
+ write_unlock_irqrestore(&Dl_spinlock, flags);
if (mSdelay-- == 0)
break;
iiDelay(pB, 1); /* 1 mS granularity on checking condition */
}
- COMPLETE(pB, I2EE_TXE_TIME);
+ I2_COMPLETE(pB, I2EE_TXE_TIME);
}
//******************************************************************************
@@ -1002,21 +997,21 @@ iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay)
// you will generally not want to service interrupts or in any way
// disrupt the assumptions implicit in the larger context.
- WRITE_LOCK_IRQSAVE(&Dl_spinlock,flags)
+ write_lock_irqsave(&Dl_spinlock, flags);
- if (INB(pB->i2eStatus) & STE_OUT_MT) {
- UPDATE_FIFO_ROOM(pB);
- WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags)
- COMPLETE(pB, I2EE_GOOD);
+ if (inb(pB->i2eStatus) & STE_OUT_MT) {
+ I2_UPDATE_FIFO_ROOM(pB);
+ write_unlock_irqrestore(&Dl_spinlock, flags);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
- WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags)
+ write_unlock_irqrestore(&Dl_spinlock, flags);
if (mSdelay-- == 0)
break;
iiDelay(pB, 1); // 1 mS granularity on checking condition
}
- COMPLETE(pB, I2EE_TXE_TIME);
+ I2_COMPLETE(pB, I2EE_TXE_TIME);
}
//******************************************************************************
@@ -1038,8 +1033,8 @@ static int
iiTxMailEmptyII(i2eBordStrPtr pB)
{
int port = pB->i2ePointer;
- OUTB ( port, SEL_OUTMAIL );
- return ( INB(port) == 0 );
+ outb(SEL_OUTMAIL, port);
+ return inb(port) == 0;
}
//******************************************************************************
@@ -1060,7 +1055,7 @@ iiTxMailEmptyII(i2eBordStrPtr pB)
static int
iiTxMailEmptyIIEX(i2eBordStrPtr pB)
{
- return !(INB(pB->i2eStatus) & STE_OUT_MAIL);
+ return !(inb(pB->i2eStatus) & STE_OUT_MAIL);
}
//******************************************************************************
@@ -1084,10 +1079,10 @@ iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail)
{
int port = pB->i2ePointer;
- OUTB(port, SEL_OUTMAIL);
- if (INB(port) == 0) {
- OUTB(port, SEL_OUTMAIL);
- OUTB(port, mail);
+ outb(SEL_OUTMAIL, port);
+ if (inb(port) == 0) {
+ outb(SEL_OUTMAIL, port);
+ outb(mail, port);
return 1;
}
return 0;
@@ -1112,10 +1107,9 @@ iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail)
static int
iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail)
{
- if(INB(pB->i2eStatus) & STE_OUT_MAIL) {
+ if (inb(pB->i2eStatus) & STE_OUT_MAIL)
return 0;
- }
- OUTB(pB->i2eXMail, mail);
+ outb(mail, pB->i2eXMail);
return 1;
}
@@ -1136,9 +1130,9 @@ iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail)
static unsigned short
iiGetMailII(i2eBordStrPtr pB)
{
- if (HAS_MAIL(pB)) {
- OUTB(pB->i2ePointer, SEL_INMAIL);
- return INB(pB->i2ePointer);
+ if (I2_HAS_MAIL(pB)) {
+ outb(SEL_INMAIL, pB->i2ePointer);
+ return inb(pB->i2ePointer);
} else {
return NO_MAIL_HERE;
}
@@ -1161,11 +1155,10 @@ iiGetMailII(i2eBordStrPtr pB)
static unsigned short
iiGetMailIIEX(i2eBordStrPtr pB)
{
- if (HAS_MAIL(pB)) {
- return INB(pB->i2eXMail);
- } else {
+ if (I2_HAS_MAIL(pB))
+ return inb(pB->i2eXMail);
+ else
return NO_MAIL_HERE;
- }
}
//******************************************************************************
@@ -1184,8 +1177,8 @@ iiGetMailIIEX(i2eBordStrPtr pB)
static void
iiEnableMailIrqII(i2eBordStrPtr pB)
{
- OUTB(pB->i2ePointer, SEL_MASK);
- OUTB(pB->i2ePointer, ST_IN_MAIL);
+ outb(SEL_MASK, pB->i2ePointer);
+ outb(ST_IN_MAIL, pB->i2ePointer);
}
//******************************************************************************
@@ -1204,7 +1197,7 @@ iiEnableMailIrqII(i2eBordStrPtr pB)
static void
iiEnableMailIrqIIEX(i2eBordStrPtr pB)
{
- OUTB(pB->i2eXMask, MX_IN_MAIL);
+ outb(MX_IN_MAIL, pB->i2eXMask);
}
//******************************************************************************
@@ -1223,8 +1216,8 @@ iiEnableMailIrqIIEX(i2eBordStrPtr pB)
static void
iiWriteMaskII(i2eBordStrPtr pB, unsigned char value)
{
- OUTB(pB->i2ePointer, SEL_MASK);
- OUTB(pB->i2ePointer, value);
+ outb(SEL_MASK, pB->i2ePointer);
+ outb(value, pB->i2ePointer);
}
//******************************************************************************
@@ -1243,7 +1236,7 @@ iiWriteMaskII(i2eBordStrPtr pB, unsigned char value)
static void
iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value)
{
- OUTB(pB->i2eXMask, value);
+ outb(value, pB->i2eXMask);
}
//******************************************************************************
@@ -1354,9 +1347,8 @@ iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard)
// immediately and be harmless, though not strictly necessary.
itemp = MAX_DLOAD_ACK_TIME/10;
while (--itemp) {
- if (HAS_INPUT(pB)) {
- switch(BYTE_FROM(pB))
- {
+ if (I2_HAS_INPUT(pB)) {
+ switch (inb(pB->i2eData)) {
case LOADWARE_OK:
pB->i2eState =
isStandard ? II_STATE_STDLOADED :II_STATE_LOADED;
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h
index 433305062fb..c88a64e527a 100644
--- a/drivers/char/ip2/i2ellis.h
+++ b/drivers/char/ip2/i2ellis.h
@@ -185,10 +185,6 @@ typedef struct _i2eBordStr
// The highest allowable IRQ, based on the
// slot size.
- unsigned char i2eChangeIrq;
- // Whether tis valid to change IRQ's
- // ISA = ok, EISA, MicroChannel, no
-
// Accelerators for various addresses on the board
int i2eBase; // I/O Address of the Board
int i2eData; // From here data transfers happen
@@ -431,12 +427,6 @@ typedef struct _i2eBordStr
// Manifests for i2eBordStr:
//-------------------------------------------
-#define YES 1
-#define NO 0
-
-#define NULLFUNC (void (*)(void))0
-#define NULLPTR (void *)0
-
typedef void (*delayFunc_t)(unsigned int);
// i2eValid
@@ -494,8 +484,8 @@ typedef void (*delayFunc_t)(unsigned int);
// i2eUsingIrq
//
-#define IRQ_UNDEFINED 0x1352 // No valid irq (or polling = 0) can ever
- // promote to this!
+#define I2_IRQ_UNDEFINED 0x1352 /* No valid irq (or polling = 0) can
+ * ever promote to this! */
//------------------------------------------
// Handy Macros for i2ellis.c and others
// Note these are common to -II and -IIEX
@@ -504,41 +494,14 @@ typedef void (*delayFunc_t)(unsigned int);
// Given a pointer to the board structure, does the input FIFO have any data or
// not?
//
-#define HAS_INPUT(pB) !(INB(pB->i2eStatus) & ST_IN_EMPTY)
-#define HAS_NO_INPUT(pB) (INB(pB->i2eStatus) & ST_IN_EMPTY)
-
-// Given a pointer to board structure, read a byte or word from the fifo
-//
-#define BYTE_FROM(pB) (unsigned char)INB(pB->i2eData)
-#define WORD_FROM(pB) (unsigned short)INW(pB->i2eData)
-
-// Given a pointer to board structure, is there room for any data to be written
-// to the data fifo?
-//
-#define HAS_OUTROOM(pB) !(INB(pB->i2eStatus) & ST_OUT_FULL)
-#define HAS_NO_OUTROOM(pB) (INB(pB->i2eStatus) & ST_OUT_FULL)
-
-// Given a pointer to board structure, write a single byte to the fifo
-// structure. Note that for 16-bit interfaces, the high order byte is undefined
-// and unknown.
-//
-#define BYTE_TO(pB, c) OUTB(pB->i2eData,(c))
-
-// Write a word to the fifo structure. For 8-bit interfaces, this may have
-// unknown results.
-//
-#define WORD_TO(pB, c) OUTW(pB->i2eData,(c))
+#define I2_HAS_INPUT(pB) !(inb(pB->i2eStatus) & ST_IN_EMPTY)
// Given a pointer to the board structure, is there anything in the incoming
// mailbox?
//
-#define HAS_MAIL(pB) (INB(pB->i2eStatus) & ST_IN_MAIL)
+#define I2_HAS_MAIL(pB) (inb(pB->i2eStatus) & ST_IN_MAIL)
-#define UPDATE_FIFO_ROOM(pB) (pB)->i2eFifoRemains=(pB)->i2eFifoSize
-
-// Handy macro to round up a number (like the buffer write and read routines do)
-//
-#define ROUNDUP(number) (((number)+1) & (~1))
+#define I2_UPDATE_FIFO_ROOM(pB) ((pB)->i2eFifoRemains = (pB)->i2eFifoSize)
//------------------------------------------
// Function Declarations for i2ellis.c
@@ -593,20 +556,11 @@ static int iiDownloadBlock(i2eBordStrPtr, loadHdrStrPtr, int);
//
static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int);
-// Called indirectly always. Needed externally so the routine might be
-// SPECIFIED as an argument to iiReset()
-//
-//static void ii2DelayIO(unsigned int); // N-millisecond delay using
- //hardware spin
-//static void ii2DelayTimer(unsigned int); // N-millisecond delay using Linux
- //timer
-
// Many functions defined here return True if good, False otherwise, with an
// error code in i2eError field. Here is a handy macro for setting the error
// code and returning.
//
-#define COMPLETE(pB,code) \
- do { \
+#define I2_COMPLETE(pB,code) do { \
pB->i2eError = code; \
return (code == I2EE_GOOD);\
} while (0)
diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h
index 15fe04e748f..8aa6e7ab8d5 100644
--- a/drivers/char/ip2/i2hw.h
+++ b/drivers/char/ip2/i2hw.h
@@ -129,7 +129,6 @@ registers, use byte operations only.
//------------------------------------------------
//
#include "ip2types.h"
-#include "i2os.h" /* For any o.s., compiler, or host-related issues */
//-------------------------------------------------------------------------
// Manifests for the I/O map:
@@ -644,5 +643,10 @@ typedef union _loadHdrStr
#define ABS_BIGGEST_BOX 16 // Absolute the most ports per box
#define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX)
+#define I2_OUTSW(port, addr, count) outsw((port), (addr), (((count)+1)/2))
+#define I2_OUTSB(port, addr, count) outsb((port), (addr), (((count)+1))&-2)
+#define I2_INSW(port, addr, count) insw((port), (addr), (((count)+1)/2))
+#define I2_INSB(port, addr, count) insb((port), (addr), (((count)+1))&-2)
+
#endif // I2HW_H
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 9c25320121e..938879cc7bc 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -227,17 +227,17 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
i2ChanStrPtr *ppCh;
if (pB->i2eValid != I2E_MAGIC) {
- COMPLETE(pB, I2EE_BADMAGIC);
+ I2_COMPLETE(pB, I2EE_BADMAGIC);
}
if (pB->i2eState != II_STATE_STDLOADED) {
- COMPLETE(pB, I2EE_BADSTATE);
+ I2_COMPLETE(pB, I2EE_BADSTATE);
}
- LOCK_INIT(&pB->read_fifo_spinlock);
- LOCK_INIT(&pB->write_fifo_spinlock);
- LOCK_INIT(&pB->Dbuf_spinlock);
- LOCK_INIT(&pB->Bbuf_spinlock);
- LOCK_INIT(&pB->Fbuf_spinlock);
+ rwlock_init(&pB->read_fifo_spinlock);
+ rwlock_init(&pB->write_fifo_spinlock);
+ rwlock_init(&pB->Dbuf_spinlock);
+ rwlock_init(&pB->Bbuf_spinlock);
+ rwlock_init(&pB->Fbuf_spinlock);
// NO LOCK needed yet - this is init
@@ -259,10 +259,10 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) {
continue;
}
- LOCK_INIT(&pCh->Ibuf_spinlock);
- LOCK_INIT(&pCh->Obuf_spinlock);
- LOCK_INIT(&pCh->Cbuf_spinlock);
- LOCK_INIT(&pCh->Pbuf_spinlock);
+ rwlock_init(&pCh->Ibuf_spinlock);
+ rwlock_init(&pCh->Obuf_spinlock);
+ rwlock_init(&pCh->Cbuf_spinlock);
+ rwlock_init(&pCh->Pbuf_spinlock);
// NO LOCK needed yet - this is init
// Set up validity flag according to support level
if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) {
@@ -347,7 +347,7 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh)
}
// No need to check for wrap here; this is initialization.
pB->i2Fbuf_stuff = stuffIndex;
- COMPLETE(pB, I2EE_GOOD);
+ I2_COMPLETE(pB, I2EE_GOOD);
}
@@ -374,7 +374,7 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type)
case NEED_INLINE:
- WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Dbuf_spinlock, flags);
if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip)
{
queueIndex = pB->i2Dbuf_strip;
@@ -386,12 +386,12 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type)
pB->i2Dbuf_strip = queueIndex;
pCh->channelNeeds &= ~NEED_INLINE;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Dbuf_spinlock, flags);
break;
case NEED_BYPASS:
- WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Bbuf_spinlock, flags);
if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip)
{
queueIndex = pB->i2Bbuf_strip;
@@ -403,12 +403,12 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type)
pB->i2Bbuf_strip = queueIndex;
pCh->channelNeeds &= ~NEED_BYPASS;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Bbuf_spinlock, flags);
break;
case NEED_FLOW:
- WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Fbuf_spinlock, flags);
if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip)
{
queueIndex = pB->i2Fbuf_strip;
@@ -420,7 +420,7 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type)
pB->i2Fbuf_strip = queueIndex;
pCh->channelNeeds &= ~NEED_FLOW;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Fbuf_spinlock, flags);
break;
default:
printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type);
@@ -453,7 +453,7 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
case NEED_INLINE:
- WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Dbuf_spinlock, flags);
if ( !(pCh->channelNeeds & NEED_INLINE) )
{
pCh->channelNeeds |= NEED_INLINE;
@@ -463,12 +463,12 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
queueIndex = 0;
pB->i2Dbuf_stuff = queueIndex;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Dbuf_spinlock, flags);
break;
case NEED_BYPASS:
- WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Bbuf_spinlock, flags);
if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS))
{
pCh->channelNeeds |= NEED_BYPASS;
@@ -478,12 +478,12 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
queueIndex = 0;
pB->i2Bbuf_stuff = queueIndex;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Bbuf_spinlock, flags);
break;
case NEED_FLOW:
- WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags);
+ write_lock_irqsave(&pB->Fbuf_spinlock, flags);
if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW))
{
pCh->channelNeeds |= NEED_FLOW;
@@ -493,7 +493,7 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type)
queueIndex = 0;
pB->i2Fbuf_stuff = queueIndex;
}
- WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags);
+ write_unlock_irqrestore(&pB->Fbuf_spinlock, flags);
break;
case NEED_CREDIT:
@@ -562,9 +562,8 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
pB = pCh->pMyBord;
// Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT
- if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) {
+ if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED)
return -2;
- }
// If the board has gone fatal, return bad, and also hit the trap routine if
// it exists.
if (pB->i2eFatal) {
@@ -620,13 +619,13 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
switch(type) {
case PTYPE_INLINE:
lock_var_p = &pCh->Obuf_spinlock;
- WRITE_LOCK_IRQSAVE(lock_var_p,flags);
+ write_lock_irqsave(lock_var_p, flags);
stuffIndex = pCh->Obuf_stuff;
bufroom = pCh->Obuf_strip - stuffIndex;
break;
case PTYPE_BYPASS:
lock_var_p = &pCh->Cbuf_spinlock;
- WRITE_LOCK_IRQSAVE(lock_var_p,flags);
+ write_lock_irqsave(lock_var_p, flags);
stuffIndex = pCh->Cbuf_stuff;
bufroom = pCh->Cbuf_strip - stuffIndex;
break;
@@ -645,7 +644,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
break; /* from for()- Enough room: goto proceed */
}
ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize);
- WRITE_UNLOCK_IRQRESTORE(lock_var_p, flags);
+ write_unlock_irqrestore(lock_var_p, flags);
} else
ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize);
@@ -747,7 +746,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
{
case PTYPE_INLINE:
pCh->Obuf_stuff = stuffIndex; // Store buffer pointer
- WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
pB->debugInlineQueued++;
// Add the channel pointer to list of channels needing service (first
@@ -757,7 +756,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands,
case PTYPE_BYPASS:
pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer
- WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags);
pB->debugBypassQueued++;
// Add the channel pointer to list of channels needing service (first
@@ -840,7 +839,7 @@ i2Input(i2ChanStrPtr pCh)
count = -1;
goto i2Input_exit;
}
- WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Ibuf_spinlock, flags);
// initialize some accelerators and private copies
stripIndex = pCh->Ibuf_strip;
@@ -850,7 +849,7 @@ i2Input(i2ChanStrPtr pCh)
// If buffer is empty or requested data count was 0, (trivial case) return
// without any further thought.
if ( count == 0 ) {
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
goto i2Input_exit;
}
// Adjust for buffer wrap
@@ -891,10 +890,10 @@ i2Input(i2ChanStrPtr pCh)
if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) {
pCh->sinceLastFlow -= pCh->whenSendFlow;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
} else {
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
}
i2Input_exit:
@@ -926,7 +925,7 @@ i2InputFlush(i2ChanStrPtr pCh)
ip2trace (CHANN, ITRC_INPUT, 10, 0);
- WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Ibuf_spinlock, flags);
count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
// Adjust for buffer wrap
@@ -947,10 +946,10 @@ i2InputFlush(i2ChanStrPtr pCh)
if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow )
{
pCh->sinceLastFlow -= pCh->whenSendFlow;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW);
} else {
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
}
ip2trace (CHANN, ITRC_INPUT, 19, 1, count);
@@ -979,9 +978,9 @@ i2InputAvailable(i2ChanStrPtr pCh)
// initialize some accelerators and private copies
- READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
count = pCh->Ibuf_stuff - pCh->Ibuf_strip;
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
// Adjust for buffer wrap
if (count < 0)
@@ -1045,9 +1044,9 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
while ( count > 0 ) {
// How much room in output buffer is there?
- READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Obuf_spinlock, flags);
amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
- READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
if (amountToMove < 0) {
amountToMove += OBUF_SIZE;
}
@@ -1075,7 +1074,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) )
&& amountToMove > 0 )
{
- WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Obuf_spinlock, flags);
stuffIndex = pCh->Obuf_stuff;
// Had room to move some data: don't know whether the block size,
@@ -1102,7 +1101,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
}
pCh->Obuf_stuff = stuffIndex;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex );
@@ -1352,9 +1351,9 @@ i2OutputFree(i2ChanStrPtr pCh)
if ( !i2Validate ( pCh ) ) {
return -1;
}
- READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Obuf_spinlock, flags);
amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1;
- READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
if (amountToMove < 0) {
amountToMove += OBUF_SIZE;
@@ -1464,11 +1463,11 @@ i2StripFifo(i2eBordStrPtr pB)
// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 );
- while (HAS_INPUT(pB)) {
+ while (I2_HAS_INPUT(pB)) {
// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 );
// Process packet from fifo a one atomic unit
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, bflags);
// The first word (or two bytes) will have channel number and type of
// packet, possibly other information
@@ -1490,7 +1489,8 @@ i2StripFifo(i2eBordStrPtr pB)
// sick!
if ( ((unsigned int)count) > IBUF_SIZE ) {
pB->i2eFatal = 2;
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
+ bflags);
return; /* Bail out ASAP */
}
// Channel is illegally big ?
@@ -1498,7 +1498,8 @@ i2StripFifo(i2eBordStrPtr pB)
(NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])))
{
iiReadBuf(pB, junkBuffer, count);
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
+ bflags);
break; /* From switch: ready for next packet */
}
@@ -1512,14 +1513,15 @@ i2StripFifo(i2eBordStrPtr pB)
if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY)
{
pCh->hotKeyIn = iiReadWord(pB) & 0xff;
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
+ bflags);
i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK);
break; /* From the switch: ready for next packet */
}
// Normal data! We crudely assume there is room for the data in our
// buffer because the board wouldn't have exceeded his credit limit.
- WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags);
+ write_lock_irqsave(&pCh->Ibuf_spinlock, cflags);
// We have 2 locks now
stuffIndex = pCh->Ibuf_stuff;
amountToRead = IBUF_SIZE - stuffIndex;
@@ -1562,8 +1564,9 @@ i2StripFifo(i2eBordStrPtr pB)
// Update stuff index
pCh->Ibuf_stuff = stuffIndex;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags);
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+ write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
+ bflags);
#ifdef USE_IQ
schedule_work(&pCh->tqueue_input);
@@ -1585,7 +1588,8 @@ i2StripFifo(i2eBordStrPtr pB)
iiReadBuf(pB, cmdBuffer, count);
// We can release early with buffer grab
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
+ bflags);
pc = cmdBuffer;
pcLimit = &(cmdBuffer[count]);
@@ -1830,12 +1834,12 @@ i2StripFifo(i2eBordStrPtr pB)
default: // Neither packet? should be impossible
ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1,
PTYPE_OF(pB->i2eLeadoffWord) );
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,
+ write_unlock_irqrestore(&pB->read_fifo_spinlock,
bflags);
break;
} // End of switch on type of packets
- } //while(board HAS_INPUT)
+ } /*while(board I2_HAS_INPUT)*/
ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 );
@@ -1858,7 +1862,7 @@ i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve)
{
int rc = 0;
unsigned long flags;
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
if (!pB->i2eWaitingForEmptyFifo) {
if (pB->i2eFifoRemains > (count+reserve)) {
pB->i2eFifoRemains -= count;
@@ -1867,7 +1871,7 @@ i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve)
rc = count;
}
}
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
return rc;
}
//******************************************************************************
@@ -1898,7 +1902,7 @@ i2StuffFifoBypass(i2eBordStrPtr pB)
while ( --bailout && notClogged &&
(NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS))))
{
- WRITE_LOCK_IRQSAVE(&pCh->Cbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Cbuf_spinlock, flags);
stripIndex = pCh->Cbuf_strip;
// as long as there are packets for this channel...
@@ -1906,7 +1910,7 @@ i2StuffFifoBypass(i2eBordStrPtr pB)
while (stripIndex != pCh->Cbuf_stuff) {
pRemove = &(pCh->Cbuf[stripIndex]);
packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader);
- paddedSize = ROUNDUP(packetSize);
+ paddedSize = roundup(packetSize, 2);
if (paddedSize > 0) {
if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) {
@@ -1930,7 +1934,7 @@ WriteDBGBuf("BYPS", pRemove, paddedSize);
// Done with this channel. Move to next, removing this one from
// the queue of channels if we cleaned it out (i.e., didn't get clogged.
pCh->Cbuf_strip = stripIndex;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags);
} // Either clogged or finished all the work
#ifdef IP2DEBUG_TRACE
@@ -1954,7 +1958,7 @@ static inline void
i2StuffFifoFlow(i2eBordStrPtr pB)
{
i2ChanStrPtr pCh;
- unsigned short paddedSize = ROUNDUP(sizeof(flowIn));
+ unsigned short paddedSize = roundup(sizeof(flowIn), 2);
ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2,
pB->i2eFifoRemains, paddedSize );
@@ -2010,7 +2014,7 @@ i2StuffFifoInline(i2eBordStrPtr pB)
while ( --bailout && notClogged &&
(NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) )
{
- WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Obuf_spinlock, flags);
stripIndex = pCh->Obuf_strip;
ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff );
@@ -2031,7 +2035,7 @@ i2StuffFifoInline(i2eBordStrPtr pB)
packetSize = flowsize + sizeof(i2CmdHeader);
}
flowsize = CREDIT_USAGE(flowsize);
- paddedSize = ROUNDUP(packetSize);
+ paddedSize = roundup(packetSize, 2);
ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize );
@@ -2086,7 +2090,7 @@ WriteDBGBuf("DATA", pRemove, paddedSize);
// Done with this channel. Move to next, removing this one from the
// queue of channels if we cleaned it out (i.e., didn't get clogged.
pCh->Obuf_strip = stripIndex;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
if ( notClogged )
{
@@ -2190,10 +2194,11 @@ i2ServiceBoard ( i2eBordStrPtr pB )
if (inmail & MB_OUT_STRIPPED) {
pB->i2eFifoOutInts++;
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
pB->i2eFifoRemains = pB->i2eFifoSize;
pB->i2eWaitingForEmptyFifo = 0;
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock,
+ flags);
ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains );
diff --git a/drivers/char/ip2/i2os.h b/drivers/char/ip2/i2os.h
deleted file mode 100644
index eff9b542d69..00000000000
--- a/drivers/char/ip2/i2os.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*******************************************************************************
-*
-* (c) 1999 by Computone Corporation
-*
-********************************************************************************
-*
-*
-* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport
-* serial I/O controllers.
-*
-* DESCRIPTION: Defines, definitions and includes which are heavily dependent
-* on O/S, host, compiler, etc. This file is tailored for:
-* Linux v2.0.0 and later
-* Gnu gcc c2.7.2
-* 80x86 architecture
-*
-*******************************************************************************/
-
-#ifndef I2OS_H /* To prevent multiple includes */
-#define I2OS_H 1
-
-//-------------------------------------------------
-// Required Includes
-//-------------------------------------------------
-
-#include "ip2types.h"
-#include <asm/io.h> /* For inb, etc */
-
-//------------------------------------
-// Defines for I/O instructions:
-//------------------------------------
-
-#define INB(port) inb(port)
-#define OUTB(port,value) outb((value),(port))
-#define INW(port) inw(port)
-#define OUTW(port,value) outw((value),(port))
-#define OUTSW(port,addr,count) outsw((port),(addr),(((count)+1)/2))
-#define OUTSB(port,addr,count) outsb((port),(addr),(((count)+1))&-2)
-#define INSW(port,addr,count) insw((port),(addr),(((count)+1)/2))
-#define INSB(port,addr,count) insb((port),(addr),(((count)+1))&-2)
-
-//--------------------------------------------
-// Interrupt control
-//--------------------------------------------
-
-#define LOCK_INIT(a) rwlock_init(a)
-
-#define SAVE_AND_DISABLE_INTS(a,b) { \
- /* printk("get_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- spin_lock_irqsave(a,b); \
-}
-
-#define RESTORE_INTS(a,b) { \
- /* printk("rel_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- spin_unlock_irqrestore(a,b); \
-}
-
-#define READ_LOCK_IRQSAVE(a,b) { \
- /* printk("get_read_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- read_lock_irqsave(a,b); \
-}
-
-#define READ_UNLOCK_IRQRESTORE(a,b) { \
- /* printk("rel_read_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- read_unlock_irqrestore(a,b); \
-}
-
-#define WRITE_LOCK_IRQSAVE(a,b) { \
- /* printk("get_write_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- write_lock_irqsave(a,b); \
-}
-
-#define WRITE_UNLOCK_IRQRESTORE(a,b) { \
- /* printk("rel_write_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \
- write_unlock_irqrestore(a,b); \
-}
-
-
-//------------------------------------------------------------------------------
-// Hardware-delay loop
-//
-// Probably used in only one place (see i2ellis.c) but this helps keep things
-// together. Note we have unwound the IN instructions. On machines with a
-// reasonable cache, the eight instructions (1 byte each) should fit in cache
-// nicely, and on un-cached machines, the code-fetch would tend not to dominate.
-// Note that cx is shifted so that "count" still reflects the total number of
-// iterations assuming no unwinding.
-//------------------------------------------------------------------------------
-
-//#define DELAY1MS(port,count,label)
-
-//------------------------------------------------------------------------------
-// Macros to switch to a new stack, saving stack pointers, and to restore the
-// old stack (Used, for example, in i2lib.c) "heap" is the address of some
-// buffer which will become the new stack (working down from highest address).
-// The two words at the two lowest addresses in this stack are for storing the
-// SS and SP.
-//------------------------------------------------------------------------------
-
-//#define TO_NEW_STACK(heap,size)
-//#define TO_OLD_STACK(heap)
-
-//------------------------------------------------------------------------------
-// Macros to save the original IRQ vectors and masks, and to patch in new ones.
-//------------------------------------------------------------------------------
-
-//#define SAVE_IRQ_MASKS(dest)
-//#define WRITE_IRQ_MASKS(src)
-//#define SAVE_IRQ_VECTOR(value,dest)
-//#define WRITE_IRQ_VECTOR(value,src)
-
-//------------------------------------------------------------------------------
-// Macro to copy data from one far pointer to another.
-//------------------------------------------------------------------------------
-
-#define I2_MOVE_DATA(fpSource,fpDest,count) memmove(fpDest,fpSource,count);
-
-//------------------------------------------------------------------------------
-// Macros to issue eoi's to host interrupt control (IBM AT 8259-style).
-//------------------------------------------------------------------------------
-
-//#define MASTER_EOI
-//#define SLAVE_EOI
-
-#endif /* I2OS_H */
-
-
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 0a61856c631..70957acaa96 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -169,7 +169,7 @@ static int Fip_firmware_size;
static int ip2_open(PTTY, struct file *);
static void ip2_close(PTTY, struct file *);
static int ip2_write(PTTY, const unsigned char *, int);
-static void ip2_putchar(PTTY, unsigned char);
+static int ip2_putchar(PTTY, unsigned char);
static void ip2_flush_chars(PTTY);
static int ip2_write_room(PTTY);
static int ip2_chars_in_buf(PTTY);
@@ -355,14 +355,15 @@ have_requested_irq( char irq )
/* the driver initialisation function and returns what it returns. */
/******************************************************************************/
#ifdef MODULE
-int
-init_module(void)
+static int __init
+ip2_init_module(void)
{
#ifdef IP2DEBUG_INIT
printk (KERN_DEBUG "Loading module ...\n" );
#endif
return 0;
}
+module_init(ip2_init_module);
#endif /* MODULE */
/******************************************************************************/
@@ -381,8 +382,8 @@ init_module(void)
/* driver should be returned since it may be unloaded from memory. */
/******************************************************************************/
#ifdef MODULE
-void
-cleanup_module(void)
+void __exit
+ip2_cleanup_module(void)
{
int err;
int i;
@@ -452,6 +453,7 @@ cleanup_module(void)
printk (KERN_DEBUG "IP2 Unloaded\n" );
#endif
}
+module_exit(ip2_cleanup_module);
#endif /* MODULE */
static const struct tty_operations ip2_ops = {
@@ -1050,9 +1052,9 @@ set_irq( int boardnum, int boardIrq )
* Write to FIFO; don't bother to adjust fifo capacity for this, since
* board will respond almost immediately after SendMail hit.
*/
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 4);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
pB->i2eUsingIrq = boardIrq;
pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
@@ -1070,9 +1072,9 @@ set_irq( int boardnum, int boardIrq )
(CMD_OF(tempCommand))[4] = 64; // chars
(CMD_OF(tempCommand))[5] = 87; // HW_TEST
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 8);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
CHANNEL_OF(tempCommand) = 0;
PTYPE_OF(tempCommand) = PTYPE_BYPASS;
@@ -1087,9 +1089,9 @@ set_irq( int boardnum, int boardIrq )
CMD_COUNT_OF(tempCommand) = 2;
(CMD_OF(tempCommand))[0] = 44; /* get ping */
(CMD_OF(tempCommand))[1] = 200; /* 200 ms */
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 4);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
#endif
iiEnableMailIrq(pB);
@@ -1268,12 +1270,12 @@ static void do_input(struct work_struct *work)
// Data input
if ( pCh->pTTY != NULL ) {
- READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+ read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
i2Input( pCh );
} else
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
} else {
ip2trace(CHANN, ITRC_INPUT, 22, 0 );
@@ -1614,10 +1616,8 @@ ip2_close( PTTY tty, struct file *pFile )
serviceOutgoingFifo ( pCh->pMyBord );
- if ( tty->driver->flush_buffer )
- tty->driver->flush_buffer(tty);
- if ( tty->ldisc.flush_buffer )
- tty->ldisc.flush_buffer(tty);
+ tty_ldisc_flush(tty);
+ tty_driver_flush_buffer(tty);
tty->closing = 0;
pCh->pTTY = NULL;
@@ -1717,9 +1717,9 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
ip2_flush_chars( tty );
/* This is the actual move bit. Make sure it does what we need!!!!! */
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
bytesSent = i2Output( pCh, pData, count);
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
@@ -1736,7 +1736,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
/* */
/* */
/******************************************************************************/
-static void
+static int
ip2_putchar( PTTY tty, unsigned char ch )
{
i2ChanStrPtr pCh = tty->driver_data;
@@ -1744,13 +1744,14 @@ ip2_putchar( PTTY tty, unsigned char ch )
// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2_flush_chars( tty );
} else
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
+ return 1;
// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
}
@@ -1770,7 +1771,7 @@ ip2_flush_chars( PTTY tty )
i2ChanStrPtr pCh = tty->driver_data;
unsigned long flags;
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
if ( pCh->Pbuf_stuff ) {
// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
@@ -1784,7 +1785,7 @@ ip2_flush_chars( PTTY tty )
}
pCh->Pbuf_stuff -= strip;
}
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
}
/******************************************************************************/
@@ -1802,9 +1803,9 @@ ip2_write_room ( PTTY tty )
i2ChanStrPtr pCh = tty->driver_data;
unsigned long flags;
- READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
- READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
@@ -1834,12 +1835,12 @@ ip2_chars_in_buf ( PTTY tty )
pCh->Obuf_char_count + pCh->Pbuf_stuff,
pCh->Obuf_char_count, pCh->Pbuf_stuff );
#endif
- READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Obuf_spinlock, flags);
rc = pCh->Obuf_char_count;
- READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
- READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
+ read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
rc += pCh->Pbuf_stuff;
- READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
return rc;
}
@@ -1863,9 +1864,9 @@ ip2_flush_buffer( PTTY tty )
#ifdef IP2DEBUG_WRITE
printk (KERN_DEBUG "IP2: flush buffer\n" );
#endif
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
pCh->Pbuf_stuff = 0;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
i2FlushOutput( pCh );
ip2_owake(tty);
@@ -1951,15 +1952,15 @@ ip2_unthrottle ( PTTY tty )
pCh->throttled = 0;
i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
serviceOutgoingFifo( pCh->pMyBord );
- READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+ read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
#ifdef IP2DEBUG_READ
printk (KERN_DEBUG "i2Input called from unthrottle\n" );
#endif
i2Input( pCh );
} else
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
}
static void
@@ -2202,9 +2203,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
* for masking). Caller should use TIOCGICOUNT to see which one it was
*/
case TIOCMIWAIT:
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cprev = pCh->icount; /* note the counters on entry */
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
init_waitqueue_entry(&wait, current);
@@ -2224,9 +2225,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
rc = -ERESTARTSYS;
break;
}
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cnow = pCh->icount; /* atomic copy */
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
rc = -EIO; /* no change => rc */
@@ -2264,9 +2265,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
case TIOCGICOUNT:
ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cnow = pCh->icount;
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
p_cuser = argp;
rc = put_user(cnow.cts, &p_cuser->cts);
rc = put_user(cnow.dsr, &p_cuser->dsr);
@@ -2872,7 +2873,7 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
case 65: /* Board - ip2stat */
if ( pB ) {
rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
- rc = put_user(INB(pB->i2eStatus),
+ rc = put_user(inb(pB->i2eStatus),
(ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
} else {
rc = -ENODEV;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index eba2883b630..4f3cefa8eb0 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -126,8 +126,8 @@
#include <linux/delay.h>
#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/system.h>
#include <linux/pci.h>
@@ -189,7 +189,7 @@ struct isi_board {
unsigned short status;
unsigned short port_status; /* each bit for each port */
unsigned short shift_count;
- struct isi_port * ports;
+ struct isi_port *ports;
signed char count;
spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */
unsigned long flags;
@@ -205,11 +205,11 @@ struct isi_port {
u16 channel;
u16 status;
u16 closing_wait;
- struct isi_board * card;
- struct tty_struct * tty;
+ struct isi_board *card;
+ struct tty_struct *tty;
wait_queue_head_t close_wait;
wait_queue_head_t open_wait;
- unsigned char * xmit_buf;
+ unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
@@ -405,7 +405,7 @@ static void isicom_tx(unsigned long _data)
/* find next active board */
card = (prev_card + 1) & 0x0003;
- while(count-- > 0) {
+ while (count-- > 0) {
if (isi_card[card].status & BOARD_ACTIVE)
break;
card = (card + 1) & 0x0003;
@@ -428,7 +428,7 @@ static void isicom_tx(unsigned long _data)
if (retries >= 100)
goto unlock;
- for (;count > 0;count--, port++) {
+ for (; count > 0; count--, port++) {
/* port not active or tx disabled to force flow control */
if (!(port->flags & ASYNC_INITIALIZED) ||
!(port->status & ISI_TXOK))
@@ -471,9 +471,10 @@ static void isicom_tx(unsigned long _data)
break;
}
}
- if (cnt <= 0) break;
+ if (cnt <= 0)
+ break;
word_count = cnt >> 1;
- outsw(base, port->xmit_buf+port->xmit_tail,word_count);
+ outsw(base, port->xmit_buf+port->xmit_tail, word_count);
port->xmit_tail = (port->xmit_tail
+ (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
txcount -= (word_count << 1);
@@ -556,7 +557,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
tty = port->tty;
if (tty == NULL) {
word_count = byte_count >> 1;
- while(byte_count > 1) {
+ while (byte_count > 1) {
inw(base);
byte_count -= 2;
}
@@ -569,7 +570,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
if (header & 0x8000) { /* Status Packet */
header = inw(base);
- switch(header & 0xff) {
+ switch (header & 0xff) {
case 0: /* Change in EIA signals */
if (port->flags & ASYNC_CHECK_CD) {
if (port->status & ISI_DCD) {
@@ -656,7 +657,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
if (byte_count > 0) {
pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
"bytes...\n", base, channel + 1);
- while(byte_count > 0) { /* drain out unread xtra data */
+ /* drain out unread xtra data */
+ while (byte_count > 0) {
inw(base);
byte_count -= 2;
}
@@ -679,8 +681,11 @@ static void isicom_config_port(struct isi_port *port)
shift_count = card->shift_count;
unsigned char flow_ctrl;
- if (!(tty = port->tty) || !tty->termios)
+ tty = port->tty;
+
+ if (tty == NULL)
return;
+ /* FIXME: Switch to new tty baud API */
baud = C_BAUD(tty);
if (baud & CBAUDEX) {
baud &= ~CBAUDEX;
@@ -706,7 +711,7 @@ static void isicom_config_port(struct isi_port *port)
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baud++; /* 57.6 Kbps */
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baud +=2; /* 115 Kbps */
+ 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)
@@ -716,15 +721,14 @@ static void isicom_config_port(struct isi_port *port)
/* hang up */
drop_dtr(port);
return;
- }
- else
+ } else
raise_dtr(port);
if (WaitTillCardIsFree(base) == 0) {
- outw(0x8000 | (channel << shift_count) |0x03, base);
+ outw(0x8000 | (channel << shift_count) | 0x03, base);
outw(linuxb_to_isib[baud] << 8 | 0x03, base);
channel_setup = 0;
- switch(C_CSIZE(tty)) {
+ switch (C_CSIZE(tty)) {
case CS5:
channel_setup |= ISICOM_CS5;
break;
@@ -767,7 +771,7 @@ static void isicom_config_port(struct isi_port *port)
flow_ctrl |= ISICOM_INITIATE_XONXOFF;
if (WaitTillCardIsFree(base) == 0) {
- outw(0x8000 | (channel << shift_count) |0x04, base);
+ outw(0x8000 | (channel << shift_count) | 0x04, base);
outw(flow_ctrl << 8 | 0x05, base);
outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
InterruptTheCard(base);
@@ -805,20 +809,17 @@ static int isicom_setup_port(struct isi_port *port)
struct isi_board *card = port->card;
unsigned long flags;
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->flags & ASYNC_INITIALIZED)
return 0;
- }
if (!port->xmit_buf) {
- unsigned long page;
-
- if (!(page = get_zeroed_page(GFP_KERNEL)))
+ /* Relies on BKL */
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ if (page == 0)
return -ENOMEM;
-
- if (port->xmit_buf) {
+ if (port->xmit_buf)
free_page(page);
- return -ERESTARTSYS;
- }
- port->xmit_buf = (unsigned char *) page;
+ else
+ port->xmit_buf = (unsigned char *) page;
}
spin_lock_irqsave(&card->card_lock, flags);
@@ -949,21 +950,18 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
port->count++;
tty->driver_data = port;
port->tty = tty;
- if ((error = isicom_setup_port(port))!=0)
- return error;
- if ((error = block_til_ready(tty, filp, port))!=0)
- return error;
-
- return 0;
+ error = isicom_setup_port(port);
+ if (error == 0)
+ error = block_til_ready(tty, filp, port);
+ return error;
}
/* close et all */
static inline void isicom_shutdown_board(struct isi_board *bp)
{
- if (bp->status & BOARD_ACTIVE) {
+ if (bp->status & BOARD_ACTIVE)
bp->status &= ~BOARD_ACTIVE;
- }
}
/* card->lock HAS to be held */
@@ -1012,6 +1010,22 @@ static void isicom_shutdown_port(struct isi_port *port)
}
}
+static void isicom_flush_buffer(struct tty_struct *tty)
+{
+ struct isi_port *port = tty->driver_data;
+ struct isi_board *card = port->card;
+ unsigned long flags;
+
+ if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
+ return;
+
+ spin_lock_irqsave(&card->card_lock, flags);
+ port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+ spin_unlock_irqrestore(&card->card_lock, flags);
+
+ tty_wakeup(tty);
+}
+
static void isicom_close(struct tty_struct *tty, struct file *filp)
{
struct isi_port *port = tty->driver_data;
@@ -1065,8 +1079,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
isicom_shutdown_port(port);
spin_unlock_irqrestore(&card->card_lock, flags);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ isicom_flush_buffer(tty);
tty_ldisc_flush(tty);
spin_lock_irqsave(&card->card_lock, flags);
@@ -1104,7 +1117,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
spin_lock_irqsave(&card->card_lock, flags);
- while(1) {
+ while (1) {
cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
- 1, SERIAL_XMIT_SIZE - port->xmit_head));
if (cnt <= 0)
@@ -1125,28 +1138,29 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
}
/* put_char et all */
-static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
+static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
{
struct isi_port *port = tty->driver_data;
struct isi_board *card = port->card;
unsigned long flags;
if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
- return;
+ return 0;
if (!port->xmit_buf)
- return;
+ return 0;
spin_lock_irqsave(&card->card_lock, flags);
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
spin_unlock_irqrestore(&card->card_lock, flags);
- return;
+ return 0;
}
port->xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
port->xmit_cnt++;
spin_unlock_irqrestore(&card->card_lock, flags);
+ return 1;
}
/* flush_chars et all */
@@ -1258,6 +1272,8 @@ static int isicom_set_serial_info(struct isi_port *port,
if (copy_from_user(&newinfo, info, sizeof(newinfo)))
return -EFAULT;
+ lock_kernel();
+
reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
(newinfo.flags & ASYNC_SPD_MASK));
@@ -1265,12 +1281,13 @@ static int isicom_set_serial_info(struct isi_port *port,
if ((newinfo.close_delay != port->close_delay) ||
(newinfo.closing_wait != port->closing_wait) ||
((newinfo.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->flags & ~ASYNC_USR_MASK))) {
+ unlock_kernel();
return -EPERM;
- port->flags = ((port->flags & ~ ASYNC_USR_MASK) |
+ }
+ port->flags = ((port->flags & ~ASYNC_USR_MASK) |
(newinfo.flags & ASYNC_USR_MASK));
- }
- else {
+ } else {
port->close_delay = newinfo.close_delay;
port->closing_wait = newinfo.closing_wait;
port->flags = ((port->flags & ~ASYNC_FLAGS) |
@@ -1282,6 +1299,7 @@ static int isicom_set_serial_info(struct isi_port *port,
isicom_config_port(port);
spin_unlock_irqrestore(&port->card->card_lock, flags);
}
+ unlock_kernel();
return 0;
}
@@ -1290,6 +1308,7 @@ static int isicom_get_serial_info(struct isi_port *port,
{
struct serial_struct out_info;
+ lock_kernel();
memset(&out_info, 0, sizeof(out_info));
/* out_info.type = ? */
out_info.line = port - isi_ports;
@@ -1299,6 +1318,7 @@ static int isicom_get_serial_info(struct isi_port *port,
/* out_info.baud_base = ? */
out_info.close_delay = port->close_delay;
out_info.closing_wait = port->closing_wait;
+ unlock_kernel();
if (copy_to_user(info, &out_info, sizeof(out_info)))
return -EFAULT;
return 0;
@@ -1314,7 +1334,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
return -ENODEV;
- switch(cmd) {
+ switch (cmd) {
case TCSBRK:
retval = tty_check_change(tty);
if (retval)
@@ -1331,19 +1351,6 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
tty_wait_until_sent(tty, 0);
isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
return 0;
-
- case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0,
- (unsigned long __user *)argp);
-
- case TIOCSSOFTCAR:
- if (get_user(arg, (unsigned long __user *) argp))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
-
case TIOCGSERIAL:
return isicom_get_serial_info(port, argp);
@@ -1453,22 +1460,6 @@ static void isicom_hangup(struct tty_struct *tty)
wake_up_interruptible(&port->open_wait);
}
-/* flush_buffer et all */
-static void isicom_flush_buffer(struct tty_struct *tty)
-{
- struct isi_port *port = tty->driver_data;
- struct isi_board *card = port->card;
- unsigned long flags;
-
- if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
- return;
-
- spin_lock_irqsave(&card->card_lock, flags);
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- spin_unlock_irqrestore(&card->card_lock, flags);
-
- tty_wakeup(tty);
-}
/*
* Driver init and deinit functions
@@ -1592,7 +1583,7 @@ static int __devinit load_firmware(struct pci_dev *pdev,
default:
dev_err(&pdev->dev, "Unknown signature.\n");
goto end;
- }
+ }
retval = request_firmware(&fw, name, &pdev->dev);
if (retval)
@@ -1620,7 +1611,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if (WaitTillCardIsFree(base))
goto errrelfw;
- if ((status = inw(base + 0x4)) != 0) {
+ status = inw(base + 0x4);
+ if (status != 0) {
dev_warn(&pdev->dev, "Card%d rejected load header:\n"
KERN_WARNING "Address:0x%x\n"
KERN_WARNING "Count:0x%x\n"
@@ -1637,12 +1629,13 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if (WaitTillCardIsFree(base))
goto errrelfw;
- if ((status = inw(base + 0x4)) != 0) {
+ status = inw(base + 0x4);
+ if (status != 0) {
dev_err(&pdev->dev, "Card%d got out of sync.Card "
"Status:0x%x\n", index + 1, status);
goto errrelfw;
}
- }
+ }
/* XXX: should we test it by reading it back and comparing with original like
* in load firmware package? */
@@ -1666,7 +1659,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if (WaitTillCardIsFree(base))
goto errrelfw;
- if ((status = inw(base + 0x4)) != 0) {
+ status = inw(base + 0x4);
+ if (status != 0) {
dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
KERN_WARNING "Address:0x%x\n"
KERN_WARNING "Count:0x%x\n"
@@ -1699,7 +1693,8 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if (WaitTillCardIsFree(base))
goto errrelfw;
- if ((status = inw(base + 0x4)) != 0) {
+ status = inw(base + 0x4);
+ if (status != 0) {
dev_err(&pdev->dev, "Card%d verify got out of sync. "
"Card Status:0x%x\n", index + 1, status);
goto errrelfw;
@@ -1764,7 +1759,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
index + 1);
retval = -EBUSY;
goto errdec;
- }
+ }
retval = request_irq(board->irq, isicom_interrupt,
IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
@@ -1818,7 +1813,7 @@ static int __init isicom_init(void)
int retval, idx, channel;
struct isi_port *port;
- for(idx = 0; idx < BOARD_COUNT; idx++) {
+ for (idx = 0; idx < BOARD_COUNT; idx++) {
port = &isi_ports[idx * 16];
isi_card[idx].ports = port;
spin_lock_init(&isi_card[idx].card_lock);
@@ -1832,7 +1827,7 @@ static int __init isicom_init(void)
init_waitqueue_head(&port->open_wait);
init_waitqueue_head(&port->close_wait);
/* . . . */
- }
+ }
isi_card[idx].base = 0;
isi_card[idx].irq = 0;
}
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index c645455c3fd..7c8b62f162b 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -1682,16 +1682,6 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
rc = 0;
switch (cmd) {
- case TIOCGSOFTCAR:
- rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
- (unsigned __user *) arg);
- break;
- case TIOCSSOFTCAR:
- if ((rc = get_user(ival, (unsigned __user *) arg)) == 0)
- tty->termios->c_cflag =
- (tty->termios->c_cflag & ~CLOCAL) |
- (ival ? CLOCAL : 0);
- break;
case TIOCGSERIAL:
rc = stli_getserial(portp, argp);
break;
@@ -3267,7 +3257,7 @@ static int stli_initecp(struct stlibrd *brdp)
*/
EBRDINIT(brdp);
- brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
+ brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
if (brdp->membase == NULL) {
retval = -ENOMEM;
goto err_reg;
@@ -3424,7 +3414,7 @@ static int stli_initonb(struct stlibrd *brdp)
*/
EBRDINIT(brdp);
- brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
+ brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
if (brdp->membase == NULL) {
retval = -ENOMEM;
goto err_reg;
@@ -3675,7 +3665,7 @@ static int stli_eisamemprobe(struct stlibrd *brdp)
*/
for (i = 0; (i < stli_eisamempsize); i++) {
brdp->memaddr = stli_eisamemprobeaddrs[i];
- brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
+ brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize);
if (brdp->membase == NULL)
continue;
@@ -4433,6 +4423,8 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
done = 0;
rc = 0;
+ lock_kernel();
+
switch (cmd) {
case COM_GETPORTSTATS:
rc = stli_getportstats(NULL, argp);
@@ -4455,6 +4447,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
done++;
break;
}
+ unlock_kernel();
if (done)
return rc;
@@ -4472,6 +4465,8 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
if (brdp->state == 0)
return -ENODEV;
+ lock_kernel();
+
switch (cmd) {
case STL_BINTR:
EBRDINTR(brdp);
@@ -4494,6 +4489,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
rc = -ENOIOCTLCMD;
break;
}
+ unlock_kernel();
return rc;
}
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 60b934adea6..7f7e798c138 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -110,6 +110,7 @@ const int max_vals[] = {
const int NR_TYPES = ARRAY_SIZE(max_vals);
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+EXPORT_SYMBOL_GPL(kbd_table);
static struct kbd_struct *kbd = kbd_table;
struct vt_spawn_console vt_spawn_con = {
@@ -260,6 +261,7 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
} else
kd_nosound(0);
}
+EXPORT_SYMBOL(kd_mksound);
/*
* Setting the keyboard rate.
@@ -1230,7 +1232,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
if (rep &&
(!vc_kbd_mode(kbd, VC_REPEAT) ||
- (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) {
+ (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
/*
* Don't repeat a key if the input buffers are not empty and the
* characters get aren't echoed locally. This makes key repeat
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index e60a74c66e3..d83db5d880e 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -74,9 +74,8 @@ static const struct file_operations mmtimer_fops = {
* We only have comparison registers RTC1-4 currently available per
* node. RTC0 is used by SAL.
*/
-#define NUM_COMPARATORS 3
/* Check for an RTC interrupt pending */
-static int inline mmtimer_int_pending(int comparator)
+static int mmtimer_int_pending(int comparator)
{
if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) &
SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator)
@@ -84,15 +83,16 @@ static int inline mmtimer_int_pending(int comparator)
else
return 0;
}
+
/* Clear the RTC interrupt pending bit */
-static void inline mmtimer_clr_int_pending(int comparator)
+static void mmtimer_clr_int_pending(int comparator)
{
HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator);
}
/* Setup timer on comparator RTC1 */
-static void inline mmtimer_setup_int_0(u64 expires)
+static void mmtimer_setup_int_0(int cpu, u64 expires)
{
u64 val;
@@ -106,7 +106,7 @@ static void inline mmtimer_setup_int_0(u64 expires)
mmtimer_clr_int_pending(0);
val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC1_INT_CONFIG_IDX_SHFT) |
- ((u64)cpu_physical_id(smp_processor_id()) <<
+ ((u64)cpu_physical_id(cpu) <<
SH_RTC1_INT_CONFIG_PID_SHFT);
/* Set configuration */
@@ -122,7 +122,7 @@ static void inline mmtimer_setup_int_0(u64 expires)
}
/* Setup timer on comparator RTC2 */
-static void inline mmtimer_setup_int_1(u64 expires)
+static void mmtimer_setup_int_1(int cpu, u64 expires)
{
u64 val;
@@ -133,7 +133,7 @@ static void inline mmtimer_setup_int_1(u64 expires)
mmtimer_clr_int_pending(1);
val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC2_INT_CONFIG_IDX_SHFT) |
- ((u64)cpu_physical_id(smp_processor_id()) <<
+ ((u64)cpu_physical_id(cpu) <<
SH_RTC2_INT_CONFIG_PID_SHFT);
HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_CONFIG), val);
@@ -144,7 +144,7 @@ static void inline mmtimer_setup_int_1(u64 expires)
}
/* Setup timer on comparator RTC3 */
-static void inline mmtimer_setup_int_2(u64 expires)
+static void mmtimer_setup_int_2(int cpu, u64 expires)
{
u64 val;
@@ -155,7 +155,7 @@ static void inline mmtimer_setup_int_2(u64 expires)
mmtimer_clr_int_pending(2);
val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC3_INT_CONFIG_IDX_SHFT) |
- ((u64)cpu_physical_id(smp_processor_id()) <<
+ ((u64)cpu_physical_id(cpu) <<
SH_RTC3_INT_CONFIG_PID_SHFT);
HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_CONFIG), val);
@@ -170,22 +170,22 @@ static void inline mmtimer_setup_int_2(u64 expires)
* in order to insure that the setup succeeds in a deterministic time frame.
* It will check if the interrupt setup succeeded.
*/
-static int inline mmtimer_setup(int comparator, unsigned long expires)
+static int mmtimer_setup(int cpu, int comparator, unsigned long expires)
{
switch (comparator) {
case 0:
- mmtimer_setup_int_0(expires);
+ mmtimer_setup_int_0(cpu, expires);
break;
case 1:
- mmtimer_setup_int_1(expires);
+ mmtimer_setup_int_1(cpu, expires);
break;
case 2:
- mmtimer_setup_int_2(expires);
+ mmtimer_setup_int_2(cpu, expires);
break;
}
/* We might've missed our expiration time */
- if (rtc_time() < expires)
+ if (rtc_time() <= expires)
return 1;
/*
@@ -195,7 +195,7 @@ static int inline mmtimer_setup(int comparator, unsigned long expires)
return mmtimer_int_pending(comparator);
}
-static int inline mmtimer_disable_int(long nasid, int comparator)
+static int mmtimer_disable_int(long nasid, int comparator)
{
switch (comparator) {
case 0:
@@ -216,18 +216,124 @@ static int inline mmtimer_disable_int(long nasid, int comparator)
return 0;
}
-#define TIMER_OFF 0xbadcabLL
+#define COMPARATOR 1 /* The comparator to use */
-/* There is one of these for each comparator */
-typedef struct mmtimer {
- spinlock_t lock ____cacheline_aligned;
+#define TIMER_OFF 0xbadcabLL /* Timer is not setup */
+#define TIMER_SET 0 /* Comparator is set for this timer */
+
+/* There is one of these for each timer */
+struct mmtimer {
+ struct rb_node list;
struct k_itimer *timer;
- int i;
int cpu;
+};
+
+struct mmtimer_node {
+ spinlock_t lock ____cacheline_aligned;
+ struct rb_root timer_head;
+ struct rb_node *next;
struct tasklet_struct tasklet;
-} mmtimer_t;
+};
+static struct mmtimer_node *timers;
+
+
+/*
+ * Add a new mmtimer struct to the node's mmtimer list.
+ * This function assumes the struct mmtimer_node is locked.
+ */
+static void mmtimer_add_list(struct mmtimer *n)
+{
+ int nodeid = n->timer->it.mmtimer.node;
+ unsigned long expires = n->timer->it.mmtimer.expires;
+ struct rb_node **link = &timers[nodeid].timer_head.rb_node;
+ struct rb_node *parent = NULL;
+ struct mmtimer *x;
+
+ /*
+ * Find the right place in the rbtree:
+ */
+ while (*link) {
+ parent = *link;
+ x = rb_entry(parent, struct mmtimer, list);
+
+ if (expires < x->timer->it.mmtimer.expires)
+ link = &(*link)->rb_left;
+ else
+ link = &(*link)->rb_right;
+ }
+
+ /*
+ * Insert the timer to the rbtree and check whether it
+ * replaces the first pending timer
+ */
+ rb_link_node(&n->list, parent, link);
+ rb_insert_color(&n->list, &timers[nodeid].timer_head);
+
+ if (!timers[nodeid].next || expires < rb_entry(timers[nodeid].next,
+ struct mmtimer, list)->timer->it.mmtimer.expires)
+ timers[nodeid].next = &n->list;
+}
+
+/*
+ * Set the comparator for the next timer.
+ * This function assumes the struct mmtimer_node is locked.
+ */
+static void mmtimer_set_next_timer(int nodeid)
+{
+ struct mmtimer_node *n = &timers[nodeid];
+ struct mmtimer *x;
+ struct k_itimer *t;
+ int o;
+
+restart:
+ if (n->next == NULL)
+ return;
-static mmtimer_t ** timers;
+ x = rb_entry(n->next, struct mmtimer, list);
+ t = x->timer;
+ if (!t->it.mmtimer.incr) {
+ /* Not an interval timer */
+ if (!mmtimer_setup(x->cpu, COMPARATOR,
+ t->it.mmtimer.expires)) {
+ /* Late setup, fire now */
+ tasklet_schedule(&n->tasklet);
+ }
+ return;
+ }
+
+ /* Interval timer */
+ o = 0;
+ while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) {
+ unsigned long e, e1;
+ struct rb_node *next;
+ t->it.mmtimer.expires += t->it.mmtimer.incr << o;
+ t->it_overrun += 1 << o;
+ o++;
+ if (o > 20) {
+ printk(KERN_ALERT "mmtimer: cannot reschedule timer\n");
+ t->it.mmtimer.clock = TIMER_OFF;
+ n->next = rb_next(&x->list);
+ rb_erase(&x->list, &n->timer_head);
+ kfree(x);
+ goto restart;
+ }
+
+ e = t->it.mmtimer.expires;
+ next = rb_next(&x->list);
+
+ if (next == NULL)
+ continue;
+
+ e1 = rb_entry(next, struct mmtimer, list)->
+ timer->it.mmtimer.expires;
+ if (e > e1) {
+ n->next = next;
+ rb_erase(&x->list, &n->timer_head);
+ mmtimer_add_list(x);
+ goto restart;
+ }
+ }
+}
/**
* mmtimer_ioctl - ioctl interface for /dev/mmtimer
@@ -390,35 +496,6 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp)
return 0;
}
-/*
- * Schedule the next periodic interrupt. This function will attempt
- * to schedule a periodic interrupt later if necessary. If the scheduling
- * of an interrupt fails then the time to skip is lengthened
- * exponentially in order to ensure that the next interrupt
- * can be properly scheduled..
- */
-static int inline reschedule_periodic_timer(mmtimer_t *x)
-{
- int n;
- struct k_itimer *t = x->timer;
-
- t->it.mmtimer.clock = x->i;
- t->it_overrun--;
-
- n = 0;
- do {
-
- t->it.mmtimer.expires += t->it.mmtimer.incr << n;
- t->it_overrun += 1 << n;
- n++;
- if (n > 20)
- return 1;
-
- } while (!mmtimer_setup(x->i, t->it.mmtimer.expires));
-
- return 0;
-}
-
/**
* mmtimer_interrupt - timer interrupt handler
* @irq: irq received
@@ -435,71 +512,75 @@ static int inline reschedule_periodic_timer(mmtimer_t *x)
static irqreturn_t
mmtimer_interrupt(int irq, void *dev_id)
{
- int i;
unsigned long expires = 0;
int result = IRQ_NONE;
unsigned indx = cpu_to_node(smp_processor_id());
+ struct mmtimer *base;
- /*
- * Do this once for each comparison register
- */
- for (i = 0; i < NUM_COMPARATORS; i++) {
- mmtimer_t *base = timers[indx] + i;
- /* Make sure this doesn't get reused before tasklet_sched */
- spin_lock(&base->lock);
- if (base->cpu == smp_processor_id()) {
- if (base->timer)
- expires = base->timer->it.mmtimer.expires;
- /* expires test won't work with shared irqs */
- if ((mmtimer_int_pending(i) > 0) ||
- (expires && (expires < rtc_time()))) {
- mmtimer_clr_int_pending(i);
- tasklet_schedule(&base->tasklet);
- result = IRQ_HANDLED;
- }
+ spin_lock(&timers[indx].lock);
+ base = rb_entry(timers[indx].next, struct mmtimer, list);
+ if (base == NULL) {
+ spin_unlock(&timers[indx].lock);
+ return result;
+ }
+
+ if (base->cpu == smp_processor_id()) {
+ if (base->timer)
+ expires = base->timer->it.mmtimer.expires;
+ /* expires test won't work with shared irqs */
+ if ((mmtimer_int_pending(COMPARATOR) > 0) ||
+ (expires && (expires <= rtc_time()))) {
+ mmtimer_clr_int_pending(COMPARATOR);
+ tasklet_schedule(&timers[indx].tasklet);
+ result = IRQ_HANDLED;
}
- spin_unlock(&base->lock);
- expires = 0;
}
+ spin_unlock(&timers[indx].lock);
return result;
}
-void mmtimer_tasklet(unsigned long data) {
- mmtimer_t *x = (mmtimer_t *)data;
- struct k_itimer *t = x->timer;
+static void mmtimer_tasklet(unsigned long data)
+{
+ int nodeid = data;
+ struct mmtimer_node *mn = &timers[nodeid];
+ struct mmtimer *x = rb_entry(mn->next, struct mmtimer, list);
+ struct k_itimer *t;
unsigned long flags;
- if (t == NULL)
- return;
-
/* Send signal and deal with periodic signals */
- spin_lock_irqsave(&t->it_lock, flags);
- spin_lock(&x->lock);
- /* If timer was deleted between interrupt and here, leave */
- if (t != x->timer)
+ spin_lock_irqsave(&mn->lock, flags);
+ if (!mn->next)
goto out;
- t->it_overrun = 0;
- if (posix_timer_event(t, 0) != 0) {
+ x = rb_entry(mn->next, struct mmtimer, list);
+ t = x->timer;
+
+ if (t->it.mmtimer.clock == TIMER_OFF)
+ goto out;
+
+ t->it_overrun = 0;
- // printk(KERN_WARNING "mmtimer: cannot deliver signal.\n");
+ mn->next = rb_next(&x->list);
+ rb_erase(&x->list, &mn->timer_head);
+ if (posix_timer_event(t, 0) != 0)
t->it_overrun++;
- }
+
if(t->it.mmtimer.incr) {
- /* Periodic timer */
- if (reschedule_periodic_timer(x)) {
- printk(KERN_WARNING "mmtimer: unable to reschedule\n");
- x->timer = NULL;
- }
+ t->it.mmtimer.expires += t->it.mmtimer.incr;
+ mmtimer_add_list(x);
} else {
/* Ensure we don't false trigger in mmtimer_interrupt */
+ t->it.mmtimer.clock = TIMER_OFF;
t->it.mmtimer.expires = 0;
+ kfree(x);
}
+ /* Set comparator for next timer, if there is one */
+ mmtimer_set_next_timer(nodeid);
+
t->it_overrun_last = t->it_overrun;
out:
- spin_unlock(&x->lock);
- spin_unlock_irqrestore(&t->it_lock, flags);
+ spin_unlock_irqrestore(&mn->lock, flags);
}
static int sgi_timer_create(struct k_itimer *timer)
@@ -516,19 +597,50 @@ static int sgi_timer_create(struct k_itimer *timer)
*/
static int sgi_timer_del(struct k_itimer *timr)
{
- int i = timr->it.mmtimer.clock;
cnodeid_t nodeid = timr->it.mmtimer.node;
- mmtimer_t *t = timers[nodeid] + i;
unsigned long irqflags;
- if (i != TIMER_OFF) {
- spin_lock_irqsave(&t->lock, irqflags);
- mmtimer_disable_int(cnodeid_to_nasid(nodeid),i);
- t->timer = NULL;
+ spin_lock_irqsave(&timers[nodeid].lock, irqflags);
+ if (timr->it.mmtimer.clock != TIMER_OFF) {
+ unsigned long expires = timr->it.mmtimer.expires;
+ struct rb_node *n = timers[nodeid].timer_head.rb_node;
+ struct mmtimer *uninitialized_var(t);
+ int r = 0;
+
timr->it.mmtimer.clock = TIMER_OFF;
timr->it.mmtimer.expires = 0;
- spin_unlock_irqrestore(&t->lock, irqflags);
+
+ while (n) {
+ t = rb_entry(n, struct mmtimer, list);
+ if (t->timer == timr)
+ break;
+
+ if (expires < t->timer->it.mmtimer.expires)
+ n = n->rb_left;
+ else
+ n = n->rb_right;
+ }
+
+ if (!n) {
+ spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
+ return 0;
+ }
+
+ if (timers[nodeid].next == n) {
+ timers[nodeid].next = rb_next(n);
+ r = 1;
+ }
+
+ rb_erase(n, &timers[nodeid].timer_head);
+ kfree(t);
+
+ if (r) {
+ mmtimer_disable_int(cnodeid_to_nasid(nodeid),
+ COMPARATOR);
+ mmtimer_set_next_timer(nodeid);
+ }
}
+ spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
return 0;
}
@@ -557,12 +669,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
struct itimerspec * new_setting,
struct itimerspec * old_setting)
{
-
- int i;
unsigned long when, period, irqflags;
int err = 0;
cnodeid_t nodeid;
- mmtimer_t *base;
+ struct mmtimer *base;
+ struct rb_node *n;
if (old_setting)
sgi_timer_get(timr, old_setting);
@@ -575,6 +686,10 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
/* Clear timer */
return 0;
+ base = kmalloc(sizeof(struct mmtimer), GFP_KERNEL);
+ if (base == NULL)
+ return -ENOMEM;
+
if (flags & TIMER_ABSTIME) {
struct timespec n;
unsigned long now;
@@ -604,47 +719,38 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
preempt_disable();
nodeid = cpu_to_node(smp_processor_id());
-retry:
- /* Don't use an allocated timer, or a deleted one that's pending */
- for(i = 0; i< NUM_COMPARATORS; i++) {
- base = timers[nodeid] + i;
- if (!base->timer && !base->tasklet.state) {
- break;
- }
- }
-
- if (i == NUM_COMPARATORS) {
- preempt_enable();
- return -EBUSY;
- }
- spin_lock_irqsave(&base->lock, irqflags);
+ /* Lock the node timer structure */
+ spin_lock_irqsave(&timers[nodeid].lock, irqflags);
- if (base->timer || base->tasklet.state != 0) {
- spin_unlock_irqrestore(&base->lock, irqflags);
- goto retry;
- }
base->timer = timr;
base->cpu = smp_processor_id();
- timr->it.mmtimer.clock = i;
+ timr->it.mmtimer.clock = TIMER_SET;
timr->it.mmtimer.node = nodeid;
timr->it.mmtimer.incr = period;
timr->it.mmtimer.expires = when;
- if (period == 0) {
- if (!mmtimer_setup(i, when)) {
- mmtimer_disable_int(-1, i);
- posix_timer_event(timr, 0);
- timr->it.mmtimer.expires = 0;
- }
- } else {
- timr->it.mmtimer.expires -= period;
- if (reschedule_periodic_timer(base))
- err = -EINVAL;
+ n = timers[nodeid].next;
+
+ /* Add the new struct mmtimer to node's timer list */
+ mmtimer_add_list(base);
+
+ if (timers[nodeid].next == n) {
+ /* No need to reprogram comparator for now */
+ spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
+ preempt_enable();
+ return err;
}
- spin_unlock_irqrestore(&base->lock, irqflags);
+ /* We need to reprogram the comparator */
+ if (n)
+ mmtimer_disable_int(cnodeid_to_nasid(nodeid), COMPARATOR);
+
+ mmtimer_set_next_timer(nodeid);
+
+ /* Unlock the node timer structure */
+ spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
preempt_enable();
@@ -669,7 +775,6 @@ static struct k_clock sgi_clock = {
*/
static int __init mmtimer_init(void)
{
- unsigned i;
cnodeid_t node, maxn = -1;
if (!ia64_platform_is("sn2"))
@@ -706,31 +811,18 @@ static int __init mmtimer_init(void)
maxn++;
/* Allocate list of node ptrs to mmtimer_t's */
- timers = kzalloc(sizeof(mmtimer_t *)*maxn, GFP_KERNEL);
+ timers = kzalloc(sizeof(struct mmtimer_node)*maxn, GFP_KERNEL);
if (timers == NULL) {
printk(KERN_ERR "%s: failed to allocate memory for device\n",
MMTIMER_NAME);
goto out3;
}
- /* Allocate mmtimer_t's for each online node */
+ /* Initialize struct mmtimer's for each online node */
for_each_online_node(node) {
- timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node);
- if (timers[node] == NULL) {
- printk(KERN_ERR "%s: failed to allocate memory for device\n",
- MMTIMER_NAME);
- goto out4;
- }
- for (i=0; i< NUM_COMPARATORS; i++) {
- mmtimer_t * base = timers[node] + i;
-
- spin_lock_init(&base->lock);
- base->timer = NULL;
- base->cpu = 0;
- base->i = i;
- tasklet_init(&base->tasklet, mmtimer_tasklet,
- (unsigned long) (base));
- }
+ spin_lock_init(&timers[node].lock);
+ tasklet_init(&timers[node].tasklet, mmtimer_tasklet,
+ (unsigned long) node);
}
sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second;
@@ -741,11 +833,8 @@ static int __init mmtimer_init(void)
return 0;
-out4:
- for_each_online_node(node) {
- kfree(timers[node]);
- }
out3:
+ kfree(timers);
misc_deregister(&mmtimer_miscdev);
out2:
free_irq(SGI_MMTIMER_VECTOR, NULL);
@@ -754,4 +843,3 @@ out1:
}
module_init(mmtimer_init);
-
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 64b7b2b1835..d57d3a61919 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -2,7 +2,8 @@
/*
* moxa.c -- MOXA Intellio family multiport serial driver.
*
- * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com.tw).
+ * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com).
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
*
* This code is loosely based on the Linux serial driver, written by
* Linus Torvalds, Theodore T'so and others.
@@ -25,6 +26,7 @@
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/errno.h>
+#include <linux/firmware.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
@@ -41,21 +43,26 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
-#include <linux/completion.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#define MOXA_VERSION "5.1k"
+#include "moxa.h"
+
+#define MOXA_VERSION "6.0k"
+
+#define MOXA_FW_HDRLEN 32
#define MOXAMAJOR 172
-#define MOXACUMAJOR 173
#define MAX_BOARDS 4 /* Don't change this value */
#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)
+#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \
+ (brd)->boardType == MOXA_BOARD_C320_PCI)
+
/*
* Define the Moxa PCI vendor and device IDs.
*/
@@ -92,24 +99,16 @@ static struct pci_device_id moxa_pcibrds[] = {
MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
#endif /* CONFIG_PCI */
-struct moxa_isa_board_conf {
- int boardType;
- int numPorts;
- unsigned long baseAddr;
-};
-
-static struct moxa_isa_board_conf moxa_isa_boards[] =
-{
-/* {MOXA_BOARD_C218_ISA,8,0xDC000}, */
-};
+struct moxa_port;
static struct moxa_board_conf {
int boardType;
int numPorts;
- unsigned long baseAddr;
int busType;
- int loadstat;
+ unsigned int ready;
+
+ struct moxa_port *ports;
void __iomem *basemem;
void __iomem *intNdx;
@@ -131,30 +130,27 @@ struct moxaq_str {
};
struct moxa_port {
+ struct moxa_board_conf *board;
+ struct tty_struct *tty;
+ void __iomem *tableAddr;
+
int type;
- int port;
int close_delay;
- unsigned short closing_wait;
- int count;
- int blocked_open;
- long event; /* long req'd for set_bit --RR */
+ unsigned int count;
int asyncflags;
- unsigned long statusflags;
- struct tty_struct *tty;
int cflag;
+ unsigned long statusflags;
wait_queue_head_t open_wait;
- struct completion close_wait;
-
- struct timer_list emptyTimer;
- char chkPort;
- char lineCtrl;
- void __iomem *tableAddr;
- long curBaud;
- char DCDState;
- char lowChkFlag;
+ u8 DCDState;
+ u8 lineCtrl;
+ u8 lowChkFlag;
+};
- ushort breakCnt;
+struct mon_str {
+ int tick;
+ int rxcnt[MAX_PORTS];
+ int txcnt[MAX_PORTS];
};
/* statusflags */
@@ -168,20 +164,27 @@ struct moxa_port {
#define WAKEUP_CHARS 256
static int ttymajor = MOXAMAJOR;
+static struct mon_str moxaLog;
+static unsigned int moxaFuncTout = HZ / 2;
+static unsigned int moxaLowWaterChk;
+static DEFINE_MUTEX(moxa_openlock);
/* Variables for insmod */
#ifdef MODULE
-static int baseaddr[4];
-static int type[4];
-static int numports[4];
+static unsigned long baseaddr[MAX_BOARDS];
+static unsigned int type[MAX_BOARDS];
+static unsigned int numports[MAX_BOARDS];
#endif
MODULE_AUTHOR("William Chen");
MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
MODULE_LICENSE("GPL");
#ifdef MODULE
-module_param_array(type, int, NULL, 0);
-module_param_array(baseaddr, int, NULL, 0);
-module_param_array(numports, int, NULL, 0);
+module_param_array(type, uint, NULL, 0);
+MODULE_PARM_DESC(type, "card type: C218=2, C320=4");
+module_param_array(baseaddr, ulong, NULL, 0);
+MODULE_PARM_DESC(baseaddr, "base address");
+module_param_array(numports, uint, NULL, 0);
+MODULE_PARM_DESC(numports, "numports (ignored for C218)");
#endif
module_param(ttymajor, int, 0);
@@ -194,9 +197,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int);
static int moxa_write_room(struct tty_struct *);
static void moxa_flush_buffer(struct tty_struct *);
static int moxa_chars_in_buffer(struct tty_struct *);
-static void moxa_flush_chars(struct tty_struct *);
-static void moxa_put_char(struct tty_struct *, unsigned char);
-static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
static void moxa_throttle(struct tty_struct *);
static void moxa_unthrottle(struct tty_struct *);
static void moxa_set_termios(struct tty_struct *, struct ktermios *);
@@ -208,44 +208,183 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void moxa_poll(unsigned long);
static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
-static int moxa_block_till_ready(struct tty_struct *, struct file *,
- struct moxa_port *);
static void moxa_setup_empty_event(struct tty_struct *);
-static void moxa_check_xmit_empty(unsigned long);
static void moxa_shut_down(struct moxa_port *);
-static void moxa_receive_data(struct moxa_port *);
/*
* moxa board interface functions:
*/
-static void MoxaDriverInit(void);
-static int MoxaDriverIoctl(unsigned int, unsigned long, int);
-static int MoxaDriverPoll(void);
-static int MoxaPortsOfCard(int);
-static int MoxaPortIsValid(int);
-static void MoxaPortEnable(int);
-static void MoxaPortDisable(int);
-static long MoxaPortGetMaxBaud(int);
-static long MoxaPortSetBaud(int, long);
-static int MoxaPortSetTermio(int, struct ktermios *, speed_t);
-static int MoxaPortGetLineOut(int, int *, int *);
-static void MoxaPortLineCtrl(int, int, int);
-static void MoxaPortFlowCtrl(int, int, int, int, int, int);
-static int MoxaPortLineStatus(int);
-static int MoxaPortDCDChange(int);
-static int MoxaPortDCDON(int);
-static void MoxaPortFlushData(int, int);
-static int MoxaPortWriteData(int, unsigned char *, int);
-static int MoxaPortReadData(int, struct tty_struct *tty);
-static int MoxaPortTxQueue(int);
-static int MoxaPortRxQueue(int);
-static int MoxaPortTxFree(int);
-static void MoxaPortTxDisable(int);
-static void MoxaPortTxEnable(int);
-static int MoxaPortResetBrkCnt(int);
-static void MoxaPortSendBreak(int, int);
+static void MoxaPortEnable(struct moxa_port *);
+static void MoxaPortDisable(struct moxa_port *);
+static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
+static int MoxaPortGetLineOut(struct moxa_port *, int *, int *);
+static void MoxaPortLineCtrl(struct moxa_port *, int, int);
+static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
+static int MoxaPortLineStatus(struct moxa_port *);
+static void MoxaPortFlushData(struct moxa_port *, int);
+static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int);
+static int MoxaPortReadData(struct moxa_port *);
+static int MoxaPortTxQueue(struct moxa_port *);
+static int MoxaPortRxQueue(struct moxa_port *);
+static int MoxaPortTxFree(struct moxa_port *);
+static void MoxaPortTxDisable(struct moxa_port *);
+static void MoxaPortTxEnable(struct moxa_port *);
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 void MoxaSetFifo(struct moxa_port *port, int enable);
+
+/*
+ * I/O functions
+ */
+
+static void moxa_wait_finish(void __iomem *ofsAddr)
+{
+ unsigned long end = jiffies + moxaFuncTout;
+
+ while (readw(ofsAddr + FuncCode) != 0)
+ if (time_after(jiffies, end))
+ return;
+ if (readw(ofsAddr + FuncCode) != 0 && printk_ratelimit())
+ printk(KERN_WARNING "moxa function expired\n");
+}
+
+static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
+{
+ writew(arg, ofsAddr + FuncArg);
+ writew(cmd, ofsAddr + FuncCode);
+ moxa_wait_finish(ofsAddr);
+}
+
+static void moxa_low_water_check(void __iomem *ofsAddr)
+{
+ u16 rptr, wptr, mask, len;
+
+ if (readb(ofsAddr + FlagStat) & Xoff_state) {
+ rptr = readw(ofsAddr + RXrptr);
+ wptr = readw(ofsAddr + RXwptr);
+ mask = readw(ofsAddr + RX_mask);
+ len = (wptr - rptr) & mask;
+ if (len <= Low_water)
+ moxafunc(ofsAddr, FC_SendXon, 0);
+ }
+}
+
+/*
+ * TTY operations
+ */
+
+static int moxa_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct moxa_port *ch = tty->driver_data;
+ void __user *argp = (void __user *)arg;
+ int status, ret = 0;
+
+ if (tty->index == MAX_PORTS) {
+ if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE &&
+ cmd != MOXA_GETMSTATUS)
+ return -EINVAL;
+ } else if (!ch)
+ return -ENODEV;
+
+ switch (cmd) {
+ case MOXA_GETDATACOUNT:
+ moxaLog.tick = jiffies;
+ if (copy_to_user(argp, &moxaLog, sizeof(moxaLog)))
+ ret = -EFAULT;
+ break;
+ case MOXA_FLUSH_QUEUE:
+ MoxaPortFlushData(ch, arg);
+ break;
+ case MOXA_GET_IOQUEUE: {
+ struct moxaq_str __user *argm = argp;
+ struct moxaq_str tmp;
+ struct moxa_port *p;
+ unsigned int i, j;
+
+ mutex_lock(&moxa_openlock);
+ for (i = 0; i < MAX_BOARDS; i++) {
+ p = moxa_boards[i].ports;
+ for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
+ memset(&tmp, 0, sizeof(tmp));
+ if (moxa_boards[i].ready) {
+ tmp.inq = MoxaPortRxQueue(p);
+ tmp.outq = MoxaPortTxQueue(p);
+ }
+ if (copy_to_user(argm, &tmp, sizeof(tmp))) {
+ mutex_unlock(&moxa_openlock);
+ return -EFAULT;
+ }
+ }
+ }
+ mutex_unlock(&moxa_openlock);
+ break;
+ } case MOXA_GET_OQUEUE:
+ status = MoxaPortTxQueue(ch);
+ ret = put_user(status, (unsigned long __user *)argp);
+ break;
+ case MOXA_GET_IQUEUE:
+ status = MoxaPortRxQueue(ch);
+ ret = put_user(status, (unsigned long __user *)argp);
+ break;
+ case MOXA_GETMSTATUS: {
+ struct mxser_mstatus __user *argm = argp;
+ struct mxser_mstatus tmp;
+ struct moxa_port *p;
+ unsigned int i, j;
+
+ mutex_lock(&moxa_openlock);
+ for (i = 0; i < MAX_BOARDS; i++) {
+ p = moxa_boards[i].ports;
+ for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
+ memset(&tmp, 0, sizeof(tmp));
+ if (!moxa_boards[i].ready)
+ goto copy;
+
+ status = MoxaPortLineStatus(p);
+ if (status & 1)
+ tmp.cts = 1;
+ if (status & 2)
+ tmp.dsr = 1;
+ if (status & 4)
+ tmp.dcd = 1;
+
+ if (!p->tty || !p->tty->termios)
+ tmp.cflag = p->cflag;
+ else
+ tmp.cflag = p->tty->termios->c_cflag;
+copy:
+ if (copy_to_user(argm, &tmp, sizeof(tmp))) {
+ mutex_unlock(&moxa_openlock);
+ return -EFAULT;
+ }
+ }
+ }
+ mutex_unlock(&moxa_openlock);
+ break;
+ }
+ case TIOCGSERIAL:
+ mutex_lock(&moxa_openlock);
+ ret = moxa_get_serial_info(ch, argp);
+ mutex_unlock(&moxa_openlock);
+ break;
+ case TIOCSSERIAL:
+ mutex_lock(&moxa_openlock);
+ ret = moxa_set_serial_info(ch, argp);
+ mutex_unlock(&moxa_openlock);
+ break;
+ default:
+ ret = -ENOIOCTLCMD;
+ }
+ return ret;
+}
+
+static void moxa_break_ctl(struct tty_struct *tty, int state)
+{
+ struct moxa_port *port = tty->driver_data;
+
+ moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
+ Magic_code);
+}
static const struct tty_operations moxa_ops = {
.open = moxa_open,
@@ -254,8 +393,6 @@ static const struct tty_operations moxa_ops = {
.write_room = moxa_write_room,
.flush_buffer = moxa_flush_buffer,
.chars_in_buffer = moxa_chars_in_buffer,
- .flush_chars = moxa_flush_chars,
- .put_char = moxa_put_char,
.ioctl = moxa_ioctl,
.throttle = moxa_throttle,
.unthrottle = moxa_unthrottle,
@@ -263,15 +400,509 @@ static const struct tty_operations moxa_ops = {
.stop = moxa_stop,
.start = moxa_start,
.hangup = moxa_hangup,
+ .break_ctl = moxa_break_ctl,
.tiocmget = moxa_tiocmget,
.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);
+/*
+ * HW init
+ */
+
+static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)
+{
+ switch (brd->boardType) {
+ case MOXA_BOARD_C218_ISA:
+ case MOXA_BOARD_C218_PCI:
+ if (model != 1)
+ goto err;
+ break;
+ case MOXA_BOARD_CP204J:
+ if (model != 3)
+ goto err;
+ break;
+ default:
+ if (model != 2)
+ goto err;
+ break;
+ }
+ return 0;
+err:
+ return -EINVAL;
+}
+
+static int moxa_check_fw(const void *ptr)
+{
+ const __le16 *lptr = ptr;
+
+ if (*lptr != cpu_to_le16(0x7980))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf,
+ size_t len)
+{
+ void __iomem *baseAddr = brd->basemem;
+ u16 tmp;
+
+ writeb(HW_reset, baseAddr + Control_reg); /* reset */
+ msleep(10);
+ memset_io(baseAddr, 0, 4096);
+ memcpy_toio(baseAddr, buf, len); /* download BIOS */
+ writeb(0, baseAddr + Control_reg); /* restart */
+
+ msleep(2000);
+
+ switch (brd->boardType) {
+ case MOXA_BOARD_C218_ISA:
+ case MOXA_BOARD_C218_PCI:
+ tmp = readw(baseAddr + C218_key);
+ if (tmp != C218_KeyCode)
+ goto err;
+ break;
+ case MOXA_BOARD_CP204J:
+ tmp = readw(baseAddr + C218_key);
+ if (tmp != CP204J_KeyCode)
+ goto err;
+ break;
+ default:
+ tmp = readw(baseAddr + C320_key);
+ if (tmp != C320_KeyCode)
+ goto err;
+ tmp = readw(baseAddr + C320_status);
+ if (tmp != STS_init) {
+ printk(KERN_ERR "MOXA: bios upload failed -- CPU/Basic "
+ "module not found\n");
+ return -EIO;
+ }
+ break;
+ }
+
+ return 0;
+err:
+ printk(KERN_ERR "MOXA: bios upload failed -- board not found\n");
+ return -EIO;
+}
+
+static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr,
+ size_t len)
+{
+ void __iomem *baseAddr = brd->basemem;
+
+ if (len < 7168) {
+ printk(KERN_ERR "MOXA: invalid 320 bios -- too short\n");
+ return -EINVAL;
+ }
+
+ writew(len - 7168 - 2, baseAddr + C320bapi_len);
+ writeb(1, baseAddr + Control_reg); /* Select Page 1 */
+ memcpy_toio(baseAddr + DynPage_addr, ptr, 7168);
+ writeb(2, baseAddr + Control_reg); /* Select Page 2 */
+ memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168);
+
+ return 0;
+}
+
+static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
+ size_t len)
+{
+ void __iomem *baseAddr = brd->basemem;
+ const u16 *uptr = ptr;
+ size_t wlen, len2, j;
+ unsigned long key, loadbuf, loadlen, checksum, checksum_ok;
+ unsigned int i, retry;
+ u16 usum, keycode;
+
+ keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode :
+ C218_KeyCode;
+
+ switch (brd->boardType) {
+ case MOXA_BOARD_CP204J:
+ case MOXA_BOARD_C218_ISA:
+ case MOXA_BOARD_C218_PCI:
+ key = C218_key;
+ loadbuf = C218_LoadBuf;
+ loadlen = C218DLoad_len;
+ checksum = C218check_sum;
+ checksum_ok = C218chksum_ok;
+ break;
+ default:
+ key = C320_key;
+ keycode = C320_KeyCode;
+ loadbuf = C320_LoadBuf;
+ loadlen = C320DLoad_len;
+ checksum = C320check_sum;
+ checksum_ok = C320chksum_ok;
+ break;
+ }
+
+ usum = 0;
+ wlen = len >> 1;
+ for (i = 0; i < wlen; i++)
+ usum += le16_to_cpu(uptr[i]);
+ retry = 0;
+ do {
+ wlen = len >> 1;
+ j = 0;
+ while (wlen) {
+ len2 = (wlen > 2048) ? 2048 : wlen;
+ wlen -= len2;
+ memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1);
+ j += len2 << 1;
+
+ writew(len2, baseAddr + loadlen);
+ writew(0, baseAddr + key);
+ for (i = 0; i < 100; i++) {
+ if (readw(baseAddr + key) == keycode)
+ break;
+ msleep(10);
+ }
+ if (readw(baseAddr + key) != keycode)
+ return -EIO;
+ }
+ writew(0, baseAddr + loadlen);
+ writew(usum, baseAddr + checksum);
+ writew(0, baseAddr + key);
+ for (i = 0; i < 100; i++) {
+ if (readw(baseAddr + key) == keycode)
+ break;
+ msleep(10);
+ }
+ retry++;
+ } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3));
+ if (readb(baseAddr + checksum_ok) != 1)
+ return -EIO;
+
+ writew(0, baseAddr + key);
+ for (i = 0; i < 600; i++) {
+ if (readw(baseAddr + Magic_no) == Magic_code)
+ break;
+ msleep(10);
+ }
+ if (readw(baseAddr + Magic_no) != Magic_code)
+ return -EIO;
+
+ if (MOXA_IS_320(brd)) {
+ if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */
+ writew(0x3800, baseAddr + TMS320_PORT1);
+ writew(0x3900, baseAddr + TMS320_PORT2);
+ writew(28499, baseAddr + TMS320_CLOCK);
+ } else {
+ writew(0x3200, baseAddr + TMS320_PORT1);
+ writew(0x3400, baseAddr + TMS320_PORT2);
+ writew(19999, baseAddr + TMS320_CLOCK);
+ }
+ }
+ writew(1, baseAddr + Disable_IRQ);
+ writew(0, baseAddr + Magic_no);
+ for (i = 0; i < 500; i++) {
+ if (readw(baseAddr + Magic_no) == Magic_code)
+ break;
+ msleep(10);
+ }
+ if (readw(baseAddr + Magic_no) != Magic_code)
+ return -EIO;
+
+ if (MOXA_IS_320(brd)) {
+ j = readw(baseAddr + Module_cnt);
+ if (j <= 0)
+ return -EIO;
+ brd->numPorts = j * 8;
+ writew(j, baseAddr + Module_no);
+ writew(0, baseAddr + Magic_no);
+ for (i = 0; i < 600; i++) {
+ if (readw(baseAddr + Magic_no) == Magic_code)
+ break;
+ msleep(10);
+ }
+ if (readw(baseAddr + Magic_no) != Magic_code)
+ return -EIO;
+ }
+ brd->intNdx = baseAddr + IRQindex;
+ brd->intPend = baseAddr + IRQpending;
+ brd->intTable = baseAddr + IRQtable;
+
+ return 0;
+}
+
+static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,
+ size_t len)
+{
+ void __iomem *ofsAddr, *baseAddr = brd->basemem;
+ struct moxa_port *port;
+ int retval, i;
+
+ if (len % 2) {
+ printk(KERN_ERR "MOXA: bios length is not even\n");
+ return -EINVAL;
+ }
+
+ retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */
+ if (retval)
+ return retval;
+
+ switch (brd->boardType) {
+ case MOXA_BOARD_C218_ISA:
+ case MOXA_BOARD_C218_PCI:
+ case MOXA_BOARD_CP204J:
+ port = brd->ports;
+ for (i = 0; i < brd->numPorts; i++, port++) {
+ port->board = brd;
+ port->DCDState = 0;
+ port->tableAddr = baseAddr + Extern_table +
+ Extern_size * i;
+ ofsAddr = port->tableAddr;
+ writew(C218rx_mask, ofsAddr + RX_mask);
+ writew(C218tx_mask, ofsAddr + TX_mask);
+ writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
+ writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
+
+ writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
+ writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
+
+ }
+ break;
+ default:
+ port = brd->ports;
+ for (i = 0; i < brd->numPorts; i++, port++) {
+ port->board = brd;
+ port->DCDState = 0;
+ port->tableAddr = baseAddr + Extern_table +
+ Extern_size * i;
+ ofsAddr = port->tableAddr;
+ switch (brd->numPorts) {
+ case 8:
+ writew(C320p8rx_mask, ofsAddr + RX_mask);
+ writew(C320p8tx_mask, ofsAddr + TX_mask);
+ writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
+ writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
+ writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
+ writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
+
+ break;
+ case 16:
+ writew(C320p16rx_mask, ofsAddr + RX_mask);
+ writew(C320p16tx_mask, ofsAddr + TX_mask);
+ writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
+ writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
+ writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
+ writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
+ break;
+
+ case 24:
+ writew(C320p24rx_mask, ofsAddr + RX_mask);
+ writew(C320p24tx_mask, ofsAddr + TX_mask);
+ writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
+ writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
+ writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
+ writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
+ break;
+ case 32:
+ writew(C320p32rx_mask, ofsAddr + RX_mask);
+ writew(C320p32tx_mask, ofsAddr + TX_mask);
+ writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
+ writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
+ writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
+ writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
+ writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)
+{
+ void *ptr = fw->data;
+ char rsn[64];
+ u16 lens[5];
+ size_t len;
+ unsigned int a, lenp, lencnt;
+ int ret = -EINVAL;
+ struct {
+ __le32 magic; /* 0x34303430 */
+ u8 reserved1[2];
+ u8 type; /* UNIX = 3 */
+ u8 model; /* C218T=1, C320T=2, CP204=3 */
+ u8 reserved2[8];
+ __le16 len[5];
+ } *hdr = ptr;
+
+ BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens));
+
+ if (fw->size < MOXA_FW_HDRLEN) {
+ strcpy(rsn, "too short (even header won't fit)");
+ goto err;
+ }
+ if (hdr->magic != cpu_to_le32(0x30343034)) {
+ sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic));
+ goto err;
+ }
+ if (hdr->type != 3) {
+ sprintf(rsn, "not for linux, type is %u", hdr->type);
+ goto err;
+ }
+ if (moxa_check_fw_model(brd, hdr->model)) {
+ sprintf(rsn, "not for this card, model is %u", hdr->model);
+ goto err;
+ }
+
+ len = MOXA_FW_HDRLEN;
+ lencnt = hdr->model == 2 ? 5 : 3;
+ for (a = 0; a < ARRAY_SIZE(lens); a++) {
+ lens[a] = le16_to_cpu(hdr->len[a]);
+ if (lens[a] && len + lens[a] <= fw->size &&
+ moxa_check_fw(&fw->data[len]))
+ printk(KERN_WARNING "MOXA firmware: unexpected input "
+ "at offset %u, but going on\n", (u32)len);
+ if (!lens[a] && a < lencnt) {
+ sprintf(rsn, "too few entries in fw file");
+ goto err;
+ }
+ len += lens[a];
+ }
+
+ if (len != fw->size) {
+ sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size,
+ (u32)len);
+ goto err;
+ }
+
+ ptr += MOXA_FW_HDRLEN;
+ lenp = 0; /* bios */
+
+ strcpy(rsn, "read above");
+
+ ret = moxa_load_bios(brd, ptr, lens[lenp]);
+ if (ret)
+ goto err;
+
+ /* we skip the tty section (lens[1]), since we don't need it */
+ ptr += lens[lenp] + lens[lenp + 1];
+ lenp += 2; /* comm */
+
+ if (hdr->model == 2) {
+ ret = moxa_load_320b(brd, ptr, lens[lenp]);
+ if (ret)
+ goto err;
+ /* skip another tty */
+ ptr += lens[lenp] + lens[lenp + 1];
+ lenp += 2;
+ }
+
+ ret = moxa_load_code(brd, ptr, lens[lenp]);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn);
+ return ret;
+}
+
+static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
+{
+ const struct firmware *fw;
+ const char *file;
+ struct moxa_port *p;
+ unsigned int i;
+ int ret;
+
+ brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports),
+ GFP_KERNEL);
+ if (brd->ports == NULL) {
+ printk(KERN_ERR "cannot allocate memory for ports\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) {
+ p->type = PORT_16550A;
+ p->close_delay = 5 * HZ / 10;
+ p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
+ init_waitqueue_head(&p->open_wait);
+ }
+
+ switch (brd->boardType) {
+ case MOXA_BOARD_C218_ISA:
+ case MOXA_BOARD_C218_PCI:
+ file = "c218tunx.cod";
+ break;
+ case MOXA_BOARD_CP204J:
+ file = "cp204unx.cod";
+ break;
+ default:
+ file = "c320tunx.cod";
+ break;
+ }
+
+ ret = request_firmware(&fw, file, dev);
+ if (ret) {
+ printk(KERN_ERR "MOXA: request_firmware failed. Make sure "
+ "you've placed '%s' file into your firmware "
+ "loader directory (e.g. /lib/firmware)\n",
+ file);
+ goto err_free;
+ }
+
+ ret = moxa_load_fw(brd, fw);
+
+ release_firmware(fw);
+
+ if (ret)
+ goto err_free;
+
+ spin_lock_bh(&moxa_lock);
+ brd->ready = 1;
+ if (!timer_pending(&moxaTimer))
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
+ spin_unlock_bh(&moxa_lock);
+
+ return 0;
+err_free:
+ kfree(brd->ports);
+err:
+ return ret;
+}
+
+static void moxa_board_deinit(struct moxa_board_conf *brd)
+{
+ unsigned int a, opened;
+
+ mutex_lock(&moxa_openlock);
+ spin_lock_bh(&moxa_lock);
+ brd->ready = 0;
+ spin_unlock_bh(&moxa_lock);
+
+ /* pci hot-un-plug support */
+ for (a = 0; a < brd->numPorts; a++)
+ if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
+ tty_hangup(brd->ports[a].tty);
+ while (1) {
+ opened = 0;
+ for (a = 0; a < brd->numPorts; a++)
+ if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
+ opened++;
+ mutex_unlock(&moxa_openlock);
+ if (!opened)
+ break;
+ msleep(50);
+ mutex_lock(&moxa_openlock);
+ }
+
+ iounmap(brd->basemem);
+ brd->basemem = NULL;
+ kfree(brd->ports);
+}
+
#ifdef CONFIG_PCI
static int __devinit moxa_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -299,10 +930,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
}
board = &moxa_boards[i];
- board->basemem = pci_iomap(pdev, 2, 0x4000);
+
+ retval = pci_request_region(pdev, 2, "moxa-base");
+ if (retval) {
+ dev_err(&pdev->dev, "can't request pci region 2\n");
+ goto err;
+ }
+
+ board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000);
if (board->basemem == NULL) {
dev_err(&pdev->dev, "can't remap io space 2\n");
- goto err;
+ goto err_reg;
}
board->boardType = board_type;
@@ -321,9 +959,21 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
}
board->busType = MOXA_BUS_TYPE_PCI;
+ retval = moxa_init_board(board, &pdev->dev);
+ if (retval)
+ goto err_base;
+
pci_set_drvdata(pdev, board);
- return (0);
+ dev_info(&pdev->dev, "board '%s' ready (%u ports, firmware loaded)\n",
+ moxa_brdname[board_type - 1], board->numPorts);
+
+ return 0;
+err_base:
+ iounmap(board->basemem);
+ board->basemem = NULL;
+err_reg:
+ pci_release_region(pdev, 2);
err:
return retval;
}
@@ -332,8 +982,9 @@ 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;
+ moxa_board_deinit(brd);
+
+ pci_release_region(pdev, 2);
}
static struct pci_driver moxa_pci_driver = {
@@ -346,8 +997,8 @@ static struct pci_driver moxa_pci_driver = {
static int __init moxa_init(void)
{
- int i, numBoards, retval = 0;
- struct moxa_port *ch;
+ unsigned int isabrds = 0;
+ int retval = 0;
printk(KERN_INFO "MOXA Intellio family driver version %s\n",
MOXA_VERSION);
@@ -368,154 +1019,176 @@ static int __init moxa_init(void)
moxaDriver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(moxaDriver, &moxa_ops);
- for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) {
- ch->type = PORT_16550A;
- ch->port = i;
- ch->close_delay = 5 * HZ / 10;
- ch->closing_wait = 30 * HZ;
- ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
- init_waitqueue_head(&ch->open_wait);
- init_completion(&ch->close_wait);
-
- setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
- (unsigned long)ch);
- }
-
- pr_debug("Moxa tty devices major number = %d\n", ttymajor);
-
if (tty_register_driver(moxaDriver)) {
- printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
+ printk(KERN_ERR "can't register MOXA Smartio tty driver!\n");
put_tty_driver(moxaDriver);
return -1;
}
- mod_timer(&moxaTimer, jiffies + HZ / 50);
-
- /* Find the boards defined in source code */
- numBoards = 0;
- for (i = 0; i < MAX_BOARDS; i++) {
- if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) ||
- (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) {
- moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType;
- if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
- moxa_boards[numBoards].numPorts = 8;
- else
- moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
- moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
- moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
- pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
- numBoards + 1,
- moxa_brdname[moxa_boards[numBoards].boardType-1],
- moxa_boards[numBoards].baseAddr);
- numBoards++;
- }
- }
- /* Find the boards defined form module args. */
+ /* Find the boards defined from module args. */
#ifdef MODULE
+ {
+ struct moxa_board_conf *brd = moxa_boards;
+ unsigned int i;
for (i = 0; i < MAX_BOARDS; i++) {
- if ((type[i] == MOXA_BOARD_C218_ISA) ||
- (type[i] == MOXA_BOARD_C320_ISA)) {
+ if (!baseaddr[i])
+ break;
+ if (type[i] == MOXA_BOARD_C218_ISA ||
+ type[i] == MOXA_BOARD_C320_ISA) {
pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
- numBoards + 1, moxa_brdname[type[i] - 1],
- (unsigned long)baseaddr[i]);
- if (numBoards >= MAX_BOARDS) {
- printk(KERN_WARNING "More than %d MOXA "
- "Intellio family boards found. Board "
- "is ignored.\n", MAX_BOARDS);
+ isabrds + 1, moxa_brdname[type[i] - 1],
+ baseaddr[i]);
+ brd->boardType = type[i];
+ brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 :
+ numports[i];
+ brd->busType = MOXA_BUS_TYPE_ISA;
+ brd->basemem = ioremap_nocache(baseaddr[i], 0x4000);
+ if (!brd->basemem) {
+ printk(KERN_ERR "MOXA: can't remap %lx\n",
+ baseaddr[i]);
continue;
}
- moxa_boards[numBoards].boardType = type[i];
- if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
- moxa_boards[numBoards].numPorts = 8;
- else
- moxa_boards[numBoards].numPorts = numports[i];
- moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
- moxa_boards[numBoards].baseAddr = baseaddr[i];
- numBoards++;
+ if (moxa_init_board(brd, NULL)) {
+ iounmap(brd->basemem);
+ brd->basemem = NULL;
+ continue;
+ }
+
+ printk(KERN_INFO "MOXA isa board found at 0x%.8lu and "
+ "ready (%u ports, firmware loaded)\n",
+ baseaddr[i], brd->numPorts);
+
+ brd++;
+ isabrds++;
}
}
+ }
#endif
#ifdef CONFIG_PCI
retval = pci_register_driver(&moxa_pci_driver);
if (retval) {
- printk(KERN_ERR "Can't register moxa pci driver!\n");
- if (numBoards)
+ printk(KERN_ERR "Can't register MOXA pci driver!\n");
+ if (isabrds)
retval = 0;
}
#endif
- for (i = 0; i < numBoards; i++) {
- moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr,
- 0x4000);
- }
-
return retval;
}
static void __exit moxa_exit(void)
{
- int i;
+ unsigned int i;
- del_timer_sync(&moxaTimer);
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&moxa_pci_driver);
+#endif
+
+ for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */
+ if (moxa_boards[i].ready)
+ moxa_board_deinit(&moxa_boards[i]);
- for (i = 0; i < MAX_PORTS; i++)
- del_timer_sync(&moxa_ports[i].emptyTimer);
+ del_timer_sync(&moxaTimer);
if (tty_unregister_driver(moxaDriver))
printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
"serial driver\n");
put_tty_driver(moxaDriver);
-
-#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);
}
module_init(moxa_init);
module_exit(moxa_exit);
+static void moxa_close_port(struct moxa_port *ch)
+{
+ moxa_shut_down(ch);
+ MoxaPortFlushData(ch, 2);
+ ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
+ ch->tty->driver_data = NULL;
+ ch->tty = NULL;
+}
+
+static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
+ struct moxa_port *ch)
+{
+ DEFINE_WAIT(wait);
+ int retval = 0;
+ u8 dcd;
+
+ while (1) {
+ prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE);
+ if (tty_hung_up_p(filp)) {
+#ifdef SERIAL_DO_RESTART
+ retval = -ERESTARTSYS;
+#else
+ retval = -EAGAIN;
+#endif
+ break;
+ }
+ spin_lock_bh(&moxa_lock);
+ dcd = ch->DCDState;
+ spin_unlock_bh(&moxa_lock);
+ if (dcd)
+ break;
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ }
+ finish_wait(&ch->open_wait, &wait);
+
+ return retval;
+}
+
static int moxa_open(struct tty_struct *tty, struct file *filp)
{
+ struct moxa_board_conf *brd;
struct moxa_port *ch;
int port;
int retval;
port = tty->index;
if (port == MAX_PORTS) {
- return (0);
+ return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
}
- if (!MoxaPortIsValid(port)) {
- tty->driver_data = NULL;
- return (-ENODEV);
+ if (mutex_lock_interruptible(&moxa_openlock))
+ return -ERESTARTSYS;
+ brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
+ if (!brd->ready) {
+ mutex_unlock(&moxa_openlock);
+ return -ENODEV;
}
- ch = &moxa_ports[port];
+ ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
ch->count++;
tty->driver_data = ch;
ch->tty = tty;
if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
ch->statusflags = 0;
moxa_set_tty_param(tty, tty->termios);
- MoxaPortLineCtrl(ch->port, 1, 1);
- MoxaPortEnable(ch->port);
+ MoxaPortLineCtrl(ch, 1, 1);
+ MoxaPortEnable(ch);
+ MoxaSetFifo(ch, ch->type == PORT_16550A);
ch->asyncflags |= ASYNC_INITIALIZED;
}
- retval = moxa_block_till_ready(tty, filp, ch);
+ mutex_unlock(&moxa_openlock);
- moxa_unthrottle(tty);
-
- if (ch->type == PORT_16550A) {
- MoxaSetFifo(ch->port, 1);
- } else {
- MoxaSetFifo(ch->port, 0);
- }
+ retval = 0;
+ if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
+ retval = moxa_block_till_ready(tty, filp, ch);
+ mutex_lock(&moxa_openlock);
+ if (retval) {
+ if (ch->count) /* 0 means already hung up... */
+ if (--ch->count == 0)
+ moxa_close_port(ch);
+ } else
+ ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ mutex_unlock(&moxa_openlock);
- return (retval);
+ return retval;
}
static void moxa_close(struct tty_struct *tty, struct file *filp)
@@ -524,23 +1197,14 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
int port;
port = tty->index;
- if (port == MAX_PORTS) {
- return;
- }
- if (!MoxaPortIsValid(port)) {
- pr_debug("Invalid portno in moxa_close\n");
- tty->driver_data = NULL;
- return;
- }
- if (tty->driver_data == NULL) {
+ if (port == MAX_PORTS || tty_hung_up_p(filp))
return;
- }
- if (tty_hung_up_p(filp)) {
- return;
- }
- ch = (struct moxa_port *) tty->driver_data;
- if ((tty->count == 1) && (ch->count != 1)) {
+ mutex_lock(&moxa_openlock);
+ ch = tty->driver_data;
+ if (ch == NULL)
+ goto unlock;
+ if (tty->count == 1 && ch->count != 1) {
printk(KERN_WARNING "moxa_close: bad serial port count; "
"tty->count is 1, ch->count is %d\n", ch->count);
ch->count = 1;
@@ -550,59 +1214,35 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
"device=%s\n", tty->name);
ch->count = 0;
}
- if (ch->count) {
- return;
- }
- ch->asyncflags |= ASYNC_CLOSING;
+ if (ch->count)
+ goto unlock;
ch->cflag = tty->termios->c_cflag;
if (ch->asyncflags & ASYNC_INITIALIZED) {
moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
- del_timer_sync(&moxa_ports[ch->port].emptyTimer);
- }
- moxa_shut_down(ch);
- MoxaPortFlushData(port, 2);
-
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- tty_ldisc_flush(tty);
-
- tty->closing = 0;
- ch->event = 0;
- ch->tty = NULL;
- if (ch->blocked_open) {
- if (ch->close_delay) {
- msleep_interruptible(jiffies_to_msecs(ch->close_delay));
- }
- wake_up_interruptible(&ch->open_wait);
}
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- complete_all(&ch->close_wait);
+
+ moxa_close_port(ch);
+unlock:
+ mutex_unlock(&moxa_openlock);
}
static int moxa_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
- struct moxa_port *ch;
- int len, port;
- unsigned long flags;
+ struct moxa_port *ch = tty->driver_data;
+ int len;
- ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
- return (0);
- port = ch->port;
+ return 0;
- spin_lock_irqsave(&moxa_lock, flags);
- len = MoxaPortWriteData(port, (unsigned char *) buf, count);
- spin_unlock_irqrestore(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
+ len = MoxaPortWriteData(ch, buf, count);
+ spin_unlock_bh(&moxa_lock);
- /*********************************************
- if ( !(ch->statusflags & LOWWAIT) &&
- ((len != count) || (MoxaPortTxFree(port) <= 100)) )
- ************************************************/
ch->statusflags |= LOWWAIT;
- return (len);
+ return len;
}
static int moxa_write_room(struct tty_struct *tty)
@@ -610,27 +1250,27 @@ static int moxa_write_room(struct tty_struct *tty)
struct moxa_port *ch;
if (tty->stopped)
- return (0);
- ch = (struct moxa_port *) tty->driver_data;
+ return 0;
+ ch = tty->driver_data;
if (ch == NULL)
- return (0);
- return (MoxaPortTxFree(ch->port));
+ return 0;
+ return MoxaPortTxFree(ch);
}
static void moxa_flush_buffer(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
- MoxaPortFlushData(ch->port, 1);
+ MoxaPortFlushData(ch, 1);
tty_wakeup(tty);
}
static int moxa_chars_in_buffer(struct tty_struct *tty)
{
+ struct moxa_port *ch = tty->driver_data;
int chars;
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
/*
* Sigh...I have to check if driver_data is NULL here, because
@@ -639,8 +1279,9 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
* routine. And since the open() failed, we return 0 here. TDJ
*/
if (ch == NULL)
- return (0);
- chars = MoxaPortTxQueue(ch->port);
+ return 0;
+ lock_kernel();
+ chars = MoxaPortTxQueue(ch);
if (chars) {
/*
* Make it possible to wakeup anything waiting for output
@@ -649,73 +1290,54 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
if (!(ch->statusflags & EMPTYWAIT))
moxa_setup_empty_event(tty);
}
- return (chars);
-}
-
-static void moxa_flush_chars(struct tty_struct *tty)
-{
- /*
- * Don't think I need this, because this is called to empty the TX
- * buffer for the 16450, 16550, etc.
- */
-}
-
-static void moxa_put_char(struct tty_struct *tty, unsigned char c)
-{
- struct moxa_port *ch;
- int port;
- unsigned long flags;
-
- ch = (struct moxa_port *) tty->driver_data;
- if (ch == NULL)
- return;
- port = ch->port;
- spin_lock_irqsave(&moxa_lock, flags);
- MoxaPortWriteData(port, &c, 1);
- spin_unlock_irqrestore(&moxa_lock, flags);
- /************************************************
- if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
- *************************************************/
- ch->statusflags |= LOWWAIT;
+ unlock_kernel();
+ return chars;
}
static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
- int port;
+ struct moxa_port *ch;
int flag = 0, dtr, rts;
- port = tty->index;
- if ((port != MAX_PORTS) && (!ch))
- return (-EINVAL);
+ mutex_lock(&moxa_openlock);
+ ch = tty->driver_data;
+ if (!ch) {
+ mutex_unlock(&moxa_openlock);
+ return -EINVAL;
+ }
- MoxaPortGetLineOut(ch->port, &dtr, &rts);
+ MoxaPortGetLineOut(ch, &dtr, &rts);
if (dtr)
flag |= TIOCM_DTR;
if (rts)
flag |= TIOCM_RTS;
- dtr = MoxaPortLineStatus(ch->port);
+ dtr = MoxaPortLineStatus(ch);
if (dtr & 1)
flag |= TIOCM_CTS;
if (dtr & 2)
flag |= TIOCM_DSR;
if (dtr & 4)
flag |= TIOCM_CD;
+ mutex_unlock(&moxa_openlock);
return flag;
}
static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch;
int port;
int dtr, rts;
port = tty->index;
- if ((port != MAX_PORTS) && (!ch))
- return (-EINVAL);
+ mutex_lock(&moxa_openlock);
+ ch = tty->driver_data;
+ if (!ch) {
+ mutex_unlock(&moxa_openlock);
+ return -EINVAL;
+ }
- MoxaPortGetLineOut(ch->port, &dtr, &rts);
+ MoxaPortGetLineOut(ch, &dtr, &rts);
if (set & TIOCM_RTS)
rts = 1;
if (set & TIOCM_DTR)
@@ -724,105 +1346,51 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
rts = 0;
if (clear & TIOCM_DTR)
dtr = 0;
- MoxaPortLineCtrl(ch->port, dtr, rts);
+ MoxaPortLineCtrl(ch, dtr, rts);
+ mutex_unlock(&moxa_openlock);
return 0;
}
-static int moxa_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
- register int port;
- void __user *argp = (void __user *)arg;
- int retval;
-
- port = tty->index;
- if ((port != MAX_PORTS) && (!ch))
- return (-EINVAL);
-
- switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return (retval);
- moxa_setup_empty_event(tty);
- tty_wait_until_sent(tty, 0);
- if (!arg)
- MoxaPortSendBreak(ch->port, 0);
- return (0);
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return (retval);
- moxa_setup_empty_event(tty);
- tty_wait_until_sent(tty, 0);
- MoxaPortSendBreak(ch->port, arg);
- return (0);
- case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
- case TIOCSSOFTCAR:
- if(get_user(retval, (unsigned long __user *) argp))
- return -EFAULT;
- arg = retval;
- tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- if (C_CLOCAL(tty))
- ch->asyncflags &= ~ASYNC_CHECK_CD;
- else
- ch->asyncflags |= ASYNC_CHECK_CD;
- return (0);
- case TIOCGSERIAL:
- return moxa_get_serial_info(ch, argp);
-
- case TIOCSSERIAL:
- return moxa_set_serial_info(ch, argp);
- default:
- retval = MoxaDriverIoctl(cmd, arg, port);
- }
- return (retval);
-}
-
static void moxa_throttle(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
ch->statusflags |= THROTTLE;
}
static void moxa_unthrottle(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
ch->statusflags &= ~THROTTLE;
}
static void moxa_set_termios(struct tty_struct *tty,
- struct ktermios *old_termios)
+ struct ktermios *old_termios)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
moxa_set_tty_param(tty, old_termios);
- if (!(old_termios->c_cflag & CLOCAL) &&
- (tty->termios->c_cflag & CLOCAL))
+ if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))
wake_up_interruptible(&ch->open_wait);
}
static void moxa_stop(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
- MoxaPortTxDisable(ch->port);
+ MoxaPortTxDisable(ch);
ch->statusflags |= TXSTOPPED;
}
static void moxa_start(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
if (ch == NULL)
return;
@@ -830,91 +1398,143 @@ static void moxa_start(struct tty_struct *tty)
if (!(ch->statusflags & TXSTOPPED))
return;
- MoxaPortTxEnable(ch->port);
+ MoxaPortTxEnable(ch);
ch->statusflags &= ~TXSTOPPED;
}
static void moxa_hangup(struct tty_struct *tty)
{
- struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
+ struct moxa_port *ch;
- moxa_flush_buffer(tty);
- moxa_shut_down(ch);
- ch->event = 0;
+ mutex_lock(&moxa_openlock);
+ ch = tty->driver_data;
+ if (ch == NULL) {
+ mutex_unlock(&moxa_openlock);
+ return;
+ }
ch->count = 0;
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- ch->tty = NULL;
+ moxa_close_port(ch);
+ mutex_unlock(&moxa_openlock);
+
wake_up_interruptible(&ch->open_wait);
}
-static void moxa_poll(unsigned long ignored)
+static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{
- register int card;
- struct moxa_port *ch;
- struct tty_struct *tp;
- int i, ports;
+ dcd = !!dcd;
- del_timer(&moxaTimer);
+ if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) {
+ if (!dcd)
+ tty_hangup(p->tty);
+ }
+ p->DCDState = dcd;
+}
- if (MoxaDriverPoll() < 0) {
- mod_timer(&moxaTimer, jiffies + HZ / 50);
- return;
+static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
+ u16 __iomem *ip)
+{
+ struct tty_struct *tty = p->tty;
+ void __iomem *ofsAddr;
+ unsigned int inited = p->asyncflags & ASYNC_INITIALIZED;
+ u16 intr;
+
+ if (tty) {
+ if ((p->statusflags & EMPTYWAIT) &&
+ MoxaPortTxQueue(p) == 0) {
+ p->statusflags &= ~EMPTYWAIT;
+ tty_wakeup(tty);
+ }
+ if ((p->statusflags & LOWWAIT) && !tty->stopped &&
+ MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
+ p->statusflags &= ~LOWWAIT;
+ tty_wakeup(tty);
+ }
+
+ if (inited && !(p->statusflags & THROTTLE) &&
+ MoxaPortRxQueue(p) > 0) { /* RX */
+ MoxaPortReadData(p);
+ tty_schedule_flip(tty);
+ }
+ } else {
+ p->statusflags &= ~EMPTYWAIT;
+ MoxaPortFlushData(p, 0); /* flush RX */
}
+
+ if (!handle) /* nothing else to do */
+ return 0;
+
+ intr = readw(ip); /* port irq status */
+ if (intr == 0)
+ return 0;
+
+ writew(0, ip); /* ACK port */
+ ofsAddr = p->tableAddr;
+ if (intr & IntrTx) /* disable tx intr */
+ writew(readw(ofsAddr + HostStat) & ~WakeupTx,
+ ofsAddr + HostStat);
+
+ if (!inited)
+ return 0;
+
+ if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
+ tty_schedule_flip(tty);
+ }
+
+ if (intr & IntrLine)
+ moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+
+ return 0;
+}
+
+static void moxa_poll(unsigned long ignored)
+{
+ struct moxa_board_conf *brd;
+ u16 __iomem *ip;
+ unsigned int card, port, served = 0;
+
+ spin_lock(&moxa_lock);
for (card = 0; card < MAX_BOARDS; card++) {
- if ((ports = MoxaPortsOfCard(card)) <= 0)
+ brd = &moxa_boards[card];
+ if (!brd->ready)
continue;
- ch = &moxa_ports[card * MAX_PORTS_PER_BOARD];
- for (i = 0; i < ports; i++, ch++) {
- if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
- continue;
- if (!(ch->statusflags & THROTTLE) &&
- (MoxaPortRxQueue(ch->port) > 0))
- moxa_receive_data(ch);
- if ((tp = ch->tty) == 0)
- continue;
- if (ch->statusflags & LOWWAIT) {
- if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
- if (!tp->stopped) {
- ch->statusflags &= ~LOWWAIT;
- tty_wakeup(tp);
- }
- }
- }
- if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) {
- tty_insert_flip_char(tp, 0, TTY_BREAK);
- tty_schedule_flip(tp);
- }
- if (MoxaPortDCDChange(ch->port)) {
- if (ch->asyncflags & ASYNC_CHECK_CD) {
- if (MoxaPortDCDON(ch->port))
- wake_up_interruptible(&ch->open_wait);
- else {
- tty_hangup(tp);
- wake_up_interruptible(&ch->open_wait);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- }
+
+ served++;
+
+ ip = NULL;
+ if (readb(brd->intPend) == 0xff)
+ ip = brd->intTable + readb(brd->intNdx);
+
+ for (port = 0; port < brd->numPorts; port++)
+ moxa_poll_port(&brd->ports[port], !!ip, ip + port);
+
+ if (ip)
+ writeb(0, brd->intPend); /* ACK */
+
+ if (moxaLowWaterChk) {
+ struct moxa_port *p = brd->ports;
+ for (port = 0; port < brd->numPorts; port++, p++)
+ if (p->lowChkFlag) {
+ p->lowChkFlag = 0;
+ moxa_low_water_check(p->tableAddr);
}
- }
}
}
+ moxaLowWaterChk = 0;
- mod_timer(&moxaTimer, jiffies + HZ / 50);
+ if (served)
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
+ spin_unlock(&moxa_lock);
}
/******************************************************************************/
static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios)
{
- register struct ktermios *ts;
- struct moxa_port *ch;
+ register struct ktermios *ts = tty->termios;
+ struct moxa_port *ch = tty->driver_data;
int rts, cts, txflow, rxflow, xany, baud;
- ch = (struct moxa_port *) tty->driver_data;
- ts = tty->termios;
- if (ts->c_cflag & CLOCAL)
- ch->asyncflags &= ~ASYNC_CHECK_CD;
- else
- ch->asyncflags |= ASYNC_CHECK_CD;
rts = cts = txflow = rxflow = xany = 0;
if (ts->c_cflag & CRTSCTS)
rts = cts = 1;
@@ -927,776 +1547,60 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
/* Clear the features we don't support */
ts->c_cflag &= ~CMSPAR;
- MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
- baud = MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
+ MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany);
+ baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty));
if (baud == -1)
baud = tty_termios_baud_rate(old_termios);
/* Not put the baud rate into the termios data */
tty_encode_baud_rate(tty, baud, baud);
}
-static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
- struct moxa_port *ch)
-{
- DECLARE_WAITQUEUE(wait,current);
- unsigned long flags;
- int retval;
- int do_clocal = C_CLOCAL(tty);
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
- if (ch->asyncflags & ASYNC_CLOSING)
- wait_for_completion_interruptible(&ch->close_wait);
-#ifdef SERIAL_DO_RESTART
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
- return (-EAGAIN);
- else
- return (-ERESTARTSYS);
-#else
- return (-EAGAIN);
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if (filp->f_flags & O_NONBLOCK) {
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
- return (0);
- }
- /*
- * Block waiting for the carrier detect and the line to become free
- */
- retval = 0;
- add_wait_queue(&ch->open_wait, &wait);
- pr_debug("block_til_ready before block: ttys%d, count = %d\n",
- ch->port, ch->count);
- spin_lock_irqsave(&moxa_lock, flags);
- if (!tty_hung_up_p(filp))
- ch->count--;
- ch->blocked_open++;
- spin_unlock_irqrestore(&moxa_lock, flags);
-
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
- MoxaPortDCDON(ch->port)))
- break;
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&ch->open_wait, &wait);
-
- spin_lock_irqsave(&moxa_lock, flags);
- if (!tty_hung_up_p(filp))
- ch->count++;
- ch->blocked_open--;
- spin_unlock_irqrestore(&moxa_lock, flags);
- pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
- ch->port, ch->count);
- if (retval)
- return (retval);
- /* FIXME: review to see if we need to use set_bit on these */
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
static void moxa_setup_empty_event(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
- unsigned long flags;
- spin_lock_irqsave(&moxa_lock, flags);
+ spin_lock_bh(&moxa_lock);
ch->statusflags |= EMPTYWAIT;
- mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
- spin_unlock_irqrestore(&moxa_lock, flags);
-}
-
-static void moxa_check_xmit_empty(unsigned long data)
-{
- struct moxa_port *ch;
-
- ch = (struct moxa_port *) data;
- if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
- if (MoxaPortTxQueue(ch->port) == 0) {
- ch->statusflags &= ~EMPTYWAIT;
- tty_wakeup(ch->tty);
- return;
- }
- mod_timer(&moxa_ports[ch->port].emptyTimer,
- round_jiffies(jiffies + HZ));
- } else
- ch->statusflags &= ~EMPTYWAIT;
+ spin_unlock_bh(&moxa_lock);
}
static void moxa_shut_down(struct moxa_port *ch)
{
- struct tty_struct *tp;
+ struct tty_struct *tp = ch->tty;
if (!(ch->asyncflags & ASYNC_INITIALIZED))
return;
- tp = ch->tty;
-
- MoxaPortDisable(ch->port);
+ MoxaPortDisable(ch);
/*
* If we're a modem control device and HUPCL is on, drop RTS & DTR.
*/
- if (tp->termios->c_cflag & HUPCL)
- MoxaPortLineCtrl(ch->port, 0, 0);
+ if (C_HUPCL(tp))
+ MoxaPortLineCtrl(ch, 0, 0);
+ spin_lock_bh(&moxa_lock);
ch->asyncflags &= ~ASYNC_INITIALIZED;
+ spin_unlock_bh(&moxa_lock);
}
-static void moxa_receive_data(struct moxa_port *ch)
-{
- struct tty_struct *tp;
- struct ktermios *ts;
- unsigned long flags;
-
- ts = NULL;
- tp = ch->tty;
- if (tp)
- ts = tp->termios;
- /**************************************************
- if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
- *****************************************************/
- if (!tp || !ts) {
- MoxaPortFlushData(ch->port, 0);
- return;
- }
- spin_lock_irqsave(&moxa_lock, flags);
- MoxaPortReadData(ch->port, tp);
- spin_unlock_irqrestore(&moxa_lock, flags);
- tty_schedule_flip(tp);
-}
-
-#define Magic_code 0x404
-
-/*
- * System Configuration
- */
-/*
- * for C218 BIOS initialization
- */
-#define C218_ConfBase 0x800
-#define C218_status (C218_ConfBase + 0) /* BIOS running status */
-#define C218_diag (C218_ConfBase + 2) /* diagnostic status */
-#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */
-#define C218DLoad_len (C218_ConfBase + 6) /* WORD */
-#define C218check_sum (C218_ConfBase + 8) /* BYTE */
-#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */
-#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */
-#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */
-#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */
-#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */
-
-#define C218_LoadBuf 0x0F00
-#define C218_KeyCode 0x218
-#define CP204J_KeyCode 0x204
-
-/*
- * for C320 BIOS initialization
- */
-#define C320_ConfBase 0x800
-#define C320_LoadBuf 0x0f00
-#define STS_init 0x05 /* for C320_status */
-
-#define C320_status C320_ConfBase + 0 /* BIOS running status */
-#define C320_diag C320_ConfBase + 2 /* diagnostic status */
-#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */
-#define C320DLoad_len C320_ConfBase + 6 /* WORD */
-#define C320check_sum C320_ConfBase + 8 /* WORD */
-#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */
-#define C320bapi_len C320_ConfBase + 0x0c /* WORD */
-#define C320UART_no C320_ConfBase + 0x0e /* WORD */
-
-#define C320_KeyCode 0x320
-
-#define FixPage_addr 0x0000 /* starting addr of static page */
-#define DynPage_addr 0x2000 /* starting addr of dynamic page */
-#define C218_start 0x3000 /* starting addr of C218 BIOS prg */
-#define Control_reg 0x1ff0 /* select page and reset control */
-#define HW_reset 0x80
-
-/*
- * Function Codes
- */
-#define FC_CardReset 0x80
-#define FC_ChannelReset 1 /* C320 firmware not supported */
-#define FC_EnableCH 2
-#define FC_DisableCH 3
-#define FC_SetParam 4
-#define FC_SetMode 5
-#define FC_SetRate 6
-#define FC_LineControl 7
-#define FC_LineStatus 8
-#define FC_XmitControl 9
-#define FC_FlushQueue 10
-#define FC_SendBreak 11
-#define FC_StopBreak 12
-#define FC_LoopbackON 13
-#define FC_LoopbackOFF 14
-#define FC_ClrIrqTable 15
-#define FC_SendXon 16
-#define FC_SetTermIrq 17 /* C320 firmware not supported */
-#define FC_SetCntIrq 18 /* C320 firmware not supported */
-#define FC_SetBreakIrq 19
-#define FC_SetLineIrq 20
-#define FC_SetFlowCtl 21
-#define FC_GenIrq 22
-#define FC_InCD180 23
-#define FC_OutCD180 24
-#define FC_InUARTreg 23
-#define FC_OutUARTreg 24
-#define FC_SetXonXoff 25
-#define FC_OutCD180CCR 26
-#define FC_ExtIQueue 27
-#define FC_ExtOQueue 28
-#define FC_ClrLineIrq 29
-#define FC_HWFlowCtl 30
-#define FC_GetClockRate 35
-#define FC_SetBaud 36
-#define FC_SetDataMode 41
-#define FC_GetCCSR 43
-#define FC_GetDataError 45
-#define FC_RxControl 50
-#define FC_ImmSend 51
-#define FC_SetXonState 52
-#define FC_SetXoffState 53
-#define FC_SetRxFIFOTrig 54
-#define FC_SetTxFIFOCnt 55
-#define FC_UnixRate 56
-#define FC_UnixResetTimer 57
-
-#define RxFIFOTrig1 0
-#define RxFIFOTrig4 1
-#define RxFIFOTrig8 2
-#define RxFIFOTrig14 3
-
-/*
- * Dual-Ported RAM
- */
-#define DRAM_global 0
-#define INT_data (DRAM_global + 0)
-#define Config_base (DRAM_global + 0x108)
-
-#define IRQindex (INT_data + 0)
-#define IRQpending (INT_data + 4)
-#define IRQtable (INT_data + 8)
-
-/*
- * Interrupt Status
- */
-#define IntrRx 0x01 /* receiver data O.K. */
-#define IntrTx 0x02 /* transmit buffer empty */
-#define IntrFunc 0x04 /* function complete */
-#define IntrBreak 0x08 /* received break */
-#define IntrLine 0x10 /* line status change
- for transmitter */
-#define IntrIntr 0x20 /* received INTR code */
-#define IntrQuit 0x40 /* received QUIT code */
-#define IntrEOF 0x80 /* received EOF code */
-
-#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
-#define IntrTxTrigger 0x200 /* tx data count below trigger value */
-
-#define Magic_no (Config_base + 0)
-#define Card_model_no (Config_base + 2)
-#define Total_ports (Config_base + 4)
-#define Module_cnt (Config_base + 8)
-#define Module_no (Config_base + 10)
-#define Timer_10ms (Config_base + 14)
-#define Disable_IRQ (Config_base + 20)
-#define TMS320_PORT1 (Config_base + 22)
-#define TMS320_PORT2 (Config_base + 24)
-#define TMS320_CLOCK (Config_base + 26)
-
-/*
- * DATA BUFFER in DRAM
- */
-#define Extern_table 0x400 /* Base address of the external table
- (24 words * 64) total 3K bytes
- (24 words * 128) total 6K bytes */
-#define Extern_size 0x60 /* 96 bytes */
-#define RXrptr 0x00 /* read pointer for RX buffer */
-#define RXwptr 0x02 /* write pointer for RX buffer */
-#define TXrptr 0x04 /* read pointer for TX buffer */
-#define TXwptr 0x06 /* write pointer for TX buffer */
-#define HostStat 0x08 /* IRQ flag and general flag */
-#define FlagStat 0x0A
-#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
- /* x x x x | | | | */
- /* | | | + CTS flow */
- /* | | +--- RTS flow */
- /* | +------ TX Xon/Xoff */
- /* +--------- RX Xon/Xoff */
-#define Break_cnt 0x0E /* received break count */
-#define CD180TXirq 0x10 /* if non-0: enable TX irq */
-#define RX_mask 0x12
-#define TX_mask 0x14
-#define Ofs_rxb 0x16
-#define Ofs_txb 0x18
-#define Page_rxb 0x1A
-#define Page_txb 0x1C
-#define EndPage_rxb 0x1E
-#define EndPage_txb 0x20
-#define Data_error 0x22
-#define RxTrigger 0x28
-#define TxTrigger 0x2a
-
-#define rRXwptr 0x34
-#define Low_water 0x36
-
-#define FuncCode 0x40
-#define FuncArg 0x42
-#define FuncArg1 0x44
-
-#define C218rx_size 0x2000 /* 8K bytes */
-#define C218tx_size 0x8000 /* 32K bytes */
-
-#define C218rx_mask (C218rx_size - 1)
-#define C218tx_mask (C218tx_size - 1)
-
-#define C320p8rx_size 0x2000
-#define C320p8tx_size 0x8000
-#define C320p8rx_mask (C320p8rx_size - 1)
-#define C320p8tx_mask (C320p8tx_size - 1)
-
-#define C320p16rx_size 0x2000
-#define C320p16tx_size 0x4000
-#define C320p16rx_mask (C320p16rx_size - 1)
-#define C320p16tx_mask (C320p16tx_size - 1)
-
-#define C320p24rx_size 0x2000
-#define C320p24tx_size 0x2000
-#define C320p24rx_mask (C320p24rx_size - 1)
-#define C320p24tx_mask (C320p24tx_size - 1)
-
-#define C320p32rx_size 0x1000
-#define C320p32tx_size 0x1000
-#define C320p32rx_mask (C320p32rx_size - 1)
-#define C320p32tx_mask (C320p32tx_size - 1)
-
-#define Page_size 0x2000
-#define Page_mask (Page_size - 1)
-#define C218rx_spage 3
-#define C218tx_spage 4
-#define C218rx_pageno 1
-#define C218tx_pageno 4
-#define C218buf_pageno 5
-
-#define C320p8rx_spage 3
-#define C320p8tx_spage 4
-#define C320p8rx_pgno 1
-#define C320p8tx_pgno 4
-#define C320p8buf_pgno 5
-
-#define C320p16rx_spage 3
-#define C320p16tx_spage 4
-#define C320p16rx_pgno 1
-#define C320p16tx_pgno 2
-#define C320p16buf_pgno 3
-
-#define C320p24rx_spage 3
-#define C320p24tx_spage 4
-#define C320p24rx_pgno 1
-#define C320p24tx_pgno 1
-#define C320p24buf_pgno 2
-
-#define C320p32rx_spage 3
-#define C320p32tx_ofs C320p32rx_size
-#define C320p32tx_spage 3
-#define C320p32buf_pgno 1
-
-/*
- * Host Status
- */
-#define WakeupRx 0x01
-#define WakeupTx 0x02
-#define WakeupBreak 0x08
-#define WakeupLine 0x10
-#define WakeupIntr 0x20
-#define WakeupQuit 0x40
-#define WakeupEOF 0x80 /* used in VTIME control */
-#define WakeupRxTrigger 0x100
-#define WakeupTxTrigger 0x200
-/*
- * Flag status
- */
-#define Rx_over 0x01
-#define Xoff_state 0x02
-#define Tx_flowOff 0x04
-#define Tx_enable 0x08
-#define CTS_state 0x10
-#define DSR_state 0x20
-#define DCD_state 0x80
-/*
- * FlowControl
- */
-#define CTS_FlowCtl 1
-#define RTS_FlowCtl 2
-#define Tx_FlowCtl 4
-#define Rx_FlowCtl 8
-#define IXM_IXANY 0x10
-
-#define LowWater 128
-
-#define DTR_ON 1
-#define RTS_ON 2
-#define CTS_ON 1
-#define DSR_ON 2
-#define DCD_ON 8
-
-/* mode definition */
-#define MX_CS8 0x03
-#define MX_CS7 0x02
-#define MX_CS6 0x01
-#define MX_CS5 0x00
-
-#define MX_STOP1 0x00
-#define MX_STOP15 0x04
-#define MX_STOP2 0x08
-
-#define MX_PARNONE 0x00
-#define MX_PAREVEN 0x40
-#define MX_PARODD 0xC0
-
-/*
- * Query
- */
-
-struct mon_str {
- int tick;
- int rxcnt[MAX_PORTS];
- int txcnt[MAX_PORTS];
-};
-
-#define DCD_changed 0x01
-#define DCD_oldstate 0x80
-
-static unsigned char moxaBuff[10240];
-static int moxaLowWaterChk;
-static int moxaCard;
-static struct mon_str moxaLog;
-static int moxaFuncTout = HZ / 2;
-
-static void moxafunc(void __iomem *, int, ushort);
-static void moxa_wait_finish(void __iomem *);
-static void moxa_low_water_check(void __iomem *);
-static int moxaloadbios(int, unsigned char __user *, int);
-static int moxafindcard(int);
-static int moxaload320b(int, unsigned char __user *, int);
-static int moxaloadcode(int, unsigned char __user *, int);
-static int moxaloadc218(int, void __iomem *, int);
-static int moxaloadc320(int, void __iomem *, int, int *);
-
/*****************************************************************************
* Driver level functions: *
- * 1. MoxaDriverInit(void); *
- * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); *
- * 3. MoxaDriverPoll(void); *
*****************************************************************************/
-void MoxaDriverInit(void)
-{
- 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++) {
- p = &moxa_ports[i];
- p->chkPort = 0;
- p->lowChkFlag = 0;
- p->lineCtrl = 0;
- moxaLog.rxcnt[i] = 0;
- moxaLog.txcnt[i] = 0;
- }
-}
-
-#define MOXA 0x400
-#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */
-#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */
-#define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */
-#define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */
-#define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */
-#define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */
-#define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */
-#define MOXA_GETDATACOUNT (MOXA + 23)
-#define MOXA_GET_IOQUEUE (MOXA + 27)
-#define MOXA_FLUSH_QUEUE (MOXA + 28)
-#define MOXA_GET_CONF (MOXA + 35) /* configuration */
-#define MOXA_GET_MAJOR (MOXA + 63)
-#define MOXA_GET_CUMAJOR (MOXA + 64)
-#define MOXA_GETMSTATUS (MOXA + 65)
-
-struct dl_str {
- char __user *buf;
- int len;
- int cardno;
-};
-
-static struct dl_str dltmp;
-
-void MoxaPortFlushData(int port, int mode)
+static void MoxaPortFlushData(struct moxa_port *port, int mode)
{
void __iomem *ofsAddr;
- if ((mode < 0) || (mode > 2))
+ if (mode < 0 || mode > 2)
return;
- ofsAddr = moxa_ports[port].tableAddr;
+ ofsAddr = port->tableAddr;
moxafunc(ofsAddr, FC_FlushQueue, mode);
if (mode != 1) {
- moxa_ports[port].lowChkFlag = 0;
+ port->lowChkFlag = 0;
moxa_low_water_check(ofsAddr);
}
}
-int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
-{
- int i;
- int status;
- int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
- void __user *argp = (void __user *)arg;
-
- 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) &&
- (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
- (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
- return (-EINVAL);
- }
- switch (cmd) {
- case MOXA_GET_CONF:
- if(copy_to_user(argp, &moxa_boards, MAX_BOARDS *
- sizeof(struct moxa_board_conf)))
- return -EFAULT;
- return (0);
- case MOXA_INIT_DRIVER:
- if ((int) arg == 0x404)
- MoxaDriverInit();
- return (0);
- case MOXA_GETDATACOUNT:
- moxaLog.tick = jiffies;
- 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: {
- 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;
- }
- return (0);
- } case MOXA_GET_OQUEUE:
- i = MoxaPortTxQueue(port);
- return put_user(i, (unsigned long __user *)argp);
- case MOXA_GET_IQUEUE:
- i = MoxaPortRxQueue(port);
- return put_user(i, (unsigned long __user *)argp);
- case MOXA_GET_MAJOR:
- if(copy_to_user(argp, &ttymajor, sizeof(int)))
- return -EFAULT;
- return 0;
- case MOXA_GET_CUMAJOR:
- i = 0;
- if(copy_to_user(argp, &i, sizeof(int)))
- return -EFAULT;
- return 0;
- 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(p->port);
- if (status & 1)
- tmp.cts = 1;
- if (status & 2)
- tmp.dsr = 1;
- if (status & 4)
- tmp.dcd = 1;
- }
-
- if (!p->tty || !p->tty->termios)
- tmp.cflag = p->cflag;
- else
- tmp.cflag = p->tty->termios->c_cflag;
-copy:
- if (copy_to_user(argm, &tmp, sizeof(tmp)))
- return -EFAULT;
- }
- return 0;
- } default:
- return (-ENOIOCTLCMD);
- case MOXA_LOAD_BIOS:
- case MOXA_FIND_BOARD:
- case MOXA_LOAD_C320B:
- case MOXA_LOAD_CODE:
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- break;
- }
-
- if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
- return -EFAULT;
- if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
- return -EINVAL;
-
- switch(cmd)
- {
- case MOXA_LOAD_BIOS:
- i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
- return (i);
- case MOXA_FIND_BOARD:
- return moxafindcard(dltmp.cardno);
- case MOXA_LOAD_C320B:
- moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
- default: /* to keep gcc happy */
- return (0);
- case MOXA_LOAD_CODE:
- i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
- if (i == -1)
- return (-EFAULT);
- return (i);
-
- }
-}
-
-int MoxaDriverPoll(void)
-{
- struct moxa_board_conf *brd;
- register ushort temp;
- register int card;
- void __iomem *ofsAddr;
- void __iomem *ip;
- int port, p, ports;
-
- if (moxaCard == 0)
- return (-1);
- for (card = 0; card < MAX_BOARDS; card++) {
- brd = &moxa_boards[card];
- if (brd->loadstat == 0)
- continue;
- if ((ports = brd->numPorts) == 0)
- continue;
- 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 = moxa_ports[p].tableAddr;
- if (temp & IntrTx)
- writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
- if (temp & IntrBreak) {
- moxa_ports[p].breakCnt++;
- }
- if (temp & IntrLine) {
- if (readb(ofsAddr + FlagStat) & DCD_state) {
- if ((moxa_ports[p].DCDState & DCD_oldstate) == 0)
- moxa_ports[p].DCDState = (DCD_oldstate |
- DCD_changed);
- } else {
- if (moxa_ports[p].DCDState & DCD_oldstate)
- moxa_ports[p].DCDState = DCD_changed;
- }
- }
- }
- }
- writeb(0, brd->intPend);
- }
- if (moxaLowWaterChk) {
- p = card * MAX_PORTS_PER_BOARD;
- for (port = 0; port < ports; port++, p++) {
- if (moxa_ports[p].lowChkFlag) {
- moxa_ports[p].lowChkFlag = 0;
- ofsAddr = moxa_ports[p].tableAddr;
- moxa_low_water_check(ofsAddr);
- }
- }
- }
- }
- moxaLowWaterChk = 0;
- return (0);
-}
-
-/*****************************************************************************
- * Card level function: *
- * 1. MoxaPortsOfCard(int cardno); *
- *****************************************************************************/
-int MoxaPortsOfCard(int cardno)
-{
-
- if (moxa_boards[cardno].boardType == 0)
- return (0);
- return (moxa_boards[cardno].numPorts);
-}
-
-/*****************************************************************************
- * Port level functions: *
- * 1. MoxaPortIsValid(int port); *
- * 2. MoxaPortEnable(int port); *
- * 3. MoxaPortDisable(int port); *
- * 4. MoxaPortGetMaxBaud(int port); *
- * 6. MoxaPortSetBaud(int port, long baud); *
- * 8. MoxaPortSetTermio(int port, unsigned char *termio); *
- * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); *
- * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
- * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
- * 12. MoxaPortLineStatus(int port); *
- * 13. MoxaPortDCDChange(int port); *
- * 14. MoxaPortDCDON(int port); *
- * 15. MoxaPortFlushData(int port, int mode); *
- * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
- * 17. MoxaPortReadData(int port, struct tty_struct *tty); *
- * 20. MoxaPortTxQueue(int port); *
- * 21. MoxaPortTxFree(int port); *
- * 22. MoxaPortRxQueue(int port); *
- * 24. MoxaPortTxDisable(int port); *
- * 25. MoxaPortTxEnable(int port); *
- * 27. MoxaPortResetBrkCnt(int port); *
- * 30. MoxaPortSendBreak(int port, int ticks); *
- *****************************************************************************/
/*
* Moxa Port Number Description:
*
@@ -1733,33 +1637,6 @@ int MoxaPortsOfCard(int cardno)
* -ENOIOCTLCMD
*
*
- * Function 3: Moxa driver polling process routine.
- * Syntax:
- * int MoxaDriverPoll(void);
- *
- * return: 0 ; polling O.K.
- * -1 : no any Moxa card.
- *
- *
- * Function 4: Get the ports of this card.
- * Syntax:
- * int MoxaPortsOfCard(int cardno);
- *
- * int cardno : card number (0 - 3)
- *
- * return: 0 : this card is invalid
- * 8/16/24/32
- *
- *
- * Function 5: Check this port is valid or invalid
- * Syntax:
- * int MoxaPortIsValid(int port);
- * int port : port number (0 - 127, ref port description)
- *
- * return: 0 : this port is invalid
- * 1 : this port is valid
- *
- *
* Function 6: Enable this port to start Tx/Rx data.
* Syntax:
* void MoxaPortEnable(int port);
@@ -1772,18 +1649,9 @@ int MoxaPortsOfCard(int cardno)
* int port : port number (0 - 127)
*
*
- * Function 8: Get the maximun available baud rate of this port.
- * Syntax:
- * long MoxaPortGetMaxBaud(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : this port is invalid
- * 38400/57600/115200 bps
- *
- *
* Function 10: Setting baud rate of this port.
* Syntax:
- * long MoxaPortSetBaud(int port, long baud);
+ * speed_t MoxaPortSetBaud(int port, speed_t baud);
* int port : port number (0 - 127)
* long baud : baud rate (50 - 115200)
*
@@ -1850,25 +1718,6 @@ int MoxaPortsOfCard(int cardno)
* Bit 2 - DCD state (0: off, 1: on)
*
*
- * Function 17: Check the DCD state has changed since the last read
- * of this function.
- * Syntax:
- * int MoxaPortDCDChange(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : no changed
- * 1 : DCD has changed
- *
- *
- * Function 18: Check ths current DCD state is ON or not.
- * Syntax:
- * int MoxaPortDCDON(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : DCD off
- * 1 : DCD on
- *
- *
* Function 19: Flush the Rx/Tx buffer data of this port.
* Syntax:
* void MoxaPortFlushData(int port, int mode);
@@ -1942,40 +1791,20 @@ int MoxaPortsOfCard(int cardno)
* return: 0 - .. : BREAK signal count
*
*
- * Function 34: Send out a BREAK signal.
- * Syntax:
- * void MoxaPortSendBreak(int port, int ms100);
- * int port : port number (0 - 127)
- * int ms100 : break signal time interval.
- * unit: 100 mini-second. if ms100 == 0, it will
- * send out a about 250 ms BREAK signal.
- *
*/
-int MoxaPortIsValid(int port)
-{
-
- if (moxaCard == 0)
- return (0);
- if (moxa_ports[port].chkPort == 0)
- return (0);
- return (1);
-}
-void MoxaPortEnable(int port)
+static void MoxaPortEnable(struct moxa_port *port)
{
void __iomem *ofsAddr;
- int MoxaPortLineStatus(int);
- short lowwater = 512;
+ u16 lowwater = 512;
- ofsAddr = moxa_ports[port].tableAddr;
+ ofsAddr = port->tableAddr;
writew(lowwater, ofsAddr + Low_water);
- 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)) {
+ if (MOXA_IS_320(port->board))
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
- } else {
- writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);
- }
+ else
+ writew(readw(ofsAddr + HostStat) | WakeupBreak,
+ ofsAddr + HostStat);
moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);
moxafunc(ofsAddr, FC_FlushQueue, 2);
@@ -1984,9 +1813,9 @@ void MoxaPortEnable(int port)
MoxaPortLineStatus(port);
}
-void MoxaPortDisable(int port)
+static void MoxaPortDisable(struct moxa_port *port)
{
- void __iomem *ofsAddr = moxa_ports[port].tableAddr;
+ void __iomem *ofsAddr = port->tableAddr;
moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */
moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
@@ -1994,49 +1823,32 @@ void MoxaPortDisable(int port)
moxafunc(ofsAddr, FC_DisableCH, Magic_code);
}
-long MoxaPortGetMaxBaud(int 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))
- return (460800L);
- else
- return (921600L);
-}
-
-
-long MoxaPortSetBaud(int port, long baud)
+static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud)
{
- void __iomem *ofsAddr;
- long max, clock;
- unsigned int val;
+ void __iomem *ofsAddr = port->tableAddr;
+ unsigned int clock, val;
+ speed_t max;
- if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
- return (0);
- ofsAddr = moxa_ports[port].tableAddr;
+ max = MOXA_IS_320(port->board) ? 460800 : 921600;
+ if (baud < 50)
+ return 0;
if (baud > max)
baud = max;
- if (max == 38400L)
- clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */
- else if (max == 57600L)
- clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */
- else
- clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */
+ clock = 921600;
val = clock / baud;
moxafunc(ofsAddr, FC_SetBaud, val);
baud = clock / val;
- moxa_ports[port].curBaud = baud;
- return (baud);
+ return baud;
}
-int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
+static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
+ speed_t baud)
{
void __iomem *ofsAddr;
tcflag_t cflag;
tcflag_t mode = 0;
- if (moxa_ports[port].chkPort == 0 || termio == 0)
- return (-1);
- ofsAddr = moxa_ports[port].tableAddr;
+ ofsAddr = port->tableAddr;
cflag = termio->c_cflag; /* termio->c_cflag */
mode = termio->c_cflag & CSIZE;
@@ -2065,13 +1877,11 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
} else
mode |= MX_PARNONE;
- moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
+ moxafunc(ofsAddr, FC_SetDataMode, (u16)mode);
+
+ if (MOXA_IS_320(port->board) && baud >= 921600)
+ return -1;
- 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)) {
- if (baud >= 921600L)
- return (-1);
- }
baud = MoxaPortSetBaud(port, baud);
if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
@@ -2081,51 +1891,37 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
moxa_wait_finish(ofsAddr);
}
- return (baud);
+ return baud;
}
-int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
+static int MoxaPortGetLineOut(struct moxa_port *port, int *dtrState,
+ int *rtsState)
{
+ if (dtrState)
+ *dtrState = !!(port->lineCtrl & DTR_ON);
+ if (rtsState)
+ *rtsState = !!(port->lineCtrl & RTS_ON);
- if (!MoxaPortIsValid(port))
- return (-1);
- if (dtrState) {
- if (moxa_ports[port].lineCtrl & DTR_ON)
- *dtrState = 1;
- else
- *dtrState = 0;
- }
- if (rtsState) {
- if (moxa_ports[port].lineCtrl & RTS_ON)
- *rtsState = 1;
- else
- *rtsState = 0;
- }
- return (0);
+ return 0;
}
-void MoxaPortLineCtrl(int port, int dtr, int rts)
+static void MoxaPortLineCtrl(struct moxa_port *port, int dtr, int rts)
{
- void __iomem *ofsAddr;
- int mode;
+ u8 mode = 0;
- ofsAddr = moxa_ports[port].tableAddr;
- mode = 0;
if (dtr)
mode |= DTR_ON;
if (rts)
mode |= RTS_ON;
- moxa_ports[port].lineCtrl = mode;
- moxafunc(ofsAddr, FC_LineControl, mode);
+ port->lineCtrl = mode;
+ moxafunc(port->tableAddr, FC_LineControl, mode);
}
-void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany)
+static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts,
+ int txflow, int rxflow, int txany)
{
- void __iomem *ofsAddr;
- int mode;
+ int mode = 0;
- ofsAddr = moxa_ports[port].tableAddr;
- mode = 0;
if (rts)
mode |= RTS_FlowCtl;
if (cts)
@@ -2136,81 +1932,50 @@ void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int tx
mode |= Rx_FlowCtl;
if (txany)
mode |= IXM_IXANY;
- moxafunc(ofsAddr, FC_SetFlowCtl, mode);
+ moxafunc(port->tableAddr, FC_SetFlowCtl, mode);
}
-int MoxaPortLineStatus(int port)
+static int MoxaPortLineStatus(struct moxa_port *port)
{
void __iomem *ofsAddr;
int val;
- 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)) {
+ ofsAddr = port->tableAddr;
+ if (MOXA_IS_320(port->board)) {
moxafunc(ofsAddr, FC_LineStatus, 0);
val = readw(ofsAddr + FuncArg);
} else {
val = readw(ofsAddr + FlagStat) >> 4;
}
val &= 0x0B;
- if (val & 8) {
+ if (val & 8)
val |= 4;
- if ((moxa_ports[port].DCDState & DCD_oldstate) == 0)
- moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed);
- } else {
- if (moxa_ports[port].DCDState & DCD_oldstate)
- moxa_ports[port].DCDState = DCD_changed;
- }
+ spin_lock_bh(&moxa_lock);
+ moxa_new_dcdstate(port, val & 8);
+ spin_unlock_bh(&moxa_lock);
val &= 7;
- return (val);
-}
-
-int MoxaPortDCDChange(int port)
-{
- int n;
-
- if (moxa_ports[port].chkPort == 0)
- return (0);
- n = moxa_ports[port].DCDState;
- moxa_ports[port].DCDState &= ~DCD_changed;
- n &= DCD_changed;
- return (n);
-}
-
-int MoxaPortDCDON(int port)
-{
- int n;
-
- if (moxa_ports[port].chkPort == 0)
- return (0);
- if (moxa_ports[port].DCDState & DCD_oldstate)
- n = 1;
- else
- n = 0;
- return (n);
+ return val;
}
-int MoxaPortWriteData(int port, unsigned char * buffer, int len)
+static int MoxaPortWriteData(struct moxa_port *port,
+ const unsigned char *buffer, int len)
{
- int c, total, i;
- ushort tail;
- int cnt;
- ushort head, tx_mask, spage, epage;
- ushort pageno, pageofs, bufhead;
void __iomem *baseAddr, *ofsAddr, *ofs;
+ unsigned int c, total;
+ u16 head, tail, tx_mask, spage, epage;
+ u16 pageno, pageofs, bufhead;
- ofsAddr = moxa_ports[port].tableAddr;
- baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
+ ofsAddr = port->tableAddr;
+ baseAddr = port->board->basemem;
tx_mask = readw(ofsAddr + TX_mask);
spage = readw(ofsAddr + Page_txb);
epage = readw(ofsAddr + EndPage_txb);
tail = readw(ofsAddr + TXwptr);
head = readw(ofsAddr + TXrptr);
- c = (head > tail) ? (head - tail - 1)
- : (head - tail + tx_mask);
+ c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
if (c > len)
c = len;
- moxaLog.txcnt[port] += c;
+ moxaLog.txcnt[port->tty->index] += c;
total = c;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_txb);
@@ -2222,249 +1987,179 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len)
len = tx_mask + 1 - tail;
len = (c > len) ? len : c;
ofs = baseAddr + DynPage_addr + bufhead + tail;
- for (i = 0; i < len; i++)
- writeb(*buffer++, ofs + i);
+ memcpy_toio(ofs, buffer, len);
+ buffer += len;
tail = (tail + len) & tx_mask;
c -= len;
}
- writew(tail, ofsAddr + TXwptr);
} else {
- len = c;
pageno = spage + (tail >> 13);
pageofs = tail & Page_mask;
- do {
- cnt = Page_size - pageofs;
- if (cnt > c)
- cnt = c;
- c -= cnt;
+ while (c > 0) {
+ len = Page_size - pageofs;
+ if (len > c)
+ len = c;
writeb(pageno, baseAddr + Control_reg);
ofs = baseAddr + DynPage_addr + pageofs;
- for (i = 0; i < cnt; i++)
- writeb(*buffer++, ofs + i);
- if (c == 0) {
- writew((tail + len) & tx_mask, ofsAddr + TXwptr);
- break;
- }
+ memcpy_toio(ofs, buffer, len);
+ buffer += len;
if (++pageno == epage)
pageno = spage;
pageofs = 0;
- } while (1);
+ c -= len;
+ }
+ tail = (tail + total) & tx_mask;
}
+ writew(tail, ofsAddr + TXwptr);
writeb(1, ofsAddr + CD180TXirq); /* start to send */
- return (total);
+ return total;
}
-int MoxaPortReadData(int port, struct tty_struct *tty)
+static int MoxaPortReadData(struct moxa_port *port)
{
- register ushort head, pageofs;
- int i, count, cnt, len, total, remain;
- ushort tail, rx_mask, spage, epage;
- ushort pageno, bufhead;
+ struct tty_struct *tty = port->tty;
+ unsigned char *dst;
void __iomem *baseAddr, *ofsAddr, *ofs;
+ unsigned int count, len, total;
+ u16 tail, rx_mask, spage, epage;
+ u16 pageno, pageofs, bufhead, head;
- ofsAddr = moxa_ports[port].tableAddr;
- baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
+ ofsAddr = port->tableAddr;
+ baseAddr = port->board->basemem;
head = readw(ofsAddr + RXrptr);
tail = readw(ofsAddr + RXwptr);
rx_mask = readw(ofsAddr + RX_mask);
spage = readw(ofsAddr + Page_rxb);
epage = readw(ofsAddr + EndPage_rxb);
- count = (tail >= head) ? (tail - head)
- : (tail - head + rx_mask + 1);
+ count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1);
if (count == 0)
return 0;
total = count;
- remain = count - total;
- moxaLog.rxcnt[port] += total;
- count = total;
+ moxaLog.rxcnt[tty->index] += total;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_rxb);
writew(spage, baseAddr + Control_reg);
while (count > 0) {
- if (tail >= head)
- len = tail - head;
- else
- len = rx_mask + 1 - head;
- len = (count > len) ? len : count;
ofs = baseAddr + DynPage_addr + bufhead + head;
- for (i = 0; i < len; i++)
- tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
+ len = (tail >= head) ? (tail - head) :
+ (rx_mask + 1 - head);
+ len = tty_prepare_flip_string(tty, &dst,
+ min(len, count));
+ memcpy_fromio(dst, ofs, len);
head = (head + len) & rx_mask;
count -= len;
}
- writew(head, ofsAddr + RXrptr);
} else {
- len = count;
pageno = spage + (head >> 13);
pageofs = head & Page_mask;
- do {
- cnt = Page_size - pageofs;
- if (cnt > count)
- cnt = count;
- count -= cnt;
+ while (count > 0) {
writew(pageno, baseAddr + Control_reg);
ofs = baseAddr + DynPage_addr + pageofs;
- for (i = 0; i < cnt; i++)
- tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
- if (count == 0) {
- writew((head + len) & rx_mask, ofsAddr + RXrptr);
- break;
- }
- if (++pageno == epage)
+ len = tty_prepare_flip_string(tty, &dst,
+ min(Page_size - pageofs, count));
+ memcpy_fromio(dst, ofs, len);
+
+ count -= len;
+ pageofs = (pageofs + len) & Page_mask;
+ if (pageofs == 0 && ++pageno == epage)
pageno = spage;
- pageofs = 0;
- } while (1);
+ }
+ head = (head + total) & rx_mask;
}
- if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
+ writew(head, ofsAddr + RXrptr);
+ if (readb(ofsAddr + FlagStat) & Xoff_state) {
moxaLowWaterChk = 1;
- moxa_ports[port].lowChkFlag = 1;
+ port->lowChkFlag = 1;
}
- return (total);
+ return total;
}
-int MoxaPortTxQueue(int port)
+static int MoxaPortTxQueue(struct moxa_port *port)
{
- void __iomem *ofsAddr;
- ushort rptr, wptr, mask;
- int len;
+ void __iomem *ofsAddr = port->tableAddr;
+ u16 rptr, wptr, mask;
- ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
- len = (wptr - rptr) & mask;
- return (len);
+ return (wptr - rptr) & mask;
}
-int MoxaPortTxFree(int port)
+static int MoxaPortTxFree(struct moxa_port *port)
{
- void __iomem *ofsAddr;
- ushort rptr, wptr, mask;
- int len;
+ void __iomem *ofsAddr = port->tableAddr;
+ u16 rptr, wptr, mask;
- ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
- len = mask - ((wptr - rptr) & mask);
- return (len);
+ return mask - ((wptr - rptr) & mask);
}
-int MoxaPortRxQueue(int port)
+static int MoxaPortRxQueue(struct moxa_port *port)
{
- void __iomem *ofsAddr;
- ushort rptr, wptr, mask;
- int len;
+ void __iomem *ofsAddr = port->tableAddr;
+ u16 rptr, wptr, mask;
- ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + RXrptr);
wptr = readw(ofsAddr + RXwptr);
mask = readw(ofsAddr + RX_mask);
- len = (wptr - rptr) & mask;
- return (len);
+ return (wptr - rptr) & mask;
}
-
-void MoxaPortTxDisable(int port)
+static void MoxaPortTxDisable(struct moxa_port *port)
{
- void __iomem *ofsAddr;
-
- ofsAddr = moxa_ports[port].tableAddr;
- moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
+ moxafunc(port->tableAddr, FC_SetXoffState, Magic_code);
}
-void MoxaPortTxEnable(int port)
+static void MoxaPortTxEnable(struct moxa_port *port)
{
- void __iomem *ofsAddr;
-
- ofsAddr = moxa_ports[port].tableAddr;
- moxafunc(ofsAddr, FC_SetXonState, Magic_code);
-}
-
-
-int MoxaPortResetBrkCnt(int port)
-{
- ushort cnt;
- cnt = moxa_ports[port].breakCnt;
- moxa_ports[port].breakCnt = 0;
- return (cnt);
-}
-
-
-void MoxaPortSendBreak(int port, int ms100)
-{
- void __iomem *ofsAddr;
-
- ofsAddr = moxa_ports[port].tableAddr;
- if (ms100) {
- moxafunc(ofsAddr, FC_SendBreak, Magic_code);
- msleep(ms100 * 10);
- } else {
- moxafunc(ofsAddr, FC_SendBreak, Magic_code);
- msleep(250);
- }
- moxafunc(ofsAddr, FC_StopBreak, Magic_code);
+ moxafunc(port->tableAddr, FC_SetXonState, Magic_code);
}
static int moxa_get_serial_info(struct moxa_port *info,
- struct serial_struct __user *retinfo)
+ struct serial_struct __user *retinfo)
{
- struct serial_struct tmp;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = info->type;
- tmp.line = info->port;
- tmp.port = 0;
- tmp.irq = 0;
- tmp.flags = info->asyncflags;
- tmp.baud_base = 921600;
- tmp.close_delay = info->close_delay;
- tmp.closing_wait = info->closing_wait;
- tmp.custom_divisor = 0;
- tmp.hub6 = 0;
- if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
- return -EFAULT;
- return (0);
+ struct serial_struct tmp = {
+ .type = info->type,
+ .line = info->tty->index,
+ .flags = info->asyncflags,
+ .baud_base = 921600,
+ .close_delay = info->close_delay
+ };
+ return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
}
static int moxa_set_serial_info(struct moxa_port *info,
- struct serial_struct __user *new_info)
+ struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
- if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
return -EFAULT;
- if ((new_serial.irq != 0) ||
- (new_serial.port != 0) ||
-// (new_serial.type != info->type) ||
- (new_serial.custom_divisor != 0) ||
- (new_serial.baud_base != 921600))
- return (-EPERM);
+ if (new_serial.irq != 0 || new_serial.port != 0 ||
+ new_serial.custom_divisor != 0 ||
+ new_serial.baud_base != 921600)
+ return -EPERM;
if (!capable(CAP_SYS_ADMIN)) {
if (((new_serial.flags & ~ASYNC_USR_MASK) !=
(info->asyncflags & ~ASYNC_USR_MASK)))
- return (-EPERM);
- } else {
+ return -EPERM;
+ } else
info->close_delay = new_serial.close_delay * HZ / 100;
- info->closing_wait = new_serial.closing_wait * HZ / 100;
- }
new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
- if (new_serial.type == PORT_16550A) {
- MoxaSetFifo(info->port, 1);
- } else {
- MoxaSetFifo(info->port, 0);
- }
+ MoxaSetFifo(info, new_serial.type == PORT_16550A);
info->type = new_serial.type;
- return (0);
+ return 0;
}
@@ -2472,374 +2167,10 @@ static int moxa_set_serial_info(struct moxa_port *info,
/*****************************************************************************
* Static local functions: *
*****************************************************************************/
-static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
-{
-
- writew(arg, ofsAddr + FuncArg);
- writew(cmd, ofsAddr + FuncCode);
- moxa_wait_finish(ofsAddr);
-}
-
-static void moxa_wait_finish(void __iomem *ofsAddr)
-{
- unsigned long i, j;
-
- i = jiffies;
- while (readw(ofsAddr + FuncCode) != 0) {
- j = jiffies;
- if ((j - i) > moxaFuncTout) {
- return;
- }
- }
-}
-
-static void moxa_low_water_check(void __iomem *ofsAddr)
-{
- int len;
- ushort rptr, wptr, mask;
-
- if (readb(ofsAddr + FlagStat) & Xoff_state) {
- rptr = readw(ofsAddr + RXrptr);
- wptr = readw(ofsAddr + RXwptr);
- mask = readw(ofsAddr + RX_mask);
- len = (wptr - rptr) & mask;
- if (len <= Low_water)
- moxafunc(ofsAddr, FC_SendXon, 0);
- }
-}
-
-static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
-{
- void __iomem *baseAddr;
- int i;
-
- if(len < 0 || len > sizeof(moxaBuff))
- return -EINVAL;
- if(copy_from_user(moxaBuff, tmp, len))
- return -EFAULT;
- baseAddr = moxa_boards[cardno].basemem;
- writeb(HW_reset, baseAddr + Control_reg); /* reset */
- msleep(10);
- for (i = 0; i < 4096; i++)
- writeb(0, baseAddr + i); /* clear fix page */
- for (i = 0; i < len; i++)
- writeb(moxaBuff[i], baseAddr + i); /* download BIOS */
- writeb(0, baseAddr + Control_reg); /* restart */
- return (0);
-}
-
-static int moxafindcard(int cardno)
-{
- void __iomem *baseAddr;
- ushort tmp;
-
- baseAddr = moxa_boards[cardno].basemem;
- switch (moxa_boards[cardno].boardType) {
- case MOXA_BOARD_C218_ISA:
- case MOXA_BOARD_C218_PCI:
- if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) {
- return (-1);
- }
- break;
- case MOXA_BOARD_CP204J:
- if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) {
- return (-1);
- }
- break;
- default:
- if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) {
- return (-1);
- }
- if ((tmp = readw(baseAddr + C320_status)) != STS_init) {
- return (-2);
- }
- }
- return (0);
-}
-
-static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
-{
- void __iomem *baseAddr;
- int i;
-
- if(len < 0 || len > sizeof(moxaBuff))
- return -EINVAL;
- if(copy_from_user(moxaBuff, tmp, len))
- return -EFAULT;
- 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++)
- writeb(moxaBuff[i], baseAddr + DynPage_addr + i);
- writeb(2, baseAddr + Control_reg); /* Select Page 2 */
- for (i = 0; i < (len - 7168); i++)
- writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i);
- return (0);
-}
-
-static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
-{
- void __iomem *baseAddr, *ofsAddr;
- int retval, port, i;
-
- if(len < 0 || len > sizeof(moxaBuff))
- return -EINVAL;
- if(copy_from_user(moxaBuff, tmp, len))
- return -EFAULT;
- baseAddr = moxa_boards[cardno].basemem;
- switch (moxa_boards[cardno].boardType) {
- case MOXA_BOARD_C218_ISA:
- case MOXA_BOARD_C218_PCI:
- case MOXA_BOARD_CP204J:
- retval = moxaloadc218(cardno, baseAddr, len);
- if (retval)
- return (retval);
- port = cardno * MAX_PORTS_PER_BOARD;
- for (i = 0; i < moxa_boards[cardno].numPorts; i++, 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);
- writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
-
- writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
- writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
-
- }
- break;
- default:
- retval = moxaloadc320(cardno, baseAddr, len,
- &moxa_boards[cardno].numPorts);
- if (retval)
- return (retval);
- port = cardno * MAX_PORTS_PER_BOARD;
- for (i = 0; i < moxa_boards[cardno].numPorts; i++, 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);
- writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
- writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
- writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
- writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
-
- } else if (moxa_boards[cardno].numPorts == 16) {
- writew(C320p16rx_mask, ofsAddr + RX_mask);
- writew(C320p16tx_mask, ofsAddr + TX_mask);
- writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
- writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
- writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
- writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
-
- } else if (moxa_boards[cardno].numPorts == 24) {
- writew(C320p24rx_mask, ofsAddr + RX_mask);
- writew(C320p24tx_mask, ofsAddr + TX_mask);
- writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
- writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
- writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
- writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
- } else if (moxa_boards[cardno].numPorts == 32) {
- writew(C320p32rx_mask, ofsAddr + RX_mask);
- writew(C320p32tx_mask, ofsAddr + TX_mask);
- writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
- writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
- writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
- writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
- writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
- }
- }
- break;
- }
- moxa_boards[cardno].loadstat = 1;
- return (0);
-}
-
-static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
-{
- char retry;
- int i, j, len1, len2;
- ushort usum, *ptr, keycode;
-
- if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
- keycode = CP204J_KeyCode;
- else
- keycode = C218_KeyCode;
- usum = 0;
- len1 = len >> 1;
- ptr = (ushort *) moxaBuff;
- for (i = 0; i < len1; i++)
- usum += le16_to_cpu(*(ptr + i));
- retry = 0;
- do {
- len1 = len >> 1;
- j = 0;
- while (len1) {
- len2 = (len1 > 2048) ? 2048 : len1;
- len1 -= len2;
- for (i = 0; i < len2 << 1; i++)
- writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i);
- j += i;
-
- writew(len2, baseAddr + C218DLoad_len);
- writew(0, baseAddr + C218_key);
- for (i = 0; i < 100; i++) {
- if (readw(baseAddr + C218_key) == keycode)
- break;
- msleep(10);
- }
- if (readw(baseAddr + C218_key) != keycode) {
- return (-1);
- }
- }
- writew(0, baseAddr + C218DLoad_len);
- writew(usum, baseAddr + C218check_sum);
- writew(0, baseAddr + C218_key);
- for (i = 0; i < 100; i++) {
- if (readw(baseAddr + C218_key) == keycode)
- break;
- msleep(10);
- }
- retry++;
- } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
- if (readb(baseAddr + C218chksum_ok) != 1) {
- return (-1);
- }
- writew(0, baseAddr + C218_key);
- for (i = 0; i < 100; i++) {
- if (readw(baseAddr + Magic_no) == Magic_code)
- break;
- msleep(10);
- }
- if (readw(baseAddr + Magic_no) != Magic_code) {
- return (-1);
- }
- writew(1, baseAddr + Disable_IRQ);
- writew(0, baseAddr + Magic_no);
- for (i = 0; i < 100; i++) {
- if (readw(baseAddr + Magic_no) == Magic_code)
- break;
- msleep(10);
- }
- if (readw(baseAddr + Magic_no) != Magic_code) {
- return (-1);
- }
- moxaCard = 1;
- moxa_boards[cardno].intNdx = baseAddr + IRQindex;
- moxa_boards[cardno].intPend = baseAddr + IRQpending;
- moxa_boards[cardno].intTable = baseAddr + IRQtable;
- return (0);
-}
-
-static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
-{
- ushort usum;
- int i, j, wlen, len2, retry;
- ushort *uptr;
-
- usum = 0;
- wlen = len >> 1;
- uptr = (ushort *) moxaBuff;
- for (i = 0; i < wlen; i++)
- usum += le16_to_cpu(uptr[i]);
- retry = 0;
- j = 0;
- do {
- while (wlen) {
- if (wlen > 2048)
- len2 = 2048;
- else
- len2 = wlen;
- wlen -= len2;
- len2 <<= 1;
- for (i = 0; i < len2; i++)
- writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i);
- len2 >>= 1;
- j += i;
- writew(len2, baseAddr + C320DLoad_len);
- writew(0, baseAddr + C320_key);
- for (i = 0; i < 10; i++) {
- if (readw(baseAddr + C320_key) == C320_KeyCode)
- break;
- msleep(10);
- }
- if (readw(baseAddr + C320_key) != C320_KeyCode)
- return (-1);
- }
- writew(0, baseAddr + C320DLoad_len);
- writew(usum, baseAddr + C320check_sum);
- writew(0, baseAddr + C320_key);
- for (i = 0; i < 10; i++) {
- if (readw(baseAddr + C320_key) == C320_KeyCode)
- break;
- msleep(10);
- }
- retry++;
- } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
- if (readb(baseAddr + C320chksum_ok) != 1)
- return (-1);
- writew(0, baseAddr + C320_key);
- for (i = 0; i < 600; i++) {
- if (readw(baseAddr + Magic_no) == Magic_code)
- break;
- msleep(10);
- }
- if (readw(baseAddr + Magic_no) != Magic_code)
- return (-100);
-
- if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */
- writew(0x3800, baseAddr + TMS320_PORT1);
- writew(0x3900, baseAddr + TMS320_PORT2);
- writew(28499, baseAddr + TMS320_CLOCK);
- } else {
- writew(0x3200, baseAddr + TMS320_PORT1);
- writew(0x3400, baseAddr + TMS320_PORT2);
- writew(19999, baseAddr + TMS320_CLOCK);
- }
- writew(1, baseAddr + Disable_IRQ);
- writew(0, baseAddr + Magic_no);
- for (i = 0; i < 500; i++) {
- if (readw(baseAddr + Magic_no) == Magic_code)
- break;
- msleep(10);
- }
- if (readw(baseAddr + Magic_no) != Magic_code)
- return (-102);
-
- j = readw(baseAddr + Module_cnt);
- if (j <= 0)
- return (-101);
- *numPorts = j * 8;
- writew(j, baseAddr + Module_no);
- writew(0, baseAddr + Magic_no);
- for (i = 0; i < 600; i++) {
- if (readw(baseAddr + Magic_no) == Magic_code)
- break;
- msleep(10);
- }
- if (readw(baseAddr + Magic_no) != Magic_code)
- return (-102);
- moxaCard = 1;
- moxa_boards[cardno].intNdx = baseAddr + IRQindex;
- moxa_boards[cardno].intPend = baseAddr + IRQpending;
- moxa_boards[cardno].intTable = baseAddr + IRQtable;
- return (0);
-}
-static void MoxaSetFifo(int port, int enable)
+static void MoxaSetFifo(struct moxa_port *port, int enable)
{
- void __iomem *ofsAddr = moxa_ports[port].tableAddr;
+ void __iomem *ofsAddr = port->tableAddr;
if (!enable) {
moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h
new file mode 100644
index 00000000000..87d16ce57be
--- /dev/null
+++ b/drivers/char/moxa.h
@@ -0,0 +1,304 @@
+#ifndef MOXA_H_FILE
+#define MOXA_H_FILE
+
+#define MOXA 0x400
+#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */
+#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */
+#define MOXA_GETDATACOUNT (MOXA + 23)
+#define MOXA_GET_IOQUEUE (MOXA + 27)
+#define MOXA_FLUSH_QUEUE (MOXA + 28)
+#define MOXA_GETMSTATUS (MOXA + 65)
+
+/*
+ * System Configuration
+ */
+
+#define Magic_code 0x404
+
+/*
+ * for C218 BIOS initialization
+ */
+#define C218_ConfBase 0x800
+#define C218_status (C218_ConfBase + 0) /* BIOS running status */
+#define C218_diag (C218_ConfBase + 2) /* diagnostic status */
+#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */
+#define C218DLoad_len (C218_ConfBase + 6) /* WORD */
+#define C218check_sum (C218_ConfBase + 8) /* BYTE */
+#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */
+#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */
+#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */
+#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */
+#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */
+
+#define C218_LoadBuf 0x0F00
+#define C218_KeyCode 0x218
+#define CP204J_KeyCode 0x204
+
+/*
+ * for C320 BIOS initialization
+ */
+#define C320_ConfBase 0x800
+#define C320_LoadBuf 0x0f00
+#define STS_init 0x05 /* for C320_status */
+
+#define C320_status C320_ConfBase + 0 /* BIOS running status */
+#define C320_diag C320_ConfBase + 2 /* diagnostic status */
+#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */
+#define C320DLoad_len C320_ConfBase + 6 /* WORD */
+#define C320check_sum C320_ConfBase + 8 /* WORD */
+#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */
+#define C320bapi_len C320_ConfBase + 0x0c /* WORD */
+#define C320UART_no C320_ConfBase + 0x0e /* WORD */
+
+#define C320_KeyCode 0x320
+
+#define FixPage_addr 0x0000 /* starting addr of static page */
+#define DynPage_addr 0x2000 /* starting addr of dynamic page */
+#define C218_start 0x3000 /* starting addr of C218 BIOS prg */
+#define Control_reg 0x1ff0 /* select page and reset control */
+#define HW_reset 0x80
+
+/*
+ * Function Codes
+ */
+#define FC_CardReset 0x80
+#define FC_ChannelReset 1 /* C320 firmware not supported */
+#define FC_EnableCH 2
+#define FC_DisableCH 3
+#define FC_SetParam 4
+#define FC_SetMode 5
+#define FC_SetRate 6
+#define FC_LineControl 7
+#define FC_LineStatus 8
+#define FC_XmitControl 9
+#define FC_FlushQueue 10
+#define FC_SendBreak 11
+#define FC_StopBreak 12
+#define FC_LoopbackON 13
+#define FC_LoopbackOFF 14
+#define FC_ClrIrqTable 15
+#define FC_SendXon 16
+#define FC_SetTermIrq 17 /* C320 firmware not supported */
+#define FC_SetCntIrq 18 /* C320 firmware not supported */
+#define FC_SetBreakIrq 19
+#define FC_SetLineIrq 20
+#define FC_SetFlowCtl 21
+#define FC_GenIrq 22
+#define FC_InCD180 23
+#define FC_OutCD180 24
+#define FC_InUARTreg 23
+#define FC_OutUARTreg 24
+#define FC_SetXonXoff 25
+#define FC_OutCD180CCR 26
+#define FC_ExtIQueue 27
+#define FC_ExtOQueue 28
+#define FC_ClrLineIrq 29
+#define FC_HWFlowCtl 30
+#define FC_GetClockRate 35
+#define FC_SetBaud 36
+#define FC_SetDataMode 41
+#define FC_GetCCSR 43
+#define FC_GetDataError 45
+#define FC_RxControl 50
+#define FC_ImmSend 51
+#define FC_SetXonState 52
+#define FC_SetXoffState 53
+#define FC_SetRxFIFOTrig 54
+#define FC_SetTxFIFOCnt 55
+#define FC_UnixRate 56
+#define FC_UnixResetTimer 57
+
+#define RxFIFOTrig1 0
+#define RxFIFOTrig4 1
+#define RxFIFOTrig8 2
+#define RxFIFOTrig14 3
+
+/*
+ * Dual-Ported RAM
+ */
+#define DRAM_global 0
+#define INT_data (DRAM_global + 0)
+#define Config_base (DRAM_global + 0x108)
+
+#define IRQindex (INT_data + 0)
+#define IRQpending (INT_data + 4)
+#define IRQtable (INT_data + 8)
+
+/*
+ * Interrupt Status
+ */
+#define IntrRx 0x01 /* receiver data O.K. */
+#define IntrTx 0x02 /* transmit buffer empty */
+#define IntrFunc 0x04 /* function complete */
+#define IntrBreak 0x08 /* received break */
+#define IntrLine 0x10 /* line status change
+ for transmitter */
+#define IntrIntr 0x20 /* received INTR code */
+#define IntrQuit 0x40 /* received QUIT code */
+#define IntrEOF 0x80 /* received EOF code */
+
+#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
+#define IntrTxTrigger 0x200 /* tx data count below trigger value */
+
+#define Magic_no (Config_base + 0)
+#define Card_model_no (Config_base + 2)
+#define Total_ports (Config_base + 4)
+#define Module_cnt (Config_base + 8)
+#define Module_no (Config_base + 10)
+#define Timer_10ms (Config_base + 14)
+#define Disable_IRQ (Config_base + 20)
+#define TMS320_PORT1 (Config_base + 22)
+#define TMS320_PORT2 (Config_base + 24)
+#define TMS320_CLOCK (Config_base + 26)
+
+/*
+ * DATA BUFFER in DRAM
+ */
+#define Extern_table 0x400 /* Base address of the external table
+ (24 words * 64) total 3K bytes
+ (24 words * 128) total 6K bytes */
+#define Extern_size 0x60 /* 96 bytes */
+#define RXrptr 0x00 /* read pointer for RX buffer */
+#define RXwptr 0x02 /* write pointer for RX buffer */
+#define TXrptr 0x04 /* read pointer for TX buffer */
+#define TXwptr 0x06 /* write pointer for TX buffer */
+#define HostStat 0x08 /* IRQ flag and general flag */
+#define FlagStat 0x0A
+#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
+ /* x x x x | | | | */
+ /* | | | + CTS flow */
+ /* | | +--- RTS flow */
+ /* | +------ TX Xon/Xoff */
+ /* +--------- RX Xon/Xoff */
+#define Break_cnt 0x0E /* received break count */
+#define CD180TXirq 0x10 /* if non-0: enable TX irq */
+#define RX_mask 0x12
+#define TX_mask 0x14
+#define Ofs_rxb 0x16
+#define Ofs_txb 0x18
+#define Page_rxb 0x1A
+#define Page_txb 0x1C
+#define EndPage_rxb 0x1E
+#define EndPage_txb 0x20
+#define Data_error 0x22
+#define RxTrigger 0x28
+#define TxTrigger 0x2a
+
+#define rRXwptr 0x34
+#define Low_water 0x36
+
+#define FuncCode 0x40
+#define FuncArg 0x42
+#define FuncArg1 0x44
+
+#define C218rx_size 0x2000 /* 8K bytes */
+#define C218tx_size 0x8000 /* 32K bytes */
+
+#define C218rx_mask (C218rx_size - 1)
+#define C218tx_mask (C218tx_size - 1)
+
+#define C320p8rx_size 0x2000
+#define C320p8tx_size 0x8000
+#define C320p8rx_mask (C320p8rx_size - 1)
+#define C320p8tx_mask (C320p8tx_size - 1)
+
+#define C320p16rx_size 0x2000
+#define C320p16tx_size 0x4000
+#define C320p16rx_mask (C320p16rx_size - 1)
+#define C320p16tx_mask (C320p16tx_size - 1)
+
+#define C320p24rx_size 0x2000
+#define C320p24tx_size 0x2000
+#define C320p24rx_mask (C320p24rx_size - 1)
+#define C320p24tx_mask (C320p24tx_size - 1)
+
+#define C320p32rx_size 0x1000
+#define C320p32tx_size 0x1000
+#define C320p32rx_mask (C320p32rx_size - 1)
+#define C320p32tx_mask (C320p32tx_size - 1)
+
+#define Page_size 0x2000U
+#define Page_mask (Page_size - 1)
+#define C218rx_spage 3
+#define C218tx_spage 4
+#define C218rx_pageno 1
+#define C218tx_pageno 4
+#define C218buf_pageno 5
+
+#define C320p8rx_spage 3
+#define C320p8tx_spage 4
+#define C320p8rx_pgno 1
+#define C320p8tx_pgno 4
+#define C320p8buf_pgno 5
+
+#define C320p16rx_spage 3
+#define C320p16tx_spage 4
+#define C320p16rx_pgno 1
+#define C320p16tx_pgno 2
+#define C320p16buf_pgno 3
+
+#define C320p24rx_spage 3
+#define C320p24tx_spage 4
+#define C320p24rx_pgno 1
+#define C320p24tx_pgno 1
+#define C320p24buf_pgno 2
+
+#define C320p32rx_spage 3
+#define C320p32tx_ofs C320p32rx_size
+#define C320p32tx_spage 3
+#define C320p32buf_pgno 1
+
+/*
+ * Host Status
+ */
+#define WakeupRx 0x01
+#define WakeupTx 0x02
+#define WakeupBreak 0x08
+#define WakeupLine 0x10
+#define WakeupIntr 0x20
+#define WakeupQuit 0x40
+#define WakeupEOF 0x80 /* used in VTIME control */
+#define WakeupRxTrigger 0x100
+#define WakeupTxTrigger 0x200
+/*
+ * Flag status
+ */
+#define Rx_over 0x01
+#define Xoff_state 0x02
+#define Tx_flowOff 0x04
+#define Tx_enable 0x08
+#define CTS_state 0x10
+#define DSR_state 0x20
+#define DCD_state 0x80
+/*
+ * FlowControl
+ */
+#define CTS_FlowCtl 1
+#define RTS_FlowCtl 2
+#define Tx_FlowCtl 4
+#define Rx_FlowCtl 8
+#define IXM_IXANY 0x10
+
+#define LowWater 128
+
+#define DTR_ON 1
+#define RTS_ON 2
+#define CTS_ON 1
+#define DSR_ON 2
+#define DCD_ON 8
+
+/* mode definition */
+#define MX_CS8 0x03
+#define MX_CS7 0x02
+#define MX_CS6 0x01
+#define MX_CS5 0x00
+
+#define MX_STOP1 0x00
+#define MX_STOP15 0x04
+#define MX_STOP2 0x08
+
+#define MX_PARNONE 0x00
+#define MX_PAREVEN 0x40
+#define MX_PARODD 0xC0
+
+#endif
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 68c2e923469..4b81a85c5b5 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -307,6 +307,200 @@ 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 void mxser_enable_must_enchance_mode(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_disable_must_enchance_mode(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_set_must_xon1_value(unsigned long baseio, u8 value)
+{
+ u8 oldlcr;
+ u8 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(value, baseio + MOXA_MUST_XON1_REGISTER);
+ outb(oldlcr, baseio + UART_LCR);
+}
+
+static void mxser_set_must_xoff1_value(unsigned long baseio, u8 value)
+{
+ u8 oldlcr;
+ u8 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(value, baseio + MOXA_MUST_XOFF1_REGISTER);
+ outb(oldlcr, baseio + UART_LCR);
+}
+
+static void mxser_set_must_fifo_value(struct mxser_port *info)
+{
+ u8 oldlcr;
+ u8 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;
+
+ 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);
+}
+
+static void mxser_set_must_enum_value(unsigned long baseio, u8 value)
+{
+ u8 oldlcr;
+ u8 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);
+ outb(value, baseio + MOXA_MUST_ENUM_REGISTER);
+ outb(oldlcr, baseio + UART_LCR);
+}
+
+static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_enable_must_tx_software_flow_control(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_disable_must_tx_software_flow_control(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_enable_must_rx_software_flow_control(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
+static void mxser_disable_must_rx_software_flow_control(unsigned long baseio)
+{
+ u8 oldlcr;
+ u8 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);
+}
+
#ifdef CONFIG_PCI
static int __devinit CheckIsMoxaMust(unsigned long io)
{
@@ -314,16 +508,16 @@ static int __devinit CheckIsMoxaMust(unsigned long io)
int i;
outb(0, io + UART_LCR);
- DISABLE_MOXA_MUST_ENCHANCE_MODE(io);
+ mxser_disable_must_enchance_mode(io);
oldmcr = inb(io + UART_MCR);
outb(0, io + UART_MCR);
- SET_MOXA_MUST_XON1_VALUE(io, 0x11);
+ mxser_set_must_xon1_value(io, 0x11);
if ((hwid = inb(io + UART_MCR)) != 0) {
outb(oldmcr, io + UART_MCR);
return MOXA_OTHER_UART;
}
- GET_MOXA_MUST_HARDWARE_ID(io, &hwid);
+ mxser_get_must_hardware_id(io, &hwid);
for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */
if (hwid == Gpci_uart_info[i].type)
return (int)hwid;
@@ -494,10 +688,10 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
} else
quot /= newspd;
- SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot);
+ mxser_set_must_enum_value(info->ioaddr, quot);
} else
#endif
- SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0);
+ mxser_set_must_enum_value(info->ioaddr, 0);
return 0;
}
@@ -553,14 +747,14 @@ static int mxser_change_speed(struct mxser_port *info,
if (info->board->chip_flag) {
fcr = UART_FCR_ENABLE_FIFO;
fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
- SET_MOXA_MUST_FIFO_VALUE(info);
+ mxser_set_must_fifo_value(info);
} else
fcr = 0;
} else {
fcr = UART_FCR_ENABLE_FIFO;
if (info->board->chip_flag) {
fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
- SET_MOXA_MUST_FIFO_VALUE(info);
+ mxser_set_must_fifo_value(info);
} else {
switch (info->rx_trigger) {
case 1:
@@ -657,17 +851,21 @@ static int mxser_change_speed(struct mxser_port *info,
}
}
if (info->board->chip_flag) {
- SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty));
- SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty));
+ mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->tty));
+ mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->tty));
if (I_IXON(info->tty)) {
- ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+ mxser_enable_must_rx_software_flow_control(
+ info->ioaddr);
} else {
- DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+ mxser_disable_must_rx_software_flow_control(
+ info->ioaddr);
}
if (I_IXOFF(info->tty)) {
- ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+ mxser_enable_must_tx_software_flow_control(
+ info->ioaddr);
} else {
- DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+ mxser_disable_must_tx_software_flow_control(
+ info->ioaddr);
}
}
@@ -927,6 +1125,27 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
return 0;
}
+static void mxser_flush_buffer(struct tty_struct *tty)
+{
+ struct mxser_port *info = tty->driver_data;
+ char fcr;
+ unsigned long flags;
+
+
+ spin_lock_irqsave(&info->slock, flags);
+ info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+ fcr = inb(info->ioaddr + UART_FCR);
+ outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
+ info->ioaddr + UART_FCR);
+ outb(fcr, info->ioaddr + UART_FCR);
+
+ spin_unlock_irqrestore(&info->slock, flags);
+
+ tty_wakeup(tty);
+}
+
+
/*
* This routine is called when the serial port gets closed. First, we
* wait for the last remaining data to be sent. Then, we unlink its
@@ -1013,9 +1232,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
}
mxser_shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
-
+ mxser_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
@@ -1072,16 +1289,16 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
return total;
}
-static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
+static int mxser_put_char(struct tty_struct *tty, unsigned char ch)
{
struct mxser_port *info = tty->driver_data;
unsigned long flags;
if (!info->xmit_buf)
- return;
+ return 0;
if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
- return;
+ return 0;
spin_lock_irqsave(&info->slock, flags);
info->xmit_buf[info->xmit_head++] = ch;
@@ -1099,6 +1316,7 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
spin_unlock_irqrestore(&info->slock, flags);
}
}
+ return 1;
}
@@ -1142,26 +1360,6 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
return info->xmit_cnt;
}
-static void mxser_flush_buffer(struct tty_struct *tty)
-{
- struct mxser_port *info = tty->driver_data;
- char fcr;
- unsigned long flags;
-
-
- spin_lock_irqsave(&info->slock, flags);
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
- fcr = inb(info->ioaddr + UART_FCR);
- outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
- info->ioaddr + UART_FCR);
- outb(fcr, info->ioaddr + UART_FCR);
-
- spin_unlock_irqrestore(&info->slock, flags);
-
- tty_wakeup(tty);
-}
-
/*
* ------------------------------------------------------------
* friends of mxser_ioctl()
@@ -1460,6 +1658,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
struct mxser_port *port;
int result, status;
unsigned int i, j;
+ int ret = 0;
switch (cmd) {
case MOXA_GET_MAJOR:
@@ -1467,18 +1666,21 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
case MOXA_CHKPORTENABLE:
result = 0;
-
+ lock_kernel();
for (i = 0; i < MXSER_BOARDS; i++)
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
if (mxser_boards[i].ports[j].ioaddr)
result |= (1 << i);
-
+ unlock_kernel();
return put_user(result, (unsigned long __user *)argp);
case MOXA_GETDATACOUNT:
+ lock_kernel();
if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ unlock_kernel();
+ return ret;
case MOXA_GETMSTATUS:
+ lock_kernel();
for (i = 0; i < MXSER_BOARDS; i++)
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
port = &mxser_boards[i].ports[j];
@@ -1515,6 +1717,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
else
GMStatus[i].cts = 0;
}
+ unlock_kernel();
if (copy_to_user(argp, GMStatus,
sizeof(struct mxser_mstatus) * MXSER_PORTS))
return -EFAULT;
@@ -1524,7 +1727,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
unsigned long opmode;
unsigned cflag, iflag;
- for (i = 0; i < MXSER_BOARDS; i++)
+ lock_kernel();
+ for (i = 0; i < MXSER_BOARDS; i++) {
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
port = &mxser_boards[i].ports[j];
if (!port->ioaddr)
@@ -1589,13 +1793,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
mon_data_ext.iftype[i] = opmode;
}
- if (copy_to_user(argp, &mon_data_ext,
- sizeof(mon_data_ext)))
- return -EFAULT;
-
- return 0;
-
- } default:
+ }
+ unlock_kernel();
+ if (copy_to_user(argp, &mon_data_ext,
+ sizeof(mon_data_ext)))
+ return -EFAULT;
+ return 0;
+ }
+ default:
return -ENOIOCTLCMD;
}
return 0;
@@ -1651,16 +1856,20 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
opmode != RS422_MODE &&
opmode != RS485_4WIRE_MODE)
return -EFAULT;
+ lock_kernel();
mask = ModeMask[p];
shiftbit = p * 2;
val = inb(info->opmode_ioaddr);
val &= mask;
val |= (opmode << shiftbit);
outb(val, info->opmode_ioaddr);
+ unlock_kernel();
} else {
+ lock_kernel();
shiftbit = p * 2;
opmode = inb(info->opmode_ioaddr) >> shiftbit;
opmode &= OP_MODE_MASK;
+ unlock_kernel();
if (put_user(opmode, (int __user *)argp))
return -EFAULT;
}
@@ -1687,19 +1896,18 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
tty_wait_until_sent(tty, 0);
mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
return 0;
- case TIOCGSOFTCAR:
- return put_user(!!C_CLOCAL(tty), (unsigned long __user *)argp);
- case TIOCSSOFTCAR:
- if (get_user(arg, (unsigned long __user *)argp))
- return -EFAULT;
- tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
- return 0;
case TIOCGSERIAL:
- return mxser_get_serial_info(info, argp);
+ lock_kernel();
+ retval = mxser_get_serial_info(info, argp);
+ unlock_kernel();
+ return retval;
case TIOCSSERIAL:
- return mxser_set_serial_info(info, argp);
+ lock_kernel();
+ retval = mxser_set_serial_info(info, argp);
+ unlock_kernel();
+ return retval;
case TIOCSERGETLSR: /* Get line status register */
- return mxser_get_lsr_info(info, argp);
+ return mxser_get_lsr_info(info, argp);
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
* - mask passed in arg for lines of interest
@@ -1746,24 +1954,27 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
case MOXA_HighSpeedOn:
return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
case MOXA_SDS_RSTICOUNTER:
+ lock_kernel();
info->mon_data.rxcnt = 0;
info->mon_data.txcnt = 0;
+ unlock_kernel();
return 0;
case MOXA_ASPP_OQUEUE:{
int len, lsr;
+ lock_kernel();
len = mxser_chars_in_buffer(tty);
-
lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT;
-
len += (lsr ? 0 : 1);
+ unlock_kernel();
return put_user(len, (int __user *)argp);
}
case MOXA_ASPP_MON: {
int mcr, status;
+ lock_kernel();
status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(info, status);
@@ -1782,7 +1993,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
else
info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
-
+ unlock_kernel();
if (copy_to_user(argp, &info->mon_data,
sizeof(struct mxser_mon)))
return -EFAULT;
@@ -1925,7 +2136,8 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
if (info->board->chip_flag) {
spin_lock_irqsave(&info->slock, flags);
- DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+ mxser_disable_must_rx_software_flow_control(
+ info->ioaddr);
spin_unlock_irqrestore(&info->slock, flags);
}
@@ -1979,6 +2191,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
timeout, char_time);
printk("jiff=%lu...", jiffies);
#endif
+ lock_kernel();
while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
@@ -1990,6 +2203,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
set_current_state(TASK_RUNNING);
+ unlock_kernel();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
@@ -2342,7 +2556,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
/* Enhance mode enabled here */
if (brd->chip_flag != MOXA_OTHER_UART)
- ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr);
+ mxser_enable_must_enchance_mode(info->ioaddr);
info->flags = ASYNC_SHARE_IRQ;
info->type = brd->uart_type;
diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h
index 84417111595..41878a69203 100644
--- a/drivers/char/mxser.h
+++ b/drivers/char/mxser.h
@@ -147,141 +147,4 @@
/* Rx software flow control mask */
#define MOXA_MUST_EFR_SF_RX_MASK 0x03
-#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); \
-} 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); \
-} 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); \
- outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-} while (0)
-
-#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_XOFF1_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-} while (0)
-
-#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; \
- 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); \
-} 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); \
- outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-} while (0)
-
-#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_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_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; \
- __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_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); \
-} 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); \
-} while (0)
-
#endif
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 06803ed5568..a35bfd7ee80 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -342,12 +342,10 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
#endif
/* Flush any pending characters in the driver and discipline. */
-
if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer (tty);
+ tty->ldisc.flush_buffer(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer (tty);
+ tty_driver_flush_buffer(tty);
if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
@@ -399,7 +397,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
/* Send the next block of data to device */
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- actual = tty->driver->write(tty, tbuf->buf, tbuf->count);
+ actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
/* rollback was possible and has been done */
if (actual == -ERESTARTSYS) {
@@ -578,26 +576,36 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
return -EFAULT;
}
+ lock_kernel();
+
for (;;) {
- if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+ unlock_kernel();
return -EIO;
+ }
n_hdlc = tty2n_hdlc (tty);
if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
- tty != n_hdlc->tty)
+ tty != n_hdlc->tty) {
+ unlock_kernel();
return 0;
+ }
rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
if (rbuf)
break;
/* no data */
- if (file->f_flags & O_NONBLOCK)
+ if (file->f_flags & O_NONBLOCK) {
+ unlock_kernel();
return -EAGAIN;
+ }
interruptible_sleep_on (&tty->read_wait);
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ unlock_kernel();
return -EINTR;
+ }
}
if (rbuf->count > nr)
@@ -618,7 +626,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
kfree(rbuf);
else
n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
-
+ unlock_kernel();
return ret;
} /* end of n_hdlc_tty_read() */
@@ -661,6 +669,8 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
count = maxframe;
}
+ lock_kernel();
+
add_wait_queue(&tty->write_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
@@ -695,7 +705,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
n_hdlc_send_frames(n_hdlc,tty);
}
-
+ unlock_kernel();
return error;
} /* end of n_hdlc_tty_write() */
@@ -740,8 +750,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
case TIOCOUTQ:
/* get the pending tx byte count in the driver */
- count = tty->driver->chars_in_buffer ?
- tty->driver->chars_in_buffer(tty) : 0;
+ count = tty_chars_in_buffer(tty);
/* add size of next output frame in queue */
spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
if (n_hdlc->tx_buf_list.head)
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 6b918b80f73..90216906233 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -376,8 +376,9 @@ static void put_char(struct r3964_info *pInfo, unsigned char ch)
if (tty == NULL)
return;
- if (tty->driver->put_char) {
- tty->driver->put_char(tty, ch);
+ /* FIXME: put_char should not be called from an IRQ */
+ if (tty->ops->put_char) {
+ tty->ops->put_char(tty, ch);
}
pInfo->bcc ^= ch;
}
@@ -386,12 +387,9 @@ static void flush(struct r3964_info *pInfo)
{
struct tty_struct *tty = pInfo->tty;
- if (tty == NULL)
+ if (tty == NULL || tty->ops->flush_chars == NULL)
return;
-
- if (tty->driver->flush_chars) {
- tty->driver->flush_chars(tty);
- }
+ tty->ops->flush_chars(tty);
}
static void trigger_transmit(struct r3964_info *pInfo)
@@ -449,12 +447,11 @@ static void transmit_block(struct r3964_info *pInfo)
struct r3964_block_header *pBlock = pInfo->tx_first;
int room = 0;
- if ((tty == NULL) || (pBlock == NULL)) {
+ if (tty == NULL || pBlock == NULL) {
return;
}
- if (tty->driver->write_room)
- room = tty->driver->write_room(tty);
+ room = tty_write_room(tty);
TRACE_PS("transmit_block %p, room %d, length %d",
pBlock, room, pBlock->length);
@@ -1075,12 +1072,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
TRACE_L("read()");
+ lock_kernel();
+
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) {
+ unlock_kernel();
return -EAGAIN;
}
/* block until there is a message: */
@@ -1090,8 +1090,10 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
/* If we still haven't got a message, we must have been signalled */
- if (!pMsg)
+ if (!pMsg) {
+ unlock_kernel();
return -EINTR;
+ }
/* deliver msg to client process: */
theMsg.msg_id = pMsg->msg_id;
@@ -1102,12 +1104,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
kfree(pMsg);
TRACE_M("r3964_read - msg kfree %p", pMsg);
- if (copy_to_user(buf, &theMsg, count))
+ if (copy_to_user(buf, &theMsg, count)) {
+ unlock_kernel();
return -EFAULT;
+ }
TRACE_PS("read - return %d", count);
return count;
}
+ unlock_kernel();
return -EPERM;
}
@@ -1156,6 +1161,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
pHeader->locks = 0;
pHeader->owner = NULL;
+ lock_kernel();
+
pClient = findClient(pInfo, task_pid(current));
if (pClient) {
pHeader->owner = pClient;
@@ -1173,6 +1180,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
add_tx_queue(pInfo, pHeader);
trigger_transmit(pInfo);
+ unlock_kernel();
+
return 0;
}
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 0c09409fa45..19105ec203f 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -147,10 +147,8 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty)
static void check_unthrottle(struct tty_struct *tty)
{
- if (tty->count &&
- test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
- tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ if (tty->count)
+ tty_unthrottle(tty);
}
/**
@@ -183,22 +181,24 @@ static void reset_buffer_flags(struct tty_struct *tty)
* at hangup) or when the N_TTY line discipline internally has to
* clean the pending queue (for example some signals).
*
- * FIXME: tty->ctrl_status is not spinlocked and relies on
- * lock_kernel() still.
+ * Locking: ctrl_lock
*/
static void n_tty_flush_buffer(struct tty_struct *tty)
{
+ unsigned long flags;
/* clear everything and unthrottle the driver */
reset_buffer_flags(tty);
if (!tty->link)
return;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
if (tty->link->packet) {
tty->ctrl_status |= TIOCPKT_FLUSHREAD;
wake_up_interruptible(&tty->link->read_wait);
}
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
}
/**
@@ -264,17 +264,18 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
* relevant in the world today. If you ever need them, add them here.
*
* Called from both the receive and transmit sides and can be called
- * re-entrantly. Relies on lock_kernel() still.
+ * re-entrantly. Relies on lock_kernel() for tty->column state.
*/
static int opost(unsigned char c, struct tty_struct *tty)
{
int space, spaces;
- space = tty->driver->write_room(tty);
+ space = tty_write_room(tty);
if (!space)
return -1;
+ lock_kernel();
if (O_OPOST(tty)) {
switch (c) {
case '\n':
@@ -283,7 +284,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
if (O_ONLCR(tty)) {
if (space < 2)
return -1;
- tty->driver->put_char(tty, '\r');
+ tty_put_char(tty, '\r');
tty->column = 0;
}
tty->canon_column = tty->column;
@@ -305,7 +306,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
if (space < spaces)
return -1;
tty->column += spaces;
- tty->driver->write(tty, " ", spaces);
+ tty->ops->write(tty, " ", spaces);
return 0;
}
tty->column += spaces;
@@ -322,7 +323,8 @@ static int opost(unsigned char c, struct tty_struct *tty)
break;
}
}
- tty->driver->put_char(tty, c);
+ tty_put_char(tty, c);
+ unlock_kernel();
return 0;
}
@@ -337,7 +339,8 @@ static int opost(unsigned char c, struct tty_struct *tty)
* the simple cases normally found and helps to generate blocks of
* symbols for the console driver and thus improve performance.
*
- * Called from write_chan under the tty layer write lock.
+ * Called from write_chan under the tty layer write lock. Relies
+ * on lock_kernel for the tty->column state.
*/
static ssize_t opost_block(struct tty_struct *tty,
@@ -347,12 +350,13 @@ static ssize_t opost_block(struct tty_struct *tty,
int i;
const unsigned char *cp;
- space = tty->driver->write_room(tty);
+ space = tty_write_room(tty);
if (!space)
return 0;
if (nr > space)
nr = space;
+ lock_kernel();
for (i = 0, cp = buf; i < nr; i++, cp++) {
switch (*cp) {
case '\n':
@@ -384,27 +388,15 @@ static ssize_t opost_block(struct tty_struct *tty,
}
}
break_out:
- if (tty->driver->flush_chars)
- tty->driver->flush_chars(tty);
- i = tty->driver->write(tty, buf, i);
+ if (tty->ops->flush_chars)
+ tty->ops->flush_chars(tty);
+ i = tty->ops->write(tty, buf, i);
+ unlock_kernel();
return i;
}
/**
- * put_char - write character to driver
- * @c: character (or part of unicode symbol)
- * @tty: terminal device
- *
- * Queue a byte to the driver layer for output
- */
-
-static inline void put_char(unsigned char c, struct tty_struct *tty)
-{
- tty->driver->put_char(tty, c);
-}
-
-/**
* echo_char - echo characters
* @c: unicode byte to echo
* @tty: terminal device
@@ -416,8 +408,8 @@ static inline void put_char(unsigned char c, struct tty_struct *tty)
static void echo_char(unsigned char c, struct tty_struct *tty)
{
if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') {
- put_char('^', tty);
- put_char(c ^ 0100, tty);
+ tty_put_char(tty, '^');
+ tty_put_char(tty, c ^ 0100);
tty->column += 2;
} else
opost(c, tty);
@@ -426,7 +418,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
static inline void finish_erasing(struct tty_struct *tty)
{
if (tty->erasing) {
- put_char('/', tty);
+ tty_put_char(tty, '/');
tty->column++;
tty->erasing = 0;
}
@@ -510,7 +502,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
if (L_ECHO(tty)) {
if (L_ECHOPRT(tty)) {
if (!tty->erasing) {
- put_char('\\', tty);
+ tty_put_char(tty, '\\');
tty->column++;
tty->erasing = 1;
}
@@ -518,7 +510,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
echo_char(c, tty);
while (--cnt > 0) {
head = (head+1) & (N_TTY_BUF_SIZE-1);
- put_char(tty->read_buf[head], tty);
+ tty_put_char(tty, tty->read_buf[head]);
}
} else if (kill_type == ERASE && !L_ECHOE(tty)) {
echo_char(ERASE_CHAR(tty), tty);
@@ -546,22 +538,22 @@ static void eraser(unsigned char c, struct tty_struct *tty)
/* Now backup to that column. */
while (tty->column > col) {
/* Can't use opost here. */
- put_char('\b', tty);
+ tty_put_char(tty, '\b');
if (tty->column > 0)
tty->column--;
}
} else {
if (iscntrl(c) && L_ECHOCTL(tty)) {
- put_char('\b', tty);
- put_char(' ', tty);
- put_char('\b', tty);
+ tty_put_char(tty, '\b');
+ tty_put_char(tty, ' ');
+ tty_put_char(tty, '\b');
if (tty->column > 0)
tty->column--;
}
if (!iscntrl(c) || L_ECHOCTL(tty)) {
- put_char('\b', tty);
- put_char(' ', tty);
- put_char('\b', tty);
+ tty_put_char(tty, '\b');
+ tty_put_char(tty, ' ');
+ tty_put_char(tty, '\b');
if (tty->column > 0)
tty->column--;
}
@@ -592,8 +584,7 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
n_tty_flush_buffer(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
}
}
@@ -701,7 +692,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) ||
- c == INTR_CHAR(tty) || c == QUIT_CHAR(tty)))
+ c == INTR_CHAR(tty) || c == QUIT_CHAR(tty) || c == SUSP_CHAR(tty)))
start_tty(tty);
if (tty->closing) {
@@ -725,7 +716,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
tty->lnext = 0;
if (L_ECHO(tty)) {
if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
- put_char('\a', tty); /* beep if no space */
+ tty_put_char(tty, '\a'); /* beep if no space */
return;
}
/* Record the column of first canon char. */
@@ -739,13 +730,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return;
}
- if (c == '\r') {
- if (I_IGNCR(tty))
- return;
- if (I_ICRNL(tty))
- c = '\n';
- } else if (c == '\n' && I_INLCR(tty))
- c = '\r';
if (I_IXON(tty)) {
if (c == START_CHAR(tty)) {
start_tty(tty);
@@ -756,6 +740,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return;
}
}
+
if (L_ISIG(tty)) {
int signal;
signal = SIGINT;
@@ -775,8 +760,7 @@ send_signal:
*/
if (!L_NOFLSH(tty)) {
n_tty_flush_buffer(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
}
if (L_ECHO(tty))
echo_char(c, tty);
@@ -785,6 +769,15 @@ send_signal:
return;
}
}
+
+ if (c == '\r') {
+ if (I_IGNCR(tty))
+ return;
+ if (I_ICRNL(tty))
+ c = '\n';
+ } else if (c == '\n' && I_INLCR(tty))
+ c = '\r';
+
if (tty->icanon) {
if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
(c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
@@ -796,8 +789,8 @@ send_signal:
if (L_ECHO(tty)) {
finish_erasing(tty);
if (L_ECHOCTL(tty)) {
- put_char('^', tty);
- put_char('\b', tty);
+ tty_put_char(tty, '^');
+ tty_put_char(tty, '\b');
}
}
return;
@@ -818,7 +811,7 @@ send_signal:
if (c == '\n') {
if (L_ECHO(tty) || L_ECHONL(tty)) {
if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
- put_char('\a', tty);
+ tty_put_char(tty, '\a');
opost('\n', tty);
}
goto handle_newline;
@@ -836,7 +829,7 @@ send_signal:
*/
if (L_ECHO(tty)) {
if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
- put_char('\a', tty);
+ tty_put_char(tty, '\a');
/* Record the column of first canon char. */
if (tty->canon_head == tty->read_head)
tty->canon_column = tty->column;
@@ -866,7 +859,7 @@ handle_newline:
finish_erasing(tty);
if (L_ECHO(tty)) {
if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
- put_char('\a', tty); /* beep if no space */
+ tty_put_char(tty, '\a'); /* beep if no space */
return;
}
if (c == '\n')
@@ -970,8 +963,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
break;
}
}
- if (tty->driver->flush_chars)
- tty->driver->flush_chars(tty);
+ if (tty->ops->flush_chars)
+ tty->ops->flush_chars(tty);
}
n_tty_set_room(tty);
@@ -987,12 +980,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
* mode. We don't want to throttle the driver if we're in
* canonical mode and don't have a newline yet!
*/
- if (tty->receive_room < TTY_THRESHOLD_THROTTLE) {
- /* check TTY_THROTTLED first so it indicates our state */
- if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
- tty->driver->throttle)
- tty->driver->throttle(tty);
- }
+ if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
+ tty_throttle(tty);
}
int is_ignored(int sig)
@@ -1076,6 +1065,9 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
tty->real_raw = 0;
}
n_tty_set_room(tty);
+ /* The termios change make the tty ready for I/O */
+ wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible(&tty->read_wait);
}
/**
@@ -1194,6 +1186,11 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *,
* Perform job control management checks on this file/tty descriptor
* and if appropriate send any needed signals and return a negative
* error code if action should be taken.
+ *
+ * FIXME:
+ * Locking: None - redirected write test is safe, testing
+ * current->signal should possibly lock current->sighand
+ * pgrp locking ?
*/
static int job_control(struct tty_struct *tty, struct file *file)
@@ -1246,6 +1243,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
ssize_t size;
long timeout;
unsigned long flags;
+ int packet;
do_it_again:
@@ -1289,16 +1287,19 @@ do_it_again:
if (mutex_lock_interruptible(&tty->atomic_read_lock))
return -ERESTARTSYS;
}
+ packet = tty->packet;
add_wait_queue(&tty->read_wait, &wait);
while (nr) {
/* First test for status change. */
- if (tty->packet && tty->link->ctrl_status) {
+ if (packet && tty->link->ctrl_status) {
unsigned char cs;
if (b != buf)
break;
+ spin_lock_irqsave(&tty->link->ctrl_lock, flags);
cs = tty->link->ctrl_status;
tty->link->ctrl_status = 0;
+ spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
if (tty_put_user(tty, cs, b++)) {
retval = -EFAULT;
b--;
@@ -1333,6 +1334,7 @@ do_it_again:
retval = -ERESTARTSYS;
break;
}
+ /* FIXME: does n_tty_set_room need locking ? */
n_tty_set_room(tty);
timeout = schedule_timeout(timeout);
continue;
@@ -1340,7 +1342,7 @@ do_it_again:
__set_current_state(TASK_RUNNING);
/* Deal with packet mode. */
- if (tty->packet && b == buf) {
+ if (packet && b == buf) {
if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
retval = -EFAULT;
b--;
@@ -1388,6 +1390,8 @@ do_it_again:
break;
} else {
int uncopied;
+ /* The copy function takes the read lock and handles
+ locking internally for this case */
uncopied = copy_from_read_buf(tty, &b, &nr);
uncopied += copy_from_read_buf(tty, &b, &nr);
if (uncopied) {
@@ -1429,7 +1433,6 @@ do_it_again:
goto do_it_again;
n_tty_set_room(tty);
-
return retval;
}
@@ -1492,11 +1495,11 @@ static ssize_t write_chan(struct tty_struct *tty, struct file *file,
break;
b++; nr--;
}
- if (tty->driver->flush_chars)
- tty->driver->flush_chars(tty);
+ if (tty->ops->flush_chars)
+ tty->ops->flush_chars(tty);
} else {
while (nr > 0) {
- c = tty->driver->write(tty, b, nr);
+ c = tty->ops->write(tty, b, nr);
if (c < 0) {
retval = c;
goto break_out;
@@ -1533,11 +1536,6 @@ break_out:
*
* This code must be sure never to sleep through a hangup.
* Called without the kernel lock held - fine
- *
- * FIXME: if someone changes the VMIN or discipline settings for the
- * terminal while another process is in poll() the poll does not
- * recompute the new limits. Possibly set_termios should issue
- * a read wakeup to fix this bug.
*/
static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
@@ -1561,9 +1559,9 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
else
tty->minimum_to_wake = 1;
}
- if (!tty_is_writelocked(tty) &&
- tty->driver->chars_in_buffer(tty) < WAKEUP_CHARS &&
- tty->driver->write_room(tty) > 0)
+ if (tty->ops->write && !tty_is_writelocked(tty) &&
+ tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
+ tty_write_room(tty) > 0)
mask |= POLLOUT | POLLWRNORM;
return mask;
}
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 6a6843a0a67..66a0f931c66 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -73,7 +73,7 @@ do { \
char tmp[P_BUF_SIZE]; \
snprintf(tmp, sizeof(tmp), ##args); \
printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \
- __FUNCTION__, tmp); \
+ __func__, tmp); \
} while (0)
#define DBG1(args...) D_(0x01, ##args)
@@ -1407,7 +1407,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
/* Find out what card type it is */
nozomi_get_card_type(dc);
- dc->base_addr = ioremap(start, dc->card_type);
+ dc->base_addr = ioremap_nocache(start, dc->card_type);
if (!dc->base_addr) {
dev_err(&pdev->dev, "Unable to map card MMIO\n");
ret = -ENODEV;
@@ -1724,6 +1724,8 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)
const struct ctrl_dl *ctrl_dl = &port->ctrl_dl;
const struct ctrl_ul *ctrl_ul = &port->ctrl_ul;
+ /* Note: these could change under us but it is not clear this
+ matters if so */
return (ctrl_ul->RTS ? TIOCM_RTS : 0) |
(ctrl_ul->DTR ? TIOCM_DTR : 0) |
(ctrl_dl->DCD ? TIOCM_CAR : 0) |
@@ -1849,16 +1851,6 @@ static void ntty_throttle(struct tty_struct *tty)
spin_unlock_irqrestore(&dc->spin_mutex, flags);
}
-/* just to discard single character writes */
-static void ntty_put_char(struct tty_struct *tty, unsigned char c)
-{
- /*
- * card does not react correct when we write single chars
- * to the card, so we discard them
- */
- DBG2("PUT CHAR Function: %c", c);
-}
-
/* Returns number of chars in buffer, called by tty layer */
static s32 ntty_chars_in_buffer(struct tty_struct *tty)
{
@@ -1892,7 +1884,6 @@ static const struct tty_operations tty_ops = {
.unthrottle = ntty_unthrottle,
.throttle = ntty_throttle,
.chars_in_buffer = ntty_chars_in_buffer,
- .put_char = ntty_put_char,
.tiocmget = ntty_tiocmget,
.tiocmset = ntty_tiocmset,
};
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 454d7324ba4..4a933d41342 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -53,7 +53,7 @@ module_param(pc_debug, int, 0600);
#define DEBUGP(n, rdr, x, args...) do { \
if (pc_debug >= (n)) \
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __FUNCTION__ , ## args); \
+ __func__ , ## args); \
} while (0)
#else
#define DEBUGP(n, rdr, x, args...)
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 5f291bf739a..035084c0732 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -47,7 +47,7 @@ module_param(pc_debug, int, 0600);
#define DEBUGP(n, rdr, x, args...) do { \
if (pc_debug >= (n)) \
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __FUNCTION__ , ##args); \
+ __func__ , ##args); \
} while (0)
#else
#define DEBUGP(n, rdr, x, args...)
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 583356426df..1dd0e992c83 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -503,20 +503,9 @@ static void* mgslpc_get_text_ptr(void)
* The wrappers maintain line discipline references
* while calling into the line discipline.
*
- * ldisc_flush_buffer - flush line discipline receive buffers
* ldisc_receive_buf - pass receive data to line discipline
*/
-static void ldisc_flush_buffer(struct tty_struct *tty)
-{
- struct tty_ldisc *ld = tty_ldisc_ref(tty);
- if (ld) {
- if (ld->flush_buffer)
- ld->flush_buffer(tty);
- tty_ldisc_deref(ld);
- }
-}
-
static void ldisc_receive_buf(struct tty_struct *tty,
const __u8 *data, char *flags, int count)
{
@@ -1556,7 +1545,7 @@ static void mgslpc_change_params(MGSLPC_INFO *info)
/* Add a character to the transmit buffer
*/
-static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch)
+static int mgslpc_put_char(struct tty_struct *tty, unsigned char ch)
{
MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
unsigned long flags;
@@ -1567,10 +1556,10 @@ static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch)
}
if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char"))
- return;
+ return 0;
if (!info->tx_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->lock,flags);
@@ -1583,6 +1572,7 @@ static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch)
}
spin_unlock_irqrestore(&info->lock,flags);
+ return 1;
}
/* Enable transmitter so remaining characters in the
@@ -2467,10 +2457,9 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp)
if (info->flags & ASYNC_INITIALIZED)
mgslpc_wait_until_sent(tty, info->timeout);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ mgslpc_flush_buffer(tty);
- ldisc_flush_buffer(tty);
+ tty_ldisc_flush(tty);
shutdown(info);
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 706ff34728f..0a05c038ae6 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -181,6 +181,7 @@ static int pty_set_lock(struct tty_struct *tty, int __user * arg)
static void pty_flush_buffer(struct tty_struct *tty)
{
struct tty_struct *to = tty->link;
+ unsigned long flags;
if (!to)
return;
@@ -189,8 +190,10 @@ static void pty_flush_buffer(struct tty_struct *tty)
to->ldisc.flush_buffer(to);
if (to->packet) {
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
wake_up_interruptible(&to->read_wait);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
}
}
@@ -251,6 +254,18 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
module_param(legacy_count, int, 0);
+static const struct tty_operations pty_ops_bsd = {
+ .open = pty_open,
+ .close = pty_close,
+ .write = pty_write,
+ .write_room = pty_write_room,
+ .flush_buffer = pty_flush_buffer,
+ .chars_in_buffer = pty_chars_in_buffer,
+ .unthrottle = pty_unthrottle,
+ .set_termios = pty_set_termios,
+ .ioctl = pty_bsd_ioctl,
+};
+
static void __init legacy_pty_init(void)
{
if (legacy_count <= 0)
@@ -281,7 +296,6 @@ static void __init legacy_pty_init(void)
pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
pty_driver->other = pty_slave_driver;
tty_set_operations(pty_driver, &pty_ops);
- pty_driver->ioctl = pty_bsd_ioctl;
pty_slave_driver->owner = THIS_MODULE;
pty_slave_driver->driver_name = "pty_slave";
@@ -374,6 +388,19 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
return -ENOIOCTLCMD;
}
+static const struct tty_operations pty_unix98_ops = {
+ .open = pty_open,
+ .close = pty_close,
+ .write = pty_write,
+ .write_room = pty_write_room,
+ .flush_buffer = pty_flush_buffer,
+ .chars_in_buffer = pty_chars_in_buffer,
+ .unthrottle = pty_unthrottle,
+ .set_termios = pty_set_termios,
+ .ioctl = pty_unix98_ioctl
+};
+
+
static void __init unix98_pty_init(void)
{
ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
@@ -400,8 +427,7 @@ static void __init unix98_pty_init(void)
ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
ptm_driver->other = pts_driver;
- tty_set_operations(ptm_driver, &pty_ops);
- ptm_driver->ioctl = pty_unix98_ioctl;
+ tty_set_operations(ptm_driver, &pty_unix98_ops);
pts_driver->owner = THIS_MODULE;
pts_driver->driver_name = "pty_slave";
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h
index f4f837f8682..a03a538a3ef 100644
--- a/drivers/char/rio/cirrus.h
+++ b/drivers/char/rio/cirrus.h
@@ -43,83 +43,83 @@
/* Bit fields for particular registers shared with driver */
/* COR1 - driver and RTA */
-#define COR1_ODD 0x80 /* Odd parity */
-#define COR1_EVEN 0x00 /* Even parity */
-#define COR1_NOP 0x00 /* No parity */
-#define COR1_FORCE 0x20 /* Force parity */
-#define COR1_NORMAL 0x40 /* With parity */
-#define COR1_1STOP 0x00 /* 1 stop bit */
-#define COR1_15STOP 0x04 /* 1.5 stop bits */
-#define COR1_2STOP 0x08 /* 2 stop bits */
-#define COR1_5BITS 0x00 /* 5 data bits */
-#define COR1_6BITS 0x01 /* 6 data bits */
-#define COR1_7BITS 0x02 /* 7 data bits */
-#define COR1_8BITS 0x03 /* 8 data bits */
-
-#define COR1_HOST 0xef /* Safe host bits */
+#define RIOC_COR1_ODD 0x80 /* Odd parity */
+#define RIOC_COR1_EVEN 0x00 /* Even parity */
+#define RIOC_COR1_NOP 0x00 /* No parity */
+#define RIOC_COR1_FORCE 0x20 /* Force parity */
+#define RIOC_COR1_NORMAL 0x40 /* With parity */
+#define RIOC_COR1_1STOP 0x00 /* 1 stop bit */
+#define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */
+#define RIOC_COR1_2STOP 0x08 /* 2 stop bits */
+#define RIOC_COR1_5BITS 0x00 /* 5 data bits */
+#define RIOC_COR1_6BITS 0x01 /* 6 data bits */
+#define RIOC_COR1_7BITS 0x02 /* 7 data bits */
+#define RIOC_COR1_8BITS 0x03 /* 8 data bits */
+
+#define RIOC_COR1_HOST 0xef /* Safe host bits */
/* RTA only */
-#define COR1_CINPCK 0x00 /* Check parity of received characters */
-#define COR1_CNINPCK 0x10 /* Don't check parity */
+#define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */
+#define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */
/* COR2 bits for both RTA and driver use */
-#define COR2_IXANY 0x80 /* IXANY - any character is XON */
-#define COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */
-#define COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */
+#define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */
+#define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */
+#define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */
/* Additional driver bits */
-#define COR2_HUPCL 0x20 /* Hang up on close */
-#define COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */
-#define COR2_IXOFF 0x01 /* Enable rx software flow control */
-#define COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */
+#define RIOC_COR2_HUPCL 0x20 /* Hang up on close */
+#define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */
+#define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */
+#define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */
/* RTA use only */
-#define COR2_ETC 0x20 /* Embedded transmit options */
-#define COR2_LOCAL 0x10 /* Local loopback mode */
-#define COR2_REMOTE 0x08 /* Remote loopback mode */
-#define COR2_HOST 0xc2 /* Safe host bits */
+#define RIOC_COR2_ETC 0x20 /* Embedded transmit options */
+#define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */
+#define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */
+#define RIOC_COR2_HOST 0xc2 /* Safe host bits */
/* COR3 - RTA use only */
-#define COR3_SCDRNG 0x80 /* Enable special char detect for range */
-#define COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */
-#define COR3_FCT 0x20 /* Flow control transparency */
-#define COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */
-#define COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */
-#define COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */
-#define COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */
-#define COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */
-
-#define COR3_THRESHOLD COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */
-
-#define COR3_DEFAULT (COR3_FCT | COR3_THRESHOLD)
+#define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */
+#define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */
+#define RIOC_COR3_FCT 0x20 /* Flow control transparency */
+#define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */
+#define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */
+#define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */
+#define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */
+#define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */
+
+#define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */
+
+#define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD)
/* Default bits for COR3 */
/* COR4 driver and RTA use */
-#define COR4_IGNCR 0x80 /* Throw away CR's on input */
-#define COR4_ICRNL 0x40 /* Map CR -> NL on input */
-#define COR4_INLCR 0x20 /* Map NL -> CR on input */
-#define COR4_IGNBRK 0x10 /* Ignore Break */
-#define COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */
-#define COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */
+#define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */
+#define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */
+#define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */
+#define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */
+#define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */
+#define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */
/* COR4 driver only */
-#define COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */
-#define COR4_PARMRK 0x02 /* PARMRK */
+#define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */
+#define RIOC_COR4_PARMRK 0x02 /* PARMRK */
-#define COR4_HOST 0xf8 /* Safe host bits */
+#define RIOC_COR4_HOST 0xf8 /* Safe host bits */
/* COR4 RTA only */
-#define COR4_CIGNPAR 0x02 /* Thrown away bad characters */
-#define COR4_CPARMRK 0x04 /* PARMRK characters */
-#define COR4_CNPARMRK 0x03 /* Don't PARMRK */
+#define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */
+#define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */
+#define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */
/* COR5 driver and RTA use */
-#define COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */
-#define COR5_LNE 0x40 /* Enable LNEXT processing */
-#define COR5_CMOE 0x20 /* Match good and errored characters */
-#define COR5_ONLCR 0x02 /* NL -> CR NL on output */
-#define COR5_OCRNL 0x01 /* CR -> NL on output */
+#define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */
+#define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */
+#define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */
+#define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */
+#define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */
/*
** Spare bits - these are not used in the CIRRUS registers, so we use
@@ -128,86 +128,86 @@
/*
** tstop and tbusy indication
*/
-#define COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */
-#define COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */
+#define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */
+#define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */
/*
** TAB3
*/
-#define COR5_TAB3 0x10 /* TAB3 mode */
+#define RIOC_COR5_TAB3 0x10 /* TAB3 mode */
-#define COR5_HOST 0xc3 /* Safe host bits */
+#define RIOC_COR5_HOST 0xc3 /* Safe host bits */
/* CCSR */
-#define CCSR_TXFLOFF 0x04 /* Tx is xoffed */
+#define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */
/* MSVR1 */
/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the
RTA. This is because otherwise DCD would get lost on the 1 parallel / 3
serial option.
*/
-#define MSVR1_CD 0x80 /* CD (DSR on Cirrus) */
-#define MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */
-#define MSVR1_RI 0x20 /* RI */
-#define MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */
-#define MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */
+#define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */
+#define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */
+#define RIOC_MSVR1_RI 0x20 /* RI */
+#define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */
+#define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */
/* Next two used to indicate state of tbusy and tstop to driver */
-#define MSVR1_TSTOP 0x08 /* Set if port flow controlled */
-#define MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */
+#define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */
+#define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */
-#define MSVR1_HOST 0xf3 /* The bits the host wants */
+#define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */
/* Defines for the subscripts of a CONFIG packet */
-#define CONFIG_COR1 1 /* Option register 1 */
-#define CONFIG_COR2 2 /* Option register 2 */
-#define CONFIG_COR4 3 /* Option register 4 */
-#define CONFIG_COR5 4 /* Option register 5 */
-#define CONFIG_TXXON 5 /* Tx XON character */
-#define CONFIG_TXXOFF 6 /* Tx XOFF character */
-#define CONFIG_RXXON 7 /* Rx XON character */
-#define CONFIG_RXXOFF 8 /* Rx XOFF character */
-#define CONFIG_LNEXT 9 /* LNEXT character */
-#define CONFIG_TXBAUD 10 /* Tx baud rate */
-#define CONFIG_RXBAUD 11 /* Rx baud rate */
-
-#define PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */
+#define RIOC_CONFIG_COR1 1 /* Option register 1 */
+#define RIOC_CONFIG_COR2 2 /* Option register 2 */
+#define RIOC_CONFIG_COR4 3 /* Option register 4 */
+#define RIOC_CONFIG_COR5 4 /* Option register 5 */
+#define RIOC_CONFIG_TXXON 5 /* Tx XON character */
+#define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */
+#define RIOC_CONFIG_RXXON 7 /* Rx XON character */
+#define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */
+#define RIOC_CONFIG_LNEXT 9 /* LNEXT character */
+#define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */
+#define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */
+
+#define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */
/* Packet types going from Host to remote - with the exception of OPEN, MOPEN,
CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not
be used
*/
-#define OPEN 0x00 /* Open a port */
-#define CONFIG 0x01 /* Configure a port */
-#define MOPEN 0x02 /* Modem open (block for DCD) */
-#define CLOSE 0x03 /* Close a port */
-#define WFLUSH (0x04 | PRE_EMPTIVE) /* Write flush */
-#define RFLUSH (0x05 | PRE_EMPTIVE) /* Read flush */
-#define RESUME (0x06 | PRE_EMPTIVE) /* Resume if xoffed */
-#define SBREAK 0x07 /* Start break */
-#define EBREAK 0x08 /* End break */
-#define SUSPEND (0x09 | PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */
-#define FCLOSE (0x0a | PRE_EMPTIVE) /* Force close */
-#define XPRINT 0x0b /* Xprint packet */
-#define MBIS (0x0c | PRE_EMPTIVE) /* Set modem lines */
-#define MBIC (0x0d | PRE_EMPTIVE) /* Clear modem lines */
-#define MSET (0x0e | PRE_EMPTIVE) /* Set modem lines */
-#define PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */
-#define MGET (0x10 | PRE_EMPTIVE) /* Force update of modem status */
-#define MEMDUMP (0x11 | PRE_EMPTIVE) /* Send back mem from addr supplied */
-#define READ_REGISTER (0x12 | PRE_EMPTIVE) /* Read CD1400 register (debug) */
+#define RIOC_OPEN 0x00 /* Open a port */
+#define RIOC_CONFIG 0x01 /* Configure a port */
+#define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */
+#define RIOC_CLOSE 0x03 /* Close a port */
+#define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */
+#define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */
+#define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */
+#define RIOC_SBREAK 0x07 /* Start break */
+#define RIOC_EBREAK 0x08 /* End break */
+#define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */
+#define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */
+#define RIOC_XPRINT 0x0b /* Xprint packet */
+#define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */
+#define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */
+#define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */
+#define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */
+#define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */
+#define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */
+#define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */
/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS
use data[4] / data[3] to indicate current state and modem status respectively
*/
-#define COMPLETE (0x20 | PRE_EMPTIVE)
+#define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE)
/* Command complete */
-#define BREAK_RECEIVED (0x21 | PRE_EMPTIVE)
+#define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE)
/* Break received */
-#define MODEM_STATUS (0x22 | PRE_EMPTIVE)
+#define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE)
/* Change in modem status */
/* "Command" packet that could go either way - handshake wake-up */
-#define HANDSHAKE (0x23 | PRE_EMPTIVE)
+#define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE)
/* Wake-up to HOST / RTA */
#endif
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 0ce96670f97..412777cd1e6 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -344,7 +344,7 @@ int rio_minor(struct tty_struct *tty)
static int rio_set_real_termios(void *ptr)
{
- return RIOParam((struct Port *) ptr, CONFIG, 1, 1);
+ return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1);
}
@@ -487,7 +487,7 @@ static int rio_get_CD(void *ptr)
int rv;
func_enter();
- rv = (PortP->ModemState & MSVR1_CD) != 0;
+ rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0;
rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv);
@@ -607,7 +607,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n");
rc = -EIO;
} else {
- if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) {
+ if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) ==
+ RIO_FAIL) {
rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
rc = -EIO;
}
@@ -622,7 +623,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd
l = arg ? arg * 100 : 250;
if (l > 255)
l = 255;
- if (RIOShortCommand(p, PortP, SBREAK, 2, arg ? arg * 100 : 250) == RIO_FAIL) {
+ if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2,
+ arg ? arg * 100 : 250) == RIO_FAIL) {
rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
rc = -EIO;
}
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h
index dc3f005614a..7f26cd7c815 100644
--- a/drivers/char/rio/rio_linux.h
+++ b/drivers/char/rio/rio_linux.h
@@ -186,9 +186,9 @@ static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n)
#ifdef DEBUG
#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
-#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __FUNCTION__)
-#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __FUNCTION__)
-#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__FUNCTION__, port->line)
+#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__)
+#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__)
+#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line)
#else
#define rio_dprintk(f, str...) /* nothing */
#define func_enter()
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index bf36959fc12..7b96e081488 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -417,7 +417,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
PortP = p->RIOPortp[SysPort];
rio_spin_lock_irqsave(&PortP->portSem, flags);
switch (readb(&PktCmdP->Command)) {
- case BREAK_RECEIVED:
+ case RIOC_BREAK_RECEIVED:
rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n");
/* If the current line disc. is not multi-threading and
the current processor is not the default, reset rup_intr
@@ -428,16 +428,16 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
gs_got_break(&PortP->gs);
break;
- case COMPLETE:
+ case RIOC_COMPLETE:
rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts);
subCommand = 1;
switch (readb(&PktCmdP->SubCommand)) {
- case MEMDUMP:
+ case RIOC_MEMDUMP:
rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr));
break;
- case READ_REGISTER:
+ case RIOC_READ_REGISTER:
rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr));
- p->CdRegister = (readb(&PktCmdP->ModemStatus) & MSVR1_HOST);
+ p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST);
break;
default:
subCommand = 0;
@@ -456,14 +456,15 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
rio_dprintk(RIO_DEBUG_CMD, "No change\n");
/* FALLTHROUGH */
- case MODEM_STATUS:
+ case RIOC_MODEM_STATUS:
/*
** Knock out the tbusy and tstop bits, as these are not relevant
** to the check for modem status change (they're just there because
** it's a convenient place to put them!).
*/
ReportedModemStatus = readb(&PktCmdP->ModemStatus);
- if ((PortP->ModemState & MSVR1_HOST) == (ReportedModemStatus & MSVR1_HOST)) {
+ if ((PortP->ModemState & RIOC_MSVR1_HOST) ==
+ (ReportedModemStatus & RIOC_MSVR1_HOST)) {
rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
/*
** Update ModemState just in case tbusy or tstop states have
@@ -497,7 +498,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
/*
** Is there a carrier?
*/
- if (PortP->ModemState & MSVR1_CD) {
+ if (PortP->ModemState & RIOC_MSVR1_CD) {
/*
** Has carrier just appeared?
*/
@@ -691,7 +692,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
*/
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
FreeMe = RIOCommandRup(p, Rup, HostP, PacketP);
- if (readb(&PacketP->data[5]) == MEMDUMP) {
+ if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) {
rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6])));
rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32);
}
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index d8eb2bcbe01..d65ceb9a434 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -422,7 +422,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
- if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == RIO_FAIL) {
+ if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) ==
+ RIO_FAIL) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return -EBUSY;
@@ -636,7 +637,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
return -ENXIO;
}
PortP = (p->RIOPortp[PortTty.port]);
- RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP);
+ RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM,
+ OK_TO_SLEEP);
return retval;
case RIO_SET_PORT_PARAMS:
@@ -1247,7 +1249,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
rio_spin_lock_irqsave(&PortP->portSem, flags);
- if (RIOPreemptiveCmd(p, PortP, MEMDUMP) == RIO_FAIL) {
+ if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return -EBUSY;
@@ -1313,7 +1315,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
rio_spin_lock_irqsave(&PortP->portSem, flags);
- if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
+ if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) ==
+ RIO_FAIL) {
rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
return -EBUSY;
@@ -1434,50 +1437,50 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd)
PktCmdP->PhbNum = port;
switch (Cmd) {
- case MEMDUMP:
+ case RIOC_MEMDUMP:
rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p "
"(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr);
- PktCmdP->SubCommand = MEMDUMP;
+ PktCmdP->SubCommand = RIOC_MEMDUMP;
PktCmdP->SubAddr = SubCmd.Addr;
break;
- case FCLOSE:
+ case RIOC_FCLOSE:
rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n",
CmdBlkP);
break;
- case READ_REGISTER:
+ case RIOC_READ_REGISTER:
rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) "
"command blk %p\n", (int) SubCmd.Addr, CmdBlkP);
- PktCmdP->SubCommand = READ_REGISTER;
+ PktCmdP->SubCommand = RIOC_READ_REGISTER;
PktCmdP->SubAddr = SubCmd.Addr;
break;
- case RESUME:
+ case RIOC_RESUME:
rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n",
CmdBlkP);
break;
- case RFLUSH:
+ case RIOC_RFLUSH:
rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n",
CmdBlkP);
CmdBlkP->PostFuncP = RIORFlushEnable;
break;
- case SUSPEND:
+ case RIOC_SUSPEND:
rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n",
CmdBlkP);
break;
- case MGET:
+ case RIOC_MGET:
rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n",
CmdBlkP);
break;
- case MSET:
- case MBIC:
- case MBIS:
+ case RIOC_MSET:
+ case RIOC_MBIC:
+ case RIOC_MBIS:
CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command "
"blk %p\n", CmdBlkP);
break;
- case WFLUSH:
+ case RIOC_WFLUSH:
/*
** If we have queued up the maximum number of Write flushes
** allowed then we should not bother sending any more to the
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index 4734e26e1cc..ea21686c69a 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -401,9 +401,8 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
PortP->InUse = NOT_INUSE;
rio_spin_unlock(&PortP->portSem);
- if (RIOParam(PortP, OPEN, ((PortP->Cor2Copy & (COR2_RTSFLOW | COR2_CTSFLOW)) == (COR2_RTSFLOW | COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) {
+ if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL)
continue; /* with next port */
- }
rio_spin_lock(&PortP->portSem);
PortP->MagicFlags &= ~MAGIC_REBOOT;
}
@@ -429,7 +428,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
*/
PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0];
- writeb(WFLUSH, &PktCmdP->Command);
+ writeb(RIOC_WFLUSH, &PktCmdP->Command);
p = PortP->HostPort % (u16) PORTS_PER_RTA;
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index da276ed57b3..4810b845cc2 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -177,7 +177,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
- if (cmd == OPEN) {
+ if (cmd == RIOC_OPEN) {
/*
** If the port is set to store or lock the parameters, and it is
** paramed with OPEN, we want to restore the saved port termio, but
@@ -241,50 +241,50 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
case CS5:
{
rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n");
- Cor1 |= COR1_5BITS;
+ Cor1 |= RIOC_COR1_5BITS;
break;
}
case CS6:
{
rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n");
- Cor1 |= COR1_6BITS;
+ Cor1 |= RIOC_COR1_6BITS;
break;
}
case CS7:
{
rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n");
- Cor1 |= COR1_7BITS;
+ Cor1 |= RIOC_COR1_7BITS;
break;
}
case CS8:
{
rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n");
- Cor1 |= COR1_8BITS;
+ Cor1 |= RIOC_COR1_8BITS;
break;
}
}
if (TtyP->termios->c_cflag & CSTOPB) {
rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n");
- Cor1 |= COR1_2STOP;
+ Cor1 |= RIOC_COR1_2STOP;
} else {
rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n");
- Cor1 |= COR1_1STOP;
+ Cor1 |= RIOC_COR1_1STOP;
}
if (TtyP->termios->c_cflag & PARENB) {
rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n");
- Cor1 |= COR1_NORMAL;
+ Cor1 |= RIOC_COR1_NORMAL;
} else {
rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n");
- Cor1 |= COR1_NOP;
+ Cor1 |= RIOC_COR1_NOP;
}
if (TtyP->termios->c_cflag & PARODD) {
rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n");
- Cor1 |= COR1_ODD;
+ Cor1 |= RIOC_COR1_ODD;
} else {
rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n");
- Cor1 |= COR1_EVEN;
+ Cor1 |= RIOC_COR1_EVEN;
}
/*
@@ -292,11 +292,11 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
*/
if (TtyP->termios->c_iflag & IXON) {
rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n");
- Cor2 |= COR2_IXON;
+ Cor2 |= RIOC_COR2_IXON;
} else {
if (PortP->Config & RIO_IXON) {
rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
- Cor2 |= COR2_IXON;
+ Cor2 |= RIOC_COR2_IXON;
} else
rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n");
}
@@ -304,29 +304,29 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
if (TtyP->termios->c_iflag & IXANY) {
if (PortP->Config & RIO_IXANY) {
rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n");
- Cor2 |= COR2_IXANY;
+ Cor2 |= RIOC_COR2_IXANY;
} else
rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
}
if (TtyP->termios->c_iflag & IXOFF) {
rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
- Cor2 |= COR2_IXOFF;
+ Cor2 |= RIOC_COR2_IXOFF;
}
if (TtyP->termios->c_cflag & HUPCL) {
rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n");
- Cor2 |= COR2_HUPCL;
+ Cor2 |= RIOC_COR2_HUPCL;
}
if (C_CRTSCTS(TtyP)) {
rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
- Cor2 |= COR2_CTSFLOW;
- Cor2 |= COR2_RTSFLOW;
+ Cor2 |= RIOC_COR2_CTSFLOW;
+ Cor2 |= RIOC_COR2_RTSFLOW;
} else {
rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
- Cor2 &= ~COR2_CTSFLOW;
- Cor2 &= ~COR2_RTSFLOW;
+ Cor2 &= ~RIOC_COR2_CTSFLOW;
+ Cor2 &= ~RIOC_COR2_RTSFLOW;
}
@@ -341,36 +341,36 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
*/
if (TtyP->termios->c_iflag & IGNBRK) {
rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n");
- Cor4 |= COR4_IGNBRK;
+ Cor4 |= RIOC_COR4_IGNBRK;
}
if (!(TtyP->termios->c_iflag & BRKINT)) {
rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n");
- Cor4 |= COR4_NBRKINT;
+ Cor4 |= RIOC_COR4_NBRKINT;
} else {
rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n");
}
if (TtyP->termios->c_iflag & INLCR) {
rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
- Cor4 |= COR4_INLCR;
+ Cor4 |= RIOC_COR4_INLCR;
}
if (TtyP->termios->c_iflag & IGNCR) {
rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
- Cor4 |= COR4_IGNCR;
+ Cor4 |= RIOC_COR4_IGNCR;
}
if (TtyP->termios->c_iflag & ICRNL) {
rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
- Cor4 |= COR4_ICRNL;
+ Cor4 |= RIOC_COR4_ICRNL;
}
if (TtyP->termios->c_iflag & IGNPAR) {
rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
- Cor4 |= COR4_IGNPAR;
+ Cor4 |= RIOC_COR4_IGNPAR;
}
if (TtyP->termios->c_iflag & PARMRK) {
rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n");
- Cor4 |= COR4_PARMRK;
+ Cor4 |= RIOC_COR4_PARMRK;
}
/*
@@ -378,22 +378,22 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
** on reception of a config packet.
** The download code handles the zero baud condition.
*/
- Cor4 |= COR4_RAISEMOD;
+ Cor4 |= RIOC_COR4_RAISEMOD;
/*
** COR 5
*/
- Cor5 = COR5_CMOE;
+ Cor5 = RIOC_COR5_CMOE;
/*
** Set to monitor tbusy/tstop (or not).
*/
if (PortP->MonitorTstate)
- Cor5 |= COR5_TSTATE_ON;
+ Cor5 |= RIOC_COR5_TSTATE_ON;
else
- Cor5 |= COR5_TSTATE_OFF;
+ Cor5 |= RIOC_COR5_TSTATE_OFF;
/*
** Could set LNE here if you wanted LNext processing. SVR4 will use it.
@@ -401,24 +401,24 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
if (TtyP->termios->c_iflag & ISTRIP) {
rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n");
if (!(PortP->State & RIO_TRIAD_MODE)) {
- Cor5 |= COR5_ISTRIP;
+ Cor5 |= RIOC_COR5_ISTRIP;
}
}
if (TtyP->termios->c_oflag & ONLCR) {
rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
if (PortP->CookMode == COOK_MEDIUM)
- Cor5 |= COR5_ONLCR;
+ Cor5 |= RIOC_COR5_ONLCR;
}
if (TtyP->termios->c_oflag & OCRNL) {
rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
if (PortP->CookMode == COOK_MEDIUM)
- Cor5 |= COR5_OCRNL;
+ Cor5 |= RIOC_COR5_OCRNL;
}
if ((TtyP->termios->c_oflag & TABDLY) == TAB3) {
rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n");
if (PortP->CookMode == COOK_MEDIUM)
- Cor5 |= COR5_TAB3;
+ Cor5 |= RIOC_COR5_TAB3;
}
/*
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index 1cb8580a161..c99354843be 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -211,7 +211,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
if (repeat_this-- <= 0) {
rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
retval = -EINTR;
goto bombout;
}
@@ -264,7 +264,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
here. If I read the docs correctly the "open"
command piggybacks the parameters immediately.
-- REW */
- RIOParam(PortP, OPEN, 1, OK_TO_SLEEP); /* Open the port */
+ RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */
rio_spin_lock_irqsave(&PortP->portSem, flags);
/*
@@ -275,7 +275,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
func_exit();
return -EINTR;
}
@@ -297,7 +297,8 @@ int riotopen(struct tty_struct *tty, struct file *filp)
** insert test for carrier here. -- ???
** I already see that test here. What's the deal? -- REW
*/
- if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD)) {
+ if ((PortP->gs.tty->termios->c_cflag & CLOCAL) ||
+ (PortP->ModemState & RIOC_MSVR1_CD)) {
rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
/*
tp->tm.c_state |= CARR_ON;
@@ -325,7 +326,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
** I think it's OK. -- REW
*/
rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort);
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
/*
tp->tm.c_state &= ~WOPEN;
*/
@@ -416,7 +417,7 @@ int riotclose(void *ptr)
*/
PortP->State &= ~RIO_MOPEN;
PortP->State &= ~RIO_CARR_ON;
- PortP->ModemState &= ~MSVR1_CD;
+ PortP->ModemState &= ~RIOC_MSVR1_CD;
/*
** If the device was open as both a Modem and a tty line
** then we need to wimp out here, as the port has not really
@@ -453,7 +454,7 @@ int riotclose(void *ptr)
if (repeat_this-- <= 0) {
rv = -EINTR;
rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
goto close_end;
}
rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -492,8 +493,8 @@ int riotclose(void *ptr)
/* Can't call RIOShortCommand with the port locked. */
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
- if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) {
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
}
@@ -503,7 +504,7 @@ int riotclose(void *ptr)
try--;
if (time_after(jiffies, end_time)) {
rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n");
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
break;
}
rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN);
@@ -515,14 +516,14 @@ int riotclose(void *ptr)
}
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n");
- RIOPreemptiveCmd(p, PortP, FCLOSE);
+ RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE);
break;
}
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try);
- /* RIOPreemptiveCmd(p, PortP, FCLOSE); */
+ /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */
/*
** 15.10.1998 ARG - ESIL 0761 part fix
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 3f9d0a9ac36..f073c710ab8 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -4,9 +4,9 @@
* Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
*
* This code is loosely based on the Linux serial driver, written by
- * Linus Torvalds, Theodore T'so and others. The RISCom/8 card
- * programming info was obtained from various drivers for other OSes
- * (FreeBSD, ISC, etc), but no source code from those drivers were
+ * Linus Torvalds, Theodore T'so and others. The RISCom/8 card
+ * programming info was obtained from various drivers for other OSes
+ * (FreeBSD, ISC, etc), but no source code from those drivers were
* directly included in this driver.
*
*
@@ -33,7 +33,7 @@
#include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
@@ -49,7 +49,7 @@
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "riscom8.h"
#include "riscom8_reg.h"
@@ -57,15 +57,15 @@
/* Am I paranoid or not ? ;-) */
#define RISCOM_PARANOIA_CHECK
-/*
- * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals.
+/*
+ * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals.
* You can slightly speed up things by #undefing the following option,
- * if you are REALLY sure that your board is correct one.
+ * if you are REALLY sure that your board is correct one.
*/
#define RISCOM_BRAIN_DAMAGED_CTS
-/*
+/*
* The following defines are mostly for testing purposes. But if you need
* some nice reporting in your syslog, you can define them also.
*/
@@ -112,7 +112,7 @@ static unsigned short rc_ioport[] = {
#define RC_NIOPORT ARRAY_SIZE(rc_ioport)
-static inline int rc_paranoia_check(struct riscom_port const * port,
+static int rc_paranoia_check(struct riscom_port const *port,
char *name, const char *routine)
{
#ifdef RISCOM_PARANOIA_CHECK
@@ -134,52 +134,53 @@ static inline int rc_paranoia_check(struct riscom_port const * port,
}
/*
- *
+ *
* Service functions for RISCom/8 driver.
- *
+ *
*/
/* Get board number from pointer */
-static inline int board_No (struct riscom_board const * bp)
+static inline int board_No(struct riscom_board const *bp)
{
return bp - rc_board;
}
/* Get port number from pointer */
-static inline int port_No (struct riscom_port const * port)
+static inline int port_No(struct riscom_port const *port)
{
- return RC_PORT(port - rc_port);
+ return RC_PORT(port - rc_port);
}
/* Get pointer to board from pointer to port */
-static inline struct riscom_board * port_Board(struct riscom_port const * port)
+static inline struct riscom_board *port_Board(struct riscom_port const *port)
{
return &rc_board[RC_BOARD(port - rc_port)];
}
/* Input Byte from CL CD180 register */
-static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg)
+static inline unsigned char rc_in(struct riscom_board const *bp,
+ unsigned short reg)
{
return inb(bp->base + RC_TO_ISA(reg));
}
/* Output Byte to CL CD180 register */
-static inline void rc_out(struct riscom_board const * bp, unsigned short reg,
+static inline void rc_out(struct riscom_board const *bp, unsigned short reg,
unsigned char val)
{
outb(val, bp->base + RC_TO_ISA(reg));
}
/* Wait for Channel Command Register ready */
-static inline void rc_wait_CCR(struct riscom_board const * bp)
+static void rc_wait_CCR(struct riscom_board const *bp)
{
unsigned long delay;
/* FIXME: need something more descriptive then 100000 :) */
- for (delay = 100000; delay; delay--)
+ for (delay = 100000; delay; delay--)
if (!rc_in(bp, CD180_CCR))
return;
-
+
printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp));
}
@@ -187,11 +188,11 @@ static inline void rc_wait_CCR(struct riscom_board const * bp)
* RISCom/8 probe functions.
*/
-static inline int rc_request_io_range(struct riscom_board * const bp)
+static int rc_request_io_range(struct riscom_board * const bp)
{
int i;
-
- for (i = 0; i < RC_NIOPORT; i++)
+
+ for (i = 0; i < RC_NIOPORT; i++)
if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1,
"RISCom/8")) {
goto out_release;
@@ -200,42 +201,42 @@ static inline int rc_request_io_range(struct riscom_board * const bp)
out_release:
printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n",
board_No(bp), bp->base);
- while(--i >= 0)
+ while (--i >= 0)
release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
return 1;
}
-static inline void rc_release_io_range(struct riscom_board * const bp)
+static void rc_release_io_range(struct riscom_board * const bp)
{
int i;
-
- for (i = 0; i < RC_NIOPORT; i++)
+
+ for (i = 0; i < RC_NIOPORT; i++)
release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
}
-
+
/* Reset and setup CD180 chip */
-static void __init rc_init_CD180(struct riscom_board const * bp)
+static void __init rc_init_CD180(struct riscom_board const *bp)
{
unsigned long flags;
-
+
spin_lock_irqsave(&riscom_lock, flags);
- rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
- rc_wait_CCR(bp); /* Wait for CCR ready */
- rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
+ rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
+ rc_wait_CCR(bp); /* Wait for CCR ready */
+ rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
spin_unlock_irqrestore(&riscom_lock, flags);
- msleep(50); /* Delay 0.05 sec */
+ msleep(50); /* Delay 0.05 sec */
spin_lock_irqsave(&riscom_lock, flags);
- rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
- rc_out(bp, CD180_GICR, 0); /* Clear all bits */
- rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
- rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for transmitter intr */
- rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for receiver intr */
-
+ rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
+ rc_out(bp, CD180_GICR, 0); /* Clear all bits */
+ rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
+ rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */
+ rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */
+
/* Setting up prescaler. We need 4 ticks per 1 ms */
rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
-
+
spin_unlock_irqrestore(&riscom_lock, flags);
}
@@ -245,12 +246,12 @@ static int __init rc_probe(struct riscom_board *bp)
unsigned char val1, val2;
int irqs = 0;
int retries;
-
+
bp->irq = 0;
if (rc_request_io_range(bp))
return 1;
-
+
/* Are the I/O ports here ? */
rc_out(bp, CD180_PPRL, 0x5a);
outb(0xff, 0x80);
@@ -258,34 +259,34 @@ static int __init rc_probe(struct riscom_board *bp)
rc_out(bp, CD180_PPRL, 0xa5);
outb(0x00, 0x80);
val2 = rc_in(bp, CD180_PPRL);
-
+
if ((val1 != 0x5a) || (val2 != 0xa5)) {
printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n",
board_No(bp), bp->base);
goto out_release;
}
-
+
/* It's time to find IRQ for this board */
- for (retries = 0; retries < 5 && irqs <= 0; retries++) {
+ for (retries = 0; retries < 5 && irqs <= 0; retries++) {
irqs = probe_irq_on();
- rc_init_CD180(bp); /* Reset CD180 chip */
- rc_out(bp, CD180_CAR, 2); /* Select port 2 */
+ rc_init_CD180(bp); /* Reset CD180 chip */
+ rc_out(bp, CD180_CAR, 2); /* Select port 2 */
rc_wait_CCR(bp);
- rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */
- rc_out(bp, CD180_IER, IER_TXRDY); /* Enable tx empty intr */
+ rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */
+ rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */
msleep(50);
irqs = probe_irq_off(irqs);
- val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */
- val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */
- rc_init_CD180(bp); /* Reset CD180 again */
-
+ val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */
+ val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */
+ rc_init_CD180(bp); /* Reset CD180 again */
+
if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) {
printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not "
"found.\n", board_No(bp), bp->base);
goto out_release;
}
}
-
+
if (irqs <= 0) {
printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board "
"at 0x%03x.\n", board_No(bp), bp->base);
@@ -293,113 +294,112 @@ static int __init rc_probe(struct riscom_board *bp)
}
bp->irq = irqs;
bp->flags |= RC_BOARD_PRESENT;
-
+
printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at "
"0x%03x, IRQ %d.\n",
board_No(bp),
(rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */
bp->base, bp->irq);
-
+
return 0;
out_release:
rc_release_io_range(bp);
return 1;
}
-/*
- *
+/*
+ *
* Interrupt processing routines.
- *
+ *
*/
-static inline struct riscom_port * rc_get_port(struct riscom_board const * bp,
- unsigned char const * what)
+static struct riscom_port *rc_get_port(struct riscom_board const *bp,
+ unsigned char const *what)
{
unsigned char channel;
- struct riscom_port * port;
-
+ struct riscom_port *port;
+
channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
if (channel < CD180_NCH) {
port = &rc_port[board_No(bp) * RC_NPORT + channel];
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->flags & ASYNC_INITIALIZED)
return port;
- }
}
- printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
+ printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
board_No(bp), what, channel);
return NULL;
}
-static inline void rc_receive_exc(struct riscom_board const * bp)
+static void rc_receive_exc(struct riscom_board const *bp)
{
struct riscom_port *port;
struct tty_struct *tty;
unsigned char status;
unsigned char ch, flag;
-
- if (!(port = rc_get_port(bp, "Receive")))
+
+ port = rc_get_port(bp, "Receive");
+ if (port == NULL)
return;
tty = port->tty;
-
-#ifdef RC_REPORT_OVERRUN
+
+#ifdef RC_REPORT_OVERRUN
status = rc_in(bp, CD180_RCSR);
if (status & RCSR_OE)
port->overrun++;
status &= port->mark_mask;
-#else
+#else
status = rc_in(bp, CD180_RCSR) & port->mark_mask;
-#endif
+#endif
ch = rc_in(bp, CD180_RDR);
- if (!status) {
+ if (!status)
return;
- }
if (status & RCSR_TOUT) {
printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
- "Hardware problems ?\n",
+ "Hardware problems ?\n",
board_No(bp), port_No(port));
return;
-
+
} else if (status & RCSR_BREAK) {
printk(KERN_INFO "rc%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
flag = TTY_BREAK;
if (port->flags & ASYNC_SAK)
do_SAK(tty);
-
- } else if (status & RCSR_PE)
+
+ } else if (status & RCSR_PE)
flag = TTY_PARITY;
-
- else if (status & RCSR_FE)
+
+ else if (status & RCSR_FE)
flag = TTY_FRAME;
-
- else if (status & RCSR_OE)
+
+ else if (status & RCSR_OE)
flag = TTY_OVERRUN;
-
else
flag = TTY_NORMAL;
-
+
tty_insert_flip_char(tty, ch, flag);
tty_flip_buffer_push(tty);
}
-static inline void rc_receive(struct riscom_board const * bp)
+static void rc_receive(struct riscom_board const *bp)
{
struct riscom_port *port;
struct tty_struct *tty;
unsigned char count;
-
- if (!(port = rc_get_port(bp, "Receive")))
+
+ port = rc_get_port(bp, "Receive");
+ if (port == NULL)
return;
-
+
tty = port->tty;
-
+
count = rc_in(bp, CD180_RDCR);
-
+
#ifdef RC_REPORT_FIFO
port->hits[count > 8 ? 9 : count]++;
-#endif
-
+#endif
+
while (count--) {
if (tty_buffer_request_room(tty, 1) == 0) {
printk(KERN_WARNING "rc%d: port %d: Working around "
@@ -412,26 +412,26 @@ static inline void rc_receive(struct riscom_board const * bp)
tty_flip_buffer_push(tty);
}
-static inline void rc_transmit(struct riscom_board const * bp)
+static void rc_transmit(struct riscom_board const *bp)
{
struct riscom_port *port;
struct tty_struct *tty;
unsigned char count;
-
-
- if (!(port = rc_get_port(bp, "Transmit")))
+
+ port = rc_get_port(bp, "Transmit");
+ if (port == NULL)
return;
-
+
tty = port->tty;
-
- if (port->IER & IER_TXEMPTY) {
+
+ if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
rc_out(bp, CD180_CAR, port_No(port));
port->IER &= ~IER_TXEMPTY;
rc_out(bp, CD180_IER, port->IER);
return;
}
-
+
if ((port->xmit_cnt <= 0 && !port->break_length)
|| tty->stopped || tty->hw_stopped) {
rc_out(bp, CD180_CAR, port_No(port));
@@ -439,7 +439,7 @@ static inline void rc_transmit(struct riscom_board const * bp)
rc_out(bp, CD180_IER, port->IER);
return;
}
-
+
if (port->break_length) {
if (port->break_length > 0) {
if (port->COR2 & COR2_ETC) {
@@ -451,7 +451,8 @@ static inline void rc_transmit(struct riscom_board const * bp)
rc_out(bp, CD180_TDR, CD180_C_ESC);
rc_out(bp, CD180_TDR, CD180_C_DELAY);
rc_out(bp, CD180_TDR, count);
- if (!(port->break_length -= count))
+ port->break_length -= count;
+ if (port->break_length == 0)
port->break_length--;
} else {
rc_out(bp, CD180_TDR, CD180_C_ESC);
@@ -463,7 +464,7 @@ static inline void rc_transmit(struct riscom_board const * bp)
}
return;
}
-
+
count = CD180_NFIFO;
do {
rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
@@ -471,7 +472,7 @@ static inline void rc_transmit(struct riscom_board const * bp)
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
-
+
if (port->xmit_cnt <= 0) {
rc_out(bp, CD180_CAR, port_No(port));
port->IER &= ~IER_TXRDY;
@@ -481,25 +482,26 @@ static inline void rc_transmit(struct riscom_board const * bp)
tty_wakeup(tty);
}
-static inline void rc_check_modem(struct riscom_board const * bp)
+static void rc_check_modem(struct riscom_board const *bp)
{
struct riscom_port *port;
struct tty_struct *tty;
unsigned char mcr;
-
- if (!(port = rc_get_port(bp, "Modem")))
+
+ port = rc_get_port(bp, "Modem");
+ if (port == NULL)
return;
-
+
tty = port->tty;
-
+
mcr = rc_in(bp, CD180_MCR);
- if (mcr & MCR_CDCHG) {
- if (rc_in(bp, CD180_MSVR) & MSVR_CD)
+ if (mcr & MCR_CDCHG) {
+ if (rc_in(bp, CD180_MSVR) & MSVR_CD)
wake_up_interruptible(&port->open_wait);
else
tty_hangup(tty);
}
-
+
#ifdef RISCOM_BRAIN_DAMAGED_CTS
if (mcr & MCR_CTSCHG) {
if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
@@ -526,13 +528,13 @@ static inline void rc_check_modem(struct riscom_board const * bp)
rc_out(bp, CD180_IER, port->IER);
}
#endif /* RISCOM_BRAIN_DAMAGED_CTS */
-
+
/* Clear change bits */
rc_out(bp, CD180_MCR, 0);
}
/* The main interrupt processing routine */
-static irqreturn_t rc_interrupt(int dummy, void * dev_id)
+static irqreturn_t rc_interrupt(int dummy, void *dev_id)
{
unsigned char status;
unsigned char ack;
@@ -547,13 +549,11 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id)
(RC_BSR_TOUT | RC_BSR_TINT |
RC_BSR_MINT | RC_BSR_RINT))) {
handled = 1;
- if (status & RC_BSR_TOUT)
+ if (status & RC_BSR_TOUT)
printk(KERN_WARNING "rc%d: Got timeout. Hardware "
"error?\n", board_No(bp));
-
else if (status & RC_BSR_RINT) {
ack = rc_in(bp, RC_ACK_RINT);
-
if (ack == (RC_ID | GIVR_IT_RCV))
rc_receive(bp);
else if (ack == (RC_ID | GIVR_IT_REXC))
@@ -562,29 +562,23 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id)
printk(KERN_WARNING "rc%d: Bad receive ack "
"0x%02x.\n",
board_No(bp), ack);
-
} else if (status & RC_BSR_TINT) {
ack = rc_in(bp, RC_ACK_TINT);
-
if (ack == (RC_ID | GIVR_IT_TX))
rc_transmit(bp);
else
printk(KERN_WARNING "rc%d: Bad transmit ack "
"0x%02x.\n",
board_No(bp), ack);
-
} else /* if (status & RC_BSR_MINT) */ {
ack = rc_in(bp, RC_ACK_MINT);
-
- if (ack == (RC_ID | GIVR_IT_MODEM))
+ if (ack == (RC_ID | GIVR_IT_MODEM))
rc_check_modem(bp);
else
printk(KERN_WARNING "rc%d: Bad modem ack "
"0x%02x.\n",
board_No(bp), ack);
-
- }
-
+ }
rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */
rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */
}
@@ -596,24 +590,24 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id)
*/
/* Called with disabled interrupts */
-static int rc_setup_board(struct riscom_board * bp)
+static int rc_setup_board(struct riscom_board *bp)
{
int error;
- if (bp->flags & RC_BOARD_ACTIVE)
+ if (bp->flags & RC_BOARD_ACTIVE)
return 0;
-
+
error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED,
"RISCom/8", bp);
- if (error)
+ if (error)
return error;
-
+
rc_out(bp, RC_CTOUT, 0); /* Just in case */
bp->DTR = ~0;
rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
-
+
bp->flags |= RC_BOARD_ACTIVE;
-
+
return 0;
}
@@ -622,40 +616,40 @@ static void rc_shutdown_board(struct riscom_board *bp)
{
if (!(bp->flags & RC_BOARD_ACTIVE))
return;
-
+
bp->flags &= ~RC_BOARD_ACTIVE;
-
+
free_irq(bp->irq, NULL);
-
+
bp->DTR = ~0;
rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
-
+
}
/*
- * Setting up port characteristics.
+ * Setting up port characteristics.
* Must be called with disabled interrupts
*/
static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
{
- struct tty_struct *tty;
+ struct tty_struct *tty = port->tty;
unsigned long baud;
long tmp;
unsigned char cor1 = 0, cor3 = 0;
unsigned char mcor1 = 0, mcor2 = 0;
-
- if (!(tty = port->tty) || !tty->termios)
+
+ if (tty == NULL || tty->termios == NULL)
return;
port->IER = 0;
port->COR2 = 0;
port->MSVR = MSVR_RTS;
-
+
baud = tty_get_baud_rate(tty);
-
+
/* Select port on the board */
rc_out(bp, CD180_CAR, port_No(port));
-
+
if (!baud) {
/* Drop DTR & exit */
bp->DTR |= (1u << port_No(port));
@@ -666,69 +660,68 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
bp->DTR &= ~(1u << port_No(port));
rc_out(bp, RC_DTR, bp->DTR);
}
-
+
/*
- * Now we must calculate some speed depended things
+ * Now we must calculate some speed depended things
*/
-
+
/* Set baud rate for port */
tmp = (((RC_OSCFREQ + baud/2) / baud +
CD180_TPC/2) / CD180_TPC);
- rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
- rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
- rc_out(bp, CD180_RBPRL, tmp & 0xff);
+ rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
+ rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
+ rc_out(bp, CD180_RBPRL, tmp & 0xff);
rc_out(bp, CD180_TBPRL, tmp & 0xff);
-
+
baud = (baud + 5) / 10; /* Estimated CPS */
-
+
/* Two timer ticks seems enough to wakeup something like SLIP driver */
- tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
+ tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
SERIAL_XMIT_SIZE - 1 : tmp);
-
+
/* Receiver timeout will be transmission time for 1.5 chars */
tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
tmp = (tmp > 0xff) ? 0xff : tmp;
rc_out(bp, CD180_RTPR, tmp);
-
- switch (C_CSIZE(tty)) {
- case CS5:
+
+ switch (C_CSIZE(tty)) {
+ case CS5:
cor1 |= COR1_5BITS;
break;
- case CS6:
+ case CS6:
cor1 |= COR1_6BITS;
break;
- case CS7:
+ case CS7:
cor1 |= COR1_7BITS;
break;
- case CS8:
+ case CS8:
cor1 |= COR1_8BITS;
break;
}
-
- if (C_CSTOPB(tty))
+ if (C_CSTOPB(tty))
cor1 |= COR1_2SB;
-
+
cor1 |= COR1_IGNORE;
- if (C_PARENB(tty)) {
+ if (C_PARENB(tty)) {
cor1 |= COR1_NORMPAR;
- if (C_PARODD(tty))
+ if (C_PARODD(tty))
cor1 |= COR1_ODDP;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
cor1 &= ~COR1_IGNORE;
}
/* Set marking of some errors */
port->mark_mask = RCSR_OE | RCSR_TOUT;
- if (I_INPCK(tty))
+ if (I_INPCK(tty))
port->mark_mask |= RCSR_FE | RCSR_PE;
- if (I_BRKINT(tty) || I_PARMRK(tty))
+ if (I_BRKINT(tty) || I_PARMRK(tty))
port->mark_mask |= RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
port->mark_mask &= ~(RCSR_FE | RCSR_PE);
- if (I_IGNBRK(tty)) {
+ if (I_IGNBRK(tty)) {
port->mark_mask &= ~RCSR_BREAK;
- if (I_IGNPAR(tty))
+ if (I_IGNPAR(tty))
/* Real raw mode. Ignore all */
port->mark_mask &= ~RCSR_OE;
}
@@ -738,7 +731,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
port->IER |= IER_DSR | IER_CTS;
mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
- tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
+ tty->hw_stopped = !(rc_in(bp, CD180_MSVR) &
+ (MSVR_CTS|MSVR_DSR));
#else
port->COR2 |= COR2_CTSAE;
#endif
@@ -761,13 +755,13 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
mcor1 |= MCOR1_CDZD;
mcor2 |= MCOR2_CDOD;
}
-
- if (C_CREAD(tty))
+
+ if (C_CREAD(tty))
/* Enable receiver */
port->IER |= IER_RXD;
-
+
/* Set input FIFO size (1-8 bytes) */
- cor3 |= RISCOM_RXFIFO;
+ cor3 |= RISCOM_RXFIFO;
/* Setting up CD180 channel registers */
rc_out(bp, CD180_COR1, cor1);
rc_out(bp, CD180_COR2, port->COR2);
@@ -791,36 +785,30 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
{
unsigned long flags;
-
+
if (port->flags & ASYNC_INITIALIZED)
return 0;
-
+
if (!port->xmit_buf) {
/* We may sleep in get_zeroed_page() */
- unsigned long tmp;
-
- if (!(tmp = get_zeroed_page(GFP_KERNEL)))
+ unsigned long tmp = get_zeroed_page(GFP_KERNEL);
+ if (tmp == 0)
return -ENOMEM;
-
- if (port->xmit_buf) {
+ if (port->xmit_buf)
free_page(tmp);
- return -ERESTARTSYS;
- }
- port->xmit_buf = (unsigned char *) tmp;
+ else
+ port->xmit_buf = (unsigned char *) tmp;
}
-
spin_lock_irqsave(&riscom_lock, flags);
- if (port->tty)
+ if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
-
- if (port->count == 1)
+ if (port->count == 1)
bp->count++;
-
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
rc_change_speed(bp, port);
port->flags |= ASYNC_INITIALIZED;
-
+
spin_unlock_irqrestore(&riscom_lock, flags);
return 0;
}
@@ -829,38 +817,39 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
{
struct tty_struct *tty;
-
- if (!(port->flags & ASYNC_INITIALIZED))
+
+ if (!(port->flags & ASYNC_INITIALIZED))
return;
-
+
#ifdef RC_REPORT_OVERRUN
printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
board_No(bp), port_No(port), port->overrun);
-#endif
+#endif
#ifdef RC_REPORT_FIFO
{
int i;
-
+
printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
board_No(bp), port_No(port));
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 10; i++)
printk("%ld ", port->hits[i]);
- }
printk("].\n");
}
-#endif
+#endif
if (port->xmit_buf) {
free_page((unsigned long) port->xmit_buf);
port->xmit_buf = NULL;
}
- if (!(tty = port->tty) || C_HUPCL(tty)) {
+ tty = port->tty;
+
+ if (tty == NULL || C_HUPCL(tty)) {
/* Drop DTR */
bp->DTR |= (1u << port_No(port));
rc_out(bp, RC_DTR, bp->DTR);
}
-
- /* Select port */
+
+ /* Select port */
rc_out(bp, CD180_CAR, port_No(port));
/* Reset port */
rc_wait_CCR(bp);
@@ -868,28 +857,26 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
/* Disable all interrupts from this port */
port->IER = 0;
rc_out(bp, CD180_IER, port->IER);
-
- if (tty)
+
+ if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->flags &= ~ASYNC_INITIALIZED;
-
+
if (--bp->count < 0) {
printk(KERN_INFO "rc%d: rc_shutdown_port: "
"bad board count: %d\n",
board_No(bp), bp->count);
bp->count = 0;
}
-
/*
* If this is the last opened port on the board
* shutdown whole board
*/
- if (!bp->count)
+ if (!bp->count)
rc_shutdown_board(bp);
}
-
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
struct riscom_port *port)
{
DECLARE_WAITQUEUE(wait, current);
@@ -921,7 +908,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
return 0;
}
- if (C_CLOCAL(tty))
+ if (C_CLOCAL(tty))
do_clocal = 1;
/*
@@ -959,7 +946,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
break;
}
if (!(port->flags & ASYNC_CLOSING) &&
@@ -978,50 +965,63 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
port->blocked_open--;
if (retval)
return retval;
-
+
port->flags |= ASYNC_NORMAL_ACTIVE;
return 0;
-}
+}
-static int rc_open(struct tty_struct * tty, struct file * filp)
+static int rc_open(struct tty_struct *tty, struct file *filp)
{
int board;
int error;
- struct riscom_port * port;
- struct riscom_board * bp;
-
+ struct riscom_port *port;
+ struct riscom_board *bp;
+
board = RC_BOARD(tty->index);
if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
return -ENODEV;
-
+
bp = &rc_board[board];
port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
if (rc_paranoia_check(port, tty->name, "rc_open"))
return -ENODEV;
-
- if ((error = rc_setup_board(bp)))
+
+ error = rc_setup_board(bp);
+ if (error)
return error;
-
+
port->count++;
tty->driver_data = port;
port->tty = tty;
-
- if ((error = rc_setup_port(bp, port)))
- return error;
-
- if ((error = block_til_ready(tty, filp, port)))
- return error;
-
- return 0;
+
+ error = rc_setup_port(bp, port);
+ if (error == 0)
+ error = block_til_ready(tty, filp, port);
+ return error;
}
-static void rc_close(struct tty_struct * tty, struct file * filp)
+static void rc_flush_buffer(struct tty_struct *tty)
+{
+ struct riscom_port *port = (struct riscom_port *)tty->driver_data;
+ unsigned long flags;
+
+ if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
+ return;
+
+ spin_lock_irqsave(&riscom_lock, flags);
+ port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+ spin_unlock_irqrestore(&riscom_lock, flags);
+
+ tty_wakeup(tty);
+}
+
+static void rc_close(struct tty_struct *tty, struct file *filp)
{
struct riscom_port *port = (struct riscom_port *) tty->driver_data;
struct riscom_board *bp;
unsigned long flags;
unsigned long timeout;
-
+
if (!port || rc_paranoia_check(port, tty->name, "close"))
return;
@@ -1029,7 +1029,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
if (tty_hung_up_p(filp))
goto out;
-
+
bp = port_Board(port);
if ((tty->count == 1) && (port->count != 1)) {
printk(KERN_INFO "rc%d: rc_close: bad port count;"
@@ -1047,7 +1047,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
goto out;
port->flags |= ASYNC_CLOSING;
/*
- * Now we wait for the transmit buffer to clear; and we notify
+ * Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
@@ -1070,24 +1070,22 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
* has completely drained; this is especially
* important if there is a transmit FIFO!
*/
- timeout = jiffies+HZ;
- while(port->IER & IER_TXEMPTY) {
+ timeout = jiffies + HZ;
+ while (port->IER & IER_TXEMPTY) {
msleep_interruptible(jiffies_to_msecs(port->timeout));
if (time_after(jiffies, timeout))
break;
}
}
rc_shutdown_port(bp, port);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ rc_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
port->tty = NULL;
if (port->blocked_open) {
- if (port->close_delay) {
+ if (port->close_delay)
msleep_interruptible(jiffies_to_msecs(port->close_delay));
- }
wake_up_interruptible(&port->open_wait);
}
port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1097,17 +1095,17 @@ out:
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static int rc_write(struct tty_struct * tty,
+static int rc_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
int c, total = 0;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_write"))
return 0;
-
+
bp = port_Board(port);
if (!tty || !port->xmit_buf)
@@ -1144,38 +1142,41 @@ static int rc_write(struct tty_struct * tty,
return total;
}
-static void rc_put_char(struct tty_struct * tty, unsigned char ch)
+static int rc_put_char(struct tty_struct *tty, unsigned char ch)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
unsigned long flags;
+ int ret = 0;
if (rc_paranoia_check(port, tty->name, "rc_put_char"))
- return;
+ return 0;
if (!tty || !port->xmit_buf)
- return;
+ return 0;
spin_lock_irqsave(&riscom_lock, flags);
-
+
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
goto out;
port->xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= SERIAL_XMIT_SIZE - 1;
port->xmit_cnt++;
+ ret = 1;
out:
spin_unlock_irqrestore(&riscom_lock, flags);
+ return ret;
}
-static void rc_flush_chars(struct tty_struct * tty)
+static void rc_flush_chars(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
return;
-
+
if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
!port->xmit_buf)
return;
@@ -1189,11 +1190,11 @@ static void rc_flush_chars(struct tty_struct * tty)
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static int rc_write_room(struct tty_struct * tty)
+static int rc_write_room(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
int ret;
-
+
if (rc_paranoia_check(port, tty->name, "rc_write_room"))
return 0;
@@ -1206,39 +1207,22 @@ static int rc_write_room(struct tty_struct * tty)
static int rc_chars_in_buffer(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
-
+
if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
return 0;
-
- return port->xmit_cnt;
-}
-
-static void rc_flush_buffer(struct tty_struct *tty)
-{
- struct riscom_port *port = (struct riscom_port *)tty->driver_data;
- unsigned long flags;
-
- if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
- return;
-
- spin_lock_irqsave(&riscom_lock, flags);
-
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- spin_unlock_irqrestore(&riscom_lock, flags);
-
- tty_wakeup(tty);
+ return port->xmit_cnt;
}
static int rc_tiocmget(struct tty_struct *tty, struct file *file)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
- struct riscom_board * bp;
+ struct riscom_board *bp;
unsigned char status;
unsigned int result;
unsigned long flags;
- if (rc_paranoia_check(port, tty->name, __FUNCTION__))
+ if (rc_paranoia_check(port, tty->name, __func__))
return -ENODEV;
bp = port_Board(port);
@@ -1266,7 +1250,7 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
unsigned long flags;
struct riscom_board *bp;
- if (rc_paranoia_check(port, tty->name, __FUNCTION__))
+ if (rc_paranoia_check(port, tty->name, __func__))
return -ENODEV;
bp = port_Board(port);
@@ -1292,11 +1276,11 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
-static inline void rc_send_break(struct riscom_port * port, unsigned long length)
+static void rc_send_break(struct riscom_port *port, unsigned long length)
{
struct riscom_board *bp = port_Board(port);
unsigned long flags;
-
+
spin_lock_irqsave(&riscom_lock, flags);
port->break_length = RISCOM_TPS / HZ * length;
@@ -1312,17 +1296,17 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static inline int rc_set_serial_info(struct riscom_port * port,
- struct serial_struct __user * newinfo)
+static int rc_set_serial_info(struct riscom_port *port,
+ struct serial_struct __user *newinfo)
{
struct serial_struct tmp;
struct riscom_board *bp = port_Board(port);
int change_speed;
-
+
if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
return -EFAULT;
-
-#if 0
+
+#if 0
if ((tmp.irq != bp->irq) ||
(tmp.port != bp->base) ||
(tmp.type != PORT_CIRRUS) ||
@@ -1331,16 +1315,16 @@ static inline int rc_set_serial_info(struct riscom_port * port,
(tmp.xmit_fifo_size != CD180_NFIFO) ||
(tmp.flags & ~RISCOM_LEGAL_FLAGS))
return -EINVAL;
-#endif
-
+#endif
+
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
-
+
if (!capable(CAP_SYS_ADMIN)) {
if ((tmp.close_delay != port->close_delay) ||
(tmp.closing_wait != port->closing_wait) ||
((tmp.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->flags & ~ASYNC_USR_MASK)))
return -EPERM;
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
(tmp.flags & ASYNC_USR_MASK));
@@ -1360,12 +1344,12 @@ static inline int rc_set_serial_info(struct riscom_port * port,
return 0;
}
-static inline int rc_get_serial_info(struct riscom_port * port,
+static int rc_get_serial_info(struct riscom_port *port,
struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
struct riscom_board *bp = port_Board(port);
-
+
memset(&tmp, 0, sizeof(tmp));
tmp.type = PORT_CIRRUS;
tmp.line = port - rc_port;
@@ -1379,19 +1363,18 @@ static inline int rc_get_serial_info(struct riscom_port * port,
return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
-static int rc_ioctl(struct tty_struct * tty, struct file * filp,
+static int rc_ioctl(struct tty_struct *tty, struct file *filp,
unsigned int cmd, unsigned long arg)
-
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
void __user *argp = (void __user *)arg;
- int retval;
-
+ int retval = 0;
+
if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
return -ENODEV;
-
+
switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
+ case TCSBRK: /* SVID version: non-zero arg --> no break */
retval = tty_check_change(tty);
if (retval)
return retval;
@@ -1399,45 +1382,40 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp,
if (!arg)
rc_send_break(port, HZ/4); /* 1/4 second */
break;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
+ case TCSBRKP: /* support for POSIX tcsendbreak() */
retval = tty_check_change(tty);
if (retval)
return retval;
tty_wait_until_sent(tty, 0);
rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
break;
- case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp);
- case TIOCSSOFTCAR:
- if (get_user(arg,(unsigned __user *) argp))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
+ case TIOCGSERIAL:
+ lock_kernel();
+ retval = rc_get_serial_info(port, argp);
+ unlock_kernel();
break;
- case TIOCGSERIAL:
- return rc_get_serial_info(port, argp);
- case TIOCSSERIAL:
- return rc_set_serial_info(port, argp);
- default:
- return -ENOIOCTLCMD;
+ case TIOCSSERIAL:
+ lock_kernel();
+ retval = rc_set_serial_info(port, argp);
+ unlock_kernel();
+ break;
+ default:
+ retval = -ENOIOCTLCMD;
}
- return 0;
+ return retval;
}
-static void rc_throttle(struct tty_struct * tty)
+static void rc_throttle(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_throttle"))
return;
-
bp = port_Board(port);
spin_lock_irqsave(&riscom_lock, flags);
-
port->MSVR &= ~MSVR_RTS;
rc_out(bp, CD180_CAR, port_No(port));
if (I_IXOFF(tty)) {
@@ -1446,23 +1424,20 @@ static void rc_throttle(struct tty_struct * tty)
rc_wait_CCR(bp);
}
rc_out(bp, CD180_MSVR, port->MSVR);
-
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static void rc_unthrottle(struct tty_struct * tty)
+static void rc_unthrottle(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
return;
-
bp = port_Board(port);
-
- spin_lock_irqsave(&riscom_lock, flags);
+ spin_lock_irqsave(&riscom_lock, flags);
port->MSVR |= MSVR_RTS;
rc_out(bp, CD180_CAR, port_No(port));
if (I_IXOFF(tty)) {
@@ -1471,62 +1446,58 @@ static void rc_unthrottle(struct tty_struct * tty)
rc_wait_CCR(bp);
}
rc_out(bp, CD180_MSVR, port->MSVR);
-
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static void rc_stop(struct tty_struct * tty)
+static void rc_stop(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_stop"))
return;
-
+
bp = port_Board(port);
-
- spin_lock_irqsave(&riscom_lock, flags);
+ spin_lock_irqsave(&riscom_lock, flags);
port->IER &= ~IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
-
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static void rc_start(struct tty_struct * tty)
+static void rc_start(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_start"))
return;
-
+
bp = port_Board(port);
-
+
spin_lock_irqsave(&riscom_lock, flags);
- if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
+ if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
}
-
spin_unlock_irqrestore(&riscom_lock, flags);
}
-static void rc_hangup(struct tty_struct * tty)
+static void rc_hangup(struct tty_struct *tty)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
struct riscom_board *bp;
-
+
if (rc_paranoia_check(port, tty->name, "rc_hangup"))
return;
-
+
bp = port_Board(port);
-
+
rc_shutdown_port(bp, port);
port->count = 0;
port->flags &= ~ASYNC_NORMAL_ACTIVE;
@@ -1534,17 +1505,14 @@ static void rc_hangup(struct tty_struct * tty)
wake_up_interruptible(&port->open_wait);
}
-static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
+static void rc_set_termios(struct tty_struct *tty,
+ struct ktermios *old_termios)
{
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
unsigned long flags;
-
+
if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
return;
-
- if (tty->termios->c_cflag == old_termios->c_cflag &&
- tty->termios->c_iflag == old_termios->c_iflag)
- return;
spin_lock_irqsave(&riscom_lock, flags);
rc_change_speed(port_Board(port), port);
@@ -1583,9 +1551,9 @@ static int __init rc_init_drivers(void)
int i;
riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
- if (!riscom_driver)
+ if (!riscom_driver)
return -ENOMEM;
-
+
riscom_driver->owner = THIS_MODULE;
riscom_driver->name = "ttyL";
riscom_driver->major = RISCOM8_NORMAL_MAJOR;
@@ -1598,23 +1566,21 @@ static int __init rc_init_drivers(void)
riscom_driver->init_termios.c_ospeed = 9600;
riscom_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(riscom_driver, &riscom_ops);
- if ((error = tty_register_driver(riscom_driver))) {
+ error = tty_register_driver(riscom_driver);
+ if (error != 0) {
put_tty_driver(riscom_driver);
printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
- "error = %d\n",
- error);
+ "error = %d\n", error);
return 1;
}
-
memset(rc_port, 0, sizeof(rc_port));
for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
rc_port[i].magic = RISCOM8_MAGIC;
- rc_port[i].close_delay = 50 * HZ/100;
- rc_port[i].closing_wait = 3000 * HZ/100;
+ rc_port[i].close_delay = 50 * HZ / 100;
+ rc_port[i].closing_wait = 3000 * HZ / 100;
init_waitqueue_head(&rc_port[i].open_wait);
init_waitqueue_head(&rc_port[i].close_wait);
}
-
return 0;
}
@@ -1627,13 +1593,13 @@ static void rc_release_drivers(void)
#ifndef MODULE
/*
* Called at boot time.
- *
+ *
* You can specify IO base for up to RC_NBOARD cards,
* using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
* Note that there will be no probing at default
* addresses in this case.
*
- */
+ */
static int __init riscom8_setup(char *str)
{
int ints[RC_NBOARD];
@@ -1644,7 +1610,7 @@ static int __init riscom8_setup(char *str)
for (i = 0; i < RC_NBOARD; i++) {
if (i < ints[0])
rc_board[i].base = ints[i+1];
- else
+ else
rc_board[i].base = 0;
}
return 1;
@@ -1659,8 +1625,8 @@ static char banner[] __initdata =
static char no_boards_msg[] __initdata =
KERN_INFO "rc: No RISCom/8 boards detected.\n";
-/*
- * This routine must be called by kernel at boot time
+/*
+ * This routine must be called by kernel at boot time
*/
static int __init riscom8_init(void)
{
@@ -1669,13 +1635,12 @@ static int __init riscom8_init(void)
printk(banner);
- if (rc_init_drivers())
+ if (rc_init_drivers())
return -EIO;
- for (i = 0; i < RC_NBOARD; i++)
- if (rc_board[i].base && !rc_probe(&rc_board[i]))
+ for (i = 0; i < RC_NBOARD; i++)
+ if (rc_board[i].base && !rc_probe(&rc_board[i]))
found++;
-
if (!found) {
rc_release_drivers();
printk(no_boards_msg);
@@ -1702,13 +1667,13 @@ MODULE_LICENSE("GPL");
* by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
*
*/
-static int __init riscom8_init_module (void)
+static int __init riscom8_init_module(void)
{
#ifdef MODULE
int i;
if (iobase || iobase1 || iobase2 || iobase3) {
- for(i = 0; i < RC_NBOARD; i++)
+ for (i = 0; i < RC_NBOARD; i++)
rc_board[i].base = 0;
}
@@ -1724,18 +1689,17 @@ static int __init riscom8_init_module (void)
return riscom8_init();
}
-
-static void __exit riscom8_exit_module (void)
+
+static void __exit riscom8_exit_module(void)
{
int i;
-
+
rc_release_drivers();
- for (i = 0; i < RC_NBOARD; i++)
- if (rc_board[i].flags & RC_BOARD_PRESENT)
+ for (i = 0; i < RC_NBOARD; i++)
+ if (rc_board[i].flags & RC_BOARD_PRESENT)
rc_release_io_range(&rc_board[i]);
-
+
}
module_init(riscom8_init_module);
module_exit(riscom8_exit_module);
-
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index f585bc8579e..743dc80a932 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -449,7 +449,8 @@ static void rp_do_transmit(struct r_port *info)
while (1) {
if (tty->stopped || tty->hw_stopped)
break;
- c = min(info->xmit_fifo_room, min(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
+ c = min(info->xmit_fifo_room, info->xmit_cnt);
+ c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
if (c <= 0 || info->xmit_fifo_room <= 0)
break;
sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
@@ -1433,29 +1434,38 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
{
struct r_port *info = (struct r_port *) tty->driver_data;
void __user *argp = (void __user *)arg;
+ int ret = 0;
if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
return -ENXIO;
+ lock_kernel();
+
switch (cmd) {
case RCKP_GET_STRUCT:
if (copy_to_user(argp, info, sizeof (struct r_port)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
case RCKP_GET_CONFIG:
- return get_config(info, argp);
+ ret = get_config(info, argp);
+ break;
case RCKP_SET_CONFIG:
- return set_config(info, argp);
+ ret = set_config(info, argp);
+ break;
case RCKP_GET_PORTS:
- return get_ports(info, argp);
+ ret = get_ports(info, argp);
+ break;
case RCKP_RESET_RM2:
- return reset_rm2(info, argp);
+ ret = reset_rm2(info, argp);
+ break;
case RCKP_GET_VERSION:
- return get_version(info, argp);
+ ret = get_version(info, argp);
+ break;
default:
- return -ENOIOCTLCMD;
+ ret = -ENOIOCTLCMD;
}
- return 0;
+ unlock_kernel();
+ return ret;
}
static void rp_send_xchar(struct tty_struct *tty, char ch)
@@ -1575,6 +1585,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
jiffies);
printk(KERN_INFO "cps=%d...\n", info->cps);
#endif
+ lock_kernel();
while (1) {
txcnt = sGetTxCnt(cp);
if (!txcnt) {
@@ -1602,6 +1613,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
__set_current_state(TASK_RUNNING);
+ unlock_kernel();
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
#endif
@@ -1651,14 +1663,14 @@ static void rp_hangup(struct tty_struct *tty)
* writing routines will write directly to transmit FIFO.
* Write buffer and counters protected by spinlocks
*/
-static void rp_put_char(struct tty_struct *tty, unsigned char ch)
+static int rp_put_char(struct tty_struct *tty, unsigned char ch)
{
struct r_port *info = (struct r_port *) tty->driver_data;
CHANNEL_t *cp;
unsigned long flags;
if (rocket_paranoia_check(info, "rp_put_char"))
- return;
+ return 0;
/*
* Grab the port write mutex, locking out other processes that try to
@@ -1687,6 +1699,7 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
}
spin_unlock_irqrestore(&info->slock, flags);
mutex_unlock(&info->write_mtx);
+ return 1;
}
/*
@@ -1749,10 +1762,10 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
- if (!info->tty) /* Seemingly obligatory check... */
+ if (!info->tty) /* Seemingly obligatory check... */
goto end;
-
- c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
+ c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
+ c = min(c, XMIT_BUF_SIZE - info->xmit_head);
if (c <= 0)
break;
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index df8cd0ca97e..fd2db07a50f 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1060,7 +1060,7 @@ static void config_setup(struct cyclades_port *info)
} /* config_setup */
-static void cy_put_char(struct tty_struct *tty, unsigned char ch)
+static int cy_put_char(struct tty_struct *tty, unsigned char ch)
{
struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
unsigned long flags;
@@ -1070,7 +1070,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
#endif
if (serial_paranoia_check(info, tty->name, "cy_put_char"))
- return;
+ return 0;
if (!info->xmit_buf)
return;
@@ -1078,13 +1078,14 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
local_irq_save(flags);
if (info->xmit_cnt >= PAGE_SIZE - 1) {
local_irq_restore(flags);
- return;
+ return 0;
}
info->xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= PAGE_SIZE - 1;
info->xmit_cnt++;
local_irq_restore(flags);
+ return 1;
} /* cy_put_char */
static void cy_flush_chars(struct tty_struct *tty)
@@ -1539,6 +1540,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
#endif
+ lock_kernel();
+
switch (cmd) {
case CYGETMON:
ret_val = get_mon_info(info, argp);
@@ -1584,18 +1587,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
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;
@@ -1605,6 +1596,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
default:
ret_val = -ENOIOCTLCMD;
}
+ unlock_kernel();
#ifdef SERIAL_DEBUG_OTHER
printk("cy_ioctl done\n");
@@ -1683,8 +1675,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
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);
+ cy_flush_buffer(tty);
tty_ldisc_flush(tty);
info->tty = NULL;
if (info->blocked_open) {
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index b9c1dba6bd0..8fe099a4106 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -80,7 +80,7 @@ scdrv_open(struct inode *inode, struct file *file)
sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
if (sd == NULL) {
printk("%s: couldn't allocate subchannel data\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
@@ -90,7 +90,7 @@ scdrv_open(struct inode *inode, struct file *file)
if (sd->sd_subch < 0) {
kfree(sd);
- printk("%s: couldn't allocate subchannel\n", __FUNCTION__);
+ printk("%s: couldn't allocate subchannel\n", __func__);
return -EBUSY;
}
@@ -110,7 +110,7 @@ scdrv_open(struct inode *inode, struct file *file)
if (rv) {
ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
kfree(sd);
- printk("%s: irq request failed (%d)\n", __FUNCTION__, rv);
+ printk("%s: irq request failed (%d)\n", __func__, rv);
return -EBUSY;
}
@@ -215,7 +215,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
*/
if (count < len) {
pr_debug("%s: only accepting %d of %d bytes\n",
- __FUNCTION__, (int) count, len);
+ __func__, (int) count, len);
}
len = min((int) count, len);
if (copy_to_user(buf, sd->sd_rb, len))
@@ -384,7 +384,7 @@ scdrv_init(void)
if (alloc_chrdev_region(&first_dev, 0, num_cnodes,
SYSCTL_BASENAME) < 0) {
printk("%s: failed to register SN system controller device\n",
- __FUNCTION__);
+ __func__);
return -ENODEV;
}
snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
@@ -403,7 +403,7 @@ scdrv_init(void)
GFP_KERNEL);
if (!scd) {
printk("%s: failed to allocate device info"
- "for %s/%s\n", __FUNCTION__,
+ "for %s/%s\n", __func__,
SYSCTL_BASENAME, devname);
continue;
}
@@ -412,7 +412,7 @@ scdrv_init(void)
scd->scd_nasid = cnodeid_to_nasid(cnode);
if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) {
printk("%s: failed to allocate driver buffer"
- "(%s%s)\n", __FUNCTION__,
+ "(%s%s)\n", __func__,
SYSCTL_BASENAME, devname);
kfree(scd);
continue;
@@ -424,7 +424,7 @@ scdrv_init(void)
("%s: failed to initialize SAL for"
" system controller communication"
" (%s/%s): outdated PROM?\n",
- __FUNCTION__, SYSCTL_BASENAME, devname);
+ __func__, SYSCTL_BASENAME, devname);
kfree(scd);
kfree(salbuf);
continue;
@@ -435,7 +435,7 @@ scdrv_init(void)
if (cdev_add(&scd->scd_cdev, dev, 1)) {
printk("%s: failed to register system"
" controller device (%s%s)\n",
- __FUNCTION__, SYSCTL_BASENAME, devname);
+ __func__, SYSCTL_BASENAME, devname);
kfree(scd);
kfree(salbuf);
continue;
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index 31a7765eaf7..53b3d44f8c0 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -271,7 +271,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
if (event_sd == NULL) {
printk(KERN_WARNING "%s: couldn't allocate subchannel info"
- " for event monitoring\n", __FUNCTION__);
+ " for event monitoring\n", __func__);
return;
}
@@ -285,7 +285,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
if (event_sd->sd_subch < 0) {
kfree(event_sd);
printk(KERN_WARNING "%s: couldn't open event subchannel\n",
- __FUNCTION__);
+ __func__);
return;
}
@@ -295,7 +295,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
"system controller events", event_sd);
if (rv) {
printk(KERN_WARNING "%s: irq request failed (%d)\n",
- __FUNCTION__, rv);
+ __func__, rv);
ia64_sn_irtr_close(event_sd->sd_nasid, event_sd->sd_subch);
kfree(event_sd);
return;
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index c03ad164c39..58533de5902 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -506,7 +506,7 @@ static struct sonypi_device {
while (--n && (command)) \
udelay(1); \
if (!n && (verbose || !quiet)) \
- printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \
+ printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \
}
#ifdef CONFIG_ACPI
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 4b5b5b78acb..2ee4d989375 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO;
#define SX_DEBUG_FIFO 0x0800
-#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
-#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
+#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__)
+#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
@@ -874,7 +874,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
spin_lock_irqsave(&bp->lock, flags);
- dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
+ dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
if (!(bp->flags & SX_BOARD_ACTIVE)) {
dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq);
spin_unlock_irqrestore(&bp->lock, flags);
@@ -1504,6 +1504,27 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
return 0;
}
+static void sx_flush_buffer(struct tty_struct *tty)
+{
+ struct specialix_port *port = (struct specialix_port *)tty->driver_data;
+ unsigned long flags;
+ struct specialix_board * bp;
+
+ func_enter();
+
+ if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
+ func_exit();
+ return;
+ }
+
+ bp = port_Board(port);
+ spin_lock_irqsave(&port->lock, flags);
+ port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+ spin_unlock_irqrestore(&port->lock, flags);
+ tty_wakeup(tty);
+
+ func_exit();
+}
static void sx_close(struct tty_struct * tty, struct file * filp)
{
@@ -1597,8 +1618,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
sx_shutdown_port(bp, port);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ sx_flush_buffer(tty);
tty_ldisc_flush(tty);
spin_lock_irqsave(&port->lock, flags);
tty->closing = 0;
@@ -1670,7 +1690,7 @@ static int sx_write(struct tty_struct * tty,
}
-static void sx_put_char(struct tty_struct * tty, unsigned char ch)
+static int sx_put_char(struct tty_struct * tty, unsigned char ch)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
unsigned long flags;
@@ -1680,12 +1700,12 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch)
if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
func_exit();
- return;
+ return 0;
}
dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
if (!port->xmit_buf) {
func_exit();
- return;
+ return 0;
}
bp = port_Board(port);
spin_lock_irqsave(&port->lock, flags);
@@ -1695,7 +1715,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch)
spin_unlock_irqrestore(&port->lock, flags);
dprintk (SX_DEBUG_TX, "Exit size\n");
func_exit();
- return;
+ return 0;
}
dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
port->xmit_buf[port->xmit_head++] = ch;
@@ -1704,6 +1724,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch)
spin_unlock_irqrestore(&port->lock, flags);
func_exit();
+ return 1;
}
@@ -1770,28 +1791,6 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
}
-static void sx_flush_buffer(struct tty_struct *tty)
-{
- struct specialix_port *port = (struct specialix_port *)tty->driver_data;
- unsigned long flags;
- struct specialix_board * bp;
-
- func_enter();
-
- if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
- func_exit();
- return;
- }
-
- bp = port_Board(port);
- spin_lock_irqsave(&port->lock, flags);
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- spin_unlock_irqrestore(&port->lock, flags);
- tty_wakeup(tty);
-
- func_exit();
-}
-
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
{
@@ -1803,7 +1802,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
func_enter();
- if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
+ if (sx_paranoia_check(port, tty->name, __func__)) {
func_exit();
return -ENODEV;
}
@@ -1845,7 +1844,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
func_enter();
- if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
+ if (sx_paranoia_check(port, tty->name, __func__)) {
func_exit();
return -ENODEV;
}
@@ -1922,29 +1921,13 @@ static inline int sx_set_serial_info(struct specialix_port * port,
int change_speed;
func_enter();
- /*
- if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
- func_exit();
- return -EFAULT;
- }
- */
+
if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
func_enter();
return -EFAULT;
}
-#if 0
- if ((tmp.irq != bp->irq) ||
- (tmp.port != bp->base) ||
- (tmp.type != PORT_CIRRUS) ||
- (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
- (tmp.custom_divisor != 0) ||
- (tmp.xmit_fifo_size != CD186x_NFIFO) ||
- (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
- func_exit();
- return -EINVAL;
- }
-#endif
+ lock_kernel();
change_speed = ((port->flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
@@ -1956,6 +1939,7 @@ static inline int sx_set_serial_info(struct specialix_port * port,
((tmp.flags & ~ASYNC_USR_MASK) !=
(port->flags & ~ASYNC_USR_MASK))) {
func_exit();
+ unlock_kernel();
return -EPERM;
}
port->flags = ((port->flags & ~ASYNC_USR_MASK) |
@@ -1972,6 +1956,7 @@ static inline int sx_set_serial_info(struct specialix_port * port,
sx_change_speed(bp, port);
}
func_exit();
+ unlock_kernel();
return 0;
}
@@ -1984,12 +1969,8 @@ static inline int sx_get_serial_info(struct specialix_port * port,
func_enter();
- /*
- if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
- return -EFAULT;
- */
-
memset(&tmp, 0, sizeof(tmp));
+ lock_kernel();
tmp.type = PORT_CIRRUS;
tmp.line = port - sx_port;
tmp.port = bp->base;
@@ -2000,6 +1981,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
tmp.closing_wait = port->closing_wait * HZ/100;
tmp.custom_divisor = port->custom_divisor;
tmp.xmit_fifo_size = CD186x_NFIFO;
+ unlock_kernel();
if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
func_exit();
return -EFAULT;
@@ -2045,23 +2027,6 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
func_exit();
return 0;
- case TIOCGSOFTCAR:
- if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
- func_exit();
- return -EFAULT;
- }
- func_exit();
- return 0;
- case TIOCSSOFTCAR:
- if (get_user(arg, (unsigned long __user *) argp)) {
- func_exit();
- return -EFAULT;
- }
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- func_exit();
- return 0;
case TIOCGSERIAL:
func_exit();
return sx_get_serial_info(port, argp);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 874aaa08e95..d17be10c5d2 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -875,6 +875,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
timeout = HZ;
tend = jiffies + timeout;
+ lock_kernel();
while (stl_datastate(portp)) {
if (signal_pending(current))
break;
@@ -882,6 +883,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
if (time_after_eq(jiffies, tend))
break;
}
+ unlock_kernel();
}
/*****************************************************************************/
@@ -1273,18 +1275,9 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
rc = 0;
+ lock_kernel();
+
switch (cmd) {
- case TIOCGSOFTCAR:
- rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
- (unsigned __user *) argp);
- break;
- case TIOCSSOFTCAR:
- if (get_user(ival, (unsigned int __user *) arg))
- return -EFAULT;
- tty->termios->c_cflag =
- (tty->termios->c_cflag & ~CLOCAL) |
- (ival ? CLOCAL : 0);
- break;
case TIOCGSERIAL:
rc = stl_getserial(portp, argp);
break;
@@ -1308,7 +1301,7 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
rc = -ENOIOCTLCMD;
break;
}
-
+ unlock_kernel();
return rc;
}
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index a6e1c9ba121..f39f6fd8935 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -384,11 +384,11 @@ static struct real_driver sx_real_driver = {
#define sx_dprintk(f, str...) /* nothing */
#endif
-#define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__)
-#define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__FUNCTION__)
+#define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__)
+#define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__)
#define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
- __FUNCTION__, port->line)
+ __func__, port->line)
/*
* Firmware loader driver specific routines
@@ -1574,7 +1574,7 @@ static void sx_close(void *ptr)
sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n",
port->gs.count);
/*printk("%s SETTING port count to zero: %p count: %d\n",
- __FUNCTION__, port, port->gs.count);
+ __func__, port, port->gs.count);
port->gs.count = 0;*/
}
@@ -1844,6 +1844,7 @@ static void sx_break(struct tty_struct *tty, int flag)
int rv;
func_enter();
+ lock_kernel();
if (flag)
rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK);
@@ -1852,7 +1853,7 @@ static void sx_break(struct tty_struct *tty, int flag)
if (rv != 1)
printk(KERN_ERR "sx: couldn't send break (%x).\n",
read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
-
+ unlock_kernel();
func_exit();
}
@@ -1888,23 +1889,12 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp,
int rc;
struct sx_port *port = tty->driver_data;
void __user *argp = (void __user *)arg;
- int ival;
/* func_enter2(); */
rc = 0;
+ lock_kernel();
switch (cmd) {
- case TIOCGSOFTCAR:
- rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
- (unsigned __user *)argp);
- break;
- case TIOCSSOFTCAR:
- if ((rc = get_user(ival, (unsigned __user *)argp)) == 0) {
- tty->termios->c_cflag =
- (tty->termios->c_cflag & ~CLOCAL) |
- (ival ? CLOCAL : 0);
- }
- break;
case TIOCGSERIAL:
rc = gs_getserial(&port->gs, argp);
break;
@@ -1915,6 +1905,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp,
rc = -ENOIOCTLCMD;
break;
}
+ unlock_kernel();
/* func_exit(); */
return rc;
@@ -2549,7 +2540,7 @@ static int __devinit sx_eisa_probe(struct device *dev)
goto err_flag;
}
board->base2 =
- board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
+ board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN);
if (!board->base) {
dev_err(dev, "can't remap memory\n");
goto err_reg;
@@ -2626,7 +2617,7 @@ static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board)
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
- rebase = ioremap(hwbase, 0x80);
+ rebase = ioremap_nocache(hwbase, 0x80);
t = readl(rebase + CNTRL_REG_OFFSET);
if (t != CNTRL_REG_GOODVALUE) {
printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> "
@@ -2770,7 +2761,7 @@ static int __init sx_init(void)
if (!request_region(board->hw_base, board->hw_len, "sx"))
continue;
board->base2 =
- board->base = ioremap(board->hw_base, board->hw_len);
+ board->base = ioremap_nocache(board->hw_base, board->hw_len);
if (!board->base)
goto err_sx_reg;
board->flags &= ~SX_BOARD_TYPE;
@@ -2794,7 +2785,7 @@ err_sx_reg:
if (!request_region(board->hw_base, board->hw_len, "sx"))
continue;
board->base2 =
- board->base = ioremap(board->hw_base, board->hw_len);
+ board->base = ioremap_nocache(board->hw_base, board->hw_len);
if (!board->base)
goto err_si_reg;
board->flags &= ~SX_BOARD_TYPE;
@@ -2817,7 +2808,7 @@ err_si_reg:
if (!request_region(board->hw_base, board->hw_len, "sx"))
continue;
board->base2 =
- board->base = ioremap(board->hw_base, board->hw_len);
+ board->base = ioremap_nocache(board->hw_base, board->hw_len);
if (!board->base)
goto err_si1_reg;
board->flags &= ~SX_BOARD_TYPE;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index fadab1d9510..513b7c2f3e2 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -2026,10 +2026,11 @@ static void mgsl_change_params(struct mgsl_struct *info)
*
* Return Value: None
*/
-static void mgsl_put_char(struct tty_struct *tty, unsigned char ch)
+static int mgsl_put_char(struct tty_struct *tty, unsigned char ch)
{
struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;
unsigned long flags;
+ int ret;
if ( debug_level >= DEBUG_LEVEL_INFO ) {
printk( "%s(%d):mgsl_put_char(%d) on %s\n",
@@ -2037,23 +2038,23 @@ static void mgsl_put_char(struct tty_struct *tty, unsigned char ch)
}
if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char"))
- return;
+ return 0;
if (!tty || !info->xmit_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->irq_spinlock,flags);
if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) {
-
if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) {
info->xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= SERIAL_XMIT_SIZE-1;
info->xmit_cnt++;
+ ret = 1;
}
}
-
spin_unlock_irqrestore(&info->irq_spinlock,flags);
+ return ret;
} /* end of mgsl_put_char() */
@@ -2942,6 +2943,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
+ int ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__,
@@ -2956,7 +2958,10 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
return -EIO;
}
- return mgsl_ioctl_common(info, cmd, arg);
+ lock_kernel();
+ ret = mgsl_ioctl_common(info, cmd, arg);
+ unlock_kernel();
+ return ret;
}
static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
@@ -3153,8 +3158,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
if (info->flags & ASYNC_INITIALIZED)
mgsl_wait_until_sent(tty, info->timeout);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ mgsl_flush_buffer(tty);
tty_ldisc_flush(tty);
@@ -3217,7 +3221,8 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
* interval should also be less than the timeout.
* Note: use tight timings here to satisfy the NIST-PCTS.
*/
-
+
+ lock_kernel();
if ( info->params.data_rate ) {
char_time = info->timeout/(32 * 5);
if (!char_time)
@@ -3247,6 +3252,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
}
+ unlock_kernel();
exit:
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -4144,7 +4150,8 @@ static int mgsl_claim_resources(struct mgsl_struct *info)
}
info->lcr_mem_requested = true;
- info->memory_base = ioremap(info->phys_memory_base,0x40000);
+ info->memory_base = ioremap_nocache(info->phys_memory_base,
+ 0x40000);
if (!info->memory_base) {
printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
@@ -4157,12 +4164,14 @@ static int mgsl_claim_resources(struct mgsl_struct *info)
goto errout;
}
- info->lcr_base = ioremap(info->phys_lcr_base,PAGE_SIZE) + info->lcr_offset;
+ info->lcr_base = ioremap_nocache(info->phys_lcr_base,
+ PAGE_SIZE);
if (!info->lcr_base) {
printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
goto errout;
}
+ info->lcr_base += info->lcr_offset;
} else {
/* claim DMA channel */
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index f3d8d72e5ea..2001b0e52dc 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -151,7 +151,7 @@ static void hangup(struct tty_struct *tty);
static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);
static int write(struct tty_struct *tty, const unsigned char *buf, int count);
-static void put_char(struct tty_struct *tty, unsigned char ch);
+static int put_char(struct tty_struct *tty, unsigned char ch);
static void send_xchar(struct tty_struct *tty, char ch);
static void wait_until_sent(struct tty_struct *tty, int timeout);
static int write_room(struct tty_struct *tty);
@@ -771,8 +771,7 @@ static void close(struct tty_struct *tty, struct file *filp)
if (info->flags & ASYNC_INITIALIZED)
wait_until_sent(tty, info->timeout);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(info);
@@ -913,20 +912,24 @@ cleanup:
return ret;
}
-static void put_char(struct tty_struct *tty, unsigned char ch)
+static int put_char(struct tty_struct *tty, unsigned char ch)
{
struct slgt_info *info = tty->driver_data;
unsigned long flags;
+ int ret;
if (sanity_check(info, tty->name, "put_char"))
- return;
+ return 0;
DBGINFO(("%s put_char(%d)\n", info->device_name, ch));
if (!info->tx_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->lock,flags);
- if (!info->tx_active && (info->tx_count < info->max_frame_size))
+ if (!info->tx_active && (info->tx_count < info->max_frame_size)) {
info->tx_buf[info->tx_count++] = ch;
+ ret = 1;
+ }
spin_unlock_irqrestore(&info->lock,flags);
+ return ret;
}
static void send_xchar(struct tty_struct *tty, char ch)
@@ -967,6 +970,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
* Note: use tight timings here to satisfy the NIST-PCTS.
*/
+ lock_kernel();
+
if (info->params.data_rate) {
char_time = info->timeout/(32 * 5);
if (!char_time)
@@ -984,6 +989,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
+ unlock_kernel();
exit:
DBGINFO(("%s wait_until_sent exit\n", info->device_name));
@@ -1097,6 +1103,7 @@ static int ioctl(struct tty_struct *tty, struct file *file,
struct serial_icounter_struct __user *p_cuser; /* user space */
unsigned long flags;
void __user *argp = (void __user *)arg;
+ int ret;
if (sanity_check(info, tty->name, "ioctl"))
return -ENODEV;
@@ -1108,37 +1115,54 @@ static int ioctl(struct tty_struct *tty, struct file *file,
return -EIO;
}
+ lock_kernel();
+
switch (cmd) {
case MGSL_IOCGPARAMS:
- return get_params(info, argp);
+ ret = get_params(info, argp);
+ break;
case MGSL_IOCSPARAMS:
- return set_params(info, argp);
+ ret = set_params(info, argp);
+ break;
case MGSL_IOCGTXIDLE:
- return get_txidle(info, argp);
+ ret = get_txidle(info, argp);
+ break;
case MGSL_IOCSTXIDLE:
- return set_txidle(info, (int)arg);
+ ret = set_txidle(info, (int)arg);
+ break;
case MGSL_IOCTXENABLE:
- return tx_enable(info, (int)arg);
+ ret = tx_enable(info, (int)arg);
+ break;
case MGSL_IOCRXENABLE:
- return rx_enable(info, (int)arg);
+ ret = rx_enable(info, (int)arg);
+ break;
case MGSL_IOCTXABORT:
- return tx_abort(info);
+ ret = tx_abort(info);
+ break;
case MGSL_IOCGSTATS:
- return get_stats(info, argp);
+ ret = get_stats(info, argp);
+ break;
case MGSL_IOCWAITEVENT:
- return wait_mgsl_event(info, argp);
+ ret = wait_mgsl_event(info, argp);
+ break;
case TIOCMIWAIT:
- return modem_input_wait(info,(int)arg);
+ ret = modem_input_wait(info,(int)arg);
+ break;
case MGSL_IOCGIF:
- return get_interface(info, argp);
+ ret = get_interface(info, argp);
+ break;
case MGSL_IOCSIF:
- return set_interface(info,(int)arg);
+ ret = set_interface(info,(int)arg);
+ break;
case MGSL_IOCSGPIO:
- return set_gpio(info, argp);
+ ret = set_gpio(info, argp);
+ break;
case MGSL_IOCGGPIO:
- return get_gpio(info, argp);
+ ret = get_gpio(info, argp);
+ break;
case MGSL_IOCWAITGPIO:
- return wait_gpio(info, argp);
+ ret = wait_gpio(info, argp);
+ break;
case TIOCGICOUNT:
spin_lock_irqsave(&info->lock,flags);
cnow = info->icount;
@@ -1155,12 +1179,14 @@ static int ioctl(struct tty_struct *tty, struct file *file,
put_user(cnow.parity, &p_cuser->parity) ||
put_user(cnow.brk, &p_cuser->brk) ||
put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ ret = 0;
+ break;
default:
- return -ENOIOCTLCMD;
+ ret = -ENOIOCTLCMD;
}
- return 0;
+ unlock_kernel();
+ return ret;
}
/*
@@ -3324,7 +3350,7 @@ static int claim_resources(struct slgt_info *info)
else
info->reg_addr_requested = true;
- info->reg_addr = ioremap(info->phys_reg_addr, SLGT_REG_SIZE);
+ info->reg_addr = ioremap_nocache(info->phys_reg_addr, SLGT_REG_SIZE);
if (!info->reg_addr) {
DBGERR(("%s cant map device registers, addr=%08X\n",
info->device_name, info->phys_reg_addr));
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index e98c3e6f821..bec54866e0b 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -519,7 +519,7 @@ static void hangup(struct tty_struct *tty);
static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);
static int write(struct tty_struct *tty, const unsigned char *buf, int count);
-static void put_char(struct tty_struct *tty, unsigned char ch);
+static int put_char(struct tty_struct *tty, unsigned char ch);
static void send_xchar(struct tty_struct *tty, char ch);
static void wait_until_sent(struct tty_struct *tty, int timeout);
static int write_room(struct tty_struct *tty);
@@ -862,8 +862,7 @@ static void close(struct tty_struct *tty, struct file *filp)
if (info->flags & ASYNC_INITIALIZED)
wait_until_sent(tty, info->timeout);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ flush_buffer(tty);
tty_ldisc_flush(tty);
@@ -1046,10 +1045,11 @@ cleanup:
/* Add a character to the transmit buffer.
*/
-static void put_char(struct tty_struct *tty, unsigned char ch)
+static int put_char(struct tty_struct *tty, unsigned char ch)
{
SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
unsigned long flags;
+ int ret = 0;
if ( debug_level >= DEBUG_LEVEL_INFO ) {
printk( "%s(%d):%s put_char(%d)\n",
@@ -1057,10 +1057,10 @@ static void put_char(struct tty_struct *tty, unsigned char ch)
}
if (sanity_check(info, tty->name, "put_char"))
- return;
+ return 0;
if (!info->tx_buf)
- return;
+ return 0;
spin_lock_irqsave(&info->lock,flags);
@@ -1072,10 +1072,12 @@ static void put_char(struct tty_struct *tty, unsigned char ch)
if (info->tx_put >= info->max_frame_size)
info->tx_put -= info->max_frame_size;
info->tx_count++;
+ ret = 1;
}
}
spin_unlock_irqrestore(&info->lock,flags);
+ return ret;
}
/* Send a high-priority XON/XOFF character
@@ -1119,6 +1121,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
if (sanity_check(info, tty->name, "wait_until_sent"))
return;
+ lock_kernel();
+
if (!(info->flags & ASYNC_INITIALIZED))
goto exit;
@@ -1161,6 +1165,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
}
exit:
+ unlock_kernel();
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s wait_until_sent() exit\n",
__FILE__,__LINE__, info->device_name );
@@ -1176,6 +1181,7 @@ static int write_room(struct tty_struct *tty)
if (sanity_check(info, tty->name, "write_room"))
return 0;
+ lock_kernel();
if (info->params.mode == MGSL_MODE_HDLC) {
ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
} else {
@@ -1183,6 +1189,7 @@ static int write_room(struct tty_struct *tty)
if (ret < 0)
ret = 0;
}
+ unlock_kernel();
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s write_room()=%d\n",
@@ -1303,7 +1310,7 @@ static void tx_release(struct tty_struct *tty)
*
* Return Value: 0 if success, otherwise error code
*/
-static int ioctl(struct tty_struct *tty, struct file *file,
+static int do_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
@@ -1393,6 +1400,16 @@ static int ioctl(struct tty_struct *tty, struct file *file,
return 0;
}
+static int ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret;
+ lock_kernel();
+ ret = do_ioctl(tty, file, cmd, arg);
+ unlock_kernel();
+ return ret;
+}
+
/*
* /proc fs routines....
*/
@@ -3626,7 +3643,8 @@ static int claim_resources(SLMP_INFO *info)
else
info->sca_statctrl_requested = true;
- info->memory_base = ioremap(info->phys_memory_base,SCA_MEM_SIZE);
+ info->memory_base = ioremap_nocache(info->phys_memory_base,
+ SCA_MEM_SIZE);
if (!info->memory_base) {
printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
@@ -3634,7 +3652,7 @@ static int claim_resources(SLMP_INFO *info)
goto errout;
}
- info->lcr_base = ioremap(info->phys_lcr_base,PAGE_SIZE);
+ info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE);
if (!info->lcr_base) {
printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
@@ -3643,7 +3661,7 @@ static int claim_resources(SLMP_INFO *info)
}
info->lcr_base += info->lcr_offset;
- info->sca_base = ioremap(info->phys_sca_base,PAGE_SIZE);
+ info->sca_base = ioremap_nocache(info->phys_sca_base, PAGE_SIZE);
if (!info->sca_base) {
printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_sca_base );
@@ -3652,7 +3670,8 @@ static int claim_resources(SLMP_INFO *info)
}
info->sca_base += info->sca_offset;
- info->statctrl_base = ioremap(info->phys_statctrl_base,PAGE_SIZE);
+ info->statctrl_base = ioremap_nocache(info->phys_statctrl_base,
+ PAGE_SIZE);
if (!info->statctrl_base) {
printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_statctrl_base );
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 2fa6856706a..1d298c2cf93 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -91,7 +91,6 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
-#include <linux/idr.h>
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/delay.h>
@@ -137,9 +136,6 @@ EXPORT_SYMBOL(tty_mutex);
#ifdef CONFIG_UNIX98_PTYS
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
-extern int pty_limit; /* Config limit on Unix98 ptys */
-static DEFINE_IDR(allocated_ptys);
-static DEFINE_MUTEX(allocated_ptys_lock);
static int ptmx_open(struct inode *, struct file *);
#endif
@@ -152,8 +148,7 @@ ssize_t redirected_tty_write(struct file *, const char __user *,
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
static int tty_release(struct inode *, struct file *);
-int tty_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
+long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
@@ -1109,8 +1104,8 @@ restart:
a reference to the old ldisc. If we ended up flipping back
to the existing ldisc we have two references to it */
- if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc)
- tty->driver->set_ldisc(tty);
+ if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc)
+ tty->ops->set_ldisc(tty);
tty_ldisc_put(o_ldisc.num);
@@ -1182,9 +1177,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
if (*str == '\0')
str = NULL;
- if (tty_line >= 0 && tty_line <= p->num && p->poll_init &&
- !p->poll_init(p, tty_line, str)) {
-
+ if (tty_line >= 0 && tty_line <= p->num && p->ops &&
+ p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
res = p;
*line = tty_line;
break;
@@ -1205,26 +1199,37 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver);
* not in the foreground, send a SIGTTOU. If the signal is blocked or
* ignored, go ahead and perform the operation. (POSIX 7.2)
*
- * Locking: none
+ * Locking: ctrl_lock
*/
int tty_check_change(struct tty_struct *tty)
{
+ unsigned long flags;
+ int ret = 0;
+
if (current->signal->tty != tty)
return 0;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+
if (!tty->pgrp) {
printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
- return 0;
+ goto out;
}
if (task_pgrp(current) == tty->pgrp)
- return 0;
+ goto out;
if (is_ignored(SIGTTOU))
- return 0;
- if (is_current_pgrp_orphaned())
- return -EIO;
+ goto out;
+ if (is_current_pgrp_orphaned()) {
+ ret = -EIO;
+ goto out;
+ }
kill_pgrp(task_pgrp(current), SIGTTOU, 1);
set_thread_flag(TIF_SIGPENDING);
- return -ERESTARTSYS;
+ ret = -ERESTARTSYS;
+out:
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ return ret;
}
EXPORT_SYMBOL(tty_check_change);
@@ -1247,8 +1252,8 @@ static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
}
-static int hung_up_tty_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
}
@@ -1264,7 +1269,7 @@ static const struct file_operations tty_fops = {
.read = tty_read,
.write = tty_write,
.poll = tty_poll,
- .ioctl = tty_ioctl,
+ .unlocked_ioctl = tty_ioctl,
.compat_ioctl = tty_compat_ioctl,
.open = tty_open,
.release = tty_release,
@@ -1277,7 +1282,7 @@ static const struct file_operations ptmx_fops = {
.read = tty_read,
.write = tty_write,
.poll = tty_poll,
- .ioctl = tty_ioctl,
+ .unlocked_ioctl = tty_ioctl,
.compat_ioctl = tty_compat_ioctl,
.open = ptmx_open,
.release = tty_release,
@@ -1290,7 +1295,7 @@ static const struct file_operations console_fops = {
.read = tty_read,
.write = redirected_tty_write,
.poll = tty_poll,
- .ioctl = tty_ioctl,
+ .unlocked_ioctl = tty_ioctl,
.compat_ioctl = tty_compat_ioctl,
.open = tty_open,
.release = tty_release,
@@ -1302,7 +1307,7 @@ static const struct file_operations hung_up_tty_fops = {
.read = hung_up_tty_read,
.write = hung_up_tty_write,
.poll = hung_up_tty_poll,
- .ioctl = hung_up_tty_ioctl,
+ .unlocked_ioctl = hung_up_tty_ioctl,
.compat_ioctl = hung_up_tty_compat_ioctl,
.release = tty_release,
};
@@ -1404,6 +1409,7 @@ static void do_tty_hangup(struct work_struct *work)
struct task_struct *p;
struct tty_ldisc *ld;
int closecount = 0, n;
+ unsigned long flags;
if (!tty)
return;
@@ -1441,8 +1447,7 @@ static void do_tty_hangup(struct work_struct *work)
/* We may have no line discipline at this point */
if (ld->flush_buffer)
ld->flush_buffer(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
ld->write_wakeup)
ld->write_wakeup(tty);
@@ -1480,19 +1485,24 @@ static void do_tty_hangup(struct work_struct *work)
__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
put_pid(p->signal->tty_old_pgrp); /* A noop */
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
if (tty->pgrp)
p->signal->tty_old_pgrp = get_pid(tty->pgrp);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_unlock_irq(&p->sighand->siglock);
} while_each_pid_task(tty->session, PIDTYPE_SID, p);
}
read_unlock(&tasklist_lock);
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->flags = 0;
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
tty->ctrl_status = 0;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
/*
* If one of the devices matches a console pointer, we
* cannot just call hangup() because that will cause
@@ -1500,11 +1510,11 @@ static void do_tty_hangup(struct work_struct *work)
* So we just call close() the right number of times.
*/
if (cons_filp) {
- if (tty->driver->close)
+ if (tty->ops->close)
for (n = 0; n < closecount; n++)
- tty->driver->close(tty, cons_filp);
- } else if (tty->driver->hangup)
- (tty->driver->hangup)(tty);
+ tty->ops->close(tty, cons_filp);
+ } else if (tty->ops->hangup)
+ (tty->ops->hangup)(tty);
/*
* We don't want to have driver/ldisc interactions beyond
* the ones we did here. The driver layer expects no
@@ -1626,16 +1636,17 @@ void disassociate_ctty(int on_exit)
struct tty_struct *tty;
struct pid *tty_pgrp = NULL;
- lock_kernel();
mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex);
+ lock_kernel();
/* XXX: here we race, there is nothing protecting tty */
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
+ unlock_kernel();
} else if (on_exit) {
struct pid *old_pgrp;
spin_lock_irq(&current->sighand->siglock);
@@ -1648,7 +1659,6 @@ void disassociate_ctty(int on_exit)
put_pid(old_pgrp);
}
mutex_unlock(&tty_mutex);
- unlock_kernel();
return;
}
if (tty_pgrp) {
@@ -1667,10 +1677,13 @@ void disassociate_ctty(int on_exit)
/* It is possible that do_tty_hangup has free'd this tty */
tty = get_current_tty();
if (tty) {
+ unsigned long flags;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
} else {
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
@@ -1683,7 +1696,6 @@ void disassociate_ctty(int on_exit)
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
read_unlock(&tasklist_lock);
- unlock_kernel();
}
/**
@@ -1693,8 +1705,10 @@ void disassociate_ctty(int on_exit)
void no_tty(void)
{
struct task_struct *tsk = current;
+ lock_kernel();
if (tsk->signal->leader)
disassociate_ctty(0);
+ unlock_kernel();
proc_clear_tty(tsk);
}
@@ -1714,21 +1728,26 @@ void no_tty(void)
* but not always.
*
* Locking:
- * Broken. Relies on BKL which is unsafe here.
+ * Uses the tty control lock internally
*/
void stop_tty(struct tty_struct *tty)
{
- if (tty->stopped)
+ unsigned long flags;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ if (tty->stopped) {
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
return;
+ }
tty->stopped = 1;
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_START;
tty->ctrl_status |= TIOCPKT_STOP;
wake_up_interruptible(&tty->link->read_wait);
}
- if (tty->driver->stop)
- (tty->driver->stop)(tty);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ if (tty->ops->stop)
+ (tty->ops->stop)(tty);
}
EXPORT_SYMBOL(stop_tty);
@@ -1743,21 +1762,26 @@ EXPORT_SYMBOL(stop_tty);
* driver start method is invoked and the line discipline woken.
*
* Locking:
- * Broken. Relies on BKL which is unsafe here.
+ * ctrl_lock
*/
void start_tty(struct tty_struct *tty)
{
- if (!tty->stopped || tty->flow_stopped)
+ unsigned long flags;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ if (!tty->stopped || tty->flow_stopped) {
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
return;
+ }
tty->stopped = 0;
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_STOP;
tty->ctrl_status |= TIOCPKT_START;
wake_up_interruptible(&tty->link->read_wait);
}
- if (tty->driver->start)
- (tty->driver->start)(tty);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ if (tty->ops->start)
+ (tty->ops->start)(tty);
/* If we have a running line discipline it may need kicking */
tty_wakeup(tty);
}
@@ -1775,10 +1799,8 @@ EXPORT_SYMBOL(start_tty);
* for hung up devices before calling the line discipline method.
*
* Locking:
- * Locks the line discipline internally while needed
- * For historical reasons the line discipline read method is
- * invoked under the BKL. This will go away in time so do not rely on it
- * in new code. Multiple read calls may be outstanding in parallel.
+ * Locks the line discipline internally while needed. Multiple
+ * read calls may be outstanding in parallel.
*/
static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
@@ -1799,13 +1821,11 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
/* We want to wait for the line discipline to sort out in this
situation */
ld = tty_ldisc_ref_wait(tty);
- lock_kernel();
if (ld->read)
i = (ld->read)(tty, file, buf, count);
else
i = -EIO;
tty_ldisc_deref(ld);
- unlock_kernel();
if (i > 0)
inode->i_atime = current_fs_time(inode->i_sb);
return i;
@@ -1893,9 +1913,7 @@ static inline ssize_t do_tty_write(
ret = -EFAULT;
if (copy_from_user(tty->write_buf, buf, size))
break;
- lock_kernel();
ret = write(tty, file, tty->write_buf, size);
- unlock_kernel();
if (ret <= 0)
break;
written += ret;
@@ -1948,10 +1966,13 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
tty = (struct tty_struct *)file->private_data;
if (tty_paranoia_check(tty, inode, "tty_write"))
return -EIO;
- if (!tty || !tty->driver->write ||
+ if (!tty || !tty->ops->write ||
(test_bit(TTY_IO_ERROR, &tty->flags)))
return -EIO;
-
+ /* Short term debug to catch buggy drivers */
+ if (tty->ops->write_room == NULL)
+ printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
+ tty->driver->name);
ld = tty_ldisc_ref_wait(tty);
if (!ld->write)
ret = -EIO;
@@ -2098,6 +2119,7 @@ static int init_dev(struct tty_driver *driver, int idx,
goto fail_no_mem;
initialize_tty_struct(tty);
tty->driver = driver;
+ tty->ops = driver->ops;
tty->index = idx;
tty_line_name(driver, idx, tty->name);
@@ -2128,6 +2150,7 @@ static int init_dev(struct tty_driver *driver, int idx,
goto free_mem_out;
initialize_tty_struct(o_tty);
o_tty->driver = driver->other;
+ o_tty->ops = driver->ops;
o_tty->index = idx;
tty_line_name(driver->other, idx, o_tty->name);
@@ -2432,8 +2455,8 @@ static void release_dev(struct file *filp)
}
}
#endif
- if (tty->driver->close)
- tty->driver->close(tty, filp);
+ if (tty->ops->close)
+ tty->ops->close(tty, filp);
/*
* Sanity check: if tty->count is going to zero, there shouldn't be
@@ -2612,15 +2635,9 @@ static void release_dev(struct file *filp)
*/
release_tty(tty, idx);
-#ifdef CONFIG_UNIX98_PTYS
/* Make this pty number available for reallocation */
- if (devpts) {
- mutex_lock(&allocated_ptys_lock);
- idr_remove(&allocated_ptys, idx);
- mutex_unlock(&allocated_ptys_lock);
- }
-#endif
-
+ if (devpts)
+ devpts_kill_index(idx);
}
/**
@@ -2716,8 +2733,8 @@ got_driver:
printk(KERN_DEBUG "opening %s...", tty->name);
#endif
if (!retval) {
- if (tty->driver->open)
- retval = tty->driver->open(tty, filp);
+ if (tty->ops->open)
+ retval = tty->ops->open(tty, filp);
else
retval = -ENODEV;
}
@@ -2776,29 +2793,13 @@ static int ptmx_open(struct inode *inode, struct file *filp)
struct tty_struct *tty;
int retval;
int index;
- int idr_ret;
nonseekable_open(inode, filp);
/* find a device that is not in use. */
- mutex_lock(&allocated_ptys_lock);
- if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) {
- mutex_unlock(&allocated_ptys_lock);
- return -ENOMEM;
- }
- idr_ret = idr_get_new(&allocated_ptys, NULL, &index);
- if (idr_ret < 0) {
- mutex_unlock(&allocated_ptys_lock);
- if (idr_ret == -EAGAIN)
- return -ENOMEM;
- return -EIO;
- }
- if (index >= pty_limit) {
- idr_remove(&allocated_ptys, index);
- mutex_unlock(&allocated_ptys_lock);
- return -EIO;
- }
- mutex_unlock(&allocated_ptys_lock);
+ index = devpts_new_index();
+ if (index < 0)
+ return index;
mutex_lock(&tty_mutex);
retval = init_dev(ptm_driver, index, &tty);
@@ -2811,21 +2812,19 @@ static int ptmx_open(struct inode *inode, struct file *filp)
filp->private_data = tty;
file_move(filp, &tty->tty_files);
- retval = -ENOMEM;
- if (devpts_pty_new(tty->link))
+ retval = devpts_pty_new(tty->link);
+ if (retval)
goto out1;
- check_tty_count(tty, "tty_open");
- retval = ptm_driver->open(tty, filp);
+ check_tty_count(tty, "ptmx_open");
+ retval = ptm_driver->ops->open(tty, filp);
if (!retval)
return 0;
out1:
release_dev(filp);
return retval;
out:
- mutex_lock(&allocated_ptys_lock);
- idr_remove(&allocated_ptys, index);
- mutex_unlock(&allocated_ptys_lock);
+ devpts_kill_index(index);
return retval;
}
#endif
@@ -2882,6 +2881,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
static int tty_fasync(int fd, struct file *filp, int on)
{
struct tty_struct *tty;
+ unsigned long flags;
int retval;
tty = (struct tty_struct *)filp->private_data;
@@ -2897,6 +2897,7 @@ static int tty_fasync(int fd, struct file *filp, int on)
struct pid *pid;
if (!waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = 1;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
if (tty->pgrp) {
pid = tty->pgrp;
type = PIDTYPE_PGID;
@@ -2904,6 +2905,7 @@ static int tty_fasync(int fd, struct file *filp, int on)
pid = task_pid(current);
type = PIDTYPE_PID;
}
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
retval = __f_setown(filp, pid, type, 0);
if (retval)
return retval;
@@ -2989,6 +2991,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
struct winsize __user *arg)
{
struct winsize tmp_ws;
+ struct pid *pgrp, *rpgrp;
+ unsigned long flags;
if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
return -EFAULT;
@@ -3006,10 +3010,21 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
}
}
#endif
- if (tty->pgrp)
- kill_pgrp(tty->pgrp, SIGWINCH, 1);
- if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
- kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
+ /* Get the PID values and reference them so we can
+ avoid holding the tty ctrl lock while sending signals */
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ pgrp = get_pid(tty->pgrp);
+ rpgrp = get_pid(real_tty->pgrp);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+ if (pgrp)
+ kill_pgrp(pgrp, SIGWINCH, 1);
+ if (rpgrp != pgrp && rpgrp)
+ kill_pgrp(rpgrp, SIGWINCH, 1);
+
+ put_pid(pgrp);
+ put_pid(rpgrp);
+
tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws;
done:
@@ -3070,10 +3085,13 @@ static int fionbio(struct file *file, int __user *p)
if (get_user(nonblock, p))
return -EFAULT;
+ /* file->f_flags is still BKL protected in the fs layer - vomit */
+ lock_kernel();
if (nonblock)
file->f_flags |= O_NONBLOCK;
else
file->f_flags &= ~O_NONBLOCK;
+ unlock_kernel();
return 0;
}
@@ -3131,6 +3149,27 @@ unlock:
}
/**
+ * tty_get_pgrp - return a ref counted pgrp pid
+ * @tty: tty to read
+ *
+ * Returns a refcounted instance of the pid struct for the process
+ * group controlling the tty.
+ */
+
+struct pid *tty_get_pgrp(struct tty_struct *tty)
+{
+ unsigned long flags;
+ struct pid *pgrp;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ pgrp = get_pid(tty->pgrp);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+ return pgrp;
+}
+EXPORT_SYMBOL_GPL(tty_get_pgrp);
+
+/**
* tiocgpgrp - get process group
* @tty: tty passed by user
* @real_tty: tty side of the tty pased by the user if a pty else the tty
@@ -3144,13 +3183,18 @@ unlock:
static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ struct pid *pid;
+ int ret;
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(pid_vnr(real_tty->pgrp), p);
+ pid = tty_get_pgrp(real_tty);
+ ret = put_user(pid_vnr(pid), p);
+ put_pid(pid);
+ return ret;
}
/**
@@ -3162,7 +3206,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
* Set the process group of the tty to the session passed. Only
* permitted where the tty session is our session.
*
- * Locking: None
+ * Locking: RCU, ctrl lock
*/
static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -3170,6 +3214,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
struct pid *pgrp;
pid_t pgrp_nr;
int retval = tty_check_change(real_tty);
+ unsigned long flags;
if (retval == -EIO)
return -ENOTTY;
@@ -3192,8 +3237,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
out_unlock:
rcu_read_unlock();
return retval;
@@ -3237,10 +3284,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
static int tiocsetd(struct tty_struct *tty, int __user *p)
{
int ldisc;
+ int ret;
if (get_user(ldisc, p))
return -EFAULT;
- return tty_set_ldisc(tty, ldisc);
+
+ lock_kernel();
+ ret = tty_set_ldisc(tty, ldisc);
+ unlock_kernel();
+
+ return ret;
}
/**
@@ -3260,18 +3313,18 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
{
if (tty_write_lock(tty, 0) < 0)
return -EINTR;
- tty->driver->break_ctl(tty, -1);
+ tty->ops->break_ctl(tty, -1);
if (!signal_pending(current))
msleep_interruptible(duration);
- tty->driver->break_ctl(tty, 0);
+ tty->ops->break_ctl(tty, 0);
tty_write_unlock(tty);
- if (signal_pending(current))
+ if (!signal_pending(current))
return -EINTR;
return 0;
}
/**
- * tiocmget - get modem status
+ * tty_tiocmget - get modem status
* @tty: tty device
* @file: user file pointer
* @p: pointer to result
@@ -3286,8 +3339,8 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
{
int retval = -EINVAL;
- if (tty->driver->tiocmget) {
- retval = tty->driver->tiocmget(tty, file);
+ if (tty->ops->tiocmget) {
+ retval = tty->ops->tiocmget(tty, file);
if (retval >= 0)
retval = put_user(retval, p);
@@ -3296,7 +3349,7 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
}
/**
- * tiocmset - set modem status
+ * tty_tiocmset - set modem status
* @tty: tty device
* @file: user file pointer
* @cmd: command - clear bits, set bits or set all
@@ -3313,7 +3366,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
{
int retval = -EINVAL;
- if (tty->driver->tiocmset) {
+ if (tty->ops->tiocmset) {
unsigned int set, clear, val;
retval = get_user(val, p);
@@ -3337,7 +3390,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
- retval = tty->driver->tiocmset(tty, file, set, clear);
+ retval = tty->ops->tiocmset(tty, file, set, clear);
}
return retval;
}
@@ -3345,20 +3398,18 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
/*
* Split this up, as gcc can choke on it otherwise..
*/
-int tty_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct tty_struct *tty, *real_tty;
void __user *p = (void __user *)arg;
int retval;
struct tty_ldisc *ld;
+ struct inode *inode = file->f_dentry->d_inode;
tty = (struct tty_struct *)file->private_data;
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
return -EINVAL;
- /* CHECKME: is this safe as one end closes ? */
-
real_tty = tty;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER)
@@ -3367,21 +3418,28 @@ int tty_ioctl(struct inode *inode, struct file *file,
/*
* Break handling by driver
*/
- if (!tty->driver->break_ctl) {
+
+ retval = -EINVAL;
+
+ if (!tty->ops->break_ctl) {
switch (cmd) {
case TIOCSBRK:
case TIOCCBRK:
- if (tty->driver->ioctl)
- return tty->driver->ioctl(tty, file, cmd, arg);
- return -EINVAL;
+ if (tty->ops->ioctl)
+ retval = tty->ops->ioctl(tty, file, cmd, arg);
+ if (retval != -EINVAL && retval != -ENOIOCTLCMD)
+ printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
+ return retval;
/* These two ioctl's always return success; even if */
/* the driver doesn't support them. */
case TCSBRK:
case TCSBRKP:
- if (!tty->driver->ioctl)
+ if (!tty->ops->ioctl)
return 0;
- retval = tty->driver->ioctl(tty, file, cmd, arg);
+ retval = tty->ops->ioctl(tty, file, cmd, arg);
+ if (retval != -EINVAL && retval != -ENOIOCTLCMD)
+ printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
if (retval == -ENOIOCTLCMD)
retval = 0;
return retval;
@@ -3439,7 +3497,6 @@ int tty_ioctl(struct inode *inode, struct file *file,
case TIOCGSID:
return tiocgsid(tty, real_tty, p);
case TIOCGETD:
- /* FIXME: check this is ok */
return put_user(tty->ldisc.num, (int __user *)p);
case TIOCSETD:
return tiocsetd(tty, p);
@@ -3451,11 +3508,13 @@ int tty_ioctl(struct inode *inode, struct file *file,
* Break handling
*/
case TIOCSBRK: /* Turn break on, unconditionally */
- tty->driver->break_ctl(tty, -1);
+ if (tty->ops->break_ctl)
+ tty->ops->break_ctl(tty, -1);
return 0;
case TIOCCBRK: /* Turn break off, unconditionally */
- tty->driver->break_ctl(tty, 0);
+ if (tty->ops->break_ctl)
+ tty->ops->break_ctl(tty, 0);
return 0;
case TCSBRK: /* SVID version: non-zero arg --> no break */
/* non-zero arg means wait for all output data
@@ -3484,8 +3543,8 @@ int tty_ioctl(struct inode *inode, struct file *file,
}
break;
}
- if (tty->driver->ioctl) {
- retval = (tty->driver->ioctl)(tty, file, cmd, arg);
+ if (tty->ops->ioctl) {
+ retval = (tty->ops->ioctl)(tty, file, cmd, arg);
if (retval != -ENOIOCTLCMD)
return retval;
}
@@ -3512,8 +3571,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
return -EINVAL;
- if (tty->driver->compat_ioctl) {
- retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg);
+ if (tty->ops->compat_ioctl) {
+ retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
if (retval != -ENOIOCTLCMD)
return retval;
}
@@ -3563,8 +3622,7 @@ void __do_SAK(struct tty_struct *tty)
tty_ldisc_flush(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
read_lock(&tasklist_lock);
/* Kill the entire session */
@@ -3770,19 +3828,32 @@ static void initialize_tty_struct(struct tty_struct *tty)
mutex_init(&tty->atomic_read_lock);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->read_lock);
+ spin_lock_init(&tty->ctrl_lock);
INIT_LIST_HEAD(&tty->tty_files);
INIT_WORK(&tty->SAK_work, do_SAK_work);
}
-/*
- * The default put_char routine if the driver did not define one.
+/**
+ * tty_put_char - write one character to a tty
+ * @tty: tty
+ * @ch: character
+ *
+ * Write one byte to the tty using the provided put_char method
+ * if present. Returns the number of characters successfully output.
+ *
+ * Note: the specific put_char operation in the driver layer may go
+ * away soon. Don't call it directly, use this method
*/
-static void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
+int tty_put_char(struct tty_struct *tty, unsigned char ch)
{
- tty->driver->write(tty, &ch, 1);
+ if (tty->ops->put_char)
+ return tty->ops->put_char(tty, ch);
+ return tty->ops->write(tty, &ch, 1);
}
+EXPORT_SYMBOL_GPL(tty_put_char);
+
static struct class *tty_class;
/**
@@ -3865,37 +3936,8 @@ void put_tty_driver(struct tty_driver *driver)
void tty_set_operations(struct tty_driver *driver,
const struct tty_operations *op)
{
- driver->open = op->open;
- driver->close = op->close;
- driver->write = op->write;
- driver->put_char = op->put_char;
- driver->flush_chars = op->flush_chars;
- driver->write_room = op->write_room;
- driver->chars_in_buffer = op->chars_in_buffer;
- driver->ioctl = op->ioctl;
- driver->compat_ioctl = op->compat_ioctl;
- driver->set_termios = op->set_termios;
- driver->throttle = op->throttle;
- driver->unthrottle = op->unthrottle;
- driver->stop = op->stop;
- driver->start = op->start;
- driver->hangup = op->hangup;
- driver->break_ctl = op->break_ctl;
- driver->flush_buffer = op->flush_buffer;
- driver->set_ldisc = op->set_ldisc;
- driver->wait_until_sent = op->wait_until_sent;
- driver->send_xchar = op->send_xchar;
- driver->read_proc = op->read_proc;
- driver->write_proc = op->write_proc;
- driver->tiocmget = op->tiocmget;
- driver->tiocmset = op->tiocmset;
-#ifdef CONFIG_CONSOLE_POLL
- driver->poll_init = op->poll_init;
- driver->poll_get_char = op->poll_get_char;
- driver->poll_put_char = op->poll_put_char;
-#endif
-}
-
+ driver->ops = op;
+};
EXPORT_SYMBOL(alloc_tty_driver);
EXPORT_SYMBOL(put_tty_driver);
@@ -3958,9 +4000,6 @@ int tty_register_driver(struct tty_driver *driver)
return error;
}
- if (!driver->put_char)
- driver->put_char = tty_default_put_char;
-
mutex_lock(&tty_mutex);
list_add(&driver->tty_drivers, &tty_drivers);
mutex_unlock(&tty_mutex);
@@ -4036,14 +4075,19 @@ void proc_clear_tty(struct task_struct *p)
}
EXPORT_SYMBOL(proc_clear_tty);
+/* Called under the sighand lock */
+
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
if (tty) {
- /* We should not have a session or pgrp to here but.... */
+ unsigned long flags;
+ /* We should not have a session or pgrp to put here but.... */
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
- tty->session = get_pid(task_session(tsk));
tty->pgrp = get_pid(task_pgrp(tsk));
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ tty->session = get_pid(task_session(tsk));
}
put_pid(tsk->signal->tty_old_pgrp);
tsk->signal->tty = tty;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index f95a80b2265..b1a757a5ee2 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -39,6 +40,50 @@
#define TERMIOS_OLD 8
+int tty_chars_in_buffer(struct tty_struct *tty)
+{
+ if (tty->ops->chars_in_buffer)
+ return tty->ops->chars_in_buffer(tty);
+ else
+ return 0;
+}
+
+EXPORT_SYMBOL(tty_chars_in_buffer);
+
+int tty_write_room(struct tty_struct *tty)
+{
+ if (tty->ops->write_room)
+ return tty->ops->write_room(tty);
+ return 2048;
+}
+
+EXPORT_SYMBOL(tty_write_room);
+
+void tty_driver_flush_buffer(struct tty_struct *tty)
+{
+ if (tty->ops->flush_buffer)
+ tty->ops->flush_buffer(tty);
+}
+
+EXPORT_SYMBOL(tty_driver_flush_buffer);
+
+void tty_throttle(struct tty_struct *tty)
+{
+ /* check TTY_THROTTLED first so it indicates our state */
+ if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
+ tty->ops->throttle)
+ tty->ops->throttle(tty);
+}
+EXPORT_SYMBOL(tty_throttle);
+
+void tty_unthrottle(struct tty_struct *tty)
+{
+ if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
+ tty->ops->unthrottle)
+ tty->ops->unthrottle(tty);
+}
+EXPORT_SYMBOL(tty_unthrottle);
+
/**
* tty_wait_until_sent - wait for I/O to finish
* @tty: tty we are waiting for
@@ -57,15 +102,13 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
#endif
- if (!tty->driver->chars_in_buffer)
- return;
if (!timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
if (wait_event_interruptible_timeout(tty->write_wait,
- !tty->driver->chars_in_buffer(tty), timeout) < 0)
- return;
- if (tty->driver->wait_until_sent)
- tty->driver->wait_until_sent(tty, timeout);
+ !tty_chars_in_buffer(tty), timeout) >= 0) {
+ if (tty->ops->wait_until_sent)
+ tty->ops->wait_until_sent(tty, timeout);
+ }
}
EXPORT_SYMBOL(tty_wait_until_sent);
@@ -393,8 +436,9 @@ EXPORT_SYMBOL(tty_termios_hw_change);
static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
{
int canon_change;
- struct ktermios old_termios = *tty->termios;
+ struct ktermios old_termios;
struct tty_ldisc *ld;
+ unsigned long flags;
/*
* Perform the actual termios internal changes under lock.
@@ -404,7 +448,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
/* FIXME: we need to decide on some locking/ordering semantics
for the set_termios notification eventually */
mutex_lock(&tty->termios_mutex);
-
+ old_termios = *tty->termios;
*tty->termios = *new_termios;
unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
@@ -429,17 +473,19 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
STOP_CHAR(tty) == '\023' &&
START_CHAR(tty) == '\021');
if (old_flow != new_flow) {
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
if (new_flow)
tty->ctrl_status |= TIOCPKT_DOSTOP;
else
tty->ctrl_status |= TIOCPKT_NOSTOP;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
wake_up_interruptible(&tty->link->read_wait);
}
}
- if (tty->driver->set_termios)
- (*tty->driver->set_termios)(tty, &old_termios);
+ if (tty->ops->set_termios)
+ (*tty->ops->set_termios)(tty, &old_termios);
else
tty_termios_copy_hw(tty->termios, &old_termios);
@@ -474,7 +520,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
if (retval)
return retval;
+ mutex_lock(&tty->termios_mutex);
memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
+ mutex_unlock(&tty->termios_mutex);
if (opt & TERMIOS_TERMIO) {
if (user_termio_to_kernel_termios(&tmp_termios,
@@ -660,12 +708,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
{
struct tchars tmp;
+ mutex_lock(&tty->termios_mutex);
tmp.t_intrc = tty->termios->c_cc[VINTR];
tmp.t_quitc = tty->termios->c_cc[VQUIT];
tmp.t_startc = tty->termios->c_cc[VSTART];
tmp.t_stopc = tty->termios->c_cc[VSTOP];
tmp.t_eofc = tty->termios->c_cc[VEOF];
tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
+ mutex_unlock(&tty->termios_mutex);
return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
@@ -675,12 +725,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
if (copy_from_user(&tmp, tchars, sizeof(tmp)))
return -EFAULT;
+ mutex_lock(&tty->termios_mutex);
tty->termios->c_cc[VINTR] = tmp.t_intrc;
tty->termios->c_cc[VQUIT] = tmp.t_quitc;
tty->termios->c_cc[VSTART] = tmp.t_startc;
tty->termios->c_cc[VSTOP] = tmp.t_stopc;
tty->termios->c_cc[VEOF] = tmp.t_eofc;
tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
+ mutex_unlock(&tty->termios_mutex);
return 0;
}
#endif
@@ -690,6 +742,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
{
struct ltchars tmp;
+ mutex_lock(&tty->termios_mutex);
tmp.t_suspc = tty->termios->c_cc[VSUSP];
/* what is dsuspc anyway? */
tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
@@ -698,6 +751,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
tmp.t_flushc = tty->termios->c_cc[VEOL2];
tmp.t_werasc = tty->termios->c_cc[VWERASE];
tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
+ mutex_unlock(&tty->termios_mutex);
return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
@@ -708,6 +762,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
return -EFAULT;
+ mutex_lock(&tty->termios_mutex);
tty->termios->c_cc[VSUSP] = tmp.t_suspc;
/* what is dsuspc anyway? */
tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
@@ -716,6 +771,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
tty->termios->c_cc[VEOL2] = tmp.t_flushc;
tty->termios->c_cc[VWERASE] = tmp.t_werasc;
tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
+ mutex_unlock(&tty->termios_mutex);
return 0;
}
#endif
@@ -732,8 +788,8 @@ static int send_prio_char(struct tty_struct *tty, char ch)
{
int was_stopped = tty->stopped;
- if (tty->driver->send_xchar) {
- tty->driver->send_xchar(tty, ch);
+ if (tty->ops->send_xchar) {
+ tty->ops->send_xchar(tty, ch);
return 0;
}
@@ -742,7 +798,7 @@ static int send_prio_char(struct tty_struct *tty, char ch)
if (was_stopped)
start_tty(tty);
- tty->driver->write(tty, &ch, 1);
+ tty->ops->write(tty, &ch, 1);
if (was_stopped)
stop_tty(tty);
tty_write_unlock(tty);
@@ -750,6 +806,33 @@ static int send_prio_char(struct tty_struct *tty, char ch)
}
/**
+ * tty_change_softcar - carrier change ioctl helper
+ * @tty: tty to update
+ * @arg: enable/disable CLOCAL
+ *
+ * Perform a change to the CLOCAL state and call into the driver
+ * layer to make it visible. All done with the termios mutex
+ */
+
+static int tty_change_softcar(struct tty_struct *tty, int arg)
+{
+ int ret = 0;
+ int bit = arg ? CLOCAL : 0;
+ struct ktermios old;
+
+ mutex_lock(&tty->termios_mutex);
+ old = *tty->termios;
+ tty->termios->c_cflag &= ~CLOCAL;
+ tty->termios->c_cflag |= bit;
+ if (tty->ops->set_termios)
+ tty->ops->set_termios(tty, &old);
+ if ((tty->termios->c_cflag & CLOCAL) != bit)
+ ret = -EINVAL;
+ mutex_unlock(&tty->termios_mutex);
+ return ret;
+}
+
+/**
* tty_mode_ioctl - mode related ioctls
* @tty: tty for the ioctl
* @file: file pointer for the tty
@@ -859,12 +942,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
case TIOCSSOFTCAR:
if (get_user(arg, (unsigned int __user *) arg))
return -EFAULT;
- mutex_lock(&tty->termios_mutex);
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- mutex_unlock(&tty->termios_mutex);
- return 0;
+ return tty_change_softcar(tty, arg);
default:
return -ENOIOCTLCMD;
}
@@ -889,8 +967,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
ld->flush_buffer(tty);
/* fall through */
case TCOFLUSH:
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
break;
default:
tty_ldisc_deref(ld);
@@ -905,6 +982,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct tty_struct *real_tty;
+ unsigned long flags;
int retval;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -946,9 +1024,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
case TCFLSH:
return tty_perform_flush(tty, arg);
case TIOCOUTQ:
- return put_user(tty->driver->chars_in_buffer ?
- tty->driver->chars_in_buffer(tty) : 0,
- (int __user *) arg);
+ return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
case TIOCINQ:
retval = tty->read_cnt;
if (L_ICANON(tty))
@@ -963,6 +1039,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
return -ENOTTY;
if (get_user(pktmode, (int __user *) arg))
return -EFAULT;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
if (pktmode) {
if (!tty->packet) {
tty->packet = 1;
@@ -970,6 +1047,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
}
} else
tty->packet = 0;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
return 0;
}
default:
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 8de6b95aeb8..3d3e1c2b310 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -628,13 +628,13 @@ static int viotty_write(struct tty_struct *tty, const unsigned char *buf,
/*
* TTY put_char method
*/
-static void viotty_put_char(struct tty_struct *tty, unsigned char ch)
+static int viotty_put_char(struct tty_struct *tty, unsigned char ch)
{
struct port_info *pi;
pi = get_port_data(tty);
if (pi == NULL)
- return;
+ return 0;
/* This will append '\r' as well if the char is '\n' */
if (viochar_is_console(pi))
@@ -642,6 +642,7 @@ static void viotty_put_char(struct tty_struct *tty, unsigned char ch)
if (viopath_isactive(pi->lp))
internal_write(pi, &ch, 1);
+ return 1;
}
/*
@@ -704,8 +705,11 @@ static int viotty_ioctl(struct tty_struct *tty, struct file *file,
case KDSKBLED:
return 0;
}
-
- return n_tty_ioctl(tty, file, cmd, arg);
+ /* FIXME: WTF is this being called for ??? */
+ lock_kernel();
+ ret = n_tty_ioctl(tty, file, cmd, arg);
+ unlock_kernel();
+ return ret;
}
/*
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1c266047713..e458b08139a 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -909,15 +909,21 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
if (vc->vc_tty) {
struct winsize ws, *cws = &vc->vc_tty->winsize;
+ unsigned long flags;
memset(&ws, 0, sizeof(ws));
ws.ws_row = vc->vc_rows;
ws.ws_col = vc->vc_cols;
ws.ws_ypixel = vc->vc_scan_lines;
+
+ mutex_lock(&vc->vc_tty->termios_mutex);
+ spin_lock_irqsave(&vc->vc_tty->ctrl_lock, flags);
if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
vc->vc_tty->pgrp)
kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
+ spin_unlock_irqrestore(&vc->vc_tty->ctrl_lock, flags);
*cws = ws;
+ mutex_unlock(&vc->vc_tty->termios_mutex);
}
if (CON_IS_VISIBLE(vc))
@@ -2541,6 +2547,9 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
if (get_user(type, p))
return -EFAULT;
ret = 0;
+
+ lock_kernel();
+
switch (type)
{
case TIOCL_SETSEL:
@@ -2560,7 +2569,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
ret = sel_loadlut(p);
break;
case TIOCL_GETSHIFTSTATE:
-
+
/*
* Make it possible to react to Shift+Mousebutton.
* Note that 'shift_state' is an undocumented
@@ -2615,6 +2624,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
ret = -EINVAL;
break;
}
+ unlock_kernel();
return ret;
}
@@ -2632,11 +2642,11 @@ static int con_write(struct tty_struct *tty, const unsigned char *buf, int count
return retval;
}
-static void con_put_char(struct tty_struct *tty, unsigned char ch)
+static int con_put_char(struct tty_struct *tty, unsigned char ch)
{
if (in_interrupt())
- return; /* n_r3964 calls put_char() from interrupt context */
- do_con_write(tty, &ch, 1);
+ return 0; /* n_r3964 calls put_char() from interrupt context */
+ return do_con_write(tty, &ch, 1);
}
static int con_write_room(struct tty_struct *tty)
@@ -3829,7 +3839,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
goto out;
c = (font.width+7)/8 * 32 * font.charcount;
-
+
if (op->data && font.charcount > op->charcount)
rc = -ENOSPC;
if (!(op->flags & KD_FONT_FLAG_OLD)) {
@@ -3994,6 +4004,7 @@ u16 screen_glyph(struct vc_data *vc, int offset)
c |= 0x100;
return c;
}
+EXPORT_SYMBOL_GPL(screen_glyph);
/* used by vcs - note the word offset */
unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index e6f89e8b925..3211afd9d57 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -373,11 +373,17 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
unsigned char ucval;
void __user *up = (void __user *)arg;
int i, perm;
-
+ int ret = 0;
+
console = vc->vc_num;
- if (!vc_cons_allocated(console)) /* impossible? */
- return -ENOIOCTLCMD;
+ lock_kernel();
+
+ if (!vc_cons_allocated(console)) { /* impossible? */
+ ret = -ENOIOCTLCMD;
+ goto out;
+ }
+
/*
* To have permissions to do most of the vt ioctls, we either have
@@ -391,15 +397,15 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
switch (cmd) {
case KIOCSOUND:
if (!perm)
- return -EPERM;
+ goto eperm;
if (arg)
arg = CLOCK_TICK_RATE / arg;
kd_mksound(arg, 0);
- return 0;
+ break;
case KDMKTONE:
if (!perm)
- return -EPERM;
+ goto eperm;
{
unsigned int ticks, count;
@@ -412,7 +418,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (count)
count = CLOCK_TICK_RATE / count;
kd_mksound(count, ticks);
- return 0;
+ break;
}
case KDGKBTYPE:
@@ -435,14 +441,18 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* KDADDIO and KDDELIO may be able to add ports beyond what
* we reject here, but to be safe...
*/
- if (arg < GPFIRST || arg > GPLAST)
- return -EINVAL;
- return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
+ if (arg < GPFIRST || arg > GPLAST) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
+ break;
case KDENABIO:
case KDDISABIO:
- return sys_ioperm(GPFIRST, GPNUM,
+ ret = sys_ioperm(GPFIRST, GPNUM,
(cmd == KDENABIO)) ? -ENXIO : 0;
+ break;
#endif
/* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
@@ -450,19 +460,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDKBDREP:
{
struct kbd_repeat kbrep;
- int err;
if (!capable(CAP_SYS_TTY_CONFIG))
- return -EPERM;
+ goto eperm;
- if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat)))
- return -EFAULT;
- err = kbd_rate(&kbrep);
- if (err)
- return err;
+ if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = kbd_rate(&kbrep);
+ if (ret)
+ break;
if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
}
case KDSETMODE:
@@ -475,7 +486,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* need to restore their engine state. --BenH
*/
if (!perm)
- return -EPERM;
+ goto eperm;
switch (arg) {
case KD_GRAPHICS:
break;
@@ -485,13 +496,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KD_TEXT:
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (vc->vc_mode == (unsigned char) arg)
- return 0;
+ break;
vc->vc_mode = (unsigned char) arg;
if (console != fg_console)
- return 0;
+ break;
/*
* explicitly blank/unblank the screen if switching modes
*/
@@ -501,7 +513,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
else
do_blank_screen(1);
release_console_sem();
- return 0;
+ break;
case KDGETMODE:
ucval = vc->vc_mode;
@@ -513,11 +525,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* these work like a combination of mmap and KDENABIO.
* this could be easily finished.
*/
- return -EINVAL;
+ ret = -EINVAL;
+ break;
case KDSKBMODE:
if (!perm)
- return -EPERM;
+ goto eperm;
switch(arg) {
case K_RAW:
kbd->kbdmode = VC_RAW;
@@ -534,10 +547,11 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
compute_shiftstate();
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
tty_ldisc_flush(tty);
- return 0;
+ break;
case KDGKBMODE:
ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
@@ -557,28 +571,32 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
set_vc_kbd_mode(kbd, VC_META);
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
- return 0;
+ break;
case KDGKBMETA:
ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
setint:
- return put_user(ucval, (int __user *)arg);
+ ret = put_user(ucval, (int __user *)arg);
+ break;
case KDGETKEYCODE:
case KDSETKEYCODE:
if(!capable(CAP_SYS_TTY_CONFIG))
- perm=0;
- return do_kbkeycode_ioctl(cmd, up, perm);
+ perm = 0;
+ ret = do_kbkeycode_ioctl(cmd, up, perm);
+ break;
case KDGKBENT:
case KDSKBENT:
- return do_kdsk_ioctl(cmd, up, perm, kbd);
+ ret = do_kdsk_ioctl(cmd, up, perm, kbd);
+ break;
case KDGKBSENT:
case KDSKBSENT:
- return do_kdgkb_ioctl(cmd, up, perm);
+ ret = do_kdgkb_ioctl(cmd, up, perm);
+ break;
case KDGKBDIACR:
{
@@ -586,26 +604,31 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
struct kbdiacr diacr;
int i;
- if (put_user(accent_table_size, &a->kb_cnt))
- return -EFAULT;
+ if (put_user(accent_table_size, &a->kb_cnt)) {
+ ret = -EFAULT;
+ break;
+ }
for (i = 0; i < accent_table_size; i++) {
diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
diacr.base = conv_uni_to_8bit(accent_table[i].base);
diacr.result = conv_uni_to_8bit(accent_table[i].result);
- if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
- return -EFAULT;
+ if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
+ ret = -EFAULT;
+ break;
+ }
}
- return 0;
+ break;
}
case KDGKBDIACRUC:
{
struct kbdiacrsuc __user *a = up;
if (put_user(accent_table_size, &a->kb_cnt))
- return -EFAULT;
- if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ else if (copy_to_user(a->kbdiacruc, accent_table,
+ accent_table_size*sizeof(struct kbdiacruc)))
+ ret = -EFAULT;
+ break;
}
case KDSKBDIACR:
@@ -616,20 +639,26 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
int i;
if (!perm)
- return -EPERM;
- if (get_user(ct,&a->kb_cnt))
- return -EFAULT;
- if (ct >= MAX_DIACR)
- return -EINVAL;
+ goto eperm;
+ if (get_user(ct,&a->kb_cnt)) {
+ ret = -EFAULT;
+ break;
+ }
+ if (ct >= MAX_DIACR) {
+ ret = -EINVAL;
+ break;
+ }
accent_table_size = ct;
for (i = 0; i < ct; i++) {
- if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
- return -EFAULT;
+ if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
+ ret = -EFAULT;
+ break;
+ }
accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
accent_table[i].base = conv_8bit_to_uni(diacr.base);
accent_table[i].result = conv_8bit_to_uni(diacr.result);
}
- return 0;
+ break;
}
case KDSKBDIACRUC:
@@ -638,15 +667,19 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
unsigned int ct;
if (!perm)
- return -EPERM;
- if (get_user(ct,&a->kb_cnt))
- return -EFAULT;
- if (ct >= MAX_DIACR)
- return -EINVAL;
+ goto eperm;
+ if (get_user(ct,&a->kb_cnt)) {
+ ret = -EFAULT;
+ break;
+ }
+ if (ct >= MAX_DIACR) {
+ ret = -EINVAL;
+ break;
+ }
accent_table_size = ct;
if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
}
/* the ioctls below read/set the flags usually shown in the leds */
@@ -657,26 +690,29 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDSKBLED:
if (!perm)
- return -EPERM;
- if (arg & ~0x77)
- return -EINVAL;
+ goto eperm;
+ if (arg & ~0x77) {
+ ret = -EINVAL;
+ break;
+ }
kbd->ledflagstate = (arg & 7);
kbd->default_ledflagstate = ((arg >> 4) & 7);
set_leds();
- return 0;
+ break;
/* the ioctls below only set the lights, not the functions */
/* for those, see KDGKBLED and KDSKBLED above */
case KDGETLED:
ucval = getledstate();
setchar:
- return put_user(ucval, (char __user *)arg);
+ ret = put_user(ucval, (char __user *)arg);
+ break;
case KDSETLED:
if (!perm)
- return -EPERM;
+ goto eperm;
setledstate(kbd, arg);
- return 0;
+ break;
/*
* A process can indicate its willingness to accept signals
@@ -688,16 +724,17 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDSIGACCEPT:
{
if (!perm || !capable(CAP_KILL))
- return -EPERM;
+ goto eperm;
if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
- return -EINVAL;
-
- spin_lock_irq(&vt_spawn_con.lock);
- put_pid(vt_spawn_con.pid);
- vt_spawn_con.pid = get_pid(task_pid(current));
- vt_spawn_con.sig = arg;
- spin_unlock_irq(&vt_spawn_con.lock);
- return 0;
+ ret = -EINVAL;
+ else {
+ spin_lock_irq(&vt_spawn_con.lock);
+ put_pid(vt_spawn_con.pid);
+ vt_spawn_con.pid = get_pid(task_pid(current));
+ vt_spawn_con.sig = arg;
+ spin_unlock_irq(&vt_spawn_con.lock);
+ }
+ break;
}
case VT_SETMODE:
@@ -705,11 +742,15 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
struct vt_mode tmp;
if (!perm)
- return -EPERM;
- if (copy_from_user(&tmp, up, sizeof(struct vt_mode)))
- return -EFAULT;
- if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
- return -EINVAL;
+ goto eperm;
+ if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
+ ret = -EINVAL;
+ goto out;
+ }
acquire_console_sem();
vc->vt_mode = tmp;
/* the frsig is ignored, so we set it to 0 */
@@ -719,7 +760,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
/* no switch is required -- saw@shade.msu.ru */
vc->vt_newvt = -1;
release_console_sem();
- return 0;
+ break;
}
case VT_GETMODE:
@@ -732,7 +773,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
release_console_sem();
rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
- return rc ? -EFAULT : 0;
+ if (rc)
+ ret = -EFAULT;
+ break;
}
/*
@@ -746,12 +789,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
unsigned short state, mask;
if (put_user(fg_console + 1, &vtstat->v_active))
- return -EFAULT;
- state = 1; /* /dev/tty0 is always open */
- for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)
- if (VT_IS_IN_USE(i))
- state |= mask;
- return put_user(state, &vtstat->v_state);
+ ret = -EFAULT;
+ else {
+ state = 1; /* /dev/tty0 is always open */
+ for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
+ ++i, mask <<= 1)
+ if (VT_IS_IN_USE(i))
+ state |= mask;
+ ret = put_user(state, &vtstat->v_state);
+ }
+ break;
}
/*
@@ -771,27 +818,31 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
case VT_ACTIVATE:
if (!perm)
- return -EPERM;
+ goto eperm;
if (arg == 0 || arg > MAX_NR_CONSOLES)
- return -ENXIO;
- arg--;
- acquire_console_sem();
- i = vc_allocate(arg);
- release_console_sem();
- if (i)
- return i;
- set_console(arg);
- return 0;
+ ret = -ENXIO;
+ else {
+ arg--;
+ acquire_console_sem();
+ ret = vc_allocate(arg);
+ release_console_sem();
+ if (ret)
+ break;
+ set_console(arg);
+ }
+ break;
/*
* wait until the specified VT has been activated
*/
case VT_WAITACTIVE:
if (!perm)
- return -EPERM;
+ goto eperm;
if (arg == 0 || arg > MAX_NR_CONSOLES)
- return -ENXIO;
- return vt_waitactive(arg-1);
+ ret = -ENXIO;
+ else
+ ret = vt_waitactive(arg - 1);
+ break;
/*
* If a vt is under process control, the kernel will not switch to it
@@ -805,10 +856,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
case VT_RELDISP:
if (!perm)
- return -EPERM;
- if (vc->vt_mode.mode != VT_PROCESS)
- return -EINVAL;
+ goto eperm;
+ if (vc->vt_mode.mode != VT_PROCESS) {
+ ret = -EINVAL;
+ break;
+ }
/*
* Switching-from response
*/
@@ -829,10 +882,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
int newvt;
newvt = vc->vt_newvt;
vc->vt_newvt = -1;
- i = vc_allocate(newvt);
- if (i) {
+ ret = vc_allocate(newvt);
+ if (ret) {
release_console_sem();
- return i;
+ break;
}
/*
* When we actually do the console switch,
@@ -841,31 +894,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
complete_change_console(vc_cons[newvt].d);
}
- }
-
- /*
- * Switched-to response
- */
- else
- {
+ } else {
+ /*
+ * Switched-to response
+ */
/*
* If it's just an ACK, ignore it
*/
- if (arg != VT_ACKACQ) {
- release_console_sem();
- return -EINVAL;
- }
+ if (arg != VT_ACKACQ)
+ ret = -EINVAL;
}
release_console_sem();
-
- return 0;
+ break;
/*
* Disallocate memory associated to VT (but leave VT1)
*/
case VT_DISALLOCATE:
- if (arg > MAX_NR_CONSOLES)
- return -ENXIO;
+ if (arg > MAX_NR_CONSOLES) {
+ ret = -ENXIO;
+ break;
+ }
if (arg == 0) {
/* deallocate all unused consoles, but leave 0 */
acquire_console_sem();
@@ -877,14 +926,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
/* deallocate a single console, if possible */
arg--;
if (VT_BUSY(arg))
- return -EBUSY;
- if (arg) { /* leave 0 */
+ ret = -EBUSY;
+ else if (arg) { /* leave 0 */
acquire_console_sem();
vc_deallocate(arg);
release_console_sem();
}
}
- return 0;
+ break;
case VT_RESIZE:
{
@@ -893,21 +942,21 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
ushort ll,cc;
if (!perm)
- return -EPERM;
+ goto eperm;
if (get_user(ll, &vtsizes->v_rows) ||
get_user(cc, &vtsizes->v_cols))
- return -EFAULT;
-
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- vc = vc_cons[i].d;
+ ret = -EFAULT;
+ else {
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ vc = vc_cons[i].d;
- if (vc) {
- vc->vc_resize_user = 1;
- vc_lock_resize(vc_cons[i].d, cc, ll);
+ if (vc) {
+ vc->vc_resize_user = 1;
+ vc_lock_resize(vc_cons[i].d, cc, ll);
+ }
}
}
-
- return 0;
+ break;
}
case VT_RESIZEX:
@@ -915,10 +964,13 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
struct vt_consize __user *vtconsize = up;
ushort ll,cc,vlin,clin,vcol,ccol;
if (!perm)
- return -EPERM;
+ goto eperm;
if (!access_ok(VERIFY_READ, vtconsize,
- sizeof(struct vt_consize)))
- return -EFAULT;
+ sizeof(struct vt_consize))) {
+ ret = -EFAULT;
+ break;
+ }
+ /* FIXME: Should check the copies properly */
__get_user(ll, &vtconsize->v_rows);
__get_user(cc, &vtconsize->v_cols);
__get_user(vlin, &vtconsize->v_vlin);
@@ -928,21 +980,28 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vlin = vlin ? vlin : vc->vc_scan_lines;
if (clin) {
if (ll) {
- if (ll != vlin/clin)
- return -EINVAL; /* Parameters don't add up */
+ if (ll != vlin/clin) {
+ /* Parameters don't add up */
+ ret = -EINVAL;
+ break;
+ }
} else
ll = vlin/clin;
}
if (vcol && ccol) {
if (cc) {
- if (cc != vcol/ccol)
- return -EINVAL;
+ if (cc != vcol/ccol) {
+ ret = -EINVAL;
+ break;
+ }
} else
cc = vcol/ccol;
}
- if (clin > 32)
- return -EINVAL;
+ if (clin > 32) {
+ ret = -EINVAL;
+ break;
+ }
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (!vc_cons[i].d)
@@ -956,19 +1015,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vc_resize(vc_cons[i].d, cc, ll);
release_console_sem();
}
- return 0;
+ break;
}
case PIO_FONT: {
if (!perm)
- return -EPERM;
+ goto eperm;
op.op = KD_FONT_OP_SET;
op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
op.width = 8;
op.height = 0;
op.charcount = 256;
op.data = up;
- return con_font_op(vc_cons[fg_console].d, &op);
+ ret = con_font_op(vc_cons[fg_console].d, &op);
+ break;
}
case GIO_FONT: {
@@ -978,100 +1038,124 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
op.height = 32;
op.charcount = 256;
op.data = up;
- return con_font_op(vc_cons[fg_console].d, &op);
+ ret = con_font_op(vc_cons[fg_console].d, &op);
+ break;
}
case PIO_CMAP:
if (!perm)
- return -EPERM;
- return con_set_cmap(up);
+ ret = -EPERM;
+ else
+ ret = con_set_cmap(up);
+ break;
case GIO_CMAP:
- return con_get_cmap(up);
+ ret = con_get_cmap(up);
+ break;
case PIO_FONTX:
case GIO_FONTX:
- return do_fontx_ioctl(cmd, up, perm, &op);
+ ret = do_fontx_ioctl(cmd, up, perm, &op);
+ break;
case PIO_FONTRESET:
{
if (!perm)
- return -EPERM;
+ goto eperm;
#ifdef BROKEN_GRAPHICS_PROGRAMS
/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
font is not saved. */
- return -ENOSYS;
+ ret = -ENOSYS;
+ break;
#else
{
op.op = KD_FONT_OP_SET_DEFAULT;
op.data = NULL;
- i = con_font_op(vc_cons[fg_console].d, &op);
- if (i)
- return i;
+ ret = con_font_op(vc_cons[fg_console].d, &op);
+ if (ret)
+ break;
con_set_default_unimap(vc_cons[fg_console].d);
- return 0;
+ break;
}
#endif
}
case KDFONTOP: {
- if (copy_from_user(&op, up, sizeof(op)))
- return -EFAULT;
+ if (copy_from_user(&op, up, sizeof(op))) {
+ ret = -EFAULT;
+ break;
+ }
if (!perm && op.op != KD_FONT_OP_GET)
- return -EPERM;
- i = con_font_op(vc, &op);
- if (i) return i;
+ goto eperm;
+ ret = con_font_op(vc, &op);
+ if (ret)
+ break;
if (copy_to_user(up, &op, sizeof(op)))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
}
case PIO_SCRNMAP:
if (!perm)
- return -EPERM;
- return con_set_trans_old(up);
+ ret = -EPERM;
+ else
+ ret = con_set_trans_old(up);
+ break;
case GIO_SCRNMAP:
- return con_get_trans_old(up);
+ ret = con_get_trans_old(up);
+ break;
case PIO_UNISCRNMAP:
if (!perm)
- return -EPERM;
- return con_set_trans_new(up);
+ ret = -EPERM;
+ else
+ ret = con_set_trans_new(up);
+ break;
case GIO_UNISCRNMAP:
- return con_get_trans_new(up);
+ ret = con_get_trans_new(up);
+ break;
case PIO_UNIMAPCLR:
{ struct unimapinit ui;
if (!perm)
- return -EPERM;
- i = copy_from_user(&ui, up, sizeof(struct unimapinit));
- if (i) return -EFAULT;
- con_clear_unimap(vc, &ui);
- return 0;
+ goto eperm;
+ ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
+ if (!ret)
+ con_clear_unimap(vc, &ui);
+ break;
}
case PIO_UNIMAP:
case GIO_UNIMAP:
- return do_unimap_ioctl(cmd, up, perm, vc);
+ ret = do_unimap_ioctl(cmd, up, perm, vc);
+ break;
case VT_LOCKSWITCH:
if (!capable(CAP_SYS_TTY_CONFIG))
- return -EPERM;
+ goto eperm;
vt_dont_switch = 1;
- return 0;
+ break;
case VT_UNLOCKSWITCH:
if (!capable(CAP_SYS_TTY_CONFIG))
- return -EPERM;
+ goto eperm;
vt_dont_switch = 0;
- return 0;
+ break;
case VT_GETHIFONTMASK:
- return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg);
+ ret = put_user(vc->vc_hi_font_mask,
+ (unsigned short __user *)arg);
+ break;
default:
- return -ENOIOCTLCMD;
+ ret = -ENOIOCTLCMD;
}
+out:
+ unlock_kernel();
+ return ret;
+eperm:
+ ret = -EPERM;
+ goto out;
}
/*
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 24c62b848bf..7f138c6195f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -382,7 +382,7 @@ fail:
spin_unlock_irqrestore(&gpio_lock, flags);
if (status)
pr_debug("%s: gpio-%d status %d\n",
- __FUNCTION__, gpio, status);
+ __func__, gpio, status);
return status;
}
EXPORT_SYMBOL_GPL(gpio_direction_input);
@@ -420,7 +420,7 @@ fail:
spin_unlock_irqrestore(&gpio_lock, flags);
if (status)
pr_debug("%s: gpio-%d status %d\n",
- __FUNCTION__, gpio, status);
+ __func__, gpio, status);
return status;
}
EXPORT_SYMBOL_GPL(gpio_direction_output);
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index ed71a8bc70d..5c8b6e0ff47 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -224,7 +224,7 @@ static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind)
if (in_data & 0xF000) {
printk(KERN_DEBUG
"%s : Doesn't look like an ads7828 device\n",
- __FUNCTION__);
+ __func__);
goto exit_free;
}
}
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index e1a3a79ab3f..7ff71ba7b7c 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -46,7 +46,7 @@ struct serport {
static int serport_serio_write(struct serio *serio, unsigned char data)
{
struct serport *serport = serio->port_data;
- return -(serport->tty->driver->write(serport->tty, &data, 1) != 1);
+ return -(serport->tty->ops->write(serport->tty, &data, 1) != 1);
}
static int serport_serio_open(struct serio *serio)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 24c6b7ca62b..6ca0bb949ad 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1111,11 +1111,12 @@ static int capinc_tty_write(struct tty_struct * tty,
return count;
}
-static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
+static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
struct sk_buff *skb;
unsigned long flags;
+ int ret = 1;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
@@ -1125,7 +1126,7 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_put_char: mp or mp->ncci NULL\n");
#endif
- return;
+ return 0;
}
spin_lock_irqsave(&workaround_lock, flags);
@@ -1134,7 +1135,7 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
if (skb_tailroom(skb) > 0) {
*(skb_put(skb, 1)) = ch;
spin_unlock_irqrestore(&workaround_lock, flags);
- return;
+ return 1;
}
mp->ttyskb = NULL;
skb_queue_tail(&mp->outqueue, skb);
@@ -1148,8 +1149,10 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
mp->ttyskb = skb;
} else {
printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
+ ret = 0;
}
spin_unlock_irqrestore(&workaround_lock, flags);
+ return ret;
}
static void capinc_tty_flush_chars(struct tty_struct *tty)
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index fceeb1d5768..45d1ee93cd3 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -68,10 +68,10 @@ static int write_modem(struct cardstate *cs)
struct tty_struct *tty = cs->hw.ser->tty;
struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
struct sk_buff *skb = bcs->tx_skb;
- int sent;
+ int sent = -EOPNOTSUPP;
if (!tty || !tty->driver || !skb)
- return -EFAULT;
+ return -EINVAL;
if (!skb->len) {
dev_kfree_skb_any(skb);
@@ -80,7 +80,8 @@ static int write_modem(struct cardstate *cs)
}
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- sent = tty->driver->write(tty, skb->data, skb->len);
+ if (tty->ops->write)
+ sent = tty->ops->write(tty, skb->data, skb->len);
gig_dbg(DEBUG_OUTPUT, "write_modem: sent %d", sent);
if (sent < 0) {
/* error */
@@ -120,7 +121,7 @@ static int send_cb(struct cardstate *cs)
if (cb->len) {
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- sent = tty->driver->write(tty, cb->buf + cb->offset, cb->len);
+ sent = tty->ops->write(tty, cb->buf + cb->offset, cb->len);
if (sent < 0) {
/* error */
gig_dbg(DEBUG_OUTPUT, "send_cb: write error %d", sent);
@@ -440,14 +441,14 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, unsi
struct tty_struct *tty = cs->hw.ser->tty;
unsigned int set, clear;
- if (!tty || !tty->driver || !tty->driver->tiocmset)
- return -EFAULT;
+ if (!tty || !tty->driver || !tty->ops->tiocmset)
+ return -EINVAL;
set = new_state & ~old_state;
clear = old_state & ~new_state;
if (!set && !clear)
return 0;
gig_dbg(DEBUG_IF, "tiocmset set %x clear %x", set, clear);
- return tty->driver->tiocmset(tty, NULL, set, clear);
+ return tty->ops->tiocmset(tty, NULL, set, clear);
}
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 8af0df1d5b8..1a2222cbb80 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1352,12 +1352,14 @@ isdn_tty_tiocmget(struct tty_struct *tty, struct file *file)
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
+ lock_kernel();
#ifdef ISDN_DEBUG_MODEM_IOCTL
printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line);
#endif
control = info->mcr;
status = info->msr;
+ unlock_kernel();
return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
| ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
@@ -1381,6 +1383,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file,
printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear);
#endif
+ lock_kernel();
if (set & TIOCM_RTS)
info->mcr |= UART_MCR_RTS;
if (set & TIOCM_DTR) {
@@ -1402,6 +1405,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file,
isdn_tty_modem_hup(info, 1);
}
}
+ unlock_kernel();
return 0;
}
@@ -1435,21 +1439,6 @@ isdn_tty_ioctl(struct tty_struct *tty, struct file *file,
return retval;
tty_wait_until_sent(tty, 0);
return 0;
- case TIOCGSOFTCAR:
-#ifdef ISDN_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "ttyI%d ioctl TIOCGSOFTCAR\n", info->line);
-#endif
- return put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
- case TIOCSSOFTCAR:
-#ifdef ISDN_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "ttyI%d ioctl TIOCSSOFTCAR\n", info->line);
-#endif
- if (get_user(arg, (ulong __user *) arg))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
case TIOCSERGETLSR: /* Get line status register */
#ifdef ISDN_DEBUG_MODEM_IOCTL
printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line);
@@ -1472,13 +1461,14 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
if (!old_termios)
isdn_tty_change_speed(info);
else {
- if (tty->termios->c_cflag == old_termios->c_cflag)
+ if (tty->termios->c_cflag == old_termios->c_cflag &&
+ tty->termios->c_ispeed == old_termios->c_ispeed &&
+ tty->termios->c_ospeed == old_termios->c_ospeed)
return;
isdn_tty_change_speed(info);
if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS)) {
+ !(tty->termios->c_cflag & CRTSCTS))
tty->hw_stopped = 0;
- }
}
}
@@ -1718,9 +1708,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
}
dev->modempoll--;
isdn_tty_shutdown(info);
-
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ isdn_tty_flush_buffer(tty);
tty_ldisc_flush(tty);
info->tty = NULL;
info->ncarrier = 0;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index bb3e4b1cb77..83eb78b0013 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -276,6 +276,7 @@ static mddev_t * mddev_find(dev_t unit)
init_waitqueue_head(&new->sb_wait);
new->reshape_position = MaxSector;
new->resync_max = MaxSector;
+ new->level = LEVEL_NONE;
new->queue = blk_alloc_queue(GFP_KERNEL);
if (!new->queue) {
@@ -1369,6 +1370,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
MD_BUG();
return -EINVAL;
}
+
+ /* prevent duplicates */
+ if (find_rdev(mddev, rdev->bdev->bd_dev))
+ return -EEXIST;
+
/* make sure rdev->size exceeds mddev->size */
if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
if (mddev->pers) {
@@ -1652,6 +1658,8 @@ static void md_update_sb(mddev_t * mddev, int force_change)
int sync_req;
int nospares = 0;
+ if (mddev->external)
+ return;
repeat:
spin_lock_irq(&mddev->write_lock);
@@ -1820,6 +1828,10 @@ state_show(mdk_rdev_t *rdev, char *page)
len += sprintf(page+len, "%swrite_mostly",sep);
sep = ",";
}
+ if (test_bit(Blocked, &rdev->flags)) {
+ len += sprintf(page+len, "%sblocked", sep);
+ sep = ",";
+ }
if (!test_bit(Faulty, &rdev->flags) &&
!test_bit(In_sync, &rdev->flags)) {
len += sprintf(page+len, "%sspare", sep);
@@ -1836,6 +1848,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
* remove - disconnects the device
* writemostly - sets write_mostly
* -writemostly - clears write_mostly
+ * blocked - sets the Blocked flag
+ * -blocked - clears the Blocked flag
*/
int err = -EINVAL;
if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
@@ -1858,6 +1872,16 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
} else if (cmd_match(buf, "-writemostly")) {
clear_bit(WriteMostly, &rdev->flags);
err = 0;
+ } else if (cmd_match(buf, "blocked")) {
+ set_bit(Blocked, &rdev->flags);
+ err = 0;
+ } else if (cmd_match(buf, "-blocked")) {
+ clear_bit(Blocked, &rdev->flags);
+ wake_up(&rdev->blocked_wait);
+ set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
+ md_wakeup_thread(rdev->mddev->thread);
+
+ err = 0;
}
return err ? err : len;
}
@@ -2097,7 +2121,7 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
rv = -EBUSY;
else
rv = entry->store(rdev, page, length);
- mddev_unlock(rdev->mddev);
+ mddev_unlock(mddev);
}
return rv;
}
@@ -2186,7 +2210,9 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
goto abort_free;
}
}
+
INIT_LIST_HEAD(&rdev->same_set);
+ init_waitqueue_head(&rdev->blocked_wait);
return rdev;
@@ -2457,7 +2483,6 @@ resync_start_show(mddev_t *mddev, char *page)
static ssize_t
resync_start_store(mddev_t *mddev, const char *buf, size_t len)
{
- /* can only set chunk_size if array is not yet active */
char *e;
unsigned long long n = simple_strtoull(buf, &e, 10);
@@ -2591,15 +2616,20 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
err = do_md_stop(mddev, 1);
else {
mddev->ro = 1;
+ set_disk_ro(mddev->gendisk, 1);
err = do_md_run(mddev);
}
break;
case read_auto:
- /* stopping an active array */
if (mddev->pers) {
- err = do_md_stop(mddev, 1);
- if (err == 0)
- mddev->ro = 2; /* FIXME mark devices writable */
+ if (mddev->ro != 1)
+ err = do_md_stop(mddev, 1);
+ else
+ err = restart_array(mddev);
+ if (err == 0) {
+ mddev->ro = 2;
+ set_disk_ro(mddev->gendisk, 0);
+ }
} else {
mddev->ro = 2;
err = do_md_run(mddev);
@@ -2612,6 +2642,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
if (atomic_read(&mddev->writes_pending) == 0) {
if (mddev->in_sync == 0) {
mddev->in_sync = 1;
+ if (mddev->safemode == 1)
+ mddev->safemode = 0;
if (mddev->persistent)
set_bit(MD_CHANGE_CLEAN,
&mddev->flags);
@@ -2635,6 +2667,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
err = 0;
} else {
mddev->ro = 0;
+ set_disk_ro(mddev->gendisk, 0);
err = do_md_run(mddev);
}
break;
@@ -3712,6 +3745,30 @@ static int do_md_stop(mddev_t * mddev, int mode)
mddev->reshape_position = MaxSector;
mddev->external = 0;
mddev->persistent = 0;
+ mddev->level = LEVEL_NONE;
+ mddev->clevel[0] = 0;
+ mddev->flags = 0;
+ mddev->ro = 0;
+ mddev->metadata_type[0] = 0;
+ mddev->chunk_size = 0;
+ mddev->ctime = mddev->utime = 0;
+ mddev->layout = 0;
+ mddev->max_disks = 0;
+ mddev->events = 0;
+ mddev->delta_disks = 0;
+ mddev->new_level = LEVEL_NONE;
+ mddev->new_layout = 0;
+ mddev->new_chunk = 0;
+ mddev->curr_resync = 0;
+ mddev->resync_mismatches = 0;
+ mddev->suspend_lo = mddev->suspend_hi = 0;
+ mddev->sync_speed_min = mddev->sync_speed_max = 0;
+ mddev->recovery = 0;
+ mddev->in_sync = 0;
+ mddev->changed = 0;
+ mddev->degraded = 0;
+ mddev->barriers_work = 0;
+ mddev->safemode = 0;
} else if (mddev->pers)
printk(KERN_INFO "md: %s switched to read-only mode.\n",
@@ -4919,6 +4976,9 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
if (!rdev || test_bit(Faulty, &rdev->flags))
return;
+
+ if (mddev->external)
+ set_bit(Blocked, &rdev->flags);
/*
dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
mdname(mddev),
@@ -5365,6 +5425,8 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
md_wakeup_thread(mddev->sync_thread);
}
atomic_inc(&mddev->writes_pending);
+ if (mddev->safemode == 1)
+ mddev->safemode = 0;
if (mddev->in_sync) {
spin_lock_irq(&mddev->write_lock);
if (mddev->in_sync) {
@@ -5719,7 +5781,7 @@ static int remove_and_add_spares(mddev_t *mddev)
rdev_for_each(rdev, rtmp, mddev)
if (rdev->raid_disk >= 0 &&
- !mddev->external &&
+ !test_bit(Blocked, &rdev->flags) &&
(test_bit(Faulty, &rdev->flags) ||
! test_bit(In_sync, &rdev->flags)) &&
atomic_read(&rdev->nr_pending)==0) {
@@ -5789,7 +5851,7 @@ void md_check_recovery(mddev_t *mddev)
return;
if (signal_pending(current)) {
- if (mddev->pers->sync_request) {
+ if (mddev->pers->sync_request && !mddev->external) {
printk(KERN_INFO "md: %s in immediate safe mode\n",
mdname(mddev));
mddev->safemode = 2;
@@ -5801,7 +5863,7 @@ void md_check_recovery(mddev_t *mddev)
(mddev->flags && !mddev->external) ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
- (mddev->safemode == 1) ||
+ (mddev->external == 0 && mddev->safemode == 1) ||
(mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending)
&& !mddev->in_sync && mddev->recovery_cp == MaxSector)
))
@@ -5810,16 +5872,20 @@ void md_check_recovery(mddev_t *mddev)
if (mddev_trylock(mddev)) {
int spares = 0;
- spin_lock_irq(&mddev->write_lock);
- if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
- !mddev->in_sync && mddev->recovery_cp == MaxSector) {
- mddev->in_sync = 1;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ if (!mddev->external) {
+ spin_lock_irq(&mddev->write_lock);
+ if (mddev->safemode &&
+ !atomic_read(&mddev->writes_pending) &&
+ !mddev->in_sync &&
+ mddev->recovery_cp == MaxSector) {
+ mddev->in_sync = 1;
+ if (mddev->persistent)
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ }
+ if (mddev->safemode == 1)
+ mddev->safemode = 0;
+ spin_unlock_irq(&mddev->write_lock);
}
- if (mddev->safemode == 1)
- mddev->safemode = 0;
- spin_unlock_irq(&mddev->write_lock);
if (mddev->flags)
md_update_sb(mddev, 0);
@@ -5914,6 +5980,16 @@ void md_check_recovery(mddev_t *mddev)
}
}
+void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ sysfs_notify(&rdev->kobj, NULL, "state");
+ wait_event_timeout(rdev->blocked_wait,
+ !test_bit(Blocked, &rdev->flags),
+ msecs_to_jiffies(5000));
+ rdev_dec_pending(rdev, mddev);
+}
+EXPORT_SYMBOL(md_wait_for_blocked_rdev);
+
static int md_notify_reboot(struct notifier_block *this,
unsigned long code, void *x)
{
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 9fd473a6dbf..6778b7cb39b 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -773,7 +773,6 @@ static int make_request(struct request_queue *q, struct bio * bio)
r1bio_t *r1_bio;
struct bio *read_bio;
int i, targets = 0, disks;
- mdk_rdev_t *rdev;
struct bitmap *bitmap = mddev->bitmap;
unsigned long flags;
struct bio_list bl;
@@ -781,6 +780,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
const int rw = bio_data_dir(bio);
const int do_sync = bio_sync(bio);
int do_barriers;
+ mdk_rdev_t *blocked_rdev;
/*
* Register the new request and wait if the reconstruction
@@ -862,10 +862,17 @@ static int make_request(struct request_queue *q, struct bio * bio)
first = 0;
}
#endif
+ retry_write:
+ blocked_rdev = NULL;
rcu_read_lock();
for (i = 0; i < disks; i++) {
- if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
- !test_bit(Faulty, &rdev->flags)) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+ atomic_inc(&rdev->nr_pending);
+ blocked_rdev = rdev;
+ break;
+ }
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
atomic_inc(&rdev->nr_pending);
if (test_bit(Faulty, &rdev->flags)) {
rdev_dec_pending(rdev, mddev);
@@ -878,6 +885,20 @@ static int make_request(struct request_queue *q, struct bio * bio)
}
rcu_read_unlock();
+ if (unlikely(blocked_rdev)) {
+ /* Wait for this device to become unblocked */
+ int j;
+
+ for (j = 0; j < i; j++)
+ if (r1_bio->bios[j])
+ rdev_dec_pending(conf->mirrors[j].rdev, mddev);
+
+ allow_barrier(conf);
+ md_wait_for_blocked_rdev(blocked_rdev, mddev);
+ wait_barrier(conf);
+ goto retry_write;
+ }
+
BUG_ON(targets == 0); /* we never fail the last device */
if (targets < conf->raid_disks) {
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1e96aa3ff51..5938fa96292 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -790,6 +790,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
const int do_sync = bio_sync(bio);
struct bio_list bl;
unsigned long flags;
+ mdk_rdev_t *blocked_rdev;
if (unlikely(bio_barrier(bio))) {
bio_endio(bio, -EOPNOTSUPP);
@@ -879,17 +880,23 @@ static int make_request(struct request_queue *q, struct bio * bio)
/*
* WRITE:
*/
- /* first select target devices under spinlock and
+ /* first select target devices under rcu_lock and
* inc refcount on their rdev. Record them by setting
* bios[x] to bio
*/
raid10_find_phys(conf, r10_bio);
+ retry_write:
+ blocked_rdev = 0;
rcu_read_lock();
for (i = 0; i < conf->copies; i++) {
int d = r10_bio->devs[i].devnum;
mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
- if (rdev &&
- !test_bit(Faulty, &rdev->flags)) {
+ if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+ atomic_inc(&rdev->nr_pending);
+ blocked_rdev = rdev;
+ break;
+ }
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
atomic_inc(&rdev->nr_pending);
r10_bio->devs[i].bio = bio;
} else {
@@ -899,6 +906,22 @@ static int make_request(struct request_queue *q, struct bio * bio)
}
rcu_read_unlock();
+ if (unlikely(blocked_rdev)) {
+ /* Have to wait for this device to get unblocked, then retry */
+ int j;
+ int d;
+
+ for (j = 0; j < i; j++)
+ if (r10_bio->devs[j].bio) {
+ d = r10_bio->devs[j].devnum;
+ rdev_dec_pending(conf->mirrors[d].rdev, mddev);
+ }
+ allow_barrier(conf);
+ md_wait_for_blocked_rdev(blocked_rdev, mddev);
+ wait_barrier(conf);
+ goto retry_write;
+ }
+
atomic_set(&r10_bio->remaining, 0);
bio_list_init(&bl);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 968dacaced6..087eee0cb80 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2607,6 +2607,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
}
}
+
/*
* handle_stripe - do things to a stripe.
*
@@ -2632,6 +2633,7 @@ static void handle_stripe5(struct stripe_head *sh)
struct stripe_head_state s;
struct r5dev *dev;
unsigned long pending = 0;
+ mdk_rdev_t *blocked_rdev = NULL;
memset(&s, 0, sizeof(s));
pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d "
@@ -2691,6 +2693,11 @@ static void handle_stripe5(struct stripe_head *sh)
if (dev->written)
s.written++;
rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+ blocked_rdev = rdev;
+ atomic_inc(&rdev->nr_pending);
+ break;
+ }
if (!rdev || !test_bit(In_sync, &rdev->flags)) {
/* The ReadError flag will just be confusing now */
clear_bit(R5_ReadError, &dev->flags);
@@ -2705,6 +2712,11 @@ static void handle_stripe5(struct stripe_head *sh)
}
rcu_read_unlock();
+ if (unlikely(blocked_rdev)) {
+ set_bit(STRIPE_HANDLE, &sh->state);
+ goto unlock;
+ }
+
if (s.to_fill && !test_and_set_bit(STRIPE_OP_BIOFILL, &sh->ops.pending))
sh->ops.count++;
@@ -2894,8 +2906,13 @@ static void handle_stripe5(struct stripe_head *sh)
if (sh->ops.count)
pending = get_stripe_work(sh);
+ unlock:
spin_unlock(&sh->lock);
+ /* wait for this device to become unblocked */
+ if (unlikely(blocked_rdev))
+ md_wait_for_blocked_rdev(blocked_rdev, conf->mddev);
+
if (pending)
raid5_run_ops(sh, pending);
@@ -2912,6 +2929,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
struct stripe_head_state s;
struct r6_state r6s;
struct r5dev *dev, *pdev, *qdev;
+ mdk_rdev_t *blocked_rdev = NULL;
r6s.qd_idx = raid6_next_disk(pd_idx, disks);
pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
@@ -2975,6 +2993,11 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
if (dev->written)
s.written++;
rdev = rcu_dereference(conf->disks[i].rdev);
+ if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
+ blocked_rdev = rdev;
+ atomic_inc(&rdev->nr_pending);
+ break;
+ }
if (!rdev || !test_bit(In_sync, &rdev->flags)) {
/* The ReadError flag will just be confusing now */
clear_bit(R5_ReadError, &dev->flags);
@@ -2989,6 +3012,11 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
set_bit(R5_Insync, &dev->flags);
}
rcu_read_unlock();
+
+ if (unlikely(blocked_rdev)) {
+ set_bit(STRIPE_HANDLE, &sh->state);
+ goto unlock;
+ }
pr_debug("locked=%d uptodate=%d to_read=%d"
" to_write=%d failed=%d failed_num=%d,%d\n",
s.locked, s.uptodate, s.to_read, s.to_write, s.failed,
@@ -3094,8 +3122,13 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
!test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
handle_stripe_expansion(conf, sh, &r6s);
+ unlock:
spin_unlock(&sh->lock);
+ /* wait for this device to become unblocked */
+ if (unlikely(blocked_rdev))
+ md_wait_for_blocked_rdev(blocked_rdev, conf->mddev);
+
return_io(return_bi);
for (i=disks; i-- ;) {
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 8e744823064..351b98b9b30 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -2,6 +2,7 @@ saa7146-objs := saa7146_i2c.o saa7146_core.o
saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
ir-common-objs := ir-functions.o ir-keymaps.o
+obj-y += tuners/
obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 03816b73f84..27da7b42327 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -81,8 +81,6 @@
/* Limits scaled width, which must be a multiple of 4. */
#define MAX_HACTIVE (0x3FF & -4)
-#define clamp(x, low, high) min (max (low, x), high)
-
#define BTTV_NORMS (\
V4L2_STD_PAL | V4L2_STD_PAL_N | \
V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 64819353276..17f542dfb36 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -70,12 +70,6 @@
#define VICAM_HEADER_SIZE 64
-#define clamp( x, l, h ) max_t( __typeof__( x ), \
- ( l ), \
- min_t( __typeof__( x ), \
- ( h ), \
- ( x ) ) )
-
/* Not sure what all the bytes in these char
* arrays do, but they're necessary to make
* the camera work.
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index f6f2d960cad..ef8a492766a 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -132,7 +132,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
if (iter >= MAX_ASIC_ISR_LOOPS)
printk(KERN_ERR "%s: interrupt processing overrun\n",
- __FUNCTION__);
+ __func__);
}
static inline int asic3_irq_to_bank(struct asic3 *asic, int irq)
@@ -409,7 +409,7 @@ int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio)
return asic3_get_gpio_d(asic, Status) & mask;
default:
printk(KERN_ERR "%s: invalid GPIO value 0x%x",
- __FUNCTION__, gpio);
+ __func__, gpio);
return -EINVAL;
}
}
@@ -437,7 +437,7 @@ void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val)
return;
default:
printk(KERN_ERR "%s: invalid GPIO value 0x%x",
- __FUNCTION__, gpio);
+ __func__, gpio);
return;
}
}
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 6e655b4c668..2fe64734d8a 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -349,11 +349,11 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
mode &= 3; /* get current power mode */
if (unit >= ARRAY_SIZE(sm->unit_power)) {
- dev_err(dev, "%s: bad unit %d\n", __FUNCTION__, unit);
+ dev_err(dev, "%s: bad unit %d\n", __func__, unit);
goto already;
}
- dev_dbg(sm->dev, "%s: unit %d, cur %d, to %d\n", __FUNCTION__, unit,
+ dev_dbg(sm->dev, "%s: unit %d, cur %d, to %d\n", __func__, unit,
sm->unit_power[unit], to);
if (to == 0 && sm->unit_power[unit] == 0) {
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index e5e6352556f..d21b7ab64bd 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -491,20 +491,23 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
out_be32(&fec->ievent, ievent); /* clear pending events */
- if (ievent & ~(FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
- if (ievent & ~FEC_IEVENT_TFINT)
- dev_dbg(&dev->dev, "ievent: %08x\n", ievent);
+ /* on fifo error, soft-reset fec */
+ if (ievent & (FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
+
+ if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
+ dev_warn(&dev->dev, "FEC_IEVENT_RFIFO_ERROR\n");
+ if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
+ dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
+
+ mpc52xx_fec_reset(dev);
+
+ netif_wake_queue(dev);
return IRQ_HANDLED;
}
- if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
- dev_warn(&dev->dev, "FEC_IEVENT_RFIFO_ERROR\n");
- if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
- dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
+ if (ievent & ~FEC_IEVENT_TFINT)
+ dev_dbg(&dev->dev, "ievent: %08x\n", ievent);
- mpc52xx_fec_reset(dev);
-
- netif_wake_queue(dev);
return IRQ_HANDLED;
}
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 1da55dd2a5a..9d5721287d6 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -148,13 +148,13 @@ static void sp_xmit_on_air(unsigned long channel)
if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) {
sp->led_state = 0x70;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
sp->tx_enable = 1;
- actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
+ actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
sp->xleft -= actual;
sp->xhead += actual;
sp->led_state = 0x60;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
sp->status2 = 0;
} else
mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
@@ -220,13 +220,13 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
*/
if (sp->duplex == 1) {
sp->led_state = 0x70;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
sp->tx_enable = 1;
- actual = sp->tty->driver->write(sp->tty, sp->xbuff, count);
+ actual = sp->tty->ops->write(sp->tty, sp->xbuff, count);
sp->xleft = count - actual;
sp->xhead = sp->xbuff + actual;
sp->led_state = 0x60;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
} else {
sp->xleft = count;
sp->xhead = sp->xbuff;
@@ -444,7 +444,7 @@ static void sixpack_write_wakeup(struct tty_struct *tty)
}
if (sp->tx_enable) {
- actual = tty->driver->write(tty, sp->xhead, sp->xleft);
+ actual = tty->ops->write(tty, sp->xhead, sp->xleft);
sp->xleft -= actual;
sp->xhead += actual;
}
@@ -491,9 +491,7 @@ static void sixpack_receive_buf(struct tty_struct *tty,
sixpack_decode(sp, buf, count1);
sp_put(sp);
- if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
- && tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ tty_unthrottle(tty);
}
/*
@@ -554,8 +552,8 @@ static void resync_tnc(unsigned long channel)
/* resync the TNC */
sp->led_state = 0x60;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
- sp->tty->driver->write(sp->tty, &resync_cmd, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &resync_cmd, 1);
/* Start resync timer again -- the TNC might be still absent */
@@ -573,7 +571,7 @@ static inline int tnc_init(struct sixpack *sp)
tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
- sp->tty->driver->write(sp->tty, &inbyte, 1);
+ sp->tty->ops->write(sp->tty, &inbyte, 1);
del_timer(&sp->resync_t);
sp->resync_t.data = (unsigned long) sp;
@@ -601,6 +599,8 @@ static int sixpack_open(struct tty_struct *tty)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
if (!dev) {
@@ -914,9 +914,9 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
} else { /* output watchdog char if idle */
if ((sp->status2 != 0) && (sp->duplex == 1)) {
sp->led_state = 0x70;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
sp->tx_enable = 1;
- actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
+ actual = sp->tty->ops->write(sp->tty, sp->xbuff, sp->status2);
sp->xleft -= actual;
sp->xhead += actual;
sp->led_state = 0x60;
@@ -926,7 +926,7 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
}
/* needed to trigger the TNC watchdog */
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
/* if the state byte has been received, the TNC is present,
so the resync timer can be reset. */
@@ -956,12 +956,12 @@ static void decode_std_command(struct sixpack *sp, unsigned char cmd)
if ((sp->status & SIXP_RX_DCD_MASK) ==
SIXP_RX_DCD_MASK) {
sp->led_state = 0x68;
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
}
} else {
sp->led_state = 0x60;
/* fill trailing bytes with zeroes */
- sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+ sp->tty->ops->write(sp->tty, &sp->led_state, 1);
rest = sp->rx_count;
if (rest != 0)
for (i = rest; i <= 3; i++)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 30c9b3b0d13..65166035aca 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -516,7 +516,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
spin_unlock_bh(&ax->buflock);
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
- actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
+ actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
ax->stats.tx_packets++;
ax->stats.tx_bytes += actual;
@@ -546,7 +546,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
}
printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
- (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ?
+ (ax->tty->ops->chars_in_buffer(ax->tty) || ax->xleft) ?
"bad line quality" : "driver error");
ax->xleft = 0;
@@ -736,6 +736,8 @@ static int mkiss_open(struct tty_struct *tty)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
if (!dev) {
@@ -754,8 +756,7 @@ static int mkiss_open(struct tty_struct *tty)
tty->disc_data = ax;
tty->receive_room = 65535;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
/* Restore default settings */
dev->type = ARPHRD_AX25;
@@ -935,9 +936,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
mkiss_put(ax);
- if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
- && tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ tty_unthrottle(tty);
}
/*
@@ -962,7 +961,7 @@ static void mkiss_write_wakeup(struct tty_struct *tty)
goto out;
}
- actual = tty->driver->write(tty, ax->xhead, ax->xleft);
+ actual = tty->ops->write(tty, ax->xhead, ax->xleft);
ax->xleft -= actual;
ax->xhead += actual;
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index fc753d7f674..e6f40b7f904 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -64,7 +64,7 @@ static int irtty_chars_in_buffer(struct sir_dev *dev)
IRDA_ASSERT(priv != NULL, return -1;);
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
- return priv->tty->driver->chars_in_buffer(priv->tty);
+ return tty_chars_in_buffer(priv->tty);
}
/* Wait (sleep) until underlaying hardware finished transmission
@@ -93,10 +93,8 @@ static void irtty_wait_until_sent(struct sir_dev *dev)
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
tty = priv->tty;
- if (tty->driver->wait_until_sent) {
- lock_kernel();
- tty->driver->wait_until_sent(tty, msecs_to_jiffies(100));
- unlock_kernel();
+ if (tty->ops->wait_until_sent) {
+ tty->ops->wait_until_sent(tty, msecs_to_jiffies(100));
}
else {
msleep(USBSERIAL_TX_DONE_DELAY);
@@ -125,48 +123,14 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
tty = priv->tty;
- lock_kernel();
+ mutex_lock(&tty->termios_mutex);
old_termios = *(tty->termios);
cflag = tty->termios->c_cflag;
-
- cflag &= ~CBAUD;
-
- IRDA_DEBUG(2, "%s(), Setting speed to %d\n", __FUNCTION__, speed);
-
- switch (speed) {
- case 1200:
- cflag |= B1200;
- break;
- case 2400:
- cflag |= B2400;
- break;
- case 4800:
- cflag |= B4800;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 57600:
- cflag |= B57600;
- break;
- case 115200:
- cflag |= B115200;
- break;
- case 9600:
- default:
- cflag |= B9600;
- break;
- }
-
- tty->termios->c_cflag = cflag;
- if (tty->driver->set_termios)
- tty->driver->set_termios(tty, &old_termios);
- unlock_kernel();
-
+ tty_encode_baud_rate(tty, speed, speed);
+ if (tty->ops->set_termios)
+ tty->ops->set_termios(tty, &old_termios);
priv->io.speed = speed;
+ mutex_unlock(&tty->termios_mutex);
return 0;
}
@@ -202,8 +166,8 @@ static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts)
* This function is not yet defined for all tty driver, so
* let's be careful... Jean II
*/
- IRDA_ASSERT(priv->tty->driver->tiocmset != NULL, return -1;);
- priv->tty->driver->tiocmset(priv->tty, NULL, set, clear);
+ IRDA_ASSERT(priv->tty->ops->tiocmset != NULL, return -1;);
+ priv->tty->ops->tiocmset(priv->tty, NULL, set, clear);
return 0;
}
@@ -225,17 +189,13 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
tty = priv->tty;
- if (!tty->driver->write)
+ if (!tty->ops->write)
return 0;
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- if (tty->driver->write_room) {
- writelen = tty->driver->write_room(tty);
- if (writelen > len)
- writelen = len;
- }
- else
+ writelen = tty_write_room(tty);
+ if (writelen > len)
writelen = len;
- return tty->driver->write(tty, ptr, writelen);
+ return tty->ops->write(tty, ptr, writelen);
}
/* ------------------------------------------------------- */
@@ -321,7 +281,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
struct ktermios old_termios;
int cflag;
- lock_kernel();
+ mutex_lock(&tty->termios_mutex);
old_termios = *(tty->termios);
cflag = tty->termios->c_cflag;
@@ -331,9 +291,9 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
cflag |= CREAD;
tty->termios->c_cflag = cflag;
- if (tty->driver->set_termios)
- tty->driver->set_termios(tty, &old_termios);
- unlock_kernel();
+ if (tty->ops->set_termios)
+ tty->ops->set_termios(tty, &old_termios);
+ mutex_unlock(&tty->termios_mutex);
}
/*****************************************************************/
@@ -359,8 +319,8 @@ static int irtty_start_dev(struct sir_dev *dev)
tty = priv->tty;
- if (tty->driver->start)
- tty->driver->start(tty);
+ if (tty->ops->start)
+ tty->ops->start(tty);
/* Make sure we can receive more data */
irtty_stop_receiver(tty, FALSE);
@@ -388,8 +348,8 @@ static int irtty_stop_dev(struct sir_dev *dev)
/* Make sure we don't receive more data */
irtty_stop_receiver(tty, TRUE);
- if (tty->driver->stop)
- tty->driver->stop(tty);
+ if (tty->ops->stop)
+ tty->ops->stop(tty);
mutex_unlock(&irtty_mutex);
@@ -483,11 +443,10 @@ static int irtty_open(struct tty_struct *tty)
/* stop the underlying driver */
irtty_stop_receiver(tty, TRUE);
- if (tty->driver->stop)
- tty->driver->stop(tty);
+ if (tty->ops->stop)
+ tty->ops->stop(tty);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
/* apply mtt override */
sir_tty_drv.qos_mtt_bits = qos_mtt_bits;
@@ -564,8 +523,8 @@ static void irtty_close(struct tty_struct *tty)
/* Stop tty */
irtty_stop_receiver(tty, TRUE);
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
- if (tty->driver->stop)
- tty->driver->stop(tty);
+ if (tty->ops->stop)
+ tty->ops->stop(tty);
kfree(priv);
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index f023d5b67e6..f1a52def124 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -158,6 +158,9 @@ ppp_asynctty_open(struct tty_struct *tty)
struct asyncppp *ap;
int err;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
err = -ENOMEM;
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
if (!ap)
@@ -358,9 +361,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
ap_put(ap);
- if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
- && tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ tty_unthrottle(tty);
}
static void
@@ -676,7 +677,7 @@ ppp_async_push(struct asyncppp *ap)
if (!tty_stuffed && ap->optr < ap->olim) {
avail = ap->olim - ap->optr;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- sent = tty->driver->write(tty, ap->optr, avail);
+ sent = tty->ops->write(tty, ap->optr, avail);
if (sent < 0)
goto flush; /* error, e.g. loss of CD */
ap->optr += sent;
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 0d80fa54671..b8f0369a71e 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -207,6 +207,9 @@ ppp_sync_open(struct tty_struct *tty)
struct syncppp *ap;
int err;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
err = -ENOMEM;
if (!ap)
@@ -398,9 +401,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
sp_put(ap);
- if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
- && tty->driver->unthrottle)
- tty->driver->unthrottle(tty);
+ tty_unthrottle(tty);
}
static void
@@ -653,7 +654,7 @@ ppp_sync_push(struct syncppp *ap)
tty_stuffed = 0;
if (!tty_stuffed && ap->tpkt) {
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- sent = tty->driver->write(tty, ap->tpkt->data, ap->tpkt->len);
+ sent = tty->ops->write(tty, ap->tpkt->data, ap->tpkt->len);
if (sent < 0)
goto flush; /* error, e.g. loss of CD */
if (sent < ap->tpkt->len) {
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 5a55ede352f..84af68fdb6c 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -396,14 +396,14 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
/* Order of next two lines is *very* important.
* When we are sending a little amount of data,
- * the transfer may be completed inside driver.write()
+ * the transfer may be completed inside the ops->write()
* routine, because it's running with interrupts enabled.
* In this case we *never* got WRITE_WAKEUP event,
* if we did not request it before write operation.
* 14 Oct 1994 Dmitry Gorodchanin.
*/
sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- actual = sl->tty->driver->write(sl->tty, sl->xbuff, count);
+ actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
#ifdef SL_CHECK_TRANSMIT
sl->dev->trans_start = jiffies;
#endif
@@ -437,7 +437,7 @@ static void slip_write_wakeup(struct tty_struct *tty)
return;
}
- actual = tty->driver->write(tty, sl->xhead, sl->xleft);
+ actual = tty->ops->write(tty, sl->xhead, sl->xleft);
sl->xleft -= actual;
sl->xhead += actual;
}
@@ -462,7 +462,7 @@ static void sl_tx_timeout(struct net_device *dev)
}
printk(KERN_WARNING "%s: transmit timed out, %s?\n",
dev->name,
- (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
+ (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
"bad line quality" : "driver error");
sl->xleft = 0;
sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
@@ -830,6 +830,9 @@ static int slip_open(struct tty_struct *tty)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
/* RTnetlink lock is misused here to serialize concurrent
opens of slip channels. There are better ways, but it is
the simplest one.
@@ -1432,7 +1435,7 @@ static void sl_outfill(unsigned long sls)
/* put END into tty queue. Is it right ??? */
if (!netif_queue_stopped(sl->dev)) {
/* if device busy no outfill */
- sl->tty->driver->write(sl->tty, &s, 1);
+ sl->tty->ops->write(sl->tty, &s, 1);
}
} else
set_bit(SLF_OUTWAIT, &sl->flags);
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 63abfd72542..e03eef2f228 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -178,6 +178,20 @@ static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal)
CPC_TTY_UNLOCK(card,flags);
}
+
+static const struct tty_operations pc300_ops = {
+ .open = cpc_tty_open,
+ .close = cpc_tty_close,
+ .write = cpc_tty_write,
+ .write_room = cpc_tty_write_room,
+ .chars_in_buffer = cpc_tty_chars_in_buffer,
+ .tiocmset = pc300_tiocmset,
+ .tiocmget = pc300_tiocmget,
+ .flush_buffer = cpc_tty_flush_buffer,
+ .hangup = cpc_tty_hangup,
+};
+
+
/*
* PC300 TTY initialization routine
*
@@ -225,15 +239,7 @@ void cpc_tty_init(pc300dev_t *pc300dev)
serial_drv.flags = TTY_DRIVER_REAL_RAW;
/* interface routines from the upper tty layer to the tty driver */
- serial_drv.open = cpc_tty_open;
- serial_drv.close = cpc_tty_close;
- serial_drv.write = cpc_tty_write;
- serial_drv.write_room = cpc_tty_write_room;
- serial_drv.chars_in_buffer = cpc_tty_chars_in_buffer;
- serial_drv.tiocmset = pc300_tiocmset;
- serial_drv.tiocmget = pc300_tiocmget;
- serial_drv.flush_buffer = cpc_tty_flush_buffer;
- serial_drv.hangup = cpc_tty_hangup;
+ tty_set_operations(&serial_drv, &pc300_ops);
/* register the TTY driver */
if (tty_register_driver(&serial_drv)) {
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 0f8aca8a4d4..249e18053d5 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -17,7 +17,7 @@
#include <linux/module.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/mm.h>
@@ -95,7 +95,7 @@ static struct x25_asy *x25_asy_alloc(void)
x25_asy_devs[i] = dev;
return sl;
} else {
- printk("x25_asy_alloc() - register_netdev() failure.\n");
+ printk(KERN_WARNING "x25_asy_alloc() - register_netdev() failure.\n");
free_netdev(dev);
}
}
@@ -112,23 +112,22 @@ static void x25_asy_free(struct x25_asy *sl)
kfree(sl->xbuff);
sl->xbuff = NULL;
- if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) {
- printk("%s: x25_asy_free for already free unit.\n", sl->dev->name);
- }
+ if (!test_and_clear_bit(SLF_INUSE, &sl->flags))
+ printk(KERN_ERR "%s: x25_asy_free for already free unit.\n",
+ sl->dev->name);
}
static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
{
struct x25_asy *sl = dev->priv;
unsigned char *xbuff, *rbuff;
- int len = 2* newmtu;
+ int len = 2 * newmtu;
xbuff = kmalloc(len + 4, GFP_ATOMIC);
rbuff = kmalloc(len + 4, GFP_ATOMIC);
- if (xbuff == NULL || rbuff == NULL)
- {
- printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n",
+ if (xbuff == NULL || rbuff == NULL) {
+ printk(KERN_WARNING "%s: unable to grow X.25 buffers, MTU change cancelled.\n",
dev->name);
kfree(xbuff);
kfree(rbuff);
@@ -193,25 +192,23 @@ static void x25_asy_bump(struct x25_asy *sl)
int err;
count = sl->rcount;
- sl->stats.rx_bytes+=count;
-
+ sl->stats.rx_bytes += count;
+
skb = dev_alloc_skb(count+1);
- if (skb == NULL)
- {
- printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
+ if (skb == NULL) {
+ printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
+ sl->dev->name);
sl->stats.rx_dropped++;
return;
}
- skb_push(skb,1); /* LAPB internal control */
- memcpy(skb_put(skb,count), sl->rbuff, count);
+ skb_push(skb, 1); /* LAPB internal control */
+ memcpy(skb_put(skb, count), sl->rbuff, count);
skb->protocol = x25_type_trans(skb, sl->dev);
- if((err=lapb_data_received(skb->dev, skb))!=LAPB_OK)
- {
+ err = lapb_data_received(skb->dev, skb);
+ if (err != LAPB_OK) {
kfree_skb(skb);
- printk(KERN_DEBUG "x25_asy: data received err - %d\n",err);
- }
- else
- {
+ printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
+ } else {
netif_rx(skb);
sl->dev->last_rx = jiffies;
sl->stats.rx_packets++;
@@ -224,10 +221,11 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
unsigned char *p;
int actual, count, mtu = sl->dev->mtu;
- if (len > mtu)
- { /* Sigh, shouldn't occur BUT ... */
+ if (len > mtu) {
+ /* Sigh, shouldn't occur BUT ... */
len = mtu;
- printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
+ printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
+ sl->dev->name);
sl->stats.tx_dropped++;
x25_asy_unlock(sl);
return;
@@ -245,7 +243,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
* 14 Oct 1994 Dmitry Gorodchanin.
*/
sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- actual = sl->tty->driver->write(sl->tty, sl->xbuff, count);
+ actual = sl->tty->ops->write(sl->tty, sl->xbuff, count);
sl->xleft = count - actual;
sl->xhead = sl->xbuff + actual;
/* VSV */
@@ -265,8 +263,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
return;
- if (sl->xleft <= 0)
- {
+ if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
sl->stats.tx_packets++;
@@ -275,14 +272,14 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
return;
}
- actual = tty->driver->write(tty, sl->xhead, sl->xleft);
+ actual = tty->ops->write(tty, sl->xhead, sl->xleft);
sl->xleft -= actual;
sl->xhead += actual;
}
static void x25_asy_timeout(struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+ struct x25_asy *sl = dev->priv;
spin_lock(&sl->lock);
if (netif_queue_stopped(dev)) {
@@ -290,7 +287,7 @@ static void x25_asy_timeout(struct net_device *dev)
* 14 Oct 1994 Dmitry Gorodchanin.
*/
printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
- (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
+ (tty_chars_in_buffer(sl->tty) || sl->xleft) ?
"bad line quality" : "driver error");
sl->xleft = 0;
sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
@@ -303,31 +300,34 @@ static void x25_asy_timeout(struct net_device *dev)
static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+ struct x25_asy *sl = dev->priv;
int err;
if (!netif_running(sl->dev)) {
- printk("%s: xmit call when iface is down\n", dev->name);
+ printk(KERN_ERR "%s: xmit call when iface is down\n",
+ dev->name);
kfree_skb(skb);
return 0;
}
-
- switch(skb->data[0])
- {
- case 0x00:break;
- case 0x01: /* Connection request .. do nothing */
- if((err=lapb_connect_request(dev))!=LAPB_OK)
- printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
- kfree_skb(skb);
- return 0;
- case 0x02: /* Disconnect request .. do nothing - hang up ?? */
- if((err=lapb_disconnect_request(dev))!=LAPB_OK)
- printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
- default:
- kfree_skb(skb);
- return 0;
+
+ switch (skb->data[0]) {
+ case 0x00:
+ break;
+ case 0x01: /* Connection request .. do nothing */
+ err = lapb_connect_request(dev);
+ if (err != LAPB_OK)
+ printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
+ kfree_skb(skb);
+ return 0;
+ case 0x02: /* Disconnect request .. do nothing - hang up ?? */
+ err = lapb_disconnect_request(dev);
+ if (err != LAPB_OK)
+ printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
+ default:
+ kfree_skb(skb);
+ return 0;
}
- skb_pull(skb,1); /* Remove control byte */
+ skb_pull(skb, 1); /* Remove control byte */
/*
* If we are busy already- too bad. We ought to be able
* to queue things at this point, to allow for a little
@@ -338,10 +338,10 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
* So, no queues !
* 14 Oct 1994 Dmitry Gorodchanin.
*/
-
- if((err=lapb_data_request(dev,skb))!=LAPB_OK)
- {
- printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err);
+
+ err = lapb_data_request(dev, skb);
+ if (err != LAPB_OK) {
+ printk(KERN_ERR "x25_asy: lapb_data_request error - %d\n", err);
kfree_skb(skb);
return 0;
}
@@ -357,7 +357,7 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
* Called when I frame data arrives. We did the work above - throw it
* at the net layer.
*/
-
+
static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
{
skb->dev->last_rx = jiffies;
@@ -369,24 +369,22 @@ static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
* busy cases too well. Its tricky to see how to do this nicely -
* perhaps lapb should allow us to bounce this ?
*/
-
+
static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
{
- struct x25_asy *sl=dev->priv;
-
+ struct x25_asy *sl = dev->priv;
+
spin_lock(&sl->lock);
- if (netif_queue_stopped(sl->dev) || sl->tty == NULL)
- {
+ if (netif_queue_stopped(sl->dev) || sl->tty == NULL) {
spin_unlock(&sl->lock);
printk(KERN_ERR "x25_asy: tbusy drop\n");
kfree_skb(skb);
return;
}
/* We were not busy, so we are now... :-) */
- if (skb != NULL)
- {
+ if (skb != NULL) {
x25_asy_lock(sl);
- sl->stats.tx_bytes+=skb->len;
+ sl->stats.tx_bytes += skb->len;
x25_asy_encaps(sl, skb->data, skb->len);
dev_kfree_skb(skb);
}
@@ -396,15 +394,16 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
/*
* LAPB connection establish/down information.
*/
-
+
static void x25_asy_connected(struct net_device *dev, int reason)
{
struct x25_asy *sl = dev->priv;
struct sk_buff *skb;
unsigned char *ptr;
- if ((skb = dev_alloc_skb(1)) == NULL) {
- printk(KERN_ERR "lapbeth: out of memory\n");
+ skb = dev_alloc_skb(1);
+ if (skb == NULL) {
+ printk(KERN_ERR "x25_asy: out of memory\n");
return;
}
@@ -422,7 +421,8 @@ static void x25_asy_disconnected(struct net_device *dev, int reason)
struct sk_buff *skb;
unsigned char *ptr;
- if ((skb = dev_alloc_skb(1)) == NULL) {
+ skb = dev_alloc_skb(1);
+ if (skb == NULL) {
printk(KERN_ERR "x25_asy: out of memory\n");
return;
}
@@ -449,7 +449,7 @@ static struct lapb_register_struct x25_asy_callbacks = {
/* Open the low-level part of the X.25 channel. Easy! */
static int x25_asy_open(struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+ struct x25_asy *sl = dev->priv;
unsigned long len;
int err;
@@ -466,13 +466,11 @@ static int x25_asy_open(struct net_device *dev)
len = dev->mtu * 2;
sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
- if (sl->rbuff == NULL) {
+ if (sl->rbuff == NULL)
goto norbuff;
- }
sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
- if (sl->xbuff == NULL) {
+ if (sl->xbuff == NULL)
goto noxbuff;
- }
sl->buffsize = len;
sl->rcount = 0;
@@ -480,11 +478,12 @@ static int x25_asy_open(struct net_device *dev)
sl->flags &= (1 << SLF_INUSE); /* Clear ESCAPE & ERROR flags */
netif_start_queue(dev);
-
+
/*
* Now attach LAPB
*/
- if((err=lapb_register(dev, &x25_asy_callbacks))==LAPB_OK)
+ err = lapb_register(dev, &x25_asy_callbacks);
+ if (err == LAPB_OK)
return 0;
/* Cleanup */
@@ -499,18 +498,20 @@ norbuff:
/* Close the low-level part of the X.25 channel. Easy! */
static int x25_asy_close(struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
+ struct x25_asy *sl = dev->priv;
int err;
spin_lock(&sl->lock);
- if (sl->tty)
+ if (sl->tty)
sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
netif_stop_queue(dev);
sl->rcount = 0;
sl->xleft = 0;
- if((err=lapb_unregister(dev))!=LAPB_OK)
- printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err);
+ err = lapb_unregister(dev);
+ if (err != LAPB_OK)
+ printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
+ err);
spin_unlock(&sl->lock);
return 0;
}
@@ -521,8 +522,9 @@ static int x25_asy_close(struct net_device *dev)
* a block of X.25 data has been received, which can now be decapsulated
* and sent on to some IP layer for further processing.
*/
-
-static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
+
+static void x25_asy_receive_buf(struct tty_struct *tty,
+ const unsigned char *cp, char *fp, int count)
{
struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
@@ -533,9 +535,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp,
/* Read the characters out of the buffer */
while (count--) {
if (fp && *fp++) {
- if (!test_and_set_bit(SLF_ERROR, &sl->flags)) {
+ if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->stats.rx_errors++;
- }
cp++;
continue;
}
@@ -556,31 +557,31 @@ static int x25_asy_open_tty(struct tty_struct *tty)
struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
int err;
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
/* First make sure we're not already connected. */
- if (sl && sl->magic == X25_ASY_MAGIC) {
+ if (sl && sl->magic == X25_ASY_MAGIC)
return -EEXIST;
- }
/* OK. Find a free X.25 channel to use. */
- if ((sl = x25_asy_alloc()) == NULL) {
+ sl = x25_asy_alloc();
+ if (sl == NULL)
return -ENFILE;
- }
sl->tty = tty;
tty->disc_data = sl;
tty->receive_room = 65536;
- if (tty->driver->flush_buffer) {
- tty->driver->flush_buffer(tty);
- }
+ tty_driver_flush_buffer(tty);
tty_ldisc_flush(tty);
/* Restore default settings */
sl->dev->type = ARPHRD_X25;
-
+
/* Perform the low-level X.25 async init */
- if ((err = x25_asy_open(sl->dev)))
+ err = x25_asy_open(sl->dev);
+ if (err)
return err;
-
/* Done. We have linked the TTY line to a channel. */
return sl->dev->base_addr;
}
@@ -601,9 +602,7 @@ static void x25_asy_close_tty(struct tty_struct *tty)
return;
if (sl->dev->flags & IFF_UP)
- {
- (void) dev_close(sl->dev);
- }
+ dev_close(sl->dev);
tty->disc_data = NULL;
sl->tty = NULL;
@@ -613,8 +612,7 @@ static void x25_asy_close_tty(struct tty_struct *tty)
static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
-
+ struct x25_asy *sl = dev->priv;
return &sl->stats;
}
@@ -641,21 +639,19 @@ int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
* character sequence, according to the X.25 protocol.
*/
- while (len-- > 0)
- {
- switch(c = *s++)
- {
- case X25_END:
- *ptr++ = X25_ESC;
- *ptr++ = X25_ESCAPE(X25_END);
- break;
- case X25_ESC:
- *ptr++ = X25_ESC;
- *ptr++ = X25_ESCAPE(X25_ESC);
- break;
- default:
- *ptr++ = c;
- break;
+ while (len-- > 0) {
+ switch (c = *s++) {
+ case X25_END:
+ *ptr++ = X25_ESC;
+ *ptr++ = X25_ESCAPE(X25_END);
+ break;
+ case X25_ESC:
+ *ptr++ = X25_ESC;
+ *ptr++ = X25_ESCAPE(X25_ESC);
+ break;
+ default:
+ *ptr++ = c;
+ break;
}
}
*ptr++ = X25_END;
@@ -665,31 +661,25 @@ int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
{
- switch(s)
- {
- case X25_END:
- if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))
- {
- x25_asy_bump(sl);
- }
- clear_bit(SLF_ESCAPE, &sl->flags);
- sl->rcount = 0;
- return;
-
- case X25_ESC:
- set_bit(SLF_ESCAPE, &sl->flags);
- return;
-
- case X25_ESCAPE(X25_ESC):
- case X25_ESCAPE(X25_END):
- if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
- s = X25_UNESCAPE(s);
- break;
- }
- if (!test_bit(SLF_ERROR, &sl->flags))
- {
- if (sl->rcount < sl->buffsize)
- {
+ switch (s) {
+ case X25_END:
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
+ && sl->rcount > 2)
+ x25_asy_bump(sl);
+ clear_bit(SLF_ESCAPE, &sl->flags);
+ sl->rcount = 0;
+ return;
+ case X25_ESC:
+ set_bit(SLF_ESCAPE, &sl->flags);
+ return;
+ case X25_ESCAPE(X25_ESC):
+ case X25_ESCAPE(X25_END):
+ if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
+ s = X25_UNESCAPE(s);
+ break;
+ }
+ if (!test_bit(SLF_ERROR, &sl->flags)) {
+ if (sl->rcount < sl->buffsize) {
sl->rbuff[sl->rcount++] = s;
return;
}
@@ -709,7 +699,7 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
if (!sl || sl->magic != X25_ASY_MAGIC)
return -EINVAL;
- switch(cmd) {
+ switch (cmd) {
case SIOCGIFNAME:
if (copy_to_user((void __user *)arg, sl->dev->name,
strlen(sl->dev->name) + 1))
@@ -724,8 +714,8 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
static int x25_asy_open_dev(struct net_device *dev)
{
- struct x25_asy *sl = (struct x25_asy*)(dev->priv);
- if(sl->tty==NULL)
+ struct x25_asy *sl = dev->priv;
+ if (sl->tty == NULL)
return -ENODEV;
return 0;
}
@@ -741,9 +731,9 @@ static void x25_asy_setup(struct net_device *dev)
set_bit(SLF_INUSE, &sl->flags);
/*
- * Finish setting up the DEVICE info.
+ * Finish setting up the DEVICE info.
*/
-
+
dev->mtu = SL_MTU;
dev->hard_start_xmit = x25_asy_xmit;
dev->tx_timeout = x25_asy_timeout;
@@ -778,9 +768,10 @@ static int __init init_x25_asy(void)
x25_asy_maxdev = 4; /* Sanity */
printk(KERN_INFO "X.25 async: version 0.00 ALPHA "
- "(dynamic channels, max=%d).\n", x25_asy_maxdev );
+ "(dynamic channels, max=%d).\n", x25_asy_maxdev);
- x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device*), GFP_KERNEL);
+ x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *),
+ GFP_KERNEL);
if (!x25_asy_devs) {
printk(KERN_WARNING "X25 async: Can't allocate x25_asy_ctrls[] "
"array! Uaargh! (-> No X.25 available)\n");
@@ -802,7 +793,7 @@ static void __exit exit_x25_asy(void)
struct x25_asy *sl = dev->priv;
spin_lock_bh(&sl->lock);
- if (sl->tty)
+ if (sl->tty)
tty_hangup(sl->tty);
spin_unlock_bh(&sl->lock);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index bced3fe1cf8..5dd23c93497 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -768,41 +768,17 @@ static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
/* General routines for STRIP */
/*
- * get_baud returns the current baud rate, as one of the constants defined in
- * termbits.h
- * If the user has issued a baud rate override using the 'setserial' command
- * and the logical current rate is set to 38.4, then the true baud rate
- * currently in effect (57.6 or 115.2) is returned.
- */
-static unsigned int get_baud(struct tty_struct *tty)
-{
- if (!tty || !tty->termios)
- return (0);
- if ((tty->termios->c_cflag & CBAUD) == B38400 && tty->driver_data) {
- struct async_struct *info =
- (struct async_struct *) tty->driver_data;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- return (B57600);
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- return (B115200);
- }
- return (tty->termios->c_cflag & CBAUD);
-}
-
-/*
* set_baud sets the baud rate to the rate defined by baudcode
- * Note: The rate B38400 should be avoided, because the user may have
- * issued a 'setserial' speed override to map that to a different speed.
- * We could achieve a true rate of 38400 if we needed to by cancelling
- * any user speed override that is in place, but that might annoy the
- * user, so it is simplest to just avoid using 38400.
*/
-static void set_baud(struct tty_struct *tty, unsigned int baudcode)
+static void set_baud(struct tty_struct *tty, speed_t baudrate)
{
- struct ktermios old_termios = *(tty->termios);
- tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */
- tty->termios->c_cflag |= baudcode; /* Set the new baud setting */
- tty->driver->set_termios(tty, &old_termios);
+ struct ktermios old_termios;
+
+ mutex_lock(&tty->termios_mutex);
+ old_termios =*(tty->termios);
+ tty_encode_baud_rate(tty, baudrate, baudrate);
+ tty->ops->set_termios(tty, &old_termios);
+ mutex_unlock(&tty->termios_mutex);
}
/*
@@ -1217,7 +1193,7 @@ static void ResetRadio(struct strip *strip_info)
strip_info->watchdog_doreset = jiffies + 1 * HZ;
/* If the user has selected a baud rate above 38.4 see what magic we have to do */
- if (strip_info->user_baud > B38400) {
+ if (strip_info->user_baud > 38400) {
/*
* Subtle stuff: Pay attention :-)
* If the serial port is currently at the user's selected (>38.4) rate,
@@ -1227,17 +1203,17 @@ static void ResetRadio(struct strip *strip_info)
* issued the ATS304 command last time through, so this time we restore
* the user's selected rate and issue the normal starmode reset string.
*/
- if (strip_info->user_baud == get_baud(tty)) {
+ if (strip_info->user_baud == tty_get_baud_rate(tty)) {
static const char b0[] = "ate0q1s304=57600\r";
static const char b1[] = "ate0q1s304=115200\r";
static const StringDescriptor baudstring[2] =
{ {b0, sizeof(b0) - 1}
, {b1, sizeof(b1) - 1}
};
- set_baud(tty, B19200);
- if (strip_info->user_baud == B57600)
+ set_baud(tty, 19200);
+ if (strip_info->user_baud == 57600)
s = baudstring[0];
- else if (strip_info->user_baud == B115200)
+ else if (strip_info->user_baud == 115200)
s = baudstring[1];
else
s = baudstring[1]; /* For now */
@@ -1245,7 +1221,7 @@ static void ResetRadio(struct strip *strip_info)
set_baud(tty, strip_info->user_baud);
}
- tty->driver->write(tty, s.string, s.length);
+ tty->ops->write(tty, s.string, s.length);
#ifdef EXT_COUNTERS
strip_info->tx_ebytes += s.length;
#endif
@@ -1267,7 +1243,7 @@ static void strip_write_some_more(struct tty_struct *tty)
if (strip_info->tx_left > 0) {
int num_written =
- tty->driver->write(tty, strip_info->tx_head,
+ tty->ops->write(tty, strip_info->tx_head,
strip_info->tx_left);
strip_info->tx_left -= num_written;
strip_info->tx_head += num_written;
@@ -2457,7 +2433,7 @@ static int strip_open_low(struct net_device *dev)
strip_info->working = FALSE;
strip_info->firmware_level = NoStructure;
strip_info->next_command = CompatibilityCommand;
- strip_info->user_baud = get_baud(strip_info->tty);
+ strip_info->user_baud = tty_get_baud_rate(strip_info->tty);
printk(KERN_INFO "%s: Initializing Radio.\n",
strip_info->dev->name);
@@ -2632,6 +2608,13 @@ static int strip_open(struct tty_struct *tty)
return -EEXIST;
/*
+ * We need a write method.
+ */
+
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
+ /*
* OK. Find a free STRIP channel to use.
*/
if ((strip_info = strip_alloc()) == NULL)
@@ -2652,8 +2635,7 @@ static int strip_open(struct tty_struct *tty)
tty->disc_data = strip_info;
tty->receive_room = 65536;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
/*
* Restore default settings
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index 54a6ef72906..0338b091267 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -76,7 +76,7 @@ int parport_wait_event (struct parport *port, signed long timeout)
semaphore. */
return 1;
- init_timer (&timer);
+ init_timer_on_stack(&timer);
timer.expires = jiffies + timeout;
timer.function = timeout_waiting_on_port;
port_from_cookie[port->number % PARPORT_MAX] = port;
@@ -88,6 +88,8 @@ int parport_wait_event (struct parport *port, signed long timeout)
/* Timed out. */
ret = 1;
+ destroy_timer_on_stack(&timer);
+
return ret;
}
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
index 0e77ae2b71a..e6a7e847ee8 100644
--- a/drivers/parport/parport_gsc.c
+++ b/drivers/parport/parport_gsc.c
@@ -365,11 +365,11 @@ static int __devinit parport_init_chip(struct parisc_device *dev)
if (boot_cpu_data.cpu_type > pcxt && !pdc_add_valid(port+4)) {
/* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
- printk("%s: initialize bidirectional-mode.\n", __FUNCTION__);
+ printk("%s: initialize bidirectional-mode.\n", __func__);
parport_writeb ( (0x10 + 0x20), port + 4);
} else {
- printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__);
+ printk("%s: enhanced parport-modes not supported.\n", __func__);
}
p = parport_gsc_probe_port(port, 0, dev->irq,
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index e71092e8028..e0c2a4584ec 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -1415,7 +1415,7 @@ static void __devinit winbond_check(int io, int key)
{
int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
- if (!request_region(io, 3, __FUNCTION__))
+ if (!request_region(io, 3, __func__))
return;
/* First probe without key */
@@ -1449,7 +1449,7 @@ static void __devinit winbond_check2(int io,int key)
{
int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
- if (!request_region(io, 3, __FUNCTION__))
+ if (!request_region(io, 3, __func__))
return;
/* First probe without the key */
@@ -1482,7 +1482,7 @@ static void __devinit smsc_check(int io, int key)
{
int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;
- if (!request_region(io, 3, __FUNCTION__))
+ if (!request_region(io, 3, __func__))
return;
/* First probe without the key */
@@ -1547,7 +1547,7 @@ static void __devinit detect_and_report_it87(void)
u8 r;
if (verbose_probing)
printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
- if (!request_region(0x2e, 1, __FUNCTION__))
+ if (!request_region(0x2e, 1, __func__))
return;
outb(0x87, 0x2e);
outb(0x01, 0x2e);
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 0e1f35c9ed9..3e5653c92f4 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -982,15 +982,16 @@ tty3215_write(struct tty_struct * tty,
/*
* Put character routine for 3215 ttys
*/
-static void
+static int
tty3215_put_char(struct tty_struct *tty, unsigned char ch)
{
struct raw3215_info *raw;
if (!tty)
- return;
+ return 0;
raw = (struct raw3215_info *) tty->driver_data;
raw3215_putchar(raw, ch);
+ return 1;
}
static void
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index e3b3d390b4a..40b11521cd2 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -412,14 +412,14 @@ sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
* - including previous characters from sclp_tty_put_char() and strings from
* sclp_write() without final '\n' - will be written.
*/
-static void
+static int
sclp_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
sclp_tty_chars[sclp_tty_chars_count++] = ch;
if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) {
sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
sclp_tty_chars_count = 0;
- }
+ } return 1;
}
/*
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index ed507594e62..35707c04e61 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -524,11 +524,15 @@ sclp_vt220_close(struct tty_struct *tty, struct file *filp)
* NOTE: include/linux/tty_driver.h specifies that a character should be
* ignored if there is no room in the queue. This driver implements a different
* semantic in that it will block when there is no more room left.
+ *
+ * FIXME: putchar can currently be called from BH and other non blocking
+ * handlers so this semantic isn't a good idea.
*/
-static void
+static int
sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch)
{
__sclp_vt220_write(&ch, 1, 0, 0, 1);
+ return 1;
}
/*
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 70b1980a08b..c1f2adefad4 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -965,7 +965,7 @@ tty3270_write_room(struct tty_struct *tty)
* Insert character into the screen at the current position with the
* current color and highlight. This function does NOT do cursor movement.
*/
-static void
+static int
tty3270_put_character(struct tty3270 *tp, char ch)
{
struct tty3270_line *line;
@@ -986,6 +986,7 @@ tty3270_put_character(struct tty3270 *tp, char ch)
cell->character = tp->view.ascebc[(unsigned int) ch];
cell->highlight = tp->highlight;
cell->f_color = tp->f_color;
+ return 1;
}
/*
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index a4e75814366..23570341437 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -637,7 +637,7 @@ static int wd_inittimer(int whichdog)
break;
default:
printk("%s: %s: invalid watchdog id: %i\n",
- WD_OBPNAME, __FUNCTION__, whichdog);
+ WD_OBPNAME, __func__, whichdog);
return(1);
}
if(0 != misc_register(whichmisc))
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 44d2ef906ac..383f32c1d34 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -393,13 +393,13 @@ static int __init ts102_uctrl_init(void)
err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
if (err) {
printk("%s: unable to register irq %d\n",
- __FUNCTION__, driver->irq);
+ __func__, driver->irq);
return err;
}
if (misc_register(&uctrl_dev)) {
printk("%s: unable to get misc minor %d\n",
- __FUNCTION__, uctrl_dev.minor);
+ __func__, uctrl_dev.minor);
free_irq(driver->irq, driver);
return -ENODEV;
}
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 2b8a410e095..bbf5bc5892c 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -200,7 +200,7 @@ static void rs_stop(struct tty_struct *tty)
local_irq_restore(flags);
}
-static void rs_put_char(char ch)
+static int rs_put_char(char ch)
{
int flags, loops = 0;
@@ -214,6 +214,7 @@ static void rs_put_char(char ch)
UTX_TXDATA = ch;
udelay(5);
local_irq_restore(flags);
+ return 1;
}
static void rs_start(struct tty_struct *tty)
@@ -1017,18 +1018,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
tty_wait_until_sent(tty, 0);
send_break(info, arg ? arg*(100) : 250);
return 0;
- case TIOCGSOFTCAR:
- error = put_user(C_CLOCAL(tty) ? 1 : 0,
- (unsigned long *) arg);
- if (error)
- return error;
- return 0;
- case TIOCSSOFTCAR:
- get_user(arg, (unsigned long *) arg);
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
case TIOCGSERIAL:
if (access_ok(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct)))
@@ -1061,9 +1050,6 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
- if (tty->termios->c_cflag == old_termios->c_cflag)
- return;
-
change_speed(info);
if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1140,8 +1126,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK);
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ rs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index f5946360187..d9d4e9552a4 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -995,10 +995,10 @@ static void rs_360_put_char(struct tty_struct *tty, unsigned char ch)
volatile QUICC_BD *bdp;
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
- return;
+ return 0;
if (!tty)
- return;
+ return 0;
bdp = info->tx_cur;
while (bdp->status & BD_SC_READY);
@@ -1016,6 +1016,7 @@ static void rs_360_put_char(struct tty_struct *tty, unsigned char ch)
bdp++;
info->tx_cur = (QUICC_BD *)bdp;
+ return 1;
}
@@ -1246,7 +1247,7 @@ static int rs_360_tiocmget(struct tty_struct *tty, struct file *file)
#ifdef modem_control
unsigned char control, status;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
@@ -1277,12 +1278,12 @@ static int rs_360_tiocmset(struct tty_struct *tty, struct file *file,
ser_info_t *info = (ser_info_t *)tty->driver_data;
unsigned int arg;
- if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+ if (serial_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
-
+ /* FIXME: locking on info->mcr */
if (set & TIOCM_RTS)
info->mcr |= UART_MCR_RTS;
if (set & TIOCM_DTR)
@@ -1436,18 +1437,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
return retval;
end_break(info);
return 0;
- case TIOCGSOFTCAR:
- /* return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); */
- put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
- return 0;
- case TIOCSSOFTCAR:
- error = get_user(arg, (unsigned int *) arg);
- if (error)
- return error;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
#ifdef maybe
case TIOCSERGETLSR: /* Get line status register */
return get_lsr_info(info, (unsigned int *) arg);
@@ -1665,8 +1654,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
rs_360_wait_until_sent(tty, info->timeout);
}
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ rs_360_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
@@ -1717,6 +1705,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
printk("jiff=%lu...", jiffies);
#endif
+ lock_kernel();
/* We go through the loop at least once because we can't tell
* exactly when the last character exits the shifter. There can
* be at least two characters waiting to be sent after the buffers
@@ -1745,6 +1734,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
bdp--;
} while (bdp->status & BD_SC_READY);
current->state = TASK_RUNNING;
+ unlock_kernel();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index 38776e8b064..cd898704ba4 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -156,7 +156,7 @@ static int __init parse_options(struct early_serial8250_device *device,
port->membase = ioremap(port->mapbase, 64);
if (!port->membase) {
printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
- __FUNCTION__,
+ __func__,
(unsigned long long)port->mapbase);
return -ENOMEM;
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 34b809e3b59..36acbcca2d4 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1355,4 +1355,47 @@ config SERIAL_SC26XX_CONSOLE
help
Support for Console on SC2681/SC2692 serial ports.
+config SERIAL_BFIN_SPORT
+ tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)"
+ depends on BFIN && EXPERIMENTAL
+ select SERIAL_CORE
+ help
+ Enble support SPORT emulate UART on Blackfin series.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_sport_uart.
+
+choice
+ prompt "Baud rate for Blackfin SPORT UART"
+ depends on SERIAL_BFIN_SPORT
+ default SERIAL_SPORT_BAUD_RATE_57600
+ help
+ Choose a baud rate for the SPORT UART, other uart settings are
+ 8 bit, 1 stop bit, no parity, no flow control.
+
+config SERIAL_SPORT_BAUD_RATE_115200
+ bool "115200"
+
+config SERIAL_SPORT_BAUD_RATE_57600
+ bool "57600"
+
+config SERIAL_SPORT_BAUD_RATE_38400
+ bool "38400"
+
+config SERIAL_SPORT_BAUD_RATE_19200
+ bool "19200"
+
+config SERIAL_SPORT_BAUD_RATE_9600
+ bool "9600"
+endchoice
+
+config SPORT_BAUD_RATE
+ int
+ depends on SERIAL_BFIN_SPORT
+ default 115200 if (SERIAL_SPORT_BAUD_RATE_115200)
+ default 57600 if (SERIAL_SPORT_BAUD_RATE_57600)
+ default 38400 if (SERIAL_SPORT_BAUD_RATE_38400)
+ default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
+ default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index f02ff9fad01..0d9c09b1e83 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SERIAL_PXA) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
+obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 5f55534a290..8a2f6a1baa7 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -762,7 +762,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
break;
default:
printk(KERN_ERR "%s: word lengh not supported\n",
- __FUNCTION__);
+ __func__);
}
if (termios->c_cflag & CSTOPB)
@@ -1029,7 +1029,7 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
*baud = get_sclk() / (16*(dll | dlh << 8));
}
- pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
+ pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __func__, *baud, *parity, *bits);
}
#endif
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
new file mode 100644
index 00000000000..aca1240ad80
--- /dev/null
+++ b/drivers/serial/bfin_sport_uart.c
@@ -0,0 +1,614 @@
+/*
+ * File: linux/drivers/serial/bfin_sport_uart.c
+ *
+ * Based on: drivers/serial/bfin_5xx.c by Aubrey Li.
+ * Author: Roy Huang <roy.huang@analog.com>
+ *
+ * Created: Nov 22, 2006
+ * Copyright: (c) 2006-2007 Analog Devices Inc.
+ * Description: this driver enable SPORTs on Blackfin emulate UART.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This driver and the hardware supported are in term of EE-191 of ADI.
+ * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
+ * This application note describe how to implement a UART on a Sharc DSP,
+ * but this driver is implemented on Blackfin Processor.
+ */
+
+/* After reset, there is a prelude of low level pulse when transmit data first
+ * time. No addtional pulse in following transmit.
+ * According to document:
+ * The SPORTs are ready to start transmitting or receiving data no later than
+ * three serial clock cycles after they are enabled in the SPORTx_TCR1 or
+ * SPORTx_RCR1 register. No serial clock cycles are lost from this point on.
+ * The first internal frame sync will occur one frame sync delay after the
+ * SPORTs are ready. External frame syncs can occur as soon as the SPORT is
+ * ready.
+ */
+
+/* Thanks to Axel Alatalo <axel@rubico.se> for fixing sport rx bug. Sometimes
+ * sport receives data incorrectly. The following is Axel's words.
+ * As EE-191, sport rx samples 3 times of the UART baudrate and takes the
+ * middle smaple of every 3 samples as the data bit. For a 8-N-1 UART setting,
+ * 30 samples will be required for a byte. If transmitter sends a 1/3 bit short
+ * byte due to buadrate drift, then the 30th sample of a byte, this sample is
+ * also the third sample of the stop bit, will happens on the immediately
+ * following start bit which will be thrown away and missed. Thus since parts
+ * of the startbit will be missed and the receiver will begin to drift, the
+ * effect accumulates over time until synchronization is lost.
+ * If only require 2 samples of the stopbit (by sampling in total 29 samples),
+ * then a to short byte as in the case above will be tolerated. Then the 1/3
+ * early startbit will trigger a framesync since the last read is complete
+ * after only 2/3 stopbit and framesync is active during the last 1/3 looking
+ * for a possible early startbit. */
+
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+
+#include <asm/delay.h>
+#include <asm/portmux.h>
+
+#include "bfin_sport_uart.h"
+
+unsigned short bfin_uart_pin_req_sport0[] =
+ {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0};
+
+unsigned short bfin_uart_pin_req_sport1[] =
+ {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0};
+
+#define DRV_NAME "bfin-sport-uart"
+
+struct sport_uart_port {
+ struct uart_port port;
+ char *name;
+
+ int tx_irq;
+ int rx_irq;
+ int err_irq;
+};
+
+static void sport_uart_tx_chars(struct sport_uart_port *up);
+static void sport_stop_tx(struct uart_port *port);
+
+static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
+{
+ pr_debug("%s value:%x\n", __FUNCTION__, value);
+ /* Place a Start and Stop bit */
+ __asm__ volatile (
+ "R2 = b#01111111100;\n\t"
+ "R3 = b#10000000001;\n\t"
+ "%0 <<= 2;\n\t"
+ "%0 = %0 & R2;\n\t"
+ "%0 = %0 | R3;\n\t"
+ :"=r"(value)
+ :"0"(value)
+ :"R2", "R3");
+ pr_debug("%s value:%x\n", __FUNCTION__, value);
+
+ SPORT_PUT_TX(up, value);
+}
+
+static inline unsigned int rx_one_byte(struct sport_uart_port *up)
+{
+ unsigned int value, extract;
+
+ value = SPORT_GET_RX32(up);
+ pr_debug("%s value:%x\n", __FUNCTION__, value);
+
+ /* Extract 8 bits data */
+ __asm__ volatile (
+ "R5 = 0;\n\t"
+ "P0 = 8;\n\t"
+ "R1 = 0x1801(Z);\n\t"
+ "R3 = 0x0300(Z);\n\t"
+ "R4 = 0;\n\t"
+ "LSETUP(loop_s, loop_e) LC0 = P0;\nloop_s:\t"
+ "R2 = extract(%1, R1.L)(Z);\n\t"
+ "R2 <<= R4;\n\t"
+ "R5 = R5 | R2;\n\t"
+ "R1 = R1 - R3;\nloop_e:\t"
+ "R4 += 1;\n\t"
+ "%0 = R5;\n\t"
+ :"=r"(extract)
+ :"r"(value)
+ :"P0", "R1", "R2","R3","R4", "R5");
+
+ pr_debug(" extract:%x\n", extract);
+ return extract;
+}
+
+static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
+{
+ int tclkdiv, tfsdiv, rclkdiv;
+
+ /* Set TCR1 and TCR2 */
+ SPORT_PUT_TCR1(up, (LTFS | ITFS | TFSR | TLSBIT | ITCLK));
+ SPORT_PUT_TCR2(up, 10);
+ pr_debug("%s TCR1:%x, TCR2:%x\n", __FUNCTION__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up));
+
+ /* Set RCR1 and RCR2 */
+ SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK));
+ SPORT_PUT_RCR2(up, 28);
+ pr_debug("%s RCR1:%x, RCR2:%x\n", __FUNCTION__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up));
+
+ tclkdiv = sclk/(2 * baud_rate) - 1;
+ tfsdiv = 12;
+ rclkdiv = sclk/(2 * baud_rate * 3) - 1;
+ SPORT_PUT_TCLKDIV(up, tclkdiv);
+ SPORT_PUT_TFSDIV(up, tfsdiv);
+ SPORT_PUT_RCLKDIV(up, rclkdiv);
+ SSYNC();
+ pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n",
+ __FUNCTION__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv);
+
+ return 0;
+}
+
+static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
+{
+ struct sport_uart_port *up = dev_id;
+ struct tty_struct *tty = up->port.info->tty;
+ unsigned int ch;
+
+ do {
+ ch = rx_one_byte(up);
+ up->port.icount.rx++;
+
+ if (uart_handle_sysrq_char(&up->port, ch))
+ ;
+ else
+ tty_insert_flip_char(tty, ch, TTY_NORMAL);
+ } while (SPORT_GET_STAT(up) & RXNE);
+ tty_flip_buffer_push(tty);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
+{
+ sport_uart_tx_chars(dev_id);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
+{
+ struct sport_uart_port *up = dev_id;
+ struct tty_struct *tty = up->port.info->tty;
+ unsigned int stat = SPORT_GET_STAT(up);
+
+ /* Overflow in RX FIFO */
+ if (stat & ROVF) {
+ up->port.icount.overrun++;
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */
+ }
+ /* These should not happen */
+ if (stat & (TOVF | TUVF | RUVF)) {
+ printk(KERN_ERR "SPORT Error:%s %s %s\n",
+ (stat & TOVF)?"TX overflow":"",
+ (stat & TUVF)?"TX underflow":"",
+ (stat & RUVF)?"RX underflow":"");
+ SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
+ SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
+ }
+ SSYNC();
+
+ return IRQ_HANDLED;
+}
+
+/* Reqeust IRQ, Setup clock */
+static int sport_startup(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+ char buffer[20];
+ int retval;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ memset(buffer, 20, '\0');
+ snprintf(buffer, 20, "%s rx", up->name);
+ retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up);
+ if (retval) {
+ printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
+ return retval;
+ }
+
+ snprintf(buffer, 20, "%s tx", up->name);
+ retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up);
+ if (retval) {
+ printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
+ goto fail1;
+ }
+
+ snprintf(buffer, 20, "%s err", up->name);
+ retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up);
+ if (retval) {
+ printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
+ goto fail2;
+ }
+
+ if (port->line) {
+ if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME))
+ goto fail3;
+ } else {
+ if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME))
+ goto fail3;
+ }
+
+ sport_uart_setup(up, get_sclk(), port->uartclk);
+
+ /* Enable receive interrupt */
+ SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN));
+ SSYNC();
+
+ return 0;
+
+
+fail3:
+ printk(KERN_ERR DRV_NAME
+ ": Requesting Peripherals failed\n");
+
+ free_irq(up->err_irq, up);
+fail2:
+ free_irq(up->tx_irq, up);
+fail1:
+ free_irq(up->rx_irq, up);
+
+ return retval;
+
+}
+
+static void sport_uart_tx_chars(struct sport_uart_port *up)
+{
+ struct circ_buf *xmit = &up->port.info->xmit;
+
+ if (SPORT_GET_STAT(up) & TXF)
+ return;
+
+ if (up->port.x_char) {
+ tx_one_byte(up, up->port.x_char);
+ up->port.icount.tx++;
+ up->port.x_char = 0;
+ return;
+ }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+ sport_stop_tx(&up->port);
+ return;
+ }
+
+ while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) {
+ tx_one_byte(up, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
+ up->port.icount.tx++;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&up->port);
+}
+
+static unsigned int sport_tx_empty(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+ unsigned int stat;
+
+ stat = SPORT_GET_STAT(up);
+ pr_debug("%s stat:%04x\n", __FUNCTION__, stat);
+ if (stat & TXHRE) {
+ return TIOCSER_TEMT;
+ } else
+ return 0;
+}
+
+static unsigned int sport_get_mctrl(struct uart_port *port)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+ return (TIOCM_CTS | TIOCM_CD | TIOCM_DSR);
+}
+
+static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+}
+
+static void sport_stop_tx(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+ unsigned int stat;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+
+ stat = SPORT_GET_STAT(up);
+ while(!(stat & TXHRE)) {
+ udelay(1);
+ stat = SPORT_GET_STAT(up);
+ }
+ /* Although the hold register is empty, last byte is still in shift
+ * register and not sent out yet. If baud rate is lower than default,
+ * delay should be longer. For example, if the baud rate is 9600,
+ * the delay must be at least 2ms by experience */
+ udelay(500);
+
+ SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
+ SSYNC();
+
+ return;
+}
+
+static void sport_start_tx(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ /* Write data into SPORT FIFO before enable SPROT to transmit */
+ sport_uart_tx_chars(up);
+
+ /* Enable transmit, then an interrupt will generated */
+ SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
+ SSYNC();
+ pr_debug("%s exit\n", __FUNCTION__);
+}
+
+static void sport_stop_rx(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ /* Disable sport to stop rx */
+ SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
+ SSYNC();
+}
+
+static void sport_enable_ms(struct uart_port *port)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+}
+
+static void sport_break_ctl(struct uart_port *port, int break_state)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+}
+
+static void sport_shutdown(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+
+ /* Disable sport */
+ SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
+ SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
+ SSYNC();
+
+ if (port->line) {
+ peripheral_free_list(bfin_uart_pin_req_sport1);
+ } else {
+ peripheral_free_list(bfin_uart_pin_req_sport0);
+ }
+
+ free_irq(up->rx_irq, up);
+ free_irq(up->tx_irq, up);
+ free_irq(up->err_irq, up);
+}
+
+static void sport_set_termios(struct uart_port *port,
+ struct termios *termios, struct termios *old)
+{
+ pr_debug("%s enter, c_cflag:%08x\n", __FUNCTION__, termios->c_cflag);
+ uart_update_timeout(port, CS8 ,port->uartclk);
+}
+
+static const char *sport_type(struct uart_port *port)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ return up->name;
+}
+
+static void sport_release_port(struct uart_port *port)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+}
+
+static int sport_request_port(struct uart_port *port)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+ return 0;
+}
+
+static void sport_config_port(struct uart_port *port, int flags)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)port;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ up->port.type = PORT_BFIN_SPORT;
+}
+
+static int sport_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+ return 0;
+}
+
+struct uart_ops sport_uart_ops = {
+ .tx_empty = sport_tx_empty,
+ .set_mctrl = sport_set_mctrl,
+ .get_mctrl = sport_get_mctrl,
+ .stop_tx = sport_stop_tx,
+ .start_tx = sport_start_tx,
+ .stop_rx = sport_stop_rx,
+ .enable_ms = sport_enable_ms,
+ .break_ctl = sport_break_ctl,
+ .startup = sport_startup,
+ .shutdown = sport_shutdown,
+ .set_termios = sport_set_termios,
+ .type = sport_type,
+ .release_port = sport_release_port,
+ .request_port = sport_request_port,
+ .config_port = sport_config_port,
+ .verify_port = sport_verify_port,
+};
+
+static struct sport_uart_port sport_uart_ports[] = {
+ { /* SPORT 0 */
+ .name = "SPORT0",
+ .tx_irq = IRQ_SPORT0_TX,
+ .rx_irq = IRQ_SPORT0_RX,
+ .err_irq= IRQ_SPORT0_ERROR,
+ .port = {
+ .type = PORT_BFIN_SPORT,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)SPORT0_TCR1,
+ .mapbase = SPORT0_TCR1,
+ .irq = IRQ_SPORT0_RX,
+ .uartclk = CONFIG_SPORT_BAUD_RATE,
+ .fifosize = 8,
+ .ops = &sport_uart_ops,
+ .line = 0,
+ },
+ }, { /* SPORT 1 */
+ .name = "SPORT1",
+ .tx_irq = IRQ_SPORT1_TX,
+ .rx_irq = IRQ_SPORT1_RX,
+ .err_irq= IRQ_SPORT1_ERROR,
+ .port = {
+ .type = PORT_BFIN_SPORT,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)SPORT1_TCR1,
+ .mapbase = SPORT1_TCR1,
+ .irq = IRQ_SPORT1_RX,
+ .uartclk = CONFIG_SPORT_BAUD_RATE,
+ .fifosize = 8,
+ .ops = &sport_uart_ops,
+ .line = 1,
+ },
+ }
+};
+
+static struct uart_driver sport_uart_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "SPORT-UART",
+ .dev_name = "ttySS",
+ .major = 204,
+ .minor = 84,
+ .nr = ARRAY_SIZE(sport_uart_ports),
+ .cons = NULL,
+};
+
+static int sport_uart_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct sport_uart_port *sport = platform_get_drvdata(dev);
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ if (sport)
+ uart_suspend_port(&sport_uart_reg, &sport->port);
+
+ return 0;
+}
+
+static int sport_uart_resume(struct platform_device *dev)
+{
+ struct sport_uart_port *sport = platform_get_drvdata(dev);
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ if (sport)
+ uart_resume_port(&sport_uart_reg, &sport->port);
+
+ return 0;
+}
+
+static int sport_uart_probe(struct platform_device *dev)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+ sport_uart_ports[dev->id].port.dev = &dev->dev;
+ uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port);
+ platform_set_drvdata(dev, &sport_uart_ports[dev->id]);
+
+ return 0;
+}
+
+static int sport_uart_remove(struct platform_device *dev)
+{
+ struct sport_uart_port *sport = platform_get_drvdata(dev);
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ platform_set_drvdata(dev, NULL);
+
+ if (sport)
+ uart_remove_one_port(&sport_uart_reg, &sport->port);
+
+ return 0;
+}
+
+static struct platform_driver sport_uart_driver = {
+ .probe = sport_uart_probe,
+ .remove = sport_uart_remove,
+ .suspend = sport_uart_suspend,
+ .resume = sport_uart_resume,
+ .driver = {
+ .name = DRV_NAME,
+ },
+};
+
+static int __init sport_uart_init(void)
+{
+ int ret;
+
+ pr_debug("%s enter\n", __FUNCTION__);
+ ret = uart_register_driver(&sport_uart_reg);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register %s:%d\n",
+ sport_uart_reg.driver_name, ret);
+ return ret;
+ }
+
+ ret = platform_driver_register(&sport_uart_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret);
+ uart_unregister_driver(&sport_uart_reg);
+ }
+
+
+ pr_debug("%s exit\n", __FUNCTION__);
+ return ret;
+}
+
+static void __exit sport_uart_exit(void)
+{
+ pr_debug("%s enter\n", __FUNCTION__);
+ platform_driver_unregister(&sport_uart_driver);
+ uart_unregister_driver(&sport_uart_reg);
+}
+
+module_init(sport_uart_init);
+module_exit(sport_uart_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h
new file mode 100644
index 00000000000..671d41cc1a3
--- /dev/null
+++ b/drivers/serial/bfin_sport_uart.h
@@ -0,0 +1,63 @@
+/*
+ * File: linux/drivers/serial/bfin_sport_uart.h
+ *
+ * Based on: include/asm-blackfin/mach-533/bfin_serial_5xx.h
+ * Author: Roy Huang <roy.huang>analog.com>
+ *
+ * Created: Nov 22, 2006
+ * Copyright: (C) Analog Device Inc.
+ * Description: this driver enable SPORTs on Blackfin emulate UART.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */
+#define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */
+#define OFFSET_TCLKDIV 0x08 /* Transmit Serial Clock Divider Register */
+#define OFFSET_TFSDIV 0x0C /* Transmit Frame Sync Divider Register */
+#define OFFSET_TX 0x10 /* Transmit Data Register */
+#define OFFSET_RX 0x18 /* Receive Data Register */
+#define OFFSET_RCR1 0x20 /* Receive Configuration 1 Register */
+#define OFFSET_RCR2 0x24 /* Receive Configuration 2 Register */
+#define OFFSET_RCLKDIV 0x28 /* Receive Serial Clock Divider Register */
+#define OFFSET_RFSDIV 0x2c /* Receive Frame Sync Divider Register */
+#define OFFSET_STAT 0x30 /* Status Register */
+
+#define SPORT_GET_TCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_TCR1))
+#define SPORT_GET_TCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_TCR2))
+#define SPORT_GET_TCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TCLKDIV))
+#define SPORT_GET_TFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TFSDIV))
+#define SPORT_GET_TX(sport) bfin_read16(((sport)->port.membase + OFFSET_TX))
+#define SPORT_GET_RX(sport) bfin_read16(((sport)->port.membase + OFFSET_RX))
+#define SPORT_GET_RX32(sport) bfin_read32(((sport)->port.membase + OFFSET_RX))
+#define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1))
+#define SPORT_GET_RCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR2))
+#define SPORT_GET_RCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RCLKDIV))
+#define SPORT_GET_RFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RFSDIV))
+#define SPORT_GET_STAT(sport) bfin_read16(((sport)->port.membase + OFFSET_STAT))
+
+#define SPORT_PUT_TCR1(sport, v) bfin_write16(((sport)->port.membase + OFFSET_TCR1), v)
+#define SPORT_PUT_TCR2(sport, v) bfin_write16(((sport)->port.membase + OFFSET_TCR2), v)
+#define SPORT_PUT_TCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_TCLKDIV), v)
+#define SPORT_PUT_TFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_TFSDIV), v)
+#define SPORT_PUT_TX(sport, v) bfin_write16(((sport)->port.membase + OFFSET_TX), v)
+#define SPORT_PUT_RX(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RX), v)
+#define SPORT_PUT_RCR1(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCR1), v)
+#define SPORT_PUT_RCR2(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCR2), v)
+#define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v)
+#define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v)
+#define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index a638ba0679a..a19dc7ef886 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -1117,7 +1117,7 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
line = cpm_uart_id2nr(idx);
if(line < 0) {
- printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
+ printk(KERN_ERR"%s(): port %d is not registered", __func__, idx);
return -EINVAL;
}
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 88e7c1d5b91..f9fa237aa94 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -1788,7 +1788,7 @@ static unsigned int handle_descr_data(struct e100_serial *info,
if (info->recv_cnt + recvl > 65536) {
printk(KERN_CRIT
- "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __FUNCTION__, recvl);
+ "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl);
return 0;
}
@@ -1801,7 +1801,7 @@ static unsigned int handle_descr_data(struct e100_serial *info,
append_recv_buffer(info, buffer);
if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
- panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__);
+ panic("%s: Failed to allocate memory for receive buffer!\n", __func__);
descr->buf = virt_to_phys(buffer->buffer);
@@ -1925,7 +1925,7 @@ static int start_recv_dma(struct e100_serial *info)
/* Set up the receiving descriptors */
for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) {
if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
- panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__);
+ panic("%s: Failed to allocate memory for receive buffer!\n", __func__);
descr[i].ctrl = d_int;
descr[i].buf = virt_to_phys(buffer->buffer);
@@ -3581,8 +3581,9 @@ rs_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+ unsigned long flags;
- lock_kernel();
+ local_irq_save(flags);
if (clear & TIOCM_RTS)
e100_rts(info, 0);
@@ -3604,7 +3605,7 @@ rs_tiocmset(struct tty_struct *tty, struct file *file,
if (set & TIOCM_CD)
e100_cd_out(info, 1);
- unlock_kernel();
+ local_irq_restore(flags);
return 0;
}
@@ -3613,8 +3614,10 @@ rs_tiocmget(struct tty_struct *tty, struct file *file)
{
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
unsigned int result;
+ unsigned long flags;
+
+ local_irq_save(flags);
- lock_kernel();
result =
(!E100_RTS_GET(info) ? TIOCM_RTS : 0)
| (!E100_DTR_GET(info) ? TIOCM_DTR : 0)
@@ -3623,7 +3626,7 @@ rs_tiocmget(struct tty_struct *tty, struct file *file)
| (!E100_CD_GET(info) ? TIOCM_CAR : 0)
| (!E100_CTS_GET(info) ? TIOCM_CTS : 0);
- unlock_kernel();
+ local_irq_restore(flags);
#ifdef SERIAL_DEBUG_IO
printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n",
@@ -3702,10 +3705,6 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
- if (tty->termios->c_cflag == old_termios->c_cflag &&
- tty->termios->c_iflag == old_termios->c_iflag)
- return;
-
change_speed(info);
/* Handle turning off CRTSCTS */
@@ -3808,10 +3807,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
#endif
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ rs_flush_buffer(tty);
+ tty_ldisc_flush_buffer(tty);
tty->closing = 0;
info->event = 0;
info->tty = 0;
@@ -3885,6 +3882,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
* Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
* R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
*/
+ lock_kernel();
orig_jiffies = jiffies;
while (info->xmit.head != info->xmit.tail || /* More in send queue */
(*info->ostatusadr & 0x007f) || /* more in FIFO */
@@ -3901,6 +3899,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
curr_time_usec - info->last_tx_active_usec;
}
set_current_state(TASK_RUNNING);
+ unlock_kernel();
}
/*
@@ -4520,7 +4519,7 @@ rs_init(void)
if (request_irq(SERIAL_IRQ_NBR, ser_interrupt,
IRQF_SHARED | IRQF_DISABLED, "serial ", driver))
- panic("%s: Failed to request irq8", __FUNCTION__);
+ panic("%s: Failed to request irq8", __func__);
#endif
#endif /* CONFIG_SVINTO_SIM */
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 168073f12ce..4f1af71e9a1 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -52,7 +52,7 @@ static unsigned int Submodule_slot;
#define DPRINT_CONFIG(_x...) ;
//#define DPRINT_CONFIG(_x...) printk _x
#define NOT_PROGRESS() ;
-//#define NOT_PROGRESS() printk("%s : fails %d\n", __FUNCTION__, __LINE__)
+//#define NOT_PROGRESS() printk("%s : fails %d\n", __func__, __LINE__)
/* number of characters we want to transmit to the lower level at a time */
#define MAX_CHARS 256
@@ -445,7 +445,7 @@ static int inline port_init(struct ioc3_port *port)
sbbr_h = &idd->vma->sbbr_h;
ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
DPRINT_CONFIG(("%s: ring_pci_addr 0x%p\n",
- __FUNCTION__, (void *)ring_pci_addr));
+ __func__, (void *)ring_pci_addr));
writel((unsigned int)((uint64_t) ring_pci_addr >> 32), sbbr_h);
writel((unsigned int)ring_pci_addr | BUF_SIZE_BIT, sbbr_l);
@@ -593,7 +593,7 @@ config_port(struct ioc3_port *port,
DPRINT_CONFIG(("%s: line %d baud %d byte_size %d stop %d parenb %d "
"parodd %d\n",
- __FUNCTION__, ((struct uart_port *)port->ip_port)->line,
+ __func__, ((struct uart_port *)port->ip_port)->line,
baud, byte_size, stop_bits, parenb, parodd));
if (set_baud(port, baud))
@@ -871,14 +871,14 @@ static int ioc3_set_proto(struct ioc3_port *port, int proto)
default:
case PROTO_RS232:
/* Clear the appropriate GIO pin */
- DPRINT_CONFIG(("%s: rs232\n", __FUNCTION__));
+ DPRINT_CONFIG(("%s: rs232\n", __func__));
writel(0, (&port->ip_idd->vma->gppr[0]
+ hooks->rs422_select_pin));
break;
case PROTO_RS422:
/* Set the appropriate GIO pin */
- DPRINT_CONFIG(("%s: rs422\n", __FUNCTION__));
+ DPRINT_CONFIG(("%s: rs422\n", __func__));
writel(1, (&port->ip_idd->vma->gppr[0]
+ hooks->rs422_select_pin));
break;
@@ -988,7 +988,7 @@ ioc3_change_speed(struct uart_port *the_port,
}
baud = uart_get_baud_rate(the_port, new_termios, old_termios,
MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
- DPRINT_CONFIG(("%s: returned baud %d for line %d\n", __FUNCTION__, baud,
+ DPRINT_CONFIG(("%s: returned baud %d for line %d\n", __func__, baud,
the_port->line));
if (!the_port->fifosize)
@@ -1026,7 +1026,7 @@ ioc3_change_speed(struct uart_port *the_port,
DPRINT_CONFIG(("%s : port 0x%p line %d cflag 0%o "
"config_port(baud %d data %d stop %d penable %d "
" parity %d), notification 0x%x\n",
- __FUNCTION__, (void *)port, the_port->line, cflag, baud,
+ __func__, (void *)port, the_port->line, cflag, baud,
new_data, new_stop, new_parity_enable, new_parity,
the_port->ignore_status_mask));
@@ -1919,7 +1919,7 @@ static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
struct pci_dev *pdev = idd->pdev;
DPRINT_CONFIG(("%s: attach pdev 0x%p - card_ptr 0x%p\n",
- __FUNCTION__, pdev, (void *)card_ptr));
+ __func__, pdev, (void *)card_ptr));
if (!card_ptr)
return -ENODEV;
@@ -1933,7 +1933,7 @@ static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
port->ip_port = the_port;
DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p [%d/%d]\n",
- __FUNCTION__, (void *)the_port, (void *)port,
+ __func__, (void *)the_port, (void *)port,
phys_port, ii));
/* membase, iobase and mapbase just need to be non-0 */
@@ -1950,7 +1950,7 @@ static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
if (uart_add_one_port(&ioc3_uart, the_port) < 0) {
printk(KERN_WARNING
"%s: unable to add port %d bus %d\n",
- __FUNCTION__, the_port->line, pdev->bus->number);
+ __func__, the_port->line, pdev->bus->number);
} else {
DPRINT_CONFIG(("IOC3 serial port %d irq %d bus %d\n",
the_port->line, the_port->irq, pdev->bus->number));
@@ -2017,7 +2017,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
struct ioc3_port *ports[PORTS_PER_CARD];
int phys_port;
- DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, is, idd));
+ DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd));
card_ptr = kzalloc(sizeof(struct ioc3_card), GFP_KERNEL);
if (!card_ptr) {
@@ -2067,7 +2067,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
DPRINT_CONFIG(("%s : Port A ip_serial_regs 0x%p "
"ip_uart_regs 0x%p\n",
- __FUNCTION__,
+ __func__,
(void *)port->ip_serial_regs,
(void *)port->ip_uart_regs));
@@ -2082,7 +2082,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
DPRINT_CONFIG(("%s : Port A ip_cpu_ringbuf 0x%p "
"ip_dma_ringbuf 0x%p, ip_inring 0x%p "
"ip_outring 0x%p\n",
- __FUNCTION__,
+ __func__,
(void *)port->ip_cpu_ringbuf,
(void *)port->ip_dma_ringbuf,
(void *)port->ip_inring,
@@ -2094,7 +2094,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
DPRINT_CONFIG(("%s : Port B ip_serial_regs 0x%p "
"ip_uart_regs 0x%p\n",
- __FUNCTION__,
+ __func__,
(void *)port->ip_serial_regs,
(void *)port->ip_uart_regs));
@@ -2108,7 +2108,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
DPRINT_CONFIG(("%s : Port B ip_cpu_ringbuf 0x%p "
"ip_dma_ringbuf 0x%p, ip_inring 0x%p "
"ip_outring 0x%p\n",
- __FUNCTION__,
+ __func__,
(void *)port->ip_cpu_ringbuf,
(void *)port->ip_dma_ringbuf,
(void *)port->ip_inring,
@@ -2116,7 +2116,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
}
DPRINT_CONFIG(("%s : port %d [addr 0x%p] card_ptr 0x%p",
- __FUNCTION__,
+ __func__,
phys_port, (void *)port, (void *)card_ptr));
DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
(void *)port->ip_serial_regs,
@@ -2127,7 +2127,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
DPRINT_CONFIG(("%s: phys_port %d port 0x%p inring 0x%p "
"outring 0x%p\n",
- __FUNCTION__,
+ __func__,
phys_port, (void *)port,
(void *)port->ip_inring,
(void *)port->ip_outring));
@@ -2170,7 +2170,7 @@ static int __devinit ioc3uart_init(void)
if ((ret = uart_register_driver(&ioc3_uart)) < 0) {
printk(KERN_WARNING
"%s: Couldn't register IOC3 uart serial driver\n",
- __FUNCTION__);
+ __func__);
return ret;
}
ret = ioc3_register_submodule(&ioc3uart_submodule);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 0c179384fb0..49b8a82b7b9 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -889,7 +889,7 @@ static int inline port_init(struct ioc4_port *port)
ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
DPRINT_CONFIG(("%s: ring_pci_addr 0x%lx\n",
- __FUNCTION__, ring_pci_addr));
+ __func__, ring_pci_addr));
writel((unsigned int)((uint64_t)ring_pci_addr >> 32), sbbr_h);
writel((unsigned int)ring_pci_addr | IOC4_BUF_SIZE_BIT, sbbr_l);
@@ -1028,7 +1028,7 @@ static irqreturn_t ioc4_intr(int irq, void *arg)
spin_lock_irqsave(&soft->is_ir_lock, flag);
printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies 0x%x "
"other_ir 0x%x other_ies 0x%x mask 0x%x\n",
- __FUNCTION__, __LINE__,
+ __func__, __LINE__,
(void *)mem, readl(&mem->sio_ir.raw),
readl(&mem->sio_ies.raw),
readl(&mem->other_ir.raw),
@@ -1155,14 +1155,14 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
(TOTAL_RING_BUF_SIZE - 1)) == 0));
DPRINT_CONFIG(("%s : ip_cpu_ringbuf 0x%p "
"ip_dma_ringbuf 0x%p\n",
- __FUNCTION__,
+ __func__,
(void *)port->ip_cpu_ringbuf,
(void *)port->ip_dma_ringbuf));
port->ip_inring = RING(port, RX_0_OR_2);
port->ip_outring = RING(port, TX_0_OR_2);
}
DPRINT_CONFIG(("%s : port %d [addr 0x%p] control 0x%p",
- __FUNCTION__,
+ __func__,
port_number, (void *)port, (void *)control));
DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
(void *)port->ip_serial_regs,
@@ -1173,7 +1173,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
DPRINT_CONFIG(("%s: port_number %d port 0x%p inring 0x%p "
"outring 0x%p\n",
- __FUNCTION__,
+ __func__,
port_number, (void *)port,
(void *)port->ip_inring,
(void *)port->ip_outring));
@@ -1317,7 +1317,7 @@ config_port(struct ioc4_port *port,
int spiniter = 0;
DPRINT_CONFIG(("%s: baud %d byte_size %d stop %d parenb %d parodd %d\n",
- __FUNCTION__, baud, byte_size, stop_bits, parenb, parodd));
+ __func__, baud, byte_size, stop_bits, parenb, parodd));
if (set_baud(port, baud))
return 1;
@@ -1725,7 +1725,7 @@ ioc4_change_speed(struct uart_port *the_port,
}
baud = uart_get_baud_rate(the_port, new_termios, old_termios,
MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
- DPRINT_CONFIG(("%s: returned baud %d\n", __FUNCTION__, baud));
+ DPRINT_CONFIG(("%s: returned baud %d\n", __func__, baud));
/* default is 9600 */
if (!baud)
@@ -1765,7 +1765,7 @@ ioc4_change_speed(struct uart_port *the_port,
DPRINT_CONFIG(("%s : port 0x%p cflag 0%o "
"config_port(baud %d data %d stop %d p enable %d parity %d),"
" notification 0x%x\n",
- __FUNCTION__, (void *)port, cflag, baud, new_data, new_stop,
+ __func__, (void *)port, cflag, baud, new_data, new_stop,
new_parity_enable, new_parity, the_port->ignore_status_mask));
if ((config_port(port, baud, /* baud */
@@ -2715,7 +2715,7 @@ ioc4_serial_core_attach(struct pci_dev *pdev, int port_type)
DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n",
- __FUNCTION__, pdev, (void *)control));
+ __func__, pdev, (void *)control));
if (!control)
return -ENODEV;
@@ -2734,7 +2734,7 @@ ioc4_serial_core_attach(struct pci_dev *pdev, int port_type)
port->ip_all_ports[port_type_idx] = the_port;
DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p : type %s\n",
- __FUNCTION__, (void *)the_port,
+ __func__, (void *)the_port,
(void *)port,
port_type == PROTO_RS232 ? "rs232" : "rs422"));
@@ -2752,7 +2752,7 @@ ioc4_serial_core_attach(struct pci_dev *pdev, int port_type)
if (uart_add_one_port(u_driver, the_port) < 0) {
printk(KERN_WARNING
"%s: unable to add port %d bus %d\n",
- __FUNCTION__, the_port->line, pdev->bus->number);
+ __func__, the_port->line, pdev->bus->number);
} else {
DPRINT_CONFIG(
("IOC4 serial port %d irq = %d, bus %d\n",
@@ -2777,7 +2777,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
int ret = 0;
- DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev,
+ DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, idd->idd_pdev,
idd->idd_pci_id));
/* PCI-RT does not bring out serial connections.
@@ -2806,7 +2806,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
goto out2;
}
DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n",
- __FUNCTION__, (void *)idd->idd_misc_regs,
+ __func__, (void *)idd->idd_misc_regs,
(void *)serial));
/* Get memory for the new card */
@@ -2858,7 +2858,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
} else {
printk(KERN_WARNING
"%s : request_irq fails for IRQ 0x%x\n ",
- __FUNCTION__, idd->idd_pdev->irq);
+ __func__, idd->idd_pdev->irq);
}
ret = ioc4_attach_local(idd);
if (ret)
@@ -2911,13 +2911,13 @@ int ioc4_serial_init(void)
if ((ret = uart_register_driver(&ioc4_uart_rs232)) < 0) {
printk(KERN_WARNING
"%s: Couldn't register rs232 IOC4 serial driver\n",
- __FUNCTION__);
+ __func__);
return ret;
}
if ((ret = uart_register_driver(&ioc4_uart_rs422)) < 0) {
printk(KERN_WARNING
"%s: Couldn't register rs422 IOC4 serial driver\n",
- __FUNCTION__);
+ __func__);
return ret;
}
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 9cf03327386..eadc1ab6bbc 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -96,12 +96,14 @@ static void cleanup_kgdboc(void)
static int kgdboc_get_char(void)
{
- return kgdb_tty_driver->poll_get_char(kgdb_tty_driver, kgdb_tty_line);
+ return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
+ kgdb_tty_line);
}
static void kgdboc_put_char(u8 chr)
{
- kgdb_tty_driver->poll_put_char(kgdb_tty_driver, kgdb_tty_line, chr);
+ kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
+ kgdb_tty_line, chr);
}
static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index ddd3aa50d4a..43af40d59b8 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1072,18 +1072,6 @@ static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
tty_wait_until_sent(tty, 0);
send_break(info, arg ? arg*(HZ/10) : HZ/4);
return 0;
- case TIOCGSOFTCAR:
- error = put_user(C_CLOCAL(tty) ? 1 : 0,
- (unsigned long *) arg);
- if (error)
- return error;
- return 0;
- case TIOCSSOFTCAR:
- get_user(arg, (unsigned long *) arg);
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
case TIOCGSERIAL:
if (access_ok(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct)))
@@ -1222,8 +1210,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
} else
#endif
shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ mcfrs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
@@ -1276,6 +1263,8 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
* Note: we have to use pretty tight timings here to satisfy
* the NIST-PCTS.
*/
+ lock_kernel();
+
fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud;
char_time = fifo_time / 5;
if (char_time == 0)
@@ -1312,6 +1301,7 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
+ unlock_kernel();
#else
/*
* For the other coldfire models, assume all data has been sent
@@ -1907,7 +1897,7 @@ static struct tty_driver *mcfrs_console_device(struct console *c, int *index)
* This is used for console output.
*/
-void mcfrs_put_char(char ch)
+int mcfrs_put_char(char ch)
{
volatile unsigned char *uartp;
unsigned long flags;
@@ -1931,7 +1921,7 @@ void mcfrs_put_char(char ch)
mcfrs_init_console(); /* try and get it back */
local_irq_restore(flags);
- return;
+ return 1;
}
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index d93b3578c5e..7a3625f52a0 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -1221,8 +1221,8 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
#endif
#ifdef CONFIG_PPC_MPC512x
{ .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
- {},
#endif
+ {},
};
static int __devinit
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 3123ffeac8a..81ac9bb4f39 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -287,6 +287,7 @@ static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
unsigned int val;
+ /* FIXME: Locking needed ? */
if (mctrl & TIOCM_RTS) {
val = readl(port->membase + UART_RTS_CR);
writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR);
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index da5a02cb4f6..2b6a013639e 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1096,13 +1096,13 @@ static int s3c24xx_serial_probe(struct platform_device *dev,
ourport = &s3c24xx_serial_ports[probe_index];
probe_index++;
- dbg("%s: initialising port %p...\n", __FUNCTION__, ourport);
+ dbg("%s: initialising port %p...\n", __func__, ourport);
ret = s3c24xx_serial_init_port(ourport, info, dev);
if (ret < 0)
goto probe_err;
- dbg("%s: adding port\n", __FUNCTION__);
+ dbg("%s: adding port\n", __func__);
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
platform_set_drvdata(dev, &ourport->port);
@@ -1587,7 +1587,7 @@ static int s3c2412_serial_resetport(struct uart_port *port,
unsigned long ucon = rd_regl(port, S3C2410_UCON);
dbg("%s: port=%p (%08lx), cfg=%p\n",
- __FUNCTION__, port, port->mapbase, cfg);
+ __func__, port, port->mapbase, cfg);
/* ensure we don't change the clock settings... */
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 67b2338913c..62b38582f5e 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -655,7 +655,7 @@ void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
void __init sa1100_register_uart(int idx, int port)
{
if (idx >= NR_PORTS) {
- printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
+ printk(KERN_ERR "%s: bad index number %d\n", __func__, idx);
return;
}
@@ -682,7 +682,7 @@ void __init sa1100_register_uart(int idx, int port)
break;
default:
- printk(KERN_ERR "%s: bad port number %d\n", __FUNCTION__, port);
+ printk(KERN_ERR "%s: bad port number %d\n", __func__, port);
}
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 977ce820ce3..1e2b9d826f6 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -422,6 +422,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
EXPORT_SYMBOL(uart_get_divisor);
+/* FIXME: Consistent locking policy */
static void
uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
{
@@ -454,27 +455,30 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
port->ops->set_termios(port, termios, old_termios);
}
-static inline void
+static inline int
__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
{
unsigned long flags;
+ int ret = 0;
if (!circ->buf)
- return;
+ return 0;
spin_lock_irqsave(&port->lock, flags);
if (uart_circ_chars_free(circ) != 0) {
circ->buf[circ->head] = c;
circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
+ ret = 1;
}
spin_unlock_irqrestore(&port->lock, flags);
+ return ret;
}
-static void uart_put_char(struct tty_struct *tty, unsigned char ch)
+static int uart_put_char(struct tty_struct *tty, unsigned char ch)
{
struct uart_state *state = tty->driver_data;
- __uart_put_char(state->port, &state->info->xmit, ch);
+ return __uart_put_char(state->port, &state->info->xmit, ch);
}
static void uart_flush_chars(struct tty_struct *tty)
@@ -528,15 +532,25 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
static int uart_write_room(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
+ unsigned long flags;
+ int ret;
- return uart_circ_chars_free(&state->info->xmit);
+ spin_lock_irqsave(&state->port->lock, flags);
+ ret = uart_circ_chars_free(&state->info->xmit);
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ return ret;
}
static int uart_chars_in_buffer(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
+ unsigned long flags;
+ int ret;
- return uart_circ_chars_pending(&state->info->xmit);
+ spin_lock_irqsave(&state->port->lock, flags);
+ ret = uart_circ_chars_pending(&state->info->xmit);
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ return ret;
}
static void uart_flush_buffer(struct tty_struct *tty)
@@ -618,6 +632,11 @@ static int uart_get_info(struct uart_state *state,
struct serial_struct tmp;
memset(&tmp, 0, sizeof(tmp));
+
+ /* Ensure the state we copy is consistent and no hardware changes
+ occur as we go */
+ mutex_lock(&state->mutex);
+
tmp.type = port->type;
tmp.line = port->line;
tmp.port = port->iobase;
@@ -637,6 +656,8 @@ static int uart_get_info(struct uart_state *state,
tmp.iomem_reg_shift = port->regshift;
tmp.iomem_base = (void *)(unsigned long)port->mapbase;
+ mutex_unlock(&state->mutex);
+
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
return 0;
@@ -914,8 +935,6 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port;
- BUG_ON(!kernel_locked());
-
mutex_lock(&state->mutex);
if (port->type != PORT_UNKNOWN)
@@ -1059,7 +1078,7 @@ static int uart_get_count(struct uart_state *state,
}
/*
- * Called via sys_ioctl under the BKL. We can use spin_lock_irq() here.
+ * Called via sys_ioctl. We can use spin_lock_irq() here.
*/
static int
uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
@@ -1069,7 +1088,6 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
void __user *uarg = (void __user *)arg;
int ret = -ENOIOCTLCMD;
- BUG_ON(!kernel_locked());
/*
* These ioctls don't rely on the hardware to be present.
@@ -1140,9 +1158,9 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
break;
}
}
- out_up:
+out_up:
mutex_unlock(&state->mutex);
- out:
+out:
return ret;
}
@@ -1153,7 +1171,6 @@ static void uart_set_termios(struct tty_struct *tty,
unsigned long flags;
unsigned int cflag = tty->termios->c_cflag;
- BUG_ON(!kernel_locked());
/*
* These are the bits that are used to setup various
@@ -1165,8 +1182,9 @@ static void uart_set_termios(struct tty_struct *tty,
if ((cflag ^ old_termios->c_cflag) == 0 &&
tty->termios->c_ospeed == old_termios->c_ospeed &&
tty->termios->c_ispeed == old_termios->c_ispeed &&
- RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
+ RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) {
return;
+ }
uart_change_speed(state, old_termios);
@@ -1200,7 +1218,6 @@ static void uart_set_termios(struct tty_struct *tty,
}
spin_unlock_irqrestore(&state->port->lock, flags);
}
-
#if 0
/*
* No need to wake up processes in open wait, since they
@@ -1316,11 +1333,11 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
struct uart_port *port = state->port;
unsigned long char_time, expire;
- BUG_ON(!kernel_locked());
-
if (port->type == PORT_UNKNOWN || port->fifosize == 0)
return;
+ lock_kernel();
+
/*
* Set the check interval to be 1/5 of the estimated time to
* send a single character, and make it at least 1. The check
@@ -1366,6 +1383,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
break;
}
set_current_state(TASK_RUNNING); /* might not be needed */
+ unlock_kernel();
}
/*
@@ -2079,7 +2097,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
int ret;
uart_change_pm(state, 0);
+ spin_lock_irq(&port->lock);
ops->set_mctrl(port, 0);
+ spin_unlock_irq(&port->lock);
ret = ops->startup(port);
if (ret == 0) {
uart_change_speed(state, NULL);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index c2ea5d4df44..96910618771 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -855,7 +855,7 @@ static int sci_notifier(struct notifier_block *self,
printk(KERN_INFO "%s: got a postchange notification "
"for cpu %d (old %d, new %d)\n",
- __FUNCTION__, freqs->cpu, freqs->old, freqs->new);
+ __func__, freqs->cpu, freqs->old, freqs->new);
}
return NOTIFY_OK;
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 41fc6126444..019da2e05f0 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -839,7 +839,7 @@ static int __init sn_sal_module_init(void)
if (uart_add_one_port(&sal_console_uart, &sal_console_port.sc_port) < 0) {
/* error - not sure what I'd do - so I'll do nothing */
- printk(KERN_ERR "%s: unable to add port\n", __FUNCTION__);
+ printk(KERN_ERR "%s: unable to add port\n", __func__);
}
/* when this driver is compiled in, the console initialization
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index b565d5a3749..b51c24245be 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -584,7 +584,7 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match)
const unsigned int *id;
int irq, rc;
- dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match);
+ dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match);
rc = of_address_to_resource(op->node, 0, &res);
if (rc) {
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 5e4310ccd59..01917c433f1 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -215,7 +215,7 @@ static inline dma_addr_t cpu2qe_addr(void *addr, struct uart_qe_port *qe_port)
return qe_port->bd_dma_addr + (addr - qe_port->bd_virt);
/* something nasty happened */
- printk(KERN_ERR "%s: addr=%p\n", __FUNCTION__, addr);
+ printk(KERN_ERR "%s: addr=%p\n", __func__, addr);
BUG();
return 0;
}
@@ -234,7 +234,7 @@ static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port)
return qe_port->bd_virt + (addr - qe_port->bd_dma_addr);
/* something nasty happened */
- printk(KERN_ERR "%s: addr=%x\n", __FUNCTION__, addr);
+ printk(KERN_ERR "%s: addr=%x\n", __func__, addr);
BUG();
return NULL;
}
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 02c8e305b14..e81d59d7891 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -497,7 +497,7 @@ static int atmel_spi_setup(struct spi_device *spi)
struct atmel_spi *as;
u32 scbr, csr;
unsigned int bits = spi->bits_per_word;
- unsigned long bus_hz, sck_hz;
+ unsigned long bus_hz;
unsigned int npcs_pin;
int ret;
@@ -536,14 +536,25 @@ static int atmel_spi_setup(struct spi_device *spi)
return -EINVAL;
}
- /* speed zero convention is used by some upper layers */
+ /*
+ * Pre-new_1 chips start out at half the peripheral
+ * bus speed.
+ */
bus_hz = clk_get_rate(as->clk);
+ if (!as->new_1)
+ bus_hz /= 2;
+
if (spi->max_speed_hz) {
- /* assume div32/fdiv/mbz == 0 */
- if (!as->new_1)
- bus_hz /= 2;
- scbr = ((bus_hz + spi->max_speed_hz - 1)
- / spi->max_speed_hz);
+ /*
+ * Calculate the lowest divider that satisfies the
+ * constraint, assuming div32/fdiv/mbz == 0.
+ */
+ scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz);
+
+ /*
+ * If the resulting divider doesn't fit into the
+ * register bitfield, we can't satisfy the constraint.
+ */
if (scbr >= (1 << SPI_SCBR_SIZE)) {
dev_dbg(&spi->dev,
"setup: %d Hz too slow, scbr %u; min %ld Hz\n",
@@ -551,8 +562,8 @@ static int atmel_spi_setup(struct spi_device *spi)
return -EINVAL;
}
} else
+ /* speed zero means "as slow as possible" */
scbr = 0xff;
- sck_hz = bus_hz / scbr;
csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8);
if (spi->mode & SPI_CPOL)
@@ -589,7 +600,7 @@ static int atmel_spi_setup(struct spi_device *spi)
dev_dbg(&spi->dev,
"setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
- sck_hz, bits, spi->mode, spi->chip_select, csr);
+ bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 433b3f44f42..8d158e5640e 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -170,7 +170,7 @@ static int gs_open(struct tty_struct *tty, struct file *file);
static void gs_close(struct tty_struct *tty, struct file *file);
static int gs_write(struct tty_struct *tty,
const unsigned char *buf, int count);
-static void gs_put_char(struct tty_struct *tty, unsigned char ch);
+static int gs_put_char(struct tty_struct *tty, unsigned char ch);
static void gs_flush_chars(struct tty_struct *tty);
static int gs_write_room(struct tty_struct *tty);
static int gs_chars_in_buffer(struct tty_struct *tty);
@@ -883,14 +883,15 @@ exit:
/*
* gs_put_char
*/
-static void gs_put_char(struct tty_struct *tty, unsigned char ch)
+static int gs_put_char(struct tty_struct *tty, unsigned char ch)
{
unsigned long flags;
struct gs_port *port = tty->driver_data;
+ int ret = 0;
if (port == NULL) {
pr_err("gs_put_char: NULL port pointer\n");
- return;
+ return 0;
}
gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
@@ -910,10 +911,11 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch)
goto exit;
}
- gs_buf_put(port->port_write_buf, &ch, 1);
+ ret = gs_buf_put(port->port_write_buf, &ch, 1);
exit:
spin_unlock_irqrestore(&port->port_lock, flags);
+ return ret;
}
/*
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index d17d1645714..04a56f300ea 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1421,8 +1421,7 @@ static void digi_close(struct usb_serial_port *port, struct file *filp)
tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT);
/* flush driver and line discipline buffers */
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
+ tty_driver_flush_buffer(tty);
tty_ldisc_flush(tty);
if (port->serial->dev) {
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index a9934a3f984..0cb0d77dc42 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -296,16 +296,14 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
struct usb_serial_port *port = tty->driver_data;
int retval = -ENODEV;
- if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
+ if (port->serial->dev->state == USB_STATE_NOTATTACHED)
goto exit;
dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
- if (!port->open_count) {
- retval = -EINVAL;
- dbg("%s - port not opened", __func__);
- goto exit;
- }
+ /* open_count is managed under the mutex lock for the tty so cannot
+ drop to zero until after the last close completes */
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function */
retval = port->serial->type->write(port, buf, count);
@@ -317,61 +315,28 @@ exit:
static int serial_write_room (struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
- int retval = -ENODEV;
-
- if (!port)
- goto exit;
-
dbg("%s - port %d", __func__, port->number);
-
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- goto exit;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function */
- retval = port->serial->type->write_room(port);
-
-exit:
- return retval;
+ return port->serial->type->write_room(port);
}
static int serial_chars_in_buffer (struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
- int retval = -ENODEV;
-
- if (!port)
- goto exit;
-
dbg("%s = port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- goto exit;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function */
- retval = port->serial->type->chars_in_buffer(port);
-
-exit:
- return retval;
+ return port->serial->type->chars_in_buffer(port);
}
static void serial_throttle (struct tty_struct * tty)
{
struct usb_serial_port *port = tty->driver_data;
-
- if (!port)
- return;
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg ("%s - port not open", __func__);
- return;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function */
if (port->serial->type->throttle)
port->serial->type->throttle(port);
@@ -380,17 +345,9 @@ static void serial_throttle (struct tty_struct * tty)
static void serial_unthrottle (struct tty_struct * tty)
{
struct usb_serial_port *port = tty->driver_data;
-
- if (!port)
- return;
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- return;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function */
if (port->serial->type->unthrottle)
port->serial->type->unthrottle(port);
@@ -401,42 +358,27 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
struct usb_serial_port *port = tty->driver_data;
int retval = -ENODEV;
- lock_kernel();
- if (!port)
- goto exit;
-
dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
- /* Caution - port->open_count is BKL protected */
- if (!port->open_count) {
- dbg ("%s - port not open", __func__);
- goto exit;
- }
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function if it is available */
- if (port->serial->type->ioctl)
+ if (port->serial->type->ioctl) {
+ lock_kernel();
retval = port->serial->type->ioctl(port, file, cmd, arg);
+ unlock_kernel();
+ }
else
retval = -ENOIOCTLCMD;
-exit:
- unlock_kernel();
return retval;
}
static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
{
struct usb_serial_port *port = tty->driver_data;
-
- if (!port)
- return;
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- return;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function if it is available */
if (port->serial->type->set_termios)
port->serial->type->set_termios(port, old);
@@ -448,24 +390,15 @@ static void serial_break (struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
- lock_kernel();
- if (!port) {
- unlock_kernel();
- return;
- }
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- unlock_kernel();
- return;
- }
-
+ WARN_ON(!port->open_count);
/* pass on to the driver specific version of this function if it is available */
- if (port->serial->type->break_ctl)
+ if (port->serial->type->break_ctl) {
+ lock_kernel();
port->serial->type->break_ctl(port, break_state);
- unlock_kernel();
+ unlock_kernel();
+ }
}
static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
@@ -519,19 +452,11 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file)
{
struct usb_serial_port *port = tty->driver_data;
- if (!port)
- return -ENODEV;
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- return -ENODEV;
- }
-
+ WARN_ON(!port->open_count);
if (port->serial->type->tiocmget)
return port->serial->type->tiocmget(port, file);
-
return -EINVAL;
}
@@ -540,19 +465,11 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file,
{
struct usb_serial_port *port = tty->driver_data;
- if (!port)
- return -ENODEV;
-
dbg("%s - port %d", __func__, port->number);
- if (!port->open_count) {
- dbg("%s - port not open", __func__);
- return -ENODEV;
- }
-
+ WARN_ON(!port->open_count);
if (port->serial->type->tiocmset)
return port->serial->type->tiocmset(port, file, set, clear);
-
return -EINVAL;
}
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index e96bf8663ff..f07e8a4c1f3 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -673,15 +673,13 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
}
*/
- if (port->tty->driver->flush_buffer)
- port->tty->driver->flush_buffer(port->tty);
+ tty_driver_flush_buffer(port->tty);
tty_ldisc_flush(port->tty);
firm_report_tx_done(port);
firm_close(port);
-printk(KERN_ERR"Before processing rx_urbs_submitted.\n");
/* shutdown our bulk reads and writes */
mutex_lock(&info->deathwarrant);
spin_lock_irq(&info->lock);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index a576dc26173..bb1dadaa4a2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1774,6 +1774,11 @@ config FB_PXA
If unsure, say N.
+config FB_PXA_SMARTPANEL
+ bool "PXA Smartpanel LCD support"
+ default n
+ depends on FB_PXA
+
config FB_PXA_PARAMETERS
bool "PXA LCD command line parameters"
default n
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 757651954e6..3ab6e3d973a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -39,6 +39,9 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/completion.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -57,19 +60,31 @@
#include "pxafb.h"
/* Bits which should not be set in machine configuration structures */
-#define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM|LCCR0_BM|LCCR0_QDM|LCCR0_DIS|LCCR0_EFM|LCCR0_IUM|LCCR0_SFM|LCCR0_LDM|LCCR0_ENB)
-#define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
+#define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM | LCCR0_BM | LCCR0_QDM |\
+ LCCR0_DIS | LCCR0_EFM | LCCR0_IUM |\
+ LCCR0_SFM | LCCR0_LDM | LCCR0_ENB)
+
+#define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP | LCCR3_VSP |\
+ LCCR3_PCD | LCCR3_BPP)
static void (*pxafb_backlight_power)(int);
static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
-static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
+static int pxafb_activate_var(struct fb_var_screeninfo *var,
+ struct pxafb_info *);
static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
-#ifdef CONFIG_FB_PXA_PARAMETERS
-#define PXAFB_OPTIONS_SIZE 256
-static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = "";
-#endif
+static inline unsigned long
+lcd_readl(struct pxafb_info *fbi, unsigned int off)
+{
+ return __raw_readl(fbi->mmio_base + off);
+}
+
+static inline void
+lcd_writel(struct pxafb_info *fbi, unsigned int off, unsigned long val)
+{
+ __raw_writel(val, fbi->mmio_base + off);
+}
static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state)
{
@@ -79,10 +94,12 @@ static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state)
/*
* We need to handle two requests being made at the same time.
* There are two important cases:
- * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE)
- * We must perform the unblanking, which will do our REENABLE for us.
- * 2. When we are blanking, but immediately unblank before we have
- * blanked. We do the "REENABLE" thing here as well, just to be sure.
+ * 1. When we are changing VT (C_REENABLE) while unblanking
+ * (C_ENABLE) We must perform the unblanking, which will
+ * do our REENABLE for us.
+ * 2. When we are blanking, but immediately unblank before
+ * we have blanked. We do the "REENABLE" thing here as
+ * well, just to be sure.
*/
if (fbi->task_state == C_ENABLE && state == C_REENABLE)
state = (u_int) -1;
@@ -129,13 +146,13 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
val = ((red << 8) & 0x00f80000);
val |= ((green >> 0) & 0x0000fc00);
val |= ((blue >> 8) & 0x000000f8);
- ((u32*)(fbi->palette_cpu))[regno] = val;
+ ((u32 *)(fbi->palette_cpu))[regno] = val;
break;
case LCCR4_PAL_FOR_2:
val = ((red << 8) & 0x00fc0000);
val |= ((green >> 0) & 0x0000fc00);
val |= ((blue >> 8) & 0x000000fc);
- ((u32*)(fbi->palette_cpu))[regno] = val;
+ ((u32 *)(fbi->palette_cpu))[regno] = val;
break;
}
@@ -203,15 +220,15 @@ pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
*/
static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var)
{
- int ret = 0;
- switch (var->bits_per_pixel) {
- case 1: ret = LCCR3_1BPP; break;
- case 2: ret = LCCR3_2BPP; break;
- case 4: ret = LCCR3_4BPP; break;
- case 8: ret = LCCR3_8BPP; break;
- case 16: ret = LCCR3_16BPP; break;
- }
- return ret;
+ int ret = 0;
+ switch (var->bits_per_pixel) {
+ case 1: ret = LCCR3_1BPP; break;
+ case 2: ret = LCCR3_2BPP; break;
+ case 4: ret = LCCR3_4BPP; break;
+ case 8: ret = LCCR3_8BPP; break;
+ case 16: ret = LCCR3_16BPP; break;
+ }
+ return ret;
}
#ifdef CONFIG_CPU_FREQ
@@ -223,31 +240,32 @@ static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var)
*/
static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
{
- /*
- * Period = pixclock * bits_per_byte * bytes_per_transfer
- * / memory_bits_per_pixel;
- */
- return var->pixclock * 8 * 16 / var->bits_per_pixel;
+ /*
+ * Period = pixclock * bits_per_byte * bytes_per_transfer
+ * / memory_bits_per_pixel;
+ */
+ return var->pixclock * 8 * 16 / var->bits_per_pixel;
}
-
-extern unsigned int get_clk_frequency_khz(int info);
#endif
/*
* Select the smallest mode that allows the desired resolution to be
* displayed. If desired parameters can be rounded up.
*/
-static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var)
+static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach,
+ struct fb_var_screeninfo *var)
{
struct pxafb_mode_info *mode = NULL;
struct pxafb_mode_info *modelist = mach->modes;
unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
unsigned int i;
- for (i = 0 ; i < mach->num_modes ; i++) {
- if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres &&
- modelist[i].xres < best_x && modelist[i].yres < best_y &&
- modelist[i].bpp >= var->bits_per_pixel ) {
+ for (i = 0; i < mach->num_modes; i++) {
+ if (modelist[i].xres >= var->xres &&
+ modelist[i].yres >= var->yres &&
+ modelist[i].xres < best_x &&
+ modelist[i].yres < best_y &&
+ modelist[i].bpp >= var->bits_per_pixel) {
best_x = modelist[i].xres;
best_y = modelist[i].yres;
mode = &modelist[i];
@@ -257,7 +275,8 @@ static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struc
return mode;
}
-static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode)
+static void pxafb_setmode(struct fb_var_screeninfo *var,
+ struct pxafb_mode_info *mode)
{
var->xres = mode->xres;
var->yres = mode->yres;
@@ -315,19 +334,20 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->yres_virtual =
max(var->yres_virtual, var->yres);
- /*
+ /*
* Setup the RGB parameters for this display.
*
* The pixel packing format is described on page 7-11 of the
* PXA2XX Developer's Manual.
- */
+ */
if (var->bits_per_pixel == 16) {
var->red.offset = 11; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 0; var->blue.length = 5;
var->transp.offset = var->transp.length = 0;
} else {
- var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0;
+ var->red.offset = var->green.offset = 0;
+ var->blue.offset = var->transp.offset = 0;
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
@@ -345,8 +365,7 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static inline void pxafb_set_truecolor(u_int is_true_color)
{
- pr_debug("pxafb: true_color = %d\n", is_true_color);
- // do your machine-specific setup if needed
+ /* do your machine-specific setup if needed */
}
/*
@@ -357,9 +376,6 @@ static int pxafb_set_par(struct fb_info *info)
{
struct pxafb_info *fbi = (struct pxafb_info *)info;
struct fb_var_screeninfo *var = &info->var;
- unsigned long palette_mem_size;
-
- pr_debug("pxafb: set_par\n");
if (var->bits_per_pixel == 16)
fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
@@ -379,17 +395,10 @@ static int pxafb_set_par(struct fb_info *info)
if (var->bits_per_pixel == 16)
fbi->palette_size = 0;
else
- fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
-
- if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
- palette_mem_size = fbi->palette_size * sizeof(u16);
- else
- palette_mem_size = fbi->palette_size * sizeof(u32);
-
- pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
+ fbi->palette_size = var->bits_per_pixel == 1 ?
+ 4 : 1 << var->bits_per_pixel;
- fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
- fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
+ fbi->palette_cpu = (u16 *)&fbi->dma_buff->palette[0];
/*
* Set (any) board control register to handle new color depth
@@ -407,36 +416,6 @@ static int pxafb_set_par(struct fb_info *info)
}
/*
- * Formal definition of the VESA spec:
- * On
- * This refers to the state of the display when it is in full operation
- * Stand-By
- * This defines an optional operating state of minimal power reduction with
- * the shortest recovery time
- * Suspend
- * This refers to a level of power management in which substantial power
- * reduction is achieved by the display. The display can have a longer
- * recovery time from this state than from the Stand-by state
- * Off
- * This indicates that the display is consuming the lowest level of power
- * and is non-operational. Recovery from this state may optionally require
- * the user to manually power on the monitor
- *
- * Now, the fbdev driver adds an additional state, (blank), where they
- * turn off the video (maybe by colormap tricks), but don't mess with the
- * video itself: think of it semantically between on and Stand-By.
- *
- * So here's what we should do in our fbdev blank routine:
- *
- * VESA_NO_BLANKING (mode 0) Video on, front/back light on
- * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off
- * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off
- * VESA_POWERDOWN (mode 3) Video off, front/back light off
- *
- * This will match the matrox implementation.
- */
-
-/*
* pxafb_blank():
* Blank the display by setting all palette values to zero. Note, the
* 16 bpp mode does not really use the palette, so this will not
@@ -447,8 +426,6 @@ static int pxafb_blank(int blank, struct fb_info *info)
struct pxafb_info *fbi = (struct pxafb_info *)info;
int i;
- pr_debug("pxafb: blank=%d\n", blank);
-
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_VSYNC_SUSPEND:
@@ -460,11 +437,11 @@ static int pxafb_blank(int blank, struct fb_info *info)
pxafb_setpalettereg(i, 0, 0, 0, 0, info);
pxafb_schedule_work(fbi, C_DISABLE);
- //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank);
+ /* TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); */
break;
case FB_BLANK_UNBLANK:
- //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank);
+ /* TODO if (pxafb_blank_helper) pxafb_blank_helper(blank); */
if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
fb_set_cmap(&fbi->fb.cmap, info);
@@ -480,7 +457,7 @@ static int pxafb_mmap(struct fb_info *info,
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
if (off < info->fix.smem_len) {
- vma->vm_pgoff += 1;
+ vma->vm_pgoff += fbi->video_offset / PAGE_SIZE;
return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu,
fbi->map_dma, fbi->map_size);
}
@@ -529,7 +506,8 @@ static struct fb_ops pxafb_ops = {
*
* Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
*/
-static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock)
+static inline unsigned int get_pcd(struct pxafb_info *fbi,
+ unsigned int pixclock)
{
unsigned long long pcd;
@@ -555,7 +533,7 @@ static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
unsigned long htime;
if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
- fbi->hsync_time=0;
+ fbi->hsync_time = 0;
return;
}
@@ -576,71 +554,231 @@ unsigned long pxafb_get_hsync_time(struct device *dev)
}
EXPORT_SYMBOL(pxafb_get_hsync_time);
-/*
- * pxafb_activate_var():
- * Configures LCD Controller based on entries in var parameter. Settings are
- * only written to the controller if changes were made.
- */
-static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *fbi)
+static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal,
+ unsigned int offset, size_t size)
{
- struct pxafb_lcd_reg new_regs;
- u_long flags;
- u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
+ struct pxafb_dma_descriptor *dma_desc, *pal_desc;
+ unsigned int dma_desc_off, pal_desc_off;
- pr_debug("pxafb: Configuring PXA LCD\n");
+ if (dma < 0 || dma >= DMA_MAX)
+ return -EINVAL;
- pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
- var->xres, var->hsync_len,
- var->left_margin, var->right_margin);
- pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
- var->yres, var->vsync_len,
- var->upper_margin, var->lower_margin);
- pr_debug("var: pixclock=%d pcd=%d\n", var->pixclock, pcd);
+ dma_desc = &fbi->dma_buff->dma_desc[dma];
+ dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[dma]);
-#if DEBUG_VAR
- if (var->xres < 16 || var->xres > 1024)
- printk(KERN_ERR "%s: invalid xres %d\n",
- fbi->fb.fix.id, var->xres);
- switch(var->bits_per_pixel) {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- break;
- default:
- printk(KERN_ERR "%s: invalid bit depth %d\n",
- fbi->fb.fix.id, var->bits_per_pixel);
- break;
+ dma_desc->fsadr = fbi->screen_dma + offset;
+ dma_desc->fidr = 0;
+ dma_desc->ldcmd = size;
+
+ if (pal < 0 || pal >= PAL_MAX) {
+ dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
+ fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
+ } else {
+ pal_desc = &fbi->dma_buff->pal_desc[dma];
+ pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]);
+
+ pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE;
+ pal_desc->fidr = 0;
+
+ if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+ pal_desc->ldcmd = fbi->palette_size * sizeof(u16);
+ else
+ pal_desc->ldcmd = fbi->palette_size * sizeof(u32);
+
+ pal_desc->ldcmd |= LDCMD_PAL;
+
+ /* flip back and forth between palette and frame buffer */
+ pal_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
+ dma_desc->fdadr = fbi->dma_buff_phys + pal_desc_off;
+ fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off;
}
- if (var->hsync_len < 1 || var->hsync_len > 64)
- printk(KERN_ERR "%s: invalid hsync_len %d\n",
- fbi->fb.fix.id, var->hsync_len);
- if (var->left_margin < 1 || var->left_margin > 255)
- printk(KERN_ERR "%s: invalid left_margin %d\n",
- fbi->fb.fix.id, var->left_margin);
- if (var->right_margin < 1 || var->right_margin > 255)
- printk(KERN_ERR "%s: invalid right_margin %d\n",
- fbi->fb.fix.id, var->right_margin);
- if (var->yres < 1 || var->yres > 1024)
- printk(KERN_ERR "%s: invalid yres %d\n",
- fbi->fb.fix.id, var->yres);
- if (var->vsync_len < 1 || var->vsync_len > 64)
- printk(KERN_ERR "%s: invalid vsync_len %d\n",
- fbi->fb.fix.id, var->vsync_len);
- if (var->upper_margin < 0 || var->upper_margin > 255)
- printk(KERN_ERR "%s: invalid upper_margin %d\n",
- fbi->fb.fix.id, var->upper_margin);
- if (var->lower_margin < 0 || var->lower_margin > 255)
- printk(KERN_ERR "%s: invalid lower_margin %d\n",
- fbi->fb.fix.id, var->lower_margin);
-#endif
- new_regs.lccr0 = fbi->lccr0 |
- (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
- LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
+ return 0;
+}
+
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+static int setup_smart_dma(struct pxafb_info *fbi)
+{
+ struct pxafb_dma_descriptor *dma_desc;
+ unsigned long dma_desc_off, cmd_buff_off;
+
+ dma_desc = &fbi->dma_buff->dma_desc[DMA_CMD];
+ dma_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[DMA_CMD]);
+ cmd_buff_off = offsetof(struct pxafb_dma_buff, cmd_buff);
+
+ dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off;
+ dma_desc->fsadr = fbi->dma_buff_phys + cmd_buff_off;
+ dma_desc->fidr = 0;
+ dma_desc->ldcmd = fbi->n_smart_cmds * sizeof(uint16_t);
+
+ fbi->fdadr[DMA_CMD] = dma_desc->fdadr;
+ return 0;
+}
+
+int pxafb_smart_flush(struct fb_info *info)
+{
+ struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb);
+ uint32_t prsr;
+ int ret = 0;
+
+ /* disable controller until all registers are set up */
+ lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
+
+ /* 1. make it an even number of commands to align on 32-bit boundary
+ * 2. add the interrupt command to the end of the chain so we can
+ * keep track of the end of the transfer
+ */
+
+ while (fbi->n_smart_cmds & 1)
+ fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_NOOP;
+
+ fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_INTERRUPT;
+ fbi->smart_cmds[fbi->n_smart_cmds++] = SMART_CMD_WAIT_FOR_VSYNC;
+ setup_smart_dma(fbi);
+
+ /* continue to execute next command */
+ prsr = lcd_readl(fbi, PRSR) | PRSR_ST_OK | PRSR_CON_NT;
+ lcd_writel(fbi, PRSR, prsr);
+
+ /* stop the processor in case it executed "wait for sync" cmd */
+ lcd_writel(fbi, CMDCR, 0x0001);
+
+ /* don't send interrupts for fifo underruns on channel 6 */
+ lcd_writel(fbi, LCCR5, LCCR5_IUM(6));
+
+ lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
+ lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
+ lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
+ lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
+ lcd_writel(fbi, FDADR6, fbi->fdadr[6]);
+
+ /* begin sending */
+ lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
+
+ if (wait_for_completion_timeout(&fbi->command_done, HZ/2) == 0) {
+ pr_warning("%s: timeout waiting for command done\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ }
+
+ /* quick disable */
+ prsr = lcd_readl(fbi, PRSR) & ~(PRSR_ST_OK | PRSR_CON_NT);
+ lcd_writel(fbi, PRSR, prsr);
+ lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
+ lcd_writel(fbi, FDADR6, 0);
+ fbi->n_smart_cmds = 0;
+ return ret;
+}
+
+int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds)
+{
+ int i;
+ struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb);
+
+ /* leave 2 commands for INTERRUPT and WAIT_FOR_SYNC */
+ for (i = 0; i < n_cmds; i++) {
+ if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8)
+ pxafb_smart_flush(info);
+
+ fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds++;
+ }
+
+ return 0;
+}
+
+static unsigned int __smart_timing(unsigned time_ns, unsigned long lcd_clk)
+{
+ unsigned int t = (time_ns * (lcd_clk / 1000000) / 1000);
+ return (t == 0) ? 1 : t;
+}
+
+static void setup_smart_timing(struct pxafb_info *fbi,
+ struct fb_var_screeninfo *var)
+{
+ struct pxafb_mach_info *inf = fbi->dev->platform_data;
+ struct pxafb_mode_info *mode = &inf->modes[0];
+ unsigned long lclk = clk_get_rate(fbi->clk);
+ unsigned t1, t2, t3, t4;
+
+ t1 = max(mode->a0csrd_set_hld, mode->a0cswr_set_hld);
+ t2 = max(mode->rd_pulse_width, mode->wr_pulse_width);
+ t3 = mode->op_hold_time;
+ t4 = mode->cmd_inh_time;
+
+ fbi->reg_lccr1 =
+ LCCR1_DisWdth(var->xres) |
+ LCCR1_BegLnDel(__smart_timing(t1, lclk)) |
+ LCCR1_EndLnDel(__smart_timing(t2, lclk)) |
+ LCCR1_HorSnchWdth(__smart_timing(t3, lclk));
+
+ fbi->reg_lccr2 = LCCR2_DisHght(var->yres);
+ fbi->reg_lccr3 = LCCR3_PixClkDiv(__smart_timing(t4, lclk));
+
+ /* FIXME: make this configurable */
+ fbi->reg_cmdcr = 1;
+}
+
+static int pxafb_smart_thread(void *arg)
+{
+ struct pxafb_info *fbi = arg;
+ struct pxafb_mach_info *inf = fbi->dev->platform_data;
+
+ if (!fbi || !inf->smart_update) {
+ pr_err("%s: not properly initialized, thread terminated\n",
+ __func__);
+ return -EINVAL;
+ }
- new_regs.lccr1 =
+ pr_debug("%s(): task starting\n", __func__);
+
+ set_freezable();
+ while (!kthread_should_stop()) {
+
+ if (try_to_freeze())
+ continue;
+
+ if (fbi->state == C_ENABLE) {
+ inf->smart_update(&fbi->fb);
+ complete(&fbi->refresh_done);
+ }
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(30 * HZ / 1000);
+ }
+
+ pr_debug("%s(): task ending\n", __func__);
+ return 0;
+}
+
+static int pxafb_smart_init(struct pxafb_info *fbi)
+{
+ fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi,
+ "lcd_refresh");
+ if (IS_ERR(fbi->smart_thread)) {
+ printk(KERN_ERR "%s: unable to create kernel thread\n",
+ __func__);
+ return PTR_ERR(fbi->smart_thread);
+ }
+ return 0;
+}
+#else
+int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds)
+{
+ return 0;
+}
+
+int pxafb_smart_flush(struct fb_info *info)
+{
+ return 0;
+}
+#endif /* CONFIG_FB_SMART_PANEL */
+
+static void setup_parallel_timing(struct pxafb_info *fbi,
+ struct fb_var_screeninfo *var)
+{
+ unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
+
+ fbi->reg_lccr1 =
LCCR1_DisWdth(var->xres) +
LCCR1_HorSnchWdth(var->hsync_len) +
LCCR1_BegLnDel(var->left_margin) +
@@ -654,110 +792,118 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
lines_per_panel /= 2;
- new_regs.lccr2 =
+ fbi->reg_lccr2 =
LCCR2_DisHght(lines_per_panel) +
LCCR2_VrtSnchWdth(var->vsync_len) +
LCCR2_BegFrmDel(var->upper_margin) +
LCCR2_EndFrmDel(var->lower_margin);
- new_regs.lccr3 = fbi->lccr3 |
- pxafb_bpp_to_lccr3(var) |
- (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
- (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
+ fbi->reg_lccr3 = fbi->lccr3 |
+ (var->sync & FB_SYNC_HOR_HIGH_ACT ?
+ LCCR3_HorSnchH : LCCR3_HorSnchL) |
+ (var->sync & FB_SYNC_VERT_HIGH_ACT ?
+ LCCR3_VrtSnchH : LCCR3_VrtSnchL);
+
+ if (pcd) {
+ fbi->reg_lccr3 |= LCCR3_PixClkDiv(pcd);
+ set_hsync_time(fbi, pcd);
+ }
+}
- if (pcd)
- new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
+/*
+ * pxafb_activate_var():
+ * Configures LCD Controller based on entries in var parameter.
+ * Settings are only written to the controller if changes were made.
+ */
+static int pxafb_activate_var(struct fb_var_screeninfo *var,
+ struct pxafb_info *fbi)
+{
+ u_long flags;
+ size_t nbytes;
- pr_debug("nlccr0 = 0x%08x\n", new_regs.lccr0);
- pr_debug("nlccr1 = 0x%08x\n", new_regs.lccr1);
- pr_debug("nlccr2 = 0x%08x\n", new_regs.lccr2);
- pr_debug("nlccr3 = 0x%08x\n", new_regs.lccr3);
+#if DEBUG_VAR
+ if (!(fbi->lccr0 & LCCR0_LCDT)) {
+ if (var->xres < 16 || var->xres > 1024)
+ printk(KERN_ERR "%s: invalid xres %d\n",
+ fbi->fb.fix.id, var->xres);
+ switch (var->bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ break;
+ default:
+ printk(KERN_ERR "%s: invalid bit depth %d\n",
+ fbi->fb.fix.id, var->bits_per_pixel);
+ break;
+ }
+ if (var->hsync_len < 1 || var->hsync_len > 64)
+ printk(KERN_ERR "%s: invalid hsync_len %d\n",
+ fbi->fb.fix.id, var->hsync_len);
+ if (var->left_margin < 1 || var->left_margin > 255)
+ printk(KERN_ERR "%s: invalid left_margin %d\n",
+ fbi->fb.fix.id, var->left_margin);
+ if (var->right_margin < 1 || var->right_margin > 255)
+ printk(KERN_ERR "%s: invalid right_margin %d\n",
+ fbi->fb.fix.id, var->right_margin);
+ if (var->yres < 1 || var->yres > 1024)
+ printk(KERN_ERR "%s: invalid yres %d\n",
+ fbi->fb.fix.id, var->yres);
+ if (var->vsync_len < 1 || var->vsync_len > 64)
+ printk(KERN_ERR "%s: invalid vsync_len %d\n",
+ fbi->fb.fix.id, var->vsync_len);
+ if (var->upper_margin < 0 || var->upper_margin > 255)
+ printk(KERN_ERR "%s: invalid upper_margin %d\n",
+ fbi->fb.fix.id, var->upper_margin);
+ if (var->lower_margin < 0 || var->lower_margin > 255)
+ printk(KERN_ERR "%s: invalid lower_margin %d\n",
+ fbi->fb.fix.id, var->lower_margin);
+ }
+#endif
/* Update shadow copy atomically */
local_irq_save(flags);
- /* setup dma descriptors */
- fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 3*16);
- fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 2*16);
- fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 1*16);
-
- fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16;
- fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16;
- fbi->dmadesc_palette_dma = fbi->palette_dma - 1*16;
-
-#define BYTES_PER_PANEL (lines_per_panel * fbi->fb.fix.line_length)
-
- /* populate descriptors */
- fbi->dmadesc_fblow_cpu->fdadr = fbi->dmadesc_fblow_dma;
- fbi->dmadesc_fblow_cpu->fsadr = fbi->screen_dma + BYTES_PER_PANEL;
- fbi->dmadesc_fblow_cpu->fidr = 0;
- fbi->dmadesc_fblow_cpu->ldcmd = BYTES_PER_PANEL;
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ if (fbi->lccr0 & LCCR0_LCDT)
+ setup_smart_timing(fbi, var);
+ else
+#endif
+ setup_parallel_timing(fbi, var);
- fbi->fdadr1 = fbi->dmadesc_fblow_dma; /* only used in dual-panel mode */
+ fbi->reg_lccr0 = fbi->lccr0 |
+ (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
+ LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
- fbi->dmadesc_fbhigh_cpu->fsadr = fbi->screen_dma;
- fbi->dmadesc_fbhigh_cpu->fidr = 0;
- fbi->dmadesc_fbhigh_cpu->ldcmd = BYTES_PER_PANEL;
+ fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
- fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
- fbi->dmadesc_palette_cpu->fidr = 0;
- if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
- fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
- sizeof(u16);
- else
- fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
- sizeof(u32);
- fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
+ nbytes = var->yres * fbi->fb.fix.line_length;
- if (var->bits_per_pixel == 16) {
- /* palette shouldn't be loaded in true-color mode */
- fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
- fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
- /* init it to something, even though we won't be using it */
- fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma;
- } else {
- fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
- fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
- fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
+ if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
+ nbytes = nbytes / 2;
+ setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes);
}
-#if 0
- pr_debug("fbi->dmadesc_fblow_cpu = 0x%p\n", fbi->dmadesc_fblow_cpu);
- pr_debug("fbi->dmadesc_fbhigh_cpu = 0x%p\n", fbi->dmadesc_fbhigh_cpu);
- pr_debug("fbi->dmadesc_palette_cpu = 0x%p\n", fbi->dmadesc_palette_cpu);
- pr_debug("fbi->dmadesc_fblow_dma = 0x%x\n", fbi->dmadesc_fblow_dma);
- pr_debug("fbi->dmadesc_fbhigh_dma = 0x%x\n", fbi->dmadesc_fbhigh_dma);
- pr_debug("fbi->dmadesc_palette_dma = 0x%x\n", fbi->dmadesc_palette_dma);
-
- pr_debug("fbi->dmadesc_fblow_cpu->fdadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fdadr);
- pr_debug("fbi->dmadesc_fbhigh_cpu->fdadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fdadr);
- pr_debug("fbi->dmadesc_palette_cpu->fdadr = 0x%x\n", fbi->dmadesc_palette_cpu->fdadr);
-
- pr_debug("fbi->dmadesc_fblow_cpu->fsadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fsadr);
- pr_debug("fbi->dmadesc_fbhigh_cpu->fsadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fsadr);
- pr_debug("fbi->dmadesc_palette_cpu->fsadr = 0x%x\n", fbi->dmadesc_palette_cpu->fsadr);
-
- pr_debug("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd);
- pr_debug("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd);
- pr_debug("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
-#endif
+ if ((var->bits_per_pixel >= 16) || (fbi->lccr0 & LCCR0_LCDT))
+ setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes);
+ else
+ setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes);
- fbi->reg_lccr0 = new_regs.lccr0;
- fbi->reg_lccr1 = new_regs.lccr1;
- fbi->reg_lccr2 = new_regs.lccr2;
- fbi->reg_lccr3 = new_regs.lccr3;
- fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
+ fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
- set_hsync_time(fbi, pcd);
local_irq_restore(flags);
/*
* Only update the registers if the controller is enabled
* and something has changed.
*/
- if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) ||
- (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) ||
- (FDADR0 != fbi->fdadr0) || (FDADR1 != fbi->fdadr1))
+ if ((lcd_readl(fbi, LCCR0) != fbi->reg_lccr0) ||
+ (lcd_readl(fbi, LCCR1) != fbi->reg_lccr1) ||
+ (lcd_readl(fbi, LCCR2) != fbi->reg_lccr2) ||
+ (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
+ (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
+ (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
pxafb_schedule_work(fbi, C_REENABLE);
return 0;
@@ -773,8 +919,8 @@ static inline void __pxafb_backlight_power(struct pxafb_info *fbi, int on)
{
pr_debug("pxafb: backlight o%s\n", on ? "n" : "ff");
- if (pxafb_backlight_power)
- pxafb_backlight_power(on);
+ if (pxafb_backlight_power)
+ pxafb_backlight_power(on);
}
static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
@@ -788,11 +934,11 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
static void pxafb_setup_gpio(struct pxafb_info *fbi)
{
int gpio, ldd_bits;
- unsigned int lccr0 = fbi->lccr0;
+ unsigned int lccr0 = fbi->lccr0;
/*
* setup is based on type of panel supported
- */
+ */
/* 4 bit interface */
if ((lccr0 & LCCR0_CMS) == LCCR0_Mono &&
@@ -801,21 +947,25 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
ldd_bits = 4;
/* 8 bit interface */
- else if (((lccr0 & LCCR0_CMS) == LCCR0_Mono &&
- ((lccr0 & LCCR0_SDS) == LCCR0_Dual || (lccr0 & LCCR0_DPD) == LCCR0_8PixMono)) ||
- ((lccr0 & LCCR0_CMS) == LCCR0_Color &&
- (lccr0 & LCCR0_PAS) == LCCR0_Pas && (lccr0 & LCCR0_SDS) == LCCR0_Sngl))
+ else if (((lccr0 & LCCR0_CMS) == LCCR0_Mono &&
+ ((lccr0 & LCCR0_SDS) == LCCR0_Dual ||
+ (lccr0 & LCCR0_DPD) == LCCR0_8PixMono)) ||
+ ((lccr0 & LCCR0_CMS) == LCCR0_Color &&
+ (lccr0 & LCCR0_PAS) == LCCR0_Pas &&
+ (lccr0 & LCCR0_SDS) == LCCR0_Sngl))
ldd_bits = 8;
/* 16 bit interface */
else if ((lccr0 & LCCR0_CMS) == LCCR0_Color &&
- ((lccr0 & LCCR0_SDS) == LCCR0_Dual || (lccr0 & LCCR0_PAS) == LCCR0_Act))
+ ((lccr0 & LCCR0_SDS) == LCCR0_Dual ||
+ (lccr0 & LCCR0_PAS) == LCCR0_Act))
ldd_bits = 16;
else {
- printk(KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
+ printk(KERN_ERR "pxafb_setup_gpio: unable to determine "
+ "bits per pixel\n");
return;
- }
+ }
for (gpio = 58; ldd_bits; gpio++, ldd_bits--)
pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT);
@@ -828,8 +978,8 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
static void pxafb_enable_controller(struct pxafb_info *fbi)
{
pr_debug("pxafb: Enabling LCD controller\n");
- pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr0);
- pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr1);
+ pr_debug("fdadr0 0x%08x\n", (unsigned int) fbi->fdadr[0]);
+ pr_debug("fdadr1 0x%08x\n", (unsigned int) fbi->fdadr[1]);
pr_debug("reg_lccr0 0x%08x\n", (unsigned int) fbi->reg_lccr0);
pr_debug("reg_lccr1 0x%08x\n", (unsigned int) fbi->reg_lccr1);
pr_debug("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
@@ -838,40 +988,40 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
/* enable LCD controller clock */
clk_enable(fbi->clk);
+ if (fbi->lccr0 & LCCR0_LCDT)
+ return;
+
/* Sequence from 11.7.10 */
- LCCR3 = fbi->reg_lccr3;
- LCCR2 = fbi->reg_lccr2;
- LCCR1 = fbi->reg_lccr1;
- LCCR0 = fbi->reg_lccr0 & ~LCCR0_ENB;
-
- FDADR0 = fbi->fdadr0;
- FDADR1 = fbi->fdadr1;
- LCCR0 |= LCCR0_ENB;
-
- pr_debug("FDADR0 0x%08x\n", (unsigned int) FDADR0);
- pr_debug("FDADR1 0x%08x\n", (unsigned int) FDADR1);
- pr_debug("LCCR0 0x%08x\n", (unsigned int) LCCR0);
- pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
- pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
- pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
- pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
+ lcd_writel(fbi, LCCR3, fbi->reg_lccr3);
+ lcd_writel(fbi, LCCR2, fbi->reg_lccr2);
+ lcd_writel(fbi, LCCR1, fbi->reg_lccr1);
+ lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
+
+ lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
+ lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
+ lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
}
static void pxafb_disable_controller(struct pxafb_info *fbi)
{
- DECLARE_WAITQUEUE(wait, current);
+ uint32_t lccr0;
- pr_debug("pxafb: disabling LCD controller\n");
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ if (fbi->lccr0 & LCCR0_LCDT) {
+ wait_for_completion_timeout(&fbi->refresh_done,
+ 200 * HZ / 1000);
+ return;
+ }
+#endif
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&fbi->ctrlr_wait, &wait);
+ /* Clear LCD Status Register */
+ lcd_writel(fbi, LCSR, 0xffffffff);
- LCSR = 0xffffffff; /* Clear LCD Status Register */
- LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
- LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
+ lccr0 = lcd_readl(fbi, LCCR0) & ~LCCR0_LDM;
+ lcd_writel(fbi, LCCR0, lccr0);
+ lcd_writel(fbi, LCCR0, lccr0 | LCCR0_DIS);
- schedule_timeout(200 * HZ / 1000);
- remove_wait_queue(&fbi->ctrlr_wait, &wait);
+ wait_for_completion_timeout(&fbi->disable_done, 200 * HZ / 1000);
/* disable LCD controller clock */
clk_disable(fbi->clk);
@@ -883,14 +1033,20 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
{
struct pxafb_info *fbi = dev_id;
- unsigned int lcsr = LCSR;
+ unsigned int lccr0, lcsr = lcd_readl(fbi, LCSR);
if (lcsr & LCSR_LDD) {
- LCCR0 |= LCCR0_LDM;
- wake_up(&fbi->ctrlr_wait);
+ lccr0 = lcd_readl(fbi, LCCR0);
+ lcd_writel(fbi, LCCR0, lccr0 | LCCR0_LDM);
+ complete(&fbi->disable_done);
}
- LCSR = lcsr;
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ if (lcsr & LCSR_CMD_INT)
+ complete(&fbi->command_done);
+#endif
+
+ lcd_writel(fbi, LCSR, lcsr);
return IRQ_HANDLED;
}
@@ -921,7 +1077,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
*/
if (old_state != C_DISABLE && old_state != C_DISABLE_PM) {
fbi->state = state;
- //TODO __pxafb_lcd_power(fbi, 0);
+ /* TODO __pxafb_lcd_power(fbi, 0); */
pxafb_disable_controller(fbi);
}
break;
@@ -948,7 +1104,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
if (old_state == C_DISABLE_CLKCHANGE) {
fbi->state = C_ENABLE;
pxafb_enable_controller(fbi);
- //TODO __pxafb_lcd_power(fbi, 1);
+ /* TODO __pxafb_lcd_power(fbi, 1); */
}
break;
@@ -1019,7 +1175,7 @@ static int
pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
{
struct pxafb_info *fbi = TO_INF(nb, freq_transition);
- //TODO struct cpufreq_freqs *f = data;
+ /* TODO struct cpufreq_freqs *f = data; */
u_int pcd;
switch (val) {
@@ -1030,7 +1186,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
case CPUFREQ_POSTCHANGE:
pcd = get_pcd(fbi, fbi->fb.var.pixclock);
set_hsync_time(fbi, pcd);
- fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
+ fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) |
+ LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
break;
}
@@ -1050,18 +1207,8 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
pr_debug("min dma period: %d ps, "
"new clock %d kHz\n", pxafb_display_dma_period(var),
policy->max);
- // TODO: fill in min/max values
- break;
-#if 0
- case CPUFREQ_NOTIFY:
- printk(KERN_ERR "%s: got CPUFREQ_NOTIFY\n", __FUNCTION__);
- do {} while(0);
- /* todo: panic if min/max values aren't fulfilled
- * [can't really happen unless there's a bug in the
- * CPU policy verification process *
- */
+ /* TODO: fill in min/max values */
break;
-#endif
}
return 0;
}
@@ -1102,21 +1249,21 @@ static int pxafb_resume(struct platform_device *dev)
*/
static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
{
- u_long palette_mem_size;
-
/*
* We reserve one page for the palette, plus the size
* of the framebuffer.
*/
- fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
+ fbi->video_offset = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));
+ fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + fbi->video_offset);
fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
&fbi->map_dma, GFP_KERNEL);
if (fbi->map_cpu) {
/* prevent initial garbage on screen */
memset(fbi->map_cpu, 0, fbi->map_size);
- fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE;
- fbi->screen_dma = fbi->map_dma + PAGE_SIZE;
+ fbi->fb.screen_base = fbi->map_cpu + fbi->video_offset;
+ fbi->screen_dma = fbi->map_dma + fbi->video_offset;
+
/*
* FIXME: this is actually the wrong thing to place in
* smem_start. But fbdev suffers from the problem that
@@ -1126,27 +1273,86 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
fbi->fb.fix.smem_start = fbi->screen_dma;
fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
- if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
- palette_mem_size = fbi->palette_size * sizeof(u16);
- else
- palette_mem_size = fbi->palette_size * sizeof(u32);
+ fbi->dma_buff = (void *) fbi->map_cpu;
+ fbi->dma_buff_phys = fbi->map_dma;
+ fbi->palette_cpu = (u16 *) fbi->dma_buff->palette;
- pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
-
- fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
- fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff;
+ fbi->n_smart_cmds = 0;
+#endif
}
return fbi->map_cpu ? 0 : -ENOMEM;
}
+static void pxafb_decode_mode_info(struct pxafb_info *fbi,
+ struct pxafb_mode_info *modes,
+ unsigned int num_modes)
+{
+ unsigned int i, smemlen;
+
+ pxafb_setmode(&fbi->fb.var, &modes[0]);
+
+ for (i = 0; i < num_modes; i++) {
+ smemlen = modes[i].xres * modes[i].yres * modes[i].bpp / 8;
+ if (smemlen > fbi->fb.fix.smem_len)
+ fbi->fb.fix.smem_len = smemlen;
+ }
+}
+
+static int pxafb_decode_mach_info(struct pxafb_info *fbi,
+ struct pxafb_mach_info *inf)
+{
+ unsigned int lcd_conn = inf->lcd_conn;
+
+ fbi->cmap_inverse = inf->cmap_inverse;
+ fbi->cmap_static = inf->cmap_static;
+
+ switch (lcd_conn & 0xf) {
+ case LCD_TYPE_MONO_STN:
+ fbi->lccr0 = LCCR0_CMS;
+ break;
+ case LCD_TYPE_MONO_DSTN:
+ fbi->lccr0 = LCCR0_CMS | LCCR0_SDS;
+ break;
+ case LCD_TYPE_COLOR_STN:
+ fbi->lccr0 = 0;
+ break;
+ case LCD_TYPE_COLOR_DSTN:
+ fbi->lccr0 = LCCR0_SDS;
+ break;
+ case LCD_TYPE_COLOR_TFT:
+ fbi->lccr0 = LCCR0_PAS;
+ break;
+ case LCD_TYPE_SMART_PANEL:
+ fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS;
+ break;
+ default:
+ /* fall back to backward compatibility way */
+ fbi->lccr0 = inf->lccr0;
+ fbi->lccr3 = inf->lccr3;
+ fbi->lccr4 = inf->lccr4;
+ return -EINVAL;
+ }
+
+ if (lcd_conn == LCD_MONO_STN_8BPP)
+ fbi->lccr0 |= LCCR0_DPD;
+
+ fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff);
+ fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
+ fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;
+
+ pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
+ return 0;
+}
+
static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
{
struct pxafb_info *fbi;
void *addr;
struct pxafb_mach_info *inf = dev->platform_data;
struct pxafb_mode_info *mode = inf->modes;
- int i, smemlen;
/* Alloc the pxafb_info and pseudo_palette in one step */
fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1186,187 +1392,233 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
addr = addr + sizeof(struct pxafb_info);
fbi->fb.pseudo_palette = addr;
- pxafb_setmode(&fbi->fb.var, mode);
+ fbi->state = C_STARTUP;
+ fbi->task_state = (u_char)-1;
- fbi->cmap_inverse = inf->cmap_inverse;
- fbi->cmap_static = inf->cmap_static;
-
- fbi->lccr0 = inf->lccr0;
- fbi->lccr3 = inf->lccr3;
- fbi->lccr4 = inf->lccr4;
- fbi->state = C_STARTUP;
- fbi->task_state = (u_char)-1;
-
- for (i = 0; i < inf->num_modes; i++) {
- smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
- if (smemlen > fbi->fb.fix.smem_len)
- fbi->fb.fix.smem_len = smemlen;
- }
+ pxafb_decode_mach_info(fbi, inf);
init_waitqueue_head(&fbi->ctrlr_wait);
INIT_WORK(&fbi->task, pxafb_task);
init_MUTEX(&fbi->ctrlr_sem);
+ init_completion(&fbi->disable_done);
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ init_completion(&fbi->command_done);
+ init_completion(&fbi->refresh_done);
+#endif
return fbi;
}
#ifdef CONFIG_FB_PXA_PARAMETERS
-static int __init pxafb_parse_options(struct device *dev, char *options)
+static int __init parse_opt_mode(struct device *dev, const char *this_opt)
+{
+ struct pxafb_mach_info *inf = dev->platform_data;
+
+ const char *name = this_opt+5;
+ unsigned int namelen = strlen(name);
+ int res_specified = 0, bpp_specified = 0;
+ unsigned int xres = 0, yres = 0, bpp = 0;
+ int yres_specified = 0;
+ int i;
+ for (i = namelen-1; i >= 0; i--) {
+ switch (name[i]) {
+ case '-':
+ namelen = i;
+ if (!bpp_specified && !yres_specified) {
+ bpp = simple_strtoul(&name[i+1], NULL, 0);
+ bpp_specified = 1;
+ } else
+ goto done;
+ break;
+ case 'x':
+ if (!yres_specified) {
+ yres = simple_strtoul(&name[i+1], NULL, 0);
+ yres_specified = 1;
+ } else
+ goto done;
+ break;
+ case '0' ... '9':
+ break;
+ default:
+ goto done;
+ }
+ }
+ if (i < 0 && yres_specified) {
+ xres = simple_strtoul(name, NULL, 0);
+ res_specified = 1;
+ }
+done:
+ if (res_specified) {
+ dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
+ inf->modes[0].xres = xres; inf->modes[0].yres = yres;
+ }
+ if (bpp_specified)
+ switch (bpp) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ inf->modes[0].bpp = bpp;
+ dev_info(dev, "overriding bit depth: %d\n", bpp);
+ break;
+ default:
+ dev_err(dev, "Depth %d is not valid\n", bpp);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int __init parse_opt(struct device *dev, char *this_opt)
{
struct pxafb_mach_info *inf = dev->platform_data;
+ struct pxafb_mode_info *mode = &inf->modes[0];
+ char s[64];
+
+ s[0] = '\0';
+
+ if (!strncmp(this_opt, "mode:", 5)) {
+ return parse_opt_mode(dev, this_opt);
+ } else if (!strncmp(this_opt, "pixclock:", 9)) {
+ mode->pixclock = simple_strtoul(this_opt+9, NULL, 0);
+ sprintf(s, "pixclock: %ld\n", mode->pixclock);
+ } else if (!strncmp(this_opt, "left:", 5)) {
+ mode->left_margin = simple_strtoul(this_opt+5, NULL, 0);
+ sprintf(s, "left: %u\n", mode->left_margin);
+ } else if (!strncmp(this_opt, "right:", 6)) {
+ mode->right_margin = simple_strtoul(this_opt+6, NULL, 0);
+ sprintf(s, "right: %u\n", mode->right_margin);
+ } else if (!strncmp(this_opt, "upper:", 6)) {
+ mode->upper_margin = simple_strtoul(this_opt+6, NULL, 0);
+ sprintf(s, "upper: %u\n", mode->upper_margin);
+ } else if (!strncmp(this_opt, "lower:", 6)) {
+ mode->lower_margin = simple_strtoul(this_opt+6, NULL, 0);
+ sprintf(s, "lower: %u\n", mode->lower_margin);
+ } else if (!strncmp(this_opt, "hsynclen:", 9)) {
+ mode->hsync_len = simple_strtoul(this_opt+9, NULL, 0);
+ sprintf(s, "hsynclen: %u\n", mode->hsync_len);
+ } else if (!strncmp(this_opt, "vsynclen:", 9)) {
+ mode->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
+ sprintf(s, "vsynclen: %u\n", mode->vsync_len);
+ } else if (!strncmp(this_opt, "hsync:", 6)) {
+ if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
+ sprintf(s, "hsync: Active Low\n");
+ mode->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ } else {
+ sprintf(s, "hsync: Active High\n");
+ mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ }
+ } else if (!strncmp(this_opt, "vsync:", 6)) {
+ if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
+ sprintf(s, "vsync: Active Low\n");
+ mode->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ } else {
+ sprintf(s, "vsync: Active High\n");
+ mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ }
+ } else if (!strncmp(this_opt, "dpc:", 4)) {
+ if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
+ sprintf(s, "double pixel clock: false\n");
+ inf->lccr3 &= ~LCCR3_DPC;
+ } else {
+ sprintf(s, "double pixel clock: true\n");
+ inf->lccr3 |= LCCR3_DPC;
+ }
+ } else if (!strncmp(this_opt, "outputen:", 9)) {
+ if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
+ sprintf(s, "output enable: active low\n");
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
+ } else {
+ sprintf(s, "output enable: active high\n");
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
+ }
+ } else if (!strncmp(this_opt, "pixclockpol:", 12)) {
+ if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
+ sprintf(s, "pixel clock polarity: falling edge\n");
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
+ } else {
+ sprintf(s, "pixel clock polarity: rising edge\n");
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
+ }
+ } else if (!strncmp(this_opt, "color", 5)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
+ } else if (!strncmp(this_opt, "mono", 4)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono;
+ } else if (!strncmp(this_opt, "active", 6)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act;
+ } else if (!strncmp(this_opt, "passive", 7)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas;
+ } else if (!strncmp(this_opt, "single", 6)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl;
+ } else if (!strncmp(this_opt, "dual", 4)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual;
+ } else if (!strncmp(this_opt, "4pix", 4)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono;
+ } else if (!strncmp(this_opt, "8pix", 4)) {
+ inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono;
+ } else {
+ dev_err(dev, "unknown option: %s\n", this_opt);
+ return -EINVAL;
+ }
+
+ if (s[0] != '\0')
+ dev_info(dev, "override %s", s);
+
+ return 0;
+}
+
+static int __init pxafb_parse_options(struct device *dev, char *options)
+{
char *this_opt;
+ int ret;
- if (!options || !*options)
- return 0;
+ if (!options || !*options)
+ return 0;
dev_dbg(dev, "options are \"%s\"\n", options ? options : "null");
/* could be made table driven or similar?... */
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!strncmp(this_opt, "mode:", 5)) {
- const char *name = this_opt+5;
- unsigned int namelen = strlen(name);
- int res_specified = 0, bpp_specified = 0;
- unsigned int xres = 0, yres = 0, bpp = 0;
- int yres_specified = 0;
- int i;
- for (i = namelen-1; i >= 0; i--) {
- switch (name[i]) {
- case '-':
- namelen = i;
- if (!bpp_specified && !yres_specified) {
- bpp = simple_strtoul(&name[i+1], NULL, 0);
- bpp_specified = 1;
- } else
- goto done;
- break;
- case 'x':
- if (!yres_specified) {
- yres = simple_strtoul(&name[i+1], NULL, 0);
- yres_specified = 1;
- } else
- goto done;
- break;
- case '0' ... '9':
- break;
- default:
- goto done;
- }
- }
- if (i < 0 && yres_specified) {
- xres = simple_strtoul(name, NULL, 0);
- res_specified = 1;
- }
- done:
- if (res_specified) {
- dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
- inf->modes[0].xres = xres; inf->modes[0].yres = yres;
- }
- if (bpp_specified)
- switch (bpp) {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- inf->modes[0].bpp = bpp;
- dev_info(dev, "overriding bit depth: %d\n", bpp);
- break;
- default:
- dev_err(dev, "Depth %d is not valid\n", bpp);
- }
- } else if (!strncmp(this_opt, "pixclock:", 9)) {
- inf->modes[0].pixclock = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override pixclock: %ld\n", inf->modes[0].pixclock);
- } else if (!strncmp(this_opt, "left:", 5)) {
- inf->modes[0].left_margin = simple_strtoul(this_opt+5, NULL, 0);
- dev_info(dev, "override left: %u\n", inf->modes[0].left_margin);
- } else if (!strncmp(this_opt, "right:", 6)) {
- inf->modes[0].right_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override right: %u\n", inf->modes[0].right_margin);
- } else if (!strncmp(this_opt, "upper:", 6)) {
- inf->modes[0].upper_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override upper: %u\n", inf->modes[0].upper_margin);
- } else if (!strncmp(this_opt, "lower:", 6)) {
- inf->modes[0].lower_margin = simple_strtoul(this_opt+6, NULL, 0);
- dev_info(dev, "override lower: %u\n", inf->modes[0].lower_margin);
- } else if (!strncmp(this_opt, "hsynclen:", 9)) {
- inf->modes[0].hsync_len = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override hsynclen: %u\n", inf->modes[0].hsync_len);
- } else if (!strncmp(this_opt, "vsynclen:", 9)) {
- inf->modes[0].vsync_len = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override vsynclen: %u\n", inf->modes[0].vsync_len);
- } else if (!strncmp(this_opt, "hsync:", 6)) {
- if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
- dev_info(dev, "override hsync: Active Low\n");
- inf->modes[0].sync &= ~FB_SYNC_HOR_HIGH_ACT;
- } else {
- dev_info(dev, "override hsync: Active High\n");
- inf->modes[0].sync |= FB_SYNC_HOR_HIGH_ACT;
- }
- } else if (!strncmp(this_opt, "vsync:", 6)) {
- if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
- dev_info(dev, "override vsync: Active Low\n");
- inf->modes[0].sync &= ~FB_SYNC_VERT_HIGH_ACT;
- } else {
- dev_info(dev, "override vsync: Active High\n");
- inf->modes[0].sync |= FB_SYNC_VERT_HIGH_ACT;
- }
- } else if (!strncmp(this_opt, "dpc:", 4)) {
- if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
- dev_info(dev, "override double pixel clock: false\n");
- inf->lccr3 &= ~LCCR3_DPC;
- } else {
- dev_info(dev, "override double pixel clock: true\n");
- inf->lccr3 |= LCCR3_DPC;
- }
- } else if (!strncmp(this_opt, "outputen:", 9)) {
- if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
- dev_info(dev, "override output enable: active low\n");
- inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
- } else {
- dev_info(dev, "override output enable: active high\n");
- inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
- }
- } else if (!strncmp(this_opt, "pixclockpol:", 12)) {
- if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
- dev_info(dev, "override pixel clock polarity: falling edge\n");
- inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
- } else {
- dev_info(dev, "override pixel clock polarity: rising edge\n");
- inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
- }
- } else if (!strncmp(this_opt, "color", 5)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
- } else if (!strncmp(this_opt, "mono", 4)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Mono;
- } else if (!strncmp(this_opt, "active", 6)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Act;
- } else if (!strncmp(this_opt, "passive", 7)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_PAS) | LCCR0_Pas;
- } else if (!strncmp(this_opt, "single", 6)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Sngl;
- } else if (!strncmp(this_opt, "dual", 4)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_SDS) | LCCR0_Dual;
- } else if (!strncmp(this_opt, "4pix", 4)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_4PixMono;
- } else if (!strncmp(this_opt, "8pix", 4)) {
- inf->lccr0 = (inf->lccr0 & ~LCCR0_DPD) | LCCR0_8PixMono;
- } else {
- dev_err(dev, "unknown option: %s\n", this_opt);
- return -EINVAL;
- }
- }
- return 0;
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ ret = parse_opt(dev, this_opt);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static char g_options[256] __devinitdata = "";
+#ifndef CONFIG_MODULES
+static int __devinit pxafb_setup_options(void)
+{
+ char *options = NULL;
+
+ if (fb_get_options("pxafb", &options))
+ return -ENODEV;
+
+ if (options)
+ strlcpy(g_options, options, sizeof(g_options));
+
+ return 0;
}
+#else
+#define pxafb_setup_options() (0)
+
+module_param_string(options, g_options, sizeof(g_options), 0);
+MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
+#endif
+
+#else
+#define pxafb_parse_options(...) (0)
+#define pxafb_setup_options() (0)
#endif
static int __init pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
struct pxafb_mach_info *inf;
- int ret;
+ struct resource *r;
+ int irq, ret;
dev_dbg(&dev->dev, "pxafb_probe\n");
@@ -1376,38 +1628,45 @@ static int __init pxafb_probe(struct platform_device *dev)
if (!inf)
goto failed;
-#ifdef CONFIG_FB_PXA_PARAMETERS
ret = pxafb_parse_options(&dev->dev, g_options);
if (ret < 0)
goto failed;
-#endif
#ifdef DEBUG_VAR
- /* Check for various illegal bit-combinations. Currently only
+ /* Check for various illegal bit-combinations. Currently only
* a warning is given. */
- if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
- dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n",
- inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
- if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
- dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
- inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
- if (inf->lccr0 & LCCR0_DPD &&
+ if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
+ dev_warn(&dev->dev, "machine LCCR0 setting contains "
+ "illegal bits: %08x\n",
+ inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
+ if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
+ dev_warn(&dev->dev, "machine LCCR3 setting contains "
+ "illegal bits: %08x\n",
+ inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
+ if (inf->lccr0 & LCCR0_DPD &&
((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
(inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
(inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
- dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
- " single panel mode\n");
- if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
+ dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is "
+ "only valid in passive mono"
+ " single panel mode\n");
+ if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
(inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
- dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
- if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
- (inf->modes->upper_margin || inf->modes->lower_margin))
- dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
+ dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
+ if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
+ (inf->modes->upper_margin || inf->modes->lower_margin))
+ dev_warn(&dev->dev, "Upper and lower margins must be 0 in "
+ "passive mode\n");
#endif
- dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp);
- if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) {
+ dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",
+ inf->modes->xres,
+ inf->modes->yres,
+ inf->modes->bpp);
+ if (inf->modes->xres == 0 ||
+ inf->modes->yres == 0 ||
+ inf->modes->bpp == 0) {
dev_err(&dev->dev, "Invalid resolution or bit depth\n");
ret = -EINVAL;
goto failed;
@@ -1416,26 +1675,62 @@ static int __init pxafb_probe(struct platform_device *dev)
pxafb_lcd_power = inf->pxafb_lcd_power;
fbi = pxafb_init_fbinfo(&dev->dev);
if (!fbi) {
+ /* only reason for pxafb_init_fbinfo to fail is kmalloc */
dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
- ret = -ENOMEM; // only reason for pxafb_init_fbinfo to fail is kmalloc
+ ret = -ENOMEM;
goto failed;
}
+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&dev->dev, "no I/O memory resource defined\n");
+ ret = -ENODEV;
+ goto failed;
+ }
+
+ r = request_mem_region(r->start, r->end - r->start + 1, dev->name);
+ if (r == NULL) {
+ dev_err(&dev->dev, "failed to request I/O memory\n");
+ ret = -EBUSY;
+ goto failed;
+ }
+
+ fbi->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ if (fbi->mmio_base == NULL) {
+ dev_err(&dev->dev, "failed to map I/O memory\n");
+ ret = -EBUSY;
+ goto failed_free_res;
+ }
+
/* Initialize video memory */
ret = pxafb_map_video_memory(fbi);
if (ret) {
dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
- goto failed;
+ goto failed_free_io;
+ }
+
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0) {
+ dev_err(&dev->dev, "no IRQ defined\n");
+ ret = -ENODEV;
+ goto failed_free_mem;
}
- ret = request_irq(IRQ_LCD, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi);
+ ret = request_irq(irq, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi);
if (ret) {
dev_err(&dev->dev, "request_irq failed: %d\n", ret);
ret = -EBUSY;
- goto failed;
+ goto failed_free_mem;
}
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ ret = pxafb_smart_init(fbi);
+ if (ret) {
+ dev_err(&dev->dev, "failed to initialize smartpanel\n");
+ goto failed_free_irq;
+ }
+#endif
/*
* This makes sure that our colour bitfield
* descriptors are correctly initialised.
@@ -1447,19 +1742,18 @@ static int __init pxafb_probe(struct platform_device *dev)
ret = register_framebuffer(&fbi->fb);
if (ret < 0) {
- dev_err(&dev->dev, "Failed to register framebuffer device: %d\n", ret);
- goto failed;
+ dev_err(&dev->dev,
+ "Failed to register framebuffer device: %d\n", ret);
+ goto failed_free_irq;
}
-#ifdef CONFIG_PM
- // TODO
-#endif
-
#ifdef CONFIG_CPU_FREQ
fbi->freq_transition.notifier_call = pxafb_freq_transition;
fbi->freq_policy.notifier_call = pxafb_freq_policy;
- cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
- cpufreq_register_notifier(&fbi->freq_policy, CPUFREQ_POLICY_NOTIFIER);
+ cpufreq_register_notifier(&fbi->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ cpufreq_register_notifier(&fbi->freq_policy,
+ CPUFREQ_POLICY_NOTIFIER);
#endif
/*
@@ -1469,6 +1763,15 @@ static int __init pxafb_probe(struct platform_device *dev)
return 0;
+failed_free_irq:
+ free_irq(irq, fbi);
+failed_free_res:
+ release_mem_region(r->start, r->end - r->start + 1);
+failed_free_io:
+ iounmap(fbi->mmio_base);
+failed_free_mem:
+ dma_free_writecombine(&dev->dev, fbi->map_size,
+ fbi->map_cpu, fbi->map_dma);
failed:
platform_set_drvdata(dev, NULL);
kfree(fbi);
@@ -1477,40 +1780,18 @@ failed:
static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
-#ifdef CONFIG_PM
.suspend = pxafb_suspend,
.resume = pxafb_resume,
-#endif
.driver = {
.name = "pxa2xx-fb",
},
};
-#ifndef MODULE
-static int __devinit pxafb_setup(char *options)
-{
-# ifdef CONFIG_FB_PXA_PARAMETERS
- if (options)
- strlcpy(g_options, options, sizeof(g_options));
-# endif
- return 0;
-}
-#else
-# ifdef CONFIG_FB_PXA_PARAMETERS
-module_param_string(options, g_options, sizeof(g_options), 0);
-MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
-# endif
-#endif
-
static int __devinit pxafb_init(void)
{
-#ifndef MODULE
- char *option = NULL;
+ if (pxafb_setup_options())
+ return -EINVAL;
- if (fb_get_options("pxafb", &option))
- return -ENODEV;
- pxafb_setup(option);
-#endif
return platform_driver_register(&pxafb_driver);
}
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index d920b8a14c3..8238dc82642 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -21,14 +21,6 @@
* for more details.
*/
-/* Shadows for LCD controller registers */
-struct pxafb_lcd_reg {
- unsigned int lccr0;
- unsigned int lccr1;
- unsigned int lccr2;
- unsigned int lccr3;
-};
-
/* PXA LCD DMA descriptor */
struct pxafb_dma_descriptor {
unsigned int fdadr;
@@ -37,11 +29,49 @@ struct pxafb_dma_descriptor {
unsigned int ldcmd;
};
+enum {
+ PAL_NONE = -1,
+ PAL_BASE = 0,
+ PAL_OV1 = 1,
+ PAL_OV2 = 2,
+ PAL_MAX,
+};
+
+enum {
+ DMA_BASE = 0,
+ DMA_UPPER = 0,
+ DMA_LOWER = 1,
+ DMA_OV1 = 1,
+ DMA_OV2_Y = 2,
+ DMA_OV2_Cb = 3,
+ DMA_OV2_Cr = 4,
+ DMA_CURSOR = 5,
+ DMA_CMD = 6,
+ DMA_MAX,
+};
+
+/* maximum palette size - 256 entries, each 4 bytes long */
+#define PALETTE_SIZE (256 * 4)
+#define CMD_BUFF_SIZE (1024 * 50)
+
+struct pxafb_dma_buff {
+ unsigned char palette[PAL_MAX * PALETTE_SIZE];
+ uint16_t cmd_buff[CMD_BUFF_SIZE];
+ struct pxafb_dma_descriptor pal_desc[PAL_MAX];
+ struct pxafb_dma_descriptor dma_desc[DMA_MAX];
+};
+
struct pxafb_info {
struct fb_info fb;
struct device *dev;
struct clk *clk;
+ void __iomem *mmio_base;
+
+ struct pxafb_dma_buff *dma_buff;
+ dma_addr_t dma_buff_phys;
+ dma_addr_t fdadr[DMA_MAX];
+
/*
* These are the addresses we mapped
* the framebuffer memory region to.
@@ -55,19 +85,8 @@ struct pxafb_info {
u_char * screen_cpu; /* virtual address of frame buffer */
dma_addr_t screen_dma; /* physical address of frame buffer */
u16 * palette_cpu; /* virtual address of palette memory */
- dma_addr_t palette_dma; /* physical address of palette memory */
u_int palette_size;
-
- /* DMA descriptors */
- struct pxafb_dma_descriptor * dmadesc_fblow_cpu;
- dma_addr_t dmadesc_fblow_dma;
- struct pxafb_dma_descriptor * dmadesc_fbhigh_cpu;
- dma_addr_t dmadesc_fbhigh_dma;
- struct pxafb_dma_descriptor * dmadesc_palette_cpu;
- dma_addr_t dmadesc_palette_dma;
-
- dma_addr_t fdadr0;
- dma_addr_t fdadr1;
+ ssize_t video_offset;
u_int lccr0;
u_int lccr3;
@@ -81,6 +100,7 @@ struct pxafb_info {
u_int reg_lccr2;
u_int reg_lccr3;
u_int reg_lccr4;
+ u_int reg_cmdcr;
unsigned long hsync_time;
@@ -90,6 +110,16 @@ struct pxafb_info {
wait_queue_head_t ctrlr_wait;
struct work_struct task;
+ struct completion disable_done;
+
+#ifdef CONFIG_FB_PXA_SMARTPANEL
+ uint16_t *smart_cmds;
+ size_t n_smart_cmds;
+ struct completion command_done;
+ struct completion refresh_done;
+ struct task_struct *smart_thread;
+#endif
+
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
struct notifier_block freq_policy;
diff --git a/drivers/w1/w1_log.h b/drivers/w1/w1_log.h
index fe6bdf43380..e6ab7cf08f8 100644
--- a/drivers/w1/w1_log.h
+++ b/drivers/w1/w1_log.h
@@ -30,7 +30,7 @@
# define assert(expr) \
if(unlikely(!(expr))) { \
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr, __FILE__, __func__, __LINE__); \
}
#endif