diff options
Diffstat (limited to 'drivers')
202 files changed, 3980 insertions, 4141 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index fd8059920dbf..6b355bd7816d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -161,8 +161,8 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
161 | return count; | 161 | return count; |
162 | } | 162 | } |
163 | 163 | ||
164 | /** | 164 | /* |
165 | * device_subsys - structure to be registered with kobject core. | 165 | * devices_subsys - structure to be registered with kobject core. |
166 | */ | 166 | */ |
167 | 167 | ||
168 | decl_subsys(devices, &ktype_device, &device_uevent_ops); | 168 | decl_subsys(devices, &ktype_device, &device_uevent_ops); |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 281d26784d25..07a7f97e1de9 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -83,6 +83,31 @@ static inline void register_cpu_control(struct cpu *cpu) | |||
83 | } | 83 | } |
84 | #endif /* CONFIG_HOTPLUG_CPU */ | 84 | #endif /* CONFIG_HOTPLUG_CPU */ |
85 | 85 | ||
86 | #ifdef CONFIG_KEXEC | ||
87 | #include <linux/kexec.h> | ||
88 | |||
89 | static ssize_t show_crash_notes(struct sys_device *dev, char *buf) | ||
90 | { | ||
91 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | ||
92 | ssize_t rc; | ||
93 | unsigned long long addr; | ||
94 | int cpunum; | ||
95 | |||
96 | cpunum = cpu->sysdev.id; | ||
97 | |||
98 | /* | ||
99 | * Might be reading other cpu's data based on which cpu read thread | ||
100 | * has been scheduled. But cpu data (memory) is allocated once during | ||
101 | * boot up and this data does not change there after. Hence this | ||
102 | * operation should be safe. No locking required. | ||
103 | */ | ||
104 | addr = __pa(per_cpu_ptr(crash_notes, cpunum)); | ||
105 | rc = sprintf(buf, "%Lx\n", addr); | ||
106 | return rc; | ||
107 | } | ||
108 | static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | ||
109 | #endif | ||
110 | |||
86 | /* | 111 | /* |
87 | * register_cpu - Setup a driverfs device for a CPU. | 112 | * register_cpu - Setup a driverfs device for a CPU. |
88 | * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to | 113 | * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to |
@@ -108,6 +133,11 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) | |||
108 | register_cpu_control(cpu); | 133 | register_cpu_control(cpu); |
109 | if (!error) | 134 | if (!error) |
110 | cpu_sys_devices[num] = &cpu->sysdev; | 135 | cpu_sys_devices[num] = &cpu->sysdev; |
136 | |||
137 | #ifdef CONFIG_KEXEC | ||
138 | if (!error) | ||
139 | error = sysdev_create_file(&cpu->sysdev, &attr_crash_notes); | ||
140 | #endif | ||
111 | return error; | 141 | return error; |
112 | } | 142 | } |
113 | 143 | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 573ff6c1be5f..613673b12fa6 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -279,6 +279,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
279 | 279 | ||
280 | tty->disc_data = hu; | 280 | tty->disc_data = hu; |
281 | hu->tty = tty; | 281 | hu->tty = tty; |
282 | tty->receive_room = 65536; | ||
282 | 283 | ||
283 | spin_lock_init(&hu->rx_lock); | 284 | spin_lock_init(&hu->rx_lock); |
284 | 285 | ||
@@ -348,20 +349,6 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
348 | hci_uart_tx_wakeup(hu); | 349 | hci_uart_tx_wakeup(hu); |
349 | } | 350 | } |
350 | 351 | ||
351 | /* hci_uart_tty_room() | ||
352 | * | ||
353 | * Callback function from tty driver. Return the amount of | ||
354 | * space left in the receiver's buffer to decide if remote | ||
355 | * transmitter is to be throttled. | ||
356 | * | ||
357 | * Arguments: tty pointer to associated tty instance data | ||
358 | * Return Value: number of bytes left in receive buffer | ||
359 | */ | ||
360 | static int hci_uart_tty_room (struct tty_struct *tty) | ||
361 | { | ||
362 | return 65536; | ||
363 | } | ||
364 | |||
365 | /* hci_uart_tty_receive() | 352 | /* hci_uart_tty_receive() |
366 | * | 353 | * |
367 | * Called by tty low level driver when receive data is | 354 | * Called by tty low level driver when receive data is |
@@ -544,7 +531,6 @@ static int __init hci_uart_init(void) | |||
544 | hci_uart_ldisc.write = hci_uart_tty_write; | 531 | hci_uart_ldisc.write = hci_uart_tty_write; |
545 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; | 532 | hci_uart_ldisc.ioctl = hci_uart_tty_ioctl; |
546 | hci_uart_ldisc.poll = hci_uart_tty_poll; | 533 | hci_uart_ldisc.poll = hci_uart_tty_poll; |
547 | hci_uart_ldisc.receive_room = hci_uart_tty_room; | ||
548 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; | 534 | hci_uart_ldisc.receive_buf = hci_uart_tty_receive; |
549 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; | 535 | hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; |
550 | hci_uart_ldisc.owner = THIS_MODULE; | 536 | hci_uart_ldisc.owner = THIS_MODULE; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index dd7e6901c575..d6fcd0a36f9f 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD | |||
80 | 80 | ||
81 | config COMPUTONE | 81 | config COMPUTONE |
82 | tristate "Computone IntelliPort Plus serial support" | 82 | tristate "Computone IntelliPort Plus serial support" |
83 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 83 | depends on SERIAL_NONSTANDARD |
84 | ---help--- | 84 | ---help--- |
85 | This driver supports the entire family of Intelliport II/Plus | 85 | This driver supports the entire family of Intelliport II/Plus |
86 | controllers with the exception of the MicroChannel controllers and | 86 | controllers with the exception of the MicroChannel controllers and |
@@ -153,7 +153,7 @@ config DIGIEPCA | |||
153 | 153 | ||
154 | config ESPSERIAL | 154 | config ESPSERIAL |
155 | tristate "Hayes ESP serial port support" | 155 | tristate "Hayes ESP serial port support" |
156 | depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API | 156 | depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API |
157 | help | 157 | help |
158 | This is a driver which supports Hayes ESP serial ports. Both single | 158 | This is a driver which supports Hayes ESP serial ports. Both single |
159 | port cards and multiport cards are supported. Make sure to read | 159 | port cards and multiport cards are supported. Make sure to read |
@@ -166,7 +166,7 @@ config ESPSERIAL | |||
166 | 166 | ||
167 | config MOXA_INTELLIO | 167 | config MOXA_INTELLIO |
168 | tristate "Moxa Intellio support" | 168 | tristate "Moxa Intellio support" |
169 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 169 | depends on SERIAL_NONSTANDARD |
170 | help | 170 | help |
171 | Say Y here if you have a Moxa Intellio multiport serial card. | 171 | Say Y here if you have a Moxa Intellio multiport serial card. |
172 | 172 | ||
@@ -290,7 +290,7 @@ config SX | |||
290 | 290 | ||
291 | config RIO | 291 | config RIO |
292 | tristate "Specialix RIO system support" | 292 | tristate "Specialix RIO system support" |
293 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 293 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && !64BIT |
294 | help | 294 | help |
295 | This is a driver for the Specialix RIO, a smart serial card which | 295 | This is a driver for the Specialix RIO, a smart serial card which |
296 | drives an outboard box that can support up to 128 ports. Product | 296 | drives an outboard box that can support up to 128 ports. Product |
@@ -936,6 +936,15 @@ config SCx200_GPIO | |||
936 | 936 | ||
937 | If compiled as a module, it will be called scx200_gpio. | 937 | If compiled as a module, it will be called scx200_gpio. |
938 | 938 | ||
939 | config CS5535_GPIO | ||
940 | tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" | ||
941 | depends on X86_32 | ||
942 | help | ||
943 | Give userspace access to the GPIO pins on the AMD CS5535 and | ||
944 | CS5536 Geode companion devices. | ||
945 | |||
946 | If compiled as a module, it will be called cs5535_gpio. | ||
947 | |||
939 | config GPIO_VR41XX | 948 | config GPIO_VR41XX |
940 | tristate "NEC VR4100 series General-purpose I/O Unit support" | 949 | tristate "NEC VR4100 series General-purpose I/O Unit support" |
941 | depends on CPU_VR41XX | 950 | depends on CPU_VR41XX |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d973d14d8f7f..503dd901d406 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -81,6 +81,7 @@ obj-$(CONFIG_PPDEV) += ppdev.o | |||
81 | obj-$(CONFIG_NWBUTTON) += nwbutton.o | 81 | obj-$(CONFIG_NWBUTTON) += nwbutton.o |
82 | obj-$(CONFIG_NWFLASH) += nwflash.o | 82 | obj-$(CONFIG_NWFLASH) += nwflash.o |
83 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o | 83 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o |
84 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | ||
84 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | 85 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o |
85 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o | 86 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o |
86 | obj-$(CONFIG_TELCLOCK) += tlclk.o | 87 | obj-$(CONFIG_TELCLOCK) += tlclk.o |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index a124f8c5d062..869518e4035f 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -116,7 +116,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout); | |||
116 | 116 | ||
117 | static struct serial_state rs_table[1]; | 117 | static struct serial_state rs_table[1]; |
118 | 118 | ||
119 | #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) | 119 | #define NR_PORTS ARRAY_SIZE(rs_table) |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * tmp_buf is used as a temporary buffer by serial_write. We need to | 122 | * tmp_buf is used as a temporary buffer by serial_write. We need to |
@@ -265,8 +265,9 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
265 | int status; | 265 | int status; |
266 | int serdatr; | 266 | int serdatr; |
267 | struct tty_struct *tty = info->tty; | 267 | struct tty_struct *tty = info->tty; |
268 | unsigned char ch; | 268 | unsigned char ch, flag; |
269 | struct async_icount *icount; | 269 | struct async_icount *icount; |
270 | int oe = 0; | ||
270 | 271 | ||
271 | icount = &info->state->icount; | 272 | icount = &info->state->icount; |
272 | 273 | ||
@@ -282,15 +283,12 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
282 | status |= UART_LSR_OE; | 283 | status |= UART_LSR_OE; |
283 | 284 | ||
284 | ch = serdatr & 0xff; | 285 | ch = serdatr & 0xff; |
285 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
286 | goto ignore_char; | ||
287 | *tty->flip.char_buf_ptr = ch; | ||
288 | icount->rx++; | 286 | icount->rx++; |
289 | 287 | ||
290 | #ifdef SERIAL_DEBUG_INTR | 288 | #ifdef SERIAL_DEBUG_INTR |
291 | printk("DR%02x:%02x...", ch, status); | 289 | printk("DR%02x:%02x...", ch, status); |
292 | #endif | 290 | #endif |
293 | *tty->flip.flag_buf_ptr = 0; | 291 | flag = TTY_NORMAL; |
294 | 292 | ||
295 | /* | 293 | /* |
296 | * We don't handle parity or frame errors - but I have left | 294 | * We don't handle parity or frame errors - but I have left |
@@ -319,7 +317,7 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
319 | * should be ignored. | 317 | * should be ignored. |
320 | */ | 318 | */ |
321 | if (status & info->ignore_status_mask) | 319 | if (status & info->ignore_status_mask) |
322 | goto ignore_char; | 320 | goto out; |
323 | 321 | ||
324 | status &= info->read_status_mask; | 322 | status &= info->read_status_mask; |
325 | 323 | ||
@@ -327,33 +325,28 @@ static _INLINE_ void receive_chars(struct async_struct *info) | |||
327 | #ifdef SERIAL_DEBUG_INTR | 325 | #ifdef SERIAL_DEBUG_INTR |
328 | printk("handling break...."); | 326 | printk("handling break...."); |
329 | #endif | 327 | #endif |
330 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 328 | flag = TTY_BREAK; |
331 | if (info->flags & ASYNC_SAK) | 329 | if (info->flags & ASYNC_SAK) |
332 | do_SAK(tty); | 330 | do_SAK(tty); |
333 | } else if (status & UART_LSR_PE) | 331 | } else if (status & UART_LSR_PE) |
334 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 332 | flag = TTY_PARITY; |
335 | else if (status & UART_LSR_FE) | 333 | else if (status & UART_LSR_FE) |
336 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 334 | flag = TTY_FRAME; |
337 | if (status & UART_LSR_OE) { | 335 | if (status & UART_LSR_OE) { |
338 | /* | 336 | /* |
339 | * Overrun is special, since it's | 337 | * Overrun is special, since it's |
340 | * reported immediately, and doesn't | 338 | * reported immediately, and doesn't |
341 | * affect the current character | 339 | * affect the current character |
342 | */ | 340 | */ |
343 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 341 | oe = 1; |
344 | tty->flip.count++; | ||
345 | tty->flip.flag_buf_ptr++; | ||
346 | tty->flip.char_buf_ptr++; | ||
347 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
348 | } | ||
349 | } | 342 | } |
350 | } | 343 | } |
351 | tty->flip.flag_buf_ptr++; | 344 | tty_insert_flip_char(tty, ch, flag); |
352 | tty->flip.char_buf_ptr++; | 345 | if (oe == 1) |
353 | tty->flip.count++; | 346 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
354 | ignore_char: | ||
355 | |||
356 | tty_flip_buffer_push(tty); | 347 | tty_flip_buffer_push(tty); |
348 | out: | ||
349 | return; | ||
357 | } | 350 | } |
358 | 351 | ||
359 | static _INLINE_ void transmit_chars(struct async_struct *info) | 352 | static _INLINE_ void transmit_chars(struct async_struct *info) |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c new file mode 100644 index 000000000000..5d72f50de1ac --- /dev/null +++ b/drivers/char/cs5535_gpio.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | * AMD CS5535/CS5536 GPIO driver. | ||
3 | * Allows a user space process to play with the GPIO pins. | ||
4 | * | ||
5 | * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the smems of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | */ | ||
11 | |||
12 | #include <linux/fs.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/cdev.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | #include <asm/io.h> | ||
22 | |||
23 | |||
24 | #define NAME "cs5535_gpio" | ||
25 | |||
26 | MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); | ||
27 | MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO Pin Driver"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | static int major; | ||
31 | module_param(major, int, 0); | ||
32 | MODULE_PARM_DESC(major, "Major device number"); | ||
33 | |||
34 | static ulong mask; | ||
35 | module_param(mask, ulong, 0); | ||
36 | MODULE_PARM_DESC(mask, "GPIO channel mask"); | ||
37 | |||
38 | #define MSR_LBAR_GPIO 0x5140000C | ||
39 | |||
40 | static u32 gpio_base; | ||
41 | |||
42 | static struct pci_device_id divil_pci[] = { | ||
43 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
45 | { } /* NULL entry */ | ||
46 | }; | ||
47 | |||
48 | static struct cdev cs5535_gpio_cdev; | ||
49 | |||
50 | /* reserve 32 entries even though some aren't usable */ | ||
51 | #define CS5535_GPIO_COUNT 32 | ||
52 | |||
53 | /* IO block size */ | ||
54 | #define CS5535_GPIO_SIZE 256 | ||
55 | |||
56 | struct gpio_regmap { | ||
57 | u32 rd_offset; | ||
58 | u32 wr_offset; | ||
59 | char on; | ||
60 | char off; | ||
61 | }; | ||
62 | static struct gpio_regmap rm[] = | ||
63 | { | ||
64 | { 0x30, 0x00, '1', '0' }, /* GPIOx_READ_BACK / GPIOx_OUT_VAL */ | ||
65 | { 0x20, 0x20, 'I', 'i' }, /* GPIOx_IN_EN */ | ||
66 | { 0x04, 0x04, 'O', 'o' }, /* GPIOx_OUT_EN */ | ||
67 | { 0x08, 0x08, 't', 'T' }, /* GPIOx_OUT_OD_EN */ | ||
68 | { 0x18, 0x18, 'P', 'p' }, /* GPIOx_OUT_PU_EN */ | ||
69 | { 0x1c, 0x1c, 'D', 'd' }, /* GPIOx_OUT_PD_EN */ | ||
70 | }; | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Gets the register offset for the GPIO bank. | ||
75 | * Low (0-15) starts at 0x00, high (16-31) starts at 0x80 | ||
76 | */ | ||
77 | static inline u32 cs5535_lowhigh_base(int reg) | ||
78 | { | ||
79 | return (reg & 0x10) << 3; | ||
80 | } | ||
81 | |||
82 | static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, | ||
83 | size_t len, loff_t *ppos) | ||
84 | { | ||
85 | u32 m = iminor(file->f_dentry->d_inode); | ||
86 | int i, j; | ||
87 | u32 base = gpio_base + cs5535_lowhigh_base(m); | ||
88 | u32 m0, m1; | ||
89 | char c; | ||
90 | |||
91 | /** | ||
92 | * Creates the mask for atomic bit programming. | ||
93 | * The high 16 bits and the low 16 bits are used to set the mask. | ||
94 | * For example, GPIO 15 maps to 31,15: 0,1 => On; 1,0=> Off | ||
95 | */ | ||
96 | m1 = 1 << (m & 0x0F); | ||
97 | m0 = m1 << 16; | ||
98 | |||
99 | for (i = 0; i < len; ++i) { | ||
100 | if (get_user(c, data+i)) | ||
101 | return -EFAULT; | ||
102 | |||
103 | for (j = 0; j < ARRAY_SIZE(rm); j++) { | ||
104 | if (c == rm[j].on) { | ||
105 | outl(m1, base + rm[j].wr_offset); | ||
106 | break; | ||
107 | } else if (c == rm[j].off) { | ||
108 | outl(m0, base + rm[j].wr_offset); | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | *ppos = 0; | ||
114 | return len; | ||
115 | } | ||
116 | |||
117 | static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, | ||
118 | size_t len, loff_t *ppos) | ||
119 | { | ||
120 | u32 m = iminor(file->f_dentry->d_inode); | ||
121 | u32 base = gpio_base + cs5535_lowhigh_base(m); | ||
122 | int rd_bit = 1 << (m & 0x0f); | ||
123 | int i; | ||
124 | char ch; | ||
125 | ssize_t count = 0; | ||
126 | |||
127 | if (*ppos >= ARRAY_SIZE(rm)) | ||
128 | return 0; | ||
129 | |||
130 | for (i = *ppos; (i < (*ppos + len)) && (i < ARRAY_SIZE(rm)); i++) { | ||
131 | ch = (inl(base + rm[i].rd_offset) & rd_bit) ? | ||
132 | rm[i].on : rm[i].off; | ||
133 | |||
134 | if (put_user(ch, buf+count)) | ||
135 | return -EFAULT; | ||
136 | |||
137 | count++; | ||
138 | } | ||
139 | |||
140 | /* add a line-feed if there is room */ | ||
141 | if ((i == ARRAY_SIZE(rm)) && (count < len)) { | ||
142 | put_user('\n', buf + count); | ||
143 | count++; | ||
144 | } | ||
145 | |||
146 | *ppos += count; | ||
147 | return count; | ||
148 | } | ||
149 | |||
150 | static int cs5535_gpio_open(struct inode *inode, struct file *file) | ||
151 | { | ||
152 | u32 m = iminor(inode); | ||
153 | |||
154 | /* the mask says which pins are usable by this driver */ | ||
155 | if ((mask & (1 << m)) == 0) | ||
156 | return -EINVAL; | ||
157 | |||
158 | return nonseekable_open(inode, file); | ||
159 | } | ||
160 | |||
161 | static struct file_operations cs5535_gpio_fops = { | ||
162 | .owner = THIS_MODULE, | ||
163 | .write = cs5535_gpio_write, | ||
164 | .read = cs5535_gpio_read, | ||
165 | .open = cs5535_gpio_open | ||
166 | }; | ||
167 | |||
168 | static int __init cs5535_gpio_init(void) | ||
169 | { | ||
170 | dev_t dev_id; | ||
171 | u32 low, hi; | ||
172 | int retval; | ||
173 | |||
174 | if (pci_dev_present(divil_pci) == 0) { | ||
175 | printk(KERN_WARNING NAME ": DIVIL not found\n"); | ||
176 | return -ENODEV; | ||
177 | } | ||
178 | |||
179 | /* Grab the GPIO I/O range */ | ||
180 | rdmsr(MSR_LBAR_GPIO, low, hi); | ||
181 | |||
182 | /* Check the mask and whether GPIO is enabled (sanity check) */ | ||
183 | if (hi != 0x0000f001) { | ||
184 | printk(KERN_WARNING NAME ": GPIO not enabled\n"); | ||
185 | return -ENODEV; | ||
186 | } | ||
187 | |||
188 | /* Mask off the IO base address */ | ||
189 | gpio_base = low & 0x0000ff00; | ||
190 | |||
191 | /** | ||
192 | * Some GPIO pins | ||
193 | * 31-29,23 : reserved (always mask out) | ||
194 | * 28 : Power Button | ||
195 | * 26 : PME# | ||
196 | * 22-16 : LPC | ||
197 | * 14,15 : SMBus | ||
198 | * 9,8 : UART1 | ||
199 | * 7 : PCI INTB | ||
200 | * 3,4 : UART2/DDC | ||
201 | * 2 : IDE_IRQ0 | ||
202 | * 0 : PCI INTA | ||
203 | * | ||
204 | * If a mask was not specified, be conservative and only allow: | ||
205 | * 1,2,5,6,10-13,24,25,27 | ||
206 | */ | ||
207 | if (mask != 0) | ||
208 | mask &= 0x1f7fffff; | ||
209 | else | ||
210 | mask = 0x0b003c66; | ||
211 | |||
212 | if (request_region(gpio_base, CS5535_GPIO_SIZE, NAME) == 0) { | ||
213 | printk(KERN_ERR NAME ": can't allocate I/O for GPIO\n"); | ||
214 | return -ENODEV; | ||
215 | } | ||
216 | |||
217 | if (major) { | ||
218 | dev_id = MKDEV(major, 0); | ||
219 | retval = register_chrdev_region(dev_id, CS5535_GPIO_COUNT, | ||
220 | NAME); | ||
221 | } else { | ||
222 | retval = alloc_chrdev_region(&dev_id, 0, CS5535_GPIO_COUNT, | ||
223 | NAME); | ||
224 | major = MAJOR(dev_id); | ||
225 | } | ||
226 | |||
227 | if (retval) { | ||
228 | release_region(gpio_base, CS5535_GPIO_SIZE); | ||
229 | return -1; | ||
230 | } | ||
231 | |||
232 | printk(KERN_DEBUG NAME ": base=%#x mask=%#lx major=%d\n", | ||
233 | gpio_base, mask, major); | ||
234 | |||
235 | cdev_init(&cs5535_gpio_cdev, &cs5535_gpio_fops); | ||
236 | cdev_add(&cs5535_gpio_cdev, dev_id, CS5535_GPIO_COUNT); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static void __exit cs5535_gpio_cleanup(void) | ||
242 | { | ||
243 | dev_t dev_id = MKDEV(major, 0); | ||
244 | unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); | ||
245 | if (gpio_base != 0) | ||
246 | release_region(gpio_base, CS5535_GPIO_SIZE); | ||
247 | } | ||
248 | |||
249 | module_init(cs5535_gpio_init); | ||
250 | module_exit(cs5535_gpio_cleanup); | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index c7f818cd7b02..39c61a71176e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -641,6 +641,7 @@ static char rcsid[] = | |||
641 | #include <linux/timer.h> | 641 | #include <linux/timer.h> |
642 | #include <linux/interrupt.h> | 642 | #include <linux/interrupt.h> |
643 | #include <linux/tty.h> | 643 | #include <linux/tty.h> |
644 | #include <linux/tty_flip.h> | ||
644 | #include <linux/serial.h> | 645 | #include <linux/serial.h> |
645 | #include <linux/major.h> | 646 | #include <linux/major.h> |
646 | #include <linux/string.h> | 647 | #include <linux/string.h> |
@@ -723,7 +724,7 @@ static unsigned int cy_isa_addresses[] = { | |||
723 | 0xDE000, | 724 | 0xDE000, |
724 | 0,0,0,0,0,0,0,0 | 725 | 0,0,0,0,0,0,0,0 |
725 | }; | 726 | }; |
726 | #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*)) | 727 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) |
727 | 728 | ||
728 | #ifdef MODULE | 729 | #ifdef MODULE |
729 | static long maddr[NR_CARDS] = { 0, }; | 730 | static long maddr[NR_CARDS] = { 0, }; |
@@ -1086,7 +1087,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1086 | int had_work; | 1087 | int had_work; |
1087 | int mdm_change; | 1088 | int mdm_change; |
1088 | int mdm_status; | 1089 | int mdm_status; |
1089 | 1090 | int len; | |
1090 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ | 1091 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ |
1091 | #ifdef CY_DEBUG_INTERRUPTS | 1092 | #ifdef CY_DEBUG_INTERRUPTS |
1092 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | 1093 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); |
@@ -1163,63 +1164,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1163 | info->icount.rx++; | 1164 | info->icount.rx++; |
1164 | continue; | 1165 | continue; |
1165 | } | 1166 | } |
1166 | if (tty->flip.count < TTY_FLIPBUF_SIZE){ | 1167 | if (tty_buffer_request_room(tty, 1)) { |
1167 | tty->flip.count++; | ||
1168 | if (data & info->read_status_mask){ | 1168 | if (data & info->read_status_mask){ |
1169 | if(data & CyBREAK){ | 1169 | if(data & CyBREAK){ |
1170 | *tty->flip.flag_buf_ptr++ = | 1170 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK); |
1171 | TTY_BREAK; | ||
1172 | *tty->flip.char_buf_ptr++ = | ||
1173 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1174 | info->icount.rx++; | 1171 | info->icount.rx++; |
1175 | if (info->flags & ASYNC_SAK){ | 1172 | if (info->flags & ASYNC_SAK){ |
1176 | do_SAK(tty); | 1173 | do_SAK(tty); |
1177 | } | 1174 | } |
1178 | }else if(data & CyFRAME){ | 1175 | }else if(data & CyFRAME){ |
1179 | *tty->flip.flag_buf_ptr++ = | 1176 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1180 | TTY_FRAME; | ||
1181 | *tty->flip.char_buf_ptr++ = | ||
1182 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1183 | info->icount.rx++; | 1177 | info->icount.rx++; |
1184 | info->idle_stats.frame_errs++; | 1178 | info->idle_stats.frame_errs++; |
1185 | }else if(data & CyPARITY){ | 1179 | }else if(data & CyPARITY){ |
1186 | *tty->flip.flag_buf_ptr++ = | 1180 | /* Pieces of seven... */ |
1187 | TTY_PARITY; | 1181 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY); |
1188 | *tty->flip.char_buf_ptr++ = | ||
1189 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1190 | info->icount.rx++; | 1182 | info->icount.rx++; |
1191 | info->idle_stats.parity_errs++; | 1183 | info->idle_stats.parity_errs++; |
1192 | }else if(data & CyOVERRUN){ | 1184 | }else if(data & CyOVERRUN){ |
1193 | *tty->flip.flag_buf_ptr++ = | 1185 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1194 | TTY_OVERRUN; | ||
1195 | *tty->flip.char_buf_ptr++ = 0; | ||
1196 | info->icount.rx++; | 1186 | info->icount.rx++; |
1197 | /* If the flip buffer itself is | 1187 | /* If the flip buffer itself is |
1198 | overflowing, we still lose | 1188 | overflowing, we still lose |
1199 | the next incoming character. | 1189 | the next incoming character. |
1200 | */ | 1190 | */ |
1201 | if(tty->flip.count | 1191 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1202 | < TTY_FLIPBUF_SIZE){ | 1192 | info->icount.rx++; |
1203 | tty->flip.count++; | ||
1204 | *tty->flip.flag_buf_ptr++ = | ||
1205 | TTY_NORMAL; | ||
1206 | *tty->flip.char_buf_ptr++ = | ||
1207 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1208 | info->icount.rx++; | ||
1209 | } | ||
1210 | info->idle_stats.overruns++; | 1193 | info->idle_stats.overruns++; |
1211 | /* These two conditions may imply */ | 1194 | /* These two conditions may imply */ |
1212 | /* a normal read should be done. */ | 1195 | /* a normal read should be done. */ |
1213 | /* }else if(data & CyTIMEOUT){ */ | 1196 | /* }else if(data & CyTIMEOUT){ */ |
1214 | /* }else if(data & CySPECHAR){ */ | 1197 | /* }else if(data & CySPECHAR){ */ |
1215 | }else{ | 1198 | }else { |
1216 | *tty->flip.flag_buf_ptr++ = 0; | 1199 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1217 | *tty->flip.char_buf_ptr++ = 0; | 1200 | info->icount.rx++; |
1218 | info->icount.rx++; | ||
1219 | } | 1201 | } |
1220 | }else{ | 1202 | }else{ |
1221 | *tty->flip.flag_buf_ptr++ = 0; | 1203 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1222 | *tty->flip.char_buf_ptr++ = 0; | ||
1223 | info->icount.rx++; | 1204 | info->icount.rx++; |
1224 | } | 1205 | } |
1225 | }else{ | 1206 | }else{ |
@@ -1240,14 +1221,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1240 | info->mon.char_max = char_count; | 1221 | info->mon.char_max = char_count; |
1241 | info->mon.char_last = char_count; | 1222 | info->mon.char_last = char_count; |
1242 | #endif | 1223 | #endif |
1243 | while(char_count--){ | 1224 | len = tty_buffer_request_room(tty, char_count); |
1244 | if (tty->flip.count >= TTY_FLIPBUF_SIZE){ | 1225 | while(len--){ |
1245 | break; | ||
1246 | } | ||
1247 | tty->flip.count++; | ||
1248 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1226 | data = cy_readb(base_addr+(CyRDSR<<index)); |
1249 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | 1227 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1250 | *tty->flip.char_buf_ptr++ = data; | ||
1251 | info->idle_stats.recv_bytes++; | 1228 | info->idle_stats.recv_bytes++; |
1252 | info->icount.rx++; | 1229 | info->icount.rx++; |
1253 | #ifdef CY_16Y_HACK | 1230 | #ifdef CY_16Y_HACK |
@@ -1256,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1256 | } | 1233 | } |
1257 | info->idle_stats.recv_idle = jiffies; | 1234 | info->idle_stats.recv_idle = jiffies; |
1258 | } | 1235 | } |
1259 | schedule_delayed_work(&tty->flip.work, 1); | 1236 | schedule_delayed_work(&tty->buf.work, 1); |
1260 | } | 1237 | } |
1261 | /* end of service */ | 1238 | /* end of service */ |
1262 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); | 1239 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); |
@@ -1551,6 +1528,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1551 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1528 | struct cyclades_card *cinfo = &cy_card[info->card]; |
1552 | struct tty_struct *tty = info->tty; | 1529 | struct tty_struct *tty = info->tty; |
1553 | volatile int char_count; | 1530 | volatile int char_count; |
1531 | int len; | ||
1554 | #ifdef BLOCKMOVE | 1532 | #ifdef BLOCKMOVE |
1555 | int small_count; | 1533 | int small_count; |
1556 | #else | 1534 | #else |
@@ -1606,18 +1584,11 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1606 | tty->flip.count += small_count; | 1584 | tty->flip.count += small_count; |
1607 | } | 1585 | } |
1608 | #else | 1586 | #else |
1609 | while(char_count--){ | 1587 | len = tty_buffer_request_room(tty, char_count); |
1610 | if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt) | 1588 | while(len--){ |
1611 | break; | ||
1612 | |||
1613 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1614 | break; | ||
1615 | |||
1616 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); | 1589 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); |
1617 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); | 1590 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); |
1618 | tty->flip.count++; | 1591 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1619 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
1620 | *tty->flip.char_buf_ptr++ = data; | ||
1621 | info->idle_stats.recv_bytes++; | 1592 | info->idle_stats.recv_bytes++; |
1622 | info->icount.rx++; | 1593 | info->icount.rx++; |
1623 | } | 1594 | } |
@@ -1635,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1635 | } | 1606 | } |
1636 | #endif | 1607 | #endif |
1637 | info->idle_stats.recv_idle = jiffies; | 1608 | info->idle_stats.recv_idle = jiffies; |
1638 | schedule_delayed_work(&tty->flip.work, 1); | 1609 | schedule_delayed_work(&tty->buf.work, 1); |
1639 | } | 1610 | } |
1640 | /* Update rx_get */ | 1611 | /* Update rx_get */ |
1641 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1612 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
@@ -1763,23 +1734,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1763 | 1734 | ||
1764 | switch(cmd) { | 1735 | switch(cmd) { |
1765 | case C_CM_PR_ERROR: | 1736 | case C_CM_PR_ERROR: |
1766 | tty->flip.count++; | 1737 | tty_insert_flip_char(tty, 0, TTY_PARITY); |
1767 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | ||
1768 | *tty->flip.char_buf_ptr++ = 0; | ||
1769 | info->icount.rx++; | 1738 | info->icount.rx++; |
1770 | special_count++; | 1739 | special_count++; |
1771 | break; | 1740 | break; |
1772 | case C_CM_FR_ERROR: | 1741 | case C_CM_FR_ERROR: |
1773 | tty->flip.count++; | 1742 | tty_insert_flip_char(tty, 0, TTY_FRAME); |
1774 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | ||
1775 | *tty->flip.char_buf_ptr++ = 0; | ||
1776 | info->icount.rx++; | 1743 | info->icount.rx++; |
1777 | special_count++; | 1744 | special_count++; |
1778 | break; | 1745 | break; |
1779 | case C_CM_RXBRK: | 1746 | case C_CM_RXBRK: |
1780 | tty->flip.count++; | 1747 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1781 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
1782 | *tty->flip.char_buf_ptr++ = 0; | ||
1783 | info->icount.rx++; | 1748 | info->icount.rx++; |
1784 | special_count++; | 1749 | special_count++; |
1785 | break; | 1750 | break; |
@@ -1844,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1844 | if(delta_count) | 1809 | if(delta_count) |
1845 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1810 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); |
1846 | if(special_count) | 1811 | if(special_count) |
1847 | schedule_delayed_work(&tty->flip.work, 1); | 1812 | schedule_delayed_work(&tty->buf.work, 1); |
1848 | } | 1813 | } |
1849 | } | 1814 | } |
1850 | 1815 | ||
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c index dd91ff6b474c..e9e2db18952d 100644 --- a/drivers/char/drm/drm_ioc32.c +++ b/drivers/char/drm/drm_ioc32.c | |||
@@ -28,7 +28,6 @@ | |||
28 | * IN THE SOFTWARE. | 28 | * IN THE SOFTWARE. |
29 | */ | 29 | */ |
30 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
31 | #include <linux/ioctl32.h> | ||
32 | 31 | ||
33 | #include "drmP.h" | 32 | #include "drmP.h" |
34 | #include "drm_core.h" | 33 | #include "drm_core.h" |
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c index 2218a946ec87..296248cdc767 100644 --- a/drivers/char/drm/i915_ioc32.c +++ b/drivers/char/drm/i915_ioc32.c | |||
@@ -30,7 +30,6 @@ | |||
30 | * IN THE SOFTWARE. | 30 | * IN THE SOFTWARE. |
31 | */ | 31 | */ |
32 | #include <linux/compat.h> | 32 | #include <linux/compat.h> |
33 | #include <linux/ioctl32.h> | ||
34 | 33 | ||
35 | #include "drmP.h" | 34 | #include "drmP.h" |
36 | #include "drm.h" | 35 | #include "drm.h" |
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c index 24a9d4e86af0..54a18eb2fc04 100644 --- a/drivers/char/drm/mga_ioc32.c +++ b/drivers/char/drm/mga_ioc32.c | |||
@@ -31,7 +31,6 @@ | |||
31 | * IN THE SOFTWARE. | 31 | * IN THE SOFTWARE. |
32 | */ | 32 | */ |
33 | #include <linux/compat.h> | 33 | #include <linux/compat.h> |
34 | #include <linux/ioctl32.h> | ||
35 | 34 | ||
36 | #include "drmP.h" | 35 | #include "drmP.h" |
37 | #include "drm.h" | 36 | #include "drm.h" |
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c index 1e2e367b8b82..9dd6d4116e47 100644 --- a/drivers/char/drm/r128_ioc32.c +++ b/drivers/char/drm/r128_ioc32.c | |||
@@ -30,7 +30,6 @@ | |||
30 | * IN THE SOFTWARE. | 30 | * IN THE SOFTWARE. |
31 | */ | 31 | */ |
32 | #include <linux/compat.h> | 32 | #include <linux/compat.h> |
33 | #include <linux/ioctl32.h> | ||
34 | 33 | ||
35 | #include "drmP.h" | 34 | #include "drmP.h" |
36 | #include "drm.h" | 35 | #include "drm.h" |
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c index fef4a2b84c1e..0ccfd3618ff1 100644 --- a/drivers/char/drm/radeon_ioc32.c +++ b/drivers/char/drm/radeon_ioc32.c | |||
@@ -28,7 +28,6 @@ | |||
28 | * IN THE SOFTWARE. | 28 | * IN THE SOFTWARE. |
29 | */ | 29 | */ |
30 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
31 | #include <linux/ioctl32.h> | ||
32 | 31 | ||
33 | #include "drmP.h" | 32 | #include "drmP.h" |
34 | #include "drm.h" | 33 | #include "drm.h" |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 407708a001e4..765c5c108bf4 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1786,9 +1786,7 @@ static void doevent(int crd) | |||
1786 | if (tty) { /* Begin if valid tty */ | 1786 | if (tty) { /* Begin if valid tty */ |
1787 | if (event & BREAK_IND) { /* Begin if BREAK_IND */ | 1787 | if (event & BREAK_IND) { /* Begin if BREAK_IND */ |
1788 | /* A break has been indicated */ | 1788 | /* A break has been indicated */ |
1789 | tty->flip.count++; | 1789 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1790 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
1791 | *tty->flip.char_buf_ptr++ = 0; | ||
1792 | tty_schedule_flip(tty); | 1790 | tty_schedule_flip(tty); |
1793 | } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ | 1791 | } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ |
1794 | if (ch->statusflags & LOWWAIT) | 1792 | if (ch->statusflags & LOWWAIT) |
@@ -2124,7 +2122,6 @@ static void receive_data(struct channel *ch) | |||
2124 | int dataToRead, wrapgap, bytesAvailable; | 2122 | int dataToRead, wrapgap, bytesAvailable; |
2125 | unsigned int tail, head; | 2123 | unsigned int tail, head; |
2126 | unsigned int wrapmask; | 2124 | unsigned int wrapmask; |
2127 | int rc; | ||
2128 | 2125 | ||
2129 | /* --------------------------------------------------------------- | 2126 | /* --------------------------------------------------------------- |
2130 | This routine is called by doint when a receive data event | 2127 | This routine is called by doint when a receive data event |
@@ -2162,16 +2159,15 @@ static void receive_data(struct channel *ch) | |||
2162 | return; | 2159 | return; |
2163 | } | 2160 | } |
2164 | 2161 | ||
2165 | if (tty->flip.count == TTY_FLIPBUF_SIZE) | 2162 | if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) |
2166 | return; | 2163 | return; |
2167 | 2164 | ||
2168 | if (readb(&bc->orun)) { | 2165 | if (readb(&bc->orun)) { |
2169 | writeb(0, &bc->orun); | 2166 | writeb(0, &bc->orun); |
2170 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); | 2167 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); |
2168 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
2171 | } | 2169 | } |
2172 | rxwinon(ch); | 2170 | rxwinon(ch); |
2173 | rptr = tty->flip.char_buf_ptr; | ||
2174 | rc = tty->flip.count; | ||
2175 | while (bytesAvailable > 0) { /* Begin while there is data on the card */ | 2171 | while (bytesAvailable > 0) { /* Begin while there is data on the card */ |
2176 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; | 2172 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; |
2177 | /* --------------------------------------------------------------- | 2173 | /* --------------------------------------------------------------- |
@@ -2183,8 +2179,7 @@ static void receive_data(struct channel *ch) | |||
2183 | /* -------------------------------------------------------------- | 2179 | /* -------------------------------------------------------------- |
2184 | Make sure we don't overflow the buffer | 2180 | Make sure we don't overflow the buffer |
2185 | ----------------------------------------------------------------- */ | 2181 | ----------------------------------------------------------------- */ |
2186 | if ((rc + dataToRead) > TTY_FLIPBUF_SIZE) | 2182 | dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); |
2187 | dataToRead = TTY_FLIPBUF_SIZE - rc; | ||
2188 | if (dataToRead == 0) | 2183 | if (dataToRead == 0) |
2189 | break; | 2184 | break; |
2190 | /* --------------------------------------------------------------- | 2185 | /* --------------------------------------------------------------- |
@@ -2192,13 +2187,9 @@ static void receive_data(struct channel *ch) | |||
2192 | for translation if necessary. | 2187 | for translation if necessary. |
2193 | ------------------------------------------------------------------ */ | 2188 | ------------------------------------------------------------------ */ |
2194 | memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); | 2189 | memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); |
2195 | rc += dataToRead; | ||
2196 | rptr += dataToRead; | ||
2197 | tail = (tail + dataToRead) & wrapmask; | 2190 | tail = (tail + dataToRead) & wrapmask; |
2198 | bytesAvailable -= dataToRead; | 2191 | bytesAvailable -= dataToRead; |
2199 | } /* End while there is data on the card */ | 2192 | } /* End while there is data on the card */ |
2200 | tty->flip.count = rc; | ||
2201 | tty->flip.char_buf_ptr = rptr; | ||
2202 | globalwinon(ch); | 2193 | globalwinon(ch); |
2203 | writew(tail, &bc->rout); | 2194 | writew(tail, &bc->rout); |
2204 | /* Must be called with global data */ | 2195 | /* Must be called with global data */ |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 9f53d2fcc360..e469f641c728 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -345,26 +345,22 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | |||
345 | 345 | ||
346 | for (i = 0; i < num_bytes; i++) { | 346 | for (i = 0; i < num_bytes; i++) { |
347 | if (!(err_buf->data[i] & status_mask)) { | 347 | if (!(err_buf->data[i] & status_mask)) { |
348 | *(tty->flip.char_buf_ptr++) = pio_buf->data[i]; | 348 | int flag = 0; |
349 | 349 | ||
350 | if (err_buf->data[i] & 0x04) { | 350 | if (err_buf->data[i] & 0x04) { |
351 | *(tty->flip.flag_buf_ptr++) = TTY_BREAK; | 351 | flag = TTY_BREAK; |
352 | |||
353 | if (info->flags & ASYNC_SAK) | 352 | if (info->flags & ASYNC_SAK) |
354 | do_SAK(tty); | 353 | do_SAK(tty); |
355 | } | 354 | } |
356 | else if (err_buf->data[i] & 0x02) | 355 | else if (err_buf->data[i] & 0x02) |
357 | *(tty->flip.flag_buf_ptr++) = TTY_FRAME; | 356 | flag = TTY_FRAME; |
358 | else if (err_buf->data[i] & 0x01) | 357 | else if (err_buf->data[i] & 0x01) |
359 | *(tty->flip.flag_buf_ptr++) = TTY_PARITY; | 358 | flag = TTY_PARITY; |
360 | else | 359 | tty_insert_flip_char(tty, pio_buf->data[i], flag); |
361 | *(tty->flip.flag_buf_ptr++) = 0; | ||
362 | |||
363 | tty->flip.count++; | ||
364 | } | 360 | } |
365 | } | 361 | } |
366 | 362 | ||
367 | schedule_delayed_work(&tty->flip.work, 1); | 363 | schedule_delayed_work(&tty->buf.work, 1); |
368 | 364 | ||
369 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | 365 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; |
370 | release_pio_buffer(pio_buf); | 366 | release_pio_buffer(pio_buf); |
@@ -397,7 +393,6 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
397 | int num_bytes; | 393 | int num_bytes; |
398 | unsigned long flags; | 394 | unsigned long flags; |
399 | 395 | ||
400 | |||
401 | flags=claim_dma_lock(); | 396 | flags=claim_dma_lock(); |
402 | disable_dma(dma); | 397 | disable_dma(dma); |
403 | clear_dma_ff(dma); | 398 | clear_dma_ff(dma); |
@@ -408,38 +403,31 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
408 | 403 | ||
409 | info->icount.rx += num_bytes; | 404 | info->icount.rx += num_bytes; |
410 | 405 | ||
411 | memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes); | ||
412 | tty->flip.char_buf_ptr += num_bytes; | ||
413 | tty->flip.count += num_bytes; | ||
414 | memset(tty->flip.flag_buf_ptr, 0, num_bytes); | ||
415 | tty->flip.flag_buf_ptr += num_bytes; | ||
416 | |||
417 | if (num_bytes > 0) { | 406 | if (num_bytes > 0) { |
418 | tty->flip.flag_buf_ptr--; | 407 | tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); |
419 | 408 | ||
420 | status &= (0x1c & info->read_status_mask); | 409 | status &= (0x1c & info->read_status_mask); |
410 | |||
411 | /* Is the status significant or do we throw the last byte ? */ | ||
412 | if (!(status & info->ignore_status_mask)) { | ||
413 | int statflag = 0; | ||
421 | 414 | ||
422 | if (status & info->ignore_status_mask) { | 415 | if (status & 0x10) { |
423 | tty->flip.count--; | 416 | statflag = TTY_BREAK; |
424 | tty->flip.char_buf_ptr--; | 417 | (info->icount.brk)++; |
425 | tty->flip.flag_buf_ptr--; | 418 | if (info->flags & ASYNC_SAK) |
426 | } else if (status & 0x10) { | 419 | do_SAK(tty); |
427 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 420 | } else if (status & 0x08) { |
428 | (info->icount.brk)++; | 421 | statflag = TTY_FRAME; |
429 | if (info->flags & ASYNC_SAK) | 422 | (info->icount.frame)++; |
430 | do_SAK(tty); | 423 | } |
431 | } else if (status & 0x08) { | 424 | else if (status & 0x04) { |
432 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 425 | statflag = TTY_PARITY; |
433 | (info->icount.frame)++; | 426 | (info->icount.parity)++; |
434 | } | 427 | } |
435 | else if (status & 0x04) { | 428 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); |
436 | *tty->flip.flag_buf_ptr = TTY_PARITY; | ||
437 | (info->icount.parity)++; | ||
438 | } | 429 | } |
439 | 430 | schedule_delayed_work(&tty->buf.work, 1); | |
440 | tty->flip.flag_buf_ptr++; | ||
441 | |||
442 | schedule_delayed_work(&tty->flip.work, 1); | ||
443 | } | 431 | } |
444 | 432 | ||
445 | if (dma_bytes != num_bytes) { | 433 | if (dma_bytes != num_bytes) { |
@@ -693,8 +681,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id, | |||
693 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; | 681 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; |
694 | num_bytes |= serial_in(info, UART_ESI_STAT2); | 682 | num_bytes |= serial_in(info, UART_ESI_STAT2); |
695 | 683 | ||
696 | if (num_bytes > (TTY_FLIPBUF_SIZE - info->tty->flip.count)) | 684 | num_bytes = tty_buffer_request_room(info->tty, num_bytes); |
697 | num_bytes = TTY_FLIPBUF_SIZE - info->tty->flip.count; | ||
698 | 685 | ||
699 | if (num_bytes) { | 686 | if (num_bytes) { |
700 | if (dma_bytes || | 687 | if (dma_bytes || |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index f92177634677..1994a92d4733 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -597,9 +597,7 @@ static int hvc_poll(struct hvc_struct *hp) | |||
597 | 597 | ||
598 | /* Read data if any */ | 598 | /* Read data if any */ |
599 | for (;;) { | 599 | for (;;) { |
600 | int count = N_INBUF; | 600 | int count = tty_buffer_request_room(tty, N_INBUF); |
601 | if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) | ||
602 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
603 | 601 | ||
604 | /* If flip is full, just reschedule a later read */ | 602 | /* If flip is full, just reschedule a later read */ |
605 | if (count == 0) { | 603 | if (count == 0) { |
@@ -635,7 +633,7 @@ static int hvc_poll(struct hvc_struct *hp) | |||
635 | tty_insert_flip_char(tty, buf[i], 0); | 633 | tty_insert_flip_char(tty, buf[i], 0); |
636 | } | 634 | } |
637 | 635 | ||
638 | if (tty->flip.count) | 636 | if (count) |
639 | tty_schedule_flip(tty); | 637 | tty_schedule_flip(tty); |
640 | 638 | ||
641 | /* | 639 | /* |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 53dc77c760fc..831eb4e8d9d3 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -456,12 +456,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
456 | /* remove the read masks */ | 456 | /* remove the read masks */ |
457 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); | 457 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); |
458 | 458 | ||
459 | if ((tty->flip.count + HVCS_BUFF_LEN) < TTY_FLIPBUF_SIZE) { | 459 | if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { |
460 | got = hvc_get_chars(unit_address, | 460 | got = hvc_get_chars(unit_address, |
461 | &buf[0], | 461 | &buf[0], |
462 | HVCS_BUFF_LEN); | 462 | HVCS_BUFF_LEN); |
463 | for (i=0;got && i<got;i++) | 463 | tty_insert_flip_string(tty, buf, got); |
464 | tty_insert_flip_char(tty, buf[i], TTY_NORMAL); | ||
465 | } | 464 | } |
466 | 465 | ||
467 | /* Give the TTY time to process the data we just sent. */ | 466 | /* Give the TTY time to process the data we just sent. */ |
@@ -469,10 +468,9 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
469 | hvcsd->todo_mask |= HVCS_QUICK_READ; | 468 | hvcsd->todo_mask |= HVCS_QUICK_READ; |
470 | 469 | ||
471 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 470 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
472 | if (tty->flip.count) { | 471 | /* This is synch because tty->low_latency == 1 */ |
473 | /* This is synch because tty->low_latency == 1 */ | 472 | if(got) |
474 | tty_flip_buffer_push(tty); | 473 | tty_flip_buffer_push(tty); |
475 | } | ||
476 | 474 | ||
477 | if (!got) { | 475 | if (!got) { |
478 | /* Do this _after_ the flip_buffer_push */ | 476 | /* Do this _after_ the flip_buffer_push */ |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index a22aa940e01e..a9522189fc9e 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -197,7 +197,7 @@ static inline void print_state(struct hvsi_struct *hp) | |||
197 | }; | 197 | }; |
198 | const char *name = state_names[hp->state]; | 198 | const char *name = state_names[hp->state]; |
199 | 199 | ||
200 | if (hp->state > (sizeof(state_names)/sizeof(char*))) | 200 | if (hp->state > ARRAY_SIZE(state_names)) |
201 | name = "UNKNOWN"; | 201 | name = "UNKNOWN"; |
202 | 202 | ||
203 | pr_debug("hvsi%i: state = %s\n", hp->index, name); | 203 | pr_debug("hvsi%i: state = %s\n", hp->index, name); |
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index ba85eb1b6ec7..fc944d375be7 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c | |||
@@ -854,7 +854,7 @@ i2Input(i2ChanStrPtr pCh) | |||
854 | count += IBUF_SIZE; | 854 | count += IBUF_SIZE; |
855 | } | 855 | } |
856 | // Don't give more than can be taken by the line discipline | 856 | // Don't give more than can be taken by the line discipline |
857 | amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY ); | 857 | amountToMove = pCh->pTTY->receive_room; |
858 | if (count > amountToMove) { | 858 | if (count > amountToMove) { |
859 | count = amountToMove; | 859 | count = amountToMove; |
860 | } | 860 | } |
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index d815d197dc3e..56e93a5a1e24 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c | |||
@@ -172,7 +172,7 @@ static int Fip_firmware_size; | |||
172 | /* Private (static) functions */ | 172 | /* Private (static) functions */ |
173 | static int ip2_open(PTTY, struct file *); | 173 | static int ip2_open(PTTY, struct file *); |
174 | static void ip2_close(PTTY, struct file *); | 174 | static void ip2_close(PTTY, struct file *); |
175 | static int ip2_write(PTTY, int, const unsigned char *, int); | 175 | static int ip2_write(PTTY, const unsigned char *, int); |
176 | static void ip2_putchar(PTTY, unsigned char); | 176 | static void ip2_putchar(PTTY, unsigned char); |
177 | static void ip2_flush_chars(PTTY); | 177 | static void ip2_flush_chars(PTTY); |
178 | static int ip2_write_room(PTTY); | 178 | static int ip2_write_room(PTTY); |
@@ -1713,7 +1713,7 @@ ip2_hangup ( PTTY tty ) | |||
1713 | /* */ | 1713 | /* */ |
1714 | /******************************************************************************/ | 1714 | /******************************************************************************/ |
1715 | static int | 1715 | static int |
1716 | ip2_write( PTTY tty, int user, const unsigned char *pData, int count) | 1716 | ip2_write( PTTY tty, const unsigned char *pData, int count) |
1717 | { | 1717 | { |
1718 | i2ChanStrPtr pCh = tty->driver_data; | 1718 | i2ChanStrPtr pCh = tty->driver_data; |
1719 | int bytesSent = 0; | 1719 | int bytesSent = 0; |
@@ -1726,7 +1726,7 @@ ip2_write( PTTY tty, int user, const unsigned char *pData, int count) | |||
1726 | 1726 | ||
1727 | /* This is the actual move bit. Make sure it does what we need!!!!! */ | 1727 | /* This is the actual move bit. Make sure it does what we need!!!!! */ |
1728 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1728 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); |
1729 | bytesSent = i2Output( pCh, pData, count, user ); | 1729 | bytesSent = i2Output( pCh, pData, count, 0 ); |
1730 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1730 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); |
1731 | 1731 | ||
1732 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); | 1732 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); |
@@ -2001,7 +2001,9 @@ ip2_stop ( PTTY tty ) | |||
2001 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file) | 2001 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file) |
2002 | { | 2002 | { |
2003 | i2ChanStrPtr pCh = DevTable[tty->index]; | 2003 | i2ChanStrPtr pCh = DevTable[tty->index]; |
2004 | #ifdef ENABLE_DSSNOW | ||
2004 | wait_queue_t wait; | 2005 | wait_queue_t wait; |
2006 | #endif | ||
2005 | 2007 | ||
2006 | if (pCh == NULL) | 2008 | if (pCh == NULL) |
2007 | return -ENODEV; | 2009 | return -ENODEV; |
@@ -2089,15 +2091,17 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2089 | { | 2091 | { |
2090 | wait_queue_t wait; | 2092 | wait_queue_t wait; |
2091 | i2ChanStrPtr pCh = DevTable[tty->index]; | 2093 | i2ChanStrPtr pCh = DevTable[tty->index]; |
2094 | i2eBordStrPtr pB; | ||
2092 | struct async_icount cprev, cnow; /* kernel counter temps */ | 2095 | struct async_icount cprev, cnow; /* kernel counter temps */ |
2093 | struct serial_icounter_struct __user *p_cuser; | 2096 | struct serial_icounter_struct __user *p_cuser; |
2094 | int rc = 0; | 2097 | int rc = 0; |
2095 | unsigned long flags; | 2098 | unsigned long flags; |
2096 | void __user *argp = (void __user *)arg; | 2099 | void __user *argp = (void __user *)arg; |
2097 | 2100 | ||
2098 | if ( pCh == NULL ) { | 2101 | if ( pCh == NULL ) |
2099 | return -ENODEV; | 2102 | return -ENODEV; |
2100 | } | 2103 | |
2104 | pB = pCh->pMyBord; | ||
2101 | 2105 | ||
2102 | ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg ); | 2106 | ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg ); |
2103 | 2107 | ||
@@ -2206,9 +2210,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2206 | * for masking). Caller should use TIOCGICOUNT to see which one it was | 2210 | * for masking). Caller should use TIOCGICOUNT to see which one it was |
2207 | */ | 2211 | */ |
2208 | case TIOCMIWAIT: | 2212 | case TIOCMIWAIT: |
2209 | save_flags(flags);cli(); | 2213 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); |
2210 | cprev = pCh->icount; /* note the counters on entry */ | 2214 | cprev = pCh->icount; /* note the counters on entry */ |
2211 | restore_flags(flags); | 2215 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); |
2212 | i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, | 2216 | i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, |
2213 | CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); | 2217 | CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); |
2214 | init_waitqueue_entry(&wait, current); | 2218 | init_waitqueue_entry(&wait, current); |
@@ -2228,9 +2232,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2228 | rc = -ERESTARTSYS; | 2232 | rc = -ERESTARTSYS; |
2229 | break; | 2233 | break; |
2230 | } | 2234 | } |
2231 | save_flags(flags);cli(); | 2235 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); |
2232 | cnow = pCh->icount; /* atomic copy */ | 2236 | cnow = pCh->icount; /* atomic copy */ |
2233 | restore_flags(flags); | 2237 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); |
2234 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 2238 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
2235 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { | 2239 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { |
2236 | rc = -EIO; /* no change => rc */ | 2240 | rc = -EIO; /* no change => rc */ |
@@ -2268,9 +2272,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2268 | case TIOCGICOUNT: | 2272 | case TIOCGICOUNT: |
2269 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); | 2273 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); |
2270 | 2274 | ||
2271 | save_flags(flags);cli(); | 2275 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); |
2272 | cnow = pCh->icount; | 2276 | cnow = pCh->icount; |
2273 | restore_flags(flags); | 2277 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); |
2274 | p_cuser = argp; | 2278 | p_cuser = argp; |
2275 | rc = put_user(cnow.cts, &p_cuser->cts); | 2279 | rc = put_user(cnow.cts, &p_cuser->cts); |
2276 | rc = put_user(cnow.dsr, &p_cuser->dsr); | 2280 | rc = put_user(cnow.dsr, &p_cuser->dsr); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 561430ed94af..0097f06fa67b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -57,6 +57,7 @@ static int initialized = 0; | |||
57 | 57 | ||
58 | #ifdef CONFIG_PROC_FS | 58 | #ifdef CONFIG_PROC_FS |
59 | struct proc_dir_entry *proc_ipmi_root = NULL; | 59 | struct proc_dir_entry *proc_ipmi_root = NULL; |
60 | EXPORT_SYMBOL(proc_ipmi_root); | ||
60 | #endif /* CONFIG_PROC_FS */ | 61 | #endif /* CONFIG_PROC_FS */ |
61 | 62 | ||
62 | #define MAX_EVENTS_IN_QUEUE 25 | 63 | #define MAX_EVENTS_IN_QUEUE 25 |
@@ -3295,6 +3296,5 @@ EXPORT_SYMBOL(ipmi_get_my_address); | |||
3295 | EXPORT_SYMBOL(ipmi_set_my_LUN); | 3296 | EXPORT_SYMBOL(ipmi_set_my_LUN); |
3296 | EXPORT_SYMBOL(ipmi_get_my_LUN); | 3297 | EXPORT_SYMBOL(ipmi_get_my_LUN); |
3297 | EXPORT_SYMBOL(ipmi_smi_add_proc_entry); | 3298 | EXPORT_SYMBOL(ipmi_smi_add_proc_entry); |
3298 | EXPORT_SYMBOL(proc_ipmi_root); | ||
3299 | EXPORT_SYMBOL(ipmi_user_set_run_to_completion); | 3299 | EXPORT_SYMBOL(ipmi_user_set_run_to_completion); |
3300 | EXPORT_SYMBOL(ipmi_free_recv_msg); | 3300 | EXPORT_SYMBOL(ipmi_free_recv_msg); |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index e053eade0366..49c09ae004bf 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -612,11 +612,14 @@ static int ipmi_poweroff_init (void) | |||
612 | #endif | 612 | #endif |
613 | 613 | ||
614 | rv = ipmi_smi_watcher_register(&smi_watcher); | 614 | rv = ipmi_smi_watcher_register(&smi_watcher); |
615 | |||
616 | #ifdef CONFIG_PROC_FS | ||
615 | if (rv) { | 617 | if (rv) { |
616 | unregister_sysctl_table(ipmi_table_header); | 618 | unregister_sysctl_table(ipmi_table_header); |
617 | printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); | 619 | printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); |
618 | goto out_err; | 620 | goto out_err; |
619 | } | 621 | } |
622 | #endif | ||
620 | 623 | ||
621 | out_err: | 624 | out_err: |
622 | return rv; | 625 | return rv; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 1bbf507adda5..e9ebabaf8cb0 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -20,7 +20,7 @@ | |||
20 | * 3/9/99 sameer Added support for ISI4616 cards. | 20 | * 3/9/99 sameer Added support for ISI4616 cards. |
21 | * | 21 | * |
22 | * 16/9/99 sameer We do not force RTS low anymore. | 22 | * 16/9/99 sameer We do not force RTS low anymore. |
23 | * This is to prevent the firmware | 23 | * This is to prevent the firmware |
24 | * from getting confused. | 24 | * from getting confused. |
25 | * | 25 | * |
26 | * 26/10/99 sameer Cosmetic changes:The driver now | 26 | * 26/10/99 sameer Cosmetic changes:The driver now |
@@ -31,28 +31,28 @@ | |||
31 | * | 31 | * |
32 | * 10/5/00 sameer Fixed isicom_shutdown_board() | 32 | * 10/5/00 sameer Fixed isicom_shutdown_board() |
33 | * to not lower DTR on all the ports | 33 | * to not lower DTR on all the ports |
34 | * when the last port on the card is | 34 | * when the last port on the card is |
35 | * closed. | 35 | * closed. |
36 | * | 36 | * |
37 | * 10/5/00 sameer Signal mask setup command added | 37 | * 10/5/00 sameer Signal mask setup command added |
38 | * to isicom_setup_port and | 38 | * to isicom_setup_port and |
39 | * isicom_shutdown_port. | 39 | * isicom_shutdown_port. |
40 | * | 40 | * |
41 | * 24/5/00 sameer The driver is now SMP aware. | 41 | * 24/5/00 sameer The driver is now SMP aware. |
42 | * | 42 | * |
43 | * | 43 | * |
44 | * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem | 44 | * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem |
45 | * | 45 | * |
46 | * | 46 | * |
47 | * 03/01/01 anil .s Added support for resetting the | 47 | * 03/01/01 anil .s Added support for resetting the |
48 | * internal modems on ISI cards. | 48 | * internal modems on ISI cards. |
49 | * | 49 | * |
50 | * 08/02/01 anil .s Upgraded the driver for kernel | 50 | * 08/02/01 anil .s Upgraded the driver for kernel |
51 | * 2.4.x | 51 | * 2.4.x |
52 | * | 52 | * |
53 | * 11/04/01 Kevin Fixed firmware load problem with | 53 | * 11/04/01 Kevin Fixed firmware load problem with |
54 | * ISIHP-4X card | 54 | * ISIHP-4X card |
55 | * | 55 | * |
56 | * 30/04/01 anil .s Fixed the remote login through | 56 | * 30/04/01 anil .s Fixed the remote login through |
57 | * ISI port problem. Now the link | 57 | * ISI port problem. Now the link |
58 | * does not go down before password | 58 | * does not go down before password |
@@ -62,9 +62,9 @@ | |||
62 | * among ISI-PCI cards. | 62 | * among ISI-PCI cards. |
63 | * | 63 | * |
64 | * 03/05/01 anil .s Added support to display the version | 64 | * 03/05/01 anil .s Added support to display the version |
65 | * info during insmod as well as module | 65 | * info during insmod as well as module |
66 | * listing by lsmod. | 66 | * listing by lsmod. |
67 | * | 67 | * |
68 | * 10/05/01 anil .s Done the modifications to the source | 68 | * 10/05/01 anil .s Done the modifications to the source |
69 | * file and Install script so that the | 69 | * file and Install script so that the |
70 | * same installation can be used for | 70 | * same installation can be used for |
@@ -73,19 +73,19 @@ | |||
73 | * 06/06/01 anil .s Now we drop both dtr and rts during | 73 | * 06/06/01 anil .s Now we drop both dtr and rts during |
74 | * shutdown_port as well as raise them | 74 | * shutdown_port as well as raise them |
75 | * during isicom_config_port. | 75 | * during isicom_config_port. |
76 | * | 76 | * |
77 | * 09/06/01 acme@conectiva.com.br use capable, not suser, do | 77 | * 09/06/01 acme@conectiva.com.br use capable, not suser, do |
78 | * restore_flags on failure in | 78 | * restore_flags on failure in |
79 | * isicom_send_break, verify put_user | 79 | * isicom_send_break, verify put_user |
80 | * result | 80 | * result |
81 | * | 81 | * |
82 | * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps | 82 | * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps |
83 | * Baud index extended to 21 | 83 | * Baud index extended to 21 |
84 | * | 84 | * |
85 | * 20/03/03 ranjeeth Made to work for Linux Advanced server. | 85 | * 20/03/03 ranjeeth Made to work for Linux Advanced server. |
86 | * Taken care of license warning. | 86 | * Taken care of license warning. |
87 | * | 87 | * |
88 | * 10/12/03 Ravindra Made to work for Fedora Core 1 of | 88 | * 10/12/03 Ravindra Made to work for Fedora Core 1 of |
89 | * Red Hat Distribution | 89 | * Red Hat Distribution |
90 | * | 90 | * |
91 | * 06/01/05 Alan Cox Merged the ISI and base kernel strands | 91 | * 06/01/05 Alan Cox Merged the ISI and base kernel strands |
@@ -93,10 +93,10 @@ | |||
93 | * | 93 | * |
94 | * *********************************************************** | 94 | * *********************************************************** |
95 | * | 95 | * |
96 | * To use this driver you also need the support package. You | 96 | * To use this driver you also need the support package. You |
97 | * can find this in RPM format on | 97 | * can find this in RPM format on |
98 | * ftp://ftp.linux.org.uk/pub/linux/alan | 98 | * ftp://ftp.linux.org.uk/pub/linux/alan |
99 | * | 99 | * |
100 | * You can find the original tools for this direct from Multitech | 100 | * You can find the original tools for this direct from Multitech |
101 | * ftp://ftp.multitech.com/ISI-Cards/ | 101 | * ftp://ftp.multitech.com/ISI-Cards/ |
102 | * | 102 | * |
@@ -107,20 +107,20 @@ | |||
107 | * Omit those entries for boards you don't have installed. | 107 | * Omit those entries for boards you don't have installed. |
108 | * | 108 | * |
109 | * TODO | 109 | * TODO |
110 | * Hotplug | ||
111 | * Merge testing | 110 | * Merge testing |
112 | * 64-bit verification | 111 | * 64-bit verification |
113 | */ | 112 | */ |
114 | 113 | ||
115 | #include <linux/module.h> | 114 | #include <linux/module.h> |
115 | #include <linux/firmware.h> | ||
116 | #include <linux/kernel.h> | 116 | #include <linux/kernel.h> |
117 | #include <linux/tty.h> | 117 | #include <linux/tty.h> |
118 | #include <linux/tty_flip.h> | ||
118 | #include <linux/termios.h> | 119 | #include <linux/termios.h> |
119 | #include <linux/fs.h> | 120 | #include <linux/fs.h> |
120 | #include <linux/sched.h> | 121 | #include <linux/sched.h> |
121 | #include <linux/serial.h> | 122 | #include <linux/serial.h> |
122 | #include <linux/mm.h> | 123 | #include <linux/mm.h> |
123 | #include <linux/miscdevice.h> | ||
124 | #include <linux/interrupt.h> | 124 | #include <linux/interrupt.h> |
125 | #include <linux/timer.h> | 125 | #include <linux/timer.h> |
126 | #include <linux/delay.h> | 126 | #include <linux/delay.h> |
@@ -134,50 +134,62 @@ | |||
134 | 134 | ||
135 | #include <linux/isicom.h> | 135 | #include <linux/isicom.h> |
136 | 136 | ||
137 | #define InterruptTheCard(base) outw(0, (base) + 0xc) | ||
138 | #define ClearInterrupt(base) inw((base) + 0x0a) | ||
139 | |||
140 | #ifdef DEBUG | ||
141 | #define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str) | ||
142 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) | ||
143 | #else | ||
144 | #define pr_dbg(str...) do { } while (0) | ||
145 | #define isicom_paranoia_check(a, b, c) 0 | ||
146 | #endif | ||
147 | |||
148 | static int isicom_probe(struct pci_dev *, const struct pci_device_id *); | ||
149 | static void __devexit isicom_remove(struct pci_dev *); | ||
150 | |||
137 | static struct pci_device_id isicom_pci_tbl[] = { | 151 | static struct pci_device_id isicom_pci_tbl[] = { |
138 | { VENDOR_ID, 0x2028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 152 | { PCI_DEVICE(VENDOR_ID, 0x2028) }, |
139 | { VENDOR_ID, 0x2051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 153 | { PCI_DEVICE(VENDOR_ID, 0x2051) }, |
140 | { VENDOR_ID, 0x2052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 154 | { PCI_DEVICE(VENDOR_ID, 0x2052) }, |
141 | { VENDOR_ID, 0x2053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 155 | { PCI_DEVICE(VENDOR_ID, 0x2053) }, |
142 | { VENDOR_ID, 0x2054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 156 | { PCI_DEVICE(VENDOR_ID, 0x2054) }, |
143 | { VENDOR_ID, 0x2055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 157 | { PCI_DEVICE(VENDOR_ID, 0x2055) }, |
144 | { VENDOR_ID, 0x2056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 158 | { PCI_DEVICE(VENDOR_ID, 0x2056) }, |
145 | { VENDOR_ID, 0x2057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 159 | { PCI_DEVICE(VENDOR_ID, 0x2057) }, |
146 | { VENDOR_ID, 0x2058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 160 | { PCI_DEVICE(VENDOR_ID, 0x2058) }, |
147 | { 0 } | 161 | { 0 } |
148 | }; | 162 | }; |
149 | MODULE_DEVICE_TABLE(pci, isicom_pci_tbl); | 163 | MODULE_DEVICE_TABLE(pci, isicom_pci_tbl); |
150 | 164 | ||
165 | static struct pci_driver isicom_driver = { | ||
166 | .name = "isicom", | ||
167 | .id_table = isicom_pci_tbl, | ||
168 | .probe = isicom_probe, | ||
169 | .remove = __devexit_p(isicom_remove) | ||
170 | }; | ||
171 | |||
151 | static int prev_card = 3; /* start servicing isi_card[0] */ | 172 | static int prev_card = 3; /* start servicing isi_card[0] */ |
152 | static struct tty_driver *isicom_normal; | 173 | static struct tty_driver *isicom_normal; |
153 | 174 | ||
154 | static struct timer_list tx; | 175 | static struct timer_list tx; |
155 | static char re_schedule = 1; | 176 | static char re_schedule = 1; |
156 | #ifdef ISICOM_DEBUG | ||
157 | static unsigned long tx_count = 0; | ||
158 | #endif | ||
159 | |||
160 | static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); | ||
161 | 177 | ||
162 | static void isicom_tx(unsigned long _data); | 178 | static void isicom_tx(unsigned long _data); |
163 | static void isicom_start(struct tty_struct * tty); | 179 | static void isicom_start(struct tty_struct *tty); |
164 | |||
165 | static unsigned char * tmp_buf; | ||
166 | static DECLARE_MUTEX(tmp_buf_sem); | ||
167 | 180 | ||
168 | /* baud index mappings from linux defns to isi */ | 181 | /* baud index mappings from linux defns to isi */ |
169 | 182 | ||
170 | static signed char linuxb_to_isib[] = { | 183 | static signed char linuxb_to_isib[] = { |
171 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, | 184 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19 |
172 | 18, 19 | ||
173 | }; | 185 | }; |
174 | 186 | ||
175 | struct isi_board { | 187 | struct isi_board { |
176 | unsigned short base; | 188 | unsigned long base; |
177 | unsigned char irq; | 189 | unsigned char irq; |
178 | unsigned char port_count; | 190 | unsigned char port_count; |
179 | unsigned short status; | 191 | unsigned short status; |
180 | unsigned short port_status; /* each bit represents a single port */ | 192 | unsigned short port_status; /* each bit for each port */ |
181 | unsigned short shift_count; | 193 | unsigned short shift_count; |
182 | struct isi_port * ports; | 194 | struct isi_port * ports; |
183 | signed char count; | 195 | signed char count; |
@@ -192,9 +204,9 @@ struct isi_port { | |||
192 | int count; | 204 | int count; |
193 | int blocked_open; | 205 | int blocked_open; |
194 | int close_delay; | 206 | int close_delay; |
195 | unsigned short channel; | 207 | u16 channel; |
196 | unsigned short status; | 208 | u16 status; |
197 | unsigned short closing_wait; | 209 | u16 closing_wait; |
198 | struct isi_board * card; | 210 | struct isi_board * card; |
199 | struct tty_struct * tty; | 211 | struct tty_struct * tty; |
200 | wait_queue_head_t close_wait; | 212 | wait_queue_head_t close_wait; |
@@ -215,35 +227,37 @@ static struct isi_port isi_ports[PORT_COUNT]; | |||
215 | * the kernel lock for the card and have the card in a position that | 227 | * the kernel lock for the card and have the card in a position that |
216 | * it wants to talk. | 228 | * it wants to talk. |
217 | */ | 229 | */ |
218 | 230 | ||
219 | static int lock_card(struct isi_board *card) | 231 | static int lock_card(struct isi_board *card) |
220 | { | 232 | { |
221 | char retries; | 233 | char retries; |
222 | unsigned short base = card->base; | 234 | unsigned long base = card->base; |
223 | 235 | ||
224 | for (retries = 0; retries < 100; retries++) { | 236 | for (retries = 0; retries < 100; retries++) { |
225 | spin_lock_irqsave(&card->card_lock, card->flags); | 237 | spin_lock_irqsave(&card->card_lock, card->flags); |
226 | if (inw(base + 0xe) & 0x1) { | 238 | if (inw(base + 0xe) & 0x1) { |
227 | return 1; | 239 | return 1; |
228 | } else { | 240 | } else { |
229 | spin_unlock_irqrestore(&card->card_lock, card->flags); | 241 | spin_unlock_irqrestore(&card->card_lock, card->flags); |
230 | udelay(1000); /* 1ms */ | 242 | udelay(1000); /* 1ms */ |
231 | } | 243 | } |
232 | } | 244 | } |
233 | printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%x)\n", card->base); | 245 | printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n", |
246 | card->base); | ||
247 | |||
234 | return 0; /* Failed to aquire the card! */ | 248 | return 0; /* Failed to aquire the card! */ |
235 | } | 249 | } |
236 | 250 | ||
237 | static int lock_card_at_interrupt(struct isi_board *card) | 251 | static int lock_card_at_interrupt(struct isi_board *card) |
238 | { | 252 | { |
239 | unsigned char retries; | 253 | unsigned char retries; |
240 | unsigned short base = card->base; | 254 | unsigned long base = card->base; |
241 | 255 | ||
242 | for (retries = 0; retries < 200; retries++) { | 256 | for (retries = 0; retries < 200; retries++) { |
243 | spin_lock_irqsave(&card->card_lock, card->flags); | 257 | spin_lock_irqsave(&card->card_lock, card->flags); |
244 | 258 | ||
245 | if (inw(base + 0xe) & 0x1) | 259 | if (inw(base + 0xe) & 0x1) |
246 | return 1; | 260 | return 1; |
247 | else | 261 | else |
248 | spin_unlock_irqrestore(&card->card_lock, card->flags); | 262 | spin_unlock_irqrestore(&card->card_lock, card->flags); |
249 | } | 263 | } |
@@ -259,373 +273,141 @@ static void unlock_card(struct isi_board *card) | |||
259 | /* | 273 | /* |
260 | * ISI Card specific ops ... | 274 | * ISI Card specific ops ... |
261 | */ | 275 | */ |
262 | 276 | ||
263 | static void raise_dtr(struct isi_port * port) | 277 | static void raise_dtr(struct isi_port *port) |
264 | { | 278 | { |
265 | struct isi_board * card = port->card; | 279 | struct isi_board *card = port->card; |
266 | unsigned short base = card->base; | 280 | unsigned long base = card->base; |
267 | unsigned char channel = port->channel; | 281 | u16 channel = port->channel; |
268 | 282 | ||
269 | if (!lock_card(card)) | 283 | if (!lock_card(card)) |
270 | return; | 284 | return; |
271 | 285 | ||
272 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 286 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
273 | outw(0x0504, base); | 287 | outw(0x0504, base); |
274 | InterruptTheCard(base); | 288 | InterruptTheCard(base); |
275 | port->status |= ISI_DTR; | 289 | port->status |= ISI_DTR; |
276 | unlock_card(card); | 290 | unlock_card(card); |
277 | } | 291 | } |
278 | 292 | ||
279 | static inline void drop_dtr(struct isi_port * port) | 293 | static inline void drop_dtr(struct isi_port *port) |
280 | { | 294 | { |
281 | struct isi_board * card = port->card; | 295 | struct isi_board *card = port->card; |
282 | unsigned short base = card->base; | 296 | unsigned long base = card->base; |
283 | unsigned char channel = port->channel; | 297 | u16 channel = port->channel; |
284 | 298 | ||
285 | if (!lock_card(card)) | 299 | if (!lock_card(card)) |
286 | return; | 300 | return; |
287 | 301 | ||
288 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 302 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
289 | outw(0x0404, base); | 303 | outw(0x0404, base); |
290 | InterruptTheCard(base); | 304 | InterruptTheCard(base); |
291 | port->status &= ~ISI_DTR; | 305 | port->status &= ~ISI_DTR; |
292 | unlock_card(card); | 306 | unlock_card(card); |
293 | } | 307 | } |
294 | 308 | ||
295 | static inline void raise_rts(struct isi_port * port) | 309 | static inline void raise_rts(struct isi_port *port) |
296 | { | 310 | { |
297 | struct isi_board * card = port->card; | 311 | struct isi_board *card = port->card; |
298 | unsigned short base = card->base; | 312 | unsigned long base = card->base; |
299 | unsigned char channel = port->channel; | 313 | u16 channel = port->channel; |
300 | 314 | ||
301 | if (!lock_card(card)) | 315 | if (!lock_card(card)) |
302 | return; | 316 | return; |
303 | 317 | ||
304 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 318 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
305 | outw(0x0a04, base); | 319 | outw(0x0a04, base); |
306 | InterruptTheCard(base); | 320 | InterruptTheCard(base); |
307 | port->status |= ISI_RTS; | 321 | port->status |= ISI_RTS; |
308 | unlock_card(card); | 322 | unlock_card(card); |
309 | } | 323 | } |
310 | static inline void drop_rts(struct isi_port * port) | 324 | static inline void drop_rts(struct isi_port *port) |
311 | { | 325 | { |
312 | struct isi_board * card = port->card; | 326 | struct isi_board *card = port->card; |
313 | unsigned short base = card->base; | 327 | unsigned long base = card->base; |
314 | unsigned char channel = port->channel; | 328 | u16 channel = port->channel; |
315 | 329 | ||
316 | if (!lock_card(card)) | 330 | if (!lock_card(card)) |
317 | return; | 331 | return; |
318 | 332 | ||
319 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 333 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
320 | outw(0x0804, base); | 334 | outw(0x0804, base); |
321 | InterruptTheCard(base); | 335 | InterruptTheCard(base); |
322 | port->status &= ~ISI_RTS; | 336 | port->status &= ~ISI_RTS; |
323 | unlock_card(card); | 337 | unlock_card(card); |
324 | } | 338 | } |
325 | 339 | ||
326 | static inline void raise_dtr_rts(struct isi_port * port) | 340 | static inline void raise_dtr_rts(struct isi_port *port) |
327 | { | 341 | { |
328 | struct isi_board * card = port->card; | 342 | struct isi_board *card = port->card; |
329 | unsigned short base = card->base; | 343 | unsigned long base = card->base; |
330 | unsigned char channel = port->channel; | 344 | u16 channel = port->channel; |
331 | 345 | ||
332 | if (!lock_card(card)) | 346 | if (!lock_card(card)) |
333 | return; | 347 | return; |
334 | 348 | ||
335 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 349 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
336 | outw(0x0f04, base); | 350 | outw(0x0f04, base); |
337 | InterruptTheCard(base); | 351 | InterruptTheCard(base); |
338 | port->status |= (ISI_DTR | ISI_RTS); | 352 | port->status |= (ISI_DTR | ISI_RTS); |
339 | unlock_card(card); | 353 | unlock_card(card); |
340 | } | 354 | } |
341 | 355 | ||
342 | static void drop_dtr_rts(struct isi_port * port) | 356 | static void drop_dtr_rts(struct isi_port *port) |
343 | { | 357 | { |
344 | struct isi_board * card = port->card; | 358 | struct isi_board *card = port->card; |
345 | unsigned short base = card->base; | 359 | unsigned long base = card->base; |
346 | unsigned char channel = port->channel; | 360 | u16 channel = port->channel; |
347 | 361 | ||
348 | if (!lock_card(card)) | 362 | if (!lock_card(card)) |
349 | return; | 363 | return; |
350 | 364 | ||
351 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 365 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
352 | outw(0x0c04, base); | 366 | outw(0x0c04, base); |
353 | InterruptTheCard(base); | 367 | InterruptTheCard(base); |
354 | port->status &= ~(ISI_RTS | ISI_DTR); | 368 | port->status &= ~(ISI_RTS | ISI_DTR); |
355 | unlock_card(card); | 369 | unlock_card(card); |
356 | } | 370 | } |
357 | 371 | ||
358 | static inline void kill_queue(struct isi_port * port, short queue) | 372 | static inline void kill_queue(struct isi_port *port, short queue) |
359 | { | 373 | { |
360 | struct isi_board * card = port->card; | 374 | struct isi_board *card = port->card; |
361 | unsigned short base = card->base; | 375 | unsigned long base = card->base; |
362 | unsigned char channel = port->channel; | 376 | u16 channel = port->channel; |
363 | 377 | ||
364 | if (!lock_card(card)) | 378 | if (!lock_card(card)) |
365 | return; | 379 | return; |
366 | 380 | ||
367 | outw(0x8000 | (channel << card->shift_count) | 0x02 , base); | 381 | outw(0x8000 | (channel << card->shift_count) | 0x02, base); |
368 | outw((queue << 8) | 0x06, base); | 382 | outw((queue << 8) | 0x06, base); |
369 | InterruptTheCard(base); | 383 | InterruptTheCard(base); |
370 | unlock_card(card); | 384 | unlock_card(card); |
371 | } | 385 | } |
372 | 386 | ||
373 | |||
374 | /* | ||
375 | * Firmware loader driver specific routines. This needs to mostly die | ||
376 | * and be replaced with request_firmware. | ||
377 | */ | ||
378 | |||
379 | static struct file_operations ISILoad_fops = { | ||
380 | .owner = THIS_MODULE, | ||
381 | .ioctl = ISILoad_ioctl, | ||
382 | }; | ||
383 | |||
384 | static struct miscdevice isiloader_device = { | ||
385 | ISILOAD_MISC_MINOR, "isictl", &ISILoad_fops | ||
386 | }; | ||
387 | |||
388 | |||
389 | static inline int WaitTillCardIsFree(unsigned short base) | ||
390 | { | ||
391 | unsigned long count=0; | ||
392 | while( (!(inw(base+0xe) & 0x1)) && (count++ < 6000000)); | ||
393 | if (inw(base+0xe)&0x1) | ||
394 | return 0; | ||
395 | else | ||
396 | return 1; | ||
397 | } | ||
398 | |||
399 | static int ISILoad_ioctl(struct inode *inode, struct file *filp, | ||
400 | unsigned int cmd, unsigned long arg) | ||
401 | { | ||
402 | unsigned int card, i, j, signature, status, portcount = 0; | ||
403 | unsigned long t; | ||
404 | unsigned short word_count, base; | ||
405 | bin_frame frame; | ||
406 | void __user *argp = (void __user *)arg; | ||
407 | /* exec_record exec_rec; */ | ||
408 | |||
409 | if(get_user(card, (int __user *)argp)) | ||
410 | return -EFAULT; | ||
411 | |||
412 | if(card < 0 || card >= BOARD_COUNT) | ||
413 | return -ENXIO; | ||
414 | |||
415 | base=isi_card[card].base; | ||
416 | |||
417 | if(base==0) | ||
418 | return -ENXIO; /* disabled or not used */ | ||
419 | |||
420 | switch(cmd) { | ||
421 | case MIOCTL_RESET_CARD: | ||
422 | if (!capable(CAP_SYS_ADMIN)) | ||
423 | return -EPERM; | ||
424 | printk(KERN_DEBUG "ISILoad:Resetting Card%d at 0x%x ",card+1,base); | ||
425 | |||
426 | inw(base+0x8); | ||
427 | |||
428 | for(t=jiffies+HZ/100;time_before(jiffies, t);); | ||
429 | |||
430 | outw(0,base+0x8); /* Reset */ | ||
431 | |||
432 | for(j=1;j<=3;j++) { | ||
433 | for(t=jiffies+HZ;time_before(jiffies, t);); | ||
434 | printk("."); | ||
435 | } | ||
436 | signature=(inw(base+0x4)) & 0xff; | ||
437 | if (isi_card[card].isa) { | ||
438 | |||
439 | if (!(inw(base+0xe) & 0x1) || (inw(base+0x2))) { | ||
440 | #ifdef ISICOM_DEBUG | ||
441 | printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe)); | ||
442 | #endif | ||
443 | printk("\nISILoad:ISA Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base); | ||
444 | return -EIO; | ||
445 | } | ||
446 | } | ||
447 | else { | ||
448 | portcount = inw(base+0x2); | ||
449 | if (!(inw(base+0xe) & 0x1) || ((portcount!=0) && (portcount!=4) && (portcount!=8))) { | ||
450 | #ifdef ISICOM_DEBUG | ||
451 | printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe)); | ||
452 | #endif | ||
453 | printk("\nISILoad:PCI Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base); | ||
454 | return -EIO; | ||
455 | } | ||
456 | } | ||
457 | switch(signature) { | ||
458 | case 0xa5: | ||
459 | case 0xbb: | ||
460 | case 0xdd: | ||
461 | if (isi_card[card].isa) | ||
462 | isi_card[card].port_count = 8; | ||
463 | else { | ||
464 | if (portcount == 4) | ||
465 | isi_card[card].port_count = 4; | ||
466 | else | ||
467 | isi_card[card].port_count = 8; | ||
468 | } | ||
469 | isi_card[card].shift_count = 12; | ||
470 | break; | ||
471 | |||
472 | case 0xcc: isi_card[card].port_count = 16; | ||
473 | isi_card[card].shift_count = 11; | ||
474 | break; | ||
475 | |||
476 | default: printk("ISILoad:Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base); | ||
477 | #ifdef ISICOM_DEBUG | ||
478 | printk("Sig=0x%x\n",signature); | ||
479 | #endif | ||
480 | return -EIO; | ||
481 | } | ||
482 | printk("-Done\n"); | ||
483 | return put_user(signature,(unsigned __user *)argp); | ||
484 | |||
485 | case MIOCTL_LOAD_FIRMWARE: | ||
486 | if (!capable(CAP_SYS_ADMIN)) | ||
487 | return -EPERM; | ||
488 | |||
489 | if(copy_from_user(&frame, argp, sizeof(bin_frame))) | ||
490 | return -EFAULT; | ||
491 | |||
492 | if (WaitTillCardIsFree(base)) | ||
493 | return -EIO; | ||
494 | |||
495 | outw(0xf0,base); /* start upload sequence */ | ||
496 | outw(0x00,base); | ||
497 | outw((frame.addr), base);/* lsb of adderess */ | ||
498 | |||
499 | word_count=(frame.count >> 1) + frame.count % 2; | ||
500 | outw(word_count, base); | ||
501 | InterruptTheCard(base); | ||
502 | |||
503 | for(i=0;i<=0x2f;i++); /* a wee bit of delay */ | ||
504 | |||
505 | if (WaitTillCardIsFree(base)) | ||
506 | return -EIO; | ||
507 | |||
508 | if ((status=inw(base+0x4))!=0) { | ||
509 | printk(KERN_WARNING "ISILoad:Card%d rejected load header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n", | ||
510 | card+1, frame.addr, frame.count, status); | ||
511 | return -EIO; | ||
512 | } | ||
513 | outsw(base, (void *) frame.bin_data, word_count); | ||
514 | |||
515 | InterruptTheCard(base); | ||
516 | |||
517 | for(i=0;i<=0x0f;i++); /* another wee bit of delay */ | ||
518 | |||
519 | if (WaitTillCardIsFree(base)) | ||
520 | return -EIO; | ||
521 | |||
522 | if ((status=inw(base+0x4))!=0) { | ||
523 | printk(KERN_ERR "ISILoad:Card%d got out of sync.Card Status:0x%x\n",card+1, status); | ||
524 | return -EIO; | ||
525 | } | ||
526 | return 0; | ||
527 | |||
528 | case MIOCTL_READ_FIRMWARE: | ||
529 | if (!capable(CAP_SYS_ADMIN)) | ||
530 | return -EPERM; | ||
531 | |||
532 | if(copy_from_user(&frame, argp, sizeof(bin_header))) | ||
533 | return -EFAULT; | ||
534 | |||
535 | if (WaitTillCardIsFree(base)) | ||
536 | return -EIO; | ||
537 | |||
538 | outw(0xf1,base); /* start download sequence */ | ||
539 | outw(0x00,base); | ||
540 | outw((frame.addr), base);/* lsb of adderess */ | ||
541 | |||
542 | word_count=(frame.count >> 1) + frame.count % 2; | ||
543 | outw(word_count+1, base); | ||
544 | InterruptTheCard(base); | ||
545 | |||
546 | for(i=0;i<=0xf;i++); /* a wee bit of delay */ | ||
547 | |||
548 | if (WaitTillCardIsFree(base)) | ||
549 | return -EIO; | ||
550 | |||
551 | if ((status=inw(base+0x4))!=0) { | ||
552 | printk(KERN_WARNING "ISILoad:Card%d rejected verify header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n", | ||
553 | card+1, frame.addr, frame.count, status); | ||
554 | return -EIO; | ||
555 | } | ||
556 | |||
557 | inw(base); | ||
558 | insw(base, frame.bin_data, word_count); | ||
559 | InterruptTheCard(base); | ||
560 | |||
561 | for(i=0;i<=0x0f;i++); /* another wee bit of delay */ | ||
562 | |||
563 | if (WaitTillCardIsFree(base)) | ||
564 | return -EIO; | ||
565 | |||
566 | if ((status=inw(base+0x4))!=0) { | ||
567 | printk(KERN_ERR "ISILoad:Card%d verify got out of sync.Card Status:0x%x\n",card+1, status); | ||
568 | return -EIO; | ||
569 | } | ||
570 | |||
571 | if(copy_to_user(argp, &frame, sizeof(bin_frame))) | ||
572 | return -EFAULT; | ||
573 | return 0; | ||
574 | |||
575 | case MIOCTL_XFER_CTRL: | ||
576 | if (!capable(CAP_SYS_ADMIN)) | ||
577 | return -EPERM; | ||
578 | if (WaitTillCardIsFree(base)) | ||
579 | return -EIO; | ||
580 | |||
581 | outw(0xf2, base); | ||
582 | outw(0x800, base); | ||
583 | outw(0x0, base); | ||
584 | outw(0x0, base); | ||
585 | InterruptTheCard(base); | ||
586 | outw(0x0, base+0x4); /* for ISI4608 cards */ | ||
587 | |||
588 | isi_card[card].status |= FIRMWARE_LOADED; | ||
589 | return 0; | ||
590 | |||
591 | default: | ||
592 | #ifdef ISICOM_DEBUG | ||
593 | printk(KERN_DEBUG "ISILoad: Received Ioctl cmd 0x%x.\n", cmd); | ||
594 | #endif | ||
595 | return -ENOIOCTLCMD; | ||
596 | |||
597 | } | ||
598 | |||
599 | } | ||
600 | |||
601 | |||
602 | /* | 387 | /* |
603 | * ISICOM Driver specific routines ... | 388 | * ISICOM Driver specific routines ... |
604 | * | 389 | * |
605 | */ | 390 | */ |
606 | 391 | ||
607 | static inline int isicom_paranoia_check(struct isi_port const * port, char *name, | 392 | static inline int __isicom_paranoia_check(struct isi_port const *port, |
608 | const char * routine) | 393 | char *name, const char *routine) |
609 | { | 394 | { |
610 | #ifdef ISICOM_DEBUG | ||
611 | static const char * badmagic = | ||
612 | KERN_WARNING "ISICOM: Warning: bad isicom magic for dev %s in %s.\n"; | ||
613 | static const char * badport = | ||
614 | KERN_WARNING "ISICOM: Warning: NULL isicom port for dev %s in %s.\n"; | ||
615 | if (!port) { | 395 | if (!port) { |
616 | printk(badport, name, routine); | 396 | printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for " |
397 | "dev %s in %s.\n", name, routine); | ||
617 | return 1; | 398 | return 1; |
618 | } | 399 | } |
619 | if (port->magic != ISICOM_MAGIC) { | 400 | if (port->magic != ISICOM_MAGIC) { |
620 | printk(badmagic, name, routine); | 401 | printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for " |
402 | "dev %s in %s.\n", name, routine); | ||
621 | return 1; | 403 | return 1; |
622 | } | 404 | } |
623 | #endif | 405 | |
624 | return 0; | 406 | return 0; |
625 | } | 407 | } |
626 | 408 | ||
627 | /* | 409 | /* |
628 | * Transmitter. | 410 | * Transmitter. |
629 | * | 411 | * |
630 | * We shovel data into the card buffers on a regular basis. The card | 412 | * We shovel data into the card buffers on a regular basis. The card |
631 | * will do the rest of the work for us. | 413 | * will do the rest of the work for us. |
@@ -635,25 +417,21 @@ static void isicom_tx(unsigned long _data) | |||
635 | { | 417 | { |
636 | short count = (BOARD_COUNT-1), card, base; | 418 | short count = (BOARD_COUNT-1), card, base; |
637 | short txcount, wrd, residue, word_count, cnt; | 419 | short txcount, wrd, residue, word_count, cnt; |
638 | struct isi_port * port; | 420 | struct isi_port *port; |
639 | struct tty_struct * tty; | 421 | struct tty_struct *tty; |
640 | 422 | ||
641 | #ifdef ISICOM_DEBUG | ||
642 | ++tx_count; | ||
643 | #endif | ||
644 | |||
645 | /* find next active board */ | 423 | /* find next active board */ |
646 | card = (prev_card + 1) & 0x0003; | 424 | card = (prev_card + 1) & 0x0003; |
647 | while(count-- > 0) { | 425 | while(count-- > 0) { |
648 | if (isi_card[card].status & BOARD_ACTIVE) | 426 | if (isi_card[card].status & BOARD_ACTIVE) |
649 | break; | 427 | break; |
650 | card = (card + 1) & 0x0003; | 428 | card = (card + 1) & 0x0003; |
651 | } | 429 | } |
652 | if (!(isi_card[card].status & BOARD_ACTIVE)) | 430 | if (!(isi_card[card].status & BOARD_ACTIVE)) |
653 | goto sched_again; | 431 | goto sched_again; |
654 | 432 | ||
655 | prev_card = card; | 433 | prev_card = card; |
656 | 434 | ||
657 | count = isi_card[card].port_count; | 435 | count = isi_card[card].port_count; |
658 | port = isi_card[card].ports; | 436 | port = isi_card[card].ports; |
659 | base = isi_card[card].base; | 437 | base = isi_card[card].base; |
@@ -662,18 +440,18 @@ static void isicom_tx(unsigned long _data) | |||
662 | continue; | 440 | continue; |
663 | /* port not active or tx disabled to force flow control */ | 441 | /* port not active or tx disabled to force flow control */ |
664 | if (!(port->flags & ASYNC_INITIALIZED) || | 442 | if (!(port->flags & ASYNC_INITIALIZED) || |
665 | !(port->status & ISI_TXOK)) | 443 | !(port->status & ISI_TXOK)) |
666 | unlock_card(&isi_card[card]); | 444 | unlock_card(&isi_card[card]); |
667 | continue; | 445 | continue; |
668 | 446 | ||
669 | tty = port->tty; | 447 | tty = port->tty; |
670 | 448 | ||
671 | 449 | ||
672 | if(tty == NULL) { | 450 | if (tty == NULL) { |
673 | unlock_card(&isi_card[card]); | 451 | unlock_card(&isi_card[card]); |
674 | continue; | 452 | continue; |
675 | } | 453 | } |
676 | 454 | ||
677 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); | 455 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); |
678 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) { | 456 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) { |
679 | unlock_card(&isi_card[card]); | 457 | unlock_card(&isi_card[card]); |
@@ -681,44 +459,45 @@ static void isicom_tx(unsigned long _data) | |||
681 | } | 459 | } |
682 | if (!(inw(base + 0x02) & (1 << port->channel))) { | 460 | if (!(inw(base + 0x02) & (1 << port->channel))) { |
683 | unlock_card(&isi_card[card]); | 461 | unlock_card(&isi_card[card]); |
684 | continue; | 462 | continue; |
685 | } | 463 | } |
686 | #ifdef ISICOM_DEBUG | 464 | pr_dbg("txing %d bytes, port%d.\n", txcount, |
687 | printk(KERN_DEBUG "ISICOM: txing %d bytes, port%d.\n", | 465 | port->channel + 1); |
688 | txcount, port->channel+1); | 466 | outw((port->channel << isi_card[card].shift_count) | txcount, |
689 | #endif | 467 | base); |
690 | outw((port->channel << isi_card[card].shift_count) | txcount | ||
691 | , base); | ||
692 | residue = NO; | 468 | residue = NO; |
693 | wrd = 0; | 469 | wrd = 0; |
694 | while (1) { | 470 | while (1) { |
695 | cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE - port->xmit_tail)); | 471 | cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE |
472 | - port->xmit_tail)); | ||
696 | if (residue == YES) { | 473 | if (residue == YES) { |
697 | residue = NO; | 474 | residue = NO; |
698 | if (cnt > 0) { | 475 | if (cnt > 0) { |
699 | wrd |= (port->xmit_buf[port->xmit_tail] << 8); | 476 | wrd |= (port->xmit_buf[port->xmit_tail] |
700 | port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1); | 477 | << 8); |
478 | port->xmit_tail = (port->xmit_tail + 1) | ||
479 | & (SERIAL_XMIT_SIZE - 1); | ||
701 | port->xmit_cnt--; | 480 | port->xmit_cnt--; |
702 | txcount--; | 481 | txcount--; |
703 | cnt--; | 482 | cnt--; |
704 | outw(wrd, base); | 483 | outw(wrd, base); |
705 | } | 484 | } else { |
706 | else { | ||
707 | outw(wrd, base); | 485 | outw(wrd, base); |
708 | break; | 486 | break; |
709 | } | 487 | } |
710 | } | 488 | } |
711 | if (cnt <= 0) break; | 489 | if (cnt <= 0) break; |
712 | word_count = cnt >> 1; | 490 | word_count = cnt >> 1; |
713 | outsw(base, port->xmit_buf+port->xmit_tail, word_count); | 491 | outsw(base, port->xmit_buf+port->xmit_tail,word_count); |
714 | port->xmit_tail = (port->xmit_tail + (word_count << 1)) & | 492 | port->xmit_tail = (port->xmit_tail |
715 | (SERIAL_XMIT_SIZE - 1); | 493 | + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); |
716 | txcount -= (word_count << 1); | 494 | txcount -= (word_count << 1); |
717 | port->xmit_cnt -= (word_count << 1); | 495 | port->xmit_cnt -= (word_count << 1); |
718 | if (cnt & 0x0001) { | 496 | if (cnt & 0x0001) { |
719 | residue = YES; | 497 | residue = YES; |
720 | wrd = port->xmit_buf[port->xmit_tail]; | 498 | wrd = port->xmit_buf[port->xmit_tail]; |
721 | port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1); | 499 | port->xmit_tail = (port->xmit_tail + 1) |
500 | & (SERIAL_XMIT_SIZE - 1); | ||
722 | port->xmit_cnt--; | 501 | port->xmit_cnt--; |
723 | txcount--; | 502 | txcount--; |
724 | } | 503 | } |
@@ -730,81 +509,82 @@ static void isicom_tx(unsigned long _data) | |||
730 | if (port->xmit_cnt <= WAKEUP_CHARS) | 509 | if (port->xmit_cnt <= WAKEUP_CHARS) |
731 | schedule_work(&port->bh_tqueue); | 510 | schedule_work(&port->bh_tqueue); |
732 | unlock_card(&isi_card[card]); | 511 | unlock_card(&isi_card[card]); |
733 | } | 512 | } |
513 | |||
514 | /* schedule another tx for hopefully in about 10ms */ | ||
515 | sched_again: | ||
516 | if (!re_schedule) { | ||
517 | re_schedule = 2; | ||
518 | return; | ||
519 | } | ||
734 | 520 | ||
735 | /* schedule another tx for hopefully in about 10ms */ | ||
736 | sched_again: | ||
737 | if (!re_schedule) | ||
738 | return; | ||
739 | init_timer(&tx); | 521 | init_timer(&tx); |
740 | tx.expires = jiffies + HZ/100; | 522 | tx.expires = jiffies + HZ/100; |
741 | tx.data = 0; | 523 | tx.data = 0; |
742 | tx.function = isicom_tx; | 524 | tx.function = isicom_tx; |
743 | add_timer(&tx); | 525 | add_timer(&tx); |
744 | 526 | ||
745 | return; | 527 | return; |
746 | } | 528 | } |
747 | 529 | ||
748 | /* Interrupt handlers */ | 530 | /* Interrupt handlers */ |
749 | 531 | ||
750 | 532 | ||
751 | static void isicom_bottomhalf(void * data) | 533 | static void isicom_bottomhalf(void *data) |
752 | { | 534 | { |
753 | struct isi_port * port = (struct isi_port *) data; | 535 | struct isi_port *port = (struct isi_port *) data; |
754 | struct tty_struct * tty = port->tty; | 536 | struct tty_struct *tty = port->tty; |
755 | 537 | ||
756 | if (!tty) | 538 | if (!tty) |
757 | return; | 539 | return; |
758 | 540 | ||
759 | tty_wakeup(tty); | 541 | tty_wakeup(tty); |
760 | wake_up_interruptible(&tty->write_wait); | 542 | wake_up_interruptible(&tty->write_wait); |
761 | } | 543 | } |
762 | 544 | ||
763 | /* | 545 | /* |
764 | * Main interrupt handler routine | 546 | * Main interrupt handler routine |
765 | */ | 547 | */ |
766 | 548 | ||
767 | static irqreturn_t isicom_interrupt(int irq, void *dev_id, | 549 | static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
768 | struct pt_regs *regs) | ||
769 | { | 550 | { |
770 | struct isi_board * card; | 551 | struct isi_board *card = dev_id; |
771 | struct isi_port * port; | 552 | struct isi_port *port; |
772 | struct tty_struct * tty; | 553 | struct tty_struct *tty; |
773 | unsigned short base, header, word_count, count; | 554 | unsigned long base; |
774 | unsigned char channel; | 555 | u16 header, word_count, count, channel; |
775 | short byte_count; | 556 | short byte_count; |
776 | 557 | unsigned char *rp; | |
777 | card = (struct isi_board *) dev_id; | ||
778 | 558 | ||
779 | if (!card || !(card->status & FIRMWARE_LOADED)) | 559 | if (!card || !(card->status & FIRMWARE_LOADED)) |
780 | return IRQ_NONE; | 560 | return IRQ_NONE; |
781 | 561 | ||
782 | base = card->base; | 562 | base = card->base; |
783 | spin_lock(&card->card_lock); | 563 | spin_lock(&card->card_lock); |
784 | 564 | ||
785 | if (card->isa == NO) { | 565 | if (card->isa == NO) { |
786 | /* | 566 | /* |
787 | * disable any interrupts from the PCI card and lower the | 567 | * disable any interrupts from the PCI card and lower the |
788 | * interrupt line | 568 | * interrupt line |
789 | */ | 569 | */ |
790 | outw(0x8000, base+0x04); | 570 | outw(0x8000, base+0x04); |
791 | ClearInterrupt(base); | 571 | ClearInterrupt(base); |
792 | } | 572 | } |
793 | 573 | ||
794 | inw(base); /* get the dummy word out */ | 574 | inw(base); /* get the dummy word out */ |
795 | header = inw(base); | 575 | header = inw(base); |
796 | channel = (header & 0x7800) >> card->shift_count; | 576 | channel = (header & 0x7800) >> card->shift_count; |
797 | byte_count = header & 0xff; | 577 | byte_count = header & 0xff; |
798 | 578 | ||
799 | if (channel + 1 > card->port_count) { | 579 | if (channel + 1 > card->port_count) { |
800 | printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%x): %d(channel) > port_count.\n", | 580 | printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): " |
801 | base, channel+1); | 581 | "%d(channel) > port_count.\n", base, channel+1); |
802 | if (card->isa) | 582 | if (card->isa) |
803 | ClearInterrupt(base); | 583 | ClearInterrupt(base); |
804 | else | 584 | else |
805 | outw(0x0000, base+0x04); /* enable interrupts */ | 585 | outw(0x0000, base+0x04); /* enable interrupts */ |
806 | spin_unlock(&card->card_lock); | 586 | spin_unlock(&card->card_lock); |
807 | return IRQ_HANDLED; | 587 | return IRQ_HANDLED; |
808 | } | 588 | } |
809 | port = card->ports + channel; | 589 | port = card->ports + channel; |
810 | if (!(port->flags & ASYNC_INITIALIZED)) { | 590 | if (!(port->flags & ASYNC_INITIALIZED)) { |
@@ -813,8 +593,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
813 | else | 593 | else |
814 | outw(0x0000, base+0x04); /* enable interrupts */ | 594 | outw(0x0000, base+0x04); /* enable interrupts */ |
815 | return IRQ_HANDLED; | 595 | return IRQ_HANDLED; |
816 | } | 596 | } |
817 | 597 | ||
818 | tty = port->tty; | 598 | tty = port->tty; |
819 | if (tty == NULL) { | 599 | if (tty == NULL) { |
820 | word_count = byte_count >> 1; | 600 | word_count = byte_count >> 1; |
@@ -831,224 +611,204 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id, | |||
831 | spin_unlock(&card->card_lock); | 611 | spin_unlock(&card->card_lock); |
832 | return IRQ_HANDLED; | 612 | return IRQ_HANDLED; |
833 | } | 613 | } |
834 | 614 | ||
835 | if (header & 0x8000) { /* Status Packet */ | 615 | if (header & 0x8000) { /* Status Packet */ |
836 | header = inw(base); | 616 | header = inw(base); |
837 | switch(header & 0xff) { | 617 | switch(header & 0xff) { |
838 | case 0: /* Change in EIA signals */ | 618 | case 0: /* Change in EIA signals */ |
839 | 619 | if (port->flags & ASYNC_CHECK_CD) { | |
840 | if (port->flags & ASYNC_CHECK_CD) { | 620 | if (port->status & ISI_DCD) { |
841 | if (port->status & ISI_DCD) { | 621 | if (!(header & ISI_DCD)) { |
842 | if (!(header & ISI_DCD)) { | 622 | /* Carrier has been lost */ |
843 | /* Carrier has been lost */ | 623 | pr_dbg("interrupt: DCD->low.\n" |
844 | #ifdef ISICOM_DEBUG | 624 | ); |
845 | printk(KERN_DEBUG "ISICOM: interrupt: DCD->low.\n"); | ||
846 | #endif | ||
847 | port->status &= ~ISI_DCD; | ||
848 | schedule_work(&port->hangup_tq); | ||
849 | } | ||
850 | } | ||
851 | else { | ||
852 | if (header & ISI_DCD) { | ||
853 | /* Carrier has been detected */ | ||
854 | #ifdef ISICOM_DEBUG | ||
855 | printk(KERN_DEBUG "ISICOM: interrupt: DCD->high.\n"); | ||
856 | #endif | ||
857 | port->status |= ISI_DCD; | ||
858 | wake_up_interruptible(&port->open_wait); | ||
859 | } | ||
860 | } | ||
861 | } | ||
862 | else { | ||
863 | if (header & ISI_DCD) | ||
864 | port->status |= ISI_DCD; | ||
865 | else | ||
866 | port->status &= ~ISI_DCD; | 625 | port->status &= ~ISI_DCD; |
867 | } | 626 | schedule_work(&port->hangup_tq); |
868 | |||
869 | if (port->flags & ASYNC_CTS_FLOW) { | ||
870 | if (port->tty->hw_stopped) { | ||
871 | if (header & ISI_CTS) { | ||
872 | port->tty->hw_stopped = 0; | ||
873 | /* start tx ing */ | ||
874 | port->status |= (ISI_TXOK | ISI_CTS); | ||
875 | schedule_work(&port->bh_tqueue); | ||
876 | } | ||
877 | } | ||
878 | else { | ||
879 | if (!(header & ISI_CTS)) { | ||
880 | port->tty->hw_stopped = 1; | ||
881 | /* stop tx ing */ | ||
882 | port->status &= ~(ISI_TXOK | ISI_CTS); | ||
883 | } | ||
884 | } | 627 | } |
628 | } else if (header & ISI_DCD) { | ||
629 | /* Carrier has been detected */ | ||
630 | pr_dbg("interrupt: DCD->high.\n"); | ||
631 | port->status |= ISI_DCD; | ||
632 | wake_up_interruptible(&port->open_wait); | ||
885 | } | 633 | } |
886 | else { | 634 | } else { |
887 | if (header & ISI_CTS) | 635 | if (header & ISI_DCD) |
888 | port->status |= ISI_CTS; | 636 | port->status |= ISI_DCD; |
889 | else | ||
890 | port->status &= ~ISI_CTS; | ||
891 | } | ||
892 | |||
893 | if (header & ISI_DSR) | ||
894 | port->status |= ISI_DSR; | ||
895 | else | 637 | else |
896 | port->status &= ~ISI_DSR; | 638 | port->status &= ~ISI_DCD; |
897 | 639 | } | |
898 | if (header & ISI_RI) | 640 | |
899 | port->status |= ISI_RI; | 641 | if (port->flags & ASYNC_CTS_FLOW) { |
642 | if (port->tty->hw_stopped) { | ||
643 | if (header & ISI_CTS) { | ||
644 | port->tty->hw_stopped = 0; | ||
645 | /* start tx ing */ | ||
646 | port->status |= (ISI_TXOK | ||
647 | | ISI_CTS); | ||
648 | schedule_work(&port->bh_tqueue); | ||
649 | } | ||
650 | } else if (!(header & ISI_CTS)) { | ||
651 | port->tty->hw_stopped = 1; | ||
652 | /* stop tx ing */ | ||
653 | port->status &= ~(ISI_TXOK | ISI_CTS); | ||
654 | } | ||
655 | } else { | ||
656 | if (header & ISI_CTS) | ||
657 | port->status |= ISI_CTS; | ||
900 | else | 658 | else |
901 | port->status &= ~ISI_RI; | 659 | port->status &= ~ISI_CTS; |
902 | 660 | } | |
903 | break; | 661 | |
904 | 662 | if (header & ISI_DSR) | |
905 | case 1: /* Received Break !!! */ | 663 | port->status |= ISI_DSR; |
906 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 664 | else |
907 | break; | 665 | port->status &= ~ISI_DSR; |
908 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 666 | |
909 | *tty->flip.char_buf_ptr++ = 0; | 667 | if (header & ISI_RI) |
910 | tty->flip.count++; | 668 | port->status |= ISI_RI; |
911 | if (port->flags & ASYNC_SAK) | 669 | else |
912 | do_SAK(tty); | 670 | port->status &= ~ISI_RI; |
913 | schedule_delayed_work(&tty->flip.work, 1); | 671 | |
914 | break; | 672 | break; |
915 | 673 | ||
916 | case 2: /* Statistics */ | 674 | case 1: /* Received Break !!! */ |
917 | printk(KERN_DEBUG "ISICOM: isicom_interrupt: stats!!!.\n"); | 675 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
918 | break; | 676 | if (port->flags & ASYNC_SAK) |
919 | 677 | do_SAK(tty); | |
920 | default: | 678 | tty_flip_buffer_push(tty); |
921 | printk(KERN_WARNING "ISICOM: Intr: Unknown code in status packet.\n"); | 679 | break; |
922 | break; | 680 | |
923 | } | 681 | case 2: /* Statistics */ |
924 | } | 682 | pr_dbg("isicom_interrupt: stats!!!.\n"); |
925 | else { /* Data Packet */ | 683 | break; |
926 | count = min_t(unsigned short, byte_count, (TTY_FLIPBUF_SIZE - tty->flip.count)); | 684 | |
927 | #ifdef ISICOM_DEBUG | 685 | default: |
928 | printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n", | 686 | pr_dbg("Intr: Unknown code in status packet.\n"); |
929 | count, byte_count); | 687 | break; |
930 | #endif | 688 | } |
689 | } else { /* Data Packet */ | ||
690 | |||
691 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); | ||
692 | pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count); | ||
931 | word_count = count >> 1; | 693 | word_count = count >> 1; |
932 | insw(base, tty->flip.char_buf_ptr, word_count); | 694 | insw(base, rp, word_count); |
933 | tty->flip.char_buf_ptr += (word_count << 1); | ||
934 | byte_count -= (word_count << 1); | 695 | byte_count -= (word_count << 1); |
935 | if (count & 0x0001) { | 696 | if (count & 0x0001) { |
936 | *tty->flip.char_buf_ptr++ = (char)(inw(base) & 0xff); | 697 | tty_insert_flip_char(tty, inw(base) & 0xff, |
698 | TTY_NORMAL); | ||
937 | byte_count -= 2; | 699 | byte_count -= 2; |
938 | } | 700 | } |
939 | memset(tty->flip.flag_buf_ptr, 0, count); | ||
940 | tty->flip.flag_buf_ptr += count; | ||
941 | tty->flip.count += count; | ||
942 | |||
943 | if (byte_count > 0) { | 701 | if (byte_count > 0) { |
944 | printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n", | 702 | pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping " |
945 | base, channel+1); | 703 | "bytes...\n", base, channel + 1); |
946 | while(byte_count > 0) { /* drain out unread xtra data */ | 704 | while(byte_count > 0) { /* drain out unread xtra data */ |
947 | inw(base); | 705 | inw(base); |
948 | byte_count -= 2; | 706 | byte_count -= 2; |
949 | } | 707 | } |
950 | } | 708 | } |
951 | schedule_delayed_work(&tty->flip.work, 1); | 709 | tty_flip_buffer_push(tty); |
952 | } | 710 | } |
953 | if (card->isa == YES) | 711 | if (card->isa == YES) |
954 | ClearInterrupt(base); | 712 | ClearInterrupt(base); |
955 | else | 713 | else |
956 | outw(0x0000, base+0x04); /* enable interrupts */ | 714 | outw(0x0000, base+0x04); /* enable interrupts */ |
715 | |||
957 | return IRQ_HANDLED; | 716 | return IRQ_HANDLED; |
958 | } | 717 | } |
959 | 718 | ||
960 | static void isicom_config_port(struct isi_port * port) | 719 | static void isicom_config_port(struct isi_port *port) |
961 | { | 720 | { |
962 | struct isi_board * card = port->card; | 721 | struct isi_board *card = port->card; |
963 | struct tty_struct * tty; | 722 | struct tty_struct *tty; |
964 | unsigned long baud; | 723 | unsigned long baud; |
965 | unsigned short channel_setup, base = card->base; | 724 | unsigned long base = card->base; |
966 | unsigned short channel = port->channel, shift_count = card->shift_count; | 725 | u16 channel_setup, channel = port->channel, |
726 | shift_count = card->shift_count; | ||
967 | unsigned char flow_ctrl; | 727 | unsigned char flow_ctrl; |
968 | 728 | ||
969 | if (!(tty = port->tty) || !tty->termios) | 729 | if (!(tty = port->tty) || !tty->termios) |
970 | return; | 730 | return; |
971 | baud = C_BAUD(tty); | 731 | baud = C_BAUD(tty); |
972 | if (baud & CBAUDEX) { | 732 | if (baud & CBAUDEX) { |
973 | baud &= ~CBAUDEX; | 733 | baud &= ~CBAUDEX; |
974 | 734 | ||
975 | /* if CBAUDEX bit is on and the baud is set to either 50 or 75 | 735 | /* if CBAUDEX bit is on and the baud is set to either 50 or 75 |
976 | * then the card is programmed for 57.6Kbps or 115Kbps | 736 | * then the card is programmed for 57.6Kbps or 115Kbps |
977 | * respectively. | 737 | * respectively. |
978 | */ | 738 | */ |
979 | 739 | ||
980 | if (baud < 1 || baud > 2) | 740 | if (baud < 1 || baud > 2) |
981 | port->tty->termios->c_cflag &= ~CBAUDEX; | 741 | port->tty->termios->c_cflag &= ~CBAUDEX; |
982 | else | 742 | else |
983 | baud += 15; | 743 | baud += 15; |
984 | } | 744 | } |
985 | if (baud == 15) { | 745 | if (baud == 15) { |
986 | 746 | ||
987 | /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set | 747 | /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set |
988 | * by the set_serial_info ioctl ... this is done by | 748 | * by the set_serial_info ioctl ... this is done by |
989 | * the 'setserial' utility. | 749 | * the 'setserial' utility. |
990 | */ | 750 | */ |
991 | 751 | ||
992 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 752 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
993 | baud++; /* 57.6 Kbps */ | 753 | baud++; /* 57.6 Kbps */ |
994 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 754 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
995 | baud +=2; /* 115 Kbps */ | 755 | baud +=2; /* 115 Kbps */ |
996 | } | 756 | } |
997 | if (linuxb_to_isib[baud] == -1) { | 757 | if (linuxb_to_isib[baud] == -1) { |
998 | /* hang up */ | 758 | /* hang up */ |
999 | drop_dtr(port); | 759 | drop_dtr(port); |
1000 | return; | 760 | return; |
1001 | } | 761 | } |
1002 | else | 762 | else |
1003 | raise_dtr(port); | 763 | raise_dtr(port); |
1004 | 764 | ||
1005 | if (lock_card(card)) { | 765 | if (lock_card(card)) { |
1006 | outw(0x8000 | (channel << shift_count) |0x03, base); | 766 | outw(0x8000 | (channel << shift_count) |0x03, base); |
1007 | outw(linuxb_to_isib[baud] << 8 | 0x03, base); | 767 | outw(linuxb_to_isib[baud] << 8 | 0x03, base); |
1008 | channel_setup = 0; | 768 | channel_setup = 0; |
1009 | switch(C_CSIZE(tty)) { | 769 | switch(C_CSIZE(tty)) { |
1010 | case CS5: | 770 | case CS5: |
1011 | channel_setup |= ISICOM_CS5; | 771 | channel_setup |= ISICOM_CS5; |
1012 | break; | 772 | break; |
1013 | case CS6: | 773 | case CS6: |
1014 | channel_setup |= ISICOM_CS6; | 774 | channel_setup |= ISICOM_CS6; |
1015 | break; | 775 | break; |
1016 | case CS7: | 776 | case CS7: |
1017 | channel_setup |= ISICOM_CS7; | 777 | channel_setup |= ISICOM_CS7; |
1018 | break; | 778 | break; |
1019 | case CS8: | 779 | case CS8: |
1020 | channel_setup |= ISICOM_CS8; | 780 | channel_setup |= ISICOM_CS8; |
1021 | break; | 781 | break; |
1022 | } | 782 | } |
1023 | 783 | ||
1024 | if (C_CSTOPB(tty)) | 784 | if (C_CSTOPB(tty)) |
1025 | channel_setup |= ISICOM_2SB; | 785 | channel_setup |= ISICOM_2SB; |
1026 | if (C_PARENB(tty)) { | 786 | if (C_PARENB(tty)) { |
1027 | channel_setup |= ISICOM_EVPAR; | 787 | channel_setup |= ISICOM_EVPAR; |
1028 | if (C_PARODD(tty)) | 788 | if (C_PARODD(tty)) |
1029 | channel_setup |= ISICOM_ODPAR; | 789 | channel_setup |= ISICOM_ODPAR; |
1030 | } | 790 | } |
1031 | outw(channel_setup, base); | 791 | outw(channel_setup, base); |
1032 | InterruptTheCard(base); | 792 | InterruptTheCard(base); |
1033 | unlock_card(card); | 793 | unlock_card(card); |
1034 | } | 794 | } |
1035 | if (C_CLOCAL(tty)) | 795 | if (C_CLOCAL(tty)) |
1036 | port->flags &= ~ASYNC_CHECK_CD; | 796 | port->flags &= ~ASYNC_CHECK_CD; |
1037 | else | 797 | else |
1038 | port->flags |= ASYNC_CHECK_CD; | 798 | port->flags |= ASYNC_CHECK_CD; |
1039 | 799 | ||
1040 | /* flow control settings ...*/ | 800 | /* flow control settings ...*/ |
1041 | flow_ctrl = 0; | 801 | flow_ctrl = 0; |
1042 | port->flags &= ~ASYNC_CTS_FLOW; | 802 | port->flags &= ~ASYNC_CTS_FLOW; |
1043 | if (C_CRTSCTS(tty)) { | 803 | if (C_CRTSCTS(tty)) { |
1044 | port->flags |= ASYNC_CTS_FLOW; | 804 | port->flags |= ASYNC_CTS_FLOW; |
1045 | flow_ctrl |= ISICOM_CTSRTS; | 805 | flow_ctrl |= ISICOM_CTSRTS; |
1046 | } | 806 | } |
1047 | if (I_IXON(tty)) | 807 | if (I_IXON(tty)) |
1048 | flow_ctrl |= ISICOM_RESPOND_XONXOFF; | 808 | flow_ctrl |= ISICOM_RESPOND_XONXOFF; |
1049 | if (I_IXOFF(tty)) | 809 | if (I_IXOFF(tty)) |
1050 | flow_ctrl |= ISICOM_INITIATE_XONXOFF; | 810 | flow_ctrl |= ISICOM_INITIATE_XONXOFF; |
1051 | 811 | ||
1052 | if (lock_card(card)) { | 812 | if (lock_card(card)) { |
1053 | outw(0x8000 | (channel << shift_count) |0x04, base); | 813 | outw(0x8000 | (channel << shift_count) |0x04, base); |
1054 | outw(flow_ctrl << 8 | 0x05, base); | 814 | outw(flow_ctrl << 8 | 0x05, base); |
@@ -1056,22 +816,22 @@ static void isicom_config_port(struct isi_port * port) | |||
1056 | InterruptTheCard(base); | 816 | InterruptTheCard(base); |
1057 | unlock_card(card); | 817 | unlock_card(card); |
1058 | } | 818 | } |
1059 | 819 | ||
1060 | /* rx enabled -> enable port for rx on the card */ | 820 | /* rx enabled -> enable port for rx on the card */ |
1061 | if (C_CREAD(tty)) { | 821 | if (C_CREAD(tty)) { |
1062 | card->port_status |= (1 << channel); | 822 | card->port_status |= (1 << channel); |
1063 | outw(card->port_status, base + 0x02); | 823 | outw(card->port_status, base + 0x02); |
1064 | } | 824 | } |
1065 | } | 825 | } |
1066 | |||
1067 | /* open et all */ | ||
1068 | 826 | ||
1069 | static inline void isicom_setup_board(struct isi_board * bp) | 827 | /* open et all */ |
828 | |||
829 | static inline void isicom_setup_board(struct isi_board *bp) | ||
1070 | { | 830 | { |
1071 | int channel; | 831 | int channel; |
1072 | struct isi_port * port; | 832 | struct isi_port *port; |
1073 | unsigned long flags; | 833 | unsigned long flags; |
1074 | 834 | ||
1075 | spin_lock_irqsave(&bp->card_lock, flags); | 835 | spin_lock_irqsave(&bp->card_lock, flags); |
1076 | if (bp->status & BOARD_ACTIVE) { | 836 | if (bp->status & BOARD_ACTIVE) { |
1077 | spin_unlock_irqrestore(&bp->card_lock, flags); | 837 | spin_unlock_irqrestore(&bp->card_lock, flags); |
@@ -1080,53 +840,54 @@ static inline void isicom_setup_board(struct isi_board * bp) | |||
1080 | port = bp->ports; | 840 | port = bp->ports; |
1081 | bp->status |= BOARD_ACTIVE; | 841 | bp->status |= BOARD_ACTIVE; |
1082 | spin_unlock_irqrestore(&bp->card_lock, flags); | 842 | spin_unlock_irqrestore(&bp->card_lock, flags); |
1083 | for(channel = 0; channel < bp->port_count; channel++, port++) | 843 | for (channel = 0; channel < bp->port_count; channel++, port++) |
1084 | drop_dtr_rts(port); | 844 | drop_dtr_rts(port); |
1085 | return; | 845 | return; |
1086 | } | 846 | } |
1087 | 847 | ||
1088 | static int isicom_setup_port(struct isi_port * port) | 848 | static int isicom_setup_port(struct isi_port *port) |
1089 | { | 849 | { |
1090 | struct isi_board * card = port->card; | 850 | struct isi_board *card = port->card; |
1091 | unsigned long flags; | 851 | unsigned long flags; |
1092 | 852 | ||
1093 | if (port->flags & ASYNC_INITIALIZED) { | 853 | if (port->flags & ASYNC_INITIALIZED) { |
1094 | return 0; | 854 | return 0; |
1095 | } | 855 | } |
1096 | if (!port->xmit_buf) { | 856 | if (!port->xmit_buf) { |
1097 | unsigned long page; | 857 | unsigned long page; |
1098 | 858 | ||
1099 | if (!(page = get_zeroed_page(GFP_KERNEL))) | 859 | if (!(page = get_zeroed_page(GFP_KERNEL))) |
1100 | return -ENOMEM; | 860 | return -ENOMEM; |
1101 | 861 | ||
1102 | if (port->xmit_buf) { | 862 | if (port->xmit_buf) { |
1103 | free_page(page); | 863 | free_page(page); |
1104 | return -ERESTARTSYS; | 864 | return -ERESTARTSYS; |
1105 | } | 865 | } |
1106 | port->xmit_buf = (unsigned char *) page; | 866 | port->xmit_buf = (unsigned char *) page; |
1107 | } | 867 | } |
1108 | 868 | ||
1109 | spin_lock_irqsave(&card->card_lock, flags); | 869 | spin_lock_irqsave(&card->card_lock, flags); |
1110 | if (port->tty) | 870 | if (port->tty) |
1111 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 871 | clear_bit(TTY_IO_ERROR, &port->tty->flags); |
1112 | if (port->count == 1) | 872 | if (port->count == 1) |
1113 | card->count++; | 873 | card->count++; |
1114 | 874 | ||
1115 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 875 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
1116 | 876 | ||
1117 | /* discard any residual data */ | 877 | /* discard any residual data */ |
1118 | kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX); | 878 | kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX); |
1119 | 879 | ||
1120 | isicom_config_port(port); | 880 | isicom_config_port(port); |
1121 | port->flags |= ASYNC_INITIALIZED; | 881 | port->flags |= ASYNC_INITIALIZED; |
1122 | spin_unlock_irqrestore(&card->card_lock, flags); | 882 | spin_unlock_irqrestore(&card->card_lock, flags); |
1123 | 883 | ||
1124 | return 0; | 884 | return 0; |
1125 | } | 885 | } |
1126 | 886 | ||
1127 | static int block_til_ready(struct tty_struct * tty, struct file * filp, struct isi_port * port) | 887 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
888 | struct isi_port *port) | ||
1128 | { | 889 | { |
1129 | struct isi_board * card = port->card; | 890 | struct isi_board *card = port->card; |
1130 | int do_clocal = 0, retval; | 891 | int do_clocal = 0, retval; |
1131 | unsigned long flags; | 892 | unsigned long flags; |
1132 | DECLARE_WAITQUEUE(wait, current); | 893 | DECLARE_WAITQUEUE(wait, current); |
@@ -1134,30 +895,27 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i | |||
1134 | /* block if port is in the process of being closed */ | 895 | /* block if port is in the process of being closed */ |
1135 | 896 | ||
1136 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | 897 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
1137 | #ifdef ISICOM_DEBUG | 898 | pr_dbg("block_til_ready: close in progress.\n"); |
1138 | printk(KERN_DEBUG "ISICOM: block_til_ready: close in progress.\n"); | ||
1139 | #endif | ||
1140 | interruptible_sleep_on(&port->close_wait); | 899 | interruptible_sleep_on(&port->close_wait); |
1141 | if (port->flags & ASYNC_HUP_NOTIFY) | 900 | if (port->flags & ASYNC_HUP_NOTIFY) |
1142 | return -EAGAIN; | 901 | return -EAGAIN; |
1143 | else | 902 | else |
1144 | return -ERESTARTSYS; | 903 | return -ERESTARTSYS; |
1145 | } | 904 | } |
1146 | 905 | ||
1147 | /* if non-blocking mode is set ... */ | 906 | /* if non-blocking mode is set ... */ |
1148 | 907 | ||
1149 | if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { | 908 | if ((filp->f_flags & O_NONBLOCK) || |
1150 | #ifdef ISICOM_DEBUG | 909 | (tty->flags & (1 << TTY_IO_ERROR))) { |
1151 | printk(KERN_DEBUG "ISICOM: block_til_ready: non-block mode.\n"); | 910 | pr_dbg("block_til_ready: non-block mode.\n"); |
1152 | #endif | ||
1153 | port->flags |= ASYNC_NORMAL_ACTIVE; | 911 | port->flags |= ASYNC_NORMAL_ACTIVE; |
1154 | return 0; | 912 | return 0; |
1155 | } | 913 | } |
1156 | 914 | ||
1157 | if (C_CLOCAL(tty)) | 915 | if (C_CLOCAL(tty)) |
1158 | do_clocal = 1; | 916 | do_clocal = 1; |
1159 | 917 | ||
1160 | /* block waiting for DCD to be asserted, and while | 918 | /* block waiting for DCD to be asserted, and while |
1161 | callout dev is busy */ | 919 | callout dev is busy */ |
1162 | retval = 0; | 920 | retval = 0; |
1163 | add_wait_queue(&port->open_wait, &wait); | 921 | add_wait_queue(&port->open_wait, &wait); |
@@ -1167,27 +925,27 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i | |||
1167 | port->count--; | 925 | port->count--; |
1168 | port->blocked_open++; | 926 | port->blocked_open++; |
1169 | spin_unlock_irqrestore(&card->card_lock, flags); | 927 | spin_unlock_irqrestore(&card->card_lock, flags); |
1170 | 928 | ||
1171 | while (1) { | 929 | while (1) { |
1172 | raise_dtr_rts(port); | 930 | raise_dtr_rts(port); |
1173 | 931 | ||
1174 | set_current_state(TASK_INTERRUPTIBLE); | 932 | set_current_state(TASK_INTERRUPTIBLE); |
1175 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | 933 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { |
1176 | if (port->flags & ASYNC_HUP_NOTIFY) | 934 | if (port->flags & ASYNC_HUP_NOTIFY) |
1177 | retval = -EAGAIN; | 935 | retval = -EAGAIN; |
1178 | else | 936 | else |
1179 | retval = -ERESTARTSYS; | 937 | retval = -ERESTARTSYS; |
1180 | break; | 938 | break; |
1181 | } | 939 | } |
1182 | if (!(port->flags & ASYNC_CLOSING) && | 940 | if (!(port->flags & ASYNC_CLOSING) && |
1183 | (do_clocal || (port->status & ISI_DCD))) { | 941 | (do_clocal || (port->status & ISI_DCD))) { |
1184 | break; | 942 | break; |
1185 | } | 943 | } |
1186 | if (signal_pending(current)) { | 944 | if (signal_pending(current)) { |
1187 | retval = -ERESTARTSYS; | 945 | retval = -ERESTARTSYS; |
1188 | break; | 946 | break; |
1189 | } | 947 | } |
1190 | schedule(); | 948 | schedule(); |
1191 | } | 949 | } |
1192 | set_current_state(TASK_RUNNING); | 950 | set_current_state(TASK_RUNNING); |
1193 | remove_wait_queue(&port->open_wait, &wait); | 951 | remove_wait_queue(&port->open_wait, &wait); |
@@ -1201,11 +959,11 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i | |||
1201 | port->flags |= ASYNC_NORMAL_ACTIVE; | 959 | port->flags |= ASYNC_NORMAL_ACTIVE; |
1202 | return 0; | 960 | return 0; |
1203 | } | 961 | } |
1204 | 962 | ||
1205 | static int isicom_open(struct tty_struct * tty, struct file * filp) | 963 | static int isicom_open(struct tty_struct *tty, struct file *filp) |
1206 | { | 964 | { |
1207 | struct isi_port * port; | 965 | struct isi_port *port; |
1208 | struct isi_board * card; | 966 | struct isi_board *card; |
1209 | unsigned int line, board; | 967 | unsigned int line, board; |
1210 | int error; | 968 | int error; |
1211 | 969 | ||
@@ -1214,20 +972,20 @@ static int isicom_open(struct tty_struct * tty, struct file * filp) | |||
1214 | return -ENODEV; | 972 | return -ENODEV; |
1215 | board = BOARD(line); | 973 | board = BOARD(line); |
1216 | card = &isi_card[board]; | 974 | card = &isi_card[board]; |
1217 | 975 | ||
1218 | if (!(card->status & FIRMWARE_LOADED)) | 976 | if (!(card->status & FIRMWARE_LOADED)) |
1219 | return -ENODEV; | 977 | return -ENODEV; |
1220 | 978 | ||
1221 | /* open on a port greater than the port count for the card !!! */ | 979 | /* open on a port greater than the port count for the card !!! */ |
1222 | if (line > ((board * 16) + card->port_count - 1)) | 980 | if (line > ((board * 16) + card->port_count - 1)) |
1223 | return -ENODEV; | 981 | return -ENODEV; |
1224 | 982 | ||
1225 | port = &isi_ports[line]; | 983 | port = &isi_ports[line]; |
1226 | if (isicom_paranoia_check(port, tty->name, "isicom_open")) | 984 | if (isicom_paranoia_check(port, tty->name, "isicom_open")) |
1227 | return -ENODEV; | 985 | return -ENODEV; |
1228 | 986 | ||
1229 | isicom_setup_board(card); | 987 | isicom_setup_board(card); |
1230 | 988 | ||
1231 | port->count++; | 989 | port->count++; |
1232 | tty->driver_data = port; | 990 | tty->driver_data = port; |
1233 | port->tty = tty; | 991 | port->tty = tty; |
@@ -1236,12 +994,12 @@ static int isicom_open(struct tty_struct * tty, struct file * filp) | |||
1236 | if ((error = block_til_ready(tty, filp, port))!=0) | 994 | if ((error = block_til_ready(tty, filp, port))!=0) |
1237 | return error; | 995 | return error; |
1238 | 996 | ||
1239 | return 0; | 997 | return 0; |
1240 | } | 998 | } |
1241 | 999 | ||
1242 | /* close et all */ | 1000 | /* close et all */ |
1243 | 1001 | ||
1244 | static inline void isicom_shutdown_board(struct isi_board * bp) | 1002 | static inline void isicom_shutdown_board(struct isi_board *bp) |
1245 | { | 1003 | { |
1246 | unsigned long flags; | 1004 | unsigned long flags; |
1247 | 1005 | ||
@@ -1252,15 +1010,15 @@ static inline void isicom_shutdown_board(struct isi_board * bp) | |||
1252 | spin_unlock_irqrestore(&bp->card_lock, flags); | 1010 | spin_unlock_irqrestore(&bp->card_lock, flags); |
1253 | } | 1011 | } |
1254 | 1012 | ||
1255 | static void isicom_shutdown_port(struct isi_port * port) | 1013 | static void isicom_shutdown_port(struct isi_port *port) |
1256 | { | 1014 | { |
1257 | struct isi_board * card = port->card; | 1015 | struct isi_board *card = port->card; |
1258 | struct tty_struct * tty; | 1016 | struct tty_struct *tty; |
1259 | unsigned long flags; | 1017 | unsigned long flags; |
1260 | 1018 | ||
1261 | tty = port->tty; | 1019 | tty = port->tty; |
1262 | 1020 | ||
1263 | spin_lock_irqsave(&card->card_lock, flags); | 1021 | spin_lock_irqsave(&card->card_lock, flags); |
1264 | if (!(port->flags & ASYNC_INITIALIZED)) { | 1022 | if (!(port->flags & ASYNC_INITIALIZED)) { |
1265 | spin_unlock_irqrestore(&card->card_lock, flags); | 1023 | spin_unlock_irqrestore(&card->card_lock, flags); |
1266 | return; | 1024 | return; |
@@ -1268,93 +1026,91 @@ static void isicom_shutdown_port(struct isi_port * port) | |||
1268 | if (port->xmit_buf) { | 1026 | if (port->xmit_buf) { |
1269 | free_page((unsigned long) port->xmit_buf); | 1027 | free_page((unsigned long) port->xmit_buf); |
1270 | port->xmit_buf = NULL; | 1028 | port->xmit_buf = NULL; |
1271 | } | 1029 | } |
1272 | port->flags &= ~ASYNC_INITIALIZED; | 1030 | port->flags &= ~ASYNC_INITIALIZED; |
1273 | /* 3rd October 2000 : Vinayak P Risbud */ | 1031 | /* 3rd October 2000 : Vinayak P Risbud */ |
1274 | port->tty = NULL; | 1032 | port->tty = NULL; |
1275 | spin_unlock_irqrestore(&card->card_lock, flags); | 1033 | spin_unlock_irqrestore(&card->card_lock, flags); |
1276 | 1034 | ||
1277 | /*Fix done by Anil .S on 30-04-2001 | 1035 | /*Fix done by Anil .S on 30-04-2001 |
1278 | remote login through isi port has dtr toggle problem | 1036 | remote login through isi port has dtr toggle problem |
1279 | due to which the carrier drops before the password prompt | 1037 | due to which the carrier drops before the password prompt |
1280 | appears on the remote end. Now we drop the dtr only if the | 1038 | appears on the remote end. Now we drop the dtr only if the |
1281 | HUPCL(Hangup on close) flag is set for the tty*/ | 1039 | HUPCL(Hangup on close) flag is set for the tty*/ |
1282 | 1040 | ||
1283 | if (C_HUPCL(tty)) | 1041 | if (C_HUPCL(tty)) |
1284 | /* drop dtr on this port */ | 1042 | /* drop dtr on this port */ |
1285 | drop_dtr(port); | 1043 | drop_dtr(port); |
1286 | 1044 | ||
1287 | /* any other port uninits */ | 1045 | /* any other port uninits */ |
1288 | if (tty) | 1046 | if (tty) |
1289 | set_bit(TTY_IO_ERROR, &tty->flags); | 1047 | set_bit(TTY_IO_ERROR, &tty->flags); |
1290 | 1048 | ||
1291 | if (--card->count < 0) { | 1049 | if (--card->count < 0) { |
1292 | printk(KERN_DEBUG "ISICOM: isicom_shutdown_port: bad board(0x%x) count %d.\n", | 1050 | pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n", |
1293 | card->base, card->count); | 1051 | card->base, card->count); |
1294 | card->count = 0; | 1052 | card->count = 0; |
1295 | } | 1053 | } |
1296 | 1054 | ||
1297 | /* last port was closed , shutdown that boad too */ | 1055 | /* last port was closed, shutdown that boad too */ |
1298 | if(C_HUPCL(tty)) { | 1056 | if (C_HUPCL(tty)) { |
1299 | if (!card->count) | 1057 | if (!card->count) |
1300 | isicom_shutdown_board(card); | 1058 | isicom_shutdown_board(card); |
1301 | } | 1059 | } |
1302 | } | 1060 | } |
1303 | 1061 | ||
1304 | static void isicom_close(struct tty_struct * tty, struct file * filp) | 1062 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
1305 | { | 1063 | { |
1306 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1064 | struct isi_port *port = tty->driver_data; |
1307 | struct isi_board * card = port->card; | 1065 | struct isi_board *card = port->card; |
1308 | unsigned long flags; | 1066 | unsigned long flags; |
1309 | 1067 | ||
1310 | if (!port) | 1068 | if (!port) |
1311 | return; | 1069 | return; |
1312 | if (isicom_paranoia_check(port, tty->name, "isicom_close")) | 1070 | if (isicom_paranoia_check(port, tty->name, "isicom_close")) |
1313 | return; | 1071 | return; |
1314 | 1072 | ||
1315 | #ifdef ISICOM_DEBUG | 1073 | pr_dbg("Close start!!!.\n"); |
1316 | printk(KERN_DEBUG "ISICOM: Close start!!!.\n"); | 1074 | |
1317 | #endif | ||
1318 | |||
1319 | spin_lock_irqsave(&card->card_lock, flags); | 1075 | spin_lock_irqsave(&card->card_lock, flags); |
1320 | if (tty_hung_up_p(filp)) { | 1076 | if (tty_hung_up_p(filp)) { |
1321 | spin_unlock_irqrestore(&card->card_lock, flags); | 1077 | spin_unlock_irqrestore(&card->card_lock, flags); |
1322 | return; | 1078 | return; |
1323 | } | 1079 | } |
1324 | 1080 | ||
1325 | if (tty->count == 1 && port->count != 1) { | 1081 | if (tty->count == 1 && port->count != 1) { |
1326 | printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count" | 1082 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " |
1327 | "tty->count = 1 port count = %d.\n", | 1083 | "count tty->count = 1 port count = %d.\n", |
1328 | card->base, port->count); | 1084 | card->base, port->count); |
1329 | port->count = 1; | 1085 | port->count = 1; |
1330 | } | 1086 | } |
1331 | if (--port->count < 0) { | 1087 | if (--port->count < 0) { |
1332 | printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count for" | 1088 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " |
1333 | "channel%d = %d", card->base, port->channel, | 1089 | "count for channel%d = %d", card->base, port->channel, |
1334 | port->count); | 1090 | port->count); |
1335 | port->count = 0; | 1091 | port->count = 0; |
1336 | } | 1092 | } |
1337 | 1093 | ||
1338 | if (port->count) { | 1094 | if (port->count) { |
1339 | spin_unlock_irqrestore(&card->card_lock, flags); | 1095 | spin_unlock_irqrestore(&card->card_lock, flags); |
1340 | return; | 1096 | return; |
1341 | } | 1097 | } |
1342 | port->flags |= ASYNC_CLOSING; | 1098 | port->flags |= ASYNC_CLOSING; |
1343 | tty->closing = 1; | 1099 | tty->closing = 1; |
1344 | spin_unlock_irqrestore(&card->card_lock, flags); | 1100 | spin_unlock_irqrestore(&card->card_lock, flags); |
1345 | 1101 | ||
1346 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1102 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1347 | tty_wait_until_sent(tty, port->closing_wait); | 1103 | tty_wait_until_sent(tty, port->closing_wait); |
1348 | /* indicate to the card that no more data can be received | 1104 | /* indicate to the card that no more data can be received |
1349 | on this port */ | 1105 | on this port */ |
1350 | spin_lock_irqsave(&card->card_lock, flags); | 1106 | spin_lock_irqsave(&card->card_lock, flags); |
1351 | if (port->flags & ASYNC_INITIALIZED) { | 1107 | if (port->flags & ASYNC_INITIALIZED) { |
1352 | card->port_status &= ~(1 << port->channel); | 1108 | card->port_status &= ~(1 << port->channel); |
1353 | outw(card->port_status, card->base + 0x02); | 1109 | outw(card->port_status, card->base + 0x02); |
1354 | } | 1110 | } |
1355 | isicom_shutdown_port(port); | 1111 | isicom_shutdown_port(port); |
1356 | spin_unlock_irqrestore(&card->card_lock, flags); | 1112 | spin_unlock_irqrestore(&card->card_lock, flags); |
1357 | 1113 | ||
1358 | if (tty->driver->flush_buffer) | 1114 | if (tty->driver->flush_buffer) |
1359 | tty->driver->flush_buffer(tty); | 1115 | tty->driver->flush_buffer(tty); |
1360 | tty_ldisc_flush(tty); | 1116 | tty_ldisc_flush(tty); |
@@ -1365,65 +1121,65 @@ static void isicom_close(struct tty_struct * tty, struct file * filp) | |||
1365 | if (port->blocked_open) { | 1121 | if (port->blocked_open) { |
1366 | spin_unlock_irqrestore(&card->card_lock, flags); | 1122 | spin_unlock_irqrestore(&card->card_lock, flags); |
1367 | if (port->close_delay) { | 1123 | if (port->close_delay) { |
1368 | #ifdef ISICOM_DEBUG | 1124 | pr_dbg("scheduling until time out.\n"); |
1369 | printk(KERN_DEBUG "ISICOM: scheduling until time out.\n"); | 1125 | msleep_interruptible( |
1370 | #endif | 1126 | jiffies_to_msecs(port->close_delay)); |
1371 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | ||
1372 | } | 1127 | } |
1373 | spin_lock_irqsave(&card->card_lock, flags); | 1128 | spin_lock_irqsave(&card->card_lock, flags); |
1374 | wake_up_interruptible(&port->open_wait); | 1129 | wake_up_interruptible(&port->open_wait); |
1375 | } | 1130 | } |
1376 | port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 1131 | port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
1377 | wake_up_interruptible(&port->close_wait); | 1132 | wake_up_interruptible(&port->close_wait); |
1378 | spin_unlock_irqrestore(&card->card_lock, flags); | 1133 | spin_unlock_irqrestore(&card->card_lock, flags); |
1379 | } | 1134 | } |
1380 | 1135 | ||
1381 | /* write et all */ | 1136 | /* write et all */ |
1382 | static int isicom_write(struct tty_struct * tty, | 1137 | static int isicom_write(struct tty_struct *tty, const unsigned char *buf, |
1383 | const unsigned char * buf, int count) | 1138 | int count) |
1384 | { | 1139 | { |
1385 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1140 | struct isi_port *port = tty->driver_data; |
1386 | struct isi_board * card = port->card; | 1141 | struct isi_board *card = port->card; |
1387 | unsigned long flags; | 1142 | unsigned long flags; |
1388 | int cnt, total = 0; | 1143 | int cnt, total = 0; |
1389 | 1144 | ||
1390 | if (isicom_paranoia_check(port, tty->name, "isicom_write")) | 1145 | if (isicom_paranoia_check(port, tty->name, "isicom_write")) |
1391 | return 0; | 1146 | return 0; |
1392 | 1147 | ||
1393 | if (!tty || !port->xmit_buf || !tmp_buf) | 1148 | if (!tty || !port->xmit_buf) |
1394 | return 0; | 1149 | return 0; |
1395 | 1150 | ||
1396 | spin_lock_irqsave(&card->card_lock, flags); | 1151 | spin_lock_irqsave(&card->card_lock, flags); |
1397 | 1152 | ||
1398 | while(1) { | 1153 | while(1) { |
1399 | cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, | 1154 | cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt |
1400 | SERIAL_XMIT_SIZE - port->xmit_head)); | 1155 | - 1, SERIAL_XMIT_SIZE - port->xmit_head)); |
1401 | if (cnt <= 0) | 1156 | if (cnt <= 0) |
1402 | break; | 1157 | break; |
1403 | 1158 | ||
1404 | memcpy(port->xmit_buf + port->xmit_head, buf, cnt); | 1159 | memcpy(port->xmit_buf + port->xmit_head, buf, cnt); |
1405 | port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - 1); | 1160 | port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE |
1161 | - 1); | ||
1406 | port->xmit_cnt += cnt; | 1162 | port->xmit_cnt += cnt; |
1407 | buf += cnt; | 1163 | buf += cnt; |
1408 | count -= cnt; | 1164 | count -= cnt; |
1409 | total += cnt; | 1165 | total += cnt; |
1410 | } | 1166 | } |
1411 | if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped) | 1167 | if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped) |
1412 | port->status |= ISI_TXOK; | 1168 | port->status |= ISI_TXOK; |
1413 | spin_unlock_irqrestore(&card->card_lock, flags); | 1169 | spin_unlock_irqrestore(&card->card_lock, flags); |
1414 | return total; | 1170 | return total; |
1415 | } | 1171 | } |
1416 | 1172 | ||
1417 | /* put_char et all */ | 1173 | /* put_char et all */ |
1418 | static void isicom_put_char(struct tty_struct * tty, unsigned char ch) | 1174 | static void isicom_put_char(struct tty_struct *tty, unsigned char ch) |
1419 | { | 1175 | { |
1420 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1176 | struct isi_port *port = tty->driver_data; |
1421 | struct isi_board * card = port->card; | 1177 | struct isi_board *card = port->card; |
1422 | unsigned long flags; | 1178 | unsigned long flags; |
1423 | 1179 | ||
1424 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) | 1180 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) |
1425 | return; | 1181 | return; |
1426 | 1182 | ||
1427 | if (!tty || !port->xmit_buf) | 1183 | if (!tty || !port->xmit_buf) |
1428 | return; | 1184 | return; |
1429 | 1185 | ||
@@ -1432,7 +1188,7 @@ static void isicom_put_char(struct tty_struct * tty, unsigned char ch) | |||
1432 | spin_unlock_irqrestore(&card->card_lock, flags); | 1188 | spin_unlock_irqrestore(&card->card_lock, flags); |
1433 | return; | 1189 | return; |
1434 | } | 1190 | } |
1435 | 1191 | ||
1436 | port->xmit_buf[port->xmit_head++] = ch; | 1192 | port->xmit_buf[port->xmit_head++] = ch; |
1437 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); | 1193 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); |
1438 | port->xmit_cnt++; | 1194 | port->xmit_cnt++; |
@@ -1440,30 +1196,31 @@ static void isicom_put_char(struct tty_struct * tty, unsigned char ch) | |||
1440 | } | 1196 | } |
1441 | 1197 | ||
1442 | /* flush_chars et all */ | 1198 | /* flush_chars et all */ |
1443 | static void isicom_flush_chars(struct tty_struct * tty) | 1199 | static void isicom_flush_chars(struct tty_struct *tty) |
1444 | { | 1200 | { |
1445 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1201 | struct isi_port *port = tty->driver_data; |
1446 | 1202 | ||
1447 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars")) | 1203 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars")) |
1448 | return; | 1204 | return; |
1449 | 1205 | ||
1450 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf) | 1206 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
1207 | !port->xmit_buf) | ||
1451 | return; | 1208 | return; |
1452 | 1209 | ||
1453 | /* this tells the transmitter to consider this port for | 1210 | /* this tells the transmitter to consider this port for |
1454 | data output to the card ... that's the best we can do. */ | 1211 | data output to the card ... that's the best we can do. */ |
1455 | port->status |= ISI_TXOK; | 1212 | port->status |= ISI_TXOK; |
1456 | } | 1213 | } |
1457 | 1214 | ||
1458 | /* write_room et all */ | 1215 | /* write_room et all */ |
1459 | static int isicom_write_room(struct tty_struct * tty) | 1216 | static int isicom_write_room(struct tty_struct *tty) |
1460 | { | 1217 | { |
1461 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1218 | struct isi_port *port = tty->driver_data; |
1462 | int free; | 1219 | int free; |
1463 | 1220 | ||
1464 | if (isicom_paranoia_check(port, tty->name, "isicom_write_room")) | 1221 | if (isicom_paranoia_check(port, tty->name, "isicom_write_room")) |
1465 | return 0; | 1222 | return 0; |
1466 | 1223 | ||
1467 | free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; | 1224 | free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; |
1468 | if (free < 0) | 1225 | if (free < 0) |
1469 | free = 0; | 1226 | free = 0; |
@@ -1471,23 +1228,24 @@ static int isicom_write_room(struct tty_struct * tty) | |||
1471 | } | 1228 | } |
1472 | 1229 | ||
1473 | /* chars_in_buffer et all */ | 1230 | /* chars_in_buffer et all */ |
1474 | static int isicom_chars_in_buffer(struct tty_struct * tty) | 1231 | static int isicom_chars_in_buffer(struct tty_struct *tty) |
1475 | { | 1232 | { |
1476 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1233 | struct isi_port *port = tty->driver_data; |
1477 | if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer")) | 1234 | if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer")) |
1478 | return 0; | 1235 | return 0; |
1479 | return port->xmit_cnt; | 1236 | return port->xmit_cnt; |
1480 | } | 1237 | } |
1481 | 1238 | ||
1482 | /* ioctl et all */ | 1239 | /* ioctl et all */ |
1483 | static inline void isicom_send_break(struct isi_port * port, unsigned long length) | 1240 | static inline void isicom_send_break(struct isi_port *port, |
1241 | unsigned long length) | ||
1484 | { | 1242 | { |
1485 | struct isi_board * card = port->card; | 1243 | struct isi_board *card = port->card; |
1486 | unsigned short base = card->base; | 1244 | unsigned long base = card->base; |
1487 | 1245 | ||
1488 | if(!lock_card(card)) | 1246 | if (!lock_card(card)) |
1489 | return; | 1247 | return; |
1490 | 1248 | ||
1491 | outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); | 1249 | outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); |
1492 | outw((length & 0xff) << 8 | 0x00, base); | 1250 | outw((length & 0xff) << 8 | 0x00, base); |
1493 | outw((length & 0xff00), base); | 1251 | outw((length & 0xff00), base); |
@@ -1498,13 +1256,13 @@ static inline void isicom_send_break(struct isi_port * port, unsigned long lengt | |||
1498 | 1256 | ||
1499 | static int isicom_tiocmget(struct tty_struct *tty, struct file *file) | 1257 | static int isicom_tiocmget(struct tty_struct *tty, struct file *file) |
1500 | { | 1258 | { |
1501 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1259 | struct isi_port *port = tty->driver_data; |
1502 | /* just send the port status */ | 1260 | /* just send the port status */ |
1503 | unsigned short status = port->status; | 1261 | u16 status = port->status; |
1504 | 1262 | ||
1505 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) | 1263 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) |
1506 | return -ENODEV; | 1264 | return -ENODEV; |
1507 | 1265 | ||
1508 | return ((status & ISI_RTS) ? TIOCM_RTS : 0) | | 1266 | return ((status & ISI_RTS) ? TIOCM_RTS : 0) | |
1509 | ((status & ISI_DTR) ? TIOCM_DTR : 0) | | 1267 | ((status & ISI_DTR) ? TIOCM_DTR : 0) | |
1510 | ((status & ISI_DCD) ? TIOCM_CAR : 0) | | 1268 | ((status & ISI_DCD) ? TIOCM_CAR : 0) | |
@@ -1514,13 +1272,13 @@ static int isicom_tiocmget(struct tty_struct *tty, struct file *file) | |||
1514 | } | 1272 | } |
1515 | 1273 | ||
1516 | static int isicom_tiocmset(struct tty_struct *tty, struct file *file, | 1274 | static int isicom_tiocmset(struct tty_struct *tty, struct file *file, |
1517 | unsigned int set, unsigned int clear) | 1275 | unsigned int set, unsigned int clear) |
1518 | { | 1276 | { |
1519 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1277 | struct isi_port *port = tty->driver_data; |
1520 | 1278 | ||
1521 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) | 1279 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) |
1522 | return -ENODEV; | 1280 | return -ENODEV; |
1523 | 1281 | ||
1524 | if (set & TIOCM_RTS) | 1282 | if (set & TIOCM_RTS) |
1525 | raise_rts(port); | 1283 | raise_rts(port); |
1526 | if (set & TIOCM_DTR) | 1284 | if (set & TIOCM_DTR) |
@@ -1532,46 +1290,46 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file, | |||
1532 | drop_dtr(port); | 1290 | drop_dtr(port); |
1533 | 1291 | ||
1534 | return 0; | 1292 | return 0; |
1535 | } | 1293 | } |
1536 | 1294 | ||
1537 | static int isicom_set_serial_info(struct isi_port * port, | 1295 | static int isicom_set_serial_info(struct isi_port *port, |
1538 | struct serial_struct __user *info) | 1296 | struct serial_struct __user *info) |
1539 | { | 1297 | { |
1540 | struct serial_struct newinfo; | 1298 | struct serial_struct newinfo; |
1541 | int reconfig_port; | 1299 | int reconfig_port; |
1542 | 1300 | ||
1543 | if(copy_from_user(&newinfo, info, sizeof(newinfo))) | 1301 | if (copy_from_user(&newinfo, info, sizeof(newinfo))) |
1544 | return -EFAULT; | 1302 | return -EFAULT; |
1545 | 1303 | ||
1546 | reconfig_port = ((port->flags & ASYNC_SPD_MASK) != | 1304 | reconfig_port = ((port->flags & ASYNC_SPD_MASK) != |
1547 | (newinfo.flags & ASYNC_SPD_MASK)); | 1305 | (newinfo.flags & ASYNC_SPD_MASK)); |
1548 | 1306 | ||
1549 | if (!capable(CAP_SYS_ADMIN)) { | 1307 | if (!capable(CAP_SYS_ADMIN)) { |
1550 | if ((newinfo.close_delay != port->close_delay) || | 1308 | if ((newinfo.close_delay != port->close_delay) || |
1551 | (newinfo.closing_wait != port->closing_wait) || | 1309 | (newinfo.closing_wait != port->closing_wait) || |
1552 | ((newinfo.flags & ~ASYNC_USR_MASK) != | 1310 | ((newinfo.flags & ~ASYNC_USR_MASK) != |
1553 | (port->flags & ~ASYNC_USR_MASK))) | 1311 | (port->flags & ~ASYNC_USR_MASK))) |
1554 | return -EPERM; | 1312 | return -EPERM; |
1555 | port->flags = ((port->flags & ~ ASYNC_USR_MASK) | | 1313 | port->flags = ((port->flags & ~ ASYNC_USR_MASK) | |
1556 | (newinfo.flags & ASYNC_USR_MASK)); | 1314 | (newinfo.flags & ASYNC_USR_MASK)); |
1557 | } | 1315 | } |
1558 | else { | 1316 | else { |
1559 | port->close_delay = newinfo.close_delay; | 1317 | port->close_delay = newinfo.close_delay; |
1560 | port->closing_wait = newinfo.closing_wait; | 1318 | port->closing_wait = newinfo.closing_wait; |
1561 | port->flags = ((port->flags & ~ASYNC_FLAGS) | | 1319 | port->flags = ((port->flags & ~ASYNC_FLAGS) | |
1562 | (newinfo.flags & ASYNC_FLAGS)); | 1320 | (newinfo.flags & ASYNC_FLAGS)); |
1563 | } | 1321 | } |
1564 | if (reconfig_port) { | 1322 | if (reconfig_port) { |
1565 | isicom_config_port(port); | 1323 | isicom_config_port(port); |
1566 | } | 1324 | } |
1567 | return 0; | 1325 | return 0; |
1568 | } | 1326 | } |
1569 | 1327 | ||
1570 | static int isicom_get_serial_info(struct isi_port * port, | 1328 | static int isicom_get_serial_info(struct isi_port *port, |
1571 | struct serial_struct __user *info) | 1329 | struct serial_struct __user *info) |
1572 | { | 1330 | { |
1573 | struct serial_struct out_info; | 1331 | struct serial_struct out_info; |
1574 | 1332 | ||
1575 | memset(&out_info, 0, sizeof(out_info)); | 1333 | memset(&out_info, 0, sizeof(out_info)); |
1576 | /* out_info.type = ? */ | 1334 | /* out_info.type = ? */ |
1577 | out_info.line = port - isi_ports; | 1335 | out_info.line = port - isi_ports; |
@@ -1581,15 +1339,15 @@ static int isicom_get_serial_info(struct isi_port * port, | |||
1581 | /* out_info.baud_base = ? */ | 1339 | /* out_info.baud_base = ? */ |
1582 | out_info.close_delay = port->close_delay; | 1340 | out_info.close_delay = port->close_delay; |
1583 | out_info.closing_wait = port->closing_wait; | 1341 | out_info.closing_wait = port->closing_wait; |
1584 | if(copy_to_user(info, &out_info, sizeof(out_info))) | 1342 | if (copy_to_user(info, &out_info, sizeof(out_info))) |
1585 | return -EFAULT; | 1343 | return -EFAULT; |
1586 | return 0; | 1344 | return 0; |
1587 | } | 1345 | } |
1588 | 1346 | ||
1589 | static int isicom_ioctl(struct tty_struct * tty, struct file * filp, | 1347 | static int isicom_ioctl(struct tty_struct *tty, struct file *filp, |
1590 | unsigned int cmd, unsigned long arg) | 1348 | unsigned int cmd, unsigned long arg) |
1591 | { | 1349 | { |
1592 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1350 | struct isi_port *port = tty->driver_data; |
1593 | void __user *argp = (void __user *)arg; | 1351 | void __user *argp = (void __user *)arg; |
1594 | int retval; | 1352 | int retval; |
1595 | 1353 | ||
@@ -1597,139 +1355,141 @@ static int isicom_ioctl(struct tty_struct * tty, struct file * filp, | |||
1597 | return -ENODEV; | 1355 | return -ENODEV; |
1598 | 1356 | ||
1599 | switch(cmd) { | 1357 | switch(cmd) { |
1600 | case TCSBRK: | 1358 | case TCSBRK: |
1601 | retval = tty_check_change(tty); | 1359 | retval = tty_check_change(tty); |
1602 | if (retval) | 1360 | if (retval) |
1603 | return retval; | 1361 | return retval; |
1604 | tty_wait_until_sent(tty, 0); | 1362 | tty_wait_until_sent(tty, 0); |
1605 | if (!arg) | 1363 | if (!arg) |
1606 | isicom_send_break(port, HZ/4); | 1364 | isicom_send_break(port, HZ/4); |
1607 | return 0; | 1365 | return 0; |
1608 | 1366 | ||
1609 | case TCSBRKP: | 1367 | case TCSBRKP: |
1610 | retval = tty_check_change(tty); | 1368 | retval = tty_check_change(tty); |
1611 | if (retval) | 1369 | if (retval) |
1612 | return retval; | 1370 | return retval; |
1613 | tty_wait_until_sent(tty, 0); | 1371 | tty_wait_until_sent(tty, 0); |
1614 | isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4); | 1372 | isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4); |
1615 | return 0; | 1373 | return 0; |
1616 | 1374 | ||
1617 | case TIOCGSOFTCAR: | 1375 | case TIOCGSOFTCAR: |
1618 | return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); | 1376 | return put_user(C_CLOCAL(tty) ? 1 : 0, |
1619 | 1377 | (unsigned long __user *)argp); | |
1620 | case TIOCSSOFTCAR: | 1378 | |
1621 | if(get_user(arg, (unsigned long __user *) argp)) | 1379 | case TIOCSSOFTCAR: |
1622 | return -EFAULT; | 1380 | if (get_user(arg, (unsigned long __user *) argp)) |
1623 | tty->termios->c_cflag = | 1381 | return -EFAULT; |
1624 | ((tty->termios->c_cflag & ~CLOCAL) | | 1382 | tty->termios->c_cflag = |
1625 | (arg ? CLOCAL : 0)); | 1383 | ((tty->termios->c_cflag & ~CLOCAL) | |
1626 | return 0; | 1384 | (arg ? CLOCAL : 0)); |
1627 | 1385 | return 0; | |
1628 | case TIOCGSERIAL: | 1386 | |
1629 | return isicom_get_serial_info(port, argp); | 1387 | case TIOCGSERIAL: |
1630 | 1388 | return isicom_get_serial_info(port, argp); | |
1631 | case TIOCSSERIAL: | 1389 | |
1632 | return isicom_set_serial_info(port, argp); | 1390 | case TIOCSSERIAL: |
1633 | 1391 | return isicom_set_serial_info(port, argp); | |
1634 | default: | 1392 | |
1635 | return -ENOIOCTLCMD; | 1393 | default: |
1394 | return -ENOIOCTLCMD; | ||
1636 | } | 1395 | } |
1637 | return 0; | 1396 | return 0; |
1638 | } | 1397 | } |
1639 | 1398 | ||
1640 | /* set_termios et all */ | 1399 | /* set_termios et all */ |
1641 | static void isicom_set_termios(struct tty_struct * tty, struct termios * old_termios) | 1400 | static void isicom_set_termios(struct tty_struct *tty, |
1401 | struct termios *old_termios) | ||
1642 | { | 1402 | { |
1643 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1403 | struct isi_port *port = tty->driver_data; |
1644 | 1404 | ||
1645 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) | 1405 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) |
1646 | return; | 1406 | return; |
1647 | 1407 | ||
1648 | if (tty->termios->c_cflag == old_termios->c_cflag && | 1408 | if (tty->termios->c_cflag == old_termios->c_cflag && |
1649 | tty->termios->c_iflag == old_termios->c_iflag) | 1409 | tty->termios->c_iflag == old_termios->c_iflag) |
1650 | return; | 1410 | return; |
1651 | 1411 | ||
1652 | isicom_config_port(port); | 1412 | isicom_config_port(port); |
1653 | 1413 | ||
1654 | if ((old_termios->c_cflag & CRTSCTS) && | 1414 | if ((old_termios->c_cflag & CRTSCTS) && |
1655 | !(tty->termios->c_cflag & CRTSCTS)) { | 1415 | !(tty->termios->c_cflag & CRTSCTS)) { |
1656 | tty->hw_stopped = 0; | 1416 | tty->hw_stopped = 0; |
1657 | isicom_start(tty); | 1417 | isicom_start(tty); |
1658 | } | 1418 | } |
1659 | } | 1419 | } |
1660 | 1420 | ||
1661 | /* throttle et all */ | 1421 | /* throttle et all */ |
1662 | static void isicom_throttle(struct tty_struct * tty) | 1422 | static void isicom_throttle(struct tty_struct *tty) |
1663 | { | 1423 | { |
1664 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1424 | struct isi_port *port = tty->driver_data; |
1665 | struct isi_board * card = port->card; | 1425 | struct isi_board *card = port->card; |
1666 | 1426 | ||
1667 | if (isicom_paranoia_check(port, tty->name, "isicom_throttle")) | 1427 | if (isicom_paranoia_check(port, tty->name, "isicom_throttle")) |
1668 | return; | 1428 | return; |
1669 | 1429 | ||
1670 | /* tell the card that this port cannot handle any more data for now */ | 1430 | /* tell the card that this port cannot handle any more data for now */ |
1671 | card->port_status &= ~(1 << port->channel); | 1431 | card->port_status &= ~(1 << port->channel); |
1672 | outw(card->port_status, card->base + 0x02); | 1432 | outw(card->port_status, card->base + 0x02); |
1673 | } | 1433 | } |
1674 | 1434 | ||
1675 | /* unthrottle et all */ | 1435 | /* unthrottle et all */ |
1676 | static void isicom_unthrottle(struct tty_struct * tty) | 1436 | static void isicom_unthrottle(struct tty_struct *tty) |
1677 | { | 1437 | { |
1678 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1438 | struct isi_port *port = tty->driver_data; |
1679 | struct isi_board * card = port->card; | 1439 | struct isi_board *card = port->card; |
1680 | 1440 | ||
1681 | if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle")) | 1441 | if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle")) |
1682 | return; | 1442 | return; |
1683 | 1443 | ||
1684 | /* tell the card that this port is ready to accept more data */ | 1444 | /* tell the card that this port is ready to accept more data */ |
1685 | card->port_status |= (1 << port->channel); | 1445 | card->port_status |= (1 << port->channel); |
1686 | outw(card->port_status, card->base + 0x02); | 1446 | outw(card->port_status, card->base + 0x02); |
1687 | } | 1447 | } |
1688 | 1448 | ||
1689 | /* stop et all */ | 1449 | /* stop et all */ |
1690 | static void isicom_stop(struct tty_struct * tty) | 1450 | static void isicom_stop(struct tty_struct *tty) |
1691 | { | 1451 | { |
1692 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1452 | struct isi_port *port = tty->driver_data; |
1693 | 1453 | ||
1694 | if (isicom_paranoia_check(port, tty->name, "isicom_stop")) | 1454 | if (isicom_paranoia_check(port, tty->name, "isicom_stop")) |
1695 | return; | 1455 | return; |
1696 | 1456 | ||
1697 | /* this tells the transmitter not to consider this port for | 1457 | /* this tells the transmitter not to consider this port for |
1698 | data output to the card. */ | 1458 | data output to the card. */ |
1699 | port->status &= ~ISI_TXOK; | 1459 | port->status &= ~ISI_TXOK; |
1700 | } | 1460 | } |
1701 | 1461 | ||
1702 | /* start et all */ | 1462 | /* start et all */ |
1703 | static void isicom_start(struct tty_struct * tty) | 1463 | static void isicom_start(struct tty_struct *tty) |
1704 | { | 1464 | { |
1705 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1465 | struct isi_port *port = tty->driver_data; |
1706 | 1466 | ||
1707 | if (isicom_paranoia_check(port, tty->name, "isicom_start")) | 1467 | if (isicom_paranoia_check(port, tty->name, "isicom_start")) |
1708 | return; | 1468 | return; |
1709 | 1469 | ||
1710 | /* this tells the transmitter to consider this port for | 1470 | /* this tells the transmitter to consider this port for |
1711 | data output to the card. */ | 1471 | data output to the card. */ |
1712 | port->status |= ISI_TXOK; | 1472 | port->status |= ISI_TXOK; |
1713 | } | 1473 | } |
1714 | 1474 | ||
1715 | /* hangup et all */ | 1475 | /* hangup et all */ |
1716 | static void do_isicom_hangup(void * data) | 1476 | static void do_isicom_hangup(void *data) |
1717 | { | 1477 | { |
1718 | struct isi_port * port = (struct isi_port *) data; | 1478 | struct isi_port *port = data; |
1719 | struct tty_struct * tty; | 1479 | struct tty_struct *tty; |
1720 | 1480 | ||
1721 | tty = port->tty; | 1481 | tty = port->tty; |
1722 | if (tty) | 1482 | if (tty) |
1723 | tty_hangup(tty); | 1483 | tty_hangup(tty); |
1724 | } | 1484 | } |
1725 | 1485 | ||
1726 | static void isicom_hangup(struct tty_struct * tty) | 1486 | static void isicom_hangup(struct tty_struct *tty) |
1727 | { | 1487 | { |
1728 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1488 | struct isi_port *port = tty->driver_data; |
1729 | 1489 | ||
1730 | if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) | 1490 | if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) |
1731 | return; | 1491 | return; |
1732 | 1492 | ||
1733 | isicom_shutdown_port(port); | 1493 | isicom_shutdown_port(port); |
1734 | port->count = 0; | 1494 | port->count = 0; |
1735 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 1495 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -1738,342 +1498,540 @@ static void isicom_hangup(struct tty_struct * tty) | |||
1738 | } | 1498 | } |
1739 | 1499 | ||
1740 | /* flush_buffer et all */ | 1500 | /* flush_buffer et all */ |
1741 | static void isicom_flush_buffer(struct tty_struct * tty) | 1501 | static void isicom_flush_buffer(struct tty_struct *tty) |
1742 | { | 1502 | { |
1743 | struct isi_port * port = (struct isi_port *) tty->driver_data; | 1503 | struct isi_port *port = tty->driver_data; |
1744 | struct isi_board * card = port->card; | 1504 | struct isi_board *card = port->card; |
1745 | unsigned long flags; | 1505 | unsigned long flags; |
1746 | 1506 | ||
1747 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) | 1507 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) |
1748 | return; | 1508 | return; |
1749 | 1509 | ||
1750 | spin_lock_irqsave(&card->card_lock, flags); | 1510 | spin_lock_irqsave(&card->card_lock, flags); |
1751 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 1511 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
1752 | spin_unlock_irqrestore(&card->card_lock, flags); | 1512 | spin_unlock_irqrestore(&card->card_lock, flags); |
1753 | 1513 | ||
1754 | wake_up_interruptible(&tty->write_wait); | 1514 | wake_up_interruptible(&tty->write_wait); |
1755 | tty_wakeup(tty); | 1515 | tty_wakeup(tty); |
1756 | } | 1516 | } |
1757 | 1517 | ||
1518 | /* | ||
1519 | * Driver init and deinit functions | ||
1520 | */ | ||
1758 | 1521 | ||
1759 | static int __devinit register_ioregion(void) | 1522 | static int __devinit isicom_register_ioregion(struct pci_dev *pdev, |
1523 | const unsigned int index) | ||
1760 | { | 1524 | { |
1761 | int count, done=0; | 1525 | struct isi_board *board = pci_get_drvdata(pdev); |
1762 | for (count=0; count < BOARD_COUNT; count++ ) { | 1526 | |
1763 | if (isi_card[count].base) | 1527 | if (!board->base) |
1764 | if (!request_region(isi_card[count].base,16,ISICOM_NAME)) { | 1528 | return -EINVAL; |
1765 | printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x is busy. Card%d will be disabled.\n", | 1529 | |
1766 | isi_card[count].base,isi_card[count].base+15,count+1); | 1530 | if (!request_region(board->base, 16, ISICOM_NAME)) { |
1767 | isi_card[count].base=0; | 1531 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " |
1768 | done++; | 1532 | "will be disabled.\n", board->base, board->base + 15, |
1769 | } | 1533 | index + 1); |
1770 | } | 1534 | return -EBUSY; |
1771 | return done; | 1535 | } |
1536 | |||
1537 | return 0; | ||
1772 | } | 1538 | } |
1773 | 1539 | ||
1774 | static void unregister_ioregion(void) | 1540 | static void isicom_unregister_ioregion(struct pci_dev *pdev) |
1775 | { | 1541 | { |
1776 | int count; | 1542 | struct isi_board *board = pci_get_drvdata(pdev); |
1777 | for (count=0; count < BOARD_COUNT; count++ ) | 1543 | |
1778 | if (isi_card[count].base) { | 1544 | if (!board->base) |
1779 | release_region(isi_card[count].base,16); | 1545 | return; |
1780 | #ifdef ISICOM_DEBUG | 1546 | |
1781 | printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x released for Card%d.\n",isi_card[count].base,isi_card[count].base+15,count+1); | 1547 | release_region(board->base, 16); |
1782 | #endif | 1548 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n", |
1783 | } | 1549 | board->base, board->base + 15); |
1550 | board->base = 0; | ||
1784 | } | 1551 | } |
1785 | 1552 | ||
1786 | static struct tty_operations isicom_ops = { | 1553 | static struct tty_operations isicom_ops = { |
1787 | .open = isicom_open, | 1554 | .open = isicom_open, |
1788 | .close = isicom_close, | 1555 | .close = isicom_close, |
1789 | .write = isicom_write, | 1556 | .write = isicom_write, |
1790 | .put_char = isicom_put_char, | 1557 | .put_char = isicom_put_char, |
1791 | .flush_chars = isicom_flush_chars, | 1558 | .flush_chars = isicom_flush_chars, |
1792 | .write_room = isicom_write_room, | 1559 | .write_room = isicom_write_room, |
1793 | .chars_in_buffer = isicom_chars_in_buffer, | 1560 | .chars_in_buffer = isicom_chars_in_buffer, |
1794 | .ioctl = isicom_ioctl, | 1561 | .ioctl = isicom_ioctl, |
1795 | .set_termios = isicom_set_termios, | 1562 | .set_termios = isicom_set_termios, |
1796 | .throttle = isicom_throttle, | 1563 | .throttle = isicom_throttle, |
1797 | .unthrottle = isicom_unthrottle, | 1564 | .unthrottle = isicom_unthrottle, |
1798 | .stop = isicom_stop, | 1565 | .stop = isicom_stop, |
1799 | .start = isicom_start, | 1566 | .start = isicom_start, |
1800 | .hangup = isicom_hangup, | 1567 | .hangup = isicom_hangup, |
1801 | .flush_buffer = isicom_flush_buffer, | 1568 | .flush_buffer = isicom_flush_buffer, |
1802 | .tiocmget = isicom_tiocmget, | 1569 | .tiocmget = isicom_tiocmget, |
1803 | .tiocmset = isicom_tiocmset, | 1570 | .tiocmset = isicom_tiocmset, |
1804 | }; | 1571 | }; |
1805 | 1572 | ||
1806 | static int __devinit register_drivers(void) | 1573 | static int __devinit isicom_register_tty_driver(void) |
1807 | { | 1574 | { |
1808 | int error; | 1575 | int error = -ENOMEM; |
1809 | 1576 | ||
1810 | /* tty driver structure initialization */ | 1577 | /* tty driver structure initialization */ |
1811 | isicom_normal = alloc_tty_driver(PORT_COUNT); | 1578 | isicom_normal = alloc_tty_driver(PORT_COUNT); |
1812 | if (!isicom_normal) | 1579 | if (!isicom_normal) |
1813 | return -ENOMEM; | 1580 | goto end; |
1814 | 1581 | ||
1815 | isicom_normal->owner = THIS_MODULE; | 1582 | isicom_normal->owner = THIS_MODULE; |
1816 | isicom_normal->name = "ttyM"; | 1583 | isicom_normal->name = "ttyM"; |
1817 | isicom_normal->devfs_name = "isicom/"; | 1584 | isicom_normal->devfs_name = "isicom/"; |
1818 | isicom_normal->major = ISICOM_NMAJOR; | 1585 | isicom_normal->major = ISICOM_NMAJOR; |
1819 | isicom_normal->minor_start = 0; | 1586 | isicom_normal->minor_start = 0; |
1820 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | 1587 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; |
1821 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; | 1588 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; |
1822 | isicom_normal->init_termios = tty_std_termios; | 1589 | isicom_normal->init_termios = tty_std_termios; |
1823 | isicom_normal->init_termios.c_cflag = | 1590 | isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | |
1824 | B9600 | CS8 | CREAD | HUPCL |CLOCAL; | 1591 | CLOCAL; |
1825 | isicom_normal->flags = TTY_DRIVER_REAL_RAW; | 1592 | isicom_normal->flags = TTY_DRIVER_REAL_RAW; |
1826 | tty_set_operations(isicom_normal, &isicom_ops); | 1593 | tty_set_operations(isicom_normal, &isicom_ops); |
1827 | 1594 | ||
1828 | if ((error=tty_register_driver(isicom_normal))!=0) { | 1595 | if ((error = tty_register_driver(isicom_normal))) { |
1829 | printk(KERN_DEBUG "ISICOM: Couldn't register the dialin driver, error=%d\n", | 1596 | pr_dbg("Couldn't register the dialin driver, error=%d\n", |
1830 | error); | 1597 | error); |
1831 | put_tty_driver(isicom_normal); | 1598 | put_tty_driver(isicom_normal); |
1832 | return error; | ||
1833 | } | 1599 | } |
1834 | return 0; | 1600 | end: |
1601 | return error; | ||
1835 | } | 1602 | } |
1836 | 1603 | ||
1837 | static void unregister_drivers(void) | 1604 | static void isicom_unregister_tty_driver(void) |
1838 | { | 1605 | { |
1839 | int error = tty_unregister_driver(isicom_normal); | 1606 | int error; |
1840 | if (error) | 1607 | |
1841 | printk(KERN_DEBUG "ISICOM: couldn't unregister normal driver error=%d.\n",error); | 1608 | if ((error = tty_unregister_driver(isicom_normal))) |
1609 | pr_dbg("couldn't unregister normal driver, error=%d.\n", error); | ||
1610 | |||
1842 | put_tty_driver(isicom_normal); | 1611 | put_tty_driver(isicom_normal); |
1843 | } | 1612 | } |
1844 | 1613 | ||
1845 | static int __devinit register_isr(void) | 1614 | static int __devinit isicom_register_isr(struct pci_dev *pdev, |
1615 | const unsigned int index) | ||
1846 | { | 1616 | { |
1847 | int count, done=0; | 1617 | struct isi_board *board = pci_get_drvdata(pdev); |
1848 | unsigned long irqflags; | 1618 | unsigned long irqflags = SA_INTERRUPT; |
1849 | 1619 | int retval = -EINVAL; | |
1850 | for (count=0; count < BOARD_COUNT; count++ ) { | 1620 | |
1851 | if (isi_card[count].base) { | 1621 | if (!board->base) |
1852 | irqflags = (isi_card[count].isa == YES) ? | 1622 | goto end; |
1853 | SA_INTERRUPT : | 1623 | |
1854 | (SA_INTERRUPT | SA_SHIRQ); | 1624 | if (board->isa == NO) |
1855 | 1625 | irqflags |= SA_SHIRQ; | |
1856 | if (request_irq(isi_card[count].irq, | 1626 | |
1857 | isicom_interrupt, | 1627 | retval = request_irq(board->irq, isicom_interrupt, irqflags, |
1858 | irqflags, | 1628 | ISICOM_NAME, board); |
1859 | ISICOM_NAME, &isi_card[count])) { | 1629 | if (retval < 0) |
1860 | 1630 | dev_warn(&pdev->dev, "Could not install handler at Irq %d. " | |
1861 | printk(KERN_WARNING "ISICOM: Could not" | 1631 | "Card%d will be disabled.\n", board->irq, index + 1); |
1862 | " install handler at Irq %d." | 1632 | else |
1863 | " Card%d will be disabled.\n", | 1633 | retval = 0; |
1864 | isi_card[count].irq, count+1); | 1634 | end: |
1865 | 1635 | return retval; | |
1866 | release_region(isi_card[count].base,16); | ||
1867 | isi_card[count].base=0; | ||
1868 | } | ||
1869 | else | ||
1870 | done++; | ||
1871 | } | ||
1872 | } | ||
1873 | return done; | ||
1874 | } | 1636 | } |
1875 | 1637 | ||
1876 | static void __exit unregister_isr(void) | 1638 | static int __devinit reset_card(struct pci_dev *pdev, |
1639 | const unsigned int card, unsigned int *signature) | ||
1877 | { | 1640 | { |
1878 | int count; | 1641 | struct isi_board *board = pci_get_drvdata(pdev); |
1642 | unsigned long base = board->base; | ||
1643 | unsigned int portcount = 0; | ||
1644 | int retval = 0; | ||
1645 | |||
1646 | dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1, | ||
1647 | base); | ||
1879 | 1648 | ||
1880 | for (count=0; count < BOARD_COUNT; count++ ) { | 1649 | inw(base + 0x8); |
1881 | if (isi_card[count].base) | 1650 | |
1882 | free_irq(isi_card[count].irq, &isi_card[count]); | 1651 | mdelay(10); |
1652 | |||
1653 | outw(0, base + 0x8); /* Reset */ | ||
1654 | |||
1655 | msleep(3000); | ||
1656 | |||
1657 | *signature = inw(base + 0x4) & 0xff; | ||
1658 | |||
1659 | if (board->isa == YES) { | ||
1660 | if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) { | ||
1661 | dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", | ||
1662 | inw(base + 0x2), inw(base + 0xe)); | ||
1663 | dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure " | ||
1664 | "(Possible bad I/O Port Address 0x%lx).\n", | ||
1665 | card + 1, base); | ||
1666 | retval = -EIO; | ||
1667 | goto end; | ||
1668 | } | ||
1669 | } else { | ||
1670 | portcount = inw(base + 0x2); | ||
1671 | if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) && | ||
1672 | (portcount != 4) && (portcount != 8))) { | ||
1673 | dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", | ||
1674 | inw(base + 0x2), inw(base + 0xe)); | ||
1675 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure " | ||
1676 | "(Possible bad I/O Port Address 0x%lx).\n", | ||
1677 | card + 1, base); | ||
1678 | retval = -EIO; | ||
1679 | goto end; | ||
1680 | } | ||
1883 | } | 1681 | } |
1682 | |||
1683 | switch (*signature) { | ||
1684 | case 0xa5: | ||
1685 | case 0xbb: | ||
1686 | case 0xdd: | ||
1687 | board->port_count = (board->isa == NO && portcount == 4) ? 4 : | ||
1688 | 8; | ||
1689 | board->shift_count = 12; | ||
1690 | break; | ||
1691 | case 0xcc: | ||
1692 | board->port_count = 16; | ||
1693 | board->shift_count = 11; | ||
1694 | break; | ||
1695 | default: | ||
1696 | dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible " | ||
1697 | "bad I/O Port Address 0x%lx).\n", card + 1, base); | ||
1698 | dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature); | ||
1699 | retval = -EIO; | ||
1700 | } | ||
1701 | dev_info(&pdev->dev, "-Done\n"); | ||
1702 | |||
1703 | end: | ||
1704 | return retval; | ||
1884 | } | 1705 | } |
1885 | 1706 | ||
1886 | static int __devinit isicom_init(void) | 1707 | static inline int WaitTillCardIsFree(u16 base) |
1887 | { | 1708 | { |
1888 | int card, channel, base; | 1709 | unsigned long count = 0; |
1889 | struct isi_port * port; | 1710 | |
1890 | unsigned long page; | 1711 | while (!(inw(base + 0xe) & 0x1) && count++ < 100) |
1891 | 1712 | msleep(5); | |
1892 | if (!tmp_buf) { | 1713 | |
1893 | page = get_zeroed_page(GFP_KERNEL); | 1714 | return !(inw(base + 0xe) & 0x1); |
1894 | if (!page) { | 1715 | } |
1895 | #ifdef ISICOM_DEBUG | 1716 | |
1896 | printk(KERN_DEBUG "ISICOM: Couldn't allocate page for tmp_buf.\n"); | 1717 | static int __devinit load_firmware(struct pci_dev *pdev, |
1897 | #else | 1718 | const unsigned int index, const unsigned int signature) |
1898 | printk(KERN_ERR "ISICOM: Not enough memory...\n"); | 1719 | { |
1899 | #endif | 1720 | struct isi_board *board = pci_get_drvdata(pdev); |
1900 | return 0; | 1721 | const struct firmware *fw; |
1901 | } | 1722 | unsigned long base = board->base; |
1902 | tmp_buf = (unsigned char *) page; | 1723 | unsigned int a; |
1903 | } | 1724 | u16 word_count, status; |
1904 | 1725 | int retval = -EIO; | |
1905 | if (!register_ioregion()) | 1726 | char *name; |
1906 | { | 1727 | u8 *data; |
1907 | printk(KERN_ERR "ISICOM: All required I/O space found busy.\n"); | 1728 | |
1908 | free_page((unsigned long)tmp_buf); | 1729 | struct stframe { |
1909 | return 0; | 1730 | u16 addr; |
1910 | } | 1731 | u16 count; |
1911 | if (register_drivers()) | 1732 | u8 data[0]; |
1912 | { | 1733 | } *frame; |
1913 | unregister_ioregion(); | 1734 | |
1914 | free_page((unsigned long)tmp_buf); | 1735 | switch (signature) { |
1915 | return 0; | 1736 | case 0xa5: |
1916 | } | 1737 | name = "isi608.bin"; |
1917 | if (!register_isr()) | 1738 | break; |
1918 | { | 1739 | case 0xbb: |
1919 | unregister_drivers(); | 1740 | name = "isi608em.bin"; |
1920 | /* ioports already uregistered in register_isr */ | 1741 | break; |
1921 | free_page((unsigned long)tmp_buf); | 1742 | case 0xcc: |
1922 | return 0; | 1743 | name = "isi616em.bin"; |
1744 | break; | ||
1745 | case 0xdd: | ||
1746 | name = "isi4608.bin"; | ||
1747 | break; | ||
1748 | case 0xee: | ||
1749 | name = "isi4616.bin"; | ||
1750 | break; | ||
1751 | default: | ||
1752 | dev_err(&pdev->dev, "Unknown signature.\n"); | ||
1753 | goto end; | ||
1754 | } | ||
1755 | |||
1756 | retval = request_firmware(&fw, name, &pdev->dev); | ||
1757 | if (retval) | ||
1758 | goto end; | ||
1759 | |||
1760 | for (frame = (struct stframe *)fw->data; | ||
1761 | frame < (struct stframe *)(fw->data + fw->size); | ||
1762 | frame++) { | ||
1763 | if (WaitTillCardIsFree(base)) | ||
1764 | goto errrelfw; | ||
1765 | |||
1766 | outw(0xf0, base); /* start upload sequence */ | ||
1767 | outw(0x00, base); | ||
1768 | outw(frame->addr, base); /* lsb of address */ | ||
1769 | |||
1770 | word_count = frame->count / 2 + frame->count % 2; | ||
1771 | outw(word_count, base); | ||
1772 | InterruptTheCard(base); | ||
1773 | |||
1774 | udelay(100); /* 0x2f */ | ||
1775 | |||
1776 | if (WaitTillCardIsFree(base)) | ||
1777 | goto errrelfw; | ||
1778 | |||
1779 | if ((status = inw(base + 0x4)) != 0) { | ||
1780 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" | ||
1781 | "Address:0x%x\nCount:0x%x\nStatus:0x%x\n", | ||
1782 | index + 1, frame->addr, frame->count, status); | ||
1783 | goto errrelfw; | ||
1784 | } | ||
1785 | outsw(base, frame->data, word_count); | ||
1786 | |||
1787 | InterruptTheCard(base); | ||
1788 | |||
1789 | udelay(50); /* 0x0f */ | ||
1790 | |||
1791 | if (WaitTillCardIsFree(base)) | ||
1792 | goto errrelfw; | ||
1793 | |||
1794 | if ((status = inw(base + 0x4)) != 0) { | ||
1795 | dev_err(&pdev->dev, "Card%d got out of sync.Card " | ||
1796 | "Status:0x%x\n", index + 1, status); | ||
1797 | goto errrelfw; | ||
1798 | } | ||
1799 | } | ||
1800 | |||
1801 | retval = -EIO; | ||
1802 | |||
1803 | if (WaitTillCardIsFree(base)) | ||
1804 | goto errrelfw; | ||
1805 | |||
1806 | outw(0xf2, base); | ||
1807 | outw(0x800, base); | ||
1808 | outw(0x0, base); | ||
1809 | outw(0x0, base); | ||
1810 | InterruptTheCard(base); | ||
1811 | outw(0x0, base + 0x4); /* for ISI4608 cards */ | ||
1812 | |||
1813 | /* XXX: should we test it by reading it back and comparing with original like | ||
1814 | * in load firmware package? */ | ||
1815 | for (frame = (struct stframe*)fw->data; | ||
1816 | frame < (struct stframe*)(fw->data + fw->size); | ||
1817 | frame++) { | ||
1818 | if (WaitTillCardIsFree(base)) | ||
1819 | goto errrelfw; | ||
1820 | |||
1821 | outw(0xf1, base); /* start download sequence */ | ||
1822 | outw(0x00, base); | ||
1823 | outw(frame->addr, base); /* lsb of address */ | ||
1824 | |||
1825 | word_count = (frame->count >> 1) + frame->count % 2; | ||
1826 | outw(word_count + 1, base); | ||
1827 | InterruptTheCard(base); | ||
1828 | |||
1829 | udelay(50); /* 0xf */ | ||
1830 | |||
1831 | if (WaitTillCardIsFree(base)) | ||
1832 | goto errrelfw; | ||
1833 | |||
1834 | if ((status = inw(base + 0x4)) != 0) { | ||
1835 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" | ||
1836 | "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n", | ||
1837 | index + 1, frame->addr, frame->count, status); | ||
1838 | goto errrelfw; | ||
1839 | } | ||
1840 | |||
1841 | data = kmalloc(word_count * 2, GFP_KERNEL); | ||
1842 | inw(base); | ||
1843 | insw(base, data, word_count); | ||
1844 | InterruptTheCard(base); | ||
1845 | |||
1846 | for (a = 0; a < frame->count; a++) | ||
1847 | if (data[a] != frame->data[a]) { | ||
1848 | kfree(data); | ||
1849 | dev_err(&pdev->dev, "Card%d, firmware upload " | ||
1850 | "failed\n", index + 1); | ||
1851 | goto errrelfw; | ||
1852 | } | ||
1853 | kfree(data); | ||
1854 | |||
1855 | udelay(50); /* 0xf */ | ||
1856 | |||
1857 | if (WaitTillCardIsFree(base)) | ||
1858 | goto errrelfw; | ||
1859 | |||
1860 | if ((status = inw(base + 0x4)) != 0) { | ||
1861 | dev_err(&pdev->dev, "Card%d verify got out of sync. " | ||
1862 | "Card Status:0x%x\n", index + 1, status); | ||
1863 | goto errrelfw; | ||
1864 | } | ||
1923 | } | 1865 | } |
1924 | 1866 | ||
1925 | memset(isi_ports, 0, sizeof(isi_ports)); | 1867 | board->status |= FIRMWARE_LOADED; |
1926 | for (card = 0; card < BOARD_COUNT; card++) { | 1868 | retval = 0; |
1927 | port = &isi_ports[card * 16]; | 1869 | |
1928 | isi_card[card].ports = port; | 1870 | errrelfw: |
1929 | spin_lock_init(&isi_card[card].card_lock); | 1871 | release_firmware(fw); |
1930 | base = isi_card[card].base; | 1872 | end: |
1931 | for (channel = 0; channel < 16; channel++, port++) { | 1873 | return retval; |
1932 | port->magic = ISICOM_MAGIC; | ||
1933 | port->card = &isi_card[card]; | ||
1934 | port->channel = channel; | ||
1935 | port->close_delay = 50 * HZ/100; | ||
1936 | port->closing_wait = 3000 * HZ/100; | ||
1937 | INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); | ||
1938 | INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); | ||
1939 | port->status = 0; | ||
1940 | init_waitqueue_head(&port->open_wait); | ||
1941 | init_waitqueue_head(&port->close_wait); | ||
1942 | /* . . . */ | ||
1943 | } | ||
1944 | } | ||
1945 | |||
1946 | return 1; | ||
1947 | } | 1874 | } |
1948 | 1875 | ||
1949 | /* | 1876 | /* |
1950 | * Insmod can set static symbols so keep these static | 1877 | * Insmod can set static symbols so keep these static |
1951 | */ | 1878 | */ |
1952 | |||
1953 | static int io[4]; | 1879 | static int io[4]; |
1954 | static int irq[4]; | 1880 | static int irq[4]; |
1881 | static int card; | ||
1955 | 1882 | ||
1956 | MODULE_AUTHOR("MultiTech"); | 1883 | static int __devinit isicom_probe(struct pci_dev *pdev, |
1957 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); | 1884 | const struct pci_device_id *ent) |
1958 | MODULE_LICENSE("GPL"); | 1885 | { |
1959 | module_param_array(io, int, NULL, 0); | 1886 | unsigned int ioaddr, signature, index; |
1960 | MODULE_PARM_DESC(io, "I/O ports for the cards"); | 1887 | int retval = -EPERM; |
1961 | module_param_array(irq, int, NULL, 0); | 1888 | u8 pciirq; |
1962 | MODULE_PARM_DESC(irq, "Interrupts for the cards"); | 1889 | struct isi_board *board = NULL; |
1890 | |||
1891 | if (card >= BOARD_COUNT) | ||
1892 | goto err; | ||
1893 | |||
1894 | ioaddr = pci_resource_start(pdev, 3); | ||
1895 | /* i.e at offset 0x1c in the PCI configuration register space. */ | ||
1896 | pciirq = pdev->irq; | ||
1897 | dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device); | ||
1898 | |||
1899 | /* allot the first empty slot in the array */ | ||
1900 | for (index = 0; index < BOARD_COUNT; index++) | ||
1901 | if (isi_card[index].base == 0) { | ||
1902 | board = &isi_card[index]; | ||
1903 | break; | ||
1904 | } | ||
1905 | |||
1906 | board->base = ioaddr; | ||
1907 | board->irq = pciirq; | ||
1908 | board->isa = NO; | ||
1909 | card++; | ||
1910 | |||
1911 | pci_set_drvdata(pdev, board); | ||
1912 | |||
1913 | retval = isicom_register_ioregion(pdev, index); | ||
1914 | if (retval < 0) | ||
1915 | goto err; | ||
1916 | |||
1917 | retval = isicom_register_isr(pdev, index); | ||
1918 | if (retval < 0) | ||
1919 | goto errunrr; | ||
1920 | |||
1921 | retval = reset_card(pdev, index, &signature); | ||
1922 | if (retval < 0) | ||
1923 | goto errunri; | ||
1924 | |||
1925 | retval = load_firmware(pdev, index, signature); | ||
1926 | if (retval < 0) | ||
1927 | goto errunri; | ||
1928 | |||
1929 | return 0; | ||
1930 | |||
1931 | errunri: | ||
1932 | free_irq(board->irq, board); | ||
1933 | errunrr: | ||
1934 | isicom_unregister_ioregion(pdev); | ||
1935 | err: | ||
1936 | board->base = 0; | ||
1937 | return retval; | ||
1938 | } | ||
1939 | |||
1940 | static void __devexit isicom_remove(struct pci_dev *pdev) | ||
1941 | { | ||
1942 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1943 | |||
1944 | free_irq(board->irq, board); | ||
1945 | isicom_unregister_ioregion(pdev); | ||
1946 | } | ||
1963 | 1947 | ||
1964 | static int __devinit isicom_setup(void) | 1948 | static int __devinit isicom_setup(void) |
1965 | { | 1949 | { |
1966 | struct pci_dev *dev = NULL; | 1950 | int retval, idx, channel; |
1967 | int retval, card, idx, count; | 1951 | struct isi_port *port; |
1968 | unsigned char pciirq; | 1952 | |
1969 | unsigned int ioaddr; | ||
1970 | |||
1971 | card = 0; | 1953 | card = 0; |
1972 | for(idx=0; idx < BOARD_COUNT; idx++) { | 1954 | memset(isi_ports, 0, sizeof(isi_ports)); |
1973 | if (io[idx]) { | ||
1974 | isi_card[idx].base=io[idx]; | ||
1975 | isi_card[idx].irq=irq[idx]; | ||
1976 | isi_card[idx].isa=YES; | ||
1977 | card++; | ||
1978 | } | ||
1979 | else { | ||
1980 | isi_card[idx].base = 0; | ||
1981 | isi_card[idx].irq = 0; | ||
1982 | } | ||
1983 | } | ||
1984 | |||
1985 | for (idx=0 ;idx < card; idx++) { | ||
1986 | if (!((isi_card[idx].irq==2)||(isi_card[idx].irq==3)|| | ||
1987 | (isi_card[idx].irq==4)||(isi_card[idx].irq==5)|| | ||
1988 | (isi_card[idx].irq==7)||(isi_card[idx].irq==10)|| | ||
1989 | (isi_card[idx].irq==11)||(isi_card[idx].irq==12)|| | ||
1990 | (isi_card[idx].irq==15))) { | ||
1991 | |||
1992 | if (isi_card[idx].base) { | ||
1993 | printk(KERN_ERR "ISICOM: Irq %d unsupported. Disabling Card%d...\n", | ||
1994 | isi_card[idx].irq, idx+1); | ||
1995 | isi_card[idx].base=0; | ||
1996 | card--; | ||
1997 | } | ||
1998 | } | ||
1999 | } | ||
2000 | |||
2001 | if (card < BOARD_COUNT) { | ||
2002 | for (idx=0; idx < DEVID_COUNT; idx++) { | ||
2003 | dev = NULL; | ||
2004 | for (;;){ | ||
2005 | if (!(dev = pci_find_device(VENDOR_ID, isicom_pci_tbl[idx].device, dev))) | ||
2006 | break; | ||
2007 | if (card >= BOARD_COUNT) | ||
2008 | break; | ||
2009 | |||
2010 | if (pci_enable_device(dev)) | ||
2011 | break; | ||
2012 | 1955 | ||
2013 | /* found a PCI ISI card! */ | 1956 | for(idx = 0; idx < BOARD_COUNT; idx++) { |
2014 | ioaddr = pci_resource_start (dev, 3); /* i.e at offset 0x1c in the | 1957 | port = &isi_ports[idx * 16]; |
2015 | * PCI configuration register | 1958 | isi_card[idx].ports = port; |
2016 | * space. | 1959 | spin_lock_init(&isi_card[idx].card_lock); |
2017 | */ | 1960 | for (channel = 0; channel < 16; channel++, port++) { |
2018 | pciirq = dev->irq; | 1961 | port->magic = ISICOM_MAGIC; |
2019 | printk(KERN_INFO "ISI PCI Card(Device ID 0x%x)\n", isicom_pci_tbl[idx].device); | 1962 | port->card = &isi_card[idx]; |
2020 | /* | 1963 | port->channel = channel; |
2021 | * allot the first empty slot in the array | 1964 | port->close_delay = 50 * HZ/100; |
2022 | */ | 1965 | port->closing_wait = 3000 * HZ/100; |
2023 | for (count=0; count < BOARD_COUNT; count++) { | 1966 | INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); |
2024 | if (isi_card[count].base == 0) { | 1967 | INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); |
2025 | isi_card[count].base = ioaddr; | 1968 | port->status = 0; |
2026 | isi_card[count].irq = pciirq; | 1969 | init_waitqueue_head(&port->open_wait); |
2027 | isi_card[count].isa = NO; | 1970 | init_waitqueue_head(&port->close_wait); |
2028 | card++; | 1971 | /* . . . */ |
2029 | break; | 1972 | } |
2030 | } | 1973 | isi_card[idx].base = 0; |
2031 | } | 1974 | isi_card[idx].irq = 0; |
2032 | } | 1975 | |
2033 | if (card >= BOARD_COUNT) break; | 1976 | if (!io[idx]) |
2034 | } | 1977 | continue; |
1978 | |||
1979 | if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4 || | ||
1980 | irq[idx] == 5 || irq[idx] == 7 || | ||
1981 | irq[idx] == 10 || irq[idx] == 11 || | ||
1982 | irq[idx] == 12 || irq[idx] == 15) { | ||
1983 | printk(KERN_ERR "ISICOM: ISA not supported yet.\n"); | ||
1984 | retval = -EINVAL; | ||
1985 | goto error; | ||
1986 | } else | ||
1987 | printk(KERN_ERR "ISICOM: Irq %d unsupported. " | ||
1988 | "Disabling Card%d...\n", irq[idx], idx + 1); | ||
2035 | } | 1989 | } |
2036 | |||
2037 | if (!(isi_card[0].base || isi_card[1].base || isi_card[2].base || isi_card[3].base)) { | ||
2038 | printk(KERN_ERR "ISICOM: No valid card configuration. Driver cannot be initialized...\n"); | ||
2039 | return -EIO; | ||
2040 | } | ||
2041 | 1990 | ||
2042 | retval = misc_register(&isiloader_device); | 1991 | retval = isicom_register_tty_driver(); |
1992 | if (retval < 0) | ||
1993 | goto error; | ||
1994 | |||
1995 | retval = pci_register_driver(&isicom_driver); | ||
2043 | if (retval < 0) { | 1996 | if (retval < 0) { |
2044 | printk(KERN_ERR "ISICOM: Unable to register firmware loader driver.\n"); | 1997 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); |
2045 | return retval; | 1998 | goto errtty; |
2046 | } | ||
2047 | |||
2048 | if (!isicom_init()) { | ||
2049 | if (misc_deregister(&isiloader_device)) | ||
2050 | printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n"); | ||
2051 | return -EIO; | ||
2052 | } | 1999 | } |
2053 | 2000 | ||
2054 | init_timer(&tx); | 2001 | init_timer(&tx); |
2055 | tx.expires = jiffies + 1; | 2002 | tx.expires = jiffies + 1; |
2056 | tx.data = 0; | 2003 | tx.data = 0; |
2057 | tx.function = isicom_tx; | 2004 | tx.function = isicom_tx; |
2058 | re_schedule = 1; | 2005 | re_schedule = 1; |
2059 | add_timer(&tx); | 2006 | add_timer(&tx); |
2060 | 2007 | ||
2061 | return 0; | 2008 | return 0; |
2009 | errtty: | ||
2010 | isicom_unregister_tty_driver(); | ||
2011 | error: | ||
2012 | return retval; | ||
2062 | } | 2013 | } |
2063 | 2014 | ||
2064 | static void __exit isicom_exit(void) | 2015 | static void __exit isicom_exit(void) |
2065 | { | 2016 | { |
2017 | unsigned int index = 0; | ||
2018 | |||
2066 | re_schedule = 0; | 2019 | re_schedule = 0; |
2067 | /* FIXME */ | 2020 | |
2068 | msleep(1000); | 2021 | while (re_schedule != 2 && index++ < 100) |
2069 | unregister_isr(); | 2022 | msleep(10); |
2070 | unregister_drivers(); | 2023 | |
2071 | unregister_ioregion(); | 2024 | pci_unregister_driver(&isicom_driver); |
2072 | if(tmp_buf) | 2025 | isicom_unregister_tty_driver(); |
2073 | free_page((unsigned long)tmp_buf); | ||
2074 | if (misc_deregister(&isiloader_device)) | ||
2075 | printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n"); | ||
2076 | } | 2026 | } |
2077 | 2027 | ||
2078 | module_init(isicom_setup); | 2028 | module_init(isicom_setup); |
2079 | module_exit(isicom_exit); | 2029 | module_exit(isicom_exit); |
2030 | |||
2031 | MODULE_AUTHOR("MultiTech"); | ||
2032 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); | ||
2033 | MODULE_LICENSE("GPL"); | ||
2034 | module_param_array(io, int, NULL, 0); | ||
2035 | MODULE_PARM_DESC(io, "I/O ports for the cards"); | ||
2036 | module_param_array(irq, int, NULL, 0); | ||
2037 | MODULE_PARM_DESC(irq, "Interrupts for the cards"); | ||
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index ce3bc0d45f1f..28c5a3193b81 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -135,7 +135,7 @@ static stlconf_t stli_brdconf[] = { | |||
135 | /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/ | 135 | /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/ |
136 | }; | 136 | }; |
137 | 137 | ||
138 | static int stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t); | 138 | static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * There is some experimental EISA board detection code in this driver. | 141 | * There is some experimental EISA board detection code in this driver. |
@@ -406,7 +406,7 @@ static unsigned long stli_eisamemprobeaddrs[] = { | |||
406 | 0xff000000, 0xff010000, 0xff020000, 0xff030000, | 406 | 0xff000000, 0xff010000, 0xff020000, 0xff030000, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); | 409 | static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); |
410 | 410 | ||
411 | /* | 411 | /* |
412 | * Define the Stallion PCI vendor and device IDs. | 412 | * Define the Stallion PCI vendor and device IDs. |
@@ -899,15 +899,13 @@ static void stli_argbrds(void) | |||
899 | { | 899 | { |
900 | stlconf_t conf; | 900 | stlconf_t conf; |
901 | stlibrd_t *brdp; | 901 | stlibrd_t *brdp; |
902 | int nrargs, i; | 902 | int i; |
903 | 903 | ||
904 | #ifdef DEBUG | 904 | #ifdef DEBUG |
905 | printk("stli_argbrds()\n"); | 905 | printk("stli_argbrds()\n"); |
906 | #endif | 906 | #endif |
907 | 907 | ||
908 | nrargs = sizeof(stli_brdsp) / sizeof(char **); | 908 | for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { |
909 | |||
910 | for (i = stli_nrbrds; (i < nrargs); i++) { | ||
911 | memset(&conf, 0, sizeof(conf)); | 909 | memset(&conf, 0, sizeof(conf)); |
912 | if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) | 910 | if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) |
913 | continue; | 911 | continue; |
@@ -967,7 +965,7 @@ static unsigned long stli_atol(char *str) | |||
967 | static int stli_parsebrd(stlconf_t *confp, char **argp) | 965 | static int stli_parsebrd(stlconf_t *confp, char **argp) |
968 | { | 966 | { |
969 | char *sp; | 967 | char *sp; |
970 | int nrbrdnames, i; | 968 | int i; |
971 | 969 | ||
972 | #ifdef DEBUG | 970 | #ifdef DEBUG |
973 | printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); | 971 | printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); |
@@ -979,14 +977,13 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
979 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) | 977 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) |
980 | *sp = TOLOWER(*sp); | 978 | *sp = TOLOWER(*sp); |
981 | 979 | ||
982 | nrbrdnames = sizeof(stli_brdstr) / sizeof(stlibrdtype_t); | 980 | for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { |
983 | for (i = 0; (i < nrbrdnames); i++) { | ||
984 | if (strcmp(stli_brdstr[i].name, argp[0]) == 0) | 981 | if (strcmp(stli_brdstr[i].name, argp[0]) == 0) |
985 | break; | 982 | break; |
986 | } | 983 | } |
987 | if (i >= nrbrdnames) { | 984 | if (i == ARRAY_SIZE(stli_brdstr)) { |
988 | printk("STALLION: unknown board name, %s?\n", argp[0]); | 985 | printk("STALLION: unknown board name, %s?\n", argp[0]); |
989 | return(0); | 986 | return 0; |
990 | } | 987 | } |
991 | 988 | ||
992 | confp->brdtype = stli_brdstr[i].type; | 989 | confp->brdtype = stli_brdstr[i].type; |
@@ -2714,17 +2711,13 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2714 | stlen = size - tail; | 2711 | stlen = size - tail; |
2715 | } | 2712 | } |
2716 | 2713 | ||
2717 | len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count)); | 2714 | len = tty_buffer_request_room(tty, len); |
2715 | /* FIXME : iomap ? */ | ||
2718 | shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); | 2716 | shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); |
2719 | 2717 | ||
2720 | while (len > 0) { | 2718 | while (len > 0) { |
2721 | stlen = MIN(len, stlen); | 2719 | stlen = MIN(len, stlen); |
2722 | memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen); | 2720 | tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); |
2723 | memset(tty->flip.flag_buf_ptr, 0, stlen); | ||
2724 | tty->flip.char_buf_ptr += stlen; | ||
2725 | tty->flip.flag_buf_ptr += stlen; | ||
2726 | tty->flip.count += stlen; | ||
2727 | |||
2728 | len -= stlen; | 2721 | len -= stlen; |
2729 | tail += stlen; | 2722 | tail += stlen; |
2730 | if (tail >= size) { | 2723 | if (tail >= size) { |
@@ -2909,16 +2902,12 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2909 | 2902 | ||
2910 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { | 2903 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { |
2911 | if (tty != (struct tty_struct *) NULL) { | 2904 | if (tty != (struct tty_struct *) NULL) { |
2912 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 2905 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
2913 | tty->flip.count++; | 2906 | if (portp->flags & ASYNC_SAK) { |
2914 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 2907 | do_SAK(tty); |
2915 | *tty->flip.char_buf_ptr++ = 0; | 2908 | EBRDENABLE(brdp); |
2916 | if (portp->flags & ASYNC_SAK) { | ||
2917 | do_SAK(tty); | ||
2918 | EBRDENABLE(brdp); | ||
2919 | } | ||
2920 | tty_schedule_flip(tty); | ||
2921 | } | 2909 | } |
2910 | tty_schedule_flip(tty); | ||
2922 | } | 2911 | } |
2923 | } | 2912 | } |
2924 | 2913 | ||
@@ -4943,7 +4932,7 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4943 | if (portp->tty != (struct tty_struct *) NULL) { | 4932 | if (portp->tty != (struct tty_struct *) NULL) { |
4944 | if (portp->tty->driver_data == portp) { | 4933 | if (portp->tty->driver_data == portp) { |
4945 | stli_comstats.ttystate = portp->tty->flags; | 4934 | stli_comstats.ttystate = portp->tty->flags; |
4946 | stli_comstats.rxbuffered = portp->tty->flip.count; | 4935 | stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; |
4947 | if (portp->tty->termios != (struct termios *) NULL) { | 4936 | if (portp->tty->termios != (struct termios *) NULL) { |
4948 | stli_comstats.cflags = portp->tty->termios->c_cflag; | 4937 | stli_comstats.cflags = portp->tty->termios->c_cflag; |
4949 | stli_comstats.iflags = portp->tty->termios->c_iflag; | 4938 | stli_comstats.iflags = portp->tty->termios->c_iflag; |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 79e490ef2cf2..5e3ef5522194 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -269,7 +269,7 @@ static int MoxaPortDCDChange(int); | |||
269 | static int MoxaPortDCDON(int); | 269 | static int MoxaPortDCDON(int); |
270 | static void MoxaPortFlushData(int, int); | 270 | static void MoxaPortFlushData(int, int); |
271 | static int MoxaPortWriteData(int, unsigned char *, int); | 271 | static int MoxaPortWriteData(int, unsigned char *, int); |
272 | static int MoxaPortReadData(int, unsigned char *, int); | 272 | static int MoxaPortReadData(int, struct tty_struct *tty); |
273 | static int MoxaPortTxQueue(int); | 273 | static int MoxaPortTxQueue(int); |
274 | static int MoxaPortRxQueue(int); | 274 | static int MoxaPortRxQueue(int); |
275 | static int MoxaPortTxFree(int); | 275 | static int MoxaPortTxFree(int); |
@@ -301,6 +301,8 @@ static struct tty_operations moxa_ops = { | |||
301 | .tiocmset = moxa_tiocmset, | 301 | .tiocmset = moxa_tiocmset, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; | ||
305 | |||
304 | #ifdef CONFIG_PCI | 306 | #ifdef CONFIG_PCI |
305 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) | 307 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) |
306 | { | 308 | { |
@@ -448,7 +450,7 @@ static int __init moxa_init(void) | |||
448 | #ifdef CONFIG_PCI | 450 | #ifdef CONFIG_PCI |
449 | { | 451 | { |
450 | struct pci_dev *p = NULL; | 452 | struct pci_dev *p = NULL; |
451 | int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; | 453 | int n = ARRAY_SIZE(moxa_pcibrds) - 1; |
452 | i = 0; | 454 | i = 0; |
453 | while (i < n) { | 455 | while (i < n) { |
454 | while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) | 456 | while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) |
@@ -645,10 +647,10 @@ static int moxa_write(struct tty_struct *tty, | |||
645 | if (ch == NULL) | 647 | if (ch == NULL) |
646 | return (0); | 648 | return (0); |
647 | port = ch->port; | 649 | port = ch->port; |
648 | save_flags(flags); | 650 | |
649 | cli(); | 651 | spin_lock_irqsave(&moxa_lock, flags); |
650 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); | 652 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); |
651 | restore_flags(flags); | 653 | spin_unlock_irqrestore(&moxa_lock, flags); |
652 | 654 | ||
653 | /********************************************* | 655 | /********************************************* |
654 | if ( !(ch->statusflags & LOWWAIT) && | 656 | if ( !(ch->statusflags & LOWWAIT) && |
@@ -723,11 +725,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c) | |||
723 | if (ch == NULL) | 725 | if (ch == NULL) |
724 | return; | 726 | return; |
725 | port = ch->port; | 727 | port = ch->port; |
726 | save_flags(flags); | 728 | spin_lock_irqsave(&moxa_lock, flags); |
727 | cli(); | ||
728 | moxaXmitBuff[0] = c; | 729 | moxaXmitBuff[0] = c; |
729 | MoxaPortWriteData(port, moxaXmitBuff, 1); | 730 | MoxaPortWriteData(port, moxaXmitBuff, 1); |
730 | restore_flags(flags); | 731 | spin_unlock_irqrestore(&moxa_lock, flags); |
731 | /************************************************ | 732 | /************************************************ |
732 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) | 733 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) |
733 | *************************************************/ | 734 | *************************************************/ |
@@ -1030,12 +1031,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1030 | printk("block_til_ready before block: ttys%d, count = %d\n", | 1031 | printk("block_til_ready before block: ttys%d, count = %d\n", |
1031 | ch->line, ch->count); | 1032 | ch->line, ch->count); |
1032 | #endif | 1033 | #endif |
1033 | save_flags(flags); | 1034 | spin_lock_irqsave(&moxa_lock, flags); |
1034 | cli(); | ||
1035 | if (!tty_hung_up_p(filp)) | 1035 | if (!tty_hung_up_p(filp)) |
1036 | ch->count--; | 1036 | ch->count--; |
1037 | restore_flags(flags); | ||
1038 | ch->blocked_open++; | 1037 | ch->blocked_open++; |
1038 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1039 | |||
1039 | while (1) { | 1040 | while (1) { |
1040 | set_current_state(TASK_INTERRUPTIBLE); | 1041 | set_current_state(TASK_INTERRUPTIBLE); |
1041 | if (tty_hung_up_p(filp) || | 1042 | if (tty_hung_up_p(filp) || |
@@ -1062,17 +1063,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1062 | } | 1063 | } |
1063 | set_current_state(TASK_RUNNING); | 1064 | set_current_state(TASK_RUNNING); |
1064 | remove_wait_queue(&ch->open_wait, &wait); | 1065 | remove_wait_queue(&ch->open_wait, &wait); |
1066 | |||
1067 | spin_lock_irqsave(&moxa_lock, flags); | ||
1065 | if (!tty_hung_up_p(filp)) | 1068 | if (!tty_hung_up_p(filp)) |
1066 | ch->count++; | 1069 | ch->count++; |
1067 | ch->blocked_open--; | 1070 | ch->blocked_open--; |
1071 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1068 | #ifdef SERIAL_DEBUG_OPEN | 1072 | #ifdef SERIAL_DEBUG_OPEN |
1069 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 1073 | printk("block_til_ready after blocking: ttys%d, count = %d\n", |
1070 | ch->line, ch->count); | 1074 | ch->line, ch->count); |
1071 | #endif | 1075 | #endif |
1072 | if (retval) | 1076 | if (retval) |
1073 | return (retval); | 1077 | return (retval); |
1078 | /* FIXME: review to see if we need to use set_bit on these */ | ||
1074 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | 1079 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; |
1075 | return (0); | 1080 | return 0; |
1076 | } | 1081 | } |
1077 | 1082 | ||
1078 | static void setup_empty_event(struct tty_struct *tty) | 1083 | static void setup_empty_event(struct tty_struct *tty) |
@@ -1080,15 +1085,14 @@ static void setup_empty_event(struct tty_struct *tty) | |||
1080 | struct moxa_str *ch = tty->driver_data; | 1085 | struct moxa_str *ch = tty->driver_data; |
1081 | unsigned long flags; | 1086 | unsigned long flags; |
1082 | 1087 | ||
1083 | save_flags(flags); | 1088 | spin_lock_irqsave(&moxa_lock, flags); |
1084 | cli(); | ||
1085 | ch->statusflags |= EMPTYWAIT; | 1089 | ch->statusflags |= EMPTYWAIT; |
1086 | moxaEmptyTimer_on[ch->port] = 0; | 1090 | moxaEmptyTimer_on[ch->port] = 0; |
1087 | del_timer(&moxaEmptyTimer[ch->port]); | 1091 | del_timer(&moxaEmptyTimer[ch->port]); |
1088 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; | 1092 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; |
1089 | moxaEmptyTimer_on[ch->port] = 1; | 1093 | moxaEmptyTimer_on[ch->port] = 1; |
1090 | add_timer(&moxaEmptyTimer[ch->port]); | 1094 | add_timer(&moxaEmptyTimer[ch->port]); |
1091 | restore_flags(flags); | 1095 | spin_unlock_irqrestore(&moxa_lock, flags); |
1092 | } | 1096 | } |
1093 | 1097 | ||
1094 | static void check_xmit_empty(unsigned long data) | 1098 | static void check_xmit_empty(unsigned long data) |
@@ -1135,8 +1139,6 @@ static void receive_data(struct moxa_str *ch) | |||
1135 | { | 1139 | { |
1136 | struct tty_struct *tp; | 1140 | struct tty_struct *tp; |
1137 | struct termios *ts; | 1141 | struct termios *ts; |
1138 | int i, count, rc, space; | ||
1139 | unsigned char *charptr, *flagptr; | ||
1140 | unsigned long flags; | 1142 | unsigned long flags; |
1141 | 1143 | ||
1142 | ts = NULL; | 1144 | ts = NULL; |
@@ -1150,24 +1152,10 @@ static void receive_data(struct moxa_str *ch) | |||
1150 | MoxaPortFlushData(ch->port, 0); | 1152 | MoxaPortFlushData(ch->port, 0); |
1151 | return; | 1153 | return; |
1152 | } | 1154 | } |
1153 | space = TTY_FLIPBUF_SIZE - tp->flip.count; | 1155 | spin_lock_irqsave(&moxa_lock, flags); |
1154 | if (space <= 0) | 1156 | MoxaPortReadData(ch->port, tp); |
1155 | return; | 1157 | spin_unlock_irqrestore(&moxa_lock, flags); |
1156 | charptr = tp->flip.char_buf_ptr; | 1158 | tty_schedule_flip(tp); |
1157 | flagptr = tp->flip.flag_buf_ptr; | ||
1158 | rc = tp->flip.count; | ||
1159 | save_flags(flags); | ||
1160 | cli(); | ||
1161 | count = MoxaPortReadData(ch->port, charptr, space); | ||
1162 | restore_flags(flags); | ||
1163 | for (i = 0; i < count; i++) | ||
1164 | *flagptr++ = 0; | ||
1165 | charptr += count; | ||
1166 | rc += count; | ||
1167 | tp->flip.count = rc; | ||
1168 | tp->flip.char_buf_ptr = charptr; | ||
1169 | tp->flip.flag_buf_ptr = flagptr; | ||
1170 | tty_schedule_flip(ch->tty); | ||
1171 | } | 1159 | } |
1172 | 1160 | ||
1173 | #define Magic_code 0x404 | 1161 | #define Magic_code 0x404 |
@@ -1774,7 +1762,7 @@ int MoxaPortsOfCard(int cardno) | |||
1774 | * 14. MoxaPortDCDON(int port); * | 1762 | * 14. MoxaPortDCDON(int port); * |
1775 | * 15. MoxaPortFlushData(int port, int mode); * | 1763 | * 15. MoxaPortFlushData(int port, int mode); * |
1776 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * | 1764 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * |
1777 | * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * | 1765 | * 17. MoxaPortReadData(int port, struct tty_struct *tty); * |
1778 | * 18. MoxaPortTxBufSize(int port); * | 1766 | * 18. MoxaPortTxBufSize(int port); * |
1779 | * 19. MoxaPortRxBufSize(int port); * | 1767 | * 19. MoxaPortRxBufSize(int port); * |
1780 | * 20. MoxaPortTxQueue(int port); * | 1768 | * 20. MoxaPortTxQueue(int port); * |
@@ -2003,10 +1991,9 @@ int MoxaPortsOfCard(int cardno) | |||
2003 | * | 1991 | * |
2004 | * Function 21: Read data. | 1992 | * Function 21: Read data. |
2005 | * Syntax: | 1993 | * Syntax: |
2006 | * int MoxaPortReadData(int port, unsigned char * buffer, int length); | 1994 | * int MoxaPortReadData(int port, struct tty_struct *tty); |
2007 | * int port : port number (0 - 127) | 1995 | * int port : port number (0 - 127) |
2008 | * unsigned char * buffer : pointer to read data buffer. | 1996 | * struct tty_struct *tty : tty for data |
2009 | * int length : read data buffer length | ||
2010 | * | 1997 | * |
2011 | * return: 0 - length : real read data length | 1998 | * return: 0 - length : real read data length |
2012 | * | 1999 | * |
@@ -2504,7 +2491,7 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len) | |||
2504 | return (total); | 2491 | return (total); |
2505 | } | 2492 | } |
2506 | 2493 | ||
2507 | int MoxaPortReadData(int port, unsigned char * buffer, int space) | 2494 | int MoxaPortReadData(int port, struct tty_struct *tty) |
2508 | { | 2495 | { |
2509 | register ushort head, pageofs; | 2496 | register ushort head, pageofs; |
2510 | int i, count, cnt, len, total, remain; | 2497 | int i, count, cnt, len, total, remain; |
@@ -2522,9 +2509,9 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2522 | count = (tail >= head) ? (tail - head) | 2509 | count = (tail >= head) ? (tail - head) |
2523 | : (tail - head + rx_mask + 1); | 2510 | : (tail - head + rx_mask + 1); |
2524 | if (count == 0) | 2511 | if (count == 0) |
2525 | return (0); | 2512 | return 0; |
2526 | 2513 | ||
2527 | total = (space > count) ? count : space; | 2514 | total = count; |
2528 | remain = count - total; | 2515 | remain = count - total; |
2529 | moxaLog.rxcnt[port] += total; | 2516 | moxaLog.rxcnt[port] += total; |
2530 | count = total; | 2517 | count = total; |
@@ -2539,7 +2526,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2539 | len = (count > len) ? len : count; | 2526 | len = (count > len) ? len : count; |
2540 | ofs = baseAddr + DynPage_addr + bufhead + head; | 2527 | ofs = baseAddr + DynPage_addr + bufhead + head; |
2541 | for (i = 0; i < len; i++) | 2528 | for (i = 0; i < len; i++) |
2542 | *buffer++ = readb(ofs + i); | 2529 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2543 | head = (head + len) & rx_mask; | 2530 | head = (head + len) & rx_mask; |
2544 | count -= len; | 2531 | count -= len; |
2545 | } | 2532 | } |
@@ -2556,7 +2543,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2556 | writew(pageno, baseAddr + Control_reg); | 2543 | writew(pageno, baseAddr + Control_reg); |
2557 | ofs = baseAddr + DynPage_addr + pageofs; | 2544 | ofs = baseAddr + DynPage_addr + pageofs; |
2558 | for (i = 0; i < cnt; i++) | 2545 | for (i = 0; i < cnt; i++) |
2559 | *buffer++ = readb(ofs + i); | 2546 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2560 | if (count == 0) { | 2547 | if (count == 0) { |
2561 | writew((head + len) & rx_mask, ofsAddr + RXrptr); | 2548 | writew((head + len) & rx_mask, ofsAddr + RXrptr); |
2562 | break; | 2549 | break; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 26448f176803..ea725a9964e2 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -813,7 +813,7 @@ static int mxser_init(void) | |||
813 | 813 | ||
814 | /* start finding PCI board here */ | 814 | /* start finding PCI board here */ |
815 | #ifdef CONFIG_PCI | 815 | #ifdef CONFIG_PCI |
816 | n = (sizeof(mxser_pcibrds) / sizeof(mxser_pcibrds[0])) - 1; | 816 | n = ARRAY_SIZE(mxser_pcibrds) - 1; |
817 | index = 0; | 817 | index = 0; |
818 | b = 0; | 818 | b = 0; |
819 | while (b < n) { | 819 | while (b < n) { |
@@ -1982,7 +1982,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
1982 | 1982 | ||
1983 | spin_lock_irqsave(&info->slock, flags); | 1983 | spin_lock_irqsave(&info->slock, flags); |
1984 | 1984 | ||
1985 | recv_room = tty->ldisc.receive_room(tty); | 1985 | recv_room = tty->receive_room; |
1986 | if ((recv_room == 0) && (!info->ldisc_stop_rx)) { | 1986 | if ((recv_room == 0) && (!info->ldisc_stop_rx)) { |
1987 | //mxser_throttle(tty); | 1987 | //mxser_throttle(tty); |
1988 | mxser_stoprx(tty); | 1988 | mxser_stoprx(tty); |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index a133a62f3d55..9f54733f1623 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -191,7 +191,6 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, | |||
191 | poll_table *wait); | 191 | poll_table *wait); |
192 | static int n_hdlc_tty_open(struct tty_struct *tty); | 192 | static int n_hdlc_tty_open(struct tty_struct *tty); |
193 | static void n_hdlc_tty_close(struct tty_struct *tty); | 193 | static void n_hdlc_tty_close(struct tty_struct *tty); |
194 | static int n_hdlc_tty_room(struct tty_struct *tty); | ||
195 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, | 194 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, |
196 | char *fp, int count); | 195 | char *fp, int count); |
197 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); | 196 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); |
@@ -212,7 +211,6 @@ static struct tty_ldisc n_hdlc_ldisc = { | |||
212 | .ioctl = n_hdlc_tty_ioctl, | 211 | .ioctl = n_hdlc_tty_ioctl, |
213 | .poll = n_hdlc_tty_poll, | 212 | .poll = n_hdlc_tty_poll, |
214 | .receive_buf = n_hdlc_tty_receive, | 213 | .receive_buf = n_hdlc_tty_receive, |
215 | .receive_room = n_hdlc_tty_room, | ||
216 | .write_wakeup = n_hdlc_tty_wakeup, | 214 | .write_wakeup = n_hdlc_tty_wakeup, |
217 | }; | 215 | }; |
218 | 216 | ||
@@ -337,6 +335,7 @@ static int n_hdlc_tty_open (struct tty_struct *tty) | |||
337 | 335 | ||
338 | tty->disc_data = n_hdlc; | 336 | tty->disc_data = n_hdlc; |
339 | n_hdlc->tty = tty; | 337 | n_hdlc->tty = tty; |
338 | tty->receive_room = 65536; | ||
340 | 339 | ||
341 | #if defined(TTY_NO_WRITE_SPLIT) | 340 | #if defined(TTY_NO_WRITE_SPLIT) |
342 | /* change tty_io write() to not split large writes into 8K chunks */ | 341 | /* change tty_io write() to not split large writes into 8K chunks */ |
@@ -478,22 +477,6 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) | |||
478 | } /* end of n_hdlc_tty_wakeup() */ | 477 | } /* end of n_hdlc_tty_wakeup() */ |
479 | 478 | ||
480 | /** | 479 | /** |
481 | * n_hdlc_tty_room - Return the amount of space left in the receiver's buffer | ||
482 | * @tty - pointer to associated tty instance data | ||
483 | * | ||
484 | * Callback function from tty driver. Return the amount of space left in the | ||
485 | * receiver's buffer to decide if remote transmitter is to be throttled. | ||
486 | */ | ||
487 | static int n_hdlc_tty_room(struct tty_struct *tty) | ||
488 | { | ||
489 | if (debuglevel >= DEBUG_LEVEL_INFO) | ||
490 | printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__); | ||
491 | /* always return a larger number to prevent */ | ||
492 | /* throttling of remote transmitter. */ | ||
493 | return 65536; | ||
494 | } /* end of n_hdlc_tty_root() */ | ||
495 | |||
496 | /** | ||
497 | * n_hdlc_tty_receive - Called by tty driver when receive data is available | 480 | * n_hdlc_tty_receive - Called by tty driver when receive data is available |
498 | * @tty - pointer to tty instance data | 481 | * @tty - pointer to tty instance data |
499 | * @data - pointer to received data | 482 | * @data - pointer to received data |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 853c98cee64f..c48de09d68f0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -147,7 +147,6 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, | |||
147 | struct poll_table_struct *wait); | 147 | struct poll_table_struct *wait); |
148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
149 | char *fp, int count); | 149 | char *fp, int count); |
150 | static int r3964_receive_room(struct tty_struct *tty); | ||
151 | 150 | ||
152 | static struct tty_ldisc tty_ldisc_N_R3964 = { | 151 | static struct tty_ldisc tty_ldisc_N_R3964 = { |
153 | .owner = THIS_MODULE, | 152 | .owner = THIS_MODULE, |
@@ -161,7 +160,6 @@ static struct tty_ldisc tty_ldisc_N_R3964 = { | |||
161 | .set_termios = r3964_set_termios, | 160 | .set_termios = r3964_set_termios, |
162 | .poll = r3964_poll, | 161 | .poll = r3964_poll, |
163 | .receive_buf = r3964_receive_buf, | 162 | .receive_buf = r3964_receive_buf, |
164 | .receive_room = r3964_receive_room, | ||
165 | }; | 163 | }; |
166 | 164 | ||
167 | 165 | ||
@@ -1119,6 +1117,7 @@ static int r3964_open(struct tty_struct *tty) | |||
1119 | pInfo->nRetry = 0; | 1117 | pInfo->nRetry = 0; |
1120 | 1118 | ||
1121 | tty->disc_data = pInfo; | 1119 | tty->disc_data = pInfo; |
1120 | tty->receive_room = 65536; | ||
1122 | 1121 | ||
1123 | init_timer(&pInfo->tmr); | 1122 | init_timer(&pInfo->tmr); |
1124 | pInfo->tmr.data = (unsigned long)pInfo; | 1123 | pInfo->tmr.data = (unsigned long)pInfo; |
@@ -1405,12 +1404,5 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1405 | } | 1404 | } |
1406 | } | 1405 | } |
1407 | 1406 | ||
1408 | static int r3964_receive_room(struct tty_struct *tty) | ||
1409 | { | ||
1410 | TRACE_L("receive_room"); | ||
1411 | return -1; | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | MODULE_LICENSE("GPL"); | 1407 | MODULE_LICENSE("GPL"); |
1416 | MODULE_ALIAS_LDISC(N_R3964); | 1408 | MODULE_ALIAS_LDISC(N_R3964); |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index c556f4d3ccd7..ccad7ae94541 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -78,7 +78,32 @@ static inline void free_buf(unsigned char *buf) | |||
78 | free_page((unsigned long) buf); | 78 | free_page((unsigned long) buf); |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 81 | /** |
82 | * n_tty_set__room - receive space | ||
83 | * @tty: terminal | ||
84 | * | ||
85 | * Called by the driver to find out how much data it is | ||
86 | * permitted to feed to the line discipline without any being lost | ||
87 | * and thus to manage flow control. Not serialized. Answers for the | ||
88 | * "instant". | ||
89 | */ | ||
90 | |||
91 | static void n_tty_set_room(struct tty_struct *tty) | ||
92 | { | ||
93 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
94 | |||
95 | /* | ||
96 | * If we are doing input canonicalization, and there are no | ||
97 | * pending newlines, let characters through without limit, so | ||
98 | * that erase characters will be handled. Other excess | ||
99 | * characters will be beeped. | ||
100 | */ | ||
101 | if (left <= 0) | ||
102 | left = tty->icanon && !tty->canon_data; | ||
103 | tty->receive_room = left; | ||
104 | } | ||
105 | |||
106 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | ||
82 | { | 107 | { |
83 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 108 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
84 | tty->read_buf[tty->read_head] = c; | 109 | tty->read_buf[tty->read_head] = c; |
@@ -87,7 +112,7 @@ static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | |||
87 | } | 112 | } |
88 | } | 113 | } |
89 | 114 | ||
90 | static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) | 115 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) |
91 | { | 116 | { |
92 | unsigned long flags; | 117 | unsigned long flags; |
93 | /* | 118 | /* |
@@ -136,6 +161,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
136 | spin_unlock_irqrestore(&tty->read_lock, flags); | 161 | spin_unlock_irqrestore(&tty->read_lock, flags); |
137 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 162 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
138 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 163 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
164 | n_tty_set_room(tty); | ||
139 | check_unthrottle(tty); | 165 | check_unthrottle(tty); |
140 | } | 166 | } |
141 | 167 | ||
@@ -838,30 +864,6 @@ send_signal: | |||
838 | put_tty_queue(c, tty); | 864 | put_tty_queue(c, tty); |
839 | } | 865 | } |
840 | 866 | ||
841 | /** | ||
842 | * n_tty_receive_room - receive space | ||
843 | * @tty: terminal | ||
844 | * | ||
845 | * Called by the driver to find out how much data it is | ||
846 | * permitted to feed to the line discipline without any being lost | ||
847 | * and thus to manage flow control. Not serialized. Answers for the | ||
848 | * "instant". | ||
849 | */ | ||
850 | |||
851 | static int n_tty_receive_room(struct tty_struct *tty) | ||
852 | { | ||
853 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
854 | |||
855 | /* | ||
856 | * If we are doing input canonicalization, and there are no | ||
857 | * pending newlines, let characters through without limit, so | ||
858 | * that erase characters will be handled. Other excess | ||
859 | * characters will be beeped. | ||
860 | */ | ||
861 | if (left <= 0) | ||
862 | left = tty->icanon && !tty->canon_data; | ||
863 | return left; | ||
864 | } | ||
865 | 867 | ||
866 | /** | 868 | /** |
867 | * n_tty_write_wakeup - asynchronous I/O notifier | 869 | * n_tty_write_wakeup - asynchronous I/O notifier |
@@ -953,6 +955,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
953 | tty->driver->flush_chars(tty); | 955 | tty->driver->flush_chars(tty); |
954 | } | 956 | } |
955 | 957 | ||
958 | n_tty_set_room(tty); | ||
959 | |||
956 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { | 960 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { |
957 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 961 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
958 | if (waitqueue_active(&tty->read_wait)) | 962 | if (waitqueue_active(&tty->read_wait)) |
@@ -964,7 +968,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
964 | * mode. We don't want to throttle the driver if we're in | 968 | * mode. We don't want to throttle the driver if we're in |
965 | * canonical mode and don't have a newline yet! | 969 | * canonical mode and don't have a newline yet! |
966 | */ | 970 | */ |
967 | if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) { | 971 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { |
968 | /* check TTY_THROTTLED first so it indicates our state */ | 972 | /* check TTY_THROTTLED first so it indicates our state */ |
969 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 973 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
970 | tty->driver->throttle) | 974 | tty->driver->throttle) |
@@ -999,6 +1003,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
999 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1003 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1000 | tty->raw = 1; | 1004 | tty->raw = 1; |
1001 | tty->real_raw = 1; | 1005 | tty->real_raw = 1; |
1006 | n_tty_set_room(tty); | ||
1002 | return; | 1007 | return; |
1003 | } | 1008 | } |
1004 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1009 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1051,6 +1056,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
1051 | else | 1056 | else |
1052 | tty->real_raw = 0; | 1057 | tty->real_raw = 0; |
1053 | } | 1058 | } |
1059 | n_tty_set_room(tty); | ||
1054 | } | 1060 | } |
1055 | 1061 | ||
1056 | /** | 1062 | /** |
@@ -1130,7 +1136,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1130 | * | 1136 | * |
1131 | */ | 1137 | */ |
1132 | 1138 | ||
1133 | static inline int copy_from_read_buf(struct tty_struct *tty, | 1139 | static int copy_from_read_buf(struct tty_struct *tty, |
1134 | unsigned char __user **b, | 1140 | unsigned char __user **b, |
1135 | size_t *nr) | 1141 | size_t *nr) |
1136 | 1142 | ||
@@ -1308,6 +1314,7 @@ do_it_again: | |||
1308 | retval = -ERESTARTSYS; | 1314 | retval = -ERESTARTSYS; |
1309 | break; | 1315 | break; |
1310 | } | 1316 | } |
1317 | n_tty_set_room(tty); | ||
1311 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 1318 | clear_bit(TTY_DONT_FLIP, &tty->flags); |
1312 | timeout = schedule_timeout(timeout); | 1319 | timeout = schedule_timeout(timeout); |
1313 | set_bit(TTY_DONT_FLIP, &tty->flags); | 1320 | set_bit(TTY_DONT_FLIP, &tty->flags); |
@@ -1401,6 +1408,8 @@ do_it_again: | |||
1401 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1408 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1402 | goto do_it_again; | 1409 | goto do_it_again; |
1403 | 1410 | ||
1411 | n_tty_set_room(tty); | ||
1412 | |||
1404 | return retval; | 1413 | return retval; |
1405 | } | 1414 | } |
1406 | 1415 | ||
@@ -1553,7 +1562,6 @@ struct tty_ldisc tty_ldisc_N_TTY = { | |||
1553 | normal_poll, /* poll */ | 1562 | normal_poll, /* poll */ |
1554 | NULL, /* hangup */ | 1563 | NULL, /* hangup */ |
1555 | n_tty_receive_buf, /* receive_buf */ | 1564 | n_tty_receive_buf, /* receive_buf */ |
1556 | n_tty_receive_room, /* receive_room */ | ||
1557 | n_tty_write_wakeup /* write_wakeup */ | 1565 | n_tty_write_wakeup /* write_wakeup */ |
1558 | }; | 1566 | }; |
1559 | 1567 | ||
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 1af733d07321..3556ccd77570 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
@@ -557,13 +557,13 @@ pc_proc_infos(unsigned char *nvram, char *buffer, int *len, | |||
557 | (nvram[6] & 1) ? (nvram[6] >> 6) + 1 : 0); | 557 | (nvram[6] & 1) ? (nvram[6] >> 6) + 1 : 0); |
558 | PRINT_PROC("Floppy 0 type : "); | 558 | PRINT_PROC("Floppy 0 type : "); |
559 | type = nvram[2] >> 4; | 559 | type = nvram[2] >> 4; |
560 | if (type < sizeof (floppy_types) / sizeof (*floppy_types)) | 560 | if (type < ARRAY_SIZE(floppy_types)) |
561 | PRINT_PROC("%s\n", floppy_types[type]); | 561 | PRINT_PROC("%s\n", floppy_types[type]); |
562 | else | 562 | else |
563 | PRINT_PROC("%d (unknown)\n", type); | 563 | PRINT_PROC("%d (unknown)\n", type); |
564 | PRINT_PROC("Floppy 1 type : "); | 564 | PRINT_PROC("Floppy 1 type : "); |
565 | type = nvram[2] & 0x0f; | 565 | type = nvram[2] & 0x0f; |
566 | if (type < sizeof (floppy_types) / sizeof (*floppy_types)) | 566 | if (type < ARRAY_SIZE(floppy_types)) |
567 | PRINT_PROC("%s\n", floppy_types[type]); | 567 | PRINT_PROC("%s\n", floppy_types[type]); |
568 | else | 568 | else |
569 | PRINT_PROC("%d (unknown)\n", type); | 569 | PRINT_PROC("%d (unknown)\n", type); |
@@ -843,8 +843,6 @@ static char *colors[] = { | |||
843 | "2", "4", "16", "256", "65536", "??", "??", "??" | 843 | "2", "4", "16", "256", "65536", "??", "??", "??" |
844 | }; | 844 | }; |
845 | 845 | ||
846 | #define fieldsize(a) (sizeof(a)/sizeof(*a)) | ||
847 | |||
848 | static int | 846 | static int |
849 | atari_proc_infos(unsigned char *nvram, char *buffer, int *len, | 847 | atari_proc_infos(unsigned char *nvram, char *buffer, int *len, |
850 | off_t *begin, off_t offset, int size) | 848 | off_t *begin, off_t offset, int size) |
@@ -856,7 +854,7 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len, | |||
856 | PRINT_PROC("Checksum status : %svalid\n", checksum ? "" : "not "); | 854 | PRINT_PROC("Checksum status : %svalid\n", checksum ? "" : "not "); |
857 | 855 | ||
858 | PRINT_PROC("Boot preference : "); | 856 | PRINT_PROC("Boot preference : "); |
859 | for (i = fieldsize(boot_prefs) - 1; i >= 0; --i) { | 857 | for (i = ARRAY_SIZE(boot_prefs) - 1; i >= 0; --i) { |
860 | if (nvram[1] == boot_prefs[i].val) { | 858 | if (nvram[1] == boot_prefs[i].val) { |
861 | PRINT_PROC("%s\n", boot_prefs[i].name); | 859 | PRINT_PROC("%s\n", boot_prefs[i].name); |
862 | break; | 860 | break; |
@@ -878,12 +876,12 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len, | |||
878 | return 1; | 876 | return 1; |
879 | 877 | ||
880 | PRINT_PROC("OS language : "); | 878 | PRINT_PROC("OS language : "); |
881 | if (nvram[6] < fieldsize(languages)) | 879 | if (nvram[6] < ARRAY_SIZE(languages)) |
882 | PRINT_PROC("%s\n", languages[nvram[6]]); | 880 | PRINT_PROC("%s\n", languages[nvram[6]]); |
883 | else | 881 | else |
884 | PRINT_PROC("%u (undefined)\n", nvram[6]); | 882 | PRINT_PROC("%u (undefined)\n", nvram[6]); |
885 | PRINT_PROC("Keyboard language: "); | 883 | PRINT_PROC("Keyboard language: "); |
886 | if (nvram[7] < fieldsize(languages)) | 884 | if (nvram[7] < ARRAY_SIZE(languages)) |
887 | PRINT_PROC("%s\n", languages[nvram[7]]); | 885 | PRINT_PROC("%s\n", languages[nvram[7]]); |
888 | else | 886 | else |
889 | PRINT_PROC("%u (undefined)\n", nvram[7]); | 887 | PRINT_PROC("%u (undefined)\n", nvram[7]); |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index cf45b100eff1..8a8ca32822ba 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1007,8 +1007,9 @@ static void rx_ready_hdlc(MGSLPC_INFO *info, int eom) | |||
1007 | 1007 | ||
1008 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) | 1008 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) |
1009 | { | 1009 | { |
1010 | unsigned char data, status; | 1010 | unsigned char data, status, flag; |
1011 | int fifo_count; | 1011 | int fifo_count; |
1012 | int work = 0; | ||
1012 | struct tty_struct *tty = info->tty; | 1013 | struct tty_struct *tty = info->tty; |
1013 | struct mgsl_icount *icount = &info->icount; | 1014 | struct mgsl_icount *icount = &info->icount; |
1014 | 1015 | ||
@@ -1023,20 +1024,16 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd) | |||
1023 | fifo_count = 32; | 1024 | fifo_count = 32; |
1024 | } else | 1025 | } else |
1025 | fifo_count = 32; | 1026 | fifo_count = 32; |
1026 | 1027 | ||
1028 | tty_buffer_request_room(tty, fifo_count); | ||
1027 | /* Flush received async data to receive data buffer. */ | 1029 | /* Flush received async data to receive data buffer. */ |
1028 | while (fifo_count) { | 1030 | while (fifo_count) { |
1029 | data = read_reg(info, CHA + RXFIFO); | 1031 | data = read_reg(info, CHA + RXFIFO); |
1030 | status = read_reg(info, CHA + RXFIFO); | 1032 | status = read_reg(info, CHA + RXFIFO); |
1031 | fifo_count -= 2; | 1033 | fifo_count -= 2; |
1032 | 1034 | ||
1033 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1034 | break; | ||
1035 | |||
1036 | *tty->flip.char_buf_ptr = data; | ||
1037 | icount->rx++; | 1035 | icount->rx++; |
1038 | 1036 | flag = TTY_NORMAL; | |
1039 | *tty->flip.flag_buf_ptr = 0; | ||
1040 | 1037 | ||
1041 | // if no frameing/crc error then save data | 1038 | // if no frameing/crc error then save data |
1042 | // BIT7:parity error | 1039 | // BIT7:parity error |
@@ -1055,26 +1052,23 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd) | |||
1055 | status &= info->read_status_mask; | 1052 | status &= info->read_status_mask; |
1056 | 1053 | ||
1057 | if (status & BIT7) | 1054 | if (status & BIT7) |
1058 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1055 | flag = TTY_PARITY; |
1059 | else if (status & BIT6) | 1056 | else if (status & BIT6) |
1060 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 1057 | flag = TTY_FRAME; |
1061 | } | 1058 | } |
1062 | 1059 | work += tty_insert_flip_char(tty, data, flag); | |
1063 | tty->flip.flag_buf_ptr++; | ||
1064 | tty->flip.char_buf_ptr++; | ||
1065 | tty->flip.count++; | ||
1066 | } | 1060 | } |
1067 | issue_command(info, CHA, CMD_RXFIFO); | 1061 | issue_command(info, CHA, CMD_RXFIFO); |
1068 | 1062 | ||
1069 | if (debug_level >= DEBUG_LEVEL_ISR) { | 1063 | if (debug_level >= DEBUG_LEVEL_ISR) { |
1070 | printk("%s(%d):rx_ready_async count=%d\n", | 1064 | printk("%s(%d):rx_ready_async", |
1071 | __FILE__,__LINE__,tty->flip.count); | 1065 | __FILE__,__LINE__); |
1072 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 1066 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
1073 | __FILE__,__LINE__,icount->rx,icount->brk, | 1067 | __FILE__,__LINE__,icount->rx,icount->brk, |
1074 | icount->parity,icount->frame,icount->overrun); | 1068 | icount->parity,icount->frame,icount->overrun); |
1075 | } | 1069 | } |
1076 | 1070 | ||
1077 | if (tty->flip.count) | 1071 | if (work) |
1078 | tty_flip_buffer_push(tty); | 1072 | tty_flip_buffer_push(tty); |
1079 | } | 1073 | } |
1080 | 1074 | ||
@@ -4005,7 +3999,7 @@ BOOLEAN register_test(MGSLPC_INFO *info) | |||
4005 | { | 3999 | { |
4006 | static unsigned char patterns[] = | 4000 | static unsigned char patterns[] = |
4007 | { 0x00, 0xff, 0xaa, 0x55, 0x69, 0x96, 0x0f }; | 4001 | { 0x00, 0xff, 0xaa, 0x55, 0x69, 0x96, 0x0f }; |
4008 | static unsigned int count = sizeof(patterns) / sizeof(patterns[0]); | 4002 | static unsigned int count = ARRAY_SIZE(patterns); |
4009 | unsigned int i; | 4003 | unsigned int i; |
4010 | BOOLEAN rc = TRUE; | 4004 | BOOLEAN rc = TRUE; |
4011 | unsigned long flags; | 4005 | unsigned long flags; |
@@ -4016,7 +4010,7 @@ BOOLEAN register_test(MGSLPC_INFO *info) | |||
4016 | for (i = 0; i < count; i++) { | 4010 | for (i = 0; i < count; i++) { |
4017 | write_reg(info, XAD1, patterns[i]); | 4011 | write_reg(info, XAD1, patterns[i]); |
4018 | write_reg(info, XAD2, patterns[(i + 1) % count]); | 4012 | write_reg(info, XAD2, patterns[(i + 1) % count]); |
4019 | if ((read_reg(info, XAD1) != patterns[i]) || | 4013 | if ((read_reg(info, XAD1) != patterns[i]) || |
4020 | (read_reg(info, XAD2) != patterns[(i + 1) % count])) { | 4014 | (read_reg(info, XAD2) != patterns[(i + 1) % count])) { |
4021 | rc = FALSE; | 4015 | rc = FALSE; |
4022 | break; | 4016 | break; |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 49f3997fd251..9b5a2c0e7008 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun | |||
111 | if (!to || tty->stopped) | 111 | if (!to || tty->stopped) |
112 | return 0; | 112 | return 0; |
113 | 113 | ||
114 | c = to->ldisc.receive_room(to); | 114 | c = to->receive_room; |
115 | if (c > count) | 115 | if (c > count) |
116 | c = count; | 116 | c = count; |
117 | to->ldisc.receive_buf(to, buf, NULL, c); | 117 | to->ldisc.receive_buf(to, buf, NULL, c); |
@@ -126,7 +126,7 @@ static int pty_write_room(struct tty_struct *tty) | |||
126 | if (!to || tty->stopped) | 126 | if (!to || tty->stopped) |
127 | return 0; | 127 | return 0; |
128 | 128 | ||
129 | return to->ldisc.receive_room(to); | 129 | return to->receive_room; |
130 | } | 130 | } |
131 | 131 | ||
132 | /* | 132 | /* |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index d7d484024e2b..7085a38532b3 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -56,10 +56,6 @@ | |||
56 | #include <linux/generic_serial.h> | 56 | #include <linux/generic_serial.h> |
57 | #include <asm/uaccess.h> | 57 | #include <asm/uaccess.h> |
58 | 58 | ||
59 | #if BITS_PER_LONG != 32 | ||
60 | # error FIXME: this driver only works on 32-bit platforms | ||
61 | #endif | ||
62 | |||
63 | #include "linux_compat.h" | 59 | #include "linux_compat.h" |
64 | #include "typdef.h" | 60 | #include "typdef.h" |
65 | #include "pkt.h" | 61 | #include "pkt.h" |
@@ -215,7 +211,7 @@ static int rio_poll = 1; | |||
215 | or less.... */ | 211 | or less.... */ |
216 | static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000}; | 212 | static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000}; |
217 | 213 | ||
218 | #define NR_RIO_ADDRS (sizeof(rio_probe_addrs)/sizeof (int)) | 214 | #define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) |
219 | 215 | ||
220 | 216 | ||
221 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | 217 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. |
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index e42e7b50bf6b..ddda9c14e059 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c | |||
@@ -38,6 +38,7 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2"; | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
40 | #include <linux/tty.h> | 40 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | ||
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
43 | #include <asm/string.h> | 44 | #include <asm/string.h> |
@@ -560,6 +561,7 @@ struct Port * PortP; | |||
560 | struct PKT *PacketP; | 561 | struct PKT *PacketP; |
561 | register uint DataCnt; | 562 | register uint DataCnt; |
562 | uchar * ptr; | 563 | uchar * ptr; |
564 | unsigned char *buf; | ||
563 | int copied =0; | 565 | int copied =0; |
564 | 566 | ||
565 | static int intCount, RxIntCnt; | 567 | static int intCount, RxIntCnt; |
@@ -657,8 +659,7 @@ struct Port * PortP; | |||
657 | ** and available space. | 659 | ** and available space. |
658 | */ | 660 | */ |
659 | 661 | ||
660 | transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK, | 662 | transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK); |
661 | TTY_FLIPBUF_SIZE - TtyP->flip.count); | ||
662 | rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", | 663 | rio_dprintk (RIO_DEBUG_REC, "port %d: Copy %d bytes\n", |
663 | PortP->PortNum, transCount); | 664 | PortP->PortNum, transCount); |
664 | /* | 665 | /* |
@@ -678,9 +679,8 @@ struct Port * PortP; | |||
678 | #endif | 679 | #endif |
679 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; | 680 | ptr = (uchar *) PacketP->data + PortP->RxDataStart; |
680 | 681 | ||
681 | rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount); | 682 | tty_prepare_flip_string(TtyP, &buf, transCount); |
682 | memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount); | 683 | rio_memcpy_fromio (buf, ptr, transCount); |
683 | |||
684 | #ifdef STATS | 684 | #ifdef STATS |
685 | /* | 685 | /* |
686 | ** keep a count for statistical purposes | 686 | ** keep a count for statistical purposes |
@@ -690,9 +690,6 @@ struct Port * PortP; | |||
690 | PortP->RxDataStart += transCount; | 690 | PortP->RxDataStart += transCount; |
691 | PacketP->len -= transCount; | 691 | PacketP->len -= transCount; |
692 | copied += transCount; | 692 | copied += transCount; |
693 | TtyP->flip.count += transCount; | ||
694 | TtyP->flip.char_buf_ptr += transCount; | ||
695 | TtyP->flip.flag_buf_ptr += transCount; | ||
696 | 693 | ||
697 | 694 | ||
698 | #ifdef ___DEBUG_IT___ | 695 | #ifdef ___DEBUG_IT___ |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 55a3a0188eda..050e70ee5920 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/major.h> | 46 | #include <linux/major.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | ||
49 | 50 | ||
50 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
51 | 52 | ||
@@ -107,15 +108,15 @@ static struct riscom_port rc_port[RC_NBOARD * RC_NPORT]; | |||
107 | 108 | ||
108 | /* RISCom/8 I/O ports addresses (without address translation) */ | 109 | /* RISCom/8 I/O ports addresses (without address translation) */ |
109 | static unsigned short rc_ioport[] = { | 110 | static unsigned short rc_ioport[] = { |
110 | #if 1 | 111 | #if 1 |
111 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, | 112 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, |
112 | #else | 113 | #else |
113 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10, | 114 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10, |
114 | 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62, | 115 | 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62, |
115 | 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101 | 116 | 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101 |
116 | #endif | 117 | #endif |
117 | }; | 118 | }; |
118 | #define RC_NIOPORT (sizeof(rc_ioport) / sizeof(rc_ioport[0])) | 119 | #define RC_NIOPORT ARRAY_SIZE(rc_ioport) |
119 | 120 | ||
120 | 121 | ||
121 | static inline int rc_paranoia_check(struct riscom_port const * port, | 122 | static inline int rc_paranoia_check(struct riscom_port const * port, |
@@ -354,28 +355,17 @@ static inline void rc_receive_exc(struct riscom_board const * bp) | |||
354 | struct riscom_port *port; | 355 | struct riscom_port *port; |
355 | struct tty_struct *tty; | 356 | struct tty_struct *tty; |
356 | unsigned char status; | 357 | unsigned char status; |
357 | unsigned char ch; | 358 | unsigned char ch, flag; |
358 | 359 | ||
359 | if (!(port = rc_get_port(bp, "Receive"))) | 360 | if (!(port = rc_get_port(bp, "Receive"))) |
360 | return; | 361 | return; |
361 | 362 | ||
362 | tty = port->tty; | 363 | tty = port->tty; |
363 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
364 | printk(KERN_WARNING "rc%d: port %d: Working around flip " | ||
365 | "buffer overflow.\n", | ||
366 | board_No(bp), port_No(port)); | ||
367 | return; | ||
368 | } | ||
369 | 364 | ||
370 | #ifdef RC_REPORT_OVERRUN | 365 | #ifdef RC_REPORT_OVERRUN |
371 | status = rc_in(bp, CD180_RCSR); | 366 | status = rc_in(bp, CD180_RCSR); |
372 | if (status & RCSR_OE) { | 367 | if (status & RCSR_OE) |
373 | port->overrun++; | 368 | port->overrun++; |
374 | #if 0 | ||
375 | printk(KERN_ERR "rc%d: port %d: Overrun. Total %ld overruns\n", | ||
376 | board_No(bp), port_No(port), port->overrun); | ||
377 | #endif | ||
378 | } | ||
379 | status &= port->mark_mask; | 369 | status &= port->mark_mask; |
380 | #else | 370 | #else |
381 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; | 371 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; |
@@ -393,25 +383,24 @@ static inline void rc_receive_exc(struct riscom_board const * bp) | |||
393 | } else if (status & RCSR_BREAK) { | 383 | } else if (status & RCSR_BREAK) { |
394 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", | 384 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", |
395 | board_No(bp), port_No(port)); | 385 | board_No(bp), port_No(port)); |
396 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 386 | flag = TTY_BREAK; |
397 | if (port->flags & ASYNC_SAK) | 387 | if (port->flags & ASYNC_SAK) |
398 | do_SAK(tty); | 388 | do_SAK(tty); |
399 | 389 | ||
400 | } else if (status & RCSR_PE) | 390 | } else if (status & RCSR_PE) |
401 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 391 | flag = TTY_PARITY; |
402 | 392 | ||
403 | else if (status & RCSR_FE) | 393 | else if (status & RCSR_FE) |
404 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 394 | flag = TTY_FRAME; |
405 | 395 | ||
406 | else if (status & RCSR_OE) | 396 | else if (status & RCSR_OE) |
407 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 397 | flag = TTY_OVERRUN; |
408 | 398 | ||
409 | else | 399 | else |
410 | *tty->flip.flag_buf_ptr++ = 0; | 400 | flag = TTY_NORMAL; |
411 | 401 | ||
412 | *tty->flip.char_buf_ptr++ = ch; | 402 | tty_insert_flip_char(tty, ch, flag); |
413 | tty->flip.count++; | 403 | tty_flip_buffer_push(tty); |
414 | schedule_delayed_work(&tty->flip.work, 1); | ||
415 | } | 404 | } |
416 | 405 | ||
417 | static inline void rc_receive(struct riscom_board const * bp) | 406 | static inline void rc_receive(struct riscom_board const * bp) |
@@ -432,17 +421,15 @@ static inline void rc_receive(struct riscom_board const * bp) | |||
432 | #endif | 421 | #endif |
433 | 422 | ||
434 | while (count--) { | 423 | while (count--) { |
435 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 424 | if (tty_buffer_request_room(tty, 1) == 0) { |
436 | printk(KERN_WARNING "rc%d: port %d: Working around " | 425 | printk(KERN_WARNING "rc%d: port %d: Working around " |
437 | "flip buffer overflow.\n", | 426 | "flip buffer overflow.\n", |
438 | board_No(bp), port_No(port)); | 427 | board_No(bp), port_No(port)); |
439 | break; | 428 | break; |
440 | } | 429 | } |
441 | *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR); | 430 | tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL); |
442 | *tty->flip.flag_buf_ptr++ = 0; | ||
443 | tty->flip.count++; | ||
444 | } | 431 | } |
445 | schedule_delayed_work(&tty->flip.work, 1); | 432 | tty_flip_buffer_push(tty); |
446 | } | 433 | } |
447 | 434 | ||
448 | static inline void rc_transmit(struct riscom_board const * bp) | 435 | static inline void rc_transmit(struct riscom_board const * bp) |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index d3bc731fbb27..0949dcef0697 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -325,19 +325,16 @@ static void rp_do_receive(struct r_port *info, | |||
325 | { | 325 | { |
326 | unsigned int CharNStat; | 326 | unsigned int CharNStat; |
327 | int ToRecv, wRecv, space = 0, count; | 327 | int ToRecv, wRecv, space = 0, count; |
328 | unsigned char *cbuf; | 328 | unsigned char *cbuf, *chead; |
329 | char *fbuf; | 329 | char *fbuf, *fhead; |
330 | struct tty_ldisc *ld; | 330 | struct tty_ldisc *ld; |
331 | 331 | ||
332 | ld = tty_ldisc_ref(tty); | 332 | ld = tty_ldisc_ref(tty); |
333 | 333 | ||
334 | ToRecv = sGetRxCnt(cp); | 334 | ToRecv = sGetRxCnt(cp); |
335 | if (ld) | 335 | space = tty->receive_room; |
336 | space = ld->receive_room(tty); | ||
337 | if (space > 2 * TTY_FLIPBUF_SIZE) | 336 | if (space > 2 * TTY_FLIPBUF_SIZE) |
338 | space = 2 * TTY_FLIPBUF_SIZE; | 337 | space = 2 * TTY_FLIPBUF_SIZE; |
339 | cbuf = tty->flip.char_buf; | ||
340 | fbuf = tty->flip.flag_buf; | ||
341 | count = 0; | 338 | count = 0; |
342 | #ifdef ROCKET_DEBUG_INTR | 339 | #ifdef ROCKET_DEBUG_INTR |
343 | printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); | 340 | printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); |
@@ -350,9 +347,13 @@ static void rp_do_receive(struct r_port *info, | |||
350 | if (ToRecv > space) | 347 | if (ToRecv > space) |
351 | ToRecv = space; | 348 | ToRecv = space; |
352 | 349 | ||
350 | ToRecv = tty_prepare_flip_string_flags(tty, &chead, &fhead, ToRecv); | ||
353 | if (ToRecv <= 0) | 351 | if (ToRecv <= 0) |
354 | goto done; | 352 | goto done; |
355 | 353 | ||
354 | cbuf = chead; | ||
355 | fbuf = fhead; | ||
356 | |||
356 | /* | 357 | /* |
357 | * if status indicates there are errored characters in the | 358 | * if status indicates there are errored characters in the |
358 | * FIFO, then enter status mode (a word in FIFO holds | 359 | * FIFO, then enter status mode (a word in FIFO holds |
@@ -399,7 +400,7 @@ static void rp_do_receive(struct r_port *info, | |||
399 | else if (CharNStat & STMRCVROVRH) | 400 | else if (CharNStat & STMRCVROVRH) |
400 | *fbuf++ = TTY_OVERRUN; | 401 | *fbuf++ = TTY_OVERRUN; |
401 | else | 402 | else |
402 | *fbuf++ = 0; | 403 | *fbuf++ = TTY_NORMAL; |
403 | *cbuf++ = CharNStat & 0xff; | 404 | *cbuf++ = CharNStat & 0xff; |
404 | count++; | 405 | count++; |
405 | ToRecv--; | 406 | ToRecv--; |
@@ -426,13 +427,13 @@ static void rp_do_receive(struct r_port *info, | |||
426 | sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); | 427 | sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); |
427 | if (ToRecv & 1) | 428 | if (ToRecv & 1) |
428 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); | 429 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); |
429 | memset(fbuf, 0, ToRecv); | 430 | memset(fbuf, TTY_NORMAL, ToRecv); |
430 | cbuf += ToRecv; | 431 | cbuf += ToRecv; |
431 | fbuf += ToRecv; | 432 | fbuf += ToRecv; |
432 | count += ToRecv; | 433 | count += ToRecv; |
433 | } | 434 | } |
434 | /* Push the data up to the tty layer */ | 435 | /* Push the data up to the tty layer */ |
435 | ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); | 436 | ld->receive_buf(tty, cbuf, fbuf, count); |
436 | done: | 437 | done: |
437 | tty_ldisc_deref(ld); | 438 | tty_ldisc_deref(ld); |
438 | } | 439 | } |
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 5b187c895c18..71093a9fc462 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -275,7 +275,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t | |||
275 | int paste_selection(struct tty_struct *tty) | 275 | int paste_selection(struct tty_struct *tty) |
276 | { | 276 | { |
277 | struct vc_data *vc = (struct vc_data *)tty->driver_data; | 277 | struct vc_data *vc = (struct vc_data *)tty->driver_data; |
278 | int pasted = 0, count; | 278 | int pasted = 0; |
279 | unsigned int count; | ||
279 | struct tty_ldisc *ld; | 280 | struct tty_ldisc *ld; |
280 | DECLARE_WAITQUEUE(wait, current); | 281 | DECLARE_WAITQUEUE(wait, current); |
281 | 282 | ||
@@ -293,7 +294,7 @@ int paste_selection(struct tty_struct *tty) | |||
293 | continue; | 294 | continue; |
294 | } | 295 | } |
295 | count = sel_buffer_lth - pasted; | 296 | count = sel_buffer_lth - pasted; |
296 | count = min(count, tty->ldisc.receive_room(tty)); | 297 | count = min(count, tty->receive_room); |
297 | tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); | 298 | tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); |
298 | pasted += count; | 299 | pasted += count; |
299 | } | 300 | } |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index dda30e42ec79..80a5b840e22f 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -194,11 +194,6 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) | |||
194 | */ | 194 | */ |
195 | struct tty_struct *tty = port->gs.tty; | 195 | struct tty_struct *tty = port->gs.tty; |
196 | 196 | ||
197 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
198 | return; | ||
199 | |||
200 | tty->flip.count++; | ||
201 | |||
202 | #if 0 | 197 | #if 0 |
203 | switch(err) { | 198 | switch(err) { |
204 | case TTY_BREAK: | 199 | case TTY_BREAK: |
@@ -212,8 +207,7 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) | |||
212 | } | 207 | } |
213 | #endif | 208 | #endif |
214 | 209 | ||
215 | *tty->flip.flag_buf_ptr++ = err; | 210 | tty_insert_flip_char(tty, ch, err); |
216 | *tty->flip.char_buf_ptr++ = ch; | ||
217 | tty_flip_buffer_push(tty); | 211 | tty_flip_buffer_push(tty); |
218 | } | 212 | } |
219 | 213 | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index c2deac968bdd..f36342ae8e7e 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -117,7 +117,7 @@ struct cyclades_port cy_port[] = { | |||
117 | {-1 }, /* ttyS2 */ | 117 | {-1 }, /* ttyS2 */ |
118 | {-1 }, /* ttyS3 */ | 118 | {-1 }, /* ttyS3 */ |
119 | }; | 119 | }; |
120 | #define NR_PORTS (sizeof(cy_port)/sizeof(struct cyclades_port)) | 120 | #define NR_PORTS ARRAY_SIZE(cy_port) |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * tmp_buf is used as a temporary buffer by serial_write. We need to | 123 | * tmp_buf is used as a temporary buffer by serial_write. We need to |
@@ -422,45 +422,35 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp) | |||
422 | base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; | 422 | base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; |
423 | return IRQ_HANDLED; | 423 | return IRQ_HANDLED; |
424 | } | 424 | } |
425 | if (tty->flip.count < TTY_FLIPBUF_SIZE){ | 425 | if (tty_buffer_request_room(tty, 1) != 0){ |
426 | tty->flip.count++; | ||
427 | if (err & info->read_status_mask){ | 426 | if (err & info->read_status_mask){ |
428 | if(err & CyBREAK){ | 427 | if(err & CyBREAK){ |
429 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 428 | tty_insert_flip_char(tty, data, TTY_BREAK); |
430 | *tty->flip.char_buf_ptr++ = data; | ||
431 | if (info->flags & ASYNC_SAK){ | 429 | if (info->flags & ASYNC_SAK){ |
432 | do_SAK(tty); | 430 | do_SAK(tty); |
433 | } | 431 | } |
434 | }else if(err & CyFRAME){ | 432 | }else if(err & CyFRAME){ |
435 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 433 | tty_insert_flip_char(tty, data, TTY_FRAME); |
436 | *tty->flip.char_buf_ptr++ = data; | ||
437 | }else if(err & CyPARITY){ | 434 | }else if(err & CyPARITY){ |
438 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 435 | tty_insert_flip_char(tty, data, TTY_PARITY); |
439 | *tty->flip.char_buf_ptr++ = data; | ||
440 | }else if(err & CyOVERRUN){ | 436 | }else if(err & CyOVERRUN){ |
441 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 437 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
442 | *tty->flip.char_buf_ptr++ = 0; | ||
443 | /* | 438 | /* |
444 | If the flip buffer itself is | 439 | If the flip buffer itself is |
445 | overflowing, we still loose | 440 | overflowing, we still loose |
446 | the next incoming character. | 441 | the next incoming character. |
447 | */ | 442 | */ |
448 | if(tty->flip.count < TTY_FLIPBUF_SIZE){ | 443 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
449 | tty->flip.count++; | 444 | } |
450 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
451 | *tty->flip.char_buf_ptr++ = data; | ||
452 | } | ||
453 | /* These two conditions may imply */ | 445 | /* These two conditions may imply */ |
454 | /* a normal read should be done. */ | 446 | /* a normal read should be done. */ |
455 | /* else if(data & CyTIMEOUT) */ | 447 | /* else if(data & CyTIMEOUT) */ |
456 | /* else if(data & CySPECHAR) */ | 448 | /* else if(data & CySPECHAR) */ |
457 | }else{ | 449 | }else{ |
458 | *tty->flip.flag_buf_ptr++ = 0; | 450 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
459 | *tty->flip.char_buf_ptr++ = 0; | ||
460 | } | 451 | } |
461 | }else{ | 452 | }else{ |
462 | *tty->flip.flag_buf_ptr++ = 0; | 453 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
463 | *tty->flip.char_buf_ptr++ = 0; | ||
464 | } | 454 | } |
465 | }else{ | 455 | }else{ |
466 | /* there was a software buffer overrun | 456 | /* there was a software buffer overrun |
@@ -692,12 +682,7 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp) | |||
692 | #endif | 682 | #endif |
693 | while(char_count--){ | 683 | while(char_count--){ |
694 | data = base_addr[CyRDR]; | 684 | data = base_addr[CyRDR]; |
695 | if (tty->flip.count >= TTY_FLIPBUF_SIZE){ | 685 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
696 | continue; | ||
697 | } | ||
698 | tty->flip.count++; | ||
699 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
700 | *tty->flip.char_buf_ptr++ = data; | ||
701 | #ifdef CYCLOM_16Y_HACK | 686 | #ifdef CYCLOM_16Y_HACK |
702 | udelay(10L); | 687 | udelay(10L); |
703 | #endif | 688 | #endif |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 0bbfce43031c..0a574bdbce36 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/interrupt.h> | 85 | #include <linux/interrupt.h> |
86 | #include <linux/errno.h> | 86 | #include <linux/errno.h> |
87 | #include <linux/tty.h> | 87 | #include <linux/tty.h> |
88 | #include <linux/tty_flip.h> | ||
88 | #include <linux/mm.h> | 89 | #include <linux/mm.h> |
89 | #include <linux/serial.h> | 90 | #include <linux/serial.h> |
90 | #include <linux/fcntl.h> | 91 | #include <linux/fcntl.h> |
@@ -665,7 +666,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
665 | struct specialix_port *port; | 666 | struct specialix_port *port; |
666 | struct tty_struct *tty; | 667 | struct tty_struct *tty; |
667 | unsigned char status; | 668 | unsigned char status; |
668 | unsigned char ch; | 669 | unsigned char ch, flag; |
669 | 670 | ||
670 | func_enter(); | 671 | func_enter(); |
671 | 672 | ||
@@ -676,8 +677,6 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
676 | return; | 677 | return; |
677 | } | 678 | } |
678 | tty = port->tty; | 679 | tty = port->tty; |
679 | dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n", | ||
680 | port, tty->flip.count, TTY_FLIPBUF_SIZE); | ||
681 | 680 | ||
682 | status = sx_in(bp, CD186x_RCSR); | 681 | status = sx_in(bp, CD186x_RCSR); |
683 | 682 | ||
@@ -691,7 +690,7 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
691 | 690 | ||
692 | /* This flip buffer check needs to be below the reading of the | 691 | /* This flip buffer check needs to be below the reading of the |
693 | status register to reset the chip's IRQ.... */ | 692 | status register to reset the chip's IRQ.... */ |
694 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 693 | if (tty_buffer_request_room(tty, 1) == 0) { |
695 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", | 694 | dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n", |
696 | board_No(bp), port_No(port)); | 695 | board_No(bp), port_No(port)); |
697 | func_exit(); | 696 | func_exit(); |
@@ -712,26 +711,24 @@ static inline void sx_receive_exc(struct specialix_board * bp) | |||
712 | } else if (status & RCSR_BREAK) { | 711 | } else if (status & RCSR_BREAK) { |
713 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", | 712 | dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", |
714 | board_No(bp), port_No(port)); | 713 | board_No(bp), port_No(port)); |
715 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 714 | flag = TTY_BREAK; |
716 | if (port->flags & ASYNC_SAK) | 715 | if (port->flags & ASYNC_SAK) |
717 | do_SAK(tty); | 716 | do_SAK(tty); |
718 | 717 | ||
719 | } else if (status & RCSR_PE) | 718 | } else if (status & RCSR_PE) |
720 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 719 | flag = TTY_PARITY; |
721 | 720 | ||
722 | else if (status & RCSR_FE) | 721 | else if (status & RCSR_FE) |
723 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 722 | flag = TTY_FRAME; |
724 | 723 | ||
725 | else if (status & RCSR_OE) | 724 | else if (status & RCSR_OE) |
726 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 725 | flag = TTY_OVERRUN; |
727 | 726 | ||
728 | else | 727 | else |
729 | *tty->flip.flag_buf_ptr++ = 0; | 728 | flag = TTY_NORMAL; |
730 | |||
731 | *tty->flip.char_buf_ptr++ = ch; | ||
732 | tty->flip.count++; | ||
733 | schedule_delayed_work(&tty->flip.work, 1); | ||
734 | 729 | ||
730 | if(tty_insert_flip_char(tty, ch, flag)) | ||
731 | tty_flip_buffer_push(tty); | ||
735 | func_exit(); | 732 | func_exit(); |
736 | } | 733 | } |
737 | 734 | ||
@@ -755,18 +752,11 @@ static inline void sx_receive(struct specialix_board * bp) | |||
755 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); | 752 | dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); |
756 | port->hits[count > 8 ? 9 : count]++; | 753 | port->hits[count > 8 ? 9 : count]++; |
757 | 754 | ||
758 | while (count--) { | 755 | tty_buffer_request_room(tty, count); |
759 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
760 | printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n", | ||
761 | board_No(bp), port_No(port)); | ||
762 | break; | ||
763 | } | ||
764 | *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR); | ||
765 | *tty->flip.flag_buf_ptr++ = 0; | ||
766 | tty->flip.count++; | ||
767 | } | ||
768 | schedule_delayed_work(&tty->flip.work, 1); | ||
769 | 756 | ||
757 | while (count--) | ||
758 | tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); | ||
759 | tty_flip_buffer_push(tty); | ||
770 | func_exit(); | 760 | func_exit(); |
771 | } | 761 | } |
772 | 762 | ||
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 95af2a941595..0e20780d4a29 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -103,7 +103,7 @@ static stlconf_t stl_brdconf[] = { | |||
103 | /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/ | 103 | /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/ |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static int stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t); | 106 | static int stl_nrbrds = ARRAY_SIZE(stl_brdconf); |
107 | 107 | ||
108 | /*****************************************************************************/ | 108 | /*****************************************************************************/ |
109 | 109 | ||
@@ -424,7 +424,7 @@ static stlpcibrd_t stl_pcibrds[] = { | |||
424 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI }, | 424 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI }, |
425 | }; | 425 | }; |
426 | 426 | ||
427 | static int stl_nrpcibrds = sizeof(stl_pcibrds) / sizeof(stlpcibrd_t); | 427 | static int stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds); |
428 | 428 | ||
429 | #endif | 429 | #endif |
430 | 430 | ||
@@ -704,7 +704,7 @@ static unsigned int sc26198_baudtable[] = { | |||
704 | 230400, 460800, 921600 | 704 | 230400, 460800, 921600 |
705 | }; | 705 | }; |
706 | 706 | ||
707 | #define SC26198_NRBAUDS (sizeof(sc26198_baudtable) / sizeof(unsigned int)) | 707 | #define SC26198_NRBAUDS ARRAY_SIZE(sc26198_baudtable) |
708 | 708 | ||
709 | /*****************************************************************************/ | 709 | /*****************************************************************************/ |
710 | 710 | ||
@@ -901,7 +901,7 @@ static unsigned long stl_atol(char *str) | |||
901 | static int stl_parsebrd(stlconf_t *confp, char **argp) | 901 | static int stl_parsebrd(stlconf_t *confp, char **argp) |
902 | { | 902 | { |
903 | char *sp; | 903 | char *sp; |
904 | int nrbrdnames, i; | 904 | int i; |
905 | 905 | ||
906 | #ifdef DEBUG | 906 | #ifdef DEBUG |
907 | printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); | 907 | printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); |
@@ -913,14 +913,13 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) | |||
913 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) | 913 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) |
914 | *sp = TOLOWER(*sp); | 914 | *sp = TOLOWER(*sp); |
915 | 915 | ||
916 | nrbrdnames = sizeof(stl_brdstr) / sizeof(stlbrdtype_t); | 916 | for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) { |
917 | for (i = 0; (i < nrbrdnames); i++) { | ||
918 | if (strcmp(stl_brdstr[i].name, argp[0]) == 0) | 917 | if (strcmp(stl_brdstr[i].name, argp[0]) == 0) |
919 | break; | 918 | break; |
920 | } | 919 | } |
921 | if (i >= nrbrdnames) { | 920 | if (i == ARRAY_SIZE(stl_brdstr)) { |
922 | printk("STALLION: unknown board name, %s?\n", argp[0]); | 921 | printk("STALLION: unknown board name, %s?\n", argp[0]); |
923 | return(0); | 922 | return 0; |
924 | } | 923 | } |
925 | 924 | ||
926 | confp->brdtype = stl_brdstr[i].type; | 925 | confp->brdtype = stl_brdstr[i].type; |
@@ -2902,7 +2901,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2902 | if (portp->tty != (struct tty_struct *) NULL) { | 2901 | if (portp->tty != (struct tty_struct *) NULL) { |
2903 | if (portp->tty->driver_data == portp) { | 2902 | if (portp->tty->driver_data == portp) { |
2904 | portp->stats.ttystate = portp->tty->flags; | 2903 | portp->stats.ttystate = portp->tty->flags; |
2905 | portp->stats.rxbuffered = portp->tty->flip.count; | 2904 | /* No longer available as a statistic */ |
2905 | portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */ | ||
2906 | if (portp->tty->termios != (struct termios *) NULL) { | 2906 | if (portp->tty->termios != (struct termios *) NULL) { |
2907 | portp->stats.cflags = portp->tty->termios->c_cflag; | 2907 | portp->stats.cflags = portp->tty->termios->c_cflag; |
2908 | portp->stats.iflags = portp->tty->termios->c_iflag; | 2908 | portp->stats.iflags = portp->tty->termios->c_iflag; |
@@ -4046,9 +4046,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4046 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { | 4046 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { |
4047 | outb((RDCR + portp->uartaddr), ioaddr); | 4047 | outb((RDCR + portp->uartaddr), ioaddr); |
4048 | len = inb(ioaddr + EREG_DATA); | 4048 | len = inb(ioaddr + EREG_DATA); |
4049 | if ((tty == (struct tty_struct *) NULL) || | 4049 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
4050 | (tty->flip.char_buf_ptr == (char *) NULL) || | ||
4051 | ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { | ||
4052 | len = MIN(len, sizeof(stl_unwanted)); | 4050 | len = MIN(len, sizeof(stl_unwanted)); |
4053 | outb((RDSR + portp->uartaddr), ioaddr); | 4051 | outb((RDSR + portp->uartaddr), ioaddr); |
4054 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); | 4052 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); |
@@ -4057,12 +4055,10 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4057 | } else { | 4055 | } else { |
4058 | len = MIN(len, buflen); | 4056 | len = MIN(len, buflen); |
4059 | if (len > 0) { | 4057 | if (len > 0) { |
4058 | unsigned char *ptr; | ||
4060 | outb((RDSR + portp->uartaddr), ioaddr); | 4059 | outb((RDSR + portp->uartaddr), ioaddr); |
4061 | insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len); | 4060 | tty_prepare_flip_string(tty, &ptr, len); |
4062 | memset(tty->flip.flag_buf_ptr, 0, len); | 4061 | insb((ioaddr + EREG_DATA), ptr, len); |
4063 | tty->flip.flag_buf_ptr += len; | ||
4064 | tty->flip.char_buf_ptr += len; | ||
4065 | tty->flip.count += len; | ||
4066 | tty_schedule_flip(tty); | 4062 | tty_schedule_flip(tty); |
4067 | portp->stats.rxtotal += len; | 4063 | portp->stats.rxtotal += len; |
4068 | } | 4064 | } |
@@ -4086,8 +4082,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4086 | portp->stats.txxoff++; | 4082 | portp->stats.txxoff++; |
4087 | goto stl_rxalldone; | 4083 | goto stl_rxalldone; |
4088 | } | 4084 | } |
4089 | if ((tty != (struct tty_struct *) NULL) && | 4085 | if (tty != NULL && (portp->rxignoremsk & status) == 0) { |
4090 | ((portp->rxignoremsk & status) == 0)) { | ||
4091 | if (portp->rxmarkmsk & status) { | 4086 | if (portp->rxmarkmsk & status) { |
4092 | if (status & ST_BREAK) { | 4087 | if (status & ST_BREAK) { |
4093 | status = TTY_BREAK; | 4088 | status = TTY_BREAK; |
@@ -4107,14 +4102,8 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4107 | } else { | 4102 | } else { |
4108 | status = 0; | 4103 | status = 0; |
4109 | } | 4104 | } |
4110 | if (tty->flip.char_buf_ptr != (char *) NULL) { | 4105 | tty_insert_flip_char(tty, ch, status); |
4111 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 4106 | tty_schedule_flip(tty); |
4112 | *tty->flip.flag_buf_ptr++ = status; | ||
4113 | *tty->flip.char_buf_ptr++ = ch; | ||
4114 | tty->flip.count++; | ||
4115 | } | ||
4116 | tty_schedule_flip(tty); | ||
4117 | } | ||
4118 | } | 4107 | } |
4119 | } else { | 4108 | } else { |
4120 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); | 4109 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); |
@@ -5013,9 +5002,7 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
5013 | len = inb(ioaddr + XP_DATA) + 1; | 5002 | len = inb(ioaddr + XP_DATA) + 1; |
5014 | 5003 | ||
5015 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { | 5004 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { |
5016 | if ((tty == (struct tty_struct *) NULL) || | 5005 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
5017 | (tty->flip.char_buf_ptr == (char *) NULL) || | ||
5018 | ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) { | ||
5019 | len = MIN(len, sizeof(stl_unwanted)); | 5006 | len = MIN(len, sizeof(stl_unwanted)); |
5020 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 5007 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
5021 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); | 5008 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); |
@@ -5024,12 +5011,10 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
5024 | } else { | 5011 | } else { |
5025 | len = MIN(len, buflen); | 5012 | len = MIN(len, buflen); |
5026 | if (len > 0) { | 5013 | if (len > 0) { |
5014 | unsigned char *ptr; | ||
5027 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 5015 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
5028 | insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len); | 5016 | tty_prepare_flip_string(tty, &ptr, len); |
5029 | memset(tty->flip.flag_buf_ptr, 0, len); | 5017 | insb((ioaddr + XP_DATA), ptr, len); |
5030 | tty->flip.flag_buf_ptr += len; | ||
5031 | tty->flip.char_buf_ptr += len; | ||
5032 | tty->flip.count += len; | ||
5033 | tty_schedule_flip(tty); | 5018 | tty_schedule_flip(tty); |
5034 | portp->stats.rxtotal += len; | 5019 | portp->stats.rxtotal += len; |
5035 | } | 5020 | } |
@@ -5097,14 +5082,8 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch | |||
5097 | status = 0; | 5082 | status = 0; |
5098 | } | 5083 | } |
5099 | 5084 | ||
5100 | if (tty->flip.char_buf_ptr != (char *) NULL) { | 5085 | tty_insert_flip_char(tty, ch, status); |
5101 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 5086 | tty_schedule_flip(tty); |
5102 | *tty->flip.flag_buf_ptr++ = status; | ||
5103 | *tty->flip.char_buf_ptr++ = ch; | ||
5104 | tty->flip.count++; | ||
5105 | } | ||
5106 | tty_schedule_flip(tty); | ||
5107 | } | ||
5108 | 5087 | ||
5109 | if (status == 0) | 5088 | if (status == 0) |
5110 | portp->stats.rxtotal++; | 5089 | portp->stats.rxtotal++; |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 3ad758a9a1dc..64bf89cb574f 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -345,9 +345,9 @@ static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, | |||
345 | 0xc8000, 0xd8000, 0xe8000, 0xa0000}; | 345 | 0xc8000, 0xd8000, 0xe8000, 0xa0000}; |
346 | static int si1_probe_addrs[]= { 0xd0000}; | 346 | static int si1_probe_addrs[]= { 0xd0000}; |
347 | 347 | ||
348 | #define NR_SX_ADDRS (sizeof(sx_probe_addrs)/sizeof (int)) | 348 | #define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) |
349 | #define NR_SI_ADDRS (sizeof(si_probe_addrs)/sizeof (int)) | 349 | #define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) |
350 | #define NR_SI1_ADDRS (sizeof(si1_probe_addrs)/sizeof (int)) | 350 | #define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) |
351 | 351 | ||
352 | 352 | ||
353 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | 353 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. |
@@ -1085,6 +1085,7 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1085 | int rx_op; | 1085 | int rx_op; |
1086 | struct tty_struct *tty; | 1086 | struct tty_struct *tty; |
1087 | int copied=0; | 1087 | int copied=0; |
1088 | unsigned char *rp; | ||
1088 | 1089 | ||
1089 | func_enter2 (); | 1090 | func_enter2 (); |
1090 | tty = port->gs.tty; | 1091 | tty = port->gs.tty; |
@@ -1095,8 +1096,8 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1095 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | 1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); |
1096 | 1097 | ||
1097 | /* Don't copy more bytes than there is room for in the buffer */ | 1098 | /* Don't copy more bytes than there is room for in the buffer */ |
1098 | if (tty->flip.count + c > TTY_FLIPBUF_SIZE) | 1099 | |
1099 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | 1100 | c = tty_prepare_flip_string(tty, &rp, c); |
1100 | 1101 | ||
1101 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1102 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1102 | 1103 | ||
@@ -1111,14 +1112,8 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1111 | sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, | 1112 | sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, |
1112 | read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), | 1113 | read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), |
1113 | CHAN_OFFSET(port, hi_rxbuf)); | 1114 | CHAN_OFFSET(port, hi_rxbuf)); |
1114 | memcpy_fromio (tty->flip.char_buf_ptr, | 1115 | memcpy_fromio (rp, |
1115 | port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); | 1116 | port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); |
1116 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, c); | ||
1117 | |||
1118 | /* Update the kernel buffer end */ | ||
1119 | tty->flip.count += c; | ||
1120 | tty->flip.char_buf_ptr += c; | ||
1121 | tty->flip.flag_buf_ptr += c; | ||
1122 | 1117 | ||
1123 | /* This one last. ( Not essential.) | 1118 | /* This one last. ( Not essential.) |
1124 | It allows the card to start putting more data into the buffer! | 1119 | It allows the card to start putting more data into the buffer! |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 62aa0e534a6d..9f1b466c4f84 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -1467,6 +1467,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1467 | { | 1467 | { |
1468 | int Fifocount; | 1468 | int Fifocount; |
1469 | u16 status; | 1469 | u16 status; |
1470 | int work = 0; | ||
1470 | unsigned char DataByte; | 1471 | unsigned char DataByte; |
1471 | struct tty_struct *tty = info->tty; | 1472 | struct tty_struct *tty = info->tty; |
1472 | struct mgsl_icount *icount = &info->icount; | 1473 | struct mgsl_icount *icount = &info->icount; |
@@ -1487,6 +1488,8 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1487 | /* flush the receive FIFO */ | 1488 | /* flush the receive FIFO */ |
1488 | 1489 | ||
1489 | while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { | 1490 | while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { |
1491 | int flag; | ||
1492 | |||
1490 | /* read one byte from RxFIFO */ | 1493 | /* read one byte from RxFIFO */ |
1491 | outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), | 1494 | outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), |
1492 | info->io_base + CCAR ); | 1495 | info->io_base + CCAR ); |
@@ -1498,13 +1501,9 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1498 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) | 1501 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) |
1499 | usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); | 1502 | usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); |
1500 | 1503 | ||
1501 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1502 | continue; | ||
1503 | |||
1504 | *tty->flip.char_buf_ptr = DataByte; | ||
1505 | icount->rx++; | 1504 | icount->rx++; |
1506 | 1505 | ||
1507 | *tty->flip.flag_buf_ptr = 0; | 1506 | flag = 0; |
1508 | if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + | 1507 | if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + |
1509 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { | 1508 | RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { |
1510 | printk("rxerr=%04X\n",status); | 1509 | printk("rxerr=%04X\n",status); |
@@ -1530,41 +1529,31 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1530 | status &= info->read_status_mask; | 1529 | status &= info->read_status_mask; |
1531 | 1530 | ||
1532 | if (status & RXSTATUS_BREAK_RECEIVED) { | 1531 | if (status & RXSTATUS_BREAK_RECEIVED) { |
1533 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 1532 | flag = TTY_BREAK; |
1534 | if (info->flags & ASYNC_SAK) | 1533 | if (info->flags & ASYNC_SAK) |
1535 | do_SAK(tty); | 1534 | do_SAK(tty); |
1536 | } else if (status & RXSTATUS_PARITY_ERROR) | 1535 | } else if (status & RXSTATUS_PARITY_ERROR) |
1537 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1536 | flag = TTY_PARITY; |
1538 | else if (status & RXSTATUS_FRAMING_ERROR) | 1537 | else if (status & RXSTATUS_FRAMING_ERROR) |
1539 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 1538 | flag = TTY_FRAME; |
1540 | if (status & RXSTATUS_OVERRUN) { | ||
1541 | /* Overrun is special, since it's | ||
1542 | * reported immediately, and doesn't | ||
1543 | * affect the current character | ||
1544 | */ | ||
1545 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
1546 | tty->flip.count++; | ||
1547 | tty->flip.flag_buf_ptr++; | ||
1548 | tty->flip.char_buf_ptr++; | ||
1549 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
1550 | } | ||
1551 | } | ||
1552 | } /* end of if (error) */ | 1539 | } /* end of if (error) */ |
1553 | 1540 | tty_insert_flip_char(tty, DataByte, flag); | |
1554 | tty->flip.flag_buf_ptr++; | 1541 | if (status & RXSTATUS_OVERRUN) { |
1555 | tty->flip.char_buf_ptr++; | 1542 | /* Overrun is special, since it's |
1556 | tty->flip.count++; | 1543 | * reported immediately, and doesn't |
1544 | * affect the current character | ||
1545 | */ | ||
1546 | work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1547 | } | ||
1557 | } | 1548 | } |
1558 | 1549 | ||
1559 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 1550 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
1560 | printk("%s(%d):mgsl_isr_receive_data flip count=%d\n", | ||
1561 | __FILE__,__LINE__,tty->flip.count); | ||
1562 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 1551 | printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
1563 | __FILE__,__LINE__,icount->rx,icount->brk, | 1552 | __FILE__,__LINE__,icount->rx,icount->brk, |
1564 | icount->parity,icount->frame,icount->overrun); | 1553 | icount->parity,icount->frame,icount->overrun); |
1565 | } | 1554 | } |
1566 | 1555 | ||
1567 | if ( tty->flip.count ) | 1556 | if(work) |
1568 | tty_flip_buffer_push(tty); | 1557 | tty_flip_buffer_push(tty); |
1569 | } | 1558 | } |
1570 | 1559 | ||
@@ -7058,7 +7047,7 @@ static BOOLEAN mgsl_register_test( struct mgsl_struct *info ) | |||
7058 | { | 7047 | { |
7059 | static unsigned short BitPatterns[] = | 7048 | static unsigned short BitPatterns[] = |
7060 | { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f }; | 7049 | { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f }; |
7061 | static unsigned int Patterncount = sizeof(BitPatterns)/sizeof(unsigned short); | 7050 | static unsigned int Patterncount = ARRAY_SIZE(BitPatterns); |
7062 | unsigned int i; | 7051 | unsigned int i; |
7063 | BOOLEAN rc = TRUE; | 7052 | BOOLEAN rc = TRUE; |
7064 | unsigned long flags; | 7053 | unsigned long flags; |
@@ -7501,9 +7490,9 @@ static int mgsl_adapter_test( struct mgsl_struct *info ) | |||
7501 | */ | 7490 | */ |
7502 | static BOOLEAN mgsl_memory_test( struct mgsl_struct *info ) | 7491 | static BOOLEAN mgsl_memory_test( struct mgsl_struct *info ) |
7503 | { | 7492 | { |
7504 | static unsigned long BitPatterns[] = { 0x0, 0x55555555, 0xaaaaaaaa, | 7493 | static unsigned long BitPatterns[] = |
7505 | 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; | 7494 | { 0x0, 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; |
7506 | unsigned long Patterncount = sizeof(BitPatterns)/sizeof(unsigned long); | 7495 | unsigned long Patterncount = ARRAY_SIZE(BitPatterns); |
7507 | unsigned long i; | 7496 | unsigned long i; |
7508 | unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); | 7497 | unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); |
7509 | unsigned long * TestAddr; | 7498 | unsigned long * TestAddr; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 2b9cde94e2f7..79c81def4104 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -75,7 +75,6 @@ | |||
75 | #include <linux/workqueue.h> | 75 | #include <linux/workqueue.h> |
76 | #include <linux/hdlc.h> | 76 | #include <linux/hdlc.h> |
77 | 77 | ||
78 | #include <asm/serial.h> | ||
79 | #include <asm/system.h> | 78 | #include <asm/system.h> |
80 | #include <asm/io.h> | 79 | #include <asm/io.h> |
81 | #include <asm/irq.h> | 80 | #include <asm/irq.h> |
@@ -1750,6 +1749,9 @@ static void rx_async(struct slgt_info *info) | |||
1750 | unsigned char status; | 1749 | unsigned char status; |
1751 | struct slgt_desc *bufs = info->rbufs; | 1750 | struct slgt_desc *bufs = info->rbufs; |
1752 | int i, count; | 1751 | int i, count; |
1752 | int chars = 0; | ||
1753 | int stat; | ||
1754 | unsigned char ch; | ||
1753 | 1755 | ||
1754 | start = end = info->rbuf_current; | 1756 | start = end = info->rbuf_current; |
1755 | 1757 | ||
@@ -1761,16 +1763,15 @@ static void rx_async(struct slgt_info *info) | |||
1761 | DBGDATA(info, p, count, "rx"); | 1763 | DBGDATA(info, p, count, "rx"); |
1762 | 1764 | ||
1763 | for(i=0 ; i < count; i+=2, p+=2) { | 1765 | for(i=0 ; i < count; i+=2, p+=2) { |
1764 | if (tty) { | 1766 | if (tty && chars) { |
1765 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 1767 | tty_flip_buffer_push(tty); |
1766 | tty_flip_buffer_push(tty); | 1768 | chars = 0; |
1767 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1768 | break; | ||
1769 | *tty->flip.char_buf_ptr = *p; | ||
1770 | *tty->flip.flag_buf_ptr = 0; | ||
1771 | } | 1769 | } |
1770 | ch = *p; | ||
1772 | icount->rx++; | 1771 | icount->rx++; |
1773 | 1772 | ||
1773 | stat = 0; | ||
1774 | |||
1774 | if ((status = *(p+1) & (BIT9 + BIT8))) { | 1775 | if ((status = *(p+1) & (BIT9 + BIT8))) { |
1775 | if (status & BIT9) | 1776 | if (status & BIT9) |
1776 | icount->parity++; | 1777 | icount->parity++; |
@@ -1779,17 +1780,14 @@ static void rx_async(struct slgt_info *info) | |||
1779 | /* discard char if tty control flags say so */ | 1780 | /* discard char if tty control flags say so */ |
1780 | if (status & info->ignore_status_mask) | 1781 | if (status & info->ignore_status_mask) |
1781 | continue; | 1782 | continue; |
1782 | if (tty) { | 1783 | if (status & BIT9) |
1783 | if (status & BIT9) | 1784 | stat = TTY_PARITY; |
1784 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 1785 | else if (status & BIT8) |
1785 | else if (status & BIT8) | 1786 | stat = TTY_FRAME; |
1786 | *tty->flip.flag_buf_ptr = TTY_FRAME; | ||
1787 | } | ||
1788 | } | 1787 | } |
1789 | if (tty) { | 1788 | if (tty) { |
1790 | tty->flip.flag_buf_ptr++; | 1789 | tty_insert_flip_char(tty, ch, stat); |
1791 | tty->flip.char_buf_ptr++; | 1790 | chars++; |
1792 | tty->flip.count++; | ||
1793 | } | 1791 | } |
1794 | } | 1792 | } |
1795 | 1793 | ||
@@ -1812,7 +1810,7 @@ static void rx_async(struct slgt_info *info) | |||
1812 | break; | 1810 | break; |
1813 | } | 1811 | } |
1814 | 1812 | ||
1815 | if (tty && tty->flip.count) | 1813 | if (tty && chars) |
1816 | tty_flip_buffer_push(tty); | 1814 | tty_flip_buffer_push(tty); |
1817 | } | 1815 | } |
1818 | 1816 | ||
@@ -2030,7 +2028,7 @@ static void isr_serial(struct slgt_info *info) | |||
2030 | if (info->tty) { | 2028 | if (info->tty) { |
2031 | if (!(status & info->ignore_status_mask)) { | 2029 | if (!(status & info->ignore_status_mask)) { |
2032 | if (info->read_status_mask & MASK_BREAK) { | 2030 | if (info->read_status_mask & MASK_BREAK) { |
2033 | *info->tty->flip.flag_buf_ptr = TTY_BREAK; | 2031 | tty_insert_flip_char(info->tty, 0, TTY_BREAK); |
2034 | if (info->flags & ASYNC_SAK) | 2032 | if (info->flags & ASYNC_SAK) |
2035 | do_SAK(info->tty); | 2033 | do_SAK(info->tty); |
2036 | } | 2034 | } |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index ee5a40be9f99..960adb256fbb 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -2196,7 +2196,7 @@ void isr_rxint(SLMP_INFO * info) | |||
2196 | if ( tty ) { | 2196 | if ( tty ) { |
2197 | if (!(status & info->ignore_status_mask1)) { | 2197 | if (!(status & info->ignore_status_mask1)) { |
2198 | if (info->read_status_mask1 & BRKD) { | 2198 | if (info->read_status_mask1 & BRKD) { |
2199 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 2199 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
2200 | if (info->flags & ASYNC_SAK) | 2200 | if (info->flags & ASYNC_SAK) |
2201 | do_SAK(tty); | 2201 | do_SAK(tty); |
2202 | } | 2202 | } |
@@ -2240,16 +2240,10 @@ void isr_rxrdy(SLMP_INFO * info) | |||
2240 | 2240 | ||
2241 | while((status = read_reg(info,CST0)) & BIT0) | 2241 | while((status = read_reg(info,CST0)) & BIT0) |
2242 | { | 2242 | { |
2243 | int flag = 0; | ||
2244 | int over = 0; | ||
2243 | DataByte = read_reg(info,TRB); | 2245 | DataByte = read_reg(info,TRB); |
2244 | 2246 | ||
2245 | if ( tty ) { | ||
2246 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
2247 | continue; | ||
2248 | |||
2249 | *tty->flip.char_buf_ptr = DataByte; | ||
2250 | *tty->flip.flag_buf_ptr = 0; | ||
2251 | } | ||
2252 | |||
2253 | icount->rx++; | 2247 | icount->rx++; |
2254 | 2248 | ||
2255 | if ( status & (PE + FRME + OVRN) ) { | 2249 | if ( status & (PE + FRME + OVRN) ) { |
@@ -2272,42 +2266,34 @@ void isr_rxrdy(SLMP_INFO * info) | |||
2272 | 2266 | ||
2273 | if ( tty ) { | 2267 | if ( tty ) { |
2274 | if (status & PE) | 2268 | if (status & PE) |
2275 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 2269 | flag = TTY_PARITY; |
2276 | else if (status & FRME) | 2270 | else if (status & FRME) |
2277 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 2271 | flag = TTY_FRAME; |
2278 | if (status & OVRN) { | 2272 | if (status & OVRN) { |
2279 | /* Overrun is special, since it's | 2273 | /* Overrun is special, since it's |
2280 | * reported immediately, and doesn't | 2274 | * reported immediately, and doesn't |
2281 | * affect the current character | 2275 | * affect the current character |
2282 | */ | 2276 | */ |
2283 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 2277 | over = 1; |
2284 | tty->flip.count++; | ||
2285 | tty->flip.flag_buf_ptr++; | ||
2286 | tty->flip.char_buf_ptr++; | ||
2287 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
2288 | } | ||
2289 | } | 2278 | } |
2290 | } | 2279 | } |
2291 | } /* end of if (error) */ | 2280 | } /* end of if (error) */ |
2292 | 2281 | ||
2293 | if ( tty ) { | 2282 | if ( tty ) { |
2294 | tty->flip.flag_buf_ptr++; | 2283 | tty_insert_flip_char(tty, DataByte, flag); |
2295 | tty->flip.char_buf_ptr++; | 2284 | if (over) |
2296 | tty->flip.count++; | 2285 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
2297 | } | 2286 | } |
2298 | } | 2287 | } |
2299 | 2288 | ||
2300 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 2289 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
2301 | printk("%s(%d):%s isr_rxrdy() flip count=%d\n", | ||
2302 | __FILE__,__LINE__,info->device_name, | ||
2303 | tty ? tty->flip.count : 0); | ||
2304 | printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", | 2290 | printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", |
2305 | __FILE__,__LINE__,info->device_name, | 2291 | __FILE__,__LINE__,info->device_name, |
2306 | icount->rx,icount->brk,icount->parity, | 2292 | icount->rx,icount->brk,icount->parity, |
2307 | icount->frame,icount->overrun); | 2293 | icount->frame,icount->overrun); |
2308 | } | 2294 | } |
2309 | 2295 | ||
2310 | if ( tty && tty->flip.count ) | 2296 | if ( tty ) |
2311 | tty_flip_buffer_push(tty); | 2297 | tty_flip_buffer_push(tty); |
2312 | } | 2298 | } |
2313 | 2299 | ||
@@ -5104,7 +5090,7 @@ void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count) | |||
5104 | int register_test(SLMP_INFO *info) | 5090 | int register_test(SLMP_INFO *info) |
5105 | { | 5091 | { |
5106 | static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96}; | 5092 | static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96}; |
5107 | static unsigned int count = sizeof(testval)/sizeof(unsigned char); | 5093 | static unsigned int count = ARRAY_SIZE(testval); |
5108 | unsigned int i; | 5094 | unsigned int i; |
5109 | int rc = TRUE; | 5095 | int rc = TRUE; |
5110 | unsigned long flags; | 5096 | unsigned long flags; |
@@ -5422,7 +5408,7 @@ int memory_test(SLMP_INFO *info) | |||
5422 | { | 5408 | { |
5423 | static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa, | 5409 | static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa, |
5424 | 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; | 5410 | 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; |
5425 | unsigned long count = sizeof(testval)/sizeof(unsigned long); | 5411 | unsigned long count = ARRAY_SIZE(testval); |
5426 | unsigned long i; | 5412 | unsigned long i; |
5427 | unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long); | 5413 | unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long); |
5428 | unsigned long * addr = (unsigned long *)info->memory_base; | 5414 | unsigned long * addr = (unsigned long *)info->memory_base; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 4b1eef51ec59..1eda82b31a61 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -166,9 +166,12 @@ static struct tty_struct *alloc_tty_struct(void) | |||
166 | return tty; | 166 | return tty; |
167 | } | 167 | } |
168 | 168 | ||
169 | static void tty_buffer_free_all(struct tty_struct *); | ||
170 | |||
169 | static inline void free_tty_struct(struct tty_struct *tty) | 171 | static inline void free_tty_struct(struct tty_struct *tty) |
170 | { | 172 | { |
171 | kfree(tty->write_buf); | 173 | kfree(tty->write_buf); |
174 | tty_buffer_free_all(tty); | ||
172 | kfree(tty); | 175 | kfree(tty); |
173 | } | 176 | } |
174 | 177 | ||
@@ -231,6 +234,201 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
231 | } | 234 | } |
232 | 235 | ||
233 | /* | 236 | /* |
237 | * Tty buffer allocation management | ||
238 | */ | ||
239 | |||
240 | static void tty_buffer_free_all(struct tty_struct *tty) | ||
241 | { | ||
242 | struct tty_buffer *thead; | ||
243 | while((thead = tty->buf.head) != NULL) { | ||
244 | tty->buf.head = thead->next; | ||
245 | kfree(thead); | ||
246 | } | ||
247 | while((thead = tty->buf.free) != NULL) { | ||
248 | tty->buf.free = thead->next; | ||
249 | kfree(thead); | ||
250 | } | ||
251 | tty->buf.tail = NULL; | ||
252 | } | ||
253 | |||
254 | static void tty_buffer_init(struct tty_struct *tty) | ||
255 | { | ||
256 | tty->buf.head = NULL; | ||
257 | tty->buf.tail = NULL; | ||
258 | tty->buf.free = NULL; | ||
259 | } | ||
260 | |||
261 | static struct tty_buffer *tty_buffer_alloc(size_t size) | ||
262 | { | ||
263 | struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
264 | if(p == NULL) | ||
265 | return NULL; | ||
266 | p->used = 0; | ||
267 | p->size = size; | ||
268 | p->next = NULL; | ||
269 | p->char_buf_ptr = (char *)(p->data); | ||
270 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
271 | /* printk("Flip create %p\n", p); */ | ||
272 | return p; | ||
273 | } | ||
274 | |||
275 | /* Must be called with the tty_read lock held. This needs to acquire strategy | ||
276 | code to decide if we should kfree or relink a given expired buffer */ | ||
277 | |||
278 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
279 | { | ||
280 | /* Dumb strategy for now - should keep some stats */ | ||
281 | /* printk("Flip dispose %p\n", b); */ | ||
282 | if(b->size >= 512) | ||
283 | kfree(b); | ||
284 | else { | ||
285 | b->next = tty->buf.free; | ||
286 | tty->buf.free = b; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
291 | { | ||
292 | struct tty_buffer **tbh = &tty->buf.free; | ||
293 | while((*tbh) != NULL) { | ||
294 | struct tty_buffer *t = *tbh; | ||
295 | if(t->size >= size) { | ||
296 | *tbh = t->next; | ||
297 | t->next = NULL; | ||
298 | t->used = 0; | ||
299 | /* DEBUG ONLY */ | ||
300 | memset(t->data, '*', size); | ||
301 | /* printk("Flip recycle %p\n", t); */ | ||
302 | return t; | ||
303 | } | ||
304 | tbh = &((*tbh)->next); | ||
305 | } | ||
306 | /* Round the buffer size out */ | ||
307 | size = (size + 0xFF) & ~ 0xFF; | ||
308 | return tty_buffer_alloc(size); | ||
309 | /* Should possibly check if this fails for the largest buffer we | ||
310 | have queued and recycle that ? */ | ||
311 | } | ||
312 | |||
313 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
314 | { | ||
315 | struct tty_buffer *b = tty->buf.head, *n; | ||
316 | int left = 0; | ||
317 | |||
318 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
319 | remove this conditional if its worth it. This would be invisible | ||
320 | to the callers */ | ||
321 | if(b != NULL) | ||
322 | left = b->size - b->used; | ||
323 | if(left >= size) | ||
324 | return size; | ||
325 | /* This is the slow path - looking for new buffers to use */ | ||
326 | n = tty_buffer_find(tty, size); | ||
327 | if(n == NULL) | ||
328 | return left; | ||
329 | n->next = b; | ||
330 | if(b != NULL) | ||
331 | b->next = n; | ||
332 | else | ||
333 | tty->buf.head = n; | ||
334 | tty->buf.tail = n; | ||
335 | return size; | ||
336 | } | ||
337 | |||
338 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
339 | |||
340 | int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size) | ||
341 | { | ||
342 | int copied = 0; | ||
343 | do { | ||
344 | int space = tty_buffer_request_room(tty, size - copied); | ||
345 | struct tty_buffer *tb = tty->buf.tail; | ||
346 | /* If there is no space then tb may be NULL */ | ||
347 | if(unlikely(space == 0)) | ||
348 | break; | ||
349 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
350 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
351 | tb->used += space; | ||
352 | copied += space; | ||
353 | chars += space; | ||
354 | /* printk("Flip insert %d.\n", space); */ | ||
355 | } | ||
356 | /* There is a small chance that we need to split the data over | ||
357 | several buffers. If this is the case we must loop */ | ||
358 | while (unlikely(size > copied)); | ||
359 | return copied; | ||
360 | } | ||
361 | |||
362 | EXPORT_SYMBOL_GPL(tty_insert_flip_string); | ||
363 | |||
364 | int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size) | ||
365 | { | ||
366 | int copied = 0; | ||
367 | do { | ||
368 | int space = tty_buffer_request_room(tty, size - copied); | ||
369 | struct tty_buffer *tb = tty->buf.tail; | ||
370 | /* If there is no space then tb may be NULL */ | ||
371 | if(unlikely(space == 0)) | ||
372 | break; | ||
373 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
374 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
375 | tb->used += space; | ||
376 | copied += space; | ||
377 | chars += space; | ||
378 | flags += space; | ||
379 | } | ||
380 | /* There is a small chance that we need to split the data over | ||
381 | several buffers. If this is the case we must loop */ | ||
382 | while (unlikely(size > copied)); | ||
383 | return copied; | ||
384 | } | ||
385 | |||
386 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); | ||
387 | |||
388 | |||
389 | /* | ||
390 | * Prepare a block of space in the buffer for data. Returns the length | ||
391 | * available and buffer pointer to the space which is now allocated and | ||
392 | * accounted for as ready for normal characters. This is used for drivers | ||
393 | * that need their own block copy routines into the buffer. There is no | ||
394 | * guarantee the buffer is a DMA target! | ||
395 | */ | ||
396 | |||
397 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) | ||
398 | { | ||
399 | int space = tty_buffer_request_room(tty, size); | ||
400 | struct tty_buffer *tb = tty->buf.tail; | ||
401 | *chars = tb->char_buf_ptr + tb->used; | ||
402 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
403 | tb->used += space; | ||
404 | return space; | ||
405 | } | ||
406 | |||
407 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
408 | |||
409 | /* | ||
410 | * Prepare a block of space in the buffer for data. Returns the length | ||
411 | * available and buffer pointer to the space which is now allocated and | ||
412 | * accounted for as ready for characters. This is used for drivers | ||
413 | * that need their own block copy routines into the buffer. There is no | ||
414 | * guarantee the buffer is a DMA target! | ||
415 | */ | ||
416 | |||
417 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) | ||
418 | { | ||
419 | int space = tty_buffer_request_room(tty, size); | ||
420 | struct tty_buffer *tb = tty->buf.tail; | ||
421 | *chars = tb->char_buf_ptr + tb->used; | ||
422 | *flags = tb->flag_buf_ptr + tb->used; | ||
423 | tb->used += space; | ||
424 | return space; | ||
425 | } | ||
426 | |||
427 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
428 | |||
429 | |||
430 | |||
431 | /* | ||
234 | * This is probably overkill for real world processors but | 432 | * This is probably overkill for real world processors but |
235 | * they are not on hot paths so a little discipline won't do | 433 | * they are not on hot paths so a little discipline won't do |
236 | * any harm. | 434 | * any harm. |
@@ -492,6 +690,17 @@ restart: | |||
492 | if (ld == NULL) | 690 | if (ld == NULL) |
493 | return -EINVAL; | 691 | return -EINVAL; |
494 | 692 | ||
693 | /* | ||
694 | * No more input please, we are switching. The new ldisc | ||
695 | * will update this value in the ldisc open function | ||
696 | */ | ||
697 | |||
698 | tty->receive_room = 0; | ||
699 | |||
700 | /* | ||
701 | * Problem: What do we do if this blocks ? | ||
702 | */ | ||
703 | |||
495 | tty_wait_until_sent(tty, 0); | 704 | tty_wait_until_sent(tty, 0); |
496 | 705 | ||
497 | if (tty->ldisc.num == ldisc) { | 706 | if (tty->ldisc.num == ldisc) { |
@@ -560,9 +769,9 @@ restart: | |||
560 | * we say so later on. | 769 | * we say so later on. |
561 | */ | 770 | */ |
562 | 771 | ||
563 | work = cancel_delayed_work(&tty->flip.work); | 772 | work = cancel_delayed_work(&tty->buf.work); |
564 | /* | 773 | /* |
565 | * Wait for ->hangup_work and ->flip.work handlers to terminate | 774 | * Wait for ->hangup_work and ->buf.work handlers to terminate |
566 | */ | 775 | */ |
567 | 776 | ||
568 | flush_scheduled_work(); | 777 | flush_scheduled_work(); |
@@ -616,7 +825,7 @@ restart: | |||
616 | /* Restart it in case no characters kick it off. Safe if | 825 | /* Restart it in case no characters kick it off. Safe if |
617 | already running */ | 826 | already running */ |
618 | if (work) | 827 | if (work) |
619 | schedule_delayed_work(&tty->flip.work, 1); | 828 | schedule_delayed_work(&tty->buf.work, 1); |
620 | return retval; | 829 | return retval; |
621 | } | 830 | } |
622 | 831 | ||
@@ -1721,10 +1930,10 @@ static void release_dev(struct file * filp) | |||
1721 | */ | 1930 | */ |
1722 | clear_bit(TTY_LDISC, &tty->flags); | 1931 | clear_bit(TTY_LDISC, &tty->flags); |
1723 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 1932 | clear_bit(TTY_DONT_FLIP, &tty->flags); |
1724 | cancel_delayed_work(&tty->flip.work); | 1933 | cancel_delayed_work(&tty->buf.work); |
1725 | 1934 | ||
1726 | /* | 1935 | /* |
1727 | * Wait for ->hangup_work and ->flip.work handlers to terminate | 1936 | * Wait for ->hangup_work and ->buf.work handlers to terminate |
1728 | */ | 1937 | */ |
1729 | 1938 | ||
1730 | flush_scheduled_work(); | 1939 | flush_scheduled_work(); |
@@ -2518,17 +2727,15 @@ EXPORT_SYMBOL(do_SAK); | |||
2518 | 2727 | ||
2519 | /* | 2728 | /* |
2520 | * This routine is called out of the software interrupt to flush data | 2729 | * This routine is called out of the software interrupt to flush data |
2521 | * from the flip buffer to the line discipline. | 2730 | * from the buffer chain to the line discipline. |
2522 | */ | 2731 | */ |
2523 | 2732 | ||
2524 | static void flush_to_ldisc(void *private_) | 2733 | static void flush_to_ldisc(void *private_) |
2525 | { | 2734 | { |
2526 | struct tty_struct *tty = (struct tty_struct *) private_; | 2735 | struct tty_struct *tty = (struct tty_struct *) private_; |
2527 | unsigned char *cp; | ||
2528 | char *fp; | ||
2529 | int count; | ||
2530 | unsigned long flags; | 2736 | unsigned long flags; |
2531 | struct tty_ldisc *disc; | 2737 | struct tty_ldisc *disc; |
2738 | struct tty_buffer *tbuf; | ||
2532 | 2739 | ||
2533 | disc = tty_ldisc_ref(tty); | 2740 | disc = tty_ldisc_ref(tty); |
2534 | if (disc == NULL) /* !TTY_LDISC */ | 2741 | if (disc == NULL) /* !TTY_LDISC */ |
@@ -2538,28 +2745,22 @@ static void flush_to_ldisc(void *private_) | |||
2538 | /* | 2745 | /* |
2539 | * Do it after the next timer tick: | 2746 | * Do it after the next timer tick: |
2540 | */ | 2747 | */ |
2541 | schedule_delayed_work(&tty->flip.work, 1); | 2748 | schedule_delayed_work(&tty->buf.work, 1); |
2542 | goto out; | 2749 | goto out; |
2543 | } | 2750 | } |
2544 | spin_lock_irqsave(&tty->read_lock, flags); | 2751 | spin_lock_irqsave(&tty->read_lock, flags); |
2545 | if (tty->flip.buf_num) { | 2752 | while((tbuf = tty->buf.head) != NULL) { |
2546 | cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; | 2753 | tty->buf.head = tbuf->next; |
2547 | fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; | 2754 | spin_unlock_irqrestore(&tty->read_lock, flags); |
2548 | tty->flip.buf_num = 0; | 2755 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ |
2549 | tty->flip.char_buf_ptr = tty->flip.char_buf; | 2756 | disc->receive_buf(tty, tbuf->char_buf_ptr, |
2550 | tty->flip.flag_buf_ptr = tty->flip.flag_buf; | 2757 | tbuf->flag_buf_ptr, |
2551 | } else { | 2758 | tbuf->used); |
2552 | cp = tty->flip.char_buf; | 2759 | spin_lock_irqsave(&tty->read_lock, flags); |
2553 | fp = tty->flip.flag_buf; | 2760 | tty_buffer_free(tty, tbuf); |
2554 | tty->flip.buf_num = 1; | 2761 | } |
2555 | tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE; | 2762 | tty->buf.tail = NULL; |
2556 | tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE; | ||
2557 | } | ||
2558 | count = tty->flip.count; | ||
2559 | tty->flip.count = 0; | ||
2560 | spin_unlock_irqrestore(&tty->read_lock, flags); | 2763 | spin_unlock_irqrestore(&tty->read_lock, flags); |
2561 | |||
2562 | disc->receive_buf(tty, cp, fp, count); | ||
2563 | out: | 2764 | out: |
2564 | tty_ldisc_deref(disc); | 2765 | tty_ldisc_deref(disc); |
2565 | } | 2766 | } |
@@ -2654,11 +2855,12 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2654 | if (tty->low_latency) | 2855 | if (tty->low_latency) |
2655 | flush_to_ldisc((void *) tty); | 2856 | flush_to_ldisc((void *) tty); |
2656 | else | 2857 | else |
2657 | schedule_delayed_work(&tty->flip.work, 1); | 2858 | schedule_delayed_work(&tty->buf.work, 1); |
2658 | } | 2859 | } |
2659 | 2860 | ||
2660 | EXPORT_SYMBOL(tty_flip_buffer_push); | 2861 | EXPORT_SYMBOL(tty_flip_buffer_push); |
2661 | 2862 | ||
2863 | |||
2662 | /* | 2864 | /* |
2663 | * This subroutine initializes a tty structure. | 2865 | * This subroutine initializes a tty structure. |
2664 | */ | 2866 | */ |
@@ -2669,10 +2871,10 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
2669 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | 2871 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); |
2670 | tty->pgrp = -1; | 2872 | tty->pgrp = -1; |
2671 | tty->overrun_time = jiffies; | 2873 | tty->overrun_time = jiffies; |
2672 | tty->flip.char_buf_ptr = tty->flip.char_buf; | 2874 | tty->buf.head = tty->buf.tail = NULL; |
2673 | tty->flip.flag_buf_ptr = tty->flip.flag_buf; | 2875 | tty_buffer_init(tty); |
2674 | INIT_WORK(&tty->flip.work, flush_to_ldisc, tty); | 2876 | INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); |
2675 | init_MUTEX(&tty->flip.pty_sem); | 2877 | init_MUTEX(&tty->buf.pty_sem); |
2676 | init_MUTEX(&tty->termios_sem); | 2878 | init_MUTEX(&tty->termios_sem); |
2677 | init_waitqueue_head(&tty->write_wait); | 2879 | init_waitqueue_head(&tty->write_wait); |
2678 | init_waitqueue_head(&tty->read_wait); | 2880 | init_waitqueue_head(&tty->read_wait); |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 4d75c261f98a..cb82ebf4cb07 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -993,11 +993,10 @@ static void vioHandleData(struct HvLpEvent *event) | |||
993 | * Don't attempt to copy more data into the buffer than we | 993 | * Don't attempt to copy more data into the buffer than we |
994 | * have room for because it would fail without indication. | 994 | * have room for because it would fail without indication. |
995 | */ | 995 | */ |
996 | if ((tty->flip.count + 1) > TTY_FLIPBUF_SIZE) { | 996 | if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) { |
997 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); | 997 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); |
998 | break; | 998 | break; |
999 | } | 999 | } |
1000 | tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL); | ||
1001 | } | 1000 | } |
1002 | 1001 | ||
1003 | /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */ | 1002 | /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */ |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 19ba83635dd7..d9325281e482 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -434,13 +434,7 @@ static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp) | |||
434 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | 434 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); |
435 | return IRQ_HANDLED; | 435 | return IRQ_HANDLED; |
436 | } | 436 | } |
437 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 437 | tty_insert_flip_char(tty, ch, 0); |
438 | *tty->flip.char_buf_ptr = ch; | ||
439 | *tty->flip.flag_buf_ptr = 0; | ||
440 | tty->flip.flag_buf_ptr++; | ||
441 | tty->flip.char_buf_ptr++; | ||
442 | tty->flip.count++; | ||
443 | } | ||
444 | 438 | ||
445 | /* Check if another character is already ready; in that case, the | 439 | /* Check if another character is already ready; in that case, the |
446 | * spcond_int() function must be used, because this character may have an | 440 | * spcond_int() function must be used, because this character may have an |
@@ -487,13 +481,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp) | |||
487 | else | 481 | else |
488 | err = 0; | 482 | err = 0; |
489 | 483 | ||
490 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | 484 | tty_insert_flip_char(tty, ch, err); |
491 | *tty->flip.char_buf_ptr = ch; | ||
492 | *tty->flip.flag_buf_ptr = err; | ||
493 | tty->flip.flag_buf_ptr++; | ||
494 | tty->flip.char_buf_ptr++; | ||
495 | tty->flip.count++; | ||
496 | } | ||
497 | 485 | ||
498 | /* ++TeSche: *All* errors have to be cleared manually, | 486 | /* ++TeSche: *All* errors have to be cleared manually, |
499 | * else the condition persists for the next chars | 487 | * else the condition persists for the next chars |
@@ -875,13 +863,13 @@ static int scc_open (struct tty_struct * tty, struct file * filp) | |||
875 | local_irq_save(flags); | 863 | local_irq_save(flags); |
876 | #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) | 864 | #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) |
877 | if (MACH_IS_MVME147 || MACH_IS_MVME16x) { | 865 | if (MACH_IS_MVME147 || MACH_IS_MVME16x) { |
878 | for (i=0; i<sizeof(mvme_init_tab)/sizeof(*mvme_init_tab); ++i) | 866 | for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i) |
879 | SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); | 867 | SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); |
880 | } | 868 | } |
881 | #endif | 869 | #endif |
882 | #if defined(CONFIG_BVME6000_SCC) | 870 | #if defined(CONFIG_BVME6000_SCC) |
883 | if (MACH_IS_BVME6000) { | 871 | if (MACH_IS_BVME6000) { |
884 | for (i=0; i<sizeof(bvme_init_tab)/sizeof(*bvme_init_tab); ++i) | 872 | for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i) |
885 | SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); | 873 | SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); |
886 | } | 874 | } |
887 | #endif | 875 | #endif |
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c index 435b30748e23..159acd8b7788 100644 --- a/drivers/char/vr41xx_rtc.c +++ b/drivers/char/vr41xx_rtc.c | |||
@@ -127,8 +127,6 @@ struct resource rtc_resource[2] = { | |||
127 | .flags = IORESOURCE_MEM, }, | 127 | .flags = IORESOURCE_MEM, }, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | #define RTC_NUM_RESOURCES sizeof(rtc_resource) / sizeof(struct resource) | ||
131 | |||
132 | static inline unsigned long read_elapsed_second(void) | 130 | static inline unsigned long read_elapsed_second(void) |
133 | { | 131 | { |
134 | unsigned long first_low, first_mid, first_high; | 132 | unsigned long first_low, first_mid, first_high; |
@@ -686,7 +684,8 @@ static int __devinit vr41xx_rtc_init(void) | |||
686 | break; | 684 | break; |
687 | } | 685 | } |
688 | 686 | ||
689 | rtc_platform_device = platform_device_register_simple("RTC", -1, rtc_resource, RTC_NUM_RESOURCES); | 687 | rtc_platform_device = platform_device_register_simple("RTC", -1, |
688 | rtc_resource, ARRAY_SIZE(rtc_resource)); | ||
690 | if (IS_ERR(rtc_platform_device)) | 689 | if (IS_ERR(rtc_platform_device)) |
691 | return PTR_ERR(rtc_platform_device); | 690 | return PTR_ERR(rtc_platform_device); |
692 | 691 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index e91268e86833..f1d9cb7feae6 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2758,29 +2758,6 @@ static void set_vesa_blanking(char __user *p) | |||
2758 | vesa_blank_mode = (mode < 4) ? mode : 0; | 2758 | vesa_blank_mode = (mode < 4) ? mode : 0; |
2759 | } | 2759 | } |
2760 | 2760 | ||
2761 | /* | ||
2762 | * This is called by a timer handler | ||
2763 | */ | ||
2764 | static void vesa_powerdown(void) | ||
2765 | { | ||
2766 | struct vc_data *c = vc_cons[fg_console].d; | ||
2767 | /* | ||
2768 | * Power down if currently suspended (1 or 2), | ||
2769 | * suspend if currently blanked (0), | ||
2770 | * else do nothing (i.e. already powered down (3)). | ||
2771 | * Called only if powerdown features are allowed. | ||
2772 | */ | ||
2773 | switch (vesa_blank_mode) { | ||
2774 | case VESA_NO_BLANKING: | ||
2775 | c->vc_sw->con_blank(c, VESA_VSYNC_SUSPEND+1, 0); | ||
2776 | break; | ||
2777 | case VESA_VSYNC_SUSPEND: | ||
2778 | case VESA_HSYNC_SUSPEND: | ||
2779 | c->vc_sw->con_blank(c, VESA_POWERDOWN+1, 0); | ||
2780 | break; | ||
2781 | } | ||
2782 | } | ||
2783 | |||
2784 | void do_blank_screen(int entering_gfx) | 2761 | void do_blank_screen(int entering_gfx) |
2785 | { | 2762 | { |
2786 | struct vc_data *vc = vc_cons[fg_console].d; | 2763 | struct vc_data *vc = vc_cons[fg_console].d; |
@@ -2791,8 +2768,7 @@ void do_blank_screen(int entering_gfx) | |||
2791 | if (console_blanked) { | 2768 | if (console_blanked) { |
2792 | if (blank_state == blank_vesa_wait) { | 2769 | if (blank_state == blank_vesa_wait) { |
2793 | blank_state = blank_off; | 2770 | blank_state = blank_off; |
2794 | vesa_powerdown(); | 2771 | vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0); |
2795 | |||
2796 | } | 2772 | } |
2797 | return; | 2773 | return; |
2798 | } | 2774 | } |
@@ -2822,7 +2798,7 @@ void do_blank_screen(int entering_gfx) | |||
2822 | 2798 | ||
2823 | save_screen(vc); | 2799 | save_screen(vc); |
2824 | /* In case we need to reset origin, blanking hook returns 1 */ | 2800 | /* In case we need to reset origin, blanking hook returns 1 */ |
2825 | i = vc->vc_sw->con_blank(vc, 1, 0); | 2801 | i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0); |
2826 | console_blanked = fg_console + 1; | 2802 | console_blanked = fg_console + 1; |
2827 | if (i) | 2803 | if (i) |
2828 | set_origin(vc); | 2804 | set_origin(vc); |
@@ -2830,13 +2806,10 @@ void do_blank_screen(int entering_gfx) | |||
2830 | if (console_blank_hook && console_blank_hook(1)) | 2806 | if (console_blank_hook && console_blank_hook(1)) |
2831 | return; | 2807 | return; |
2832 | 2808 | ||
2833 | if (vesa_off_interval) { | 2809 | if (vesa_off_interval && vesa_blank_mode) { |
2834 | blank_state = blank_vesa_wait; | 2810 | blank_state = blank_vesa_wait; |
2835 | mod_timer(&console_timer, jiffies + vesa_off_interval); | 2811 | mod_timer(&console_timer, jiffies + vesa_off_interval); |
2836 | } | 2812 | } |
2837 | |||
2838 | if (vesa_blank_mode) | ||
2839 | vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0); | ||
2840 | } | 2813 | } |
2841 | EXPORT_SYMBOL(do_blank_screen); | 2814 | EXPORT_SYMBOL(do_blank_screen); |
2842 | 2815 | ||
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 385e52930c02..4b4d7db1ff7b 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/ktime.h> | ||
27 | #include <linux/init.h> | 28 | #include <linux/init.h> |
28 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
29 | 30 | ||
@@ -56,7 +57,7 @@ void proc_fork_connector(struct task_struct *task) | |||
56 | msg = (struct cn_msg*)buffer; | 57 | msg = (struct cn_msg*)buffer; |
57 | ev = (struct proc_event*)msg->data; | 58 | ev = (struct proc_event*)msg->data; |
58 | get_seq(&msg->seq, &ev->cpu); | 59 | get_seq(&msg->seq, &ev->cpu); |
59 | getnstimestamp(&ev->timestamp); | 60 | ktime_get_ts(&ev->timestamp); /* get high res monotonic timestamp */ |
60 | ev->what = PROC_EVENT_FORK; | 61 | ev->what = PROC_EVENT_FORK; |
61 | ev->event_data.fork.parent_pid = task->real_parent->pid; | 62 | ev->event_data.fork.parent_pid = task->real_parent->pid; |
62 | ev->event_data.fork.parent_tgid = task->real_parent->tgid; | 63 | ev->event_data.fork.parent_tgid = task->real_parent->tgid; |
@@ -82,7 +83,7 @@ void proc_exec_connector(struct task_struct *task) | |||
82 | msg = (struct cn_msg*)buffer; | 83 | msg = (struct cn_msg*)buffer; |
83 | ev = (struct proc_event*)msg->data; | 84 | ev = (struct proc_event*)msg->data; |
84 | get_seq(&msg->seq, &ev->cpu); | 85 | get_seq(&msg->seq, &ev->cpu); |
85 | getnstimestamp(&ev->timestamp); | 86 | ktime_get_ts(&ev->timestamp); |
86 | ev->what = PROC_EVENT_EXEC; | 87 | ev->what = PROC_EVENT_EXEC; |
87 | ev->event_data.exec.process_pid = task->pid; | 88 | ev->event_data.exec.process_pid = task->pid; |
88 | ev->event_data.exec.process_tgid = task->tgid; | 89 | ev->event_data.exec.process_tgid = task->tgid; |
@@ -116,7 +117,7 @@ void proc_id_connector(struct task_struct *task, int which_id) | |||
116 | } else | 117 | } else |
117 | return; | 118 | return; |
118 | get_seq(&msg->seq, &ev->cpu); | 119 | get_seq(&msg->seq, &ev->cpu); |
119 | getnstimestamp(&ev->timestamp); | 120 | ktime_get_ts(&ev->timestamp); |
120 | 121 | ||
121 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); | 122 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); |
122 | msg->ack = 0; /* not used */ | 123 | msg->ack = 0; /* not used */ |
@@ -136,7 +137,7 @@ void proc_exit_connector(struct task_struct *task) | |||
136 | msg = (struct cn_msg*)buffer; | 137 | msg = (struct cn_msg*)buffer; |
137 | ev = (struct proc_event*)msg->data; | 138 | ev = (struct proc_event*)msg->data; |
138 | get_seq(&msg->seq, &ev->cpu); | 139 | get_seq(&msg->seq, &ev->cpu); |
139 | getnstimestamp(&ev->timestamp); | 140 | ktime_get_ts(&ev->timestamp); |
140 | ev->what = PROC_EVENT_EXIT; | 141 | ev->what = PROC_EVENT_EXIT; |
141 | ev->event_data.exit.process_pid = task->pid; | 142 | ev->event_data.exit.process_pid = task->pid; |
142 | ev->event_data.exit.process_tgid = task->tgid; | 143 | ev->event_data.exit.process_tgid = task->tgid; |
@@ -169,7 +170,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) | |||
169 | msg = (struct cn_msg*)buffer; | 170 | msg = (struct cn_msg*)buffer; |
170 | ev = (struct proc_event*)msg->data; | 171 | ev = (struct proc_event*)msg->data; |
171 | msg->seq = rcvd_seq; | 172 | msg->seq = rcvd_seq; |
172 | getnstimestamp(&ev->timestamp); | 173 | ktime_get_ts(&ev->timestamp); |
173 | ev->cpu = -1; | 174 | ev->cpu = -1; |
174 | ev->what = PROC_EVENT_NONE; | 175 | ev->what = PROC_EVENT_NONE; |
175 | ev->event_data.ack.err = err; | 176 | ev->event_data.ack.err = err; |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 211641a54398..fe06ebb0e5bf 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define PDC202_DEBUG_CABLE 0 | 40 | #define PDC202_DEBUG_CABLE 0 |
41 | 41 | ||
42 | const static char *pdc_quirk_drives[] = { | 42 | static const char *pdc_quirk_drives[] = { |
43 | "QUANTUM FIREBALLlct08 08", | 43 | "QUANTUM FIREBALLlct08 08", |
44 | "QUANTUM FIREBALLP KA6.4", | 44 | "QUANTUM FIREBALLP KA6.4", |
45 | "QUANTUM FIREBALLP KA9.1", | 45 | "QUANTUM FIREBALLP KA9.1", |
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c index 75897509c401..17390d762cf7 100644 --- a/drivers/ieee1394/amdtp.c +++ b/drivers/ieee1394/amdtp.c | |||
@@ -80,7 +80,6 @@ | |||
80 | #include <linux/pci.h> | 80 | #include <linux/pci.h> |
81 | #include <linux/interrupt.h> | 81 | #include <linux/interrupt.h> |
82 | #include <linux/poll.h> | 82 | #include <linux/poll.h> |
83 | #include <linux/ioctl32.h> | ||
84 | #include <linux/compat.h> | 83 | #include <linux/compat.h> |
85 | #include <linux/cdev.h> | 84 | #include <linux/cdev.h> |
86 | #include <asm/uaccess.h> | 85 | #include <asm/uaccess.h> |
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 196db7439272..efeaa944bd0a 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
@@ -108,7 +108,6 @@ | |||
108 | #include <linux/types.h> | 108 | #include <linux/types.h> |
109 | #include <linux/vmalloc.h> | 109 | #include <linux/vmalloc.h> |
110 | #include <linux/string.h> | 110 | #include <linux/string.h> |
111 | #include <linux/ioctl32.h> | ||
112 | #include <linux/compat.h> | 111 | #include <linux/compat.h> |
113 | #include <linux/cdev.h> | 112 | #include <linux/cdev.h> |
114 | 113 | ||
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 608479b2df14..39fb88309e8e 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
49 | #include <linux/timex.h> | 49 | #include <linux/timex.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/ioctl32.h> | ||
52 | #include <linux/compat.h> | 51 | #include <linux/compat.h> |
53 | #include <linux/cdev.h> | 52 | #include <linux/cdev.h> |
54 | 53 | ||
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 1bd88fca0542..54a680cc704d 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -96,6 +96,7 @@ static int serport_ldisc_open(struct tty_struct *tty) | |||
96 | init_waitqueue_head(&serport->wait); | 96 | init_waitqueue_head(&serport->wait); |
97 | 97 | ||
98 | tty->disc_data = serport; | 98 | tty->disc_data = serport; |
99 | tty->receive_room = 256; | ||
99 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 100 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
100 | 101 | ||
101 | return 0; | 102 | return 0; |
@@ -140,17 +141,6 @@ out: | |||
140 | } | 141 | } |
141 | 142 | ||
142 | /* | 143 | /* |
143 | * serport_ldisc_room() reports how much room we do have for receiving data. | ||
144 | * Although we in fact have infinite room, we need to specify some value | ||
145 | * here, and 256 seems to be reasonable. | ||
146 | */ | ||
147 | |||
148 | static int serport_ldisc_room(struct tty_struct *tty) | ||
149 | { | ||
150 | return 256; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * serport_ldisc_read() just waits indefinitely if everything goes well. | 144 | * serport_ldisc_read() just waits indefinitely if everything goes well. |
155 | * However, when the serio driver closes the serio port, it finishes, | 145 | * However, when the serio driver closes the serio port, it finishes, |
156 | * returning 0 characters. | 146 | * returning 0 characters. |
@@ -237,7 +227,6 @@ static struct tty_ldisc serport_ldisc = { | |||
237 | .read = serport_ldisc_read, | 227 | .read = serport_ldisc_read, |
238 | .ioctl = serport_ldisc_ioctl, | 228 | .ioctl = serport_ldisc_ioctl, |
239 | .receive_buf = serport_ldisc_receive, | 229 | .receive_buf = serport_ldisc_receive, |
240 | .receive_room = serport_ldisc_room, | ||
241 | .write_wakeup = serport_ldisc_write_wakeup | 230 | .write_wakeup = serport_ldisc_write_wakeup |
242 | }; | 231 | }; |
243 | 232 | ||
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 11ae0fddea04..623adbb0d13a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -463,8 +463,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) | |||
463 | #endif | 463 | #endif |
464 | goto bad; | 464 | goto bad; |
465 | } | 465 | } |
466 | if (ld->receive_room && | 466 | if (mp->tty->receive_room < datalen) { |
467 | ld->receive_room(mp->tty) < datalen) { | ||
468 | #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) | 467 | #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) |
469 | printk(KERN_DEBUG "capi: no room in tty\n"); | 468 | printk(KERN_DEBUG "capi: no room in tty\n"); |
470 | #endif | 469 | #endif |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 4643df097bfe..22759c01746a 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -857,6 +857,118 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que | |||
857 | return count; | 857 | return count; |
858 | } | 858 | } |
859 | 859 | ||
860 | /* | ||
861 | * isdn_readbchan_tty() tries to get data from the read-queue. | ||
862 | * It MUST be called with interrupts off. | ||
863 | * | ||
864 | * Be aware that this is not an atomic operation when sleep != 0, even though | ||
865 | * interrupts are turned off! Well, like that we are currently only called | ||
866 | * on behalf of a read system call on raw device files (which are documented | ||
867 | * to be dangerous and for for debugging purpose only). The inode semaphore | ||
868 | * takes care that this is not called for the same minor device number while | ||
869 | * we are sleeping, but access is not serialized against simultaneous read() | ||
870 | * from the corresponding ttyI device. Can other ugly events, like changes | ||
871 | * of the mapping (di,ch)<->minor, happen during the sleep? --he | ||
872 | */ | ||
873 | int | ||
874 | isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | ||
875 | { | ||
876 | int count; | ||
877 | int count_pull; | ||
878 | int count_put; | ||
879 | int dflag; | ||
880 | struct sk_buff *skb; | ||
881 | char last = 0; | ||
882 | int len; | ||
883 | |||
884 | if (!dev->drv[di]) | ||
885 | return 0; | ||
886 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | ||
887 | return 0; | ||
888 | |||
889 | len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); | ||
890 | if(len == 0) | ||
891 | return len; | ||
892 | |||
893 | count = 0; | ||
894 | while (len) { | ||
895 | if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel]))) | ||
896 | break; | ||
897 | #ifdef CONFIG_ISDN_AUDIO | ||
898 | if (ISDN_AUDIO_SKB_LOCK(skb)) | ||
899 | break; | ||
900 | ISDN_AUDIO_SKB_LOCK(skb) = 1; | ||
901 | if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { | ||
902 | char *p = skb->data; | ||
903 | unsigned long DLEmask = (1 << channel); | ||
904 | |||
905 | dflag = 0; | ||
906 | count_pull = count_put = 0; | ||
907 | while ((count_pull < skb->len) && (len > 0)) { | ||
908 | len--; | ||
909 | if (dev->drv[di]->DLEflag & DLEmask) { | ||
910 | last = DLE; | ||
911 | dev->drv[di]->DLEflag &= ~DLEmask; | ||
912 | } else { | ||
913 | last = *p; | ||
914 | if (last == DLE) { | ||
915 | dev->drv[di]->DLEflag |= DLEmask; | ||
916 | (ISDN_AUDIO_SKB_DLECOUNT(skb))--; | ||
917 | } | ||
918 | p++; | ||
919 | count_pull++; | ||
920 | } | ||
921 | count_put++; | ||
922 | } | ||
923 | if (count_pull >= skb->len) | ||
924 | dflag = 1; | ||
925 | } else { | ||
926 | #endif | ||
927 | /* No DLE's in buff, so simply copy it */ | ||
928 | dflag = 1; | ||
929 | if ((count_pull = skb->len) > len) { | ||
930 | count_pull = len; | ||
931 | dflag = 0; | ||
932 | } | ||
933 | count_put = count_pull; | ||
934 | if(count_put > 1) | ||
935 | tty_insert_flip_string(tty, skb->data, count_put - 1); | ||
936 | last = skb->data[count_put] - 1; | ||
937 | len -= count_put; | ||
938 | #ifdef CONFIG_ISDN_AUDIO | ||
939 | } | ||
940 | #endif | ||
941 | count += count_put; | ||
942 | if (dflag) { | ||
943 | /* We got all the data in this buff. | ||
944 | * Now we can dequeue it. | ||
945 | */ | ||
946 | if(cisco_hack) | ||
947 | tty_insert_flip_char(tty, last, 0xFF); | ||
948 | else | ||
949 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
950 | #ifdef CONFIG_ISDN_AUDIO | ||
951 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | ||
952 | #endif | ||
953 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); | ||
954 | dev_kfree_skb(skb); | ||
955 | } else { | ||
956 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
957 | /* Not yet emptied this buff, so it | ||
958 | * must stay in the queue, for further calls | ||
959 | * but we pull off the data we got until now. | ||
960 | */ | ||
961 | skb_pull(skb, count_pull); | ||
962 | #ifdef CONFIG_ISDN_AUDIO | ||
963 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | ||
964 | #endif | ||
965 | } | ||
966 | dev->drv[di]->rcvcount[channel] -= count_put; | ||
967 | } | ||
968 | return count; | ||
969 | } | ||
970 | |||
971 | |||
860 | static __inline int | 972 | static __inline int |
861 | isdn_minor2drv(int minor) | 973 | isdn_minor2drv(int minor) |
862 | { | 974 | { |
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index e27e9c3a81ed..082735dbb412 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h | |||
@@ -37,6 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); | |||
37 | extern void isdn_unexclusive_channel(int di, int ch); | 37 | extern void isdn_unexclusive_channel(int di, int ch); |
38 | extern int isdn_getnum(char **); | 38 | extern int isdn_getnum(char **); |
39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); | 39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); |
40 | extern int isdn_readbchan_tty(int, int, struct tty_struct *, int); | ||
40 | extern int isdn_get_free_channel(int, int, int, int, int, char *); | 41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); |
41 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); | 42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); |
42 | extern int register_isdn(isdn_if * i); | 43 | extern int register_isdn(isdn_if * i); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 8c404b4e2482..f190a99604f0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) | |||
64 | int c; | 64 | int c; |
65 | int len; | 65 | int len; |
66 | struct tty_struct *tty; | 66 | struct tty_struct *tty; |
67 | char last; | ||
67 | 68 | ||
68 | if (info->online) { | 69 | if (info->online) { |
69 | if ((tty = info->tty)) { | 70 | if ((tty = info->tty)) { |
70 | if (info->mcr & UART_MCR_RTS) { | 71 | if (info->mcr & UART_MCR_RTS) { |
71 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
72 | len = skb->len | 72 | len = skb->len |
73 | #ifdef CONFIG_ISDN_AUDIO | 73 | #ifdef CONFIG_ISDN_AUDIO |
74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) | 74 | + ISDN_AUDIO_SKB_DLECOUNT(skb) |
75 | #endif | 75 | #endif |
76 | ; | 76 | ; |
77 | |||
78 | c = tty_buffer_request_room(tty, len); | ||
77 | if (c >= len) { | 79 | if (c >= len) { |
78 | #ifdef CONFIG_ISDN_AUDIO | 80 | #ifdef CONFIG_ISDN_AUDIO |
79 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) | 81 | if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { |
80 | while (skb->len--) { | 82 | int l = skb->len; |
83 | unsigned char *dp = skb->data; | ||
84 | while (--l) { | ||
81 | if (*skb->data == DLE) | 85 | if (*skb->data == DLE) |
82 | tty_insert_flip_char(tty, DLE, 0); | 86 | tty_insert_flip_char(tty, DLE, 0); |
83 | tty_insert_flip_char(tty, *skb->data++, 0); | 87 | tty_insert_flip_char(tty, *dp++, 0); |
88 | } | ||
89 | last = *dp; | ||
84 | } else { | 90 | } else { |
85 | #endif | 91 | #endif |
86 | memcpy(tty->flip.char_buf_ptr, | 92 | if(len > 1) |
87 | skb->data, len); | 93 | tty_insert_flip_string(tty, skb->data, len - 1); |
88 | tty->flip.count += len; | 94 | last = skb->data[len - 1]; |
89 | tty->flip.char_buf_ptr += len; | ||
90 | memset(tty->flip.flag_buf_ptr, 0, len); | ||
91 | tty->flip.flag_buf_ptr += len; | ||
92 | #ifdef CONFIG_ISDN_AUDIO | 95 | #ifdef CONFIG_ISDN_AUDIO |
93 | } | 96 | } |
94 | #endif | 97 | #endif |
95 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) | 98 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) |
96 | tty->flip.flag_buf_ptr[len - 1] = 0xff; | 99 | tty_insert_flip_char(tty, last, 0xFF); |
97 | schedule_delayed_work(&tty->flip.work, 1); | 100 | else |
101 | tty_insert_flip_char(tty, last, TTY_NORMAL); | ||
102 | tty_flip_buffer_push(tty); | ||
98 | kfree_skb(skb); | 103 | kfree_skb(skb); |
99 | return 1; | 104 | return 1; |
100 | } | 105 | } |
@@ -114,7 +119,6 @@ isdn_tty_readmodem(void) | |||
114 | int resched = 0; | 119 | int resched = 0; |
115 | int midx; | 120 | int midx; |
116 | int i; | 121 | int i; |
117 | int c; | ||
118 | int r; | 122 | int r; |
119 | struct tty_struct *tty; | 123 | struct tty_struct *tty; |
120 | modem_info *info; | 124 | modem_info *info; |
@@ -131,20 +135,13 @@ isdn_tty_readmodem(void) | |||
131 | #endif | 135 | #endif |
132 | if ((tty = info->tty)) { | 136 | if ((tty = info->tty)) { |
133 | if (info->mcr & UART_MCR_RTS) { | 137 | if (info->mcr & UART_MCR_RTS) { |
134 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | 138 | /* CISCO AsyncPPP Hack */ |
135 | if (c > 0) { | 139 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) |
136 | r = isdn_readbchan(info->isdn_driver, info->isdn_channel, | 140 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); |
137 | tty->flip.char_buf_ptr, | 141 | else |
138 | tty->flip.flag_buf_ptr, c, NULL); | 142 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); |
139 | /* CISCO AsyncPPP Hack */ | 143 | if (r) |
140 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) | 144 | tty_flip_buffer_push(tty); |
141 | memset(tty->flip.flag_buf_ptr, 0, r); | ||
142 | tty->flip.count += r; | ||
143 | tty->flip.flag_buf_ptr += r; | ||
144 | tty->flip.char_buf_ptr += r; | ||
145 | if (r) | ||
146 | schedule_delayed_work(&tty->flip.work, 1); | ||
147 | } | ||
148 | } else | 145 | } else |
149 | r = 1; | 146 | r = 1; |
150 | } else | 147 | } else |
@@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) | |||
249 | } | 246 | } |
250 | #endif | 247 | #endif |
251 | #endif | 248 | #endif |
252 | /* Try to deliver directly via tty-flip-buf if queue is empty */ | 249 | /* Try to deliver directly via tty-buf if queue is empty */ |
253 | spin_lock_irqsave(&info->readlock, flags); | 250 | spin_lock_irqsave(&info->readlock, flags); |
254 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | 251 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) |
255 | if (isdn_tty_try_read(info, skb)) { | 252 | if (isdn_tty_try_read(info, skb)) { |
@@ -534,7 +531,7 @@ isdn_tty_senddown(modem_info * info) | |||
534 | /* The next routine is called once from within timer-interrupt | 531 | /* The next routine is called once from within timer-interrupt |
535 | * triggered within isdn_tty_modem_ncarrier(). It calls | 532 | * triggered within isdn_tty_modem_ncarrier(). It calls |
536 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message | 533 | * isdn_tty_modem_result() to stuff a "NO CARRIER" Message |
537 | * into the tty's flip-buffer. | 534 | * into the tty's buffer. |
538 | */ | 535 | */ |
539 | static void | 536 | static void |
540 | isdn_tty_modem_do_ncarrier(unsigned long data) | 537 | isdn_tty_modem_do_ncarrier(unsigned long data) |
@@ -2347,6 +2344,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2347 | u_long flags; | 2344 | u_long flags; |
2348 | struct sk_buff *skb = NULL; | 2345 | struct sk_buff *skb = NULL; |
2349 | char *sp = NULL; | 2346 | char *sp = NULL; |
2347 | int l = strlen(msg); | ||
2350 | 2348 | ||
2351 | if (!msg) { | 2349 | if (!msg) { |
2352 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); | 2350 | printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); |
@@ -2359,16 +2357,16 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2359 | return; | 2357 | return; |
2360 | } | 2358 | } |
2361 | 2359 | ||
2362 | /* use queue instead of direct flip, if online and */ | 2360 | /* use queue instead of direct, if online and */ |
2363 | /* data is in queue or flip buffer is full */ | 2361 | /* data is in queue or buffer is full */ |
2364 | if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || | 2362 | if ((info->online && tty_buffer_request_room(tty, l) < l) || |
2365 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { | 2363 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2366 | skb = alloc_skb(strlen(msg), GFP_ATOMIC); | 2364 | skb = alloc_skb(l, GFP_ATOMIC); |
2367 | if (!skb) { | 2365 | if (!skb) { |
2368 | spin_unlock_irqrestore(&info->readlock, flags); | 2366 | spin_unlock_irqrestore(&info->readlock, flags); |
2369 | return; | 2367 | return; |
2370 | } | 2368 | } |
2371 | sp = skb_put(skb, strlen(msg)); | 2369 | sp = skb_put(skb, l); |
2372 | #ifdef CONFIG_ISDN_AUDIO | 2370 | #ifdef CONFIG_ISDN_AUDIO |
2373 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; | 2371 | ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; |
2374 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | 2372 | ISDN_AUDIO_SKB_LOCK(skb) = 0; |
@@ -2392,9 +2390,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2392 | if (skb) { | 2390 | if (skb) { |
2393 | *sp++ = c; | 2391 | *sp++ = c; |
2394 | } else { | 2392 | } else { |
2395 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 2393 | if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) |
2396 | break; | 2394 | break; |
2397 | tty_insert_flip_char(tty, c, 0); | ||
2398 | } | 2395 | } |
2399 | } | 2396 | } |
2400 | if (skb) { | 2397 | if (skb) { |
@@ -2402,12 +2399,12 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2402 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; | 2399 | dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; |
2403 | spin_unlock_irqrestore(&info->readlock, flags); | 2400 | spin_unlock_irqrestore(&info->readlock, flags); |
2404 | /* Schedule dequeuing */ | 2401 | /* Schedule dequeuing */ |
2405 | if ((dev->modempoll) && (info->rcvsched)) | 2402 | if (dev->modempoll && info->rcvsched) |
2406 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); | 2403 | isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); |
2407 | 2404 | ||
2408 | } else { | 2405 | } else { |
2409 | spin_unlock_irqrestore(&info->readlock, flags); | 2406 | spin_unlock_irqrestore(&info->readlock, flags); |
2410 | schedule_delayed_work(&tty->flip.work, 1); | 2407 | tty_flip_buffer_push(tty); |
2411 | } | 2408 | } |
2412 | } | 2409 | } |
2413 | 2410 | ||
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index e6aa309a66d7..96f7af4ae400 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -303,6 +303,7 @@ static void print_multipath_conf (multipath_conf_t *conf) | |||
303 | static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | 303 | static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) |
304 | { | 304 | { |
305 | multipath_conf_t *conf = mddev->private; | 305 | multipath_conf_t *conf = mddev->private; |
306 | struct request_queue *q; | ||
306 | int found = 0; | 307 | int found = 0; |
307 | int path; | 308 | int path; |
308 | struct multipath_info *p; | 309 | struct multipath_info *p; |
@@ -311,8 +312,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
311 | 312 | ||
312 | for (path=0; path<mddev->raid_disks; path++) | 313 | for (path=0; path<mddev->raid_disks; path++) |
313 | if ((p=conf->multipaths+path)->rdev == NULL) { | 314 | if ((p=conf->multipaths+path)->rdev == NULL) { |
314 | blk_queue_stack_limits(mddev->queue, | 315 | q = rdev->bdev->bd_disk->queue; |
315 | rdev->bdev->bd_disk->queue); | 316 | blk_queue_stack_limits(mddev->queue, q); |
316 | 317 | ||
317 | /* as we don't honour merge_bvec_fn, we must never risk | 318 | /* as we don't honour merge_bvec_fn, we must never risk |
318 | * violating it, so limit ->max_sector to one PAGE, as | 319 | * violating it, so limit ->max_sector to one PAGE, as |
@@ -320,7 +321,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
320 | * (Note: it is very unlikely that a device with | 321 | * (Note: it is very unlikely that a device with |
321 | * merge_bvec_fn will be involved in multipath.) | 322 | * merge_bvec_fn will be involved in multipath.) |
322 | */ | 323 | */ |
323 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 324 | if (q->merge_bvec_fn && |
324 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) | 325 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) |
325 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 326 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
326 | 327 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index c30effdf711f..36c9f5bf8cdd 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -27,34 +27,30 @@ | |||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/videodev.h> | 28 | #include <linux/videodev.h> |
29 | 29 | ||
30 | #define DRIVER_VERSION "0.04" | 30 | #define DRIVER_VERSION "0.05" |
31 | 31 | ||
32 | #define PCI_VENDOR_ESS 0x125D | 32 | #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ |
33 | #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */ | ||
34 | #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */ | ||
35 | |||
36 | #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ | ||
37 | 33 | ||
38 | #define IO_MASK 4 /* mask register offset from GPIO_DATA | 34 | #define IO_MASK 4 /* mask register offset from GPIO_DATA |
39 | bits 1=unmask write to given bit */ | 35 | bits 1=unmask write to given bit */ |
40 | #define IO_DIR 8 /* direction register offset from GPIO_DATA | 36 | #define IO_DIR 8 /* direction register offset from GPIO_DATA |
41 | bits 0/1=read/write direction */ | 37 | bits 0/1=read/write direction */ |
42 | 38 | ||
43 | #define GPIO6 0x0040 /* mask bits for GPIO lines */ | 39 | #define GPIO6 0x0040 /* mask bits for GPIO lines */ |
44 | #define GPIO7 0x0080 | 40 | #define GPIO7 0x0080 |
45 | #define GPIO8 0x0100 | 41 | #define GPIO8 0x0100 |
46 | #define GPIO9 0x0200 | 42 | #define GPIO9 0x0200 |
47 | 43 | ||
48 | #define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */ | 44 | #define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */ |
49 | #define STR_CLK GPIO7 | 45 | #define STR_CLK GPIO7 |
50 | #define STR_WREN GPIO8 | 46 | #define STR_WREN GPIO8 |
51 | #define STR_MOST GPIO9 | 47 | #define STR_MOST GPIO9 |
52 | 48 | ||
53 | #define FREQ_LO 50*16000 | 49 | #define FREQ_LO 50*16000 |
54 | #define FREQ_HI 150*16000 | 50 | #define FREQ_HI 150*16000 |
55 | 51 | ||
56 | #define FREQ_IF 171200 /* 10.7*16000 */ | 52 | #define FREQ_IF 171200 /* 10.7*16000 */ |
57 | #define FREQ_STEP 200 /* 12.5*16 */ | 53 | #define FREQ_STEP 200 /* 12.5*16 */ |
58 | 54 | ||
59 | #define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\ | 55 | #define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\ |
60 | /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */ | 56 | /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */ |
@@ -65,7 +61,27 @@ static int radio_nr = -1; | |||
65 | module_param(radio_nr, int, 0); | 61 | module_param(radio_nr, int, 0); |
66 | 62 | ||
67 | static int radio_ioctl(struct inode *inode, struct file *file, | 63 | static int radio_ioctl(struct inode *inode, struct file *file, |
68 | unsigned int cmd, unsigned long arg); | 64 | unsigned int cmd, unsigned long arg); |
65 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); | ||
66 | static void maestro_remove(struct pci_dev *pdev); | ||
67 | |||
68 | static struct pci_device_id maestro_r_pci_tbl[] = { | ||
69 | { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968), | ||
70 | .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, | ||
71 | .class_mask = 0xffff00 }, | ||
72 | { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978), | ||
73 | .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, | ||
74 | .class_mask = 0xffff00 }, | ||
75 | { 0 } | ||
76 | }; | ||
77 | MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl); | ||
78 | |||
79 | static struct pci_driver maestro_r_driver = { | ||
80 | .name = "maestro_radio", | ||
81 | .id_table = maestro_r_pci_tbl, | ||
82 | .probe = maestro_probe, | ||
83 | .remove = __devexit_p(maestro_remove), | ||
84 | }; | ||
69 | 85 | ||
70 | static struct file_operations maestro_fops = { | 86 | static struct file_operations maestro_fops = { |
71 | .owner = THIS_MODULE, | 87 | .owner = THIS_MODULE, |
@@ -76,29 +92,27 @@ static struct file_operations maestro_fops = { | |||
76 | .llseek = no_llseek, | 92 | .llseek = no_llseek, |
77 | }; | 93 | }; |
78 | 94 | ||
79 | static struct video_device maestro_radio= | 95 | static struct video_device maestro_radio = { |
80 | { | ||
81 | .owner = THIS_MODULE, | ||
82 | .name = "Maestro radio", | 96 | .name = "Maestro radio", |
83 | .type = VID_TYPE_TUNER, | 97 | .type = VID_TYPE_TUNER, |
84 | .hardware = VID_HARDWARE_SF16MI, | 98 | .hardware = VID_HARDWARE_SF16MI, |
85 | .fops = &maestro_fops, | 99 | .fops = &maestro_fops, |
86 | }; | 100 | }; |
87 | 101 | ||
88 | static struct radio_device | 102 | struct radio_device { |
89 | { | 103 | u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ |
90 | __u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ | ||
91 | muted, /* VIDEO_AUDIO_MUTE */ | 104 | muted, /* VIDEO_AUDIO_MUTE */ |
92 | stereo, /* VIDEO_TUNER_STEREO_ON */ | 105 | stereo, /* VIDEO_TUNER_STEREO_ON */ |
93 | tuned; /* signal strength (0 or 0xffff) */ | 106 | tuned; /* signal strength (0 or 0xffff) */ |
94 | struct semaphore lock; | 107 | struct semaphore lock; |
95 | } radio_unit = {0, 0, 0, 0, }; | 108 | }; |
96 | 109 | ||
97 | static __u32 radio_bits_get(struct radio_device *dev) | 110 | static u32 radio_bits_get(struct radio_device *dev) |
98 | { | 111 | { |
99 | register __u16 io=dev->io, l, rdata; | 112 | register u16 io=dev->io, l, rdata; |
100 | register __u32 data=0; | 113 | register u32 data=0; |
101 | __u16 omask; | 114 | u16 omask; |
115 | |||
102 | omask = inw(io + IO_MASK); | 116 | omask = inw(io + IO_MASK); |
103 | outw(~(STR_CLK | STR_WREN), io + IO_MASK); | 117 | outw(~(STR_CLK | STR_WREN), io + IO_MASK); |
104 | outw(0, io); | 118 | outw(0, io); |
@@ -121,17 +135,21 @@ static __u32 radio_bits_get(struct radio_device *dev) | |||
121 | data++; | 135 | data++; |
122 | udelay(2); | 136 | udelay(2); |
123 | } | 137 | } |
138 | |||
124 | if(dev->muted) | 139 | if(dev->muted) |
125 | outw(STR_WREN, io); | 140 | outw(STR_WREN, io); |
141 | |||
126 | udelay(4); | 142 | udelay(4); |
127 | outw(omask, io + IO_MASK); | 143 | outw(omask, io + IO_MASK); |
144 | |||
128 | return data & 0x3ffe; | 145 | return data & 0x3ffe; |
129 | } | 146 | } |
130 | 147 | ||
131 | static void radio_bits_set(struct radio_device *dev, __u32 data) | 148 | static void radio_bits_set(struct radio_device *dev, u32 data) |
132 | { | 149 | { |
133 | register __u16 io=dev->io, l, bits; | 150 | register u16 io=dev->io, l, bits; |
134 | __u16 omask, odir; | 151 | u16 omask, odir; |
152 | |||
135 | omask = inw(io + IO_MASK); | 153 | omask = inw(io + IO_MASK); |
136 | odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); | 154 | odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); |
137 | outw(odir | STR_DATA, io + IO_DIR); | 155 | outw(odir | STR_DATA, io + IO_DIR); |
@@ -147,8 +165,10 @@ static void radio_bits_set(struct radio_device *dev, __u32 data) | |||
147 | outw(bits, io); /* LO level */ | 165 | outw(bits, io); /* LO level */ |
148 | udelay(4); | 166 | udelay(4); |
149 | } | 167 | } |
168 | |||
150 | if(!dev->muted) | 169 | if(!dev->muted) |
151 | outw(0, io); | 170 | outw(0, io); |
171 | |||
152 | udelay(4); | 172 | udelay(4); |
153 | outw(omask, io + IO_MASK); | 173 | outw(omask, io + IO_MASK); |
154 | outw(odir, io + IO_DIR); | 174 | outw(odir, io + IO_DIR); |
@@ -156,141 +176,103 @@ static void radio_bits_set(struct radio_device *dev, __u32 data) | |||
156 | } | 176 | } |
157 | 177 | ||
158 | static inline int radio_function(struct inode *inode, struct file *file, | 178 | static inline int radio_function(struct inode *inode, struct file *file, |
159 | unsigned int cmd, void *arg) | 179 | unsigned int cmd, void *arg) |
160 | { | 180 | { |
161 | struct video_device *dev = video_devdata(file); | 181 | struct video_device *dev = video_devdata(file); |
162 | struct radio_device *card=dev->priv; | 182 | struct radio_device *card = video_get_drvdata(dev); |
163 | 183 | ||
164 | switch(cmd) { | 184 | switch (cmd) { |
165 | case VIDIOCGCAP: { | 185 | case VIDIOCGCAP: { |
166 | struct video_capability *v = arg; | 186 | struct video_capability *v = arg; |
167 | memset(v,0,sizeof(*v)); | 187 | memset(v, 0, sizeof(*v)); |
168 | strcpy(v->name, "Maestro radio"); | 188 | strcpy(v->name, "Maestro radio"); |
169 | v->type=VID_TYPE_TUNER; | 189 | v->type = VID_TYPE_TUNER; |
170 | v->channels=v->audios=1; | 190 | v->channels = v->audios = 1; |
171 | return 0; | 191 | return 0; |
172 | } | 192 | } case VIDIOCGTUNER: { |
173 | case VIDIOCGTUNER: { | 193 | struct video_tuner *v = arg; |
174 | struct video_tuner *v = arg; | 194 | if (v->tuner) |
175 | if(v->tuner) | 195 | return -EINVAL; |
176 | return -EINVAL; | 196 | (void)radio_bits_get(card); |
177 | (void)radio_bits_get(card); | 197 | v->flags = VIDEO_TUNER_LOW | card->stereo; |
178 | v->flags = VIDEO_TUNER_LOW | card->stereo; | 198 | v->signal = card->tuned; |
179 | v->signal = card->tuned; | 199 | strcpy(v->name, "FM"); |
180 | strcpy(v->name, "FM"); | 200 | v->rangelow = FREQ_LO; |
181 | v->rangelow = FREQ_LO; | 201 | v->rangehigh = FREQ_HI; |
182 | v->rangehigh = FREQ_HI; | 202 | v->mode = VIDEO_MODE_AUTO; |
183 | v->mode = VIDEO_MODE_AUTO; | 203 | return 0; |
184 | return 0; | 204 | } case VIDIOCSTUNER: { |
185 | } | 205 | struct video_tuner *v = arg; |
186 | case VIDIOCSTUNER: { | 206 | if (v->tuner != 0) |
187 | struct video_tuner *v = arg; | 207 | return -EINVAL; |
188 | if(v->tuner!=0) | 208 | return 0; |
189 | return -EINVAL; | 209 | } case VIDIOCGFREQ: { |
190 | return 0; | 210 | unsigned long *freq = arg; |
191 | } | 211 | *freq = BITS2FREQ(radio_bits_get(card)); |
192 | case VIDIOCGFREQ: { | 212 | return 0; |
193 | unsigned long *freq = arg; | 213 | } case VIDIOCSFREQ: { |
194 | *freq = BITS2FREQ(radio_bits_get(card)); | 214 | unsigned long *freq = arg; |
195 | return 0; | 215 | if (*freq < FREQ_LO || *freq > FREQ_HI) |
196 | } | 216 | return -EINVAL; |
197 | case VIDIOCSFREQ: { | 217 | radio_bits_set(card, FREQ2BITS(*freq)); |
198 | unsigned long *freq = arg; | 218 | return 0; |
199 | if (*freq<FREQ_LO || *freq>FREQ_HI ) | 219 | } case VIDIOCGAUDIO: { |
200 | return -EINVAL; | 220 | struct video_audio *v = arg; |
201 | radio_bits_set(card, FREQ2BITS(*freq)); | 221 | memset(v, 0, sizeof(*v)); |
222 | strcpy(v->name, "Radio"); | ||
223 | v->flags = VIDEO_AUDIO_MUTABLE | card->muted; | ||
224 | v->mode = VIDEO_SOUND_STEREO; | ||
225 | return 0; | ||
226 | } case VIDIOCSAUDIO: { | ||
227 | struct video_audio *v = arg; | ||
228 | if (v->audio) | ||
229 | return -EINVAL; | ||
230 | { | ||
231 | register u16 io = card->io; | ||
232 | register u16 omask = inw(io + IO_MASK); | ||
233 | outw(~STR_WREN, io + IO_MASK); | ||
234 | outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) ? | ||
235 | STR_WREN : 0, io); | ||
236 | udelay(4); | ||
237 | outw(omask, io + IO_MASK); | ||
238 | msleep(125); | ||
202 | return 0; | 239 | return 0; |
203 | } | 240 | } |
204 | case VIDIOCGAUDIO: { | 241 | } case VIDIOCGUNIT: { |
205 | struct video_audio *v = arg; | 242 | struct video_unit *v = arg; |
206 | memset(v,0,sizeof(*v)); | 243 | v->video = VIDEO_NO_UNIT; |
207 | strcpy(v->name, "Radio"); | 244 | v->vbi = VIDEO_NO_UNIT; |
208 | v->flags=VIDEO_AUDIO_MUTABLE | card->muted; | 245 | v->radio = dev->minor; |
209 | v->mode=VIDEO_SOUND_STEREO; | 246 | v->audio = 0; |
210 | return 0; | 247 | v->teletext = VIDEO_NO_UNIT; |
211 | } | 248 | return 0; |
212 | case VIDIOCSAUDIO: { | 249 | } default: |
213 | struct video_audio *v = arg; | 250 | return -ENOIOCTLCMD; |
214 | if(v->audio) | ||
215 | return -EINVAL; | ||
216 | { | ||
217 | register __u16 io=card->io; | ||
218 | register __u16 omask = inw(io + IO_MASK); | ||
219 | outw(~STR_WREN, io + IO_MASK); | ||
220 | outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) | ||
221 | ? STR_WREN : 0, io); | ||
222 | udelay(4); | ||
223 | outw(omask, io + IO_MASK); | ||
224 | msleep(125); | ||
225 | return 0; | ||
226 | } | ||
227 | } | ||
228 | case VIDIOCGUNIT: { | ||
229 | struct video_unit *v = arg; | ||
230 | v->video=VIDEO_NO_UNIT; | ||
231 | v->vbi=VIDEO_NO_UNIT; | ||
232 | v->radio=dev->minor; | ||
233 | v->audio=0; | ||
234 | v->teletext=VIDEO_NO_UNIT; | ||
235 | return 0; | ||
236 | } | ||
237 | default: return -ENOIOCTLCMD; | ||
238 | } | 251 | } |
239 | } | 252 | } |
240 | 253 | ||
241 | static int radio_ioctl(struct inode *inode, struct file *file, | 254 | static int radio_ioctl(struct inode *inode, struct file *file, |
242 | unsigned int cmd, unsigned long arg) | 255 | unsigned int cmd, unsigned long arg) |
243 | { | 256 | { |
244 | struct video_device *dev = video_devdata(file); | 257 | struct video_device *dev = video_devdata(file); |
245 | struct radio_device *card=dev->priv; | 258 | struct radio_device *card = video_get_drvdata(dev); |
246 | int ret; | 259 | int ret; |
247 | 260 | ||
248 | down(&card->lock); | 261 | down(&card->lock); |
249 | ret = video_usercopy(inode, file, cmd, arg, radio_function); | 262 | ret = video_usercopy(inode, file, cmd, arg, radio_function); |
250 | up(&card->lock); | 263 | up(&card->lock); |
251 | return ret; | ||
252 | } | ||
253 | 264 | ||
254 | static __u16 radio_install(struct pci_dev *pcidev); | 265 | return ret; |
255 | |||
256 | MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); | ||
257 | MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); | ||
258 | MODULE_LICENSE("GPL"); | ||
259 | |||
260 | static void __exit maestro_radio_exit(void) | ||
261 | { | ||
262 | video_unregister_device(&maestro_radio); | ||
263 | } | 266 | } |
264 | 267 | ||
265 | static int __init maestro_radio_init(void) | 268 | static u16 __devinit radio_power_on(struct radio_device *dev) |
266 | { | 269 | { |
267 | register __u16 found=0; | 270 | register u16 io = dev->io; |
268 | struct pci_dev *pcidev = NULL; | 271 | register u32 ofreq; |
269 | while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS, | 272 | u16 omask, odir; |
270 | PCI_DEVICE_ID_ESS_ESS1968, | ||
271 | pcidev))) | ||
272 | found |= radio_install(pcidev); | ||
273 | while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS, | ||
274 | PCI_DEVICE_ID_ESS_ESS1978, | ||
275 | pcidev))) | ||
276 | found |= radio_install(pcidev); | ||
277 | if(!found) { | ||
278 | printk(KERN_INFO "radio-maestro: no devices found.\n"); | ||
279 | return -ENODEV; | ||
280 | } | ||
281 | return 0; | ||
282 | } | ||
283 | 273 | ||
284 | module_init(maestro_radio_init); | ||
285 | module_exit(maestro_radio_exit); | ||
286 | |||
287 | static inline __u16 radio_power_on(struct radio_device *dev) | ||
288 | { | ||
289 | register __u16 io=dev->io; | ||
290 | register __u32 ofreq; | ||
291 | __u16 omask, odir; | ||
292 | omask = inw(io + IO_MASK); | 274 | omask = inw(io + IO_MASK); |
293 | odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); | 275 | odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); |
294 | outw(odir & ~STR_WREN, io + IO_DIR); | 276 | outw(odir & ~STR_WREN, io + IO_DIR); |
295 | dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE; | 277 | dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE; |
296 | outw(odir, io + IO_DIR); | 278 | outw(odir, io + IO_DIR); |
@@ -299,35 +281,101 @@ static inline __u16 radio_power_on(struct radio_device *dev) | |||
299 | udelay(16); | 281 | udelay(16); |
300 | outw(omask, io + IO_MASK); | 282 | outw(omask, io + IO_MASK); |
301 | ofreq = radio_bits_get(dev); | 283 | ofreq = radio_bits_get(dev); |
302 | if((ofreq<FREQ2BITS(FREQ_LO)) || (ofreq>FREQ2BITS(FREQ_HI))) | 284 | |
285 | if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI))) | ||
303 | ofreq = FREQ2BITS(FREQ_LO); | 286 | ofreq = FREQ2BITS(FREQ_LO); |
304 | radio_bits_set(dev, ofreq); | 287 | radio_bits_set(dev, ofreq); |
288 | |||
305 | return (ofreq == radio_bits_get(dev)); | 289 | return (ofreq == radio_bits_get(dev)); |
306 | } | 290 | } |
307 | 291 | ||
308 | static __u16 radio_install(struct pci_dev *pcidev) | 292 | static int __devinit maestro_probe(struct pci_dev *pdev, |
293 | const struct pci_device_id *ent) | ||
309 | { | 294 | { |
310 | if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) | 295 | struct radio_device *radio_unit; |
311 | return 0; | 296 | struct video_device *maestro_radio_inst; |
312 | 297 | int retval; | |
313 | radio_unit.io = pcidev->resource[0].start + GPIO_DATA; | 298 | |
314 | maestro_radio.priv = &radio_unit; | 299 | retval = pci_enable_device(pdev); |
315 | init_MUTEX(&radio_unit.lock); | 300 | if (retval) { |
316 | 301 | dev_err(&pdev->dev, "enabling pci device failed!\n"); | |
317 | if(radio_power_on(&radio_unit)) { | 302 | goto err; |
318 | if(video_register_device(&maestro_radio, VFL_TYPE_RADIO, radio_nr)==-1) { | 303 | } |
319 | printk("radio-maestro: can't register device!"); | 304 | |
320 | return 0; | 305 | retval = -ENOMEM; |
321 | } | 306 | |
322 | printk(KERN_INFO "radio-maestro: version " | 307 | radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL); |
323 | DRIVER_VERSION | 308 | if (radio_unit == NULL) { |
324 | " time " | 309 | dev_err(&pdev->dev, "not enough memory\n"); |
325 | __TIME__ " " | 310 | goto err; |
326 | __DATE__ | 311 | } |
327 | "\n"); | 312 | |
328 | printk(KERN_INFO "radio-maestro: radio chip initialized\n"); | 313 | radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; |
329 | return 1; | 314 | init_MUTEX(&radio_unit->lock); |
330 | } else | 315 | |
331 | return 0; | 316 | maestro_radio_inst = video_device_alloc(); |
317 | if (maestro_radio_inst == NULL) { | ||
318 | dev_err(&pdev->dev, "not enough memory\n"); | ||
319 | goto errfr; | ||
320 | } | ||
321 | |||
322 | memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio)); | ||
323 | video_set_drvdata(maestro_radio_inst, radio_unit); | ||
324 | pci_set_drvdata(pdev, maestro_radio_inst); | ||
325 | |||
326 | retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, | ||
327 | radio_nr); | ||
328 | if (retval) { | ||
329 | printk(KERN_ERR "can't register video device!\n"); | ||
330 | goto errfr1; | ||
331 | } | ||
332 | |||
333 | if (!radio_power_on(radio_unit)) { | ||
334 | retval = -EIO; | ||
335 | goto errunr; | ||
336 | } | ||
337 | |||
338 | dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ " " | ||
339 | __DATE__ "\n"); | ||
340 | dev_info(&pdev->dev, "radio chip initialized\n"); | ||
341 | |||
342 | return 0; | ||
343 | errunr: | ||
344 | video_unregister_device(maestro_radio_inst); | ||
345 | errfr1: | ||
346 | kfree(maestro_radio_inst); | ||
347 | errfr: | ||
348 | kfree(radio_unit); | ||
349 | err: | ||
350 | return retval; | ||
351 | |||
352 | } | ||
353 | |||
354 | static void __devexit maestro_remove(struct pci_dev *pdev) | ||
355 | { | ||
356 | struct video_device *vdev = pci_get_drvdata(pdev); | ||
357 | |||
358 | video_unregister_device(vdev); | ||
332 | } | 359 | } |
333 | 360 | ||
361 | static int __init maestro_radio_init(void) | ||
362 | { | ||
363 | int retval = pci_register_driver(&maestro_r_driver); | ||
364 | |||
365 | if (retval) | ||
366 | printk(KERN_ERR "error during registration pci driver\n"); | ||
367 | |||
368 | return retval; | ||
369 | } | ||
370 | |||
371 | static void __exit maestro_radio_exit(void) | ||
372 | { | ||
373 | pci_unregister_driver(&maestro_r_driver); | ||
374 | } | ||
375 | |||
376 | module_init(maestro_radio_init); | ||
377 | module_exit(maestro_radio_exit); | ||
378 | |||
379 | MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); | ||
380 | MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); | ||
381 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 959d2c5951b8..7c340240a50e 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -2585,8 +2585,6 @@ static struct miscdevice mptctl_miscdev = { | |||
2585 | 2585 | ||
2586 | #ifdef CONFIG_COMPAT | 2586 | #ifdef CONFIG_COMPAT |
2587 | 2587 | ||
2588 | #include <linux/ioctl32.h> | ||
2589 | |||
2590 | static int | 2588 | static int |
2591 | compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd, | 2589 | compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd, |
2592 | unsigned long arg) | 2590 | unsigned long arg) |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 9c5945d6df88..201e1362da14 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -43,7 +43,7 @@ static int nand_width = 1; /* default x8*/ | |||
43 | /* | 43 | /* |
44 | * Define partitions for flash device | 44 | * Define partitions for flash device |
45 | */ | 45 | */ |
46 | const static struct mtd_partition partition_info[] = { | 46 | static const struct mtd_partition partition_info[] = { |
47 | { | 47 | { |
48 | .name = "NAND FS 0", | 48 | .name = "NAND FS 0", |
49 | .offset = 0, | 49 | .offset = 0, |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 3a5841c9d950..4129c03dfd90 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -96,7 +96,7 @@ static struct mtd_info *rtc_from4_mtd = NULL; | |||
96 | */ | 96 | */ |
97 | static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); | 97 | static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); |
98 | 98 | ||
99 | const static struct mtd_partition partition_info[] = { | 99 | static const struct mtd_partition partition_info[] = { |
100 | { | 100 | { |
101 | .name = "Renesas flash partition 1", | 101 | .name = "Renesas flash partition 1", |
102 | .offset = 0, | 102 | .offset = 0, |
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c index 32541cbb0103..9cf1ce718ec1 100644 --- a/drivers/mtd/nand/spia.c +++ b/drivers/mtd/nand/spia.c | |||
@@ -67,7 +67,7 @@ module_param(spia_peddr, int, 0); | |||
67 | /* | 67 | /* |
68 | * Define partitions for flash device | 68 | * Define partitions for flash device |
69 | */ | 69 | */ |
70 | const static struct mtd_partition partition_info[] = { | 70 | static const struct mtd_partition partition_info[] = { |
71 | { | 71 | { |
72 | .name = "SPIA flash partition 1", | 72 | .name = "SPIA flash partition 1", |
73 | .offset = 0, | 73 | .offset = 0, |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index d2102a27d307..adfba44dac5a 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -505,7 +505,7 @@ enum chip_flags { | |||
505 | #define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1) | 505 | #define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1) |
506 | 506 | ||
507 | /* directly indexed by chip_t, above */ | 507 | /* directly indexed by chip_t, above */ |
508 | const static struct { | 508 | static const struct { |
509 | const char *name; | 509 | const char *name; |
510 | u32 version; /* from RTL8139C/RTL8139D docs */ | 510 | u32 version; /* from RTL8139C/RTL8139D docs */ |
511 | u32 flags; | 511 | u32 flags; |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 90999867a32c..102c1f0b90da 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -456,11 +456,6 @@ out: | |||
456 | 456 | ||
457 | /* ----------------------------------------------------------------------- */ | 457 | /* ----------------------------------------------------------------------- */ |
458 | 458 | ||
459 | static int sixpack_receive_room(struct tty_struct *tty) | ||
460 | { | ||
461 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
462 | } | ||
463 | |||
464 | /* | 459 | /* |
465 | * Handle the 'receiver data ready' interrupt. | 460 | * Handle the 'receiver data ready' interrupt. |
466 | * This function is called by the 'tty_io' module in the kernel when | 461 | * This function is called by the 'tty_io' module in the kernel when |
@@ -671,6 +666,7 @@ static int sixpack_open(struct tty_struct *tty) | |||
671 | 666 | ||
672 | /* Done. We have linked the TTY line to a channel. */ | 667 | /* Done. We have linked the TTY line to a channel. */ |
673 | tty->disc_data = sp; | 668 | tty->disc_data = sp; |
669 | tty->receive_room = 65536; | ||
674 | 670 | ||
675 | /* Now we're ready to register. */ | 671 | /* Now we're ready to register. */ |
676 | if (register_netdev(dev)) | 672 | if (register_netdev(dev)) |
@@ -802,7 +798,6 @@ static struct tty_ldisc sp_ldisc = { | |||
802 | .close = sixpack_close, | 798 | .close = sixpack_close, |
803 | .ioctl = sixpack_ioctl, | 799 | .ioctl = sixpack_ioctl, |
804 | .receive_buf = sixpack_receive_buf, | 800 | .receive_buf = sixpack_receive_buf, |
805 | .receive_room = sixpack_receive_room, | ||
806 | .write_wakeup = sixpack_write_wakeup, | 801 | .write_wakeup = sixpack_write_wakeup, |
807 | }; | 802 | }; |
808 | 803 | ||
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index f4424cf886c5..dc5e9d59deed 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -753,6 +753,7 @@ static int mkiss_open(struct tty_struct *tty) | |||
753 | 753 | ||
754 | ax->tty = tty; | 754 | ax->tty = tty; |
755 | tty->disc_data = ax; | 755 | tty->disc_data = ax; |
756 | tty->receive_room = 65535; | ||
756 | 757 | ||
757 | if (tty->driver->flush_buffer) | 758 | if (tty->driver->flush_buffer) |
758 | tty->driver->flush_buffer(tty); | 759 | tty->driver->flush_buffer(tty); |
@@ -940,11 +941,6 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
940 | tty->driver->unthrottle(tty); | 941 | tty->driver->unthrottle(tty); |
941 | } | 942 | } |
942 | 943 | ||
943 | static int mkiss_receive_room(struct tty_struct *tty) | ||
944 | { | ||
945 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
946 | } | ||
947 | |||
948 | /* | 944 | /* |
949 | * Called by the driver when there's room for more data. If we have | 945 | * Called by the driver when there's room for more data. If we have |
950 | * more packets to send, we send them here. | 946 | * more packets to send, we send them here. |
@@ -983,7 +979,6 @@ static struct tty_ldisc ax_ldisc = { | |||
983 | .close = mkiss_close, | 979 | .close = mkiss_close, |
984 | .ioctl = mkiss_ioctl, | 980 | .ioctl = mkiss_ioctl, |
985 | .receive_buf = mkiss_receive_buf, | 981 | .receive_buf = mkiss_receive_buf, |
986 | .receive_room = mkiss_receive_room, | ||
987 | .write_wakeup = mkiss_write_wakeup | 982 | .write_wakeup = mkiss_write_wakeup |
988 | }; | 983 | }; |
989 | 984 | ||
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 3d016a498e1d..6070195b87bd 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c | |||
@@ -285,19 +285,6 @@ static void irport_start(struct irport_cb *self) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * Function irport_probe (void) | ||
289 | * | ||
290 | * Start IO port | ||
291 | * | ||
292 | */ | ||
293 | int irport_probe(int iobase) | ||
294 | { | ||
295 | IRDA_DEBUG(4, "%s(), iobase=%#x\n", __FUNCTION__, iobase); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * Function irport_get_fcr (speed) | 288 | * Function irport_get_fcr (speed) |
302 | * | 289 | * |
303 | * Compute value of fcr | 290 | * Compute value of fcr |
@@ -382,7 +369,7 @@ static void irport_change_speed(void *priv, __u32 speed) | |||
382 | * we cannot use schedule_timeout() when we are in interrupt context | 369 | * we cannot use schedule_timeout() when we are in interrupt context |
383 | * | 370 | * |
384 | */ | 371 | */ |
385 | int __irport_change_speed(struct irda_task *task) | 372 | static int __irport_change_speed(struct irda_task *task) |
386 | { | 373 | { |
387 | struct irport_cb *self; | 374 | struct irport_cb *self; |
388 | __u32 speed = (__u32) task->param; | 375 | __u32 speed = (__u32) task->param; |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index b8d112348ba4..101750bf210f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -289,22 +289,6 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * Function irtty_receive_room (tty) | ||
293 | * | ||
294 | * Used by the TTY to find out how much data we can receive at a time | ||
295 | * | ||
296 | */ | ||
297 | static int irtty_receive_room(struct tty_struct *tty) | ||
298 | { | ||
299 | struct sirtty_cb *priv = tty->disc_data; | ||
300 | |||
301 | IRDA_ASSERT(priv != NULL, return 0;); | ||
302 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return 0;); | ||
303 | |||
304 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Function irtty_write_wakeup (tty) | 292 | * Function irtty_write_wakeup (tty) |
309 | * | 293 | * |
310 | * Called by the driver when there's room for more data. If we have | 294 | * Called by the driver when there's room for more data. If we have |
@@ -534,6 +518,7 @@ static int irtty_open(struct tty_struct *tty) | |||
534 | 518 | ||
535 | dev->priv = priv; | 519 | dev->priv = priv; |
536 | tty->disc_data = priv; | 520 | tty->disc_data = priv; |
521 | tty->receive_room = 65536; | ||
537 | 522 | ||
538 | up(&irtty_sem); | 523 | up(&irtty_sem); |
539 | 524 | ||
@@ -605,7 +590,6 @@ static struct tty_ldisc irda_ldisc = { | |||
605 | .ioctl = irtty_ioctl, | 590 | .ioctl = irtty_ioctl, |
606 | .poll = NULL, | 591 | .poll = NULL, |
607 | .receive_buf = irtty_receive_buf, | 592 | .receive_buf = irtty_receive_buf, |
608 | .receive_room = irtty_receive_room, | ||
609 | .write_wakeup = irtty_write_wakeup, | 593 | .write_wakeup = irtty_write_wakeup, |
610 | .owner = THIS_MODULE, | 594 | .owner = THIS_MODULE, |
611 | }; | 595 | }; |
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index a1ac4bd1696e..a7bb54df75a8 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c | |||
@@ -415,7 +415,7 @@ typedef enum { | |||
415 | 415 | ||
416 | 416 | ||
417 | /* directly indexed by chip_t, above */ | 417 | /* directly indexed by chip_t, above */ |
418 | const static struct { | 418 | static const struct { |
419 | const char *name; | 419 | const char *name; |
420 | u8 version; /* from RTL8139C docs */ | 420 | u8 version; /* from RTL8139C docs */ |
421 | u32 RxConfigMask; /* should clear the bits supported by this chip */ | 421 | u32 RxConfigMask; /* should clear the bits supported by this chip */ |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 400f652282d7..aa6540b39466 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -189,7 +189,7 @@ ppp_asynctty_open(struct tty_struct *tty) | |||
189 | goto out_free; | 189 | goto out_free; |
190 | 190 | ||
191 | tty->disc_data = ap; | 191 | tty->disc_data = ap; |
192 | 192 | tty->receive_room = 65536; | |
193 | return 0; | 193 | return 0; |
194 | 194 | ||
195 | out_free: | 195 | out_free: |
@@ -343,12 +343,6 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
343 | return 0; | 343 | return 0; |
344 | } | 344 | } |
345 | 345 | ||
346 | static int | ||
347 | ppp_asynctty_room(struct tty_struct *tty) | ||
348 | { | ||
349 | return 65535; | ||
350 | } | ||
351 | |||
352 | /* | 346 | /* |
353 | * This can now be called from hard interrupt level as well | 347 | * This can now be called from hard interrupt level as well |
354 | * as soft interrupt level or mainline. | 348 | * as soft interrupt level or mainline. |
@@ -398,7 +392,6 @@ static struct tty_ldisc ppp_ldisc = { | |||
398 | .write = ppp_asynctty_write, | 392 | .write = ppp_asynctty_write, |
399 | .ioctl = ppp_asynctty_ioctl, | 393 | .ioctl = ppp_asynctty_ioctl, |
400 | .poll = ppp_asynctty_poll, | 394 | .poll = ppp_asynctty_poll, |
401 | .receive_room = ppp_asynctty_room, | ||
402 | .receive_buf = ppp_asynctty_receive, | 395 | .receive_buf = ppp_asynctty_receive, |
403 | .write_wakeup = ppp_asynctty_wakeup, | 396 | .write_wakeup = ppp_asynctty_wakeup, |
404 | }; | 397 | }; |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 4d51c0c8023d..33cb8254e79d 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -237,7 +237,7 @@ ppp_sync_open(struct tty_struct *tty) | |||
237 | goto out_free; | 237 | goto out_free; |
238 | 238 | ||
239 | tty->disc_data = ap; | 239 | tty->disc_data = ap; |
240 | 240 | tty->receive_room = 65536; | |
241 | return 0; | 241 | return 0; |
242 | 242 | ||
243 | out_free: | 243 | out_free: |
@@ -384,12 +384,6 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
387 | static int | ||
388 | ppp_sync_room(struct tty_struct *tty) | ||
389 | { | ||
390 | return 65535; | ||
391 | } | ||
392 | |||
393 | /* | 387 | /* |
394 | * This can now be called from hard interrupt level as well | 388 | * This can now be called from hard interrupt level as well |
395 | * as soft interrupt level or mainline. | 389 | * as soft interrupt level or mainline. |
@@ -439,7 +433,6 @@ static struct tty_ldisc ppp_sync_ldisc = { | |||
439 | .write = ppp_sync_write, | 433 | .write = ppp_sync_write, |
440 | .ioctl = ppp_synctty_ioctl, | 434 | .ioctl = ppp_synctty_ioctl, |
441 | .poll = ppp_sync_poll, | 435 | .poll = ppp_sync_poll, |
442 | .receive_room = ppp_sync_room, | ||
443 | .receive_buf = ppp_sync_receive, | 436 | .receive_buf = ppp_sync_receive, |
444 | .write_wakeup = ppp_sync_wakeup, | 437 | .write_wakeup = ppp_sync_wakeup, |
445 | }; | 438 | }; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 14a76f7cf900..2e1bed153c39 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -170,7 +170,7 @@ enum phy_version { | |||
170 | #define _R(NAME,MAC,MASK) \ | 170 | #define _R(NAME,MAC,MASK) \ |
171 | { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } | 171 | { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } |
172 | 172 | ||
173 | const static struct { | 173 | static const struct { |
174 | const char *name; | 174 | const char *name; |
175 | u8 mac_version; | 175 | u8 mac_version; |
176 | u32 RxConfigMask; /* Clears the bits supported by this chip */ | 176 | u32 RxConfigMask; /* Clears the bits supported by this chip */ |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 478791e09bf7..b420182eec4b 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -329,7 +329,7 @@ static struct mii_chip_info { | |||
329 | { NULL, } | 329 | { NULL, } |
330 | }; | 330 | }; |
331 | 331 | ||
332 | const static struct { | 332 | static const struct { |
333 | const char *name; | 333 | const char *name; |
334 | } sis_chip_info[] = { | 334 | } sis_chip_info[] = { |
335 | { "SiS 190 PCI Fast Ethernet adapter" }, | 335 | { "SiS 190 PCI Fast Ethernet adapter" }, |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 404ea4297e32..b2e18d28850d 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -651,11 +651,6 @@ static void sl_setup(struct net_device *dev) | |||
651 | ******************************************/ | 651 | ******************************************/ |
652 | 652 | ||
653 | 653 | ||
654 | static int slip_receive_room(struct tty_struct *tty) | ||
655 | { | ||
656 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
657 | } | ||
658 | |||
659 | /* | 654 | /* |
660 | * Handle the 'receiver data ready' interrupt. | 655 | * Handle the 'receiver data ready' interrupt. |
661 | * This function is called by the 'tty_io' module in the kernel when | 656 | * This function is called by the 'tty_io' module in the kernel when |
@@ -869,10 +864,6 @@ static int slip_open(struct tty_struct *tty) | |||
869 | sl->line = tty_devnum(tty); | 864 | sl->line = tty_devnum(tty); |
870 | sl->pid = current->pid; | 865 | sl->pid = current->pid; |
871 | 866 | ||
872 | /* FIXME: already done before we were called - seems this can go */ | ||
873 | if (tty->driver->flush_buffer) | ||
874 | tty->driver->flush_buffer(tty); | ||
875 | |||
876 | if (!test_bit(SLF_INUSE, &sl->flags)) { | 867 | if (!test_bit(SLF_INUSE, &sl->flags)) { |
877 | /* Perform the low-level SLIP initialization. */ | 868 | /* Perform the low-level SLIP initialization. */ |
878 | if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) | 869 | if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) |
@@ -897,6 +888,7 @@ static int slip_open(struct tty_struct *tty) | |||
897 | 888 | ||
898 | /* Done. We have linked the TTY line to a channel. */ | 889 | /* Done. We have linked the TTY line to a channel. */ |
899 | rtnl_unlock(); | 890 | rtnl_unlock(); |
891 | tty->receive_room = 65536; /* We don't flow control */ | ||
900 | return sl->dev->base_addr; | 892 | return sl->dev->base_addr; |
901 | 893 | ||
902 | err_free_bufs: | 894 | err_free_bufs: |
@@ -1329,7 +1321,6 @@ static struct tty_ldisc sl_ldisc = { | |||
1329 | .close = slip_close, | 1321 | .close = slip_close, |
1330 | .ioctl = slip_ioctl, | 1322 | .ioctl = slip_ioctl, |
1331 | .receive_buf = slip_receive_buf, | 1323 | .receive_buf = slip_receive_buf, |
1332 | .receive_room = slip_receive_room, | ||
1333 | .write_wakeup = slip_write_wakeup, | 1324 | .write_wakeup = slip_write_wakeup, |
1334 | }; | 1325 | }; |
1335 | 1326 | ||
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 52f26b9c69d2..931cbdf6d791 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c | |||
@@ -689,7 +689,7 @@ static void cpc_tty_rx_work(void * data) | |||
689 | } | 689 | } |
690 | } | 690 | } |
691 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; | 691 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; |
692 | kfree(buf); | 692 | kfree((void *)buf); |
693 | buf = cpc_tty->buf_rx.first; | 693 | buf = cpc_tty->buf_rx.first; |
694 | flg_rx = 1; | 694 | flg_rx = 1; |
695 | } | 695 | } |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index bdf672c48182..9c3ccc669143 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -515,11 +515,6 @@ static int x25_asy_close(struct net_device *dev) | |||
515 | return 0; | 515 | return 0; |
516 | } | 516 | } |
517 | 517 | ||
518 | static int x25_asy_receive_room(struct tty_struct *tty) | ||
519 | { | ||
520 | return 65536; /* We can handle an infinite amount of data. :-) */ | ||
521 | } | ||
522 | |||
523 | /* | 518 | /* |
524 | * Handle the 'receiver data ready' interrupt. | 519 | * Handle the 'receiver data ready' interrupt. |
525 | * This function is called by the 'tty_io' module in the kernel when | 520 | * This function is called by the 'tty_io' module in the kernel when |
@@ -573,6 +568,7 @@ static int x25_asy_open_tty(struct tty_struct *tty) | |||
573 | 568 | ||
574 | sl->tty = tty; | 569 | sl->tty = tty; |
575 | tty->disc_data = sl; | 570 | tty->disc_data = sl; |
571 | tty->receive_room = 65536; | ||
576 | if (tty->driver->flush_buffer) { | 572 | if (tty->driver->flush_buffer) { |
577 | tty->driver->flush_buffer(tty); | 573 | tty->driver->flush_buffer(tty); |
578 | } | 574 | } |
@@ -779,7 +775,6 @@ static struct tty_ldisc x25_ldisc = { | |||
779 | .close = x25_asy_close_tty, | 775 | .close = x25_asy_close_tty, |
780 | .ioctl = x25_asy_ioctl, | 776 | .ioctl = x25_asy_ioctl, |
781 | .receive_buf = x25_asy_receive_buf, | 777 | .receive_buf = x25_asy_receive_buf, |
782 | .receive_room = x25_asy_receive_room, | ||
783 | .write_wakeup = x25_asy_write_wakeup, | 778 | .write_wakeup = x25_asy_write_wakeup, |
784 | }; | 779 | }; |
785 | 780 | ||
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index d25264ba0c0e..18baacfc5a2c 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -1675,11 +1675,6 @@ static int strip_rebuild_header(struct sk_buff *skb) | |||
1675 | /************************************************************************/ | 1675 | /************************************************************************/ |
1676 | /* Receiving routines */ | 1676 | /* Receiving routines */ |
1677 | 1677 | ||
1678 | static int strip_receive_room(struct tty_struct *tty) | ||
1679 | { | ||
1680 | return 0x10000; /* We can handle an infinite amount of data. :-) */ | ||
1681 | } | ||
1682 | |||
1683 | /* | 1678 | /* |
1684 | * This function parses the response to the ATS300? command, | 1679 | * This function parses the response to the ATS300? command, |
1685 | * extracting the radio version and serial number. | 1680 | * extracting the radio version and serial number. |
@@ -2424,7 +2419,7 @@ static struct net_device_stats *strip_get_stats(struct net_device *dev) | |||
2424 | /* | 2419 | /* |
2425 | * Here's the order things happen: | 2420 | * Here's the order things happen: |
2426 | * When the user runs "slattach -p strip ..." | 2421 | * When the user runs "slattach -p strip ..." |
2427 | * 1. The TTY module calls strip_open | 2422 | * 1. The TTY module calls strip_open;; |
2428 | * 2. strip_open calls strip_alloc | 2423 | * 2. strip_open calls strip_alloc |
2429 | * 3. strip_alloc calls register_netdev | 2424 | * 3. strip_alloc calls register_netdev |
2430 | * 4. register_netdev calls strip_dev_init | 2425 | * 4. register_netdev calls strip_dev_init |
@@ -2652,6 +2647,8 @@ static int strip_open(struct tty_struct *tty) | |||
2652 | 2647 | ||
2653 | strip_info->tty = tty; | 2648 | strip_info->tty = tty; |
2654 | tty->disc_data = strip_info; | 2649 | tty->disc_data = strip_info; |
2650 | tty->receive_room = 65536; | ||
2651 | |||
2655 | if (tty->driver->flush_buffer) | 2652 | if (tty->driver->flush_buffer) |
2656 | tty->driver->flush_buffer(tty); | 2653 | tty->driver->flush_buffer(tty); |
2657 | 2654 | ||
@@ -2762,7 +2759,6 @@ static struct tty_ldisc strip_ldisc = { | |||
2762 | .close = strip_close, | 2759 | .close = strip_close, |
2763 | .ioctl = strip_ioctl, | 2760 | .ioctl = strip_ioctl, |
2764 | .receive_buf = strip_receive_buf, | 2761 | .receive_buf = strip_receive_buf, |
2765 | .receive_room = strip_receive_room, | ||
2766 | .write_wakeup = strip_write_some_more, | 2762 | .write_wakeup = strip_write_some_more, |
2767 | }; | 2763 | }; |
2768 | 2764 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 2472fa1a1be1..9c25654b1e75 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1751,6 +1751,7 @@ dasd_device_operations = { | |||
1751 | .open = dasd_open, | 1751 | .open = dasd_open, |
1752 | .release = dasd_release, | 1752 | .release = dasd_release, |
1753 | .ioctl = dasd_ioctl, | 1753 | .ioctl = dasd_ioctl, |
1754 | .compat_ioctl = dasd_compat_ioctl, | ||
1754 | .getgeo = dasd_getgeo, | 1755 | .getgeo = dasd_getgeo, |
1755 | }; | 1756 | }; |
1756 | 1757 | ||
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 2fb05c4a528c..e4b401500b01 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -527,6 +527,7 @@ void dasd_ioctl_exit(void); | |||
527 | int dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t); | 527 | int dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t); |
528 | int dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t); | 528 | int dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t); |
529 | int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 529 | int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
530 | long dasd_compat_ioctl(struct file *, unsigned int, unsigned long); | ||
530 | 531 | ||
531 | /* externals in dasd_proc.c */ | 532 | /* externals in dasd_proc.c */ |
532 | int dasd_proc_init(void); | 533 | int dasd_proc_init(void); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 8e4dcd58599e..9396fcacb8f8 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -118,6 +118,18 @@ dasd_ioctl(struct inode *inp, struct file *filp, | |||
118 | return -EINVAL; | 118 | return -EINVAL; |
119 | } | 119 | } |
120 | 120 | ||
121 | long | ||
122 | dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
123 | { | ||
124 | int rval; | ||
125 | |||
126 | lock_kernel(); | ||
127 | rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | ||
128 | unlock_kernel(); | ||
129 | |||
130 | return (rval == -EINVAL) ? -ENOIOCTLCMD : rval; | ||
131 | } | ||
132 | |||
121 | static int | 133 | static int |
122 | dasd_ioctl_api_version(struct block_device *bdev, int no, long args) | 134 | dasd_ioctl_api_version(struct block_device *bdev, int no, long args) |
123 | { | 135 | { |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 75419cf9d353..1f060914cfa4 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/kdev_t.h> | 17 | #include <linux/kdev_t.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/tty_flip.h> | ||
19 | #include <linux/vt_kern.h> | 20 | #include <linux/vt_kern.h> |
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/console.h> | 22 | #include <linux/console.h> |
@@ -432,8 +433,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
432 | if (count > slen) | 433 | if (count > slen) |
433 | count = slen; | 434 | count = slen; |
434 | } else | 435 | } else |
435 | if (count >= TTY_FLIPBUF_SIZE - tty->flip.count) | ||
436 | count = TTY_FLIPBUF_SIZE - tty->flip.count - 1; | ||
437 | EBCASC(raw->inbuf, count); | 436 | EBCASC(raw->inbuf, count); |
438 | cchar = ctrlchar_handle(raw->inbuf, count, tty); | 437 | cchar = ctrlchar_handle(raw->inbuf, count, tty); |
439 | switch (cchar & CTRLCHAR_MASK) { | 438 | switch (cchar & CTRLCHAR_MASK) { |
@@ -441,28 +440,20 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
441 | break; | 440 | break; |
442 | 441 | ||
443 | case CTRLCHAR_CTRL: | 442 | case CTRLCHAR_CTRL: |
444 | tty->flip.count++; | 443 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); |
445 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
446 | *tty->flip.char_buf_ptr++ = cchar; | ||
447 | tty_flip_buffer_push(raw->tty); | 444 | tty_flip_buffer_push(raw->tty); |
448 | break; | 445 | break; |
449 | 446 | ||
450 | case CTRLCHAR_NONE: | 447 | case CTRLCHAR_NONE: |
451 | memcpy(tty->flip.char_buf_ptr, | ||
452 | raw->inbuf, count); | ||
453 | if (count < 2 || | 448 | if (count < 2 || |
454 | (strncmp(raw->inbuf+count-2, "^n", 2) && | 449 | (strncmp(raw->inbuf+count-2, "\252n", 2) && |
455 | strncmp(raw->inbuf+count-2, "\252n", 2)) ) { | 450 | strncmp(raw->inbuf+count-2, "^n", 2)) ) { |
456 | /* don't add the auto \n */ | 451 | /* add the auto \n */ |
457 | tty->flip.char_buf_ptr[count] = '\n'; | 452 | raw->inbuf[count] = '\n'; |
458 | memset(tty->flip.flag_buf_ptr, | ||
459 | TTY_NORMAL, count + 1); | ||
460 | count++; | 453 | count++; |
461 | } else | 454 | } else |
462 | count-=2; | 455 | count -= 2; |
463 | tty->flip.char_buf_ptr += count; | 456 | tty_insert_flip_string(tty, raw->inbuf, count); |
464 | tty->flip.flag_buf_ptr += count; | ||
465 | tty->flip.count += count; | ||
466 | tty_flip_buffer_push(raw->tty); | 457 | tty_flip_buffer_push(raw->tty); |
467 | break; | 458 | break; |
468 | } | 459 | } |
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 735a7fcdeff5..5f6fa4c67843 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -319,9 +319,8 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off) | |||
319 | /* | 319 | /* |
320 | * process ioctl commands for the tube driver | 320 | * process ioctl commands for the tube driver |
321 | */ | 321 | */ |
322 | static int | 322 | static long |
323 | fs3270_ioctl(struct inode *inode, struct file *filp, | 323 | fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
324 | unsigned int cmd, unsigned long arg) | ||
325 | { | 324 | { |
326 | struct fs3270 *fp; | 325 | struct fs3270 *fp; |
327 | struct raw3270_iocb iocb; | 326 | struct raw3270_iocb iocb; |
@@ -331,6 +330,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp, | |||
331 | if (!fp) | 330 | if (!fp) |
332 | return -ENODEV; | 331 | return -ENODEV; |
333 | rc = 0; | 332 | rc = 0; |
333 | lock_kernel(); | ||
334 | switch (cmd) { | 334 | switch (cmd) { |
335 | case TUBICMD: | 335 | case TUBICMD: |
336 | fp->read_command = arg; | 336 | fp->read_command = arg; |
@@ -356,6 +356,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp, | |||
356 | rc = -EFAULT; | 356 | rc = -EFAULT; |
357 | break; | 357 | break; |
358 | } | 358 | } |
359 | unlock_kernel(); | ||
359 | return rc; | 360 | return rc; |
360 | } | 361 | } |
361 | 362 | ||
@@ -491,12 +492,13 @@ fs3270_close(struct inode *inode, struct file *filp) | |||
491 | } | 492 | } |
492 | 493 | ||
493 | static struct file_operations fs3270_fops = { | 494 | static struct file_operations fs3270_fops = { |
494 | .owner = THIS_MODULE, /* owner */ | 495 | .owner = THIS_MODULE, /* owner */ |
495 | .read = fs3270_read, /* read */ | 496 | .read = fs3270_read, /* read */ |
496 | .write = fs3270_write, /* write */ | 497 | .write = fs3270_write, /* write */ |
497 | .ioctl = fs3270_ioctl, /* ioctl */ | 498 | .unlocked_ioctl = fs3270_ioctl, /* ioctl */ |
498 | .open = fs3270_open, /* open */ | 499 | .compat_ioctl = fs3270_ioctl, /* ioctl */ |
499 | .release = fs3270_close, /* release */ | 500 | .open = fs3270_open, /* open */ |
501 | .release = fs3270_close, /* release */ | ||
500 | }; | 502 | }; |
501 | 503 | ||
502 | /* | 504 | /* |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index a20d7c89341d..6cbf067f1a8f 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kmod.h> | 13 | #include <linux/kmod.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/tty_driver.h> | 15 | #include <linux/tty_driver.h> |
16 | #include <linux/tty_flip.h> | ||
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
17 | #include <linux/wait.h> | 18 | #include <linux/wait.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -496,25 +497,19 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
496 | case CTRLCHAR_SYSRQ: | 497 | case CTRLCHAR_SYSRQ: |
497 | break; | 498 | break; |
498 | case CTRLCHAR_CTRL: | 499 | case CTRLCHAR_CTRL: |
499 | sclp_tty->flip.count++; | 500 | tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL); |
500 | *sclp_tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
501 | *sclp_tty->flip.char_buf_ptr++ = cchar; | ||
502 | tty_flip_buffer_push(sclp_tty); | 501 | tty_flip_buffer_push(sclp_tty); |
503 | break; | 502 | break; |
504 | case CTRLCHAR_NONE: | 503 | case CTRLCHAR_NONE: |
505 | /* send (normal) input to line discipline */ | 504 | /* send (normal) input to line discipline */ |
506 | memcpy(sclp_tty->flip.char_buf_ptr, buf, count); | ||
507 | if (count < 2 || | 505 | if (count < 2 || |
508 | (strncmp ((const char *) buf + count - 2, "^n", 2) && | 506 | (strncmp((const char *) buf + count - 2, "^n", 2) && |
509 | strncmp ((const char *) buf + count - 2, "\0252n", 2))) { | 507 | strncmp((const char *) buf + count - 2, "\252n", 2))) { |
510 | sclp_tty->flip.char_buf_ptr[count] = '\n'; | 508 | /* add the auto \n */ |
511 | count++; | 509 | tty_insert_flip_string(sclp_tty, buf, count); |
510 | tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL); | ||
512 | } else | 511 | } else |
513 | count -= 2; | 512 | tty_insert_flip_string(sclp_tty, buf, count - 2); |
514 | memset(sclp_tty->flip.flag_buf_ptr, TTY_NORMAL, count); | ||
515 | sclp_tty->flip.char_buf_ptr += count; | ||
516 | sclp_tty->flip.flag_buf_ptr += count; | ||
517 | sclp_tty->flip.count += count; | ||
518 | tty_flip_buffer_push(sclp_tty); | 513 | tty_flip_buffer_push(sclp_tty); |
519 | break; | 514 | break; |
520 | } | 515 | } |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 06bd85824d7b..9e02625c82cf 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
18 | #include <linux/tty_driver.h> | 18 | #include <linux/tty_driver.h> |
19 | #include <linux/tty_flip.h> | ||
19 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
@@ -482,16 +483,7 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | |||
482 | /* Send input to line discipline */ | 483 | /* Send input to line discipline */ |
483 | buffer++; | 484 | buffer++; |
484 | count--; | 485 | count--; |
485 | /* Prevent buffer overrun by discarding input. Note that | 486 | tty_insert_flip_string(sclp_vt220_tty, buffer, count); |
486 | * because buffer_push works asynchronously, we cannot wait | ||
487 | * for the buffer to be emptied. */ | ||
488 | if (count + sclp_vt220_tty->flip.count > TTY_FLIPBUF_SIZE) | ||
489 | count = TTY_FLIPBUF_SIZE - sclp_vt220_tty->flip.count; | ||
490 | memcpy(sclp_vt220_tty->flip.char_buf_ptr, buffer, count); | ||
491 | memset(sclp_vt220_tty->flip.flag_buf_ptr, TTY_NORMAL, count); | ||
492 | sclp_vt220_tty->flip.char_buf_ptr += count; | ||
493 | sclp_vt220_tty->flip.flag_buf_ptr += count; | ||
494 | sclp_vt220_tty->flip.count += count; | ||
495 | tty_flip_buffer_push(sclp_vt220_tty); | 487 | tty_flip_buffer_push(sclp_vt220_tty); |
496 | break; | 488 | break; |
497 | } | 489 | } |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 86262a13f7c6..5ce7ca38ace0 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -37,6 +37,8 @@ static int tapechar_open(struct inode *,struct file *); | |||
37 | static int tapechar_release(struct inode *,struct file *); | 37 | static int tapechar_release(struct inode *,struct file *); |
38 | static int tapechar_ioctl(struct inode *, struct file *, unsigned int, | 38 | static int tapechar_ioctl(struct inode *, struct file *, unsigned int, |
39 | unsigned long); | 39 | unsigned long); |
40 | static long tapechar_compat_ioctl(struct file *, unsigned int, | ||
41 | unsigned long); | ||
40 | 42 | ||
41 | static struct file_operations tape_fops = | 43 | static struct file_operations tape_fops = |
42 | { | 44 | { |
@@ -44,6 +46,7 @@ static struct file_operations tape_fops = | |||
44 | .read = tapechar_read, | 46 | .read = tapechar_read, |
45 | .write = tapechar_write, | 47 | .write = tapechar_write, |
46 | .ioctl = tapechar_ioctl, | 48 | .ioctl = tapechar_ioctl, |
49 | .compat_ioctl = tapechar_compat_ioctl, | ||
47 | .open = tapechar_open, | 50 | .open = tapechar_open, |
48 | .release = tapechar_release, | 51 | .release = tapechar_release, |
49 | }; | 52 | }; |
@@ -463,6 +466,23 @@ tapechar_ioctl(struct inode *inp, struct file *filp, | |||
463 | return device->discipline->ioctl_fn(device, no, data); | 466 | return device->discipline->ioctl_fn(device, no, data); |
464 | } | 467 | } |
465 | 468 | ||
469 | static long | ||
470 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | ||
471 | { | ||
472 | struct tape_device *device = filp->private_data; | ||
473 | int rval = -ENOIOCTLCMD; | ||
474 | |||
475 | if (device->discipline->ioctl_fn) { | ||
476 | lock_kernel(); | ||
477 | rval = device->discipline->ioctl_fn(device, no, data); | ||
478 | unlock_kernel(); | ||
479 | if (rval == -EINVAL) | ||
480 | rval = -ENOIOCTLCMD; | ||
481 | } | ||
482 | |||
483 | return rval; | ||
484 | } | ||
485 | |||
466 | /* | 486 | /* |
467 | * Initialize character device frontend. | 487 | * Initialize character device frontend. |
468 | */ | 488 | */ |
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index 135ae04e6e75..2f54d033d7cf 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> // mdelay | 30 | #include <linux/delay.h> // mdelay |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/interrupt.h> // for tasklets | 32 | #include <linux/interrupt.h> // for tasklets |
33 | #include <linux/ioctl32.h> | ||
34 | #include <linux/miscdevice.h> | 33 | #include <linux/miscdevice.h> |
35 | #include <linux/module.h> | 34 | #include <linux/module.h> |
36 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c index 968f2c113efe..93d1725eb79b 100644 --- a/drivers/s390/net/ctctty.c +++ b/drivers/s390/net/ctctty.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
28 | #include <linux/tty_flip.h> | ||
28 | #include <linux/serial_reg.h> | 29 | #include <linux/serial_reg.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
@@ -101,25 +102,17 @@ static spinlock_t ctc_tty_lock; | |||
101 | static int | 102 | static int |
102 | ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) | 103 | ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) |
103 | { | 104 | { |
104 | int c; | ||
105 | int len; | 105 | int len; |
106 | struct tty_struct *tty; | 106 | struct tty_struct *tty; |
107 | 107 | ||
108 | DBF_TEXT(trace, 5, __FUNCTION__); | 108 | DBF_TEXT(trace, 5, __FUNCTION__); |
109 | if ((tty = info->tty)) { | 109 | if ((tty = info->tty)) { |
110 | if (info->mcr & UART_MCR_RTS) { | 110 | if (info->mcr & UART_MCR_RTS) { |
111 | c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
112 | len = skb->len; | 111 | len = skb->len; |
113 | if (c >= len) { | 112 | tty_insert_flip_string(tty, skb->data, len); |
114 | memcpy(tty->flip.char_buf_ptr, skb->data, len); | 113 | tty_flip_buffer_push(tty); |
115 | memset(tty->flip.flag_buf_ptr, 0, len); | 114 | kfree_skb(skb); |
116 | tty->flip.count += len; | 115 | return 1; |
117 | tty->flip.char_buf_ptr += len; | ||
118 | tty->flip.flag_buf_ptr += len; | ||
119 | tty_flip_buffer_push(tty); | ||
120 | kfree_skb(skb); | ||
121 | return 1; | ||
122 | } | ||
123 | } | 116 | } |
124 | } | 117 | } |
125 | return 0; | 118 | return 0; |
@@ -138,19 +131,12 @@ ctc_tty_readmodem(ctc_tty_info *info) | |||
138 | DBF_TEXT(trace, 5, __FUNCTION__); | 131 | DBF_TEXT(trace, 5, __FUNCTION__); |
139 | if ((tty = info->tty)) { | 132 | if ((tty = info->tty)) { |
140 | if (info->mcr & UART_MCR_RTS) { | 133 | if (info->mcr & UART_MCR_RTS) { |
141 | int c = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
142 | struct sk_buff *skb; | 134 | struct sk_buff *skb; |
143 | 135 | ||
144 | if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) { | 136 | if ((skb = skb_dequeue(&info->rx_queue))) { |
145 | int len = skb->len; | 137 | int len = skb->len; |
146 | if (len > c) | 138 | tty_insert_flip_string(tty, skb->data, len); |
147 | len = c; | ||
148 | memcpy(tty->flip.char_buf_ptr, skb->data, len); | ||
149 | skb_pull(skb, len); | 139 | skb_pull(skb, len); |
150 | memset(tty->flip.flag_buf_ptr, 0, len); | ||
151 | tty->flip.count += len; | ||
152 | tty->flip.char_buf_ptr += len; | ||
153 | tty->flip.flag_buf_ptr += len; | ||
154 | tty_flip_buffer_push(tty); | 140 | tty_flip_buffer_push(tty); |
155 | if (skb->len > 0) | 141 | if (skb->len > 0) |
156 | skb_queue_head(&info->rx_queue, skb); | 142 | skb_queue_head(&info->rx_queue, skb); |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3cb68af90456..9b9062f02462 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/spinlock.h> | 47 | #include <linux/spinlock.h> |
48 | #include <linux/syscalls.h> | 48 | #include <linux/syscalls.h> |
49 | #include <linux/ioctl32.h> | ||
50 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
51 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
52 | #include <asm/semaphore.h> | 51 | #include <asm/semaphore.h> |
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 0920220f3313..4299fabca554 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/ioctl32.h> | ||
24 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
25 | #include <linux/chio.h> /* here are all the ioctls */ | 24 | #include <linux/chio.h> /* here are all the ioctls */ |
26 | 25 | ||
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h index eb8c390a0fa3..3d9e67d6849d 100644 --- a/drivers/scsi/megaraid/megaraid_mm.h +++ b/drivers/scsi/megaraid/megaraid_mm.h | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/ioctl32.h> | ||
26 | 25 | ||
27 | #include "mbox_defs.h" | 26 | #include "mbox_defs.h" |
28 | #include "megaraid_ioctl.h" | 27 | #include "megaraid_ioctl.h" |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index b5cf39468d18..221999bcf8fe 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -94,15 +94,6 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r | |||
94 | 94 | ||
95 | status = *CSR_UARTFLG; | 95 | status = *CSR_UARTFLG; |
96 | while (!(status & 0x10) && max_count--) { | 96 | while (!(status & 0x10) && max_count--) { |
97 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
98 | if (tty->low_latency) | ||
99 | tty_flip_buffer_push(tty); | ||
100 | /* | ||
101 | * If this failed then we will throw away the | ||
102 | * bytes but must do so to clear interrupts | ||
103 | */ | ||
104 | } | ||
105 | |||
106 | ch = *CSR_UARTDR; | 97 | ch = *CSR_UARTDR; |
107 | flag = TTY_NORMAL; | 98 | flag = TTY_NORMAL; |
108 | port->icount.rx++; | 99 | port->icount.rx++; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 67e9afa000c1..4dd5c3f98167 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -294,7 +294,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
294 | { | 294 | { |
295 | struct tty_struct *tty = info->tty; | 295 | struct tty_struct *tty = info->tty; |
296 | m68328_uart *uart = &uart_addr[info->line]; | 296 | m68328_uart *uart = &uart_addr[info->line]; |
297 | unsigned char ch; | 297 | unsigned char ch, flag; |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * This do { } while() loop will get ALL chars out of Rx FIFO | 300 | * This do { } while() loop will get ALL chars out of Rx FIFO |
@@ -332,26 +332,24 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
332 | /* | 332 | /* |
333 | * Make sure that we do not overflow the buffer | 333 | * Make sure that we do not overflow the buffer |
334 | */ | 334 | */ |
335 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 335 | if (tty_request_buffer_room(tty, 1) == 0) { |
336 | schedule_work(&tty->flip.work); | 336 | schedule_work(&tty->flip.work); |
337 | return; | 337 | return; |
338 | } | 338 | } |
339 | 339 | ||
340 | flag = TTY_NORMAL; | ||
341 | |||
340 | if(rx & URX_PARITY_ERROR) { | 342 | if(rx & URX_PARITY_ERROR) { |
341 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 343 | flag = TTY_PARITY; |
342 | status_handle(info, rx); | 344 | status_handle(info, rx); |
343 | } else if(rx & URX_OVRUN) { | 345 | } else if(rx & URX_OVRUN) { |
344 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 346 | flag = TTY_OVERRUN; |
345 | status_handle(info, rx); | 347 | status_handle(info, rx); |
346 | } else if(rx & URX_FRAME_ERROR) { | 348 | } else if(rx & URX_FRAME_ERROR) { |
347 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 349 | flag = TTY_FRAME; |
348 | status_handle(info, rx); | 350 | status_handle(info, rx); |
349 | } else { | ||
350 | *tty->flip.flag_buf_ptr++ = 0; /* XXX */ | ||
351 | } | 351 | } |
352 | *tty->flip.char_buf_ptr++ = ch; | 352 | tty_insert_flip_char(tty, ch, flag); |
353 | tty->flip.count++; | ||
354 | |||
355 | #ifndef CONFIG_XCOPILOT_BUGS | 353 | #ifndef CONFIG_XCOPILOT_BUGS |
356 | } while((rx = uart->urx.w) & URX_DATA_READY); | 354 | } while((rx = uart->urx.w) & URX_DATA_READY); |
357 | #endif | 355 | #endif |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 170c9d2a749c..60f5a5dc17f1 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -394,7 +394,7 @@ static void rs_360_start(struct tty_struct *tty) | |||
394 | static _INLINE_ void receive_chars(ser_info_t *info) | 394 | static _INLINE_ void receive_chars(ser_info_t *info) |
395 | { | 395 | { |
396 | struct tty_struct *tty = info->tty; | 396 | struct tty_struct *tty = info->tty; |
397 | unsigned char ch, *cp; | 397 | unsigned char ch, flag, *cp; |
398 | /*int ignored = 0;*/ | 398 | /*int ignored = 0;*/ |
399 | int i; | 399 | int i; |
400 | ushort status; | 400 | ushort status; |
@@ -438,24 +438,15 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
438 | cp = (char *)bdp->buf; | 438 | cp = (char *)bdp->buf; |
439 | status = bdp->status; | 439 | status = bdp->status; |
440 | 440 | ||
441 | /* Check to see if there is room in the tty buffer for | ||
442 | * the characters in our BD buffer. If not, we exit | ||
443 | * now, leaving the BD with the characters. We'll pick | ||
444 | * them up again on the next receive interrupt (which could | ||
445 | * be a timeout). | ||
446 | */ | ||
447 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) | ||
448 | break; | ||
449 | |||
450 | while (i-- > 0) { | 441 | while (i-- > 0) { |
451 | ch = *cp++; | 442 | ch = *cp++; |
452 | *tty->flip.char_buf_ptr = ch; | ||
453 | icount->rx++; | 443 | icount->rx++; |
454 | 444 | ||
455 | #ifdef SERIAL_DEBUG_INTR | 445 | #ifdef SERIAL_DEBUG_INTR |
456 | printk("DR%02x:%02x...", ch, status); | 446 | printk("DR%02x:%02x...", ch, status); |
457 | #endif | 447 | #endif |
458 | *tty->flip.flag_buf_ptr = 0; | 448 | flag = TTY_NORMAL; |
449 | |||
459 | if (status & (BD_SC_BR | BD_SC_FR | | 450 | if (status & (BD_SC_BR | BD_SC_FR | |
460 | BD_SC_PR | BD_SC_OV)) { | 451 | BD_SC_PR | BD_SC_OV)) { |
461 | /* | 452 | /* |
@@ -490,30 +481,18 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
490 | if (info->flags & ASYNC_SAK) | 481 | if (info->flags & ASYNC_SAK) |
491 | do_SAK(tty); | 482 | do_SAK(tty); |
492 | } else if (status & BD_SC_PR) | 483 | } else if (status & BD_SC_PR) |
493 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 484 | flag = TTY_PARITY; |
494 | else if (status & BD_SC_FR) | 485 | else if (status & BD_SC_FR) |
495 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 486 | flag = TTY_FRAME; |
496 | if (status & BD_SC_OV) { | ||
497 | /* | ||
498 | * Overrun is special, since it's | ||
499 | * reported immediately, and doesn't | ||
500 | * affect the current character | ||
501 | */ | ||
502 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
503 | tty->flip.count++; | ||
504 | tty->flip.flag_buf_ptr++; | ||
505 | tty->flip.char_buf_ptr++; | ||
506 | *tty->flip.flag_buf_ptr = | ||
507 | TTY_OVERRUN; | ||
508 | } | ||
509 | } | ||
510 | } | 487 | } |
511 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 488 | tty_insert_flip_char(tty, ch, flag); |
512 | break; | 489 | if (status & BD_SC_OV) |
513 | 490 | /* | |
514 | tty->flip.flag_buf_ptr++; | 491 | * Overrun is special, since it's |
515 | tty->flip.char_buf_ptr++; | 492 | * reported immediately, and doesn't |
516 | tty->flip.count++; | 493 | * affect the current character |
494 | */ | ||
495 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
517 | } | 496 | } |
518 | 497 | ||
519 | /* This BD is ready to be used again. Clear status. | 498 | /* This BD is ready to be used again. Clear status. |
@@ -541,12 +520,7 @@ static _INLINE_ void receive_break(ser_info_t *info) | |||
541 | /* Check to see if there is room in the tty buffer for | 520 | /* Check to see if there is room in the tty buffer for |
542 | * the break. If not, we exit now, losing the break. FIXME | 521 | * the break. If not, we exit now, losing the break. FIXME |
543 | */ | 522 | */ |
544 | if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) | 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
545 | return; | ||
546 | *(tty->flip.flag_buf_ptr++) = TTY_BREAK; | ||
547 | *(tty->flip.char_buf_ptr++) = 0; | ||
548 | tty->flip.count++; | ||
549 | |||
550 | schedule_work(&tty->flip.work); | 524 | schedule_work(&tty->flip.work); |
551 | } | 525 | } |
552 | 526 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index e8454611cb65..54e5cc0dd5f8 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1142,19 +1142,6 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
1142 | char flag; | 1142 | char flag; |
1143 | 1143 | ||
1144 | do { | 1144 | do { |
1145 | /* The following is not allowed by the tty layer and | ||
1146 | unsafe. It should be fixed ASAP */ | ||
1147 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
1148 | if (tty->low_latency) { | ||
1149 | spin_unlock(&up->port.lock); | ||
1150 | tty_flip_buffer_push(tty); | ||
1151 | spin_lock(&up->port.lock); | ||
1152 | } | ||
1153 | /* | ||
1154 | * If this failed then we will throw away the | ||
1155 | * bytes but must do so to clear interrupts | ||
1156 | */ | ||
1157 | } | ||
1158 | ch = serial_inp(up, UART_RX); | 1145 | ch = serial_inp(up, UART_RX); |
1159 | flag = TTY_NORMAL; | 1146 | flag = TTY_NORMAL; |
1160 | up->port.icount.rx++; | 1147 | up->port.icount.rx++; |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1bae26a8a503..698cb76819d9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -860,7 +860,7 @@ config SERIAL_VR41XX_CONSOLE | |||
860 | 860 | ||
861 | config SERIAL_JSM | 861 | config SERIAL_JSM |
862 | tristate "Digi International NEO PCI Support" | 862 | tristate "Digi International NEO PCI Support" |
863 | depends on PCI | 863 | depends on PCI && BROKEN |
864 | select SERIAL_CORE | 864 | select SERIAL_CORE |
865 | help | 865 | help |
866 | This is a driver for Digi International's Neo series | 866 | This is a driver for Digi International's Neo series |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 48f6e872314b..3490022e9fdc 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -154,15 +154,6 @@ pl010_rx_chars(struct uart_port *port) | |||
154 | 154 | ||
155 | status = UART_GET_FR(port); | 155 | status = UART_GET_FR(port); |
156 | while (UART_RX_DATA(status) && max_count--) { | 156 | while (UART_RX_DATA(status) && max_count--) { |
157 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
158 | if (tty->low_latency) | ||
159 | tty_flip_buffer_push(tty); | ||
160 | /* | ||
161 | * If this failed then we will throw away the | ||
162 | * bytes but must do so to clear interrupts. | ||
163 | */ | ||
164 | } | ||
165 | |||
166 | ch = UART_GET_CHAR(port); | 157 | ch = UART_GET_CHAR(port); |
167 | flag = TTY_NORMAL; | 158 | flag = TTY_NORMAL; |
168 | 159 | ||
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 129670556162..034a029e356e 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -120,15 +120,6 @@ pl011_rx_chars(struct uart_amba_port *uap) | |||
120 | 120 | ||
121 | status = readw(uap->port.membase + UART01x_FR); | 121 | status = readw(uap->port.membase + UART01x_FR); |
122 | while ((status & UART01x_FR_RXFE) == 0 && max_count--) { | 122 | while ((status & UART01x_FR_RXFE) == 0 && max_count--) { |
123 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
124 | if (tty->low_latency) | ||
125 | tty_flip_buffer_push(tty); | ||
126 | /* | ||
127 | * If this failed then we will throw away the | ||
128 | * bytes but must do so to clear interrupts | ||
129 | */ | ||
130 | } | ||
131 | |||
132 | ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; | 123 | ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; |
133 | flag = TTY_NORMAL; | 124 | flag = TTY_NORMAL; |
134 | uap->port.icount.rx++; | 125 | uap->port.icount.rx++; |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index a274ebf256a1..ceb5d7f37bbd 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
@@ -241,18 +241,12 @@ static _INLINE_ void | |||
241 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | 241 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) |
242 | { | 242 | { |
243 | struct tty_struct *tty = up->port.info->tty; | 243 | struct tty_struct *tty = up->port.info->tty; |
244 | unsigned char ch; | 244 | unsigned char ch, flag; |
245 | int max_count = 256; | 245 | int max_count = 256; |
246 | 246 | ||
247 | do { | 247 | do { |
248 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
249 | tty->flip.work.func((void *)tty); | ||
250 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
251 | return; // if TTY_DONT_FLIP is set | ||
252 | } | ||
253 | ch = serial_inp(up, UART_RX); | 248 | ch = serial_inp(up, UART_RX); |
254 | *tty->flip.char_buf_ptr = ch; | 249 | flag = TTY_NORMAL; |
255 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
256 | up->port.icount.rx++; | 250 | up->port.icount.rx++; |
257 | 251 | ||
258 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 252 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -292,30 +286,23 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
292 | #endif | 286 | #endif |
293 | if (*status & UART_LSR_BI) { | 287 | if (*status & UART_LSR_BI) { |
294 | DEBUG_INTR("handling break...."); | 288 | DEBUG_INTR("handling break...."); |
295 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 289 | flag = TTY_BREAK; |
296 | } else if (*status & UART_LSR_PE) | 290 | } else if (*status & UART_LSR_PE) |
297 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 291 | flag = TTY_PARITY; |
298 | else if (*status & UART_LSR_FE) | 292 | else if (*status & UART_LSR_FE) |
299 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 293 | flag = TTY_FRAME; |
300 | } | 294 | } |
301 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 295 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
302 | goto ignore_char; | 296 | goto ignore_char; |
303 | if ((*status & up->port.ignore_status_mask) == 0) { | 297 | if ((*status & up->port.ignore_status_mask) == 0) |
304 | tty->flip.flag_buf_ptr++; | 298 | tty_insert_flip_char(tty, ch, flag); |
305 | tty->flip.char_buf_ptr++; | 299 | if (*status & UART_LSR_OE) |
306 | tty->flip.count++; | ||
307 | } | ||
308 | if ((*status & UART_LSR_OE) && | ||
309 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
310 | /* | 300 | /* |
311 | * Overrun is special, since it's reported | 301 | * Overrun is special, since it's reported |
312 | * immediately, and doesn't affect the current | 302 | * immediately, and doesn't affect the current |
313 | * character. | 303 | * character. |
314 | */ | 304 | */ |
315 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 305 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
316 | tty->flip.flag_buf_ptr++; | ||
317 | tty->flip.char_buf_ptr++; | ||
318 | tty->flip.count++; | ||
319 | } | 306 | } |
320 | ignore_char: | 307 | ignore_char: |
321 | *status = serial_inp(up, UART_LSR); | 308 | *status = serial_inp(up, UART_LSR); |
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 87ef368384fb..8ef999481f93 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c | |||
@@ -104,8 +104,6 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re | |||
104 | while (!(status & SYSFLG_URXFE)) { | 104 | while (!(status & SYSFLG_URXFE)) { |
105 | ch = clps_readl(UARTDR(port)); | 105 | ch = clps_readl(UARTDR(port)); |
106 | 106 | ||
107 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
108 | goto ignore_char; | ||
109 | port->icount.rx++; | 107 | port->icount.rx++; |
110 | 108 | ||
111 | flg = TTY_NORMAL; | 109 | flg = TTY_NORMAL; |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index 4d8516d1bb71..a64ba26a94e8 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -216,8 +216,6 @@ static inline void dz_receive_chars(struct dz_port *dport) | |||
216 | 216 | ||
217 | if (!tty) | 217 | if (!tty) |
218 | break; | 218 | break; |
219 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
220 | break; | ||
221 | 219 | ||
222 | icount->rx++; | 220 | icount->rx++; |
223 | 221 | ||
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index eb31125c6a30..144a7a352b28 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -729,19 +729,20 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
729 | unsigned short int status; | 729 | unsigned short int status; |
730 | struct uart_icount *icount; | 730 | struct uart_icount *icount; |
731 | unsigned long offset; | 731 | unsigned long offset; |
732 | unsigned char flag; | ||
732 | 733 | ||
733 | trace(icom_port, "RCV_COMPLETE", 0); | 734 | trace(icom_port, "RCV_COMPLETE", 0); |
734 | rcv_buff = icom_port->next_rcv; | 735 | rcv_buff = icom_port->next_rcv; |
735 | 736 | ||
736 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); | 737 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); |
737 | while (status & SA_FL_RCV_DONE) { | 738 | while (status & SA_FL_RCV_DONE) { |
739 | int first = -1; | ||
738 | 740 | ||
739 | trace(icom_port, "FID_STATUS", status); | 741 | trace(icom_port, "FID_STATUS", status); |
740 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); | 742 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); |
741 | 743 | ||
744 | count = tty_buffer_request_room(tty, count); | ||
742 | trace(icom_port, "RCV_COUNT", count); | 745 | trace(icom_port, "RCV_COUNT", count); |
743 | if (count > (TTY_FLIPBUF_SIZE - tty->flip.count)) | ||
744 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
745 | 746 | ||
746 | trace(icom_port, "REAL_COUNT", count); | 747 | trace(icom_port, "REAL_COUNT", count); |
747 | 748 | ||
@@ -749,15 +750,10 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
749 | cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - | 750 | cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) - |
750 | icom_port->recv_buf_pci; | 751 | icom_port->recv_buf_pci; |
751 | 752 | ||
752 | memcpy(tty->flip.char_buf_ptr,(unsigned char *) | 753 | /* Block copy all but the last byte as this may have status */ |
753 | ((unsigned long)icom_port->recv_buf + offset), count); | ||
754 | |||
755 | if (count > 0) { | 754 | if (count > 0) { |
756 | tty->flip.count += count - 1; | 755 | first = icom_port->recv_buf[offset]; |
757 | tty->flip.char_buf_ptr += count - 1; | 756 | tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); |
758 | |||
759 | memset(tty->flip.flag_buf_ptr, 0, count); | ||
760 | tty->flip.flag_buf_ptr += count - 1; | ||
761 | } | 757 | } |
762 | 758 | ||
763 | icount = &icom_port->uart_port.icount; | 759 | icount = &icom_port->uart_port.icount; |
@@ -765,12 +761,14 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
765 | 761 | ||
766 | /* Break detect logic */ | 762 | /* Break detect logic */ |
767 | if ((status & SA_FLAGS_FRAME_ERROR) | 763 | if ((status & SA_FLAGS_FRAME_ERROR) |
768 | && (tty->flip.char_buf_ptr[0] == 0x00)) { | 764 | && first == 0) { |
769 | status &= ~SA_FLAGS_FRAME_ERROR; | 765 | status &= ~SA_FLAGS_FRAME_ERROR; |
770 | status |= SA_FLAGS_BREAK_DET; | 766 | status |= SA_FLAGS_BREAK_DET; |
771 | trace(icom_port, "BREAK_DET", 0); | 767 | trace(icom_port, "BREAK_DET", 0); |
772 | } | 768 | } |
773 | 769 | ||
770 | flag = TTY_NORMAL; | ||
771 | |||
774 | if (status & | 772 | if (status & |
775 | (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | | 773 | (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR | |
776 | SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) { | 774 | SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) { |
@@ -797,33 +795,26 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
797 | status &= icom_port->read_status_mask; | 795 | status &= icom_port->read_status_mask; |
798 | 796 | ||
799 | if (status & SA_FLAGS_BREAK_DET) { | 797 | if (status & SA_FLAGS_BREAK_DET) { |
800 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 798 | flag = TTY_BREAK; |
801 | } else if (status & SA_FLAGS_PARITY_ERROR) { | 799 | } else if (status & SA_FLAGS_PARITY_ERROR) { |
802 | trace(icom_port, "PARITY_ERROR", 0); | 800 | trace(icom_port, "PARITY_ERROR", 0); |
803 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 801 | flag = TTY_PARITY; |
804 | } else if (status & SA_FLAGS_FRAME_ERROR) | 802 | } else if (status & SA_FLAGS_FRAME_ERROR) |
805 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 803 | flag = TTY_FRAME; |
806 | 804 | ||
807 | if (status & SA_FLAGS_OVERRUN) { | ||
808 | /* | ||
809 | * Overrun is special, since it's | ||
810 | * reported immediately, and doesn't | ||
811 | * affect the current character | ||
812 | */ | ||
813 | if (tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
814 | tty->flip.count++; | ||
815 | tty->flip.flag_buf_ptr++; | ||
816 | tty->flip.char_buf_ptr++; | ||
817 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
818 | } | ||
819 | } | ||
820 | } | 805 | } |
821 | 806 | ||
822 | tty->flip.flag_buf_ptr++; | 807 | tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); |
823 | tty->flip.char_buf_ptr++; | 808 | |
824 | tty->flip.count++; | 809 | if (status & SA_FLAGS_OVERRUN) |
825 | ignore_char: | 810 | /* |
826 | icom_port->statStg->rcv[rcv_buff].flags = 0; | 811 | * Overrun is special, since it's |
812 | * reported immediately, and doesn't | ||
813 | * affect the current character | ||
814 | */ | ||
815 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
816 | ignore_char: | ||
817 | icom_port->statStg->rcv[rcv_buff].flags = 0; | ||
827 | icom_port->statStg->rcv[rcv_buff].leLength = 0; | 818 | icom_port->statStg->rcv[rcv_buff].leLength = 0; |
828 | icom_port->statStg->rcv[rcv_buff].WorkingLength = | 819 | icom_port->statStg->rcv[rcv_buff].WorkingLength = |
829 | (unsigned short int) cpu_to_le16(RCV_BUFF_SZ); | 820 | (unsigned short int) cpu_to_le16(RCV_BUFF_SZ); |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 83c4c1216587..5c098be9346b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -256,9 +256,6 @@ static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs) | |||
256 | error_return: | 256 | error_return: |
257 | tty_insert_flip_char(tty, rx, flg); | 257 | tty_insert_flip_char(tty, rx, flg); |
258 | 258 | ||
259 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
260 | goto out; | ||
261 | |||
262 | ignore_char: | 259 | ignore_char: |
263 | rx = URXD0((u32)sport->port.membase); | 260 | rx = URXD0((u32)sport->port.membase); |
264 | } while(rx & URXD_CHARRDY); | 261 | } while(rx & URXD_CHARRDY); |
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 771676abee60..1d85533d46d2 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -2327,19 +2327,13 @@ static void receive_chars(struct uart_port *the_port) | |||
2327 | spin_lock_irqsave(&the_port->lock, pflags); | 2327 | spin_lock_irqsave(&the_port->lock, pflags); |
2328 | tty = info->tty; | 2328 | tty = info->tty; |
2329 | 2329 | ||
2330 | if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count) | 2330 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2); |
2331 | request_count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
2332 | 2331 | ||
2333 | if (request_count > 0) { | 2332 | if (request_count > 0) { |
2334 | icount = &the_port->icount; | 2333 | icount = &the_port->icount; |
2335 | read_count = do_read(the_port, ch, request_count); | 2334 | read_count = do_read(the_port, ch, request_count); |
2336 | if (read_count > 0) { | 2335 | if (read_count > 0) { |
2337 | flip = 1; | 2336 | tty_insert_flip_string(tty, ch, read_count); |
2338 | memcpy(tty->flip.char_buf_ptr, ch, read_count); | ||
2339 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count); | ||
2340 | tty->flip.char_buf_ptr += read_count; | ||
2341 | tty->flip.flag_buf_ptr += read_count; | ||
2342 | tty->flip.count += read_count; | ||
2343 | icount->rx += read_count; | 2337 | icount->rx += read_count; |
2344 | } | 2338 | } |
2345 | } | 2339 | } |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index ef132349f310..66f117d15065 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -259,13 +259,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
259 | struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ | 259 | struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ |
260 | 260 | ||
261 | while (1) { | 261 | while (1) { |
262 | unsigned char ch, r1; | 262 | unsigned char ch, r1, flag; |
263 | |||
264 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
265 | tty->flip.work.func((void *)tty); | ||
266 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
267 | return; /* XXX Ignores SysRq when we need it most. Fix. */ | ||
268 | } | ||
269 | 263 | ||
270 | r1 = read_zsreg(channel, R1); | 264 | r1 = read_zsreg(channel, R1); |
271 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { | 265 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { |
@@ -303,8 +297,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
303 | } | 297 | } |
304 | 298 | ||
305 | /* A real serial line, record the character and status. */ | 299 | /* A real serial line, record the character and status. */ |
306 | *tty->flip.char_buf_ptr = ch; | 300 | flag = TTY_NORMAL; |
307 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
308 | up->port.icount.rx++; | 301 | up->port.icount.rx++; |
309 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { | 302 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { |
310 | if (r1 & BRK_ABRT) { | 303 | if (r1 & BRK_ABRT) { |
@@ -321,28 +314,21 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | |||
321 | up->port.icount.overrun++; | 314 | up->port.icount.overrun++; |
322 | r1 &= up->port.read_status_mask; | 315 | r1 &= up->port.read_status_mask; |
323 | if (r1 & BRK_ABRT) | 316 | if (r1 & BRK_ABRT) |
324 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 317 | flag = TTY_BREAK; |
325 | else if (r1 & PAR_ERR) | 318 | else if (r1 & PAR_ERR) |
326 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 319 | flag = TTY_PARITY; |
327 | else if (r1 & CRC_ERR) | 320 | else if (r1 & CRC_ERR) |
328 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 321 | flag = TTY_FRAME; |
329 | } | 322 | } |
330 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 323 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
331 | goto next_char; | 324 | goto next_char; |
332 | 325 | ||
333 | if (up->port.ignore_status_mask == 0xff || | 326 | if (up->port.ignore_status_mask == 0xff || |
334 | (r1 & up->port.ignore_status_mask) == 0) { | 327 | (r1 & up->port.ignore_status_mask) == 0) |
335 | tty->flip.flag_buf_ptr++; | 328 | tty_insert_flip_char(tty, ch, flag); |
336 | tty->flip.char_buf_ptr++; | 329 | |
337 | tty->flip.count++; | 330 | if (r1 & Rx_OVR) |
338 | } | 331 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
339 | if ((r1 & Rx_OVR) && | ||
340 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
341 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
342 | tty->flip.flag_buf_ptr++; | ||
343 | tty->flip.char_buf_ptr++; | ||
344 | tty->flip.count++; | ||
345 | } | ||
346 | next_char: | 332 | next_char: |
347 | ch = readb(&channel->control); | 333 | ch = readb(&channel->control); |
348 | ZSDELAY(); | 334 | ZSDELAY(); |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b0ecc7537ce5..b48066a64a7d 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -331,17 +331,12 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | |||
331 | { | 331 | { |
332 | struct tty_struct *tty = up->port.info->tty; | 332 | struct tty_struct *tty = up->port.info->tty; |
333 | unsigned char ch; | 333 | unsigned char ch; |
334 | unsigned char flag; | ||
334 | int max_count = 256; | 335 | int max_count = 256; |
335 | 336 | ||
336 | do { | 337 | do { |
337 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
338 | tty->flip.work.func((void *)tty); | ||
339 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
340 | return; // if TTY_DONT_FLIP is set | ||
341 | } | ||
342 | ch = sio_in(up, SIORXB); | 338 | ch = sio_in(up, SIORXB); |
343 | *tty->flip.char_buf_ptr = ch; | 339 | flag = TTY_NORMAL; |
344 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
345 | up->port.icount.rx++; | 340 | up->port.icount.rx++; |
346 | 341 | ||
347 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 342 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -380,30 +375,24 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | |||
380 | 375 | ||
381 | if (*status & UART_LSR_BI) { | 376 | if (*status & UART_LSR_BI) { |
382 | DEBUG_INTR("handling break...."); | 377 | DEBUG_INTR("handling break...."); |
383 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 378 | flag = TTY_BREAK; |
384 | } else if (*status & UART_LSR_PE) | 379 | } else if (*status & UART_LSR_PE) |
385 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 380 | flag = TTY_PARITY; |
386 | else if (*status & UART_LSR_FE) | 381 | else if (*status & UART_LSR_FE) |
387 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 382 | flag = TTY_FRAME; |
388 | } | 383 | } |
389 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 384 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
390 | goto ignore_char; | 385 | goto ignore_char; |
391 | if ((*status & up->port.ignore_status_mask) == 0) { | 386 | if ((*status & up->port.ignore_status_mask) == 0) |
392 | tty->flip.flag_buf_ptr++; | 387 | tty_insert_flip_char(tty, ch, flag); |
393 | tty->flip.char_buf_ptr++; | 388 | |
394 | tty->flip.count++; | 389 | if (*status & UART_LSR_OE) { |
395 | } | ||
396 | if ((*status & UART_LSR_OE) && | ||
397 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
398 | /* | 390 | /* |
399 | * Overrun is special, since it's reported | 391 | * Overrun is special, since it's reported |
400 | * immediately, and doesn't affect the current | 392 | * immediately, and doesn't affect the current |
401 | * character. | 393 | * character. |
402 | */ | 394 | */ |
403 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 395 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
404 | tty->flip.flag_buf_ptr++; | ||
405 | tty->flip.char_buf_ptr++; | ||
406 | tty->flip.count++; | ||
407 | } | 396 | } |
408 | ignore_char: | 397 | ignore_char: |
409 | *status = serial_in(up, UART_LSR); | 398 | *status = serial_in(up, UART_LSR); |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 47f7404cb045..f2a51e61eec7 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -313,7 +313,7 @@ static inline void receive_chars(struct mcf_serial *info) | |||
313 | { | 313 | { |
314 | volatile unsigned char *uartp; | 314 | volatile unsigned char *uartp; |
315 | struct tty_struct *tty = info->tty; | 315 | struct tty_struct *tty = info->tty; |
316 | unsigned char status, ch; | 316 | unsigned char status, ch, flag; |
317 | 317 | ||
318 | if (!tty) | 318 | if (!tty) |
319 | return; | 319 | return; |
@@ -321,10 +321,6 @@ static inline void receive_chars(struct mcf_serial *info) | |||
321 | uartp = info->addr; | 321 | uartp = info->addr; |
322 | 322 | ||
323 | while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { | 323 | while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) { |
324 | |||
325 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
326 | break; | ||
327 | |||
328 | ch = uartp[MCFUART_URB]; | 324 | ch = uartp[MCFUART_URB]; |
329 | info->stats.rx++; | 325 | info->stats.rx++; |
330 | 326 | ||
@@ -335,29 +331,24 @@ static inline void receive_chars(struct mcf_serial *info) | |||
335 | } | 331 | } |
336 | #endif | 332 | #endif |
337 | 333 | ||
338 | tty->flip.count++; | 334 | flag = TTY_NORMAL; |
339 | if (status & MCFUART_USR_RXERR) { | 335 | if (status & MCFUART_USR_RXERR) { |
340 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; | 336 | uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; |
341 | if (status & MCFUART_USR_RXBREAK) { | 337 | if (status & MCFUART_USR_RXBREAK) { |
342 | info->stats.rxbreak++; | 338 | info->stats.rxbreak++; |
343 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 339 | flag = TTY_BREAK; |
344 | } else if (status & MCFUART_USR_RXPARITY) { | 340 | } else if (status & MCFUART_USR_RXPARITY) { |
345 | info->stats.rxparity++; | 341 | info->stats.rxparity++; |
346 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | 342 | flag = TTY_PARITY; |
347 | } else if (status & MCFUART_USR_RXOVERRUN) { | 343 | } else if (status & MCFUART_USR_RXOVERRUN) { |
348 | info->stats.rxoverrun++; | 344 | info->stats.rxoverrun++; |
349 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 345 | flag = TTY_OVERRUN; |
350 | } else if (status & MCFUART_USR_RXFRAMING) { | 346 | } else if (status & MCFUART_USR_RXFRAMING) { |
351 | info->stats.rxframing++; | 347 | info->stats.rxframing++; |
352 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 348 | flag = TTY_FRAME; |
353 | } else { | ||
354 | /* This should never happen... */ | ||
355 | *tty->flip.flag_buf_ptr++ = 0; | ||
356 | } | 349 | } |
357 | } else { | ||
358 | *tty->flip.flag_buf_ptr++ = 0; | ||
359 | } | 350 | } |
360 | *tty->flip.char_buf_ptr++ = ch; | 351 | tty_insert_flip_char(tty, ch, flag); |
361 | } | 352 | } |
362 | 353 | ||
363 | schedule_work(&tty->flip.work); | 354 | schedule_work(&tty->flip.work); |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 1288d6203e94..61dd17d7bace 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -405,17 +405,13 @@ static inline int | |||
405 | mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) | 405 | mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) |
406 | { | 406 | { |
407 | struct tty_struct *tty = port->info->tty; | 407 | struct tty_struct *tty = port->info->tty; |
408 | unsigned char ch; | 408 | unsigned char ch, flag; |
409 | unsigned short status; | 409 | unsigned short status; |
410 | 410 | ||
411 | /* While we can read, do so ! */ | 411 | /* While we can read, do so ! */ |
412 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & | 412 | while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & |
413 | MPC52xx_PSC_SR_RXRDY) { | 413 | MPC52xx_PSC_SR_RXRDY) { |
414 | 414 | ||
415 | /* If we are full, just stop reading */ | ||
416 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
417 | break; | ||
418 | |||
419 | /* Get the char */ | 415 | /* Get the char */ |
420 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); | 416 | ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); |
421 | 417 | ||
@@ -428,45 +424,35 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) | |||
428 | #endif | 424 | #endif |
429 | 425 | ||
430 | /* Store it */ | 426 | /* Store it */ |
431 | *tty->flip.char_buf_ptr = ch; | 427 | |
432 | *tty->flip.flag_buf_ptr = 0; | 428 | flag = TTY_NORMAL; |
433 | port->icount.rx++; | 429 | port->icount.rx++; |
434 | 430 | ||
435 | if ( status & (MPC52xx_PSC_SR_PE | | 431 | if ( status & (MPC52xx_PSC_SR_PE | |
436 | MPC52xx_PSC_SR_FE | | 432 | MPC52xx_PSC_SR_FE | |
437 | MPC52xx_PSC_SR_RB | | 433 | MPC52xx_PSC_SR_RB) ) { |
438 | MPC52xx_PSC_SR_OE) ) { | ||
439 | 434 | ||
440 | if (status & MPC52xx_PSC_SR_RB) { | 435 | if (status & MPC52xx_PSC_SR_RB) { |
441 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 436 | flag = TTY_BREAK; |
442 | uart_handle_break(port); | 437 | uart_handle_break(port); |
443 | } else if (status & MPC52xx_PSC_SR_PE) | 438 | } else if (status & MPC52xx_PSC_SR_PE) |
444 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 439 | flag = TTY_PARITY; |
445 | else if (status & MPC52xx_PSC_SR_FE) | 440 | else if (status & MPC52xx_PSC_SR_FE) |
446 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 441 | flag = TTY_FRAME; |
447 | if (status & MPC52xx_PSC_SR_OE) { | ||
448 | /* | ||
449 | * Overrun is special, since it's | ||
450 | * reported immediately, and doesn't | ||
451 | * affect the current character | ||
452 | */ | ||
453 | if (tty->flip.count < (TTY_FLIPBUF_SIZE-1)) { | ||
454 | tty->flip.flag_buf_ptr++; | ||
455 | tty->flip.char_buf_ptr++; | ||
456 | tty->flip.count++; | ||
457 | } | ||
458 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
459 | } | ||
460 | 442 | ||
461 | /* Clear error condition */ | 443 | /* Clear error condition */ |
462 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); | 444 | out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); |
463 | 445 | ||
464 | } | 446 | } |
465 | 447 | tty_insert_flip_char(tty, ch, flag); | |
466 | tty->flip.char_buf_ptr++; | 448 | if (status & MPC52xx_PSC_SR_OE) { |
467 | tty->flip.flag_buf_ptr++; | 449 | /* |
468 | tty->flip.count++; | 450 | * Overrun is special, since it's |
469 | 451 | * reported immediately, and doesn't | |
452 | * affect the current character | ||
453 | */ | ||
454 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
455 | } | ||
470 | } | 456 | } |
471 | 457 | ||
472 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(tty); |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 8f83e4007ecd..0ca83ac31d07 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -769,12 +769,12 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs) | |||
769 | bytes_in = be16_to_cpu(rxre->bytecnt); | 769 | bytes_in = be16_to_cpu(rxre->bytecnt); |
770 | 770 | ||
771 | /* Following use of tty struct directly is deprecated */ | 771 | /* Following use of tty struct directly is deprecated */ |
772 | if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){ | 772 | if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) { |
773 | if (tty->low_latency) | 773 | if (tty->low_latency) |
774 | tty_flip_buffer_push(tty); | 774 | tty_flip_buffer_push(tty); |
775 | /* | 775 | /* |
776 | * If this failed then we will throw awa the bytes | 776 | * If this failed then we will throw away the bytes |
777 | * but mst do so to clear interrupts. | 777 | * but must do so to clear interrupts. |
778 | */ | 778 | */ |
779 | } | 779 | } |
780 | 780 | ||
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 7633132a10aa..4e49168c3176 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -223,11 +223,6 @@ static void mux_read(struct uart_port *port) | |||
223 | if (MUX_EOFIFO(data)) | 223 | if (MUX_EOFIFO(data)) |
224 | break; | 224 | break; |
225 | 225 | ||
226 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
227 | continue; | ||
228 | |||
229 | *tty->flip.char_buf_ptr = data & 0xffu; | ||
230 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
231 | port->icount.rx++; | 226 | port->icount.rx++; |
232 | 227 | ||
233 | if (MUX_BREAK(data)) { | 228 | if (MUX_BREAK(data)) { |
@@ -239,9 +234,7 @@ static void mux_read(struct uart_port *port) | |||
239 | if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) | 234 | if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) |
240 | continue; | 235 | continue; |
241 | 236 | ||
242 | tty->flip.flag_buf_ptr++; | 237 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); |
243 | tty->flip.char_buf_ptr++; | ||
244 | tty->flip.count++; | ||
245 | } | 238 | } |
246 | 239 | ||
247 | if (start_count != port->icount.rx) { | 240 | if (start_count != port->icount.rx) { |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index ea24129eb6b9..f330d6c0e0df 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -210,10 +210,9 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
210 | struct pt_regs *regs) | 210 | struct pt_regs *regs) |
211 | { | 211 | { |
212 | struct tty_struct *tty = NULL; | 212 | struct tty_struct *tty = NULL; |
213 | unsigned char ch, r1, drop, error; | 213 | unsigned char ch, r1, drop, error, flag; |
214 | int loops = 0; | 214 | int loops = 0; |
215 | 215 | ||
216 | retry: | ||
217 | /* The interrupt can be enabled when the port isn't open, typically | 216 | /* The interrupt can be enabled when the port isn't open, typically |
218 | * that happens when using one port is open and the other closed (stale | 217 | * that happens when using one port is open and the other closed (stale |
219 | * interrupt) or when one port is used as a console. | 218 | * interrupt) or when one port is used as a console. |
@@ -246,20 +245,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
246 | error = 0; | 245 | error = 0; |
247 | drop = 0; | 246 | drop = 0; |
248 | 247 | ||
249 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
250 | /* Have to drop the lock here */ | ||
251 | pmz_debug("pmz: flip overflow\n"); | ||
252 | spin_unlock(&uap->port.lock); | ||
253 | tty->flip.work.func((void *)tty); | ||
254 | spin_lock(&uap->port.lock); | ||
255 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
256 | drop = 1; | ||
257 | if (ZS_IS_ASLEEP(uap)) | ||
258 | return NULL; | ||
259 | if (!ZS_IS_OPEN(uap)) | ||
260 | goto retry; | ||
261 | } | ||
262 | |||
263 | r1 = read_zsreg(uap, R1); | 248 | r1 = read_zsreg(uap, R1); |
264 | ch = read_zsdata(uap); | 249 | ch = read_zsdata(uap); |
265 | 250 | ||
@@ -295,8 +280,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
295 | if (drop) | 280 | if (drop) |
296 | goto next_char; | 281 | goto next_char; |
297 | 282 | ||
298 | *tty->flip.char_buf_ptr = ch; | 283 | flag = TTY_NORMAL; |
299 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
300 | uap->port.icount.rx++; | 284 | uap->port.icount.rx++; |
301 | 285 | ||
302 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { | 286 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { |
@@ -316,26 +300,19 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, | |||
316 | uap->port.icount.overrun++; | 300 | uap->port.icount.overrun++; |
317 | r1 &= uap->port.read_status_mask; | 301 | r1 &= uap->port.read_status_mask; |
318 | if (r1 & BRK_ABRT) | 302 | if (r1 & BRK_ABRT) |
319 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 303 | flag = TTY_BREAK; |
320 | else if (r1 & PAR_ERR) | 304 | else if (r1 & PAR_ERR) |
321 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 305 | flag = TTY_PARITY; |
322 | else if (r1 & CRC_ERR) | 306 | else if (r1 & CRC_ERR) |
323 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 307 | flag = TTY_FRAME; |
324 | } | 308 | } |
325 | 309 | ||
326 | if (uap->port.ignore_status_mask == 0xff || | 310 | if (uap->port.ignore_status_mask == 0xff || |
327 | (r1 & uap->port.ignore_status_mask) == 0) { | 311 | (r1 & uap->port.ignore_status_mask) == 0) { |
328 | tty->flip.flag_buf_ptr++; | 312 | tty_insert_flip_char(tty, ch, flag); |
329 | tty->flip.char_buf_ptr++; | ||
330 | tty->flip.count++; | ||
331 | } | ||
332 | if ((r1 & Rx_OVR) && | ||
333 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
334 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
335 | tty->flip.flag_buf_ptr++; | ||
336 | tty->flip.char_buf_ptr++; | ||
337 | tty->flip.count++; | ||
338 | } | 313 | } |
314 | if (r1 & Rx_OVR) | ||
315 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
339 | next_char: | 316 | next_char: |
340 | /* We can get stuck in an infinite loop getting char 0 when the | 317 | /* We can get stuck in an infinite loop getting char 0 when the |
341 | * line is in a wrong HW state, we break that here. | 318 | * line is in a wrong HW state, we break that here. |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index cc998b99a19f..10535f00301f 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -107,14 +107,6 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs) | |||
107 | int max_count = 256; | 107 | int max_count = 256; |
108 | 108 | ||
109 | do { | 109 | do { |
110 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
111 | if (tty->low_latency) | ||
112 | tty_flip_buffer_push(tty); | ||
113 | /* | ||
114 | * If this failed then we will throw away the | ||
115 | * bytes but must do so to clear interrupts | ||
116 | */ | ||
117 | } | ||
118 | ch = serial_in(up, UART_RX); | 110 | ch = serial_in(up, UART_RX); |
119 | flag = TTY_NORMAL; | 111 | flag = TTY_NORMAL; |
120 | up->port.icount.rx++; | 112 | up->port.icount.rx++; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index fe83ce6fef52..eb4883efb7c6 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -323,16 +323,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs) | |||
323 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) | 323 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) |
324 | break; | 324 | break; |
325 | 325 | ||
326 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
327 | if (tty->low_latency) | ||
328 | tty_flip_buffer_push(tty); | ||
329 | |||
330 | /* | ||
331 | * If this failed then we will throw away the | ||
332 | * bytes but must do so to clear interrupts | ||
333 | */ | ||
334 | } | ||
335 | |||
336 | uerstat = rd_regl(port, S3C2410_UERSTAT); | 326 | uerstat = rd_regl(port, S3C2410_UERSTAT); |
337 | ch = rd_regb(port, S3C2410_URXH); | 327 | ch = rd_regb(port, S3C2410_URXH); |
338 | 328 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 25a086458ab9..1bd93168f504 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -201,8 +201,6 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) | |||
201 | while (status & UTSR1_TO_SM(UTSR1_RNE)) { | 201 | while (status & UTSR1_TO_SM(UTSR1_RNE)) { |
202 | ch = UART_GET_CHAR(sport); | 202 | ch = UART_GET_CHAR(sport); |
203 | 203 | ||
204 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
205 | goto ignore_char; | ||
206 | sport->port.icount.rx++; | 204 | sport->port.icount.rx++; |
207 | 205 | ||
208 | flg = TTY_NORMAL; | 206 | flg = TTY_NORMAL; |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d01dbe5da3b9..d4a1f0e798c1 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -148,15 +148,6 @@ lh7a40xuart_rx_chars (struct uart_port* port) | |||
148 | unsigned int data, flag;/* Received data and status */ | 148 | unsigned int data, flag;/* Received data and status */ |
149 | 149 | ||
150 | while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { | 150 | while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { |
151 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
152 | if (tty->low_latency) | ||
153 | tty_flip_buffer_push(tty); | ||
154 | /* | ||
155 | * If this failed then we will throw away the | ||
156 | * bytes but must do so to clear interrupts | ||
157 | */ | ||
158 | } | ||
159 | |||
160 | data = UR (port, UART_R_DATA); | 151 | data = UR (port, UART_R_DATA); |
161 | flag = TTY_NORMAL; | 152 | flag = TTY_NORMAL; |
162 | ++port->icount.rx; | 153 | ++port->icount.rx; |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 995d9dd9ddd5..fdd1f1915a42 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -303,17 +303,6 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
303 | char flag; | 303 | char flag; |
304 | 304 | ||
305 | do { | 305 | do { |
306 | /* The following is not allowed by the tty layer and | ||
307 | unsafe. It should be fixed ASAP */ | ||
308 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
309 | if (tty->low_latency) { | ||
310 | spin_unlock(&up->port.lock); | ||
311 | tty_flip_buffer_push(tty); | ||
312 | spin_lock(&up->port.lock); | ||
313 | } | ||
314 | /* If this failed then we will throw away the | ||
315 | bytes but must do so to clear interrupts */ | ||
316 | } | ||
317 | ch = sio_in(up, TXX9_SIRFIFO); | 306 | ch = sio_in(up, TXX9_SIRFIFO); |
318 | flag = TTY_NORMAL; | 307 | flag = TTY_NORMAL; |
319 | up->port.icount.rx++; | 308 | up->port.icount.rx++; |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 430754ebac8a..a9e070759628 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -482,6 +482,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
482 | struct tty_struct *tty = port->info->tty; | 482 | struct tty_struct *tty = port->info->tty; |
483 | int i, count, copied = 0; | 483 | int i, count, copied = 0; |
484 | unsigned short status; | 484 | unsigned short status; |
485 | unsigned char flag; | ||
485 | 486 | ||
486 | status = sci_in(port, SCxSR); | 487 | status = sci_in(port, SCxSR); |
487 | if (!(status & SCxSR_RDxF(port))) | 488 | if (!(status & SCxSR_RDxF(port))) |
@@ -499,8 +500,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
499 | #endif | 500 | #endif |
500 | 501 | ||
501 | /* Don't copy more bytes than there is room for in the buffer */ | 502 | /* Don't copy more bytes than there is room for in the buffer */ |
502 | if (tty->flip.count + count > TTY_FLIPBUF_SIZE) | 503 | count = tty_buffer_request_room(tty, count); |
503 | count = TTY_FLIPBUF_SIZE - tty->flip.count; | ||
504 | 504 | ||
505 | /* If for any reason we can't copy more data, we're done! */ | 505 | /* If for any reason we can't copy more data, we're done! */ |
506 | if (count == 0) | 506 | if (count == 0) |
@@ -512,8 +512,7 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
512 | || uart_handle_sysrq_char(port, c, regs)) { | 512 | || uart_handle_sysrq_char(port, c, regs)) { |
513 | count = 0; | 513 | count = 0; |
514 | } else { | 514 | } else { |
515 | tty->flip.char_buf_ptr[0] = c; | 515 | tty_insert_flip_char(tty, c, TTY_NORMAL); |
516 | tty->flip.flag_buf_ptr[0] = TTY_NORMAL; | ||
517 | } | 516 | } |
518 | } else { | 517 | } else { |
519 | for (i=0; i<count; i++) { | 518 | for (i=0; i<count; i++) { |
@@ -542,26 +541,21 @@ static inline void sci_receive_chars(struct uart_port *port, | |||
542 | } | 541 | } |
543 | 542 | ||
544 | /* Store data and status */ | 543 | /* Store data and status */ |
545 | tty->flip.char_buf_ptr[i] = c; | ||
546 | if (status&SCxSR_FER(port)) { | 544 | if (status&SCxSR_FER(port)) { |
547 | tty->flip.flag_buf_ptr[i] = TTY_FRAME; | 545 | flag = TTY_FRAME; |
548 | pr_debug("sci: frame error\n"); | 546 | pr_debug("sci: frame error\n"); |
549 | } else if (status&SCxSR_PER(port)) { | 547 | } else if (status&SCxSR_PER(port)) { |
550 | tty->flip.flag_buf_ptr[i] = TTY_PARITY; | 548 | flag = TTY_PARITY; |
551 | pr_debug("sci: parity error\n"); | 549 | pr_debug("sci: parity error\n"); |
552 | } else { | 550 | } else |
553 | tty->flip.flag_buf_ptr[i] = TTY_NORMAL; | 551 | flag = TTY_NORMAL; |
554 | } | 552 | tty_insert_flip_char(tty, c, flag); |
555 | } | 553 | } |
556 | } | 554 | } |
557 | 555 | ||
558 | sci_in(port, SCxSR); /* dummy read */ | 556 | sci_in(port, SCxSR); /* dummy read */ |
559 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 557 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
560 | 558 | ||
561 | /* Update the kernel buffer end */ | ||
562 | tty->flip.count += count; | ||
563 | tty->flip.char_buf_ptr += count; | ||
564 | tty->flip.flag_buf_ptr += count; | ||
565 | copied += count; | 559 | copied += count; |
566 | port->icount.rx += count; | 560 | port->icount.rx += count; |
567 | } | 561 | } |
@@ -608,48 +602,45 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
608 | unsigned short status = sci_in(port, SCxSR); | 602 | unsigned short status = sci_in(port, SCxSR); |
609 | struct tty_struct *tty = port->info->tty; | 603 | struct tty_struct *tty = port->info->tty; |
610 | 604 | ||
611 | if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 605 | if (status&SCxSR_ORER(port)) { |
612 | /* overrun error */ | 606 | /* overrun error */ |
613 | copied++; | 607 | if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) |
614 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 608 | copied++; |
615 | pr_debug("sci: overrun error\n"); | 609 | pr_debug("sci: overrun error\n"); |
616 | } | 610 | } |
617 | 611 | ||
618 | if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 612 | if (status&SCxSR_FER(port)) { |
619 | if (sci_rxd_in(port) == 0) { | 613 | if (sci_rxd_in(port) == 0) { |
620 | /* Notify of BREAK */ | 614 | /* Notify of BREAK */ |
621 | struct sci_port * sci_port = (struct sci_port *)port; | 615 | struct sci_port * sci_port = (struct sci_port *)port; |
622 | if(!sci_port->break_flag) { | 616 | if(!sci_port->break_flag) { |
623 | sci_port->break_flag = 1; | 617 | sci_port->break_flag = 1; |
624 | sci_schedule_break_timer((struct sci_port *)port); | 618 | sci_schedule_break_timer((struct sci_port *)port); |
625 | /* Do sysrq handling. */ | 619 | /* Do sysrq handling. */ |
626 | if(uart_handle_break(port)) { | 620 | if(uart_handle_break(port)) |
627 | return 0; | 621 | return 0; |
628 | } | ||
629 | pr_debug("sci: BREAK detected\n"); | 622 | pr_debug("sci: BREAK detected\n"); |
630 | copied++; | 623 | if(tty_insert_flip_char(tty, 0, TTY_BREAK)) |
631 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 624 | copied++; |
632 | } | 625 | } |
633 | } | 626 | } |
634 | else { | 627 | else { |
635 | /* frame error */ | 628 | /* frame error */ |
636 | copied++; | 629 | if(tty_insert_flip_char(tty, 0, TTY_FRAME)) |
637 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | 630 | copied++; |
638 | pr_debug("sci: frame error\n"); | 631 | pr_debug("sci: frame error\n"); |
639 | } | 632 | } |
640 | } | 633 | } |
641 | 634 | ||
642 | if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) { | 635 | if (status&SCxSR_PER(port)) { |
636 | if(tty_insert_flip_char(tty, 0, TTY_PARITY)) | ||
637 | copied++; | ||
643 | /* parity error */ | 638 | /* parity error */ |
644 | copied++; | ||
645 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | ||
646 | pr_debug("sci: parity error\n"); | 639 | pr_debug("sci: parity error\n"); |
647 | } | 640 | } |
648 | 641 | ||
649 | if (copied) { | 642 | if (copied) |
650 | tty->flip.count += copied; | ||
651 | tty_flip_buffer_push(tty); | 643 | tty_flip_buffer_push(tty); |
652 | } | ||
653 | 644 | ||
654 | return copied; | 645 | return copied; |
655 | } | 646 | } |
@@ -661,15 +652,14 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
661 | struct tty_struct *tty = port->info->tty; | 652 | struct tty_struct *tty = port->info->tty; |
662 | struct sci_port *s = &sci_ports[port->line]; | 653 | struct sci_port *s = &sci_ports[port->line]; |
663 | 654 | ||
664 | if (!s->break_flag && status & SCxSR_BRK(port) && | 655 | if (!s->break_flag && status & SCxSR_BRK(port)) |
665 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
666 | #if defined(CONFIG_CPU_SH3) | 656 | #if defined(CONFIG_CPU_SH3) |
667 | /* Debounce break */ | 657 | /* Debounce break */ |
668 | s->break_flag = 1; | 658 | s->break_flag = 1; |
669 | #endif | 659 | #endif |
670 | /* Notify of BREAK */ | 660 | /* Notify of BREAK */ |
671 | copied++; | 661 | if(tty_insert_flip_char(tty, 0, TTY_BREAK)) |
672 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | 662 | copied++; |
673 | pr_debug("sci: BREAK detected\n"); | 663 | pr_debug("sci: BREAK detected\n"); |
674 | } | 664 | } |
675 | 665 | ||
@@ -677,19 +667,15 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
677 | /* XXX: Handle SCIF overrun error */ | 667 | /* XXX: Handle SCIF overrun error */ |
678 | if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { | 668 | if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { |
679 | sci_out(port, SCLSR, 0); | 669 | sci_out(port, SCLSR, 0); |
680 | if(tty->flip.count<TTY_FLIPBUF_SIZE) { | 670 | if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { |
681 | copied++; | 671 | copied++; |
682 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | ||
683 | pr_debug("sci: overrun error\n"); | 672 | pr_debug("sci: overrun error\n"); |
684 | } | 673 | } |
685 | } | 674 | } |
686 | #endif | 675 | #endif |
687 | 676 | ||
688 | if (copied) { | 677 | if (copied) |
689 | tty->flip.count += copied; | ||
690 | tty_flip_buffer_push(tty); | 678 | tty_flip_buffer_push(tty); |
691 | } | ||
692 | |||
693 | return copied; | 679 | return copied; |
694 | } | 680 | } |
695 | 681 | ||
@@ -732,12 +718,9 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs) | |||
732 | struct tty_struct *tty = port->info->tty; | 718 | struct tty_struct *tty = port->info->tty; |
733 | 719 | ||
734 | sci_out(port, SCLSR, 0); | 720 | sci_out(port, SCLSR, 0); |
735 | if(tty->flip.count<TTY_FLIPBUF_SIZE) { | 721 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
736 | *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; | 722 | tty_flip_buffer_push(tty); |
737 | tty->flip.count++; | 723 | pr_debug("scif: overrun error\n"); |
738 | tty_flip_buffer_push(tty); | ||
739 | pr_debug("scif: overrun error\n"); | ||
740 | } | ||
741 | } | 724 | } |
742 | #endif | 725 | #endif |
743 | sci_rx_interrupt(irq, ptr, regs); | 726 | sci_rx_interrupt(irq, ptr, regs); |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 313f9df24a2d..5468e5a767e2 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -519,11 +519,7 @@ sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs, | |||
519 | 519 | ||
520 | /* record the character to pass up to the tty layer */ | 520 | /* record the character to pass up to the tty layer */ |
521 | if (tty) { | 521 | if (tty) { |
522 | *tty->flip.char_buf_ptr = ch; | 522 | if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) |
523 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
524 | tty->flip.char_buf_ptr++; | ||
525 | tty->flip.count++; | ||
526 | if (tty->flip.count == TTY_FLIPBUF_SIZE) | ||
527 | break; | 523 | break; |
528 | } | 524 | } |
529 | port->sc_port.icount.rx++; | 525 | port->sc_port.icount.rx++; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index ba9381fd3f2d..7e773ff76c61 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -159,21 +159,14 @@ receive_chars(struct uart_sunsab_port *up, | |||
159 | saw_console_brk = 1; | 159 | saw_console_brk = 1; |
160 | 160 | ||
161 | for (i = 0; i < count; i++) { | 161 | for (i = 0; i < count; i++) { |
162 | unsigned char ch = buf[i]; | 162 | unsigned char ch = buf[i], flag; |
163 | 163 | ||
164 | if (tty == NULL) { | 164 | if (tty == NULL) { |
165 | uart_handle_sysrq_char(&up->port, ch, regs); | 165 | uart_handle_sysrq_char(&up->port, ch, regs); |
166 | continue; | 166 | continue; |
167 | } | 167 | } |
168 | 168 | ||
169 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | 169 | flag = TTY_NORMAL; |
170 | tty->flip.work.func((void *)tty); | ||
171 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
172 | return tty; // if TTY_DONT_FLIP is set | ||
173 | } | ||
174 | |||
175 | *tty->flip.char_buf_ptr = ch; | ||
176 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
177 | up->port.icount.rx++; | 170 | up->port.icount.rx++; |
178 | 171 | ||
179 | if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR | | 172 | if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR | |
@@ -209,34 +202,21 @@ receive_chars(struct uart_sunsab_port *up, | |||
209 | stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff); | 202 | stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff); |
210 | 203 | ||
211 | if (stat->sreg.isr1 & SAB82532_ISR1_BRK) { | 204 | if (stat->sreg.isr1 & SAB82532_ISR1_BRK) { |
212 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 205 | flag = TTY_BREAK; |
213 | } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR) | 206 | } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR) |
214 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 207 | flag = TTY_PARITY; |
215 | else if (stat->sreg.isr0 & SAB82532_ISR0_FERR) | 208 | else if (stat->sreg.isr0 & SAB82532_ISR0_FERR) |
216 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 209 | flag = TTY_FRAME; |
217 | } | 210 | } |
218 | 211 | ||
219 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 212 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
220 | continue; | 213 | continue; |
221 | 214 | ||
222 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 215 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
223 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0){ | 216 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) |
224 | tty->flip.flag_buf_ptr++; | 217 | tty_insert_flip_char(tty, ch, flag); |
225 | tty->flip.char_buf_ptr++; | 218 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
226 | tty->flip.count++; | 219 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
227 | } | ||
228 | if ((stat->sreg.isr0 & SAB82532_ISR0_RFO) && | ||
229 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
230 | /* | ||
231 | * Overrun is special, since it's reported | ||
232 | * immediately, and doesn't affect the current | ||
233 | * character. | ||
234 | */ | ||
235 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
236 | tty->flip.flag_buf_ptr++; | ||
237 | tty->flip.char_buf_ptr++; | ||
238 | tty->flip.count++; | ||
239 | } | ||
240 | } | 220 | } |
241 | 221 | ||
242 | if (saw_console_brk) | 222 | if (saw_console_brk) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index f0738533f39a..9a3665b34d97 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -323,19 +323,13 @@ static _INLINE_ struct tty_struct * | |||
323 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) | 323 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) |
324 | { | 324 | { |
325 | struct tty_struct *tty = up->port.info->tty; | 325 | struct tty_struct *tty = up->port.info->tty; |
326 | unsigned char ch; | 326 | unsigned char ch, flag; |
327 | int max_count = 256; | 327 | int max_count = 256; |
328 | int saw_console_brk = 0; | 328 | int saw_console_brk = 0; |
329 | 329 | ||
330 | do { | 330 | do { |
331 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
332 | tty->flip.work.func((void *)tty); | ||
333 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
334 | return tty; // if TTY_DONT_FLIP is set | ||
335 | } | ||
336 | ch = serial_inp(up, UART_RX); | 331 | ch = serial_inp(up, UART_RX); |
337 | *tty->flip.char_buf_ptr = ch; | 332 | flag = TTY_NORMAL; |
338 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
339 | up->port.icount.rx++; | 333 | up->port.icount.rx++; |
340 | 334 | ||
341 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | 335 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | |
@@ -377,31 +371,23 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs | |||
377 | } | 371 | } |
378 | 372 | ||
379 | if (*status & UART_LSR_BI) { | 373 | if (*status & UART_LSR_BI) { |
380 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 374 | flag = TTY_BREAK; |
381 | } else if (*status & UART_LSR_PE) | 375 | } else if (*status & UART_LSR_PE) |
382 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 376 | flag = TTY_PARITY; |
383 | else if (*status & UART_LSR_FE) | 377 | else if (*status & UART_LSR_FE) |
384 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 378 | flag = TTY_FRAME; |
385 | } | 379 | } |
386 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 380 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
387 | goto ignore_char; | 381 | goto ignore_char; |
388 | if ((*status & up->port.ignore_status_mask) == 0) { | 382 | if ((*status & up->port.ignore_status_mask) == 0) |
389 | tty->flip.flag_buf_ptr++; | 383 | tty_insert_flip_char(tty, ch, flag); |
390 | tty->flip.char_buf_ptr++; | 384 | if (*status & UART_LSR_OE) |
391 | tty->flip.count++; | ||
392 | } | ||
393 | if ((*status & UART_LSR_OE) && | ||
394 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
395 | /* | 385 | /* |
396 | * Overrun is special, since it's reported | 386 | * Overrun is special, since it's reported |
397 | * immediately, and doesn't affect the current | 387 | * immediately, and doesn't affect the current |
398 | * character. | 388 | * character. |
399 | */ | 389 | */ |
400 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | 390 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
401 | tty->flip.flag_buf_ptr++; | ||
402 | tty->flip.char_buf_ptr++; | ||
403 | tty->flip.count++; | ||
404 | } | ||
405 | ignore_char: | 391 | ignore_char: |
406 | *status = serial_inp(up, UART_LSR); | 392 | *status = serial_inp(up, UART_LSR); |
407 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 393 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 7653d6cf05af..3c72484adea7 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -319,7 +319,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
319 | struct pt_regs *regs) | 319 | struct pt_regs *regs) |
320 | { | 320 | { |
321 | struct tty_struct *tty; | 321 | struct tty_struct *tty; |
322 | unsigned char ch, r1; | 322 | unsigned char ch, r1, flag; |
323 | 323 | ||
324 | tty = NULL; | 324 | tty = NULL; |
325 | if (up->port.info != NULL && /* Unopened serial console */ | 325 | if (up->port.info != NULL && /* Unopened serial console */ |
@@ -362,19 +362,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
362 | continue; | 362 | continue; |
363 | } | 363 | } |
364 | 364 | ||
365 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
366 | tty->flip.work.func((void *)tty); | ||
367 | /* | ||
368 | * The 8250 bails out of the loop here, | ||
369 | * but we need to read everything, or die. | ||
370 | */ | ||
371 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
372 | continue; | ||
373 | } | ||
374 | |||
375 | /* A real serial line, record the character and status. */ | 365 | /* A real serial line, record the character and status. */ |
376 | *tty->flip.char_buf_ptr = ch; | 366 | flag = TTY_NORMAL; |
377 | *tty->flip.flag_buf_ptr = TTY_NORMAL; | ||
378 | up->port.icount.rx++; | 367 | up->port.icount.rx++; |
379 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { | 368 | if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) { |
380 | if (r1 & BRK_ABRT) { | 369 | if (r1 & BRK_ABRT) { |
@@ -391,28 +380,21 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
391 | up->port.icount.overrun++; | 380 | up->port.icount.overrun++; |
392 | r1 &= up->port.read_status_mask; | 381 | r1 &= up->port.read_status_mask; |
393 | if (r1 & BRK_ABRT) | 382 | if (r1 & BRK_ABRT) |
394 | *tty->flip.flag_buf_ptr = TTY_BREAK; | 383 | flag = TTY_BREAK; |
395 | else if (r1 & PAR_ERR) | 384 | else if (r1 & PAR_ERR) |
396 | *tty->flip.flag_buf_ptr = TTY_PARITY; | 385 | flag = TTY_PARITY; |
397 | else if (r1 & CRC_ERR) | 386 | else if (r1 & CRC_ERR) |
398 | *tty->flip.flag_buf_ptr = TTY_FRAME; | 387 | flag = TTY_FRAME; |
399 | } | 388 | } |
400 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 389 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
401 | continue; | 390 | continue; |
402 | 391 | ||
403 | if (up->port.ignore_status_mask == 0xff || | 392 | if (up->port.ignore_status_mask == 0xff || |
404 | (r1 & up->port.ignore_status_mask) == 0) { | 393 | (r1 & up->port.ignore_status_mask) == 0) { |
405 | tty->flip.flag_buf_ptr++; | 394 | tty_insert_flip_char(tty, ch, flag); |
406 | tty->flip.char_buf_ptr++; | ||
407 | tty->flip.count++; | ||
408 | } | ||
409 | if ((r1 & Rx_OVR) && | ||
410 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
411 | *tty->flip.flag_buf_ptr = TTY_OVERRUN; | ||
412 | tty->flip.flag_buf_ptr++; | ||
413 | tty->flip.char_buf_ptr++; | ||
414 | tty->flip.count++; | ||
415 | } | 395 | } |
396 | if (r1 & Rx_OVR) | ||
397 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
416 | } | 398 | } |
417 | 399 | ||
418 | return tty; | 400 | return tty; |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 865d4dea65df..0a28deeb098d 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -371,11 +371,6 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status, | |||
371 | lsr = *status; | 371 | lsr = *status; |
372 | 372 | ||
373 | do { | 373 | do { |
374 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | ||
375 | if (tty->low_latency) | ||
376 | tty_flip_buffer_push(tty); | ||
377 | } | ||
378 | |||
379 | ch = siu_read(port, UART_RX); | 374 | ch = siu_read(port, UART_RX); |
380 | port->icount.rx++; | 375 | port->icount.rx++; |
381 | flag = TTY_NORMAL; | 376 | flag = TTY_NORMAL; |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index b28336148658..c1b47d74e206 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -532,9 +532,9 @@ static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs) | |||
532 | int ret = int_urb->status; | 532 | int ret = int_urb->status; |
533 | 533 | ||
534 | /* The magic interrupt for "up state" */ | 534 | /* The magic interrupt for "up state" */ |
535 | const static unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; | 535 | static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; |
536 | /* The magic interrupt for "down state" */ | 536 | /* The magic interrupt for "down state" */ |
537 | const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 537 | static const unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
538 | 538 | ||
539 | atm_dbg(usbatm, "%s entered\n", __func__); | 539 | atm_dbg(usbatm, "%s entered\n", __func__); |
540 | 540 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 248279e44c99..b9fd39fd1b5b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -335,14 +335,9 @@ next_buffer: | |||
335 | 335 | ||
336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); | 336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); |
337 | 337 | ||
338 | for (i = 0; i < buf->size && !acm->throttle; i++) { | 338 | tty_buffer_request_room(tty, buf->size); |
339 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 339 | if (!acm->throttle) |
340 | we drop them. */ | 340 | tty_insert_flip_string(tty, buf->base, buf->size); |
341 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
342 | tty_flip_buffer_push(tty); | ||
343 | } | ||
344 | tty_insert_flip_char(tty, buf->base[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(tty); |
347 | 342 | ||
348 | spin_lock(&acm->throttle_lock); | 343 | spin_lock(&acm->throttle_lock); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 65e084a2c87e..2e6926b33455 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -1271,6 +1271,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1271 | unsigned int len; | 1271 | unsigned int len; |
1272 | struct gs_port *port; | 1272 | struct gs_port *port; |
1273 | int ret; | 1273 | int ret; |
1274 | struct tty_struct *tty; | ||
1274 | 1275 | ||
1275 | /* TEMPORARY -- only port 0 is supported right now */ | 1276 | /* TEMPORARY -- only port 0 is supported right now */ |
1276 | port = dev->dev_port[0]; | 1277 | port = dev->dev_port[0]; |
@@ -1290,7 +1291,10 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1290 | goto exit; | 1291 | goto exit; |
1291 | } | 1292 | } |
1292 | 1293 | ||
1293 | if (port->port_tty == NULL) { | 1294 | |
1295 | tty = port->port_tty; | ||
1296 | |||
1297 | if (tty == NULL) { | ||
1294 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", | 1298 | printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n", |
1295 | port->port_num); | 1299 | port->port_num); |
1296 | ret = -EIO; | 1300 | ret = -EIO; |
@@ -1304,20 +1308,13 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size) | |||
1304 | goto exit; | 1308 | goto exit; |
1305 | } | 1309 | } |
1306 | 1310 | ||
1307 | len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count); | 1311 | len = tty_buffer_request_room(tty, size); |
1308 | if (len < size) | 1312 | if (len > 0) { |
1309 | size = len; | 1313 | tty_insert_flip_string(tty, packet, len); |
1310 | |||
1311 | if (size > 0) { | ||
1312 | memcpy(port->port_tty->flip.char_buf_ptr, packet, size); | ||
1313 | port->port_tty->flip.char_buf_ptr += size; | ||
1314 | port->port_tty->flip.count += size; | ||
1315 | tty_flip_buffer_push(port->port_tty); | 1314 | tty_flip_buffer_push(port->port_tty); |
1316 | wake_up_interruptible(&port->port_tty->read_wait); | 1315 | wake_up_interruptible(&port->port_tty->read_wait); |
1317 | } | 1316 | } |
1318 | |||
1319 | ret = 0; | 1317 | ret = 0; |
1320 | |||
1321 | exit: | 1318 | exit: |
1322 | spin_unlock(&port->port_lock); | 1319 | spin_unlock(&port->port_lock); |
1323 | return ret; | 1320 | return ret; |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 458f2acdeb0a..28538db9eaf3 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -674,7 +674,7 @@ struct vendor_product | |||
674 | 674 | ||
675 | 675 | ||
676 | /* These are taken from the msmUSB.inf file on the Windows driver CD */ | 676 | /* These are taken from the msmUSB.inf file on the Windows driver CD */ |
677 | const static struct vendor_product mts_supported_products[] = | 677 | static const struct vendor_product mts_supported_products[] = |
678 | { | 678 | { |
679 | { "Phantom 336CX", mts_sup_unknown}, | 679 | { "Phantom 336CX", mts_sup_unknown}, |
680 | { "Phantom 336CX", mts_sup_unknown}, | 680 | { "Phantom 336CX", mts_sup_unknown}, |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 14f55fd26a64..be5dc80836c3 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -84,7 +84,7 @@ config USB_SERIAL_BELKIN | |||
84 | 84 | ||
85 | config USB_SERIAL_WHITEHEAT | 85 | config USB_SERIAL_WHITEHEAT |
86 | tristate "USB ConnectTech WhiteHEAT Serial Driver" | 86 | tristate "USB ConnectTech WhiteHEAT Serial Driver" |
87 | depends on USB_SERIAL && BROKEN_ON_SMP | 87 | depends on USB_SERIAL |
88 | help | 88 | help |
89 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port | 89 | Say Y here if you want to use a ConnectTech WhiteHEAT 4 port |
90 | USB to serial converter device. | 90 | USB to serial converter device. |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 6d18d4eaba35..2357b1d102d7 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -364,7 +364,6 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
364 | struct tty_struct *tty; | 364 | struct tty_struct *tty; |
365 | unsigned char *data = urb->transfer_buffer; | 365 | unsigned char *data = urb->transfer_buffer; |
366 | short todo; | 366 | short todo; |
367 | int i; | ||
368 | int result; | 367 | int result; |
369 | 368 | ||
370 | dbg("%s - port %d", __FUNCTION__, port->number); | 369 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -381,14 +380,8 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
381 | return; | 380 | return; |
382 | } | 381 | } |
383 | if (urb->actual_length) { | 382 | if (urb->actual_length) { |
384 | for (i = 0; i < urb->actual_length ; ++i) { | 383 | tty_buffer_request_room(tty, urb->actual_length); |
385 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 384 | tty_insert_flip_string(tty, data, urb->actual_length); |
386 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
387 | tty_flip_buffer_push(tty); | ||
388 | } | ||
389 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
390 | tty_insert_flip_char(tty, data[i], 0); | ||
391 | } | ||
392 | tty_flip_buffer_push(tty); | 385 | tty_flip_buffer_push(tty); |
393 | } | 386 | } |
394 | 387 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4e9637eb6137..68067fe117a4 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1263,12 +1263,10 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
1263 | 1263 | ||
1264 | /* process read if there is data other than line status */ | 1264 | /* process read if there is data other than line status */ |
1265 | if (tty && (bytes > i)) { | 1265 | if (tty && (bytes > i)) { |
1266 | bytes = tty_buffer_request_room(tty, bytes); | ||
1266 | for (; i < bytes ; ++i) { | 1267 | for (; i < bytes ; ++i) { |
1267 | dbg("pushing byte number %d - %d - %c", i, data[i], | 1268 | dbg("pushing byte number %d - %d - %c", i, data[i], |
1268 | data[i]); | 1269 | data[i]); |
1269 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
1270 | tty_flip_buffer_push(tty); | ||
1271 | } | ||
1272 | tty_insert_flip_char(tty, data[i], tty_flag); | 1270 | tty_insert_flip_char(tty, data[i], tty_flag); |
1273 | } | 1271 | } |
1274 | tty_flip_buffer_push(port->tty); | 1272 | tty_flip_buffer_push(port->tty); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 8fc414bd5b24..b3f776a90c93 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -946,13 +946,10 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); | |||
946 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 946 | spin_lock_irqsave( &priv->dp_port_lock, flags ); |
947 | 947 | ||
948 | /* send any buffered chars from throttle time on to tty subsystem */ | 948 | /* send any buffered chars from throttle time on to tty subsystem */ |
949 | len = min(priv->dp_in_buf_len, TTY_FLIPBUF_SIZE - tty->flip.count ); | 949 | |
950 | len = tty_buffer_request_room(tty, priv->dp_in_buf_len); | ||
950 | if( len > 0 ) { | 951 | if( len > 0 ) { |
951 | memcpy( tty->flip.char_buf_ptr, priv->dp_in_buf, len ); | 952 | tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len); |
952 | memcpy( tty->flip.flag_buf_ptr, priv->dp_in_flag_buf, len ); | ||
953 | tty->flip.char_buf_ptr += len; | ||
954 | tty->flip.flag_buf_ptr += len; | ||
955 | tty->flip.count += len; | ||
956 | tty_flip_buffer_push( tty ); | 953 | tty_flip_buffer_push( tty ); |
957 | } | 954 | } |
958 | 955 | ||
@@ -1827,6 +1824,7 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1827 | int status = ((unsigned char *)urb->transfer_buffer)[2]; | 1824 | int status = ((unsigned char *)urb->transfer_buffer)[2]; |
1828 | unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; | 1825 | unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; |
1829 | int flag,throttled; | 1826 | int flag,throttled; |
1827 | int i; | ||
1830 | 1828 | ||
1831 | /* do not process callbacks on closed ports */ | 1829 | /* do not process callbacks on closed ports */ |
1832 | /* but do continue the read chain */ | 1830 | /* but do continue the read chain */ |
@@ -1885,20 +1883,18 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1885 | } | 1883 | } |
1886 | 1884 | ||
1887 | } else { | 1885 | } else { |
1888 | 1886 | len = tty_buffer_request_room(tty, len); | |
1889 | len = min( len, TTY_FLIPBUF_SIZE - tty->flip.count ); | ||
1890 | |||
1891 | if( len > 0 ) { | 1887 | if( len > 0 ) { |
1892 | memcpy( tty->flip.char_buf_ptr, data, len ); | 1888 | /* Hot path */ |
1893 | memset( tty->flip.flag_buf_ptr, flag, len ); | 1889 | if(flag == TTY_NORMAL) |
1894 | tty->flip.char_buf_ptr += len; | 1890 | tty_insert_flip_string(tty, data, len); |
1895 | tty->flip.flag_buf_ptr += len; | 1891 | else { |
1896 | tty->flip.count += len; | 1892 | for(i = 0; i < len; i++) |
1893 | tty_insert_flip_char(tty, data[i], flag); | ||
1894 | } | ||
1897 | tty_flip_buffer_push( tty ); | 1895 | tty_flip_buffer_push( tty ); |
1898 | } | 1896 | } |
1899 | |||
1900 | } | 1897 | } |
1901 | |||
1902 | } | 1898 | } |
1903 | 1899 | ||
1904 | spin_unlock( &priv->dp_port_lock ); | 1900 | spin_unlock( &priv->dp_port_lock ); |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 79a766e9ca23..63f7c78a1152 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -344,7 +344,6 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
344 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 344 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
345 | struct tty_struct *tty; | 345 | struct tty_struct *tty; |
346 | unsigned char *data = urb->transfer_buffer; | 346 | unsigned char *data = urb->transfer_buffer; |
347 | int i; | ||
348 | int result; | 347 | int result; |
349 | 348 | ||
350 | dbg("%s - port %d", __FUNCTION__, port->number); | 349 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -359,19 +358,8 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
359 | tty = port->tty; | 358 | tty = port->tty; |
360 | 359 | ||
361 | if (urb->actual_length) { | 360 | if (urb->actual_length) { |
362 | for (i = 0; i < urb->actual_length ; ++i) { | 361 | tty_buffer_request_room(tty, urb->actual_length); |
363 | /* gb - 2000/11/13 | 362 | tty_insert_flip_string(tty, data, urb->actual_length); |
364 | * If we insert too many characters we'll overflow the buffer. | ||
365 | * This means we'll lose bytes - Decidedly bad. | ||
366 | */ | ||
367 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
368 | tty_flip_buffer_push(tty); | ||
369 | } | ||
370 | tty_insert_flip_char(tty, data[i], 0); | ||
371 | } | ||
372 | /* gb - 2000/11/13 | ||
373 | * Goes straight through instead of scheduling - if tty->low_latency is set. | ||
374 | */ | ||
375 | tty_flip_buffer_push(tty); | 363 | tty_flip_buffer_push(tty); |
376 | bytes_in += urb->actual_length; | 364 | bytes_in += urb->actual_length; |
377 | } | 365 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index eb863b3f2d79..10bc1bf23b35 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1610,24 +1610,11 @@ static void ftdi_process_read (void *param) | |||
1610 | length = 0; | 1610 | length = 0; |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | /* have to make sure we don't overflow the buffer | ||
1614 | with tty_insert_flip_char's */ | ||
1615 | if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { | ||
1616 | tty_flip_buffer_push(tty); | ||
1617 | need_flip = 0; | ||
1618 | |||
1619 | if (tty->flip.count != 0) { | ||
1620 | /* flip didn't work, this happens when ftdi_process_read() is | ||
1621 | * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ | ||
1622 | dbg("%s - flip buffer push failed", __FUNCTION__); | ||
1623 | break; | ||
1624 | } | ||
1625 | } | ||
1626 | if (priv->rx_flags & THROTTLED) { | 1613 | if (priv->rx_flags & THROTTLED) { |
1627 | dbg("%s - throttled", __FUNCTION__); | 1614 | dbg("%s - throttled", __FUNCTION__); |
1628 | break; | 1615 | break; |
1629 | } | 1616 | } |
1630 | if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { | 1617 | if (tty_buffer_request_room(tty, length) < length) { |
1631 | /* break out & wait for throttling/unthrottling to happen */ | 1618 | /* break out & wait for throttling/unthrottling to happen */ |
1632 | dbg("%s - receive room low", __FUNCTION__); | 1619 | dbg("%s - receive room low", __FUNCTION__); |
1633 | break; | 1620 | break; |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 452efce72714..d6f55e9dccae 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -275,23 +275,14 @@ static void send_to_tty(struct usb_serial_port *port, | |||
275 | char *data, unsigned int actual_length) | 275 | char *data, unsigned int actual_length) |
276 | { | 276 | { |
277 | struct tty_struct *tty = port->tty; | 277 | struct tty_struct *tty = port->tty; |
278 | int i; | ||
279 | 278 | ||
280 | if (tty && actual_length) { | 279 | if (tty && actual_length) { |
281 | 280 | ||
282 | usb_serial_debug_data(debug, &port->dev, | 281 | usb_serial_debug_data(debug, &port->dev, |
283 | __FUNCTION__, actual_length, data); | 282 | __FUNCTION__, actual_length, data); |
284 | 283 | ||
285 | for (i = 0; i < actual_length ; ++i) { | 284 | tty_buffer_request_room(tty, actual_length); |
286 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 285 | tty_insert_flip_string(tty, data, actual_length); |
287 | we drop them. */ | ||
288 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
289 | tty_flip_buffer_push(tty); | ||
290 | } | ||
291 | /* this doesn't actually push the data through unless | ||
292 | tty->low_latency is set */ | ||
293 | tty_insert_flip_char(tty, data[i], 0); | ||
294 | } | ||
295 | tty_flip_buffer_push(tty); | 286 | tty_flip_buffer_push(tty); |
296 | } | 287 | } |
297 | } | 288 | } |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 4ddac620fc0c..476cda107f4f 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -254,7 +254,6 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg | |||
254 | struct usb_serial *serial = port->serial; | 254 | struct usb_serial *serial = port->serial; |
255 | struct tty_struct *tty; | 255 | struct tty_struct *tty; |
256 | unsigned char *data = urb->transfer_buffer; | 256 | unsigned char *data = urb->transfer_buffer; |
257 | int i; | ||
258 | int result; | 257 | int result; |
259 | 258 | ||
260 | dbg("%s - port %d", __FUNCTION__, port->number); | 259 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -268,14 +267,8 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg | |||
268 | 267 | ||
269 | tty = port->tty; | 268 | tty = port->tty; |
270 | if (tty && urb->actual_length) { | 269 | if (tty && urb->actual_length) { |
271 | for (i = 0; i < urb->actual_length ; ++i) { | 270 | tty_buffer_request_room(tty, urb->actual_length); |
272 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 271 | tty_insert_flip_string(tty, data, urb->actual_length); |
273 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
274 | tty_flip_buffer_push(tty); | ||
275 | } | ||
276 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
277 | tty_insert_flip_char(tty, data[i], 0); | ||
278 | } | ||
279 | tty_flip_buffer_push(tty); | 272 | tty_flip_buffer_push(tty); |
280 | } | 273 | } |
281 | 274 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index faedbeb6ba49..3f29e6b0fd19 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -1965,20 +1965,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c | |||
1965 | int cnt; | 1965 | int cnt; |
1966 | 1966 | ||
1967 | do { | 1967 | do { |
1968 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1968 | cnt = tty_buffer_request_room(tty, length); |
1969 | tty_flip_buffer_push(tty); | 1969 | if (cnt < length) { |
1970 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1970 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
1971 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1971 | __FUNCTION__, length - cnt); |
1972 | __FUNCTION__, length); | 1972 | if(cnt == 0) |
1973 | return; | 1973 | break; |
1974 | } | ||
1975 | } | 1974 | } |
1976 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1975 | tty_insert_flip_string(tty, data, cnt); |
1977 | memcpy(tty->flip.char_buf_ptr, data, cnt); | ||
1978 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1979 | tty->flip.char_buf_ptr += cnt; | ||
1980 | tty->flip.flag_buf_ptr += cnt; | ||
1981 | tty->flip.count += cnt; | ||
1982 | data += cnt; | 1976 | data += cnt; |
1983 | length -= cnt; | 1977 | length -= cnt; |
1984 | } while (length > 0); | 1978 | } while (length > 0); |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 2edf9cabad20..afc0f34b3a46 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1865,20 +1865,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c | |||
1865 | int cnt; | 1865 | int cnt; |
1866 | 1866 | ||
1867 | do { | 1867 | do { |
1868 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1868 | cnt = tty_buffer_request_room(tty, length); |
1869 | tty_flip_buffer_push(tty); | 1869 | if (cnt < length) { |
1870 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1870 | dev_err(dev, "%s - dropping data, %d bytes lost\n", |
1871 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1871 | __FUNCTION__, length - cnt); |
1872 | __FUNCTION__, length); | 1872 | if(cnt == 0) |
1873 | return; | 1873 | break; |
1874 | } | ||
1875 | } | 1874 | } |
1876 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1875 | tty_insert_flip_string(tty, data, cnt); |
1877 | memcpy(tty->flip.char_buf_ptr, data, cnt); | ||
1878 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1879 | tty->flip.char_buf_ptr += cnt; | ||
1880 | tty->flip.flag_buf_ptr += cnt; | ||
1881 | tty->flip.count += cnt; | ||
1882 | data += cnt; | 1876 | data += cnt; |
1883 | length -= cnt; | 1877 | length -= cnt; |
1884 | } while (length > 0); | 1878 | } while (length > 0); |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 06d07cea0b70..9a5c97989562 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -711,7 +711,7 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
711 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 711 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
712 | struct tty_struct *tty; | 712 | struct tty_struct *tty; |
713 | unsigned char *data = urb->transfer_buffer; | 713 | unsigned char *data = urb->transfer_buffer; |
714 | int i, result; | 714 | int result; |
715 | 715 | ||
716 | dbg("%s - port %d", __FUNCTION__, port->number); | 716 | dbg("%s - port %d", __FUNCTION__, port->number); |
717 | 717 | ||
@@ -724,14 +724,8 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
724 | 724 | ||
725 | tty = port->tty; | 725 | tty = port->tty; |
726 | if (tty && urb->actual_length) { | 726 | if (tty && urb->actual_length) { |
727 | for (i = 0; i < urb->actual_length ; ++i) { | 727 | tty_buffer_request_room(tty, urb->actual_length); |
728 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 728 | tty_insert_flip_string(tty, data, urb->actual_length); |
729 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
730 | tty_flip_buffer_push(tty); | ||
731 | } | ||
732 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
733 | tty_insert_flip_char(tty, data[i], 0); | ||
734 | } | ||
735 | tty_flip_buffer_push(tty); | 729 | tty_flip_buffer_push(tty); |
736 | bytes_in += urb->actual_length; | 730 | bytes_in += urb->actual_length; |
737 | } | 731 | } |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 2dd191f5fe76..e760a70242c1 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -166,7 +166,6 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
166 | struct usb_serial_port *port = urb->context; | 166 | struct usb_serial_port *port = urb->context; |
167 | unsigned char *data = urb->transfer_buffer; | 167 | unsigned char *data = urb->transfer_buffer; |
168 | struct tty_struct *tty; | 168 | struct tty_struct *tty; |
169 | int i; | ||
170 | int result; | 169 | int result; |
171 | 170 | ||
172 | dbg("%s - port %d", __FUNCTION__, port->number); | 171 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -180,14 +179,8 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
180 | 179 | ||
181 | tty = port->tty; | 180 | tty = port->tty; |
182 | if (tty && urb->actual_length) { | 181 | if (tty && urb->actual_length) { |
183 | for (i = 0; i < urb->actual_length ; ++i) { | 182 | tty_buffer_request_room(tty, urb->actual_length); |
184 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 183 | tty_insert_flip_string(tty, data, urb->actual_length); |
185 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
186 | tty_flip_buffer_push(tty); | ||
187 | } | ||
188 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
189 | tty_insert_flip_char(tty, data[i], 0); | ||
190 | } | ||
191 | tty_flip_buffer_push(tty); | 184 | tty_flip_buffer_push(tty); |
192 | } | 185 | } |
193 | 186 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 4e2f7dfb58b2..78335a5f7743 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -648,7 +648,6 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
648 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, | 648 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, |
649 | urb->actual_length, data); | 649 | urb->actual_length, data); |
650 | } else { | 650 | } else { |
651 | int i; | ||
652 | int bytes_sent = ((__u8 *) data)[0] + | 651 | int bytes_sent = ((__u8 *) data)[0] + |
653 | ((unsigned int) ((__u8 *) data)[1] << 8); | 652 | ((unsigned int) ((__u8 *) data)[1] << 8); |
654 | tty = port->tty; | 653 | tty = port->tty; |
@@ -669,16 +668,8 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
669 | bytes_sent = urb->actual_length - 2; | 668 | bytes_sent = urb->actual_length - 2; |
670 | } | 669 | } |
671 | 670 | ||
672 | for (i = 2; i < 2+bytes_sent; i++) { | 671 | tty_buffer_request_room(tty, bytes_sent); |
673 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 672 | tty_insert_flip_string(tty, data + 2, bytes_sent); |
674 | * we drop them. */ | ||
675 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
676 | tty_flip_buffer_push(tty); | ||
677 | } | ||
678 | /* this doesn't actually push the data through unless | ||
679 | * tty->low_latency is set */ | ||
680 | tty_insert_flip_char(tty, ((__u8*) data)[i], 0); | ||
681 | } | ||
682 | tty_flip_buffer_push(tty); | 673 | tty_flip_buffer_push(tty); |
683 | 674 | ||
684 | /* again lockless, but debug info only */ | 675 | /* again lockless, but debug info only */ |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index d9c21e275130..b8b213185d0f 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -365,7 +365,6 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp) | |||
365 | 365 | ||
366 | static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) | 366 | static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) |
367 | { | 367 | { |
368 | int i; | ||
369 | int result; | 368 | int result; |
370 | struct usb_serial_port *port = (struct usb_serial_port *) purb->context; | 369 | struct usb_serial_port *port = (struct usb_serial_port *) purb->context; |
371 | struct tty_struct *tty; | 370 | struct tty_struct *tty; |
@@ -397,14 +396,8 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) | |||
397 | */ | 396 | */ |
398 | // END DEBUG | 397 | // END DEBUG |
399 | 398 | ||
400 | for (i = 0; i < purb->actual_length; ++i) { | 399 | tty_buffer_request_room(tty, purb->actual_length); |
401 | // if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. | 400 | tty_insert_flip_string(tty, data, purb->actual_length); |
402 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
403 | tty_flip_buffer_push(tty); | ||
404 | } | ||
405 | // this doesn't actually push the data through unless tty->low_latency is set | ||
406 | tty_insert_flip_char(tty, data[i], 0); | ||
407 | } | ||
408 | tty_flip_buffer_push(tty); | 401 | tty_flip_buffer_push(tty); |
409 | } | 402 | } |
410 | 403 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3fd2405304fd..52bdf6fe46f2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -321,7 +321,7 @@ static int option_write(struct usb_serial_port *port, | |||
321 | 321 | ||
322 | static void option_indat_callback(struct urb *urb, struct pt_regs *regs) | 322 | static void option_indat_callback(struct urb *urb, struct pt_regs *regs) |
323 | { | 323 | { |
324 | int i, err; | 324 | int err; |
325 | int endpoint; | 325 | int endpoint; |
326 | struct usb_serial_port *port; | 326 | struct usb_serial_port *port; |
327 | struct tty_struct *tty; | 327 | struct tty_struct *tty; |
@@ -338,11 +338,8 @@ static void option_indat_callback(struct urb *urb, struct pt_regs *regs) | |||
338 | } else { | 338 | } else { |
339 | tty = port->tty; | 339 | tty = port->tty; |
340 | if (urb->actual_length) { | 340 | if (urb->actual_length) { |
341 | for (i = 0; i < urb->actual_length ; ++i) { | 341 | tty_buffer_request_room(tty, urb->actual_length); |
342 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | 342 | tty_insert_flip_string(tty, data, urb->actual_length); |
343 | tty_flip_buffer_push(tty); | ||
344 | tty_insert_flip_char(tty, data[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | 343 | tty_flip_buffer_push(tty); |
347 | } else { | 344 | } else { |
348 | dbg("%s: empty read urb received", __FUNCTION__); | 345 | dbg("%s: empty read urb received", __FUNCTION__); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f03721056190..9ffff1938239 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -924,16 +924,12 @@ static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
924 | 924 | ||
925 | tty = port->tty; | 925 | tty = port->tty; |
926 | if (tty && urb->actual_length) { | 926 | if (tty && urb->actual_length) { |
927 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
927 | /* overrun is special, not associated with a char */ | 928 | /* overrun is special, not associated with a char */ |
928 | if (status & UART_OVERRUN_ERROR) | 929 | if (status & UART_OVERRUN_ERROR) |
929 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 930 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
930 | 931 | for (i = 0; i < urb->actual_length; ++i) | |
931 | for (i = 0; i < urb->actual_length; ++i) { | ||
932 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
933 | tty_flip_buffer_push(tty); | ||
934 | } | ||
935 | tty_insert_flip_char (tty, data[i], tty_flag); | 932 | tty_insert_flip_char (tty, data[i], tty_flag); |
936 | } | ||
937 | tty_flip_buffer_push (tty); | 933 | tty_flip_buffer_push (tty); |
938 | } | 934 | } |
939 | 935 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index abb830cb77bd..c18db3257073 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -1280,24 +1280,18 @@ static void ti_recv(struct device *dev, struct tty_struct *tty, | |||
1280 | int cnt; | 1280 | int cnt; |
1281 | 1281 | ||
1282 | do { | 1282 | do { |
1283 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1283 | cnt = tty_buffer_request_room(tty, length); |
1284 | tty_flip_buffer_push(tty); | 1284 | if (cnt < length) { |
1285 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 1285 | dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length - cnt); |
1286 | dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length); | 1286 | if(cnt == 0) |
1287 | return; | 1287 | break; |
1288 | } | ||
1289 | } | 1288 | } |
1290 | cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count); | 1289 | tty_insert_flip_string(tty, data, cnt); |
1291 | memcpy(tty->flip.char_buf_ptr, data, cnt); | 1290 | tty_flip_buffer_push(tty); |
1292 | memset(tty->flip.flag_buf_ptr, 0, cnt); | ||
1293 | tty->flip.char_buf_ptr += cnt; | ||
1294 | tty->flip.flag_buf_ptr += cnt; | ||
1295 | tty->flip.count += cnt; | ||
1296 | data += cnt; | 1291 | data += cnt; |
1297 | length -= cnt; | 1292 | length -= cnt; |
1298 | } while (length > 0); | 1293 | } while (length > 0); |
1299 | 1294 | ||
1300 | tty_flip_buffer_push(tty); | ||
1301 | } | 1295 | } |
1302 | 1296 | ||
1303 | 1297 | ||
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 49b1fbe61f25..bce3d55affd8 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -488,7 +488,6 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
488 | unsigned char *data = urb->transfer_buffer; | 488 | unsigned char *data = urb->transfer_buffer; |
489 | struct tty_struct *tty; | 489 | struct tty_struct *tty; |
490 | unsigned long flags; | 490 | unsigned long flags; |
491 | int i; | ||
492 | int throttled; | 491 | int throttled; |
493 | int result; | 492 | int result; |
494 | 493 | ||
@@ -503,14 +502,8 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
503 | 502 | ||
504 | tty = port->tty; | 503 | tty = port->tty; |
505 | if (tty && urb->actual_length) { | 504 | if (tty && urb->actual_length) { |
506 | for (i = 0; i < urb->actual_length ; ++i) { | 505 | tty_buffer_request_room(tty, urb->actual_length); |
507 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | 506 | tty_insert_flip_string(tty, data, urb->actual_length); |
508 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
509 | tty_flip_buffer_push(tty); | ||
510 | } | ||
511 | /* this doesn't actually push the data through unless tty->low_latency is set */ | ||
512 | tty_insert_flip_char(tty, data[i], 0); | ||
513 | } | ||
514 | tty_flip_buffer_push(tty); | 507 | tty_flip_buffer_push(tty); |
515 | } | 508 | } |
516 | spin_lock_irqsave(&priv->lock, flags); | 509 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index a7c3c4734d83..557411c6e7c7 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -1434,7 +1434,9 @@ static void rx_data_softint(void *private) | |||
1434 | urb = wrap->urb; | 1434 | urb = wrap->urb; |
1435 | 1435 | ||
1436 | if (tty && urb->actual_length) { | 1436 | if (tty && urb->actual_length) { |
1437 | if (urb->actual_length > TTY_FLIPBUF_SIZE - tty->flip.count) { | 1437 | int len = tty_buffer_request_room(tty, urb->actual_length); |
1438 | /* This stuff can go away now I suspect */ | ||
1439 | if (unlikely(len < urb->actual_length)) { | ||
1438 | spin_lock_irqsave(&info->lock, flags); | 1440 | spin_lock_irqsave(&info->lock, flags); |
1439 | list_add(tmp, &info->rx_urb_q); | 1441 | list_add(tmp, &info->rx_urb_q); |
1440 | spin_unlock_irqrestore(&info->lock, flags); | 1442 | spin_unlock_irqrestore(&info->lock, flags); |
@@ -1442,11 +1444,8 @@ static void rx_data_softint(void *private) | |||
1442 | schedule_work(&info->rx_work); | 1444 | schedule_work(&info->rx_work); |
1443 | return; | 1445 | return; |
1444 | } | 1446 | } |
1445 | 1447 | tty_insert_flip_string(tty, urb->transfer_buffer, len); | |
1446 | memcpy(tty->flip.char_buf_ptr, urb->transfer_buffer, urb->actual_length); | 1448 | sent += len; |
1447 | tty->flip.char_buf_ptr += urb->actual_length; | ||
1448 | tty->flip.count += urb->actual_length; | ||
1449 | sent += urb->actual_length; | ||
1450 | } | 1449 | } |
1451 | 1450 | ||
1452 | urb->dev = port->serial->dev; | 1451 | urb->dev = port->serial->dev; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3f04427c9026..3e153d313bb0 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -993,12 +993,6 @@ config FB_ATY_GENERIC_LCD | |||
993 | Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, | 993 | Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, |
994 | Rage XC, or Rage XL chipset. | 994 | Rage XC, or Rage XL chipset. |
995 | 995 | ||
996 | config FB_ATY_XL_INIT | ||
997 | bool "Rage XL No-BIOS Init support" | ||
998 | depends on FB_ATY_CT | ||
999 | help | ||
1000 | Say Y here to support booting a Rage XL without BIOS support. | ||
1001 | |||
1002 | config FB_ATY_GX | 996 | config FB_ATY_GX |
1003 | bool "Mach64 GX support" if PCI | 997 | bool "Mach64 GX support" if PCI |
1004 | depends on FB_ATY | 998 | depends on FB_ATY |
@@ -1376,7 +1370,7 @@ config FB_PXA | |||
1376 | 1370 | ||
1377 | This driver is also available as a module ( = code which can be | 1371 | This driver is also available as a module ( = code which can be |
1378 | inserted and removed from the running kernel whenever you want). The | 1372 | inserted and removed from the running kernel whenever you want). The |
1379 | module will be called vfb. If you want to compile it as a module, | 1373 | module will be called pxafb. If you want to compile it as a module, |
1380 | say M here and read <file:Documentation/modules.txt>. | 1374 | say M here and read <file:Documentation/modules.txt>. |
1381 | 1375 | ||
1382 | If unsure, say N. | 1376 | If unsure, say N. |
@@ -1409,7 +1403,7 @@ config FB_W100 | |||
1409 | 1403 | ||
1410 | This driver is also available as a module ( = code which can be | 1404 | This driver is also available as a module ( = code which can be |
1411 | inserted and removed from the running kernel whenever you want). The | 1405 | inserted and removed from the running kernel whenever you want). The |
1412 | module will be called vfb. If you want to compile it as a module, | 1406 | module will be called w100fb. If you want to compile it as a module, |
1413 | say M here and read <file:Documentation/modules.txt>. | 1407 | say M here and read <file:Documentation/modules.txt>. |
1414 | 1408 | ||
1415 | If unsure, say N. | 1409 | If unsure, say N. |
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 2784f0a9d693..89060b2db8e5 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c | |||
@@ -366,7 +366,8 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, | |||
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
369 | void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 369 | static void arcfb_fillrect(struct fb_info *info, |
370 | const struct fb_fillrect *rect) | ||
370 | { | 371 | { |
371 | struct arcfb_par *par = info->par; | 372 | struct arcfb_par *par = info->par; |
372 | 373 | ||
@@ -376,7 +377,8 @@ void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
376 | arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); | 377 | arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); |
377 | } | 378 | } |
378 | 379 | ||
379 | void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | 380 | static void arcfb_copyarea(struct fb_info *info, |
381 | const struct fb_copyarea *area) | ||
380 | { | 382 | { |
381 | struct arcfb_par *par = info->par; | 383 | struct arcfb_par *par = info->par; |
382 | 384 | ||
@@ -386,7 +388,7 @@ void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
386 | arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); | 388 | arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); |
387 | } | 389 | } |
388 | 390 | ||
389 | void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) | 391 | static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) |
390 | { | 392 | { |
391 | struct arcfb_par *par = info->par; | 393 | struct arcfb_par *par = info->par; |
392 | 394 | ||
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index c64de59398f4..69f75547865d 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c | |||
@@ -549,7 +549,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) | |||
549 | if (!request_mem_region(addr, size, "asiliantfb")) | 549 | if (!request_mem_region(addr, size, "asiliantfb")) |
550 | return -EBUSY; | 550 | return -EBUSY; |
551 | 551 | ||
552 | p = framebuffer_alloc(sizeof(u32) * 256, &dp->dev); | 552 | p = framebuffer_alloc(sizeof(u32) * 16, &dp->dev); |
553 | if (!p) { | 553 | if (!p) { |
554 | release_mem_region(addr, size); | 554 | release_mem_region(addr, size); |
555 | return -ENOMEM; | 555 | return -ENOMEM; |
diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile index 9dec96249ffb..18521397a6e3 100644 --- a/drivers/video/aty/Makefile +++ b/drivers/video/aty/Makefile | |||
@@ -5,7 +5,6 @@ obj-$(CONFIG_FB_RADEON) += radeonfb.o | |||
5 | atyfb-y := atyfb_base.o mach64_accel.o mach64_cursor.o | 5 | atyfb-y := atyfb_base.o mach64_accel.o mach64_cursor.o |
6 | atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o | 6 | atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o |
7 | atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o | 7 | atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o |
8 | atyfb-$(CONFIG_FB_ATY_XL_INIT) += xlinit.o | ||
9 | 8 | ||
10 | atyfb-objs := $(atyfb-y) | 9 | atyfb-objs := $(atyfb-y) |
11 | 10 | ||
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 09de173c1164..e9b7a64c1ac4 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h | |||
@@ -50,6 +50,7 @@ struct pll_info { | |||
50 | int sclk, mclk, mclk_pm, xclk; | 50 | int sclk, mclk, mclk_pm, xclk; |
51 | int ref_div; | 51 | int ref_div; |
52 | int ref_clk; | 52 | int ref_clk; |
53 | int ecp_max; | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | typedef struct { | 56 | typedef struct { |
@@ -354,6 +355,5 @@ static inline void wait_for_idle(struct atyfb_par *par) | |||
354 | 355 | ||
355 | extern void aty_reset_engine(const struct atyfb_par *par); | 356 | extern void aty_reset_engine(const struct atyfb_par *par); |
356 | extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); | 357 | extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); |
357 | extern int atyfb_xl_init(struct fb_info *info); | ||
358 | extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par); | 358 | extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par); |
359 | extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); | 359 | extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 3fefdb0cbf07..e370125e4fbc 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -109,9 +109,18 @@ | |||
109 | #define GUI_RESERVE (1 * PAGE_SIZE) | 109 | #define GUI_RESERVE (1 * PAGE_SIZE) |
110 | 110 | ||
111 | /* FIXME: remove the FAIL definition */ | 111 | /* FIXME: remove the FAIL definition */ |
112 | #define FAIL(msg) do { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0) | 112 | #define FAIL(msg) do { \ |
113 | #define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0) | 113 | if (!(var->activate & FB_ACTIVATE_TEST)) \ |
114 | 114 | printk(KERN_CRIT "atyfb: " msg "\n"); \ | |
115 | return -EINVAL; \ | ||
116 | } while (0) | ||
117 | #define FAIL_MAX(msg, x, _max_) do { \ | ||
118 | if (x > _max_) { \ | ||
119 | if (!(var->activate & FB_ACTIVATE_TEST)) \ | ||
120 | printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \ | ||
121 | return -EINVAL; \ | ||
122 | } \ | ||
123 | } while (0) | ||
115 | #ifdef DEBUG | 124 | #ifdef DEBUG |
116 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args) | 125 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args) |
117 | #else | 126 | #else |
@@ -340,6 +349,7 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; | |||
340 | #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL) | 349 | #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL) |
341 | #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP) | 350 | #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP) |
342 | 351 | ||
352 | /* FIXME what is this chip? */ | ||
343 | #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP) | 353 | #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP) |
344 | 354 | ||
345 | /* make sets shorter */ | 355 | /* make sets shorter */ |
@@ -359,58 +369,60 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; | |||
359 | static struct { | 369 | static struct { |
360 | u16 pci_id; | 370 | u16 pci_id; |
361 | const char *name; | 371 | const char *name; |
362 | int pll, mclk, xclk; | 372 | int pll, mclk, xclk, ecp_max; |
363 | u32 features; | 373 | u32 features; |
364 | } aty_chips[] __devinitdata = { | 374 | } aty_chips[] __devinitdata = { |
365 | #ifdef CONFIG_FB_ATY_GX | 375 | #ifdef CONFIG_FB_ATY_GX |
366 | /* Mach64 GX */ | 376 | /* Mach64 GX */ |
367 | { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX }, | 377 | { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX }, |
368 | { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX }, | 378 | { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX }, |
369 | #endif /* CONFIG_FB_ATY_GX */ | 379 | #endif /* CONFIG_FB_ATY_GX */ |
370 | 380 | ||
371 | #ifdef CONFIG_FB_ATY_CT | 381 | #ifdef CONFIG_FB_ATY_CT |
372 | { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT }, | 382 | { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT }, |
373 | { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET }, | 383 | { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET }, |
374 | { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT }, | 384 | |
375 | { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT }, | 385 | /* FIXME what is this chip? */ |
376 | /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */ | 386 | { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT }, |
377 | { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB }, | 387 | |
378 | { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 }, | 388 | { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT }, |
379 | 389 | { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT }, | |
380 | { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT }, | 390 | |
381 | /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */ | 391 | { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 }, |
382 | { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, | 392 | { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB }, |
383 | 393 | ||
384 | { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 }, | 394 | { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, |
385 | 395 | ||
386 | { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, | 396 | { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 }, |
387 | { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, | 397 | |
388 | { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, | 398 | { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, |
389 | { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, | 399 | { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, |
390 | 400 | { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, | |
391 | { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO }, | 401 | { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, |
392 | { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO }, | 402 | |
393 | { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, | 403 | { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, |
394 | { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO }, | 404 | { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, |
395 | { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO }, | 405 | { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, |
396 | 406 | { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, | |
397 | { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO }, | 407 | { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, |
398 | { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO }, | 408 | |
399 | { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, | 409 | { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, |
400 | { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, | 410 | { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, |
401 | { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, | 411 | { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, |
402 | 412 | { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, | |
403 | { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL }, | 413 | { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, |
404 | { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL }, | 414 | |
405 | { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL }, | 415 | { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
406 | { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, | 416 | { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
407 | { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL }, | 417 | { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
408 | { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL }, | 418 | { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
409 | 419 | { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, | |
410 | { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, | 420 | { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
411 | { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, | 421 | |
412 | { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, | 422 | { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, |
413 | { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, | 423 | { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, |
424 | { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, | ||
425 | { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, | ||
414 | #endif /* CONFIG_FB_ATY_CT */ | 426 | #endif /* CONFIG_FB_ATY_CT */ |
415 | }; | 427 | }; |
416 | 428 | ||
@@ -431,6 +443,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) | |||
431 | par->pll_limits.pll_max = aty_chips[i].pll; | 443 | par->pll_limits.pll_max = aty_chips[i].pll; |
432 | par->pll_limits.mclk = aty_chips[i].mclk; | 444 | par->pll_limits.mclk = aty_chips[i].mclk; |
433 | par->pll_limits.xclk = aty_chips[i].xclk; | 445 | par->pll_limits.xclk = aty_chips[i].xclk; |
446 | par->pll_limits.ecp_max = aty_chips[i].ecp_max; | ||
434 | par->features = aty_chips[i].features; | 447 | par->features = aty_chips[i].features; |
435 | 448 | ||
436 | chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); | 449 | chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); |
@@ -450,39 +463,63 @@ static int __devinit correct_chipset(struct atyfb_par *par) | |||
450 | #endif | 463 | #endif |
451 | #ifdef CONFIG_FB_ATY_CT | 464 | #ifdef CONFIG_FB_ATY_CT |
452 | case PCI_CHIP_MACH64VT: | 465 | case PCI_CHIP_MACH64VT: |
453 | rev &= 0xc7; | 466 | switch (rev & 0x07) { |
454 | if(rev == 0x00) { | 467 | case 0x00: |
455 | name = "ATI264VTA3 (Mach64 VT)"; | 468 | switch (rev & 0xc0) { |
456 | par->pll_limits.pll_max = 170; | 469 | case 0x00: |
457 | par->pll_limits.mclk = 67; | 470 | name = "ATI264VT (A3) (Mach64 VT)"; |
458 | par->pll_limits.xclk = 67; | 471 | par->pll_limits.pll_max = 170; |
459 | par->features = ATI_CHIP_264VT; | 472 | par->pll_limits.mclk = 67; |
460 | } else if(rev == 0x40) { | 473 | par->pll_limits.xclk = 67; |
461 | name = "ATI264VTA4 (Mach64 VT)"; | 474 | par->pll_limits.ecp_max = 80; |
475 | par->features = ATI_CHIP_264VT; | ||
476 | break; | ||
477 | case 0x40: | ||
478 | name = "ATI264VT2 (A4) (Mach64 VT)"; | ||
479 | par->pll_limits.pll_max = 200; | ||
480 | par->pll_limits.mclk = 67; | ||
481 | par->pll_limits.xclk = 67; | ||
482 | par->pll_limits.ecp_max = 80; | ||
483 | par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; | ||
484 | break; | ||
485 | } | ||
486 | break; | ||
487 | case 0x01: | ||
488 | name = "ATI264VT3 (B1) (Mach64 VT)"; | ||
462 | par->pll_limits.pll_max = 200; | 489 | par->pll_limits.pll_max = 200; |
463 | par->pll_limits.mclk = 67; | 490 | par->pll_limits.mclk = 67; |
464 | par->pll_limits.xclk = 67; | 491 | par->pll_limits.xclk = 67; |
465 | par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; | 492 | par->pll_limits.ecp_max = 80; |
466 | } else { | 493 | par->features = ATI_CHIP_264VTB; |
467 | name = "ATI264VTB (Mach64 VT)"; | 494 | break; |
495 | case 0x02: | ||
496 | name = "ATI264VT3 (B2) (Mach64 VT)"; | ||
468 | par->pll_limits.pll_max = 200; | 497 | par->pll_limits.pll_max = 200; |
469 | par->pll_limits.mclk = 67; | 498 | par->pll_limits.mclk = 67; |
470 | par->pll_limits.xclk = 67; | 499 | par->pll_limits.xclk = 67; |
471 | par->features = ATI_CHIP_264VTB; | 500 | par->pll_limits.ecp_max = 80; |
501 | par->features = ATI_CHIP_264VT3; | ||
502 | break; | ||
472 | } | 503 | } |
473 | break; | 504 | break; |
474 | case PCI_CHIP_MACH64GT: | 505 | case PCI_CHIP_MACH64GT: |
475 | rev &= 0x07; | 506 | switch (rev & 0x07) { |
476 | if(rev == 0x01) { | 507 | case 0x01: |
508 | name = "3D RAGE II (Mach64 GT)"; | ||
477 | par->pll_limits.pll_max = 170; | 509 | par->pll_limits.pll_max = 170; |
478 | par->pll_limits.mclk = 67; | 510 | par->pll_limits.mclk = 67; |
479 | par->pll_limits.xclk = 67; | 511 | par->pll_limits.xclk = 67; |
512 | par->pll_limits.ecp_max = 80; | ||
480 | par->features = ATI_CHIP_264GTB; | 513 | par->features = ATI_CHIP_264GTB; |
481 | } else if(rev == 0x02) { | 514 | break; |
515 | case 0x02: | ||
516 | name = "3D RAGE II+ (Mach64 GT)"; | ||
482 | par->pll_limits.pll_max = 200; | 517 | par->pll_limits.pll_max = 200; |
483 | par->pll_limits.mclk = 67; | 518 | par->pll_limits.mclk = 67; |
484 | par->pll_limits.xclk = 67; | 519 | par->pll_limits.xclk = 67; |
520 | par->pll_limits.ecp_max = 100; | ||
485 | par->features = ATI_CHIP_264GTB; | 521 | par->features = ATI_CHIP_264GTB; |
522 | break; | ||
486 | } | 523 | } |
487 | break; | 524 | break; |
488 | #endif | 525 | #endif |
@@ -692,7 +729,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
692 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | | 729 | aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | |
693 | (SHADOW_EN | SHADOW_RW_EN), par); | 730 | (SHADOW_EN | SHADOW_RW_EN), par); |
694 | 731 | ||
695 | DPRINTK("set secondary CRT to %ix%i %c%c\n", | 732 | DPRINTK("set shadow CRT to %ix%i %c%c\n", |
696 | ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), | 733 | ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), |
697 | (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); | 734 | (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); |
698 | 735 | ||
@@ -840,11 +877,14 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
840 | know if one is connected. So it's better to fail then. | 877 | know if one is connected. So it's better to fail then. |
841 | */ | 878 | */ |
842 | if (crtc->lcd_gen_cntl & CRT_ON) { | 879 | if (crtc->lcd_gen_cntl & CRT_ON) { |
843 | PRINTKI("Disable lcd panel, because video mode does not fit.\n"); | 880 | if (!(var->activate & FB_ACTIVATE_TEST)) |
881 | PRINTKI("Disable LCD panel, because video mode does not fit.\n"); | ||
844 | crtc->lcd_gen_cntl &= ~LCD_ON; | 882 | crtc->lcd_gen_cntl &= ~LCD_ON; |
845 | /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/ | 883 | /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/ |
846 | } else { | 884 | } else { |
847 | FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode."); | 885 | if (!(var->activate & FB_ACTIVATE_TEST)) |
886 | PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n"); | ||
887 | return -EINVAL; | ||
848 | } | 888 | } |
849 | } | 889 | } |
850 | } | 890 | } |
@@ -858,9 +898,9 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
858 | vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); | 898 | vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); |
859 | 899 | ||
860 | /* This is horror! When we simulate, say 640x480 on an 800x600 | 900 | /* This is horror! When we simulate, say 640x480 on an 800x600 |
861 | lcd monitor, the CRTC should be programmed 800x600 values for | 901 | LCD monitor, the CRTC should be programmed 800x600 values for |
862 | the non visible part, but 640x480 for the visible part. | 902 | the non visible part, but 640x480 for the visible part. |
863 | This code has been tested on a laptop with it's 1400x1050 lcd | 903 | This code has been tested on a laptop with it's 1400x1050 LCD |
864 | monitor and a conventional monitor both switched on. | 904 | monitor and a conventional monitor both switched on. |
865 | Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, | 905 | Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, |
866 | works with little glitches also with DOUBLESCAN modes | 906 | works with little glitches also with DOUBLESCAN modes |
@@ -955,16 +995,6 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
955 | vdisplay = yres; | 995 | vdisplay = yres; |
956 | if(vmode & FB_VMODE_DOUBLE) | 996 | if(vmode & FB_VMODE_DOUBLE) |
957 | vdisplay <<= 1; | 997 | vdisplay <<= 1; |
958 | if(vmode & FB_VMODE_INTERLACED) { | ||
959 | vdisplay >>= 1; | ||
960 | |||
961 | /* The prefered mode for the lcd is not interlaced, so disable it if | ||
962 | it was enabled. For doublescan there is no problem, because we can | ||
963 | compensate for it in the hardware stretching (we stretch half as much) | ||
964 | */ | ||
965 | vmode &= ~FB_VMODE_INTERLACED; | ||
966 | /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/ | ||
967 | } | ||
968 | crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); | 998 | crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); |
969 | crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | | 999 | crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | |
970 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ | 1000 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ |
@@ -980,7 +1010,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
980 | crtc->horz_stretching &= | 1010 | crtc->horz_stretching &= |
981 | ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | | 1011 | ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | |
982 | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); | 1012 | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); |
983 | if (xres < par->lcd_width) { | 1013 | if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { |
984 | do { | 1014 | do { |
985 | /* | 1015 | /* |
986 | * The horizontal blender misbehaves when HDisplay is less than a | 1016 | * The horizontal blender misbehaves when HDisplay is less than a |
@@ -1042,7 +1072,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
1042 | } while (0); | 1072 | } while (0); |
1043 | } | 1073 | } |
1044 | 1074 | ||
1045 | if (vdisplay < par->lcd_height) { | 1075 | if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) { |
1046 | crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN | | 1076 | crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN | |
1047 | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); | 1077 | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); |
1048 | 1078 | ||
@@ -1065,9 +1095,8 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
1065 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ | 1095 | #endif /* CONFIG_FB_ATY_GENERIC_LCD */ |
1066 | 1096 | ||
1067 | if (M64_HAS(MAGIC_FIFO)) { | 1097 | if (M64_HAS(MAGIC_FIFO)) { |
1068 | /* Not VTB/GTB */ | 1098 | /* FIXME: display FIFO low watermark values */ |
1069 | /* FIXME: magic FIFO values */ | 1099 | crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM); |
1070 | crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH); | ||
1071 | } | 1100 | } |
1072 | crtc->dp_pix_width = dp_pix_width; | 1101 | crtc->dp_pix_width = dp_pix_width; |
1073 | crtc->dp_chain_mask = dp_chain_mask; | 1102 | crtc->dp_chain_mask = dp_chain_mask; |
@@ -1184,7 +1213,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va | |||
1184 | var->transp.length = 8; | 1213 | var->transp.length = 8; |
1185 | break; | 1214 | break; |
1186 | default: | 1215 | default: |
1187 | FAIL("Invalid pixel width"); | 1216 | PRINTKE("Invalid pixel width\n"); |
1217 | return -EINVAL; | ||
1188 | } | 1218 | } |
1189 | 1219 | ||
1190 | /* output */ | 1220 | /* output */ |
@@ -1241,7 +1271,8 @@ static int atyfb_set_par(struct fb_info *info) | |||
1241 | pixclock = atyfb_get_pixclock(var, par); | 1271 | pixclock = atyfb_get_pixclock(var, par); |
1242 | 1272 | ||
1243 | if (pixclock == 0) { | 1273 | if (pixclock == 0) { |
1244 | FAIL("Invalid pixclock"); | 1274 | PRINTKE("Invalid pixclock\n"); |
1275 | return -EINVAL; | ||
1245 | } else { | 1276 | } else { |
1246 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) | 1277 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) |
1247 | return err; | 1278 | return err; |
@@ -1446,7 +1477,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
1446 | pixclock = atyfb_get_pixclock(var, par); | 1477 | pixclock = atyfb_get_pixclock(var, par); |
1447 | 1478 | ||
1448 | if (pixclock == 0) { | 1479 | if (pixclock == 0) { |
1449 | FAIL("Invalid pixclock"); | 1480 | if (!(var->activate & FB_ACTIVATE_TEST)) |
1481 | PRINTKE("Invalid pixclock\n"); | ||
1482 | return -EINVAL; | ||
1450 | } else { | 1483 | } else { |
1451 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) | 1484 | if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) |
1452 | return err; | 1485 | return err; |
@@ -2291,10 +2324,6 @@ static int __init aty_init(struct fb_info *info, const char *name) | |||
2291 | par->dac_ops = &aty_dac_ct; | 2324 | par->dac_ops = &aty_dac_ct; |
2292 | par->pll_ops = &aty_pll_ct; | 2325 | par->pll_ops = &aty_pll_ct; |
2293 | par->bus_type = PCI; | 2326 | par->bus_type = PCI; |
2294 | #ifdef CONFIG_FB_ATY_XL_INIT | ||
2295 | if (IS_XL(par->pci_id)) | ||
2296 | atyfb_xl_init(info); | ||
2297 | #endif | ||
2298 | par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); | 2327 | par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); |
2299 | ramname = aty_ct_ram[par->ram_type]; | 2328 | ramname = aty_ct_ram[par->ram_type]; |
2300 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ | 2329 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ |
@@ -2638,16 +2667,16 @@ static int __init store_video_par(char *video_str, unsigned char m64_num) | |||
2638 | static int atyfb_blank(int blank, struct fb_info *info) | 2667 | static int atyfb_blank(int blank, struct fb_info *info) |
2639 | { | 2668 | { |
2640 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 2669 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
2641 | u8 gen_cntl; | 2670 | u32 gen_cntl; |
2642 | 2671 | ||
2643 | if (par->lock_blank || par->asleep) | 2672 | if (par->lock_blank || par->asleep) |
2644 | return 0; | 2673 | return 0; |
2645 | 2674 | ||
2646 | #ifdef CONFIG_PMAC_BACKLIGHT | 2675 | #ifdef CONFIG_PMAC_BACKLIGHT |
2647 | if ((_machine == _MACH_Pmac) && blank) | 2676 | if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) |
2648 | set_backlight_enable(0); | 2677 | set_backlight_enable(0); |
2649 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) | 2678 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) |
2650 | if (par->lcd_table && blank && | 2679 | if (par->lcd_table && blank > FB_BLANK_NORMAL && |
2651 | (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { | 2680 | (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { |
2652 | u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); | 2681 | u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); |
2653 | pm &= ~PWR_BLON; | 2682 | pm &= ~PWR_BLON; |
@@ -2655,31 +2684,31 @@ static int atyfb_blank(int blank, struct fb_info *info) | |||
2655 | } | 2684 | } |
2656 | #endif | 2685 | #endif |
2657 | 2686 | ||
2658 | gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par); | 2687 | gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); |
2659 | switch (blank) { | 2688 | switch (blank) { |
2660 | case FB_BLANK_UNBLANK: | 2689 | case FB_BLANK_UNBLANK: |
2661 | gen_cntl &= ~(0x4c); | 2690 | gen_cntl &= ~0x400004c; |
2662 | break; | 2691 | break; |
2663 | case FB_BLANK_NORMAL: | 2692 | case FB_BLANK_NORMAL: |
2664 | gen_cntl |= 0x40; | 2693 | gen_cntl |= 0x4000040; |
2665 | break; | 2694 | break; |
2666 | case FB_BLANK_VSYNC_SUSPEND: | 2695 | case FB_BLANK_VSYNC_SUSPEND: |
2667 | gen_cntl |= 0x8; | 2696 | gen_cntl |= 0x4000048; |
2668 | break; | 2697 | break; |
2669 | case FB_BLANK_HSYNC_SUSPEND: | 2698 | case FB_BLANK_HSYNC_SUSPEND: |
2670 | gen_cntl |= 0x4; | 2699 | gen_cntl |= 0x4000044; |
2671 | break; | 2700 | break; |
2672 | case FB_BLANK_POWERDOWN: | 2701 | case FB_BLANK_POWERDOWN: |
2673 | gen_cntl |= 0x4c; | 2702 | gen_cntl |= 0x400004c; |
2674 | break; | 2703 | break; |
2675 | } | 2704 | } |
2676 | aty_st_8(CRTC_GEN_CNTL, gen_cntl, par); | 2705 | aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); |
2677 | 2706 | ||
2678 | #ifdef CONFIG_PMAC_BACKLIGHT | 2707 | #ifdef CONFIG_PMAC_BACKLIGHT |
2679 | if ((_machine == _MACH_Pmac) && !blank) | 2708 | if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) |
2680 | set_backlight_enable(1); | 2709 | set_backlight_enable(1); |
2681 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) | 2710 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) |
2682 | if (par->lcd_table && !blank && | 2711 | if (par->lcd_table && blank <= FB_BLANK_NORMAL && |
2683 | (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { | 2712 | (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { |
2684 | u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); | 2713 | u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); |
2685 | pm |= PWR_BLON; | 2714 | pm |= PWR_BLON; |
@@ -3157,15 +3186,15 @@ static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) | |||
3157 | refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); | 3186 | refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); |
3158 | par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; | 3187 | par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; |
3159 | /* We now need to determine the crtc parameters for the | 3188 | /* We now need to determine the crtc parameters for the |
3160 | * lcd monitor. This is tricky, because they are not stored | 3189 | * LCD monitor. This is tricky, because they are not stored |
3161 | * individually in the BIOS. Instead, the BIOS contains a | 3190 | * individually in the BIOS. Instead, the BIOS contains a |
3162 | * table of display modes that work for this monitor. | 3191 | * table of display modes that work for this monitor. |
3163 | * | 3192 | * |
3164 | * The idea is that we search for a mode of the same dimensions | 3193 | * The idea is that we search for a mode of the same dimensions |
3165 | * as the dimensions of the lcd monitor. Say our lcd monitor | 3194 | * as the dimensions of the LCD monitor. Say our LCD monitor |
3166 | * is 800x600 pixels, we search for a 800x600 monitor. | 3195 | * is 800x600 pixels, we search for a 800x600 monitor. |
3167 | * The CRTC parameters we find here are the ones that we need | 3196 | * The CRTC parameters we find here are the ones that we need |
3168 | * to use to simulate other resolutions on the lcd screen. | 3197 | * to use to simulate other resolutions on the LCD screen. |
3169 | */ | 3198 | */ |
3170 | lcdmodeptr = (u16 *)(par->lcd_table + 64); | 3199 | lcdmodeptr = (u16 *)(par->lcd_table + 64); |
3171 | while (*lcdmodeptr != 0) { | 3200 | while (*lcdmodeptr != 0) { |
@@ -3692,9 +3721,7 @@ static int __init atyfb_init(void) | |||
3692 | atyfb_setup(option); | 3721 | atyfb_setup(option); |
3693 | #endif | 3722 | #endif |
3694 | 3723 | ||
3695 | #ifdef CONFIG_PCI | ||
3696 | pci_register_driver(&atyfb_driver); | 3724 | pci_register_driver(&atyfb_driver); |
3697 | #endif | ||
3698 | #ifdef CONFIG_ATARI | 3725 | #ifdef CONFIG_ATARI |
3699 | atyfb_atari_probe(); | 3726 | atyfb_atari_probe(); |
3700 | #endif | 3727 | #endif |
@@ -3703,9 +3730,7 @@ static int __init atyfb_init(void) | |||
3703 | 3730 | ||
3704 | static void __exit atyfb_exit(void) | 3731 | static void __exit atyfb_exit(void) |
3705 | { | 3732 | { |
3706 | #ifdef CONFIG_PCI | ||
3707 | pci_unregister_driver(&atyfb_driver); | 3733 | pci_unregister_driver(&atyfb_driver); |
3708 | #endif | ||
3709 | } | 3734 | } |
3710 | 3735 | ||
3711 | module_init(atyfb_init); | 3736 | module_init(atyfb_init); |
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index 9bdb2aab01aa..e7056934c6a8 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c | |||
@@ -206,9 +206,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll | |||
206 | { | 206 | { |
207 | u32 q; | 207 | u32 q; |
208 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 208 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
209 | #ifdef DEBUG | ||
210 | int pllvclk; | 209 | int pllvclk; |
211 | #endif | ||
212 | 210 | ||
213 | /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */ | 211 | /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */ |
214 | q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per; | 212 | q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per; |
@@ -223,13 +221,26 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll | |||
223 | pll->vclk_post_div_real = postdividers[pll->vclk_post_div]; | 221 | pll->vclk_post_div_real = postdividers[pll->vclk_post_div]; |
224 | // pll->vclk_post_div <<= 6; | 222 | // pll->vclk_post_div <<= 6; |
225 | pll->vclk_fb_div = q * pll->vclk_post_div_real / 8; | 223 | pll->vclk_fb_div = q * pll->vclk_post_div_real / 8; |
226 | #ifdef DEBUG | ||
227 | pllvclk = (1000000 * 2 * pll->vclk_fb_div) / | 224 | pllvclk = (1000000 * 2 * pll->vclk_fb_div) / |
228 | (par->ref_clk_per * pll->pll_ref_div); | 225 | (par->ref_clk_per * pll->pll_ref_div); |
226 | #ifdef DEBUG | ||
229 | printk("atyfb(%s): pllvclk=%d MHz, vclk=%d MHz\n", | 227 | printk("atyfb(%s): pllvclk=%d MHz, vclk=%d MHz\n", |
230 | __FUNCTION__, pllvclk, pllvclk / pll->vclk_post_div_real); | 228 | __FUNCTION__, pllvclk, pllvclk / pll->vclk_post_div_real); |
231 | #endif | 229 | #endif |
232 | pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */ | 230 | pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */ |
231 | |||
232 | /* Set ECP (scaler/overlay clock) divider */ | ||
233 | if (par->pll_limits.ecp_max) { | ||
234 | int ecp = pllvclk / pll->vclk_post_div_real; | ||
235 | int ecp_div = 0; | ||
236 | |||
237 | while (ecp > par->pll_limits.ecp_max && ecp_div < 2) { | ||
238 | ecp >>= 1; | ||
239 | ecp_div++; | ||
240 | } | ||
241 | pll->pll_vclk_cntl |= ecp_div << 4; | ||
242 | } | ||
243 | |||
233 | return 0; | 244 | return 0; |
234 | } | 245 | } |
235 | 246 | ||
diff --git a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c deleted file mode 100644 index a085cbf74ecb..000000000000 --- a/drivers/video/aty/xlinit.c +++ /dev/null | |||
@@ -1,359 +0,0 @@ | |||
1 | /* | ||
2 | * ATI Rage XL Initialization. Support for Xpert98 and Victoria | ||
3 | * PCI cards. | ||
4 | * | ||
5 | * Copyright (C) 2002 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * stevel@mvista.com or source@mvista.com | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | #include <linux/config.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/mm.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/vmalloc.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/fb.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/pci.h> | ||
41 | #include <asm/io.h> | ||
42 | #include <video/mach64.h> | ||
43 | #include "atyfb.h" | ||
44 | |||
45 | #define MPLL_GAIN 0xad | ||
46 | #define VPLL_GAIN 0xd5 | ||
47 | |||
48 | enum { | ||
49 | VICTORIA = 0, | ||
50 | XPERT98, | ||
51 | NUM_XL_CARDS | ||
52 | }; | ||
53 | |||
54 | extern const struct aty_pll_ops aty_pll_ct; | ||
55 | |||
56 | #define DEFAULT_CARD XPERT98 | ||
57 | static int xl_card = DEFAULT_CARD; | ||
58 | |||
59 | static const struct xl_card_cfg_t { | ||
60 | int ref_crystal; // 10^4 Hz | ||
61 | int mem_type; | ||
62 | int mem_size; | ||
63 | u32 mem_cntl; | ||
64 | u32 ext_mem_cntl; | ||
65 | u32 mem_addr_config; | ||
66 | u32 bus_cntl; | ||
67 | u32 dac_cntl; | ||
68 | u32 hw_debug; | ||
69 | u32 custom_macro_cntl; | ||
70 | u8 dll2_cntl; | ||
71 | u8 pll_yclk_cntl; | ||
72 | } card_cfg[NUM_XL_CARDS] = { | ||
73 | // VICTORIA | ||
74 | { 2700, SDRAM, 0x800000, | ||
75 | 0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040, | ||
76 | 0x82010102, 0x48803800, 0x005E0179, | ||
77 | 0x50, 0x25 | ||
78 | }, | ||
79 | // XPERT98 | ||
80 | { 1432, WRAM, 0x800000, | ||
81 | 0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001, | ||
82 | 0x8000000A, 0x48833800, 0x007F0779, | ||
83 | 0x10, 0x19 | ||
84 | } | ||
85 | }; | ||
86 | |||
87 | typedef struct { | ||
88 | u8 lcd_reg; | ||
89 | u32 val; | ||
90 | } lcd_tbl_t; | ||
91 | |||
92 | static const lcd_tbl_t lcd_tbl[] = { | ||
93 | { 0x01, 0x000520C0 }, | ||
94 | { 0x08, 0x02000408 }, | ||
95 | { 0x03, 0x00000F00 }, | ||
96 | { 0x00, 0x00000000 }, | ||
97 | { 0x02, 0x00000000 }, | ||
98 | { 0x04, 0x00000000 }, | ||
99 | { 0x05, 0x00000000 }, | ||
100 | { 0x06, 0x00000000 }, | ||
101 | { 0x33, 0x00000000 }, | ||
102 | { 0x34, 0x00000000 }, | ||
103 | { 0x35, 0x00000000 }, | ||
104 | { 0x36, 0x00000000 }, | ||
105 | { 0x37, 0x00000000 } | ||
106 | }; | ||
107 | |||
108 | static void reset_gui(struct atyfb_par *par) | ||
109 | { | ||
110 | aty_st_8(GEN_TEST_CNTL+1, 0x01, par); | ||
111 | aty_st_8(GEN_TEST_CNTL+1, 0x00, par); | ||
112 | aty_st_8(GEN_TEST_CNTL+1, 0x02, par); | ||
113 | mdelay(5); | ||
114 | } | ||
115 | |||
116 | static void reset_sdram(struct atyfb_par *par) | ||
117 | { | ||
118 | u8 temp; | ||
119 | |||
120 | temp = aty_ld_8(EXT_MEM_CNTL, par); | ||
121 | temp |= 0x02; | ||
122 | aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_RESET = 1b | ||
123 | temp |= 0x08; | ||
124 | aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 10b | ||
125 | temp |= 0x0c; | ||
126 | aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 11b | ||
127 | mdelay(5); | ||
128 | temp &= 0xf3; | ||
129 | aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 00b | ||
130 | temp &= 0xfd; | ||
131 | aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_REST = 0b | ||
132 | mdelay(5); | ||
133 | } | ||
134 | |||
135 | static void init_dll(struct atyfb_par *par) | ||
136 | { | ||
137 | // enable DLL | ||
138 | aty_st_pll_ct(PLL_GEN_CNTL, | ||
139 | aty_ld_pll_ct(PLL_GEN_CNTL, par) & 0x7f, | ||
140 | par); | ||
141 | |||
142 | // reset DLL | ||
143 | aty_st_pll_ct(DLL_CNTL, 0x82, par); | ||
144 | aty_st_pll_ct(DLL_CNTL, 0xE2, par); | ||
145 | mdelay(5); | ||
146 | aty_st_pll_ct(DLL_CNTL, 0x82, par); | ||
147 | mdelay(6); | ||
148 | } | ||
149 | |||
150 | static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll, | ||
151 | int hsync_enb) | ||
152 | { | ||
153 | reset_gui(par); | ||
154 | aty_st_pll_ct(MCLK_FB_DIV, pll->mclk_fb_div, par); | ||
155 | aty_st_pll_ct(SCLK_FB_DIV, pll->sclk_fb_div, par); | ||
156 | |||
157 | mdelay(15); | ||
158 | init_dll(par); | ||
159 | aty_st_8(GEN_TEST_CNTL+1, 0x00, par); | ||
160 | mdelay(5); | ||
161 | aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); | ||
162 | mdelay(6); | ||
163 | reset_sdram(par); | ||
164 | aty_st_8(CRTC_GEN_CNTL+3, | ||
165 | hsync_enb ? 0x00 : 0x04, par); | ||
166 | |||
167 | aty_st_pll_ct(SPLL_CNTL2, pll->spll_cntl2, par); | ||
168 | aty_st_pll_ct(PLL_GEN_CNTL, pll->pll_gen_cntl, par); | ||
169 | aty_st_pll_ct(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par); | ||
170 | } | ||
171 | |||
172 | int atyfb_xl_init(struct fb_info *info) | ||
173 | { | ||
174 | const struct xl_card_cfg_t * card = &card_cfg[xl_card]; | ||
175 | struct atyfb_par *par = (struct atyfb_par *) info->par; | ||
176 | union aty_pll pll; | ||
177 | int err; | ||
178 | u32 temp; | ||
179 | |||
180 | aty_st_8(CONFIG_STAT0, 0x85, par); | ||
181 | mdelay(10); | ||
182 | |||
183 | /* | ||
184 | * The following needs to be set before the call | ||
185 | * to var_to_pll() below. They'll be re-set again | ||
186 | * to the same values in aty_init(). | ||
187 | */ | ||
188 | par->ref_clk_per = 100000000UL/card->ref_crystal; | ||
189 | par->ram_type = card->mem_type; | ||
190 | info->fix.smem_len = card->mem_size; | ||
191 | if (xl_card == VICTORIA) { | ||
192 | // the MCLK, XCLK are 120MHz on victoria card | ||
193 | par->mclk_per = 1000000/120; | ||
194 | par->xclk_per = 1000000/120; | ||
195 | par->features &= ~M64F_MFB_FORCE_4; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Calculate mclk and xclk dividers, etc. The passed | ||
200 | * pixclock and bpp values don't matter yet, the vclk | ||
201 | * isn't programmed until later. | ||
202 | */ | ||
203 | if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll))) | ||
204 | return err; | ||
205 | |||
206 | aty_st_pll_ct(LVDS_CNTL0, 0x00, par); | ||
207 | aty_st_pll_ct(DLL2_CNTL, card->dll2_cntl, par); | ||
208 | aty_st_pll_ct(V2PLL_CNTL, 0x10, par); | ||
209 | aty_st_pll_ct(MPLL_CNTL, MPLL_GAIN, par); | ||
210 | aty_st_pll_ct(VPLL_CNTL, VPLL_GAIN, par); | ||
211 | aty_st_pll_ct(PLL_VCLK_CNTL, 0x00, par); | ||
212 | aty_st_pll_ct(VFC_CNTL, 0x1B, par); | ||
213 | aty_st_pll_ct(PLL_REF_DIV, pll.ct.pll_ref_div, par); | ||
214 | aty_st_pll_ct(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par); | ||
215 | aty_st_pll_ct(SPLL_CNTL2, 0x03, par); | ||
216 | aty_st_pll_ct(PLL_GEN_CNTL, 0x44, par); | ||
217 | |||
218 | reset_clocks(par, &pll.ct, 0); | ||
219 | mdelay(10); | ||
220 | |||
221 | aty_st_pll_ct(VCLK_POST_DIV, 0x03, par); | ||
222 | aty_st_pll_ct(VCLK0_FB_DIV, 0xDA, par); | ||
223 | aty_st_pll_ct(VCLK_POST_DIV, 0x0F, par); | ||
224 | aty_st_pll_ct(VCLK1_FB_DIV, 0xF5, par); | ||
225 | aty_st_pll_ct(VCLK_POST_DIV, 0x3F, par); | ||
226 | aty_st_pll_ct(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par); | ||
227 | aty_st_pll_ct(VCLK2_FB_DIV, 0x00, par); | ||
228 | aty_st_pll_ct(VCLK_POST_DIV, 0xFF, par); | ||
229 | aty_st_pll_ct(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par); | ||
230 | aty_st_pll_ct(VCLK3_FB_DIV, 0x00, par); | ||
231 | |||
232 | aty_st_8(BUS_CNTL, 0x01, par); | ||
233 | aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par); | ||
234 | |||
235 | aty_st_le32(CRTC_GEN_CNTL, 0x04000200, par); | ||
236 | aty_st_le16(CONFIG_STAT0, 0x0020, par); | ||
237 | aty_st_le32(MEM_CNTL, 0x10151A33, par); | ||
238 | aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, par); | ||
239 | aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, par); | ||
240 | aty_st_le32(DAC_CNTL, card->dac_cntl, par); | ||
241 | aty_st_le16(GEN_TEST_CNTL, 0x0100, par); | ||
242 | aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, par); | ||
243 | aty_st_le32(MEM_BUF_CNTL, 0x00382848, par); | ||
244 | |||
245 | aty_st_le32(HW_DEBUG, card->hw_debug, par); | ||
246 | aty_st_le16(MEM_ADDR_CONFIG, 0x0000, par); | ||
247 | aty_st_le16(GP_IO+2, 0x0000, par); | ||
248 | aty_st_le16(GEN_TEST_CNTL, 0x0000, par); | ||
249 | aty_st_le16(EXT_DAC_REGS+2, 0x0000, par); | ||
250 | aty_st_le32(CRTC_INT_CNTL, 0x00000000, par); | ||
251 | aty_st_le32(TIMER_CONFIG, 0x00000000, par); | ||
252 | aty_st_le32(0xEC, 0x00000000, par); | ||
253 | aty_st_le32(0xFC, 0x00000000, par); | ||
254 | |||
255 | #if defined (CONFIG_FB_ATY_GENERIC_LCD) | ||
256 | { | ||
257 | int i; | ||
258 | |||
259 | for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++) | ||
260 | aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par); | ||
261 | } | ||
262 | #endif | ||
263 | |||
264 | aty_st_le16(CONFIG_STAT0, 0x00A4, par); | ||
265 | mdelay(10); | ||
266 | |||
267 | aty_st_8(BUS_CNTL+1, 0xA0, par); | ||
268 | mdelay(10); | ||
269 | |||
270 | reset_clocks(par, &pll.ct, 1); | ||
271 | mdelay(10); | ||
272 | |||
273 | // something about power management | ||
274 | aty_st_8(LCD_INDEX, 0x08, par); | ||
275 | aty_st_8(LCD_DATA, 0x0A, par); | ||
276 | aty_st_8(LCD_INDEX, 0x08, par); | ||
277 | aty_st_8(LCD_DATA+3, 0x02, par); | ||
278 | aty_st_8(LCD_INDEX, 0x08, par); | ||
279 | aty_st_8(LCD_DATA, 0x0B, par); | ||
280 | mdelay(2); | ||
281 | |||
282 | // enable display requests, enable CRTC | ||
283 | aty_st_8(CRTC_GEN_CNTL+3, 0x02, par); | ||
284 | // disable display | ||
285 | aty_st_8(CRTC_GEN_CNTL, 0x40, par); | ||
286 | // disable display requests, disable CRTC | ||
287 | aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); | ||
288 | mdelay(10); | ||
289 | |||
290 | aty_st_pll_ct(PLL_YCLK_CNTL, 0x25, par); | ||
291 | |||
292 | aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par); | ||
293 | aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par); | ||
294 | aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, par); | ||
295 | aty_st_8(CUSTOM_MACRO_CNTL+1, | ||
296 | (card->custom_macro_cntl>>8) & 0xff, par); | ||
297 | |||
298 | aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, par); | ||
299 | aty_st_le32(MEM_CNTL, card->mem_cntl, par); | ||
300 | aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, par); | ||
301 | |||
302 | aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par); | ||
303 | |||
304 | aty_st_pll_ct(PLL_YCLK_CNTL, 0x01, par); | ||
305 | mdelay(15); | ||
306 | aty_st_pll_ct(PLL_YCLK_CNTL, card->pll_yclk_cntl, par); | ||
307 | mdelay(1); | ||
308 | |||
309 | reset_clocks(par, &pll.ct, 0); | ||
310 | mdelay(50); | ||
311 | reset_clocks(par, &pll.ct, 0); | ||
312 | mdelay(50); | ||
313 | |||
314 | // enable extended register block | ||
315 | aty_st_8(BUS_CNTL+3, 0x7B, par); | ||
316 | mdelay(1); | ||
317 | // disable extended register block | ||
318 | aty_st_8(BUS_CNTL+3, 0x73, par); | ||
319 | |||
320 | aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, par); | ||
321 | |||
322 | // disable display requests, disable CRTC | ||
323 | aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); | ||
324 | // disable mapping registers in VGA aperture | ||
325 | aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, par) & ~0x04, par); | ||
326 | mdelay(50); | ||
327 | // enable display requests, enable CRTC | ||
328 | aty_st_8(CRTC_GEN_CNTL+3, 0x02, par); | ||
329 | |||
330 | // make GPIO's 14,15,16 all inputs | ||
331 | aty_st_8(LCD_INDEX, 0x07, par); | ||
332 | aty_st_8(LCD_DATA+3, 0x00, par); | ||
333 | |||
334 | // enable the display | ||
335 | aty_st_8(CRTC_GEN_CNTL, 0x00, par); | ||
336 | mdelay(17); | ||
337 | // reset the memory controller | ||
338 | aty_st_8(GEN_TEST_CNTL+1, 0x02, par); | ||
339 | mdelay(15); | ||
340 | aty_st_8(GEN_TEST_CNTL+1, 0x00, par); | ||
341 | mdelay(30); | ||
342 | |||
343 | // enable extended register block | ||
344 | aty_st_8(BUS_CNTL+3, | ||
345 | (u8)(aty_ld_8(BUS_CNTL+3, par) | 0x08), | ||
346 | par); | ||
347 | // set FIFO size to 512 (PIO) | ||
348 | aty_st_le32(GUI_CNTL, | ||
349 | aty_ld_le32(GUI_CNTL, par) & ~0x3, | ||
350 | par); | ||
351 | |||
352 | // enable CRT and disable lcd | ||
353 | aty_st_8(LCD_INDEX, 0x01, par); | ||
354 | temp = aty_ld_le32(LCD_DATA, par); | ||
355 | temp = (temp | 0x01) & ~0x02; | ||
356 | aty_st_le32(LCD_DATA, temp, par); | ||
357 | return 0; | ||
358 | } | ||
359 | |||
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index e65fc3ef7630..eea422eb1ab5 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c | |||
@@ -234,14 +234,14 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | static void bit_cursor(struct vc_data *vc, struct fb_info *info, | 237 | static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, |
238 | struct display *p, int mode, int softback_lines, int fg, int bg) | 238 | int softback_lines, int fg, int bg) |
239 | { | 239 | { |
240 | struct fb_cursor cursor; | 240 | struct fb_cursor cursor; |
241 | struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; | 241 | struct fbcon_ops *ops = info->fbcon_par; |
242 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; | 242 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; |
243 | int w = (vc->vc_font.width + 7) >> 3, c; | 243 | int w = (vc->vc_font.width + 7) >> 3, c; |
244 | int y = real_y(p, vc->vc_y); | 244 | int y = real_y(ops->p, vc->vc_y); |
245 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); | 245 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); |
246 | int err = 1; | 246 | int err = 1; |
247 | char *src; | 247 | char *src; |
@@ -310,7 +310,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | if (cursor.set & FB_CUR_SETSIZE || | 312 | if (cursor.set & FB_CUR_SETSIZE || |
313 | vc->vc_cursor_type != p->cursor_shape || | 313 | vc->vc_cursor_type != ops->p->cursor_shape || |
314 | ops->cursor_state.mask == NULL || | 314 | ops->cursor_state.mask == NULL || |
315 | ops->cursor_reset) { | 315 | ops->cursor_reset) { |
316 | char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); | 316 | char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); |
@@ -323,10 +323,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, | |||
323 | kfree(ops->cursor_state.mask); | 323 | kfree(ops->cursor_state.mask); |
324 | ops->cursor_state.mask = mask; | 324 | ops->cursor_state.mask = mask; |
325 | 325 | ||
326 | p->cursor_shape = vc->vc_cursor_type; | 326 | ops->p->cursor_shape = vc->vc_cursor_type; |
327 | cursor.set |= FB_CUR_SETSHAPE; | 327 | cursor.set |= FB_CUR_SETSHAPE; |
328 | 328 | ||
329 | switch (p->cursor_shape & CUR_HWMASK) { | 329 | switch (ops->p->cursor_shape & CUR_HWMASK) { |
330 | case CUR_NONE: | 330 | case CUR_NONE: |
331 | cur_height = 0; | 331 | cur_height = 0; |
332 | break; | 332 | break; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 50e4c4eb491f..041d06987861 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -209,13 +209,13 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) | |||
209 | #endif | 209 | #endif |
210 | 210 | ||
211 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION | 211 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION |
212 | static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) | 212 | static inline void fbcon_set_rotation(struct fb_info *info) |
213 | { | 213 | { |
214 | struct fbcon_ops *ops = info->fbcon_par; | 214 | struct fbcon_ops *ops = info->fbcon_par; |
215 | 215 | ||
216 | if (!(info->flags & FBINFO_MISC_TILEBLITTING) && | 216 | if (!(info->flags & FBINFO_MISC_TILEBLITTING) && |
217 | p->con_rotate < 4) | 217 | ops->p->con_rotate < 4) |
218 | ops->rotate = p->con_rotate; | 218 | ops->rotate = ops->p->con_rotate; |
219 | else | 219 | else |
220 | ops->rotate = 0; | 220 | ops->rotate = 0; |
221 | } | 221 | } |
@@ -265,7 +265,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) | |||
265 | fbcon_set_all_vcs(info); | 265 | fbcon_set_all_vcs(info); |
266 | } | 266 | } |
267 | #else | 267 | #else |
268 | static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) | 268 | static inline void fbcon_set_rotation(struct fb_info *info) |
269 | { | 269 | { |
270 | struct fbcon_ops *ops = info->fbcon_par; | 270 | struct fbcon_ops *ops = info->fbcon_par; |
271 | 271 | ||
@@ -402,7 +402,7 @@ static void fb_flashcursor(void *private) | |||
402 | c = scr_readw((u16 *) vc->vc_pos); | 402 | c = scr_readw((u16 *) vc->vc_pos); |
403 | mode = (!ops->cursor_flash || ops->cursor_state.enable) ? | 403 | mode = (!ops->cursor_flash || ops->cursor_state.enable) ? |
404 | CM_ERASE : CM_DRAW; | 404 | CM_ERASE : CM_DRAW; |
405 | ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1), | 405 | ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1), |
406 | get_color(vc, info, c, 0)); | 406 | get_color(vc, info, c, 0)); |
407 | release_console_sem(); | 407 | release_console_sem(); |
408 | } | 408 | } |
@@ -647,29 +647,27 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | |||
647 | } | 647 | } |
648 | 648 | ||
649 | #ifdef CONFIG_FB_TILEBLITTING | 649 | #ifdef CONFIG_FB_TILEBLITTING |
650 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info, | 650 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) |
651 | struct display *p) | ||
652 | { | 651 | { |
653 | struct fbcon_ops *ops = info->fbcon_par; | 652 | struct fbcon_ops *ops = info->fbcon_par; |
654 | 653 | ||
655 | ops->p = (p) ? p : &fb_display[vc->vc_num]; | 654 | ops->p = &fb_display[vc->vc_num]; |
656 | 655 | ||
657 | if ((info->flags & FBINFO_MISC_TILEBLITTING)) | 656 | if ((info->flags & FBINFO_MISC_TILEBLITTING)) |
658 | fbcon_set_tileops(vc, info, p, ops); | 657 | fbcon_set_tileops(vc, info); |
659 | else { | 658 | else { |
660 | fbcon_set_rotation(info, ops->p); | 659 | fbcon_set_rotation(info); |
661 | fbcon_set_bitops(ops); | 660 | fbcon_set_bitops(ops); |
662 | } | 661 | } |
663 | } | 662 | } |
664 | #else | 663 | #else |
665 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info, | 664 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) |
666 | struct display *p) | ||
667 | { | 665 | { |
668 | struct fbcon_ops *ops = info->fbcon_par; | 666 | struct fbcon_ops *ops = info->fbcon_par; |
669 | 667 | ||
670 | info->flags &= ~FBINFO_MISC_TILEBLITTING; | 668 | info->flags &= ~FBINFO_MISC_TILEBLITTING; |
671 | ops->p = (p) ? p : &fb_display[vc->vc_num]; | 669 | ops->p = &fb_display[vc->vc_num]; |
672 | fbcon_set_rotation(info, ops->p); | 670 | fbcon_set_rotation(info); |
673 | fbcon_set_bitops(ops); | 671 | fbcon_set_bitops(ops); |
674 | } | 672 | } |
675 | #endif /* CONFIG_MISC_TILEBLITTING */ | 673 | #endif /* CONFIG_MISC_TILEBLITTING */ |
@@ -689,15 +687,14 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, | |||
689 | err = -ENODEV; | 687 | err = -ENODEV; |
690 | 688 | ||
691 | if (!err) { | 689 | if (!err) { |
692 | ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); | 690 | ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); |
693 | if (!ops) | 691 | if (!ops) |
694 | err = -ENOMEM; | 692 | err = -ENOMEM; |
695 | } | 693 | } |
696 | 694 | ||
697 | if (!err) { | 695 | if (!err) { |
698 | memset(ops, 0, sizeof(struct fbcon_ops)); | ||
699 | info->fbcon_par = ops; | 696 | info->fbcon_par = ops; |
700 | set_blitting_type(vc, info, NULL); | 697 | set_blitting_type(vc, info); |
701 | } | 698 | } |
702 | 699 | ||
703 | if (err) { | 700 | if (err) { |
@@ -921,19 +918,18 @@ static const char *fbcon_startup(void) | |||
921 | return NULL; | 918 | return NULL; |
922 | } | 919 | } |
923 | 920 | ||
924 | ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); | 921 | ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); |
925 | if (!ops) { | 922 | if (!ops) { |
926 | module_put(owner); | 923 | module_put(owner); |
927 | return NULL; | 924 | return NULL; |
928 | } | 925 | } |
929 | 926 | ||
930 | memset(ops, 0, sizeof(struct fbcon_ops)); | ||
931 | ops->currcon = -1; | 927 | ops->currcon = -1; |
932 | ops->graphics = 1; | 928 | ops->graphics = 1; |
933 | ops->cur_rotate = -1; | 929 | ops->cur_rotate = -1; |
934 | info->fbcon_par = ops; | 930 | info->fbcon_par = ops; |
935 | p->con_rotate = rotate; | 931 | p->con_rotate = rotate; |
936 | set_blitting_type(vc, info, NULL); | 932 | set_blitting_type(vc, info); |
937 | 933 | ||
938 | if (info->fix.type != FB_TYPE_TEXT) { | 934 | if (info->fix.type != FB_TYPE_TEXT) { |
939 | if (fbcon_softback_size) { | 935 | if (fbcon_softback_size) { |
@@ -1093,7 +1089,7 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1093 | 1089 | ||
1094 | ops = info->fbcon_par; | 1090 | ops = info->fbcon_par; |
1095 | p->con_rotate = rotate; | 1091 | p->con_rotate = rotate; |
1096 | set_blitting_type(vc, info, NULL); | 1092 | set_blitting_type(vc, info); |
1097 | 1093 | ||
1098 | cols = vc->vc_cols; | 1094 | cols = vc->vc_cols; |
1099 | rows = vc->vc_rows; | 1095 | rows = vc->vc_rows; |
@@ -1141,9 +1137,9 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1141 | if (vc == svc && softback_buf) | 1137 | if (vc == svc && softback_buf) |
1142 | fbcon_update_softback(vc); | 1138 | fbcon_update_softback(vc); |
1143 | 1139 | ||
1144 | if (ops->rotate_font && ops->rotate_font(info, vc, p)) { | 1140 | if (ops->rotate_font && ops->rotate_font(info, vc)) { |
1145 | ops->rotate = FB_ROTATE_UR; | 1141 | ops->rotate = FB_ROTATE_UR; |
1146 | set_blitting_type(vc, info, p); | 1142 | set_blitting_type(vc, info); |
1147 | } | 1143 | } |
1148 | 1144 | ||
1149 | } | 1145 | } |
@@ -1243,7 +1239,6 @@ static void fbcon_cursor(struct vc_data *vc, int mode) | |||
1243 | { | 1239 | { |
1244 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 1240 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
1245 | struct fbcon_ops *ops = info->fbcon_par; | 1241 | struct fbcon_ops *ops = info->fbcon_par; |
1246 | struct display *p = &fb_display[vc->vc_num]; | ||
1247 | int y; | 1242 | int y; |
1248 | int c = scr_readw((u16 *) vc->vc_pos); | 1243 | int c = scr_readw((u16 *) vc->vc_pos); |
1249 | 1244 | ||
@@ -1260,7 +1255,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) | |||
1260 | y = 0; | 1255 | y = 0; |
1261 | } | 1256 | } |
1262 | 1257 | ||
1263 | ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1), | 1258 | ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1), |
1264 | get_color(vc, info, c, 0)); | 1259 | get_color(vc, info, c, 0)); |
1265 | vbl_cursor_cnt = CURSOR_DRAW_DELAY; | 1260 | vbl_cursor_cnt = CURSOR_DRAW_DELAY; |
1266 | } | 1261 | } |
@@ -1411,16 +1406,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) | |||
1411 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 1406 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
1412 | struct fbcon_ops *ops = info->fbcon_par; | 1407 | struct fbcon_ops *ops = info->fbcon_par; |
1413 | struct display *p = &fb_display[vc->vc_num]; | 1408 | struct display *p = &fb_display[vc->vc_num]; |
1414 | int redraw = 0; | ||
1415 | 1409 | ||
1416 | p->yscroll += count; | 1410 | p->yscroll += count; |
1411 | |||
1417 | if (p->yscroll > p->vrows - vc->vc_rows) { | 1412 | if (p->yscroll > p->vrows - vc->vc_rows) { |
1418 | p->yscroll -= p->vrows - vc->vc_rows; | 1413 | p->yscroll -= p->vrows - vc->vc_rows; |
1419 | redraw = 1; | ||
1420 | } | ||
1421 | |||
1422 | if (redraw) | ||
1423 | fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); | 1414 | fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); |
1415 | } | ||
1424 | 1416 | ||
1425 | ops->var.xoffset = 0; | 1417 | ops->var.xoffset = 0; |
1426 | ops->var.yoffset = p->yscroll * vc->vc_font.height; | 1418 | ops->var.yoffset = p->yscroll * vc->vc_font.height; |
@@ -1462,16 +1454,13 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) | |||
1462 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 1454 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
1463 | struct fbcon_ops *ops = info->fbcon_par; | 1455 | struct fbcon_ops *ops = info->fbcon_par; |
1464 | struct display *p = &fb_display[vc->vc_num]; | 1456 | struct display *p = &fb_display[vc->vc_num]; |
1465 | int redraw = 0; | ||
1466 | 1457 | ||
1467 | p->yscroll -= count; | 1458 | p->yscroll -= count; |
1459 | |||
1468 | if (p->yscroll < 0) { | 1460 | if (p->yscroll < 0) { |
1469 | p->yscroll += p->vrows - vc->vc_rows; | 1461 | p->yscroll += p->vrows - vc->vc_rows; |
1470 | redraw = 1; | ||
1471 | } | ||
1472 | |||
1473 | if (redraw) | ||
1474 | fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); | 1462 | fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); |
1463 | } | ||
1475 | 1464 | ||
1476 | ops->var.xoffset = 0; | 1465 | ops->var.xoffset = 0; |
1477 | ops->var.yoffset = p->yscroll * vc->vc_font.height; | 1466 | ops->var.yoffset = p->yscroll * vc->vc_font.height; |
@@ -1968,7 +1957,8 @@ static __inline__ void updatescrollmode(struct display *p, | |||
1968 | divides(ypan, vc->vc_font.height) && vyres > yres; | 1957 | divides(ypan, vc->vc_font.height) && vyres > yres; |
1969 | int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) && | 1958 | int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) && |
1970 | divides(ywrap, vc->vc_font.height) && | 1959 | divides(ywrap, vc->vc_font.height) && |
1971 | divides(vc->vc_font.height, vyres); | 1960 | divides(vc->vc_font.height, vyres) && |
1961 | divides(vc->vc_font.height, yres); | ||
1972 | int reading_fast = cap & FBINFO_READS_FAST; | 1962 | int reading_fast = cap & FBINFO_READS_FAST; |
1973 | int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && | 1963 | int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && |
1974 | !(cap & FBINFO_HWACCEL_DISABLED); | 1964 | !(cap & FBINFO_HWACCEL_DISABLED); |
@@ -2107,16 +2097,19 @@ static int fbcon_switch(struct vc_data *vc) | |||
2107 | info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { | 2097 | info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { |
2108 | if (info->fbops->fb_set_par) | 2098 | if (info->fbops->fb_set_par) |
2109 | info->fbops->fb_set_par(info); | 2099 | info->fbops->fb_set_par(info); |
2110 | fbcon_del_cursor_timer(old_info); | 2100 | |
2111 | fbcon_add_cursor_timer(info); | 2101 | if (old_info != info) { |
2102 | fbcon_del_cursor_timer(old_info); | ||
2103 | fbcon_add_cursor_timer(info); | ||
2104 | } | ||
2112 | } | 2105 | } |
2113 | 2106 | ||
2114 | set_blitting_type(vc, info, p); | 2107 | set_blitting_type(vc, info); |
2115 | ops->cursor_reset = 1; | 2108 | ops->cursor_reset = 1; |
2116 | 2109 | ||
2117 | if (ops->rotate_font && ops->rotate_font(info, vc, p)) { | 2110 | if (ops->rotate_font && ops->rotate_font(info, vc)) { |
2118 | ops->rotate = FB_ROTATE_UR; | 2111 | ops->rotate = FB_ROTATE_UR; |
2119 | set_blitting_type(vc, info, p); | 2112 | set_blitting_type(vc, info); |
2120 | } | 2113 | } |
2121 | 2114 | ||
2122 | vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); | 2115 | vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); |
@@ -2739,7 +2732,7 @@ static void fbcon_modechanged(struct fb_info *info) | |||
2739 | return; | 2732 | return; |
2740 | 2733 | ||
2741 | p = &fb_display[vc->vc_num]; | 2734 | p = &fb_display[vc->vc_num]; |
2742 | set_blitting_type(vc, info, p); | 2735 | set_blitting_type(vc, info); |
2743 | 2736 | ||
2744 | if (CON_IS_VISIBLE(vc)) { | 2737 | if (CON_IS_VISIBLE(vc)) { |
2745 | var_to_display(p, &info->var, info); | 2738 | var_to_display(p, &info->var, info); |
@@ -2781,7 +2774,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2781 | continue; | 2774 | continue; |
2782 | 2775 | ||
2783 | p = &fb_display[vc->vc_num]; | 2776 | p = &fb_display[vc->vc_num]; |
2784 | set_blitting_type(vc, info, p); | 2777 | set_blitting_type(vc, info); |
2785 | var_to_display(p, &info->var, info); | 2778 | var_to_display(p, &info->var, info); |
2786 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); | 2779 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); |
2787 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); | 2780 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); |
@@ -2806,6 +2799,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2806 | fbcon_update_softback(vc); | 2799 | fbcon_update_softback(vc); |
2807 | } | 2800 | } |
2808 | } | 2801 | } |
2802 | |||
2803 | ops->p = &fb_display[ops->currcon]; | ||
2809 | } | 2804 | } |
2810 | 2805 | ||
2811 | static int fbcon_mode_deleted(struct fb_info *info, | 2806 | static int fbcon_mode_deleted(struct fb_info *info, |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 6892e7ff34de..c38c3d8e7a74 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -62,12 +62,10 @@ struct fbcon_ops { | |||
62 | int fg, int bg); | 62 | int fg, int bg); |
63 | void (*clear_margins)(struct vc_data *vc, struct fb_info *info, | 63 | void (*clear_margins)(struct vc_data *vc, struct fb_info *info, |
64 | int bottom_only); | 64 | int bottom_only); |
65 | void (*cursor)(struct vc_data *vc, struct fb_info *info, | 65 | void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode, |
66 | struct display *p, int mode, int softback_lines, | 66 | int softback_lines, int fg, int bg); |
67 | int fg, int bg); | ||
68 | int (*update_start)(struct fb_info *info); | 67 | int (*update_start)(struct fb_info *info); |
69 | int (*rotate_font)(struct fb_info *info, struct vc_data *vc, | 68 | int (*rotate_font)(struct fb_info *info, struct vc_data *vc); |
70 | struct display *p); | ||
71 | struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ | 69 | struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ |
72 | struct timer_list cursor_timer; /* Cursor timer */ | 70 | struct timer_list cursor_timer; /* Cursor timer */ |
73 | struct fb_cursor cursor_state; | 71 | struct fb_cursor cursor_state; |
@@ -173,8 +171,7 @@ struct fbcon_ops { | |||
173 | #define SCROLL_PAN_REDRAW 0x005 | 171 | #define SCROLL_PAN_REDRAW 0x005 |
174 | 172 | ||
175 | #ifdef CONFIG_FB_TILEBLITTING | 173 | #ifdef CONFIG_FB_TILEBLITTING |
176 | extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, | 174 | extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); |
177 | struct display *p, struct fbcon_ops *ops); | ||
178 | #endif | 175 | #endif |
179 | extern void fbcon_set_bitops(struct fbcon_ops *ops); | 176 | extern void fbcon_set_bitops(struct fbcon_ops *ops); |
180 | extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); | 177 | extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); |
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 4952b66ae206..990289a69b78 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c | |||
@@ -219,19 +219,18 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | static void ccw_cursor(struct vc_data *vc, struct fb_info *info, | 222 | static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, |
223 | struct display *p, int mode, int softback_lines, | 223 | int softback_lines, int fg, int bg) |
224 | int fg, int bg) | ||
225 | { | 224 | { |
226 | struct fb_cursor cursor; | 225 | struct fb_cursor cursor; |
227 | struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; | 226 | struct fbcon_ops *ops = info->fbcon_par; |
228 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; | 227 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; |
229 | int w = (vc->vc_font.height + 7) >> 3, c; | 228 | int w = (vc->vc_font.height + 7) >> 3, c; |
230 | int y = real_y(p, vc->vc_y); | 229 | int y = real_y(ops->p, vc->vc_y); |
231 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); | 230 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); |
232 | int err = 1, dx, dy; | 231 | int err = 1, dx, dy; |
233 | char *src; | 232 | char *src; |
234 | u32 vyres = GETVYRES(p->scrollmode, info); | 233 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
235 | 234 | ||
236 | if (!ops->fontbuffer) | 235 | if (!ops->fontbuffer) |
237 | return; | 236 | return; |
@@ -303,7 +302,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, | |||
303 | } | 302 | } |
304 | 303 | ||
305 | if (cursor.set & FB_CUR_SETSIZE || | 304 | if (cursor.set & FB_CUR_SETSIZE || |
306 | vc->vc_cursor_type != p->cursor_shape || | 305 | vc->vc_cursor_type != ops->p->cursor_shape || |
307 | ops->cursor_state.mask == NULL || | 306 | ops->cursor_state.mask == NULL || |
308 | ops->cursor_reset) { | 307 | ops->cursor_reset) { |
309 | char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); | 308 | char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); |
@@ -323,10 +322,10 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, | |||
323 | kfree(ops->cursor_state.mask); | 322 | kfree(ops->cursor_state.mask); |
324 | ops->cursor_state.mask = mask; | 323 | ops->cursor_state.mask = mask; |
325 | 324 | ||
326 | p->cursor_shape = vc->vc_cursor_type; | 325 | ops->p->cursor_shape = vc->vc_cursor_type; |
327 | cursor.set |= FB_CUR_SETSHAPE; | 326 | cursor.set |= FB_CUR_SETSHAPE; |
328 | 327 | ||
329 | switch (p->cursor_shape & CUR_HWMASK) { | 328 | switch (ops->p->cursor_shape & CUR_HWMASK) { |
330 | case CUR_NONE: | 329 | case CUR_NONE: |
331 | cur_height = 0; | 330 | cur_height = 0; |
332 | break; | 331 | break; |
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 6d92b8456206..d44c5fa515fb 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c | |||
@@ -203,19 +203,18 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
203 | } | 203 | } |
204 | } | 204 | } |
205 | 205 | ||
206 | static void cw_cursor(struct vc_data *vc, struct fb_info *info, | 206 | static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, |
207 | struct display *p, int mode, int softback_lines, | 207 | int softback_lines, int fg, int bg) |
208 | int fg, int bg) | ||
209 | { | 208 | { |
210 | struct fb_cursor cursor; | 209 | struct fb_cursor cursor; |
211 | struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; | 210 | struct fbcon_ops *ops = info->fbcon_par; |
212 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; | 211 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; |
213 | int w = (vc->vc_font.height + 7) >> 3, c; | 212 | int w = (vc->vc_font.height + 7) >> 3, c; |
214 | int y = real_y(p, vc->vc_y); | 213 | int y = real_y(ops->p, vc->vc_y); |
215 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); | 214 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); |
216 | int err = 1, dx, dy; | 215 | int err = 1, dx, dy; |
217 | char *src; | 216 | char *src; |
218 | u32 vxres = GETVXRES(p->scrollmode, info); | 217 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
219 | 218 | ||
220 | if (!ops->fontbuffer) | 219 | if (!ops->fontbuffer) |
221 | return; | 220 | return; |
@@ -287,7 +286,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, | |||
287 | } | 286 | } |
288 | 287 | ||
289 | if (cursor.set & FB_CUR_SETSIZE || | 288 | if (cursor.set & FB_CUR_SETSIZE || |
290 | vc->vc_cursor_type != p->cursor_shape || | 289 | vc->vc_cursor_type != ops->p->cursor_shape || |
291 | ops->cursor_state.mask == NULL || | 290 | ops->cursor_state.mask == NULL || |
292 | ops->cursor_reset) { | 291 | ops->cursor_reset) { |
293 | char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); | 292 | char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); |
@@ -307,10 +306,10 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, | |||
307 | kfree(ops->cursor_state.mask); | 306 | kfree(ops->cursor_state.mask); |
308 | ops->cursor_state.mask = mask; | 307 | ops->cursor_state.mask = mask; |
309 | 308 | ||
310 | p->cursor_shape = vc->vc_cursor_type; | 309 | ops->p->cursor_shape = vc->vc_cursor_type; |
311 | cursor.set |= FB_CUR_SETSHAPE; | 310 | cursor.set |= FB_CUR_SETSHAPE; |
312 | 311 | ||
313 | switch (p->cursor_shape & CUR_HWMASK) { | 312 | switch (ops->p->cursor_shape & CUR_HWMASK) { |
314 | case CUR_NONE: | 313 | case CUR_NONE: |
315 | cur_height = 0; | 314 | cur_height = 0; |
316 | break; | 315 | break; |
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c index ec0dd8fe241c..2dc091fbd5c9 100644 --- a/drivers/video/console/fbcon_rotate.c +++ b/drivers/video/console/fbcon_rotate.c | |||
@@ -18,8 +18,7 @@ | |||
18 | #include "fbcon.h" | 18 | #include "fbcon.h" |
19 | #include "fbcon_rotate.h" | 19 | #include "fbcon_rotate.h" |
20 | 20 | ||
21 | static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, | 21 | static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) |
22 | struct display *p) | ||
23 | { | 22 | { |
24 | struct fbcon_ops *ops = info->fbcon_par; | 23 | struct fbcon_ops *ops = info->fbcon_par; |
25 | int len, err = 0; | 24 | int len, err = 0; |
@@ -28,12 +27,12 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, | |||
28 | u8 *dst; | 27 | u8 *dst; |
29 | 28 | ||
30 | if (vc->vc_font.data == ops->fontdata && | 29 | if (vc->vc_font.data == ops->fontdata && |
31 | p->con_rotate == ops->cur_rotate) | 30 | ops->p->con_rotate == ops->cur_rotate) |
32 | goto finished; | 31 | goto finished; |
33 | 32 | ||
34 | src = ops->fontdata = vc->vc_font.data; | 33 | src = ops->fontdata = vc->vc_font.data; |
35 | ops->cur_rotate = p->con_rotate; | 34 | ops->cur_rotate = ops->p->con_rotate; |
36 | len = (!p->userfont) ? 256 : FNTCHARCNT(src); | 35 | len = (!ops->p->userfont) ? 256 : FNTCHARCNT(src); |
37 | s_cellsize = ((vc->vc_font.width + 7)/8) * | 36 | s_cellsize = ((vc->vc_font.width + 7)/8) * |
38 | vc->vc_font.height; | 37 | vc->vc_font.height; |
39 | d_cellsize = s_cellsize; | 38 | d_cellsize = s_cellsize; |
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h index 1b8f92fdc6a8..75be5ce53dc5 100644 --- a/drivers/video/console/fbcon_rotate.h +++ b/drivers/video/console/fbcon_rotate.h | |||
@@ -11,8 +11,6 @@ | |||
11 | #ifndef _FBCON_ROTATE_H | 11 | #ifndef _FBCON_ROTATE_H |
12 | #define _FBCON_ROTATE_H | 12 | #define _FBCON_ROTATE_H |
13 | 13 | ||
14 | #define FNTCHARCNT(fd) (((int *)(fd))[-3]) | ||
15 | |||
16 | #define GETVYRES(s,i) ({ \ | 14 | #define GETVYRES(s,i) ({ \ |
17 | (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ | 15 | (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ |
18 | (i)->var.yres : (i)->var.yres_virtual; }) | 16 | (i)->var.yres : (i)->var.yres_virtual; }) |
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index 9dd059e8b645..f56ed068a5bc 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c | |||
@@ -249,20 +249,19 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | static void ud_cursor(struct vc_data *vc, struct fb_info *info, | 252 | static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, |
253 | struct display *p, int mode, int softback_lines, | 253 | int softback_lines, int fg, int bg) |
254 | int fg, int bg) | ||
255 | { | 254 | { |
256 | struct fb_cursor cursor; | 255 | struct fb_cursor cursor; |
257 | struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; | 256 | struct fbcon_ops *ops = info->fbcon_par; |
258 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; | 257 | unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; |
259 | int w = (vc->vc_font.width + 7) >> 3, c; | 258 | int w = (vc->vc_font.width + 7) >> 3, c; |
260 | int y = real_y(p, vc->vc_y); | 259 | int y = real_y(ops->p, vc->vc_y); |
261 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); | 260 | int attribute, use_sw = (vc->vc_cursor_type & 0x10); |
262 | int err = 1, dx, dy; | 261 | int err = 1, dx, dy; |
263 | char *src; | 262 | char *src; |
264 | u32 vyres = GETVYRES(p->scrollmode, info); | 263 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
265 | u32 vxres = GETVXRES(p->scrollmode, info); | 264 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
266 | 265 | ||
267 | if (!ops->fontbuffer) | 266 | if (!ops->fontbuffer) |
268 | return; | 267 | return; |
@@ -334,7 +333,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, | |||
334 | } | 333 | } |
335 | 334 | ||
336 | if (cursor.set & FB_CUR_SETSIZE || | 335 | if (cursor.set & FB_CUR_SETSIZE || |
337 | vc->vc_cursor_type != p->cursor_shape || | 336 | vc->vc_cursor_type != ops->p->cursor_shape || |
338 | ops->cursor_state.mask == NULL || | 337 | ops->cursor_state.mask == NULL || |
339 | ops->cursor_reset) { | 338 | ops->cursor_reset) { |
340 | char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); | 339 | char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); |
@@ -347,10 +346,10 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, | |||
347 | kfree(ops->cursor_state.mask); | 346 | kfree(ops->cursor_state.mask); |
348 | ops->cursor_state.mask = mask; | 347 | ops->cursor_state.mask = mask; |
349 | 348 | ||
350 | p->cursor_shape = vc->vc_cursor_type; | 349 | ops->p->cursor_shape = vc->vc_cursor_type; |
351 | cursor.set |= FB_CUR_SETSHAPE; | 350 | cursor.set |= FB_CUR_SETSHAPE; |
352 | 351 | ||
353 | switch (p->cursor_shape & CUR_HWMASK) { | 352 | switch (ops->p->cursor_shape & CUR_HWMASK) { |
354 | case CUR_NONE: | 353 | case CUR_NONE: |
355 | cur_height = 0; | 354 | cur_height = 0; |
356 | break; | 355 | break; |
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 8529bf08db28..3957fc7523e2 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | 19 | ||
20 | #include "fbcon.h" | ||
21 | |||
20 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | 22 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) |
21 | { | 23 | { |
22 | unsigned int scan_align = info->pixmap.scan_align - 1; | 24 | unsigned int scan_align = info->pixmap.scan_align - 1; |
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c index cb25324a5635..153352ca9461 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/console/tileblit.c | |||
@@ -80,9 +80,8 @@ static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
80 | return; | 80 | return; |
81 | } | 81 | } |
82 | 82 | ||
83 | static void tile_cursor(struct vc_data *vc, struct fb_info *info, | 83 | static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode, |
84 | struct display *p, int mode, int softback_lines, | 84 | int softback_lines, int fg, int bg) |
85 | int fg, int bg) | ||
86 | { | 85 | { |
87 | struct fb_tilecursor cursor; | 86 | struct fb_tilecursor cursor; |
88 | int use_sw = (vc->vc_cursor_type & 0x01); | 87 | int use_sw = (vc->vc_cursor_type & 0x01); |
@@ -130,10 +129,10 @@ static int tile_update_start(struct fb_info *info) | |||
130 | return err; | 129 | return err; |
131 | } | 130 | } |
132 | 131 | ||
133 | void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, | 132 | void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info) |
134 | struct display *p, struct fbcon_ops *ops) | ||
135 | { | 133 | { |
136 | struct fb_tilemap map; | 134 | struct fb_tilemap map; |
135 | struct fbcon_ops *ops = info->fbcon_par; | ||
137 | 136 | ||
138 | ops->bmove = tile_bmove; | 137 | ops->bmove = tile_bmove; |
139 | ops->clear = tile_clear; | 138 | ops->clear = tile_clear; |
@@ -142,13 +141,13 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, | |||
142 | ops->cursor = tile_cursor; | 141 | ops->cursor = tile_cursor; |
143 | ops->update_start = tile_update_start; | 142 | ops->update_start = tile_update_start; |
144 | 143 | ||
145 | if (p) { | 144 | if (ops->p) { |
146 | map.width = vc->vc_font.width; | 145 | map.width = vc->vc_font.width; |
147 | map.height = vc->vc_font.height; | 146 | map.height = vc->vc_font.height; |
148 | map.depth = 1; | 147 | map.depth = 1; |
149 | map.length = (p->userfont) ? | 148 | map.length = (ops->p->userfont) ? |
150 | FNTCHARCNT(p->fontdata) : 256; | 149 | FNTCHARCNT(ops->p->fontdata) : 256; |
151 | map.data = p->fontdata; | 150 | map.data = ops->p->fontdata; |
152 | info->tileops->fb_settile(info, &map); | 151 | info->tileops->fb_settile(info, &map); |
153 | } | 152 | } |
154 | } | 153 | } |
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c index 0b6af00d197e..ac90883dc3aa 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbcvt.c | |||
@@ -214,12 +214,11 @@ static void fb_cvt_print_name(struct fb_cvt_data *cvt) | |||
214 | { | 214 | { |
215 | u32 pixcount, pixcount_mod; | 215 | u32 pixcount, pixcount_mod; |
216 | int cnt = 255, offset = 0, read = 0; | 216 | int cnt = 255, offset = 0, read = 0; |
217 | u8 *buf = kmalloc(256, GFP_KERNEL); | 217 | u8 *buf = kzalloc(256, GFP_KERNEL); |
218 | 218 | ||
219 | if (!buf) | 219 | if (!buf) |
220 | return; | 220 | return; |
221 | 221 | ||
222 | memset(buf, 0, 256); | ||
223 | pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000; | 222 | pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000; |
224 | pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000; | 223 | pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000; |
225 | pixcount_mod /= 1000; | 224 | pixcount_mod /= 1000; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 10dfdf035264..32a9b69becc5 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -589,17 +589,19 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
589 | return info->fbops->fb_read(file, buf, count, ppos); | 589 | return info->fbops->fb_read(file, buf, count, ppos); |
590 | 590 | ||
591 | total_size = info->screen_size; | 591 | total_size = info->screen_size; |
592 | |||
592 | if (total_size == 0) | 593 | if (total_size == 0) |
593 | total_size = info->fix.smem_len; | 594 | total_size = info->fix.smem_len; |
594 | 595 | ||
595 | if (p >= total_size) | 596 | if (p >= total_size) |
596 | return 0; | 597 | return 0; |
598 | |||
597 | if (count >= total_size) | 599 | if (count >= total_size) |
598 | count = total_size; | 600 | count = total_size; |
601 | |||
599 | if (count + p > total_size) | 602 | if (count + p > total_size) |
600 | count = total_size - p; | 603 | count = total_size - p; |
601 | 604 | ||
602 | cnt = 0; | ||
603 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, | 605 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, |
604 | GFP_KERNEL); | 606 | GFP_KERNEL); |
605 | if (!buffer) | 607 | if (!buffer) |
@@ -636,6 +638,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
636 | } | 638 | } |
637 | 639 | ||
638 | kfree(buffer); | 640 | kfree(buffer); |
641 | |||
639 | return (err) ? err : cnt; | 642 | return (err) ? err : cnt; |
640 | } | 643 | } |
641 | 644 | ||
@@ -648,7 +651,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
648 | struct fb_info *info = registered_fb[fbidx]; | 651 | struct fb_info *info = registered_fb[fbidx]; |
649 | u32 *buffer, *src; | 652 | u32 *buffer, *src; |
650 | u32 __iomem *dst; | 653 | u32 __iomem *dst; |
651 | int c, i, cnt = 0, err; | 654 | int c, i, cnt = 0, err = 0; |
652 | unsigned long total_size; | 655 | unsigned long total_size; |
653 | 656 | ||
654 | if (!info || !info->screen_base) | 657 | if (!info || !info->screen_base) |
@@ -661,19 +664,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
661 | return info->fbops->fb_write(file, buf, count, ppos); | 664 | return info->fbops->fb_write(file, buf, count, ppos); |
662 | 665 | ||
663 | total_size = info->screen_size; | 666 | total_size = info->screen_size; |
667 | |||
664 | if (total_size == 0) | 668 | if (total_size == 0) |
665 | total_size = info->fix.smem_len; | 669 | total_size = info->fix.smem_len; |
666 | 670 | ||
667 | if (p > total_size) | 671 | if (p > total_size) |
668 | return -ENOSPC; | 672 | return 0; |
673 | |||
669 | if (count >= total_size) | 674 | if (count >= total_size) |
670 | count = total_size; | 675 | count = total_size; |
671 | err = 0; | 676 | |
672 | if (count + p > total_size) { | 677 | if (count + p > total_size) |
673 | count = total_size - p; | 678 | count = total_size - p; |
674 | err = -ENOSPC; | 679 | |
675 | } | ||
676 | cnt = 0; | ||
677 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, | 680 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, |
678 | GFP_KERNEL); | 681 | GFP_KERNEL); |
679 | if (!buffer) | 682 | if (!buffer) |
@@ -687,12 +690,15 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
687 | while (count) { | 690 | while (count) { |
688 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 691 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
689 | src = buffer; | 692 | src = buffer; |
693 | |||
690 | if (copy_from_user(src, buf, c)) { | 694 | if (copy_from_user(src, buf, c)) { |
691 | err = -EFAULT; | 695 | err = -EFAULT; |
692 | break; | 696 | break; |
693 | } | 697 | } |
698 | |||
694 | for (i = c >> 2; i--; ) | 699 | for (i = c >> 2; i--; ) |
695 | fb_writel(*src++, dst++); | 700 | fb_writel(*src++, dst++); |
701 | |||
696 | if (c & 3) { | 702 | if (c & 3) { |
697 | u8 *src8 = (u8 *) src; | 703 | u8 *src8 = (u8 *) src; |
698 | u8 __iomem *dst8 = (u8 __iomem *) dst; | 704 | u8 __iomem *dst8 = (u8 __iomem *) dst; |
@@ -702,11 +708,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
702 | 708 | ||
703 | dst = (u32 __iomem *) dst8; | 709 | dst = (u32 __iomem *) dst8; |
704 | } | 710 | } |
711 | |||
705 | *ppos += c; | 712 | *ppos += c; |
706 | buf += c; | 713 | buf += c; |
707 | cnt += c; | 714 | cnt += c; |
708 | count -= c; | 715 | count -= c; |
709 | } | 716 | } |
717 | |||
710 | kfree(buffer); | 718 | kfree(buffer); |
711 | 719 | ||
712 | return (err) ? err : cnt; | 720 | return (err) ? err : cnt; |
@@ -1226,6 +1234,7 @@ fb_open(struct inode *inode, struct file *file) | |||
1226 | return -ENODEV; | 1234 | return -ENODEV; |
1227 | if (!try_module_get(info->fbops->owner)) | 1235 | if (!try_module_get(info->fbops->owner)) |
1228 | return -ENODEV; | 1236 | return -ENODEV; |
1237 | file->private_data = info; | ||
1229 | if (info->fbops->fb_open) { | 1238 | if (info->fbops->fb_open) { |
1230 | res = info->fbops->fb_open(info,1); | 1239 | res = info->fbops->fb_open(info,1); |
1231 | if (res) | 1240 | if (res) |
@@ -1237,11 +1246,9 @@ fb_open(struct inode *inode, struct file *file) | |||
1237 | static int | 1246 | static int |
1238 | fb_release(struct inode *inode, struct file *file) | 1247 | fb_release(struct inode *inode, struct file *file) |
1239 | { | 1248 | { |
1240 | int fbidx = iminor(inode); | 1249 | struct fb_info * const info = file->private_data; |
1241 | struct fb_info *info; | ||
1242 | 1250 | ||
1243 | lock_kernel(); | 1251 | lock_kernel(); |
1244 | info = registered_fb[fbidx]; | ||
1245 | if (info->fbops->fb_release) | 1252 | if (info->fbops->fb_release) |
1246 | info->fbops->fb_release(info,1); | 1253 | info->fbops->fb_release(info,1); |
1247 | module_put(info->fbops->owner); | 1254 | module_put(info->fbops->owner); |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index fc7965b66775..7c74e7325d95 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -317,26 +317,29 @@ static int edid_is_monitor_block(unsigned char *block) | |||
317 | static void calc_mode_timings(int xres, int yres, int refresh, | 317 | static void calc_mode_timings(int xres, int yres, int refresh, |
318 | struct fb_videomode *mode) | 318 | struct fb_videomode *mode) |
319 | { | 319 | { |
320 | struct fb_var_screeninfo var; | 320 | struct fb_var_screeninfo *var; |
321 | struct fb_info info; | ||
322 | 321 | ||
323 | memset(&var, 0, sizeof(struct fb_var_screeninfo)); | 322 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); |
324 | var.xres = xres; | 323 | |
325 | var.yres = yres; | 324 | if (var) { |
326 | fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, | 325 | var->xres = xres; |
327 | refresh, &var, &info); | 326 | var->yres = yres; |
328 | mode->xres = xres; | 327 | fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, |
329 | mode->yres = yres; | 328 | refresh, var, NULL); |
330 | mode->pixclock = var.pixclock; | 329 | mode->xres = xres; |
331 | mode->refresh = refresh; | 330 | mode->yres = yres; |
332 | mode->left_margin = var.left_margin; | 331 | mode->pixclock = var->pixclock; |
333 | mode->right_margin = var.right_margin; | 332 | mode->refresh = refresh; |
334 | mode->upper_margin = var.upper_margin; | 333 | mode->left_margin = var->left_margin; |
335 | mode->lower_margin = var.lower_margin; | 334 | mode->right_margin = var->right_margin; |
336 | mode->hsync_len = var.hsync_len; | 335 | mode->upper_margin = var->upper_margin; |
337 | mode->vsync_len = var.vsync_len; | 336 | mode->lower_margin = var->lower_margin; |
338 | mode->vmode = 0; | 337 | mode->hsync_len = var->hsync_len; |
339 | mode->sync = 0; | 338 | mode->vsync_len = var->vsync_len; |
339 | mode->vmode = 0; | ||
340 | mode->sync = 0; | ||
341 | kfree(var); | ||
342 | } | ||
340 | } | 343 | } |
341 | 344 | ||
342 | static int get_est_timing(unsigned char *block, struct fb_videomode *mode) | 345 | static int get_est_timing(unsigned char *block, struct fb_videomode *mode) |
@@ -525,10 +528,9 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | |||
525 | unsigned char *block; | 528 | unsigned char *block; |
526 | int num = 0, i; | 529 | int num = 0, i; |
527 | 530 | ||
528 | mode = kmalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); | 531 | mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); |
529 | if (mode == NULL) | 532 | if (mode == NULL) |
530 | return NULL; | 533 | return NULL; |
531 | memset(mode, 0, 50 * sizeof(struct fb_videomode)); | ||
532 | 534 | ||
533 | if (edid == NULL || !edid_checksum(edid) || | 535 | if (edid == NULL || !edid_checksum(edid) || |
534 | !edid_check_header(edid)) { | 536 | !edid_check_header(edid)) { |
@@ -1105,15 +1107,21 @@ static void fb_timings_dclk(struct __fb_timings *timings) | |||
1105 | */ | 1107 | */ |
1106 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) | 1108 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) |
1107 | { | 1109 | { |
1108 | struct __fb_timings timings; | 1110 | struct __fb_timings *timings; |
1109 | u32 interlace = 1, dscan = 1; | 1111 | u32 interlace = 1, dscan = 1; |
1110 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; | 1112 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0; |
1113 | |||
1114 | |||
1115 | timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL); | ||
1116 | |||
1117 | if (!timings) | ||
1118 | return -ENOMEM; | ||
1111 | 1119 | ||
1112 | /* | 1120 | /* |
1113 | * If monspecs are invalid, use values that are enough | 1121 | * If monspecs are invalid, use values that are enough |
1114 | * for 640x480@60 | 1122 | * for 640x480@60 |
1115 | */ | 1123 | */ |
1116 | if (!info->monspecs.hfmax || !info->monspecs.vfmax || | 1124 | if (!info || !info->monspecs.hfmax || !info->monspecs.vfmax || |
1117 | !info->monspecs.dclkmax || | 1125 | !info->monspecs.dclkmax || |
1118 | info->monspecs.hfmax < info->monspecs.hfmin || | 1126 | info->monspecs.hfmax < info->monspecs.hfmin || |
1119 | info->monspecs.vfmax < info->monspecs.vfmin || | 1127 | info->monspecs.vfmax < info->monspecs.vfmin || |
@@ -1130,65 +1138,66 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1130 | dclkmax = info->monspecs.dclkmax; | 1138 | dclkmax = info->monspecs.dclkmax; |
1131 | } | 1139 | } |
1132 | 1140 | ||
1133 | memset(&timings, 0, sizeof(struct __fb_timings)); | 1141 | timings->hactive = var->xres; |
1134 | timings.hactive = var->xres; | 1142 | timings->vactive = var->yres; |
1135 | timings.vactive = var->yres; | ||
1136 | if (var->vmode & FB_VMODE_INTERLACED) { | 1143 | if (var->vmode & FB_VMODE_INTERLACED) { |
1137 | timings.vactive /= 2; | 1144 | timings->vactive /= 2; |
1138 | interlace = 2; | 1145 | interlace = 2; |
1139 | } | 1146 | } |
1140 | if (var->vmode & FB_VMODE_DOUBLE) { | 1147 | if (var->vmode & FB_VMODE_DOUBLE) { |
1141 | timings.vactive *= 2; | 1148 | timings->vactive *= 2; |
1142 | dscan = 2; | 1149 | dscan = 2; |
1143 | } | 1150 | } |
1144 | 1151 | ||
1145 | switch (flags & ~FB_IGNOREMON) { | 1152 | switch (flags & ~FB_IGNOREMON) { |
1146 | case FB_MAXTIMINGS: /* maximize refresh rate */ | 1153 | case FB_MAXTIMINGS: /* maximize refresh rate */ |
1147 | timings.hfreq = hfmax; | 1154 | timings->hfreq = hfmax; |
1148 | fb_timings_hfreq(&timings); | 1155 | fb_timings_hfreq(timings); |
1149 | if (timings.vfreq > vfmax) { | 1156 | if (timings->vfreq > vfmax) { |
1150 | timings.vfreq = vfmax; | 1157 | timings->vfreq = vfmax; |
1151 | fb_timings_vfreq(&timings); | 1158 | fb_timings_vfreq(timings); |
1152 | } | 1159 | } |
1153 | if (timings.dclk > dclkmax) { | 1160 | if (timings->dclk > dclkmax) { |
1154 | timings.dclk = dclkmax; | 1161 | timings->dclk = dclkmax; |
1155 | fb_timings_dclk(&timings); | 1162 | fb_timings_dclk(timings); |
1156 | } | 1163 | } |
1157 | break; | 1164 | break; |
1158 | case FB_VSYNCTIMINGS: /* vrefresh driven */ | 1165 | case FB_VSYNCTIMINGS: /* vrefresh driven */ |
1159 | timings.vfreq = val; | 1166 | timings->vfreq = val; |
1160 | fb_timings_vfreq(&timings); | 1167 | fb_timings_vfreq(timings); |
1161 | break; | 1168 | break; |
1162 | case FB_HSYNCTIMINGS: /* hsync driven */ | 1169 | case FB_HSYNCTIMINGS: /* hsync driven */ |
1163 | timings.hfreq = val; | 1170 | timings->hfreq = val; |
1164 | fb_timings_hfreq(&timings); | 1171 | fb_timings_hfreq(timings); |
1165 | break; | 1172 | break; |
1166 | case FB_DCLKTIMINGS: /* pixelclock driven */ | 1173 | case FB_DCLKTIMINGS: /* pixelclock driven */ |
1167 | timings.dclk = PICOS2KHZ(val) * 1000; | 1174 | timings->dclk = PICOS2KHZ(val) * 1000; |
1168 | fb_timings_dclk(&timings); | 1175 | fb_timings_dclk(timings); |
1169 | break; | 1176 | break; |
1170 | default: | 1177 | default: |
1171 | return -EINVAL; | 1178 | err = -EINVAL; |
1172 | 1179 | ||
1173 | } | 1180 | } |
1174 | 1181 | ||
1175 | if (!(flags & FB_IGNOREMON) && | 1182 | if (err || (!(flags & FB_IGNOREMON) && |
1176 | (timings.vfreq < vfmin || timings.vfreq > vfmax || | 1183 | (timings->vfreq < vfmin || timings->vfreq > vfmax || |
1177 | timings.hfreq < hfmin || timings.hfreq > hfmax || | 1184 | timings->hfreq < hfmin || timings->hfreq > hfmax || |
1178 | timings.dclk < dclkmin || timings.dclk > dclkmax)) | 1185 | timings->dclk < dclkmin || timings->dclk > dclkmax))) { |
1179 | return -EINVAL; | 1186 | err = -EINVAL; |
1180 | 1187 | } else { | |
1181 | var->pixclock = KHZ2PICOS(timings.dclk/1000); | 1188 | var->pixclock = KHZ2PICOS(timings->dclk/1000); |
1182 | var->hsync_len = (timings.htotal * 8)/100; | 1189 | var->hsync_len = (timings->htotal * 8)/100; |
1183 | var->right_margin = (timings.hblank/2) - var->hsync_len; | 1190 | var->right_margin = (timings->hblank/2) - var->hsync_len; |
1184 | var->left_margin = timings.hblank - var->right_margin - var->hsync_len; | 1191 | var->left_margin = timings->hblank - var->right_margin - |
1185 | 1192 | var->hsync_len; | |
1186 | var->vsync_len = (3 * interlace)/dscan; | 1193 | var->vsync_len = (3 * interlace)/dscan; |
1187 | var->lower_margin = (1 * interlace)/dscan; | 1194 | var->lower_margin = (1 * interlace)/dscan; |
1188 | var->upper_margin = (timings.vblank * interlace)/dscan - | 1195 | var->upper_margin = (timings->vblank * interlace)/dscan - |
1189 | (var->vsync_len + var->lower_margin); | 1196 | (var->vsync_len + var->lower_margin); |
1197 | } | ||
1190 | 1198 | ||
1191 | return 0; | 1199 | kfree(timings); |
1200 | return err; | ||
1192 | } | 1201 | } |
1193 | #else | 1202 | #else |
1194 | int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) | 1203 | int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 08dac9580d15..6d26057337e2 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -43,10 +43,11 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) | |||
43 | if (size) | 43 | if (size) |
44 | fb_info_size += PADDING; | 44 | fb_info_size += PADDING; |
45 | 45 | ||
46 | p = kmalloc(fb_info_size + size, GFP_KERNEL); | 46 | p = kzalloc(fb_info_size + size, GFP_KERNEL); |
47 | |||
47 | if (!p) | 48 | if (!p) |
48 | return NULL; | 49 | return NULL; |
49 | memset(p, 0, fb_info_size + size); | 50 | |
50 | info = (struct fb_info *) p; | 51 | info = (struct fb_info *) p; |
51 | 52 | ||
52 | if (size) | 53 | if (size) |
@@ -106,8 +107,7 @@ static int mode_string(char *buf, unsigned int offset, | |||
106 | static ssize_t store_mode(struct class_device *class_device, const char * buf, | 107 | static ssize_t store_mode(struct class_device *class_device, const char * buf, |
107 | size_t count) | 108 | size_t count) |
108 | { | 109 | { |
109 | struct fb_info *fb_info = | 110 | struct fb_info *fb_info = class_get_devdata(class_device); |
110 | (struct fb_info *)class_get_devdata(class_device); | ||
111 | char mstr[100]; | 111 | char mstr[100]; |
112 | struct fb_var_screeninfo var; | 112 | struct fb_var_screeninfo var; |
113 | struct fb_modelist *modelist; | 113 | struct fb_modelist *modelist; |
@@ -137,8 +137,7 @@ static ssize_t store_mode(struct class_device *class_device, const char * buf, | |||
137 | 137 | ||
138 | static ssize_t show_mode(struct class_device *class_device, char *buf) | 138 | static ssize_t show_mode(struct class_device *class_device, char *buf) |
139 | { | 139 | { |
140 | struct fb_info *fb_info = | 140 | struct fb_info *fb_info = class_get_devdata(class_device); |
141 | (struct fb_info *)class_get_devdata(class_device); | ||
142 | 141 | ||
143 | if (!fb_info->mode) | 142 | if (!fb_info->mode) |
144 | return 0; | 143 | return 0; |
@@ -149,8 +148,7 @@ static ssize_t show_mode(struct class_device *class_device, char *buf) | |||
149 | static ssize_t store_modes(struct class_device *class_device, const char * buf, | 148 | static ssize_t store_modes(struct class_device *class_device, const char * buf, |
150 | size_t count) | 149 | size_t count) |
151 | { | 150 | { |
152 | struct fb_info *fb_info = | 151 | struct fb_info *fb_info = class_get_devdata(class_device); |
153 | (struct fb_info *)class_get_devdata(class_device); | ||
154 | LIST_HEAD(old_list); | 152 | LIST_HEAD(old_list); |
155 | int i = count / sizeof(struct fb_videomode); | 153 | int i = count / sizeof(struct fb_videomode); |
156 | 154 | ||
@@ -174,8 +172,7 @@ static ssize_t store_modes(struct class_device *class_device, const char * buf, | |||
174 | 172 | ||
175 | static ssize_t show_modes(struct class_device *class_device, char *buf) | 173 | static ssize_t show_modes(struct class_device *class_device, char *buf) |
176 | { | 174 | { |
177 | struct fb_info *fb_info = | 175 | struct fb_info *fb_info = class_get_devdata(class_device); |
178 | (struct fb_info *)class_get_devdata(class_device); | ||
179 | unsigned int i; | 176 | unsigned int i; |
180 | struct list_head *pos; | 177 | struct list_head *pos; |
181 | struct fb_modelist *modelist; | 178 | struct fb_modelist *modelist; |
@@ -193,8 +190,7 @@ static ssize_t show_modes(struct class_device *class_device, char *buf) | |||
193 | static ssize_t store_bpp(struct class_device *class_device, const char * buf, | 190 | static ssize_t store_bpp(struct class_device *class_device, const char * buf, |
194 | size_t count) | 191 | size_t count) |
195 | { | 192 | { |
196 | struct fb_info *fb_info = | 193 | struct fb_info *fb_info = class_get_devdata(class_device); |
197 | (struct fb_info *)class_get_devdata(class_device); | ||
198 | struct fb_var_screeninfo var; | 194 | struct fb_var_screeninfo var; |
199 | char ** last = NULL; | 195 | char ** last = NULL; |
200 | int err; | 196 | int err; |
@@ -208,8 +204,7 @@ static ssize_t store_bpp(struct class_device *class_device, const char * buf, | |||
208 | 204 | ||
209 | static ssize_t show_bpp(struct class_device *class_device, char *buf) | 205 | static ssize_t show_bpp(struct class_device *class_device, char *buf) |
210 | { | 206 | { |
211 | struct fb_info *fb_info = | 207 | struct fb_info *fb_info = class_get_devdata(class_device); |
212 | (struct fb_info *)class_get_devdata(class_device); | ||
213 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); | 208 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); |
214 | } | 209 | } |
215 | 210 | ||
@@ -280,8 +275,7 @@ static ssize_t show_con_rotate(struct class_device *class_device, char *buf) | |||
280 | static ssize_t store_virtual(struct class_device *class_device, | 275 | static ssize_t store_virtual(struct class_device *class_device, |
281 | const char * buf, size_t count) | 276 | const char * buf, size_t count) |
282 | { | 277 | { |
283 | struct fb_info *fb_info = | 278 | struct fb_info *fb_info = class_get_devdata(class_device); |
284 | (struct fb_info *)class_get_devdata(class_device); | ||
285 | struct fb_var_screeninfo var; | 279 | struct fb_var_screeninfo var; |
286 | char *last = NULL; | 280 | char *last = NULL; |
287 | int err; | 281 | int err; |
@@ -300,16 +294,14 @@ static ssize_t store_virtual(struct class_device *class_device, | |||
300 | 294 | ||
301 | static ssize_t show_virtual(struct class_device *class_device, char *buf) | 295 | static ssize_t show_virtual(struct class_device *class_device, char *buf) |
302 | { | 296 | { |
303 | struct fb_info *fb_info = | 297 | struct fb_info *fb_info = class_get_devdata(class_device); |
304 | (struct fb_info *)class_get_devdata(class_device); | ||
305 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, | 298 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, |
306 | fb_info->var.yres_virtual); | 299 | fb_info->var.yres_virtual); |
307 | } | 300 | } |
308 | 301 | ||
309 | static ssize_t show_stride(struct class_device *class_device, char *buf) | 302 | static ssize_t show_stride(struct class_device *class_device, char *buf) |
310 | { | 303 | { |
311 | struct fb_info *fb_info = | 304 | struct fb_info *fb_info = class_get_devdata(class_device); |
312 | (struct fb_info *)class_get_devdata(class_device); | ||
313 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); | 305 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); |
314 | } | 306 | } |
315 | 307 | ||
@@ -320,7 +312,7 @@ static ssize_t show_stride(struct class_device *class_device, char *buf) | |||
320 | static ssize_t store_cmap(struct class_device *class_device, const char *buf, | 312 | static ssize_t store_cmap(struct class_device *class_device, const char *buf, |
321 | size_t count) | 313 | size_t count) |
322 | { | 314 | { |
323 | struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 315 | struct fb_info *fb_info = class_get_devdata(class_device); |
324 | int rc, i, start, length, transp = 0; | 316 | int rc, i, start, length, transp = 0; |
325 | 317 | ||
326 | if ((count > PAGE_SIZE) || ((count % 16) != 0)) | 318 | if ((count > PAGE_SIZE) || ((count % 16) != 0)) |
@@ -380,8 +372,7 @@ static ssize_t store_cmap(struct class_device *class_device, const char *buf, | |||
380 | 372 | ||
381 | static ssize_t show_cmap(struct class_device *class_device, char *buf) | 373 | static ssize_t show_cmap(struct class_device *class_device, char *buf) |
382 | { | 374 | { |
383 | struct fb_info *fb_info = | 375 | struct fb_info *fb_info = class_get_devdata(class_device); |
384 | (struct fb_info *)class_get_devdata(class_device); | ||
385 | unsigned int i; | 376 | unsigned int i; |
386 | 377 | ||
387 | if (!fb_info->cmap.red || !fb_info->cmap.blue || | 378 | if (!fb_info->cmap.red || !fb_info->cmap.blue || |
@@ -405,8 +396,7 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) | |||
405 | static ssize_t store_blank(struct class_device *class_device, const char * buf, | 396 | static ssize_t store_blank(struct class_device *class_device, const char * buf, |
406 | size_t count) | 397 | size_t count) |
407 | { | 398 | { |
408 | struct fb_info *fb_info = | 399 | struct fb_info *fb_info = class_get_devdata(class_device); |
409 | (struct fb_info *)class_get_devdata(class_device); | ||
410 | char *last = NULL; | 400 | char *last = NULL; |
411 | int err; | 401 | int err; |
412 | 402 | ||
@@ -422,41 +412,40 @@ static ssize_t store_blank(struct class_device *class_device, const char * buf, | |||
422 | 412 | ||
423 | static ssize_t show_blank(struct class_device *class_device, char *buf) | 413 | static ssize_t show_blank(struct class_device *class_device, char *buf) |
424 | { | 414 | { |
425 | // struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 415 | // struct fb_info *fb_info = class_get_devdata(class_device); |
426 | return 0; | 416 | return 0; |
427 | } | 417 | } |
428 | 418 | ||
429 | static ssize_t store_console(struct class_device *class_device, | 419 | static ssize_t store_console(struct class_device *class_device, |
430 | const char * buf, size_t count) | 420 | const char * buf, size_t count) |
431 | { | 421 | { |
432 | // struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 422 | // struct fb_info *fb_info = class_get_devdata(class_device); |
433 | return 0; | 423 | return 0; |
434 | } | 424 | } |
435 | 425 | ||
436 | static ssize_t show_console(struct class_device *class_device, char *buf) | 426 | static ssize_t show_console(struct class_device *class_device, char *buf) |
437 | { | 427 | { |
438 | // struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 428 | // struct fb_info *fb_info = class_get_devdata(class_device); |
439 | return 0; | 429 | return 0; |
440 | } | 430 | } |
441 | 431 | ||
442 | static ssize_t store_cursor(struct class_device *class_device, | 432 | static ssize_t store_cursor(struct class_device *class_device, |
443 | const char * buf, size_t count) | 433 | const char * buf, size_t count) |
444 | { | 434 | { |
445 | // struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 435 | // struct fb_info *fb_info = class_get_devdata(class_device); |
446 | return 0; | 436 | return 0; |
447 | } | 437 | } |
448 | 438 | ||
449 | static ssize_t show_cursor(struct class_device *class_device, char *buf) | 439 | static ssize_t show_cursor(struct class_device *class_device, char *buf) |
450 | { | 440 | { |
451 | // struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 441 | // struct fb_info *fb_info = class_get_devdata(class_device); |
452 | return 0; | 442 | return 0; |
453 | } | 443 | } |
454 | 444 | ||
455 | static ssize_t store_pan(struct class_device *class_device, const char * buf, | 445 | static ssize_t store_pan(struct class_device *class_device, const char * buf, |
456 | size_t count) | 446 | size_t count) |
457 | { | 447 | { |
458 | struct fb_info *fb_info = | 448 | struct fb_info *fb_info = class_get_devdata(class_device); |
459 | (struct fb_info *)class_get_devdata(class_device); | ||
460 | struct fb_var_screeninfo var; | 449 | struct fb_var_screeninfo var; |
461 | char *last = NULL; | 450 | char *last = NULL; |
462 | int err; | 451 | int err; |
@@ -479,19 +468,40 @@ static ssize_t store_pan(struct class_device *class_device, const char * buf, | |||
479 | 468 | ||
480 | static ssize_t show_pan(struct class_device *class_device, char *buf) | 469 | static ssize_t show_pan(struct class_device *class_device, char *buf) |
481 | { | 470 | { |
482 | struct fb_info *fb_info = | 471 | struct fb_info *fb_info = class_get_devdata(class_device); |
483 | (struct fb_info *)class_get_devdata(class_device); | ||
484 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, | 472 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, |
485 | fb_info->var.xoffset); | 473 | fb_info->var.xoffset); |
486 | } | 474 | } |
487 | 475 | ||
488 | static ssize_t show_name(struct class_device *class_device, char *buf) | 476 | static ssize_t show_name(struct class_device *class_device, char *buf) |
489 | { | 477 | { |
490 | struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 478 | struct fb_info *fb_info = class_get_devdata(class_device); |
491 | 479 | ||
492 | return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); | 480 | return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); |
493 | } | 481 | } |
494 | 482 | ||
483 | static ssize_t store_fbstate(struct class_device *class_device, | ||
484 | const char *buf, size_t count) | ||
485 | { | ||
486 | struct fb_info *fb_info = class_get_devdata(class_device); | ||
487 | u32 state; | ||
488 | char *last = NULL; | ||
489 | |||
490 | state = simple_strtoul(buf, &last, 0); | ||
491 | |||
492 | acquire_console_sem(); | ||
493 | fb_set_suspend(fb_info, (int)state); | ||
494 | release_console_sem(); | ||
495 | |||
496 | return count; | ||
497 | } | ||
498 | |||
499 | static ssize_t show_fbstate(struct class_device *class_device, char *buf) | ||
500 | { | ||
501 | struct fb_info *fb_info = class_get_devdata(class_device); | ||
502 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); | ||
503 | } | ||
504 | |||
495 | static struct class_device_attribute class_device_attrs[] = { | 505 | static struct class_device_attribute class_device_attrs[] = { |
496 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), | 506 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), |
497 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), | 507 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), |
@@ -507,6 +517,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
507 | __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), | 517 | __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), |
508 | __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), | 518 | __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), |
509 | __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), | 519 | __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), |
520 | __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), | ||
510 | }; | 521 | }; |
511 | 522 | ||
512 | int fb_init_class_device(struct fb_info *fb_info) | 523 | int fb_init_class_device(struct fb_info *fb_info) |
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index b37cea7d1094..4e39035cf335 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/fb.h> | 42 | #include <linux/fb.h> |
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/ioport.h> | 44 | #include <linux/ioport.h> |
45 | #include <linux/platform_device.h> | ||
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | #include <asm/vga.h> | 47 | #include <asm/vga.h> |
47 | 48 | ||
@@ -107,7 +108,7 @@ static DEFINE_SPINLOCK(hga_reg_lock); | |||
107 | 108 | ||
108 | /* Framebuffer driver structures */ | 109 | /* Framebuffer driver structures */ |
109 | 110 | ||
110 | static struct fb_var_screeninfo hga_default_var = { | 111 | static struct fb_var_screeninfo __initdata hga_default_var = { |
111 | .xres = 720, | 112 | .xres = 720, |
112 | .yres = 348, | 113 | .yres = 348, |
113 | .xres_virtual = 720, | 114 | .xres_virtual = 720, |
@@ -121,7 +122,7 @@ static struct fb_var_screeninfo hga_default_var = { | |||
121 | .width = -1, | 122 | .width = -1, |
122 | }; | 123 | }; |
123 | 124 | ||
124 | static struct fb_fix_screeninfo hga_fix = { | 125 | static struct fb_fix_screeninfo __initdata hga_fix = { |
125 | .id = "HGA", | 126 | .id = "HGA", |
126 | .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ | 127 | .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ |
127 | .visual = FB_VISUAL_MONO10, | 128 | .visual = FB_VISUAL_MONO10, |
@@ -131,8 +132,6 @@ static struct fb_fix_screeninfo hga_fix = { | |||
131 | .accel = FB_ACCEL_NONE | 132 | .accel = FB_ACCEL_NONE |
132 | }; | 133 | }; |
133 | 134 | ||
134 | static struct fb_info fb_info; | ||
135 | |||
136 | /* Don't assume that tty1 will be the initial current console. */ | 135 | /* Don't assume that tty1 will be the initial current console. */ |
137 | static int release_io_port = 0; | 136 | static int release_io_port = 0; |
138 | static int release_io_ports = 0; | 137 | static int release_io_ports = 0; |
@@ -549,10 +548,9 @@ static struct fb_ops hgafb_ops = { | |||
549 | * Initialization | 548 | * Initialization |
550 | */ | 549 | */ |
551 | 550 | ||
552 | static int __init hgafb_init(void) | 551 | static int __init hgafb_probe(struct device *device) |
553 | { | 552 | { |
554 | if (fb_get_options("hgafb", NULL)) | 553 | struct fb_info *info; |
555 | return -ENODEV; | ||
556 | 554 | ||
557 | if (! hga_card_detect()) { | 555 | if (! hga_card_detect()) { |
558 | printk(KERN_INFO "hgafb: HGA card not detected.\n"); | 556 | printk(KERN_INFO "hgafb: HGA card not detected.\n"); |
@@ -564,41 +562,95 @@ static int __init hgafb_init(void) | |||
564 | printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", | 562 | printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", |
565 | hga_type_name, hga_vram_len/1024); | 563 | hga_type_name, hga_vram_len/1024); |
566 | 564 | ||
565 | info = framebuffer_alloc(0, NULL); | ||
566 | if (!info) { | ||
567 | iounmap(hga_vram); | ||
568 | return -ENOMEM; | ||
569 | } | ||
570 | |||
567 | hga_fix.smem_start = (unsigned long)hga_vram; | 571 | hga_fix.smem_start = (unsigned long)hga_vram; |
568 | hga_fix.smem_len = hga_vram_len; | 572 | hga_fix.smem_len = hga_vram_len; |
569 | 573 | ||
570 | fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 574 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
571 | fb_info.var = hga_default_var; | 575 | info->var = hga_default_var; |
572 | fb_info.fix = hga_fix; | 576 | info->fix = hga_fix; |
573 | fb_info.monspecs.hfmin = 0; | 577 | info->monspecs.hfmin = 0; |
574 | fb_info.monspecs.hfmax = 0; | 578 | info->monspecs.hfmax = 0; |
575 | fb_info.monspecs.vfmin = 10000; | 579 | info->monspecs.vfmin = 10000; |
576 | fb_info.monspecs.vfmax = 10000; | 580 | info->monspecs.vfmax = 10000; |
577 | fb_info.monspecs.dpms = 0; | 581 | info->monspecs.dpms = 0; |
578 | fb_info.fbops = &hgafb_ops; | 582 | info->fbops = &hgafb_ops; |
579 | fb_info.screen_base = hga_vram; | 583 | info->screen_base = hga_vram; |
580 | 584 | ||
581 | if (register_framebuffer(&fb_info) < 0) { | 585 | if (register_framebuffer(info) < 0) { |
586 | framebuffer_release(info); | ||
582 | iounmap(hga_vram); | 587 | iounmap(hga_vram); |
583 | return -EINVAL; | 588 | return -EINVAL; |
584 | } | 589 | } |
585 | 590 | ||
586 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 591 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
587 | fb_info.node, fb_info.fix.id); | 592 | info->node, info->fix.id); |
593 | dev_set_drvdata(device, info); | ||
588 | return 0; | 594 | return 0; |
589 | } | 595 | } |
590 | 596 | ||
591 | #ifdef MODULE | 597 | static int hgafb_remove(struct device *device) |
592 | static void __exit hgafb_exit(void) | ||
593 | { | 598 | { |
599 | struct fb_info *info = dev_get_drvdata(device); | ||
600 | |||
594 | hga_txt_mode(); | 601 | hga_txt_mode(); |
595 | hga_clear_screen(); | 602 | hga_clear_screen(); |
596 | unregister_framebuffer(&fb_info); | 603 | |
604 | if (info) { | ||
605 | unregister_framebuffer(info); | ||
606 | framebuffer_release(info); | ||
607 | } | ||
608 | |||
597 | iounmap(hga_vram); | 609 | iounmap(hga_vram); |
598 | if (release_io_ports) release_region(0x3b0, 12); | 610 | |
599 | if (release_io_port) release_region(0x3bf, 1); | 611 | if (release_io_ports) |
612 | release_region(0x3b0, 12); | ||
613 | |||
614 | if (release_io_port) | ||
615 | release_region(0x3bf, 1); | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static struct device_driver hgafb_driver = { | ||
621 | .name = "hgafb", | ||
622 | .bus = &platform_bus_type, | ||
623 | .probe = hgafb_probe, | ||
624 | .remove = hgafb_remove, | ||
625 | }; | ||
626 | |||
627 | static struct platform_device hgafb_device = { | ||
628 | .name = "hgafb", | ||
629 | }; | ||
630 | |||
631 | static int __init hgafb_init(void) | ||
632 | { | ||
633 | int ret; | ||
634 | |||
635 | if (fb_get_options("hgafb", NULL)) | ||
636 | return -ENODEV; | ||
637 | |||
638 | ret = driver_register(&hgafb_driver); | ||
639 | |||
640 | if (!ret) { | ||
641 | ret = platform_device_register(&hgafb_device); | ||
642 | if (ret) | ||
643 | driver_unregister(&hgafb_driver); | ||
644 | } | ||
645 | |||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | static void __exit hgafb_exit(void) | ||
650 | { | ||
651 | platform_device_unregister(&hgafb_device); | ||
652 | driver_unregister(&hgafb_driver); | ||
600 | } | 653 | } |
601 | #endif | ||
602 | 654 | ||
603 | /* ------------------------------------------------------------------------- | 655 | /* ------------------------------------------------------------------------- |
604 | * | 656 | * |
@@ -613,7 +665,4 @@ MODULE_LICENSE("GPL"); | |||
613 | module_param(nologo, bool, 0); | 665 | module_param(nologo, bool, 0); |
614 | MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)"); | 666 | MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)"); |
615 | module_init(hgafb_init); | 667 | module_init(hgafb_init); |
616 | |||
617 | #ifdef MODULE | ||
618 | module_exit(hgafb_exit); | 668 | module_exit(hgafb_exit); |
619 | #endif | ||
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index c61bad0da20f..bd410e06db73 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/fb.h> | 17 | #include <linux/fb.h> |
18 | #include "i810.h" | 18 | #include "i810.h" |
19 | #include "i810_regs.h" | 19 | #include "i810_regs.h" |
20 | #include "i810_main.h" | ||
20 | #include "../edid.h" | 21 | #include "../edid.h" |
21 | 22 | ||
22 | #define I810_DDC 0x50 | 23 | #define I810_DDC 0x50 |
@@ -42,7 +43,7 @@ | |||
42 | 43 | ||
43 | static void i810i2c_setscl(void *data, int state) | 44 | static void i810i2c_setscl(void *data, int state) |
44 | { | 45 | { |
45 | struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; | 46 | struct i810fb_i2c_chan *chan = data; |
46 | struct i810fb_par *par = chan->par; | 47 | struct i810fb_par *par = chan->par; |
47 | u8 __iomem *mmio = par->mmio_start_virtual; | 48 | u8 __iomem *mmio = par->mmio_start_virtual; |
48 | 49 | ||
diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c index 64cd1c827cf0..76764ea3486a 100644 --- a/drivers/video/i810/i810_accel.c +++ b/drivers/video/i810/i810_accel.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "i810_regs.h" | 15 | #include "i810_regs.h" |
16 | #include "i810.h" | 16 | #include "i810.h" |
17 | #include "i810_main.h" | ||
17 | 18 | ||
18 | static u32 i810fb_rop[] = { | 19 | static u32 i810fb_rop[] = { |
19 | COLOR_COPY_ROP, /* ROP_COPY */ | 20 | COLOR_COPY_ROP, /* ROP_COPY */ |
@@ -57,7 +58,7 @@ static inline void i810_report_error(u8 __iomem *mmio) | |||
57 | */ | 58 | */ |
58 | static inline int wait_for_space(struct fb_info *info, u32 space) | 59 | static inline int wait_for_space(struct fb_info *info, u32 space) |
59 | { | 60 | { |
60 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 61 | struct i810fb_par *par = info->par; |
61 | u32 head, count = WAIT_COUNT, tail; | 62 | u32 head, count = WAIT_COUNT, tail; |
62 | u8 __iomem *mmio = par->mmio_start_virtual; | 63 | u8 __iomem *mmio = par->mmio_start_virtual; |
63 | 64 | ||
@@ -88,7 +89,7 @@ static inline int wait_for_space(struct fb_info *info, u32 space) | |||
88 | */ | 89 | */ |
89 | static inline int wait_for_engine_idle(struct fb_info *info) | 90 | static inline int wait_for_engine_idle(struct fb_info *info) |
90 | { | 91 | { |
91 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 92 | struct i810fb_par *par = info->par; |
92 | u8 __iomem *mmio = par->mmio_start_virtual; | 93 | u8 __iomem *mmio = par->mmio_start_virtual; |
93 | int count = WAIT_COUNT; | 94 | int count = WAIT_COUNT; |
94 | 95 | ||
@@ -116,7 +117,7 @@ static inline int wait_for_engine_idle(struct fb_info *info) | |||
116 | */ | 117 | */ |
117 | static inline u32 begin_iring(struct fb_info *info, u32 space) | 118 | static inline u32 begin_iring(struct fb_info *info, u32 space) |
118 | { | 119 | { |
119 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 120 | struct i810fb_par *par = info->par; |
120 | 121 | ||
121 | if (par->dev_flags & ALWAYS_SYNC) | 122 | if (par->dev_flags & ALWAYS_SYNC) |
122 | wait_for_engine_idle(info); | 123 | wait_for_engine_idle(info); |
@@ -161,7 +162,7 @@ static inline void source_copy_blit(int dwidth, int dheight, int dpitch, | |||
161 | int xdir, int src, int dest, int rop, | 162 | int xdir, int src, int dest, int rop, |
162 | int blit_bpp, struct fb_info *info) | 163 | int blit_bpp, struct fb_info *info) |
163 | { | 164 | { |
164 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 165 | struct i810fb_par *par = info->par; |
165 | 166 | ||
166 | if (begin_iring(info, 24 + IRING_PAD)) return; | 167 | if (begin_iring(info, 24 + IRING_PAD)) return; |
167 | 168 | ||
@@ -195,7 +196,7 @@ static inline void color_blit(int width, int height, int pitch, int dest, | |||
195 | int rop, int what, int blit_bpp, | 196 | int rop, int what, int blit_bpp, |
196 | struct fb_info *info) | 197 | struct fb_info *info) |
197 | { | 198 | { |
198 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 199 | struct i810fb_par *par = info->par; |
199 | 200 | ||
200 | if (begin_iring(info, 24 + IRING_PAD)) return; | 201 | if (begin_iring(info, 24 + IRING_PAD)) return; |
201 | 202 | ||
@@ -236,7 +237,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch, | |||
236 | int dest, const u32 *src, int bg, | 237 | int dest, const u32 *src, int bg, |
237 | int fg, struct fb_info *info) | 238 | int fg, struct fb_info *info) |
238 | { | 239 | { |
239 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 240 | struct i810fb_par *par = info->par; |
240 | 241 | ||
241 | if (begin_iring(info, 24 + (dsize << 2) + IRING_PAD)) return; | 242 | if (begin_iring(info, 24 + (dsize << 2) + IRING_PAD)) return; |
242 | 243 | ||
@@ -254,7 +255,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch, | |||
254 | 255 | ||
255 | static inline void load_front(int offset, struct fb_info *info) | 256 | static inline void load_front(int offset, struct fb_info *info) |
256 | { | 257 | { |
257 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 258 | struct i810fb_par *par = info->par; |
258 | 259 | ||
259 | if (begin_iring(info, 8 + IRING_PAD)) return; | 260 | if (begin_iring(info, 8 + IRING_PAD)) return; |
260 | 261 | ||
@@ -296,7 +297,7 @@ static inline void i810fb_iring_enable(struct i810fb_par *par, u32 mode) | |||
296 | 297 | ||
297 | void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 298 | void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
298 | { | 299 | { |
299 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 300 | struct i810fb_par *par = info->par; |
300 | u32 dx, dy, width, height, dest, rop = 0, color = 0; | 301 | u32 dx, dy, width, height, dest, rop = 0, color = 0; |
301 | 302 | ||
302 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 303 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
@@ -322,7 +323,7 @@ void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
322 | 323 | ||
323 | void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 324 | void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
324 | { | 325 | { |
325 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 326 | struct i810fb_par *par = info->par; |
326 | u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; | 327 | u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; |
327 | 328 | ||
328 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 329 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
@@ -361,7 +362,7 @@ void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
361 | 362 | ||
362 | void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) | 363 | void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) |
363 | { | 364 | { |
364 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 365 | struct i810fb_par *par = info->par; |
365 | u32 fg = 0, bg = 0, size, dst; | 366 | u32 fg = 0, bg = 0, size, dst; |
366 | 367 | ||
367 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 368 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
@@ -397,7 +398,7 @@ void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
397 | 398 | ||
398 | int i810fb_sync(struct fb_info *info) | 399 | int i810fb_sync(struct fb_info *info) |
399 | { | 400 | { |
400 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 401 | struct i810fb_par *par = info->par; |
401 | 402 | ||
402 | if (!info->var.accel_flags || par->dev_flags & LOCKUP) | 403 | if (!info->var.accel_flags || par->dev_flags & LOCKUP) |
403 | return 0; | 404 | return 0; |
@@ -407,7 +408,7 @@ int i810fb_sync(struct fb_info *info) | |||
407 | 408 | ||
408 | void i810fb_load_front(u32 offset, struct fb_info *info) | 409 | void i810fb_load_front(u32 offset, struct fb_info *info) |
409 | { | 410 | { |
410 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 411 | struct i810fb_par *par = info->par; |
411 | u8 __iomem *mmio = par->mmio_start_virtual; | 412 | u8 __iomem *mmio = par->mmio_start_virtual; |
412 | 413 | ||
413 | if (!info->var.accel_flags || par->dev_flags & LOCKUP) | 414 | if (!info->var.accel_flags || par->dev_flags & LOCKUP) |
@@ -427,7 +428,7 @@ void i810fb_load_front(u32 offset, struct fb_info *info) | |||
427 | */ | 428 | */ |
428 | void i810fb_init_ringbuffer(struct fb_info *info) | 429 | void i810fb_init_ringbuffer(struct fb_info *info) |
429 | { | 430 | { |
430 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 431 | struct i810fb_par *par = info->par; |
431 | u32 tmp1, tmp2; | 432 | u32 tmp1, tmp2; |
432 | u8 __iomem *mmio = par->mmio_start_virtual; | 433 | u8 __iomem *mmio = par->mmio_start_virtual; |
433 | 434 | ||
diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/i810/i810_gtf.c index 64f087a4466b..9743d51e7f8c 100644 --- a/drivers/video/i810/i810_gtf.c +++ b/drivers/video/i810/i810_gtf.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "i810_regs.h" | 15 | #include "i810_regs.h" |
16 | #include "i810.h" | 16 | #include "i810.h" |
17 | #include "i810_main.h" | ||
17 | 18 | ||
18 | /* | 19 | /* |
19 | * FIFO and Watermark tables - based almost wholly on i810_wmark.c in | 20 | * FIFO and Watermark tables - based almost wholly on i810_wmark.c in |
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index c0c974b1afaa..266d0ab92663 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -42,20 +42,62 @@ | |||
42 | #include <linux/pci_ids.h> | 42 | #include <linux/pci_ids.h> |
43 | #include <linux/resource.h> | 43 | #include <linux/resource.h> |
44 | #include <linux/unistd.h> | 44 | #include <linux/unistd.h> |
45 | #include <linux/console.h> | ||
45 | 46 | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/div64.h> | 48 | #include <asm/div64.h> |
48 | |||
49 | #ifdef CONFIG_MTRR | ||
50 | #include <asm/mtrr.h> | ||
51 | #endif | ||
52 | |||
53 | #include <asm/page.h> | 49 | #include <asm/page.h> |
54 | 50 | ||
55 | #include "i810_regs.h" | 51 | #include "i810_regs.h" |
56 | #include "i810.h" | 52 | #include "i810.h" |
57 | #include "i810_main.h" | 53 | #include "i810_main.h" |
58 | 54 | ||
55 | /* | ||
56 | * voffset - framebuffer offset in MiB from aperture start address. In order for | ||
57 | * the driver to work with X, we must try to use memory holes left untouched by X. The | ||
58 | * following table lists where X's different surfaces start at. | ||
59 | * | ||
60 | * --------------------------------------------- | ||
61 | * : : 64 MiB : 32 MiB : | ||
62 | * ---------------------------------------------- | ||
63 | * : FrontBuffer : 0 : 0 : | ||
64 | * : DepthBuffer : 48 : 16 : | ||
65 | * : BackBuffer : 56 : 24 : | ||
66 | * ---------------------------------------------- | ||
67 | * | ||
68 | * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to | ||
69 | * 15 + 1 MiB of Framebuffer memory. For 32 MiB Aperture sizes, a v_offset of 8 MiB should | ||
70 | * work, allowing 7 + 1 MiB of Framebuffer memory. | ||
71 | * Note, the size of the hole may change depending on how much memory you allocate to X, | ||
72 | * and how the memory is split up between these surfaces. | ||
73 | * | ||
74 | * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with | ||
75 | * DRI disabled. But if the Frontbuffer is overlapped, X will fail to load. | ||
76 | * | ||
77 | * Experiment with v_offset to find out which works best for you. | ||
78 | */ | ||
79 | static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ | ||
80 | static u32 voffset __initdata = 0; | ||
81 | |||
82 | static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); | ||
83 | static int __devinit i810fb_init_pci (struct pci_dev *dev, | ||
84 | const struct pci_device_id *entry); | ||
85 | static void __exit i810fb_remove_pci(struct pci_dev *dev); | ||
86 | static int i810fb_resume(struct pci_dev *dev); | ||
87 | static int i810fb_suspend(struct pci_dev *dev, pm_message_t state); | ||
88 | |||
89 | /* Chipset Specific Functions */ | ||
90 | static int i810fb_set_par (struct fb_info *info); | ||
91 | static int i810fb_getcolreg (u8 regno, u8 *red, u8 *green, u8 *blue, | ||
92 | u8 *transp, struct fb_info *info); | ||
93 | static int i810fb_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, | ||
94 | unsigned transp, struct fb_info *info); | ||
95 | static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | ||
96 | static int i810fb_blank (int blank_mode, struct fb_info *info); | ||
97 | |||
98 | /* Initialization */ | ||
99 | static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); | ||
100 | |||
59 | /* PCI */ | 101 | /* PCI */ |
60 | static const char *i810_pci_list[] __devinitdata = { | 102 | static const char *i810_pci_list[] __devinitdata = { |
61 | "Intel(R) 810 Framebuffer Device" , | 103 | "Intel(R) 810 Framebuffer Device" , |
@@ -776,7 +818,7 @@ static void i810_load_cursor_image(int width, int height, u8 *data, | |||
776 | 818 | ||
777 | static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info) | 819 | static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info) |
778 | { | 820 | { |
779 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 821 | struct i810fb_par *par = info->par; |
780 | u8 __iomem *mmio = par->mmio_start_virtual; | 822 | u8 __iomem *mmio = par->mmio_start_virtual; |
781 | u8 red, green, blue, trans, temp; | 823 | u8 red, green, blue, trans, temp; |
782 | 824 | ||
@@ -949,7 +991,7 @@ static void set_color_bitfields(struct fb_var_screeninfo *var) | |||
949 | static int i810_check_params(struct fb_var_screeninfo *var, | 991 | static int i810_check_params(struct fb_var_screeninfo *var, |
950 | struct fb_info *info) | 992 | struct fb_info *info) |
951 | { | 993 | { |
952 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 994 | struct i810fb_par *par = info->par; |
953 | int line_length, vidmem, mode_valid = 0, retval = 0; | 995 | int line_length, vidmem, mode_valid = 0, retval = 0; |
954 | u32 vyres = var->yres_virtual, vxres = var->xres_virtual; | 996 | u32 vyres = var->yres_virtual, vxres = var->xres_virtual; |
955 | /* | 997 | /* |
@@ -1043,7 +1085,7 @@ static int i810_check_params(struct fb_var_screeninfo *var, | |||
1043 | */ | 1085 | */ |
1044 | static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | 1086 | static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) |
1045 | { | 1087 | { |
1046 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1088 | struct i810fb_par *par = info->par; |
1047 | 1089 | ||
1048 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); | 1090 | memset(fix, 0, sizeof(struct fb_fix_screeninfo)); |
1049 | 1091 | ||
@@ -1154,7 +1196,7 @@ static void decode_var(const struct fb_var_screeninfo *var, | |||
1154 | static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, | 1196 | static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, |
1155 | u8 *transp, struct fb_info *info) | 1197 | u8 *transp, struct fb_info *info) |
1156 | { | 1198 | { |
1157 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1199 | struct i810fb_par *par = info->par; |
1158 | u8 __iomem *mmio = par->mmio_start_virtual; | 1200 | u8 __iomem *mmio = par->mmio_start_virtual; |
1159 | u8 temp; | 1201 | u8 temp; |
1160 | 1202 | ||
@@ -1193,7 +1235,7 @@ static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, | |||
1193 | 1235 | ||
1194 | static int i810fb_open(struct fb_info *info, int user) | 1236 | static int i810fb_open(struct fb_info *info, int user) |
1195 | { | 1237 | { |
1196 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1238 | struct i810fb_par *par = info->par; |
1197 | u32 count = atomic_read(&par->use_count); | 1239 | u32 count = atomic_read(&par->use_count); |
1198 | 1240 | ||
1199 | if (count == 0) { | 1241 | if (count == 0) { |
@@ -1212,7 +1254,7 @@ static int i810fb_open(struct fb_info *info, int user) | |||
1212 | 1254 | ||
1213 | static int i810fb_release(struct fb_info *info, int user) | 1255 | static int i810fb_release(struct fb_info *info, int user) |
1214 | { | 1256 | { |
1215 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1257 | struct i810fb_par *par = info->par; |
1216 | u32 count; | 1258 | u32 count; |
1217 | 1259 | ||
1218 | count = atomic_read(&par->use_count); | 1260 | count = atomic_read(&par->use_count); |
@@ -1234,7 +1276,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1234 | unsigned blue, unsigned transp, | 1276 | unsigned blue, unsigned transp, |
1235 | struct fb_info *info) | 1277 | struct fb_info *info) |
1236 | { | 1278 | { |
1237 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1279 | struct i810fb_par *par = info->par; |
1238 | u8 __iomem *mmio = par->mmio_start_virtual; | 1280 | u8 __iomem *mmio = par->mmio_start_virtual; |
1239 | u8 temp; | 1281 | u8 temp; |
1240 | int i; | 1282 | int i; |
@@ -1328,7 +1370,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1328 | static int i810fb_pan_display(struct fb_var_screeninfo *var, | 1370 | static int i810fb_pan_display(struct fb_var_screeninfo *var, |
1329 | struct fb_info *info) | 1371 | struct fb_info *info) |
1330 | { | 1372 | { |
1331 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1373 | struct i810fb_par *par = info->par; |
1332 | u32 total; | 1374 | u32 total; |
1333 | 1375 | ||
1334 | total = var->xoffset * par->depth + | 1376 | total = var->xoffset * par->depth + |
@@ -1340,7 +1382,7 @@ static int i810fb_pan_display(struct fb_var_screeninfo *var, | |||
1340 | 1382 | ||
1341 | static int i810fb_blank (int blank_mode, struct fb_info *info) | 1383 | static int i810fb_blank (int blank_mode, struct fb_info *info) |
1342 | { | 1384 | { |
1343 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1385 | struct i810fb_par *par = info->par; |
1344 | u8 __iomem *mmio = par->mmio_start_virtual; | 1386 | u8 __iomem *mmio = par->mmio_start_virtual; |
1345 | int mode = 0, pwr, scr_off = 0; | 1387 | int mode = 0, pwr, scr_off = 0; |
1346 | 1388 | ||
@@ -1385,7 +1427,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info) | |||
1385 | 1427 | ||
1386 | static int i810fb_set_par(struct fb_info *info) | 1428 | static int i810fb_set_par(struct fb_info *info) |
1387 | { | 1429 | { |
1388 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1430 | struct i810fb_par *par = info->par; |
1389 | 1431 | ||
1390 | decode_var(&info->var, par); | 1432 | decode_var(&info->var, par); |
1391 | i810_load_regs(par); | 1433 | i810_load_regs(par); |
@@ -1429,7 +1471,7 @@ static int i810fb_check_var(struct fb_var_screeninfo *var, | |||
1429 | 1471 | ||
1430 | static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1472 | static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1431 | { | 1473 | { |
1432 | struct i810fb_par *par = (struct i810fb_par *)info->par; | 1474 | struct i810fb_par *par = info->par; |
1433 | u8 __iomem *mmio = par->mmio_start_virtual; | 1475 | u8 __iomem *mmio = par->mmio_start_virtual; |
1434 | 1476 | ||
1435 | if (!par->dev_flags & LOCKUP) | 1477 | if (!par->dev_flags & LOCKUP) |
@@ -1516,36 +1558,29 @@ static struct fb_ops i810fb_ops __devinitdata = { | |||
1516 | static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) | 1558 | static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) |
1517 | { | 1559 | { |
1518 | struct fb_info *info = pci_get_drvdata(dev); | 1560 | struct fb_info *info = pci_get_drvdata(dev); |
1519 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1561 | struct i810fb_par *par = info->par; |
1520 | int blank = 0, prev_state = par->cur_state; | ||
1521 | |||
1522 | if (state.event == prev_state) | ||
1523 | return 0; | ||
1524 | 1562 | ||
1525 | par->cur_state = state.event; | 1563 | par->cur_state = state.event; |
1526 | 1564 | ||
1527 | switch (state.event) { | 1565 | if (state.event == PM_EVENT_FREEZE) { |
1528 | case 1: | 1566 | dev->dev.power.power_state = state; |
1529 | blank = VESA_VSYNC_SUSPEND; | 1567 | return 0; |
1530 | break; | ||
1531 | case 2: | ||
1532 | blank = VESA_HSYNC_SUSPEND; | ||
1533 | break; | ||
1534 | case 3: | ||
1535 | blank = VESA_POWERDOWN; | ||
1536 | break; | ||
1537 | default: | ||
1538 | return -EINVAL; | ||
1539 | } | 1568 | } |
1540 | info->fbops->fb_blank(blank, info); | ||
1541 | 1569 | ||
1542 | if (!prev_state) { | 1570 | acquire_console_sem(); |
1543 | agp_unbind_memory(par->i810_gtt.i810_fb_memory); | 1571 | fb_set_suspend(info, 1); |
1544 | agp_unbind_memory(par->i810_gtt.i810_cursor_memory); | 1572 | |
1545 | pci_disable_device(dev); | 1573 | if (info->fbops->fb_sync) |
1546 | } | 1574 | info->fbops->fb_sync(info); |
1575 | |||
1576 | i810fb_blank(FB_BLANK_POWERDOWN, info); | ||
1577 | agp_unbind_memory(par->i810_gtt.i810_fb_memory); | ||
1578 | agp_unbind_memory(par->i810_gtt.i810_cursor_memory); | ||
1579 | |||
1547 | pci_save_state(dev); | 1580 | pci_save_state(dev); |
1581 | pci_disable_device(dev); | ||
1548 | pci_set_power_state(dev, pci_choose_state(dev, state)); | 1582 | pci_set_power_state(dev, pci_choose_state(dev, state)); |
1583 | release_console_sem(); | ||
1549 | 1584 | ||
1550 | return 0; | 1585 | return 0; |
1551 | } | 1586 | } |
@@ -1553,23 +1588,29 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) | |||
1553 | static int i810fb_resume(struct pci_dev *dev) | 1588 | static int i810fb_resume(struct pci_dev *dev) |
1554 | { | 1589 | { |
1555 | struct fb_info *info = pci_get_drvdata(dev); | 1590 | struct fb_info *info = pci_get_drvdata(dev); |
1556 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1591 | struct i810fb_par *par = info->par; |
1592 | int cur_state = par->cur_state; | ||
1593 | |||
1594 | par->cur_state = PM_EVENT_ON; | ||
1557 | 1595 | ||
1558 | if (par->cur_state == 0) | 1596 | if (cur_state == PM_EVENT_FREEZE) { |
1597 | pci_set_power_state(dev, PCI_D0); | ||
1559 | return 0; | 1598 | return 0; |
1599 | } | ||
1560 | 1600 | ||
1561 | pci_restore_state(dev); | 1601 | acquire_console_sem(); |
1562 | pci_set_power_state(dev, PCI_D0); | 1602 | pci_set_power_state(dev, PCI_D0); |
1603 | pci_restore_state(dev); | ||
1563 | pci_enable_device(dev); | 1604 | pci_enable_device(dev); |
1605 | pci_set_master(dev); | ||
1564 | agp_bind_memory(par->i810_gtt.i810_fb_memory, | 1606 | agp_bind_memory(par->i810_gtt.i810_fb_memory, |
1565 | par->fb.offset); | 1607 | par->fb.offset); |
1566 | agp_bind_memory(par->i810_gtt.i810_cursor_memory, | 1608 | agp_bind_memory(par->i810_gtt.i810_cursor_memory, |
1567 | par->cursor_heap.offset); | 1609 | par->cursor_heap.offset); |
1568 | 1610 | i810fb_set_par(info); | |
1611 | fb_set_suspend (info, 0); | ||
1569 | info->fbops->fb_blank(VESA_NO_BLANKING, info); | 1612 | info->fbops->fb_blank(VESA_NO_BLANKING, info); |
1570 | 1613 | release_console_sem(); | |
1571 | par->cur_state = 0; | ||
1572 | |||
1573 | return 0; | 1614 | return 0; |
1574 | } | 1615 | } |
1575 | /*********************************************************************** | 1616 | /*********************************************************************** |
@@ -1610,7 +1651,7 @@ static void __devinit i810_fix_offsets(struct i810fb_par *par) | |||
1610 | 1651 | ||
1611 | static int __devinit i810_alloc_agp_mem(struct fb_info *info) | 1652 | static int __devinit i810_alloc_agp_mem(struct fb_info *info) |
1612 | { | 1653 | { |
1613 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 1654 | struct i810fb_par *par = info->par; |
1614 | int size; | 1655 | int size; |
1615 | struct agp_bridge_data *bridge; | 1656 | struct agp_bridge_data *bridge; |
1616 | 1657 | ||
@@ -2074,7 +2115,7 @@ static void i810fb_release_resource(struct fb_info *info, | |||
2074 | static void __exit i810fb_remove_pci(struct pci_dev *dev) | 2115 | static void __exit i810fb_remove_pci(struct pci_dev *dev) |
2075 | { | 2116 | { |
2076 | struct fb_info *info = pci_get_drvdata(dev); | 2117 | struct fb_info *info = pci_get_drvdata(dev); |
2077 | struct i810fb_par *par = (struct i810fb_par *) info->par; | 2118 | struct i810fb_par *par = info->par; |
2078 | 2119 | ||
2079 | unregister_framebuffer(info); | 2120 | unregister_framebuffer(info); |
2080 | i810fb_release_resource(info, par); | 2121 | i810fb_release_resource(info, par); |
diff --git a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h index 06072a6466f2..51d4f3d4116d 100644 --- a/drivers/video/i810/i810_main.h +++ b/drivers/video/i810/i810_main.h | |||
@@ -14,55 +14,6 @@ | |||
14 | #ifndef __I810_MAIN_H__ | 14 | #ifndef __I810_MAIN_H__ |
15 | #define __I810_MAIN_H__ | 15 | #define __I810_MAIN_H__ |
16 | 16 | ||
17 | static int __devinit i810fb_init_pci (struct pci_dev *dev, | ||
18 | const struct pci_device_id *entry); | ||
19 | static void __exit i810fb_remove_pci(struct pci_dev *dev); | ||
20 | static int i810fb_resume(struct pci_dev *dev); | ||
21 | static int i810fb_suspend(struct pci_dev *dev, pm_message_t state); | ||
22 | |||
23 | /* | ||
24 | * voffset - framebuffer offset in MiB from aperture start address. In order for | ||
25 | * the driver to work with X, we must try to use memory holes left untouched by X. The | ||
26 | * following table lists where X's different surfaces start at. | ||
27 | * | ||
28 | * --------------------------------------------- | ||
29 | * : : 64 MiB : 32 MiB : | ||
30 | * ---------------------------------------------- | ||
31 | * : FrontBuffer : 0 : 0 : | ||
32 | * : DepthBuffer : 48 : 16 : | ||
33 | * : BackBuffer : 56 : 24 : | ||
34 | * ---------------------------------------------- | ||
35 | * | ||
36 | * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to | ||
37 | * 15 + 1 MiB of Framebuffer memory. For 32 MiB Aperture sizes, a v_offset of 8 MiB should | ||
38 | * work, allowing 7 + 1 MiB of Framebuffer memory. | ||
39 | * Note, the size of the hole may change depending on how much memory you allocate to X, | ||
40 | * and how the memory is split up between these surfaces. | ||
41 | * | ||
42 | * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with | ||
43 | * DRI disabled. But if the Frontbuffer is overlapped, X will fail to load. | ||
44 | * | ||
45 | * Experiment with v_offset to find out which works best for you. | ||
46 | */ | ||
47 | static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ | ||
48 | static u32 voffset __initdata = 0; | ||
49 | |||
50 | static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); | ||
51 | |||
52 | /* Chipset Specific Functions */ | ||
53 | static int i810fb_set_par (struct fb_info *info); | ||
54 | static int i810fb_getcolreg (u8 regno, u8 *red, u8 *green, u8 *blue, | ||
55 | u8 *transp, struct fb_info *info); | ||
56 | static int i810fb_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, | ||
57 | unsigned transp, struct fb_info *info); | ||
58 | static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | ||
59 | static int i810fb_blank (int blank_mode, struct fb_info *info); | ||
60 | |||
61 | /* Initialization */ | ||
62 | static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); | ||
63 | extern int __init agp_intel_init(void); | ||
64 | |||
65 | |||
66 | /* Video Timings */ | 17 | /* Video Timings */ |
67 | extern void round_off_xres (u32 *xres); | 18 | extern void round_off_xres (u32 *xres); |
68 | extern void round_off_yres (u32 *xres, u32 *yres); | 19 | extern void round_off_yres (u32 *xres, u32 *yres); |
@@ -101,7 +52,7 @@ static inline void i810_delete_i2c_busses(struct i810fb_par *par) { } | |||
101 | 52 | ||
102 | /* Conditionals */ | 53 | /* Conditionals */ |
103 | #ifdef CONFIG_X86 | 54 | #ifdef CONFIG_X86 |
104 | inline void flush_cache(void) | 55 | static inline void flush_cache(void) |
105 | { | 56 | { |
106 | asm volatile ("wbinvd":::"memory"); | 57 | asm volatile ("wbinvd":::"memory"); |
107 | } | 58 | } |
@@ -110,7 +61,9 @@ inline void flush_cache(void) | |||
110 | #endif | 61 | #endif |
111 | 62 | ||
112 | #ifdef CONFIG_MTRR | 63 | #ifdef CONFIG_MTRR |
113 | #define KERNEL_HAS_MTRR 1 | 64 | |
65 | #include <asm/mtrr.h> | ||
66 | |||
114 | static inline void __devinit set_mtrr(struct i810fb_par *par) | 67 | static inline void __devinit set_mtrr(struct i810fb_par *par) |
115 | { | 68 | { |
116 | par->mtrr_reg = mtrr_add((u32) par->aperture.physical, | 69 | par->mtrr_reg = mtrr_add((u32) par->aperture.physical, |
@@ -128,7 +81,6 @@ static inline void unset_mtrr(struct i810fb_par *par) | |||
128 | par->aperture.size); | 81 | par->aperture.size); |
129 | } | 82 | } |
130 | #else | 83 | #else |
131 | #define KERNEL_HAS_MTRR 0 | ||
132 | #define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n") | 84 | #define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n") |
133 | 85 | ||
134 | #define unset_mtrr(x) do { } while (0) | 86 | #define unset_mtrr(x) do { } while (0) |
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 7fbe24206b19..a5d813050db5 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c | |||
@@ -323,6 +323,7 @@ struct imstt_par { | |||
323 | unsigned long cmap_regs_phys; | 323 | unsigned long cmap_regs_phys; |
324 | __u8 *cmap_regs; | 324 | __u8 *cmap_regs; |
325 | __u32 ramdac; | 325 | __u32 ramdac; |
326 | __u32 palette[16]; | ||
326 | }; | 327 | }; |
327 | 328 | ||
328 | enum { | 329 | enum { |
@@ -657,7 +658,7 @@ set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp) | |||
657 | static void | 658 | static void |
658 | set_imstt_regvals (struct fb_info *info, u_int bpp) | 659 | set_imstt_regvals (struct fb_info *info, u_int bpp) |
659 | { | 660 | { |
660 | struct imstt_par *par = (struct imstt_par *) info->par; | 661 | struct imstt_par *par = info->par; |
661 | struct imstt_regvals *init = &par->init; | 662 | struct imstt_regvals *init = &par->init; |
662 | __u32 ctl, pitch, byteswap, scr; | 663 | __u32 ctl, pitch, byteswap, scr; |
663 | 664 | ||
@@ -749,7 +750,7 @@ set_imstt_regvals (struct fb_info *info, u_int bpp) | |||
749 | static inline void | 750 | static inline void |
750 | set_offset (struct fb_var_screeninfo *var, struct fb_info *info) | 751 | set_offset (struct fb_var_screeninfo *var, struct fb_info *info) |
751 | { | 752 | { |
752 | struct imstt_par *par = (struct imstt_par *) info->par; | 753 | struct imstt_par *par = info->par; |
753 | __u32 off = var->yoffset * (info->fix.line_length >> 3) | 754 | __u32 off = var->yoffset * (info->fix.line_length >> 3) |
754 | + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3); | 755 | + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3); |
755 | write_reg_le32(par->dc_regs, SSR, off); | 756 | write_reg_le32(par->dc_regs, SSR, off); |
@@ -863,7 +864,7 @@ imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
863 | static int | 864 | static int |
864 | imsttfb_set_par(struct fb_info *info) | 865 | imsttfb_set_par(struct fb_info *info) |
865 | { | 866 | { |
866 | struct imstt_par *par = (struct imstt_par *) info->par; | 867 | struct imstt_par *par = info->par; |
867 | 868 | ||
868 | if (!compute_imstt_regvals(par, info->var.xres, info->var.yres)) | 869 | if (!compute_imstt_regvals(par, info->var.xres, info->var.yres)) |
869 | return -EINVAL; | 870 | return -EINVAL; |
@@ -881,7 +882,7 @@ static int | |||
881 | imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, | 882 | imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, |
882 | u_int transp, struct fb_info *info) | 883 | u_int transp, struct fb_info *info) |
883 | { | 884 | { |
884 | struct imstt_par *par = (struct imstt_par *) info->par; | 885 | struct imstt_par *par = info->par; |
885 | u_int bpp = info->var.bits_per_pixel; | 886 | u_int bpp = info->var.bits_per_pixel; |
886 | 887 | ||
887 | if (regno > 255) | 888 | if (regno > 255) |
@@ -905,14 +906,17 @@ imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, | |||
905 | if (regno < 16) | 906 | if (regno < 16) |
906 | switch (bpp) { | 907 | switch (bpp) { |
907 | case 16: | 908 | case 16: |
908 | ((u16 *)info->pseudo_palette)[regno] = (regno << (info->var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno; | 909 | par->palette[regno] = |
910 | (regno << (info->var.green.length == | ||
911 | 5 ? 10 : 11)) | (regno << 5) | regno; | ||
909 | break; | 912 | break; |
910 | case 24: | 913 | case 24: |
911 | ((u32 *)info->pseudo_palette)[regno] = (regno << 16) | (regno << 8) | regno; | 914 | par->palette[regno] = |
915 | (regno << 16) | (regno << 8) | regno; | ||
912 | break; | 916 | break; |
913 | case 32: { | 917 | case 32: { |
914 | int i = (regno << 8) | regno; | 918 | int i = (regno << 8) | regno; |
915 | ((u32 *)info->pseudo_palette)[regno] = (i << 16) | i; | 919 | par->palette[regno] = (i << 16) |i; |
916 | break; | 920 | break; |
917 | } | 921 | } |
918 | } | 922 | } |
@@ -935,7 +939,7 @@ imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
935 | static int | 939 | static int |
936 | imsttfb_blank(int blank, struct fb_info *info) | 940 | imsttfb_blank(int blank, struct fb_info *info) |
937 | { | 941 | { |
938 | struct imstt_par *par = (struct imstt_par *) info->par; | 942 | struct imstt_par *par = info->par; |
939 | __u32 ctrl; | 943 | __u32 ctrl; |
940 | 944 | ||
941 | ctrl = read_reg_le32(par->dc_regs, STGCTL); | 945 | ctrl = read_reg_le32(par->dc_regs, STGCTL); |
@@ -989,7 +993,7 @@ imsttfb_blank(int blank, struct fb_info *info) | |||
989 | static void | 993 | static void |
990 | imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 994 | imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
991 | { | 995 | { |
992 | struct imstt_par *par = (struct imstt_par *) info->par; | 996 | struct imstt_par *par = info->par; |
993 | __u32 Bpp, line_pitch, bgc, dx, dy, width, height; | 997 | __u32 Bpp, line_pitch, bgc, dx, dy, width, height; |
994 | 998 | ||
995 | bgc = rect->color; | 999 | bgc = rect->color; |
@@ -1033,7 +1037,7 @@ imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
1033 | static void | 1037 | static void |
1034 | imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | 1038 | imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) |
1035 | { | 1039 | { |
1036 | struct imstt_par *par = (struct imstt_par *) info->par; | 1040 | struct imstt_par *par = info->par; |
1037 | __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl; | 1041 | __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl; |
1038 | __u32 cnt, bltctl, sx, sy, dx, dy, height, width; | 1042 | __u32 cnt, bltctl, sx, sy, dx, dy, height, width; |
1039 | 1043 | ||
@@ -1195,7 +1199,7 @@ imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on) | |||
1195 | static int | 1199 | static int |
1196 | imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1200 | imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1197 | { | 1201 | { |
1198 | struct imstt_par *par = (struct imstt_par *) info->par; | 1202 | struct imstt_par *par = info->par; |
1199 | u32 flags = cursor->set, fg, bg, xx, yy; | 1203 | u32 flags = cursor->set, fg, bg, xx, yy; |
1200 | 1204 | ||
1201 | if (cursor->dest == NULL && cursor->rop == ROP_XOR) | 1205 | if (cursor->dest == NULL && cursor->rop == ROP_XOR) |
@@ -1266,7 +1270,7 @@ static int | |||
1266 | imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd, | 1270 | imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd, |
1267 | u_long arg, struct fb_info *info) | 1271 | u_long arg, struct fb_info *info) |
1268 | { | 1272 | { |
1269 | struct imstt_par *par = (struct imstt_par *) info->par; | 1273 | struct imstt_par *par = info->par; |
1270 | void __user *argp = (void __user *)arg; | 1274 | void __user *argp = (void __user *)arg; |
1271 | __u32 reg[2]; | 1275 | __u32 reg[2]; |
1272 | __u8 idx[2]; | 1276 | __u8 idx[2]; |
@@ -1350,7 +1354,7 @@ static struct fb_ops imsttfb_ops = { | |||
1350 | static void __devinit | 1354 | static void __devinit |
1351 | init_imstt(struct fb_info *info) | 1355 | init_imstt(struct fb_info *info) |
1352 | { | 1356 | { |
1353 | struct imstt_par *par = (struct imstt_par *) info->par; | 1357 | struct imstt_par *par = info->par; |
1354 | __u32 i, tmp, *ip, *end; | 1358 | __u32 i, tmp, *ip, *end; |
1355 | 1359 | ||
1356 | tmp = read_reg_le32(par->dc_regs, PRC); | 1360 | tmp = read_reg_le32(par->dc_regs, PRC); |
@@ -1413,7 +1417,7 @@ init_imstt(struct fb_info *info) | |||
1413 | if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len | 1417 | if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len |
1414 | || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { | 1418 | || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { |
1415 | printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); | 1419 | printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); |
1416 | kfree(info); | 1420 | framebuffer_release(info); |
1417 | return; | 1421 | return; |
1418 | } | 1422 | } |
1419 | 1423 | ||
@@ -1449,7 +1453,7 @@ init_imstt(struct fb_info *info) | |||
1449 | fb_alloc_cmap(&info->cmap, 0, 0); | 1453 | fb_alloc_cmap(&info->cmap, 0, 0); |
1450 | 1454 | ||
1451 | if (register_framebuffer(info) < 0) { | 1455 | if (register_framebuffer(info) < 0) { |
1452 | kfree(info); | 1456 | framebuffer_release(info); |
1453 | return; | 1457 | return; |
1454 | } | 1458 | } |
1455 | 1459 | ||
@@ -1474,26 +1478,21 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1474 | printk(KERN_ERR "imsttfb: no OF node for pci device\n"); | 1478 | printk(KERN_ERR "imsttfb: no OF node for pci device\n"); |
1475 | #endif /* CONFIG_PPC_OF */ | 1479 | #endif /* CONFIG_PPC_OF */ |
1476 | 1480 | ||
1477 | size = sizeof(struct fb_info) + sizeof(struct imstt_par) + | 1481 | info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev); |
1478 | sizeof(u32) * 16; | ||
1479 | |||
1480 | info = kmalloc(size, GFP_KERNEL); | ||
1481 | 1482 | ||
1482 | if (!info) { | 1483 | if (!info) { |
1483 | printk(KERN_ERR "imsttfb: Can't allocate memory\n"); | 1484 | printk(KERN_ERR "imsttfb: Can't allocate memory\n"); |
1484 | return -ENOMEM; | 1485 | return -ENOMEM; |
1485 | } | 1486 | } |
1486 | 1487 | ||
1487 | memset(info, 0, size); | 1488 | par = info->par; |
1488 | |||
1489 | par = (struct imstt_par *) (info + 1); | ||
1490 | 1489 | ||
1491 | addr = pci_resource_start (pdev, 0); | 1490 | addr = pci_resource_start (pdev, 0); |
1492 | size = pci_resource_len (pdev, 0); | 1491 | size = pci_resource_len (pdev, 0); |
1493 | 1492 | ||
1494 | if (!request_mem_region(addr, size, "imsttfb")) { | 1493 | if (!request_mem_region(addr, size, "imsttfb")) { |
1495 | printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); | 1494 | printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); |
1496 | kfree(info); | 1495 | framebuffer_release(info); |
1497 | return -ENODEV; | 1496 | return -ENODEV; |
1498 | } | 1497 | } |
1499 | 1498 | ||
@@ -1516,14 +1515,13 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1516 | } | 1515 | } |
1517 | 1516 | ||
1518 | info->fix.smem_start = addr; | 1517 | info->fix.smem_start = addr; |
1519 | info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000); | 1518 | info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? |
1519 | 0x400000 : 0x800000); | ||
1520 | info->fix.mmio_start = addr + 0x800000; | 1520 | info->fix.mmio_start = addr + 0x800000; |
1521 | par->dc_regs = ioremap(addr + 0x800000, 0x1000); | 1521 | par->dc_regs = ioremap(addr + 0x800000, 0x1000); |
1522 | par->cmap_regs_phys = addr + 0x840000; | 1522 | par->cmap_regs_phys = addr + 0x840000; |
1523 | par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); | 1523 | par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); |
1524 | info->par = par; | 1524 | info->pseudo_palette = par->palette; |
1525 | info->pseudo_palette = (void *) (par + 1); | ||
1526 | info->device = &pdev->dev; | ||
1527 | init_imstt(info); | 1525 | init_imstt(info); |
1528 | 1526 | ||
1529 | pci_set_drvdata(pdev, info); | 1527 | pci_set_drvdata(pdev, info); |
@@ -1534,7 +1532,7 @@ static void __devexit | |||
1534 | imsttfb_remove(struct pci_dev *pdev) | 1532 | imsttfb_remove(struct pci_dev *pdev) |
1535 | { | 1533 | { |
1536 | struct fb_info *info = pci_get_drvdata(pdev); | 1534 | struct fb_info *info = pci_get_drvdata(pdev); |
1537 | struct imstt_par *par = (struct imstt_par *) info->par; | 1535 | struct imstt_par *par = info->par; |
1538 | int size = pci_resource_len(pdev, 0); | 1536 | int size = pci_resource_len(pdev, 0); |
1539 | 1537 | ||
1540 | unregister_framebuffer(info); | 1538 | unregister_framebuffer(info); |
@@ -1542,7 +1540,7 @@ imsttfb_remove(struct pci_dev *pdev) | |||
1542 | iounmap(par->dc_regs); | 1540 | iounmap(par->dc_regs); |
1543 | iounmap(info->screen_base); | 1541 | iounmap(info->screen_base); |
1544 | release_mem_region(info->fix.smem_start, size); | 1542 | release_mem_region(info->fix.smem_start, size); |
1545 | kfree(info); | 1543 | framebuffer_release(info); |
1546 | } | 1544 | } |
1547 | 1545 | ||
1548 | #ifndef MODULE | 1546 | #ifndef MODULE |
diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/kyro/STG4000InitDevice.c index 7e33cd307d47..ab5285a7f1d6 100644 --- a/drivers/video/kyro/STG4000InitDevice.c +++ b/drivers/video/kyro/STG4000InitDevice.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | 16 | ||
17 | #include "STG4000Reg.h" | 17 | #include "STG4000Reg.h" |
18 | #include "STG4000Interface.h" | ||
18 | 19 | ||
19 | /* SDRAM fixed settings */ | 20 | /* SDRAM fixed settings */ |
20 | #define SDRAM_CFG_0 0x49A1 | 21 | #define SDRAM_CFG_0 0x49A1 |
diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/kyro/STG4000Interface.h index e75b3b4a4aa1..b7c83d5dfb13 100644 --- a/drivers/video/kyro/STG4000Interface.h +++ b/drivers/video/kyro/STG4000Interface.h | |||
@@ -11,7 +11,8 @@ | |||
11 | #ifndef _STG4000INTERFACE_H | 11 | #ifndef _STG4000INTERFACE_H |
12 | #define _STG4000INTERFACE_H | 12 | #define _STG4000INTERFACE_H |
13 | 13 | ||
14 | struct pci_dev; | 14 | #include <linux/pci.h> |
15 | #include <video/kyro.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Ramdac Setup | 18 | * Ramdac Setup |
diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/kyro/STG4000OverlayDevice.c index 2ae9bafacdd0..a8c9713413e6 100644 --- a/drivers/video/kyro/STG4000OverlayDevice.c +++ b/drivers/video/kyro/STG4000OverlayDevice.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | 15 | ||
16 | #include "STG4000Reg.h" | 16 | #include "STG4000Reg.h" |
17 | #include "STG4000Interface.h" | ||
17 | 18 | ||
18 | /* HW Defines */ | 19 | /* HW Defines */ |
19 | 20 | ||
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c index 5eb4d5c177bd..bcd359b6d4ff 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/kyro/fbdev.c | |||
@@ -73,8 +73,6 @@ static struct fb_var_screeninfo kyro_var __devinitdata = { | |||
73 | .vmode = FB_VMODE_NONINTERLACED, | 73 | .vmode = FB_VMODE_NONINTERLACED, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static struct kyrofb_info *currentpar; | ||
77 | |||
78 | typedef struct { | 76 | typedef struct { |
79 | STG4000REG __iomem *pSTGReg; /* Virtual address of PCI register region */ | 77 | STG4000REG __iomem *pSTGReg; /* Virtual address of PCI register region */ |
80 | u32 ulNextFreeVidMem; /* Offset from start of vid mem to next free region */ | 78 | u32 ulNextFreeVidMem; /* Offset from start of vid mem to next free region */ |
@@ -309,7 +307,7 @@ enum { | |||
309 | /* Accessors */ | 307 | /* Accessors */ |
310 | static int kyro_dev_video_mode_set(struct fb_info *info) | 308 | static int kyro_dev_video_mode_set(struct fb_info *info) |
311 | { | 309 | { |
312 | struct kyrofb_info *par = (struct kyrofb_info *)info->par; | 310 | struct kyrofb_info *par = info->par; |
313 | 311 | ||
314 | /* Turn off display */ | 312 | /* Turn off display */ |
315 | StopVTG(deviceInfo.pSTGReg); | 313 | StopVTG(deviceInfo.pSTGReg); |
@@ -402,7 +400,7 @@ static inline unsigned long get_line_length(int x, int bpp) | |||
402 | 400 | ||
403 | static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 401 | static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
404 | { | 402 | { |
405 | struct kyrofb_info *par = (struct kyrofb_info *)info->par; | 403 | struct kyrofb_info *par = info->par; |
406 | 404 | ||
407 | if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) { | 405 | if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) { |
408 | printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel); | 406 | printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel); |
@@ -478,7 +476,7 @@ static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
478 | 476 | ||
479 | static int kyrofb_set_par(struct fb_info *info) | 477 | static int kyrofb_set_par(struct fb_info *info) |
480 | { | 478 | { |
481 | struct kyrofb_info *par = (struct kyrofb_info *)info->par; | 479 | struct kyrofb_info *par = info->par; |
482 | unsigned long lineclock; | 480 | unsigned long lineclock; |
483 | unsigned long frameclock; | 481 | unsigned long frameclock; |
484 | 482 | ||
@@ -536,20 +534,22 @@ static int kyrofb_set_par(struct fb_info *info) | |||
536 | static int kyrofb_setcolreg(u_int regno, u_int red, u_int green, | 534 | static int kyrofb_setcolreg(u_int regno, u_int red, u_int green, |
537 | u_int blue, u_int transp, struct fb_info *info) | 535 | u_int blue, u_int transp, struct fb_info *info) |
538 | { | 536 | { |
537 | struct kyrofb_info *par = info->par; | ||
538 | |||
539 | if (regno > 255) | 539 | if (regno > 255) |
540 | return 1; /* Invalid register */ | 540 | return 1; /* Invalid register */ |
541 | 541 | ||
542 | if (regno < 16) { | 542 | if (regno < 16) { |
543 | switch (info->var.bits_per_pixel) { | 543 | switch (info->var.bits_per_pixel) { |
544 | case 16: | 544 | case 16: |
545 | ((u16*)(info->pseudo_palette))[regno] = | 545 | par->palette[regno] = |
546 | (red & 0xf800) | | 546 | (red & 0xf800) | |
547 | ((green & 0xfc00) >> 5) | | 547 | ((green & 0xfc00) >> 5) | |
548 | ((blue & 0xf800) >> 11); | 548 | ((blue & 0xf800) >> 11); |
549 | break; | 549 | break; |
550 | case 32: | 550 | case 32: |
551 | red >>= 8; green >>= 8; blue >>= 8; transp >>= 8; | 551 | red >>= 8; green >>= 8; blue >>= 8; transp >>= 8; |
552 | ((u32*)(info->pseudo_palette))[regno] = | 552 | par->palette[regno] = |
553 | (transp << 24) | (red << 16) | (green << 8) | blue; | 553 | (transp << 24) | (red << 16) | (green << 8) | blue; |
554 | break; | 554 | break; |
555 | } | 555 | } |
@@ -675,6 +675,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, | |||
675 | const struct pci_device_id *ent) | 675 | const struct pci_device_id *ent) |
676 | { | 676 | { |
677 | struct fb_info *info; | 677 | struct fb_info *info; |
678 | struct kyrofb_info *currentpar; | ||
678 | unsigned long size; | 679 | unsigned long size; |
679 | int err; | 680 | int err; |
680 | 681 | ||
@@ -683,14 +684,11 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, | |||
683 | return err; | 684 | return err; |
684 | } | 685 | } |
685 | 686 | ||
686 | size = sizeof(struct fb_info) + sizeof(struct kyrofb_info) + 16 * sizeof(u32); | 687 | info = framebuffer_alloc(sizeof(struct kyrofb_info), &pdev->dev); |
687 | info = kmalloc(size, GFP_KERNEL); | ||
688 | if (!info) | 688 | if (!info) |
689 | return -ENOMEM; | 689 | return -ENOMEM; |
690 | 690 | ||
691 | memset(info, 0, size); | 691 | currentpar = info->par; |
692 | |||
693 | currentpar = (struct kyrofb_info *)(info + 1); | ||
694 | 692 | ||
695 | kyro_fix.smem_start = pci_resource_start(pdev, 0); | 693 | kyro_fix.smem_start = pci_resource_start(pdev, 0); |
696 | kyro_fix.smem_len = pci_resource_len(pdev, 0); | 694 | kyro_fix.smem_len = pci_resource_len(pdev, 0); |
@@ -716,8 +714,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, | |||
716 | 714 | ||
717 | info->fbops = &kyrofb_ops; | 715 | info->fbops = &kyrofb_ops; |
718 | info->fix = kyro_fix; | 716 | info->fix = kyro_fix; |
719 | info->par = currentpar; | 717 | info->pseudo_palette = currentpar->palette; |
720 | info->pseudo_palette = (void *)(currentpar + 1); | ||
721 | info->flags = FBINFO_DEFAULT; | 718 | info->flags = FBINFO_DEFAULT; |
722 | 719 | ||
723 | SetCoreClockPLL(deviceInfo.pSTGReg, pdev); | 720 | SetCoreClockPLL(deviceInfo.pSTGReg, pdev); |
@@ -741,7 +738,6 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, | |||
741 | 738 | ||
742 | fb_memset(info->screen_base, 0, size); | 739 | fb_memset(info->screen_base, 0, size); |
743 | 740 | ||
744 | info->device = &pdev->dev; | ||
745 | if (register_framebuffer(info) < 0) | 741 | if (register_framebuffer(info) < 0) |
746 | goto out_unmap; | 742 | goto out_unmap; |
747 | 743 | ||
@@ -757,7 +753,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, | |||
757 | out_unmap: | 753 | out_unmap: |
758 | iounmap(currentpar->regbase); | 754 | iounmap(currentpar->regbase); |
759 | iounmap(info->screen_base); | 755 | iounmap(info->screen_base); |
760 | kfree(info); | 756 | framebuffer_release(info); |
761 | 757 | ||
762 | return -EINVAL; | 758 | return -EINVAL; |
763 | } | 759 | } |
@@ -765,7 +761,7 @@ out_unmap: | |||
765 | static void __devexit kyrofb_remove(struct pci_dev *pdev) | 761 | static void __devexit kyrofb_remove(struct pci_dev *pdev) |
766 | { | 762 | { |
767 | struct fb_info *info = pci_get_drvdata(pdev); | 763 | struct fb_info *info = pci_get_drvdata(pdev); |
768 | struct kyrofb_info *par = (struct kyrofb_info *)info->par; | 764 | struct kyrofb_info *par = info->par; |
769 | 765 | ||
770 | /* Reset the board */ | 766 | /* Reset the board */ |
771 | StopVTG(deviceInfo.pSTGReg); | 767 | StopVTG(deviceInfo.pSTGReg); |
@@ -789,7 +785,7 @@ static void __devexit kyrofb_remove(struct pci_dev *pdev) | |||
789 | 785 | ||
790 | unregister_framebuffer(info); | 786 | unregister_framebuffer(info); |
791 | pci_set_drvdata(pdev, NULL); | 787 | pci_set_drvdata(pdev, NULL); |
792 | kfree(info); | 788 | framebuffer_release(info); |
793 | } | 789 | } |
794 | 790 | ||
795 | static int __init kyrofb_init(void) | 791 | static int __init kyrofb_init(void) |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index a8c47ad2cdb6..3a3e1804c56a 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
@@ -50,8 +50,6 @@ | |||
50 | #include <asm/mtrr.h> | 50 | #include <asm/mtrr.h> |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | #include "../console/fbcon.h" | ||
54 | |||
55 | #if defined(CONFIG_PPC_PMAC) | 53 | #if defined(CONFIG_PPC_PMAC) |
56 | #include <asm/prom.h> | 54 | #include <asm/prom.h> |
57 | #include <asm/pci-bridge.h> | 55 | #include <asm/pci-bridge.h> |
@@ -351,8 +349,6 @@ struct matrox_bios { | |||
351 | } output; | 349 | } output; |
352 | }; | 350 | }; |
353 | 351 | ||
354 | extern struct display fb_display[]; | ||
355 | |||
356 | struct matrox_switch; | 352 | struct matrox_switch; |
357 | struct matroxfb_driver; | 353 | struct matroxfb_driver; |
358 | struct matroxfb_dh_fb_info; | 354 | struct matroxfb_dh_fb_info; |
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c index 35008af7db75..c122d8743dd2 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/matrox/matroxfb_g450.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <asm/div64.h> | 21 | #include <asm/div64.h> |
22 | 22 | ||
23 | #include "matroxfb_g450.h" | ||
24 | |||
23 | /* Definition of the various controls */ | 25 | /* Definition of the various controls */ |
24 | struct mctl { | 26 | struct mctl { |
25 | struct v4l2_queryctrl desc; | 27 | struct v4l2_queryctrl desc; |
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index d9d3e9f6c08e..455a46ce840c 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c | |||
@@ -192,11 +192,8 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
192 | unsigned int wd; | 192 | unsigned int wd; |
193 | unsigned int divider; | 193 | unsigned int divider; |
194 | int i; | 194 | int i; |
195 | int fwidth; | ||
196 | struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); | 195 | struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); |
197 | 196 | ||
198 | fwidth = 8; | ||
199 | |||
200 | DBG(__FUNCTION__) | 197 | DBG(__FUNCTION__) |
201 | 198 | ||
202 | hw->SEQ[0] = 0x00; | 199 | hw->SEQ[0] = 0x00; |
@@ -235,10 +232,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
235 | hw->ATTR[16] = 0x41; | 232 | hw->ATTR[16] = 0x41; |
236 | hw->ATTR[17] = 0xFF; | 233 | hw->ATTR[17] = 0xFF; |
237 | hw->ATTR[18] = 0x0F; | 234 | hw->ATTR[18] = 0x0F; |
238 | if (fwidth == 9) | 235 | hw->ATTR[19] = 0x00; |
239 | hw->ATTR[19] = 0x08; | ||
240 | else | ||
241 | hw->ATTR[19] = 0x00; | ||
242 | hw->ATTR[20] = 0x00; | 236 | hw->ATTR[20] = 0x00; |
243 | 237 | ||
244 | hd = m->HDisplay >> 3; | 238 | hd = m->HDisplay >> 3; |
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 8486e77872dc..e18c9f98a401 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -485,7 +485,7 @@ static void vgaHWRestore(const struct fb_info *info, | |||
485 | */ | 485 | */ |
486 | static inline int neo2200_sync(struct fb_info *info) | 486 | static inline int neo2200_sync(struct fb_info *info) |
487 | { | 487 | { |
488 | struct neofb_par *par = (struct neofb_par *) info->par; | 488 | struct neofb_par *par = info->par; |
489 | int waitcycles; | 489 | int waitcycles; |
490 | 490 | ||
491 | while (readl(&par->neo2200->bltStat) & 1) | 491 | while (readl(&par->neo2200->bltStat) & 1) |
@@ -525,7 +525,7 @@ static inline void neo2200_wait_fifo(struct fb_info *info, | |||
525 | static inline void neo2200_accel_init(struct fb_info *info, | 525 | static inline void neo2200_accel_init(struct fb_info *info, |
526 | struct fb_var_screeninfo *var) | 526 | struct fb_var_screeninfo *var) |
527 | { | 527 | { |
528 | struct neofb_par *par = (struct neofb_par *) info->par; | 528 | struct neofb_par *par = info->par; |
529 | Neo2200 __iomem *neo2200 = par->neo2200; | 529 | Neo2200 __iomem *neo2200 = par->neo2200; |
530 | u32 bltMod, pitch; | 530 | u32 bltMod, pitch; |
531 | 531 | ||
@@ -560,7 +560,7 @@ static inline void neo2200_accel_init(struct fb_info *info, | |||
560 | static int | 560 | static int |
561 | neofb_open(struct fb_info *info, int user) | 561 | neofb_open(struct fb_info *info, int user) |
562 | { | 562 | { |
563 | struct neofb_par *par = (struct neofb_par *) info->par; | 563 | struct neofb_par *par = info->par; |
564 | int cnt = atomic_read(&par->ref_count); | 564 | int cnt = atomic_read(&par->ref_count); |
565 | 565 | ||
566 | if (!cnt) { | 566 | if (!cnt) { |
@@ -575,7 +575,7 @@ neofb_open(struct fb_info *info, int user) | |||
575 | static int | 575 | static int |
576 | neofb_release(struct fb_info *info, int user) | 576 | neofb_release(struct fb_info *info, int user) |
577 | { | 577 | { |
578 | struct neofb_par *par = (struct neofb_par *) info->par; | 578 | struct neofb_par *par = info->par; |
579 | int cnt = atomic_read(&par->ref_count); | 579 | int cnt = atomic_read(&par->ref_count); |
580 | 580 | ||
581 | if (!cnt) | 581 | if (!cnt) |
@@ -590,7 +590,7 @@ neofb_release(struct fb_info *info, int user) | |||
590 | static int | 590 | static int |
591 | neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 591 | neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
592 | { | 592 | { |
593 | struct neofb_par *par = (struct neofb_par *) info->par; | 593 | struct neofb_par *par = info->par; |
594 | unsigned int pixclock = var->pixclock; | 594 | unsigned int pixclock = var->pixclock; |
595 | struct xtimings timings; | 595 | struct xtimings timings; |
596 | int memlen, vramlen; | 596 | int memlen, vramlen; |
@@ -757,7 +757,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
757 | 757 | ||
758 | static int neofb_set_par(struct fb_info *info) | 758 | static int neofb_set_par(struct fb_info *info) |
759 | { | 759 | { |
760 | struct neofb_par *par = (struct neofb_par *) info->par; | 760 | struct neofb_par *par = info->par; |
761 | struct xtimings timings; | 761 | struct xtimings timings; |
762 | unsigned char temp; | 762 | unsigned char temp; |
763 | int i, clock_hi = 0; | 763 | int i, clock_hi = 0; |
@@ -1216,7 +1216,7 @@ static int neofb_set_par(struct fb_info *info) | |||
1216 | static void neofb_update_start(struct fb_info *info, | 1216 | static void neofb_update_start(struct fb_info *info, |
1217 | struct fb_var_screeninfo *var) | 1217 | struct fb_var_screeninfo *var) |
1218 | { | 1218 | { |
1219 | struct neofb_par *par = (struct neofb_par *) info->par; | 1219 | struct neofb_par *par = info->par; |
1220 | struct vgastate *state = &par->state; | 1220 | struct vgastate *state = &par->state; |
1221 | int oldExtCRTDispAddr; | 1221 | int oldExtCRTDispAddr; |
1222 | int Base; | 1222 | int Base; |
@@ -1331,7 +1331,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) | |||
1331 | * wms...Enable VESA DPMS compatible powerdown mode | 1331 | * wms...Enable VESA DPMS compatible powerdown mode |
1332 | * run "setterm -powersave powerdown" to take advantage | 1332 | * run "setterm -powersave powerdown" to take advantage |
1333 | */ | 1333 | */ |
1334 | struct neofb_par *par = (struct neofb_par *)info->par; | 1334 | struct neofb_par *par = info->par; |
1335 | int seqflags, lcdflags, dpmsflags, reg; | 1335 | int seqflags, lcdflags, dpmsflags, reg; |
1336 | 1336 | ||
1337 | switch (blank_mode) { | 1337 | switch (blank_mode) { |
@@ -1404,7 +1404,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) | |||
1404 | static void | 1404 | static void |
1405 | neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 1405 | neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
1406 | { | 1406 | { |
1407 | struct neofb_par *par = (struct neofb_par *) info->par; | 1407 | struct neofb_par *par = info->par; |
1408 | u_long dst, rop; | 1408 | u_long dst, rop; |
1409 | 1409 | ||
1410 | dst = rect->dx + rect->dy * info->var.xres_virtual; | 1410 | dst = rect->dx + rect->dy * info->var.xres_virtual; |
@@ -1440,7 +1440,7 @@ static void | |||
1440 | neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) | 1440 | neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) |
1441 | { | 1441 | { |
1442 | u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; | 1442 | u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; |
1443 | struct neofb_par *par = (struct neofb_par *) info->par; | 1443 | struct neofb_par *par = info->par; |
1444 | u_long src, dst, bltCntl; | 1444 | u_long src, dst, bltCntl; |
1445 | 1445 | ||
1446 | bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000; | 1446 | bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000; |
@@ -1472,7 +1472,7 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
1472 | static void | 1472 | static void |
1473 | neo2200_imageblit(struct fb_info *info, const struct fb_image *image) | 1473 | neo2200_imageblit(struct fb_info *info, const struct fb_image *image) |
1474 | { | 1474 | { |
1475 | struct neofb_par *par = (struct neofb_par *) info->par; | 1475 | struct neofb_par *par = info->par; |
1476 | int s_pitch = (image->width * image->depth + 7) >> 3; | 1476 | int s_pitch = (image->width * image->depth + 7) >> 3; |
1477 | int scan_align = info->pixmap.scan_align - 1; | 1477 | int scan_align = info->pixmap.scan_align - 1; |
1478 | int buf_align = info->pixmap.buf_align - 1; | 1478 | int buf_align = info->pixmap.buf_align - 1; |
@@ -1686,7 +1686,7 @@ static struct fb_videomode __devinitdata mode800x480 = { | |||
1686 | static int __devinit neo_map_mmio(struct fb_info *info, | 1686 | static int __devinit neo_map_mmio(struct fb_info *info, |
1687 | struct pci_dev *dev) | 1687 | struct pci_dev *dev) |
1688 | { | 1688 | { |
1689 | struct neofb_par *par = (struct neofb_par *) info->par; | 1689 | struct neofb_par *par = info->par; |
1690 | 1690 | ||
1691 | DBG("neo_map_mmio"); | 1691 | DBG("neo_map_mmio"); |
1692 | 1692 | ||
@@ -1733,7 +1733,7 @@ static int __devinit neo_map_mmio(struct fb_info *info, | |||
1733 | 1733 | ||
1734 | static void neo_unmap_mmio(struct fb_info *info) | 1734 | static void neo_unmap_mmio(struct fb_info *info) |
1735 | { | 1735 | { |
1736 | struct neofb_par *par = (struct neofb_par *) info->par; | 1736 | struct neofb_par *par = info->par; |
1737 | 1737 | ||
1738 | DBG("neo_unmap_mmio"); | 1738 | DBG("neo_unmap_mmio"); |
1739 | 1739 | ||
@@ -1796,7 +1796,7 @@ static void neo_unmap_video(struct fb_info *info) | |||
1796 | 1796 | ||
1797 | #ifdef CONFIG_MTRR | 1797 | #ifdef CONFIG_MTRR |
1798 | { | 1798 | { |
1799 | struct neofb_par *par = (struct neofb_par *) info->par; | 1799 | struct neofb_par *par = info->par; |
1800 | 1800 | ||
1801 | mtrr_del(par->mtrr, info->fix.smem_start, | 1801 | mtrr_del(par->mtrr, info->fix.smem_start, |
1802 | info->fix.smem_len); | 1802 | info->fix.smem_len); |
@@ -1811,7 +1811,7 @@ static void neo_unmap_video(struct fb_info *info) | |||
1811 | 1811 | ||
1812 | static int __devinit neo_scan_monitor(struct fb_info *info) | 1812 | static int __devinit neo_scan_monitor(struct fb_info *info) |
1813 | { | 1813 | { |
1814 | struct neofb_par *par = (struct neofb_par *) info->par; | 1814 | struct neofb_par *par = info->par; |
1815 | unsigned char type, display; | 1815 | unsigned char type, display; |
1816 | int w; | 1816 | int w; |
1817 | 1817 | ||
@@ -1890,7 +1890,7 @@ static int __devinit neo_scan_monitor(struct fb_info *info) | |||
1890 | 1890 | ||
1891 | static int __devinit neo_init_hw(struct fb_info *info) | 1891 | static int __devinit neo_init_hw(struct fb_info *info) |
1892 | { | 1892 | { |
1893 | struct neofb_par *par = (struct neofb_par *) info->par; | 1893 | struct neofb_par *par = info->par; |
1894 | int videoRam = 896; | 1894 | int videoRam = 896; |
1895 | int maxClock = 65000; | 1895 | int maxClock = 65000; |
1896 | int CursorMem = 1024; | 1896 | int CursorMem = 1024; |
@@ -2014,7 +2014,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st | |||
2014 | struct fb_info *info; | 2014 | struct fb_info *info; |
2015 | struct neofb_par *par; | 2015 | struct neofb_par *par; |
2016 | 2016 | ||
2017 | info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 256, &dev->dev); | 2017 | info = framebuffer_alloc(sizeof(struct neofb_par), &dev->dev); |
2018 | 2018 | ||
2019 | if (!info) | 2019 | if (!info) |
2020 | return NULL; | 2020 | return NULL; |
@@ -2081,7 +2081,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st | |||
2081 | info->fix.accel = id->driver_data; | 2081 | info->fix.accel = id->driver_data; |
2082 | 2082 | ||
2083 | info->fbops = &neofb_ops; | 2083 | info->fbops = &neofb_ops; |
2084 | info->pseudo_palette = (void *) (par + 1); | 2084 | info->pseudo_palette = par->palette; |
2085 | return info; | 2085 | return info; |
2086 | } | 2086 | } |
2087 | 2087 | ||
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index b989358437b3..99c3a8e6a237 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include "nv_type.h" | 53 | #include "nv_type.h" |
54 | #include "nv_local.h" | 54 | #include "nv_local.h" |
55 | #include "nv_proto.h" | ||
55 | 56 | ||
56 | void NVLockUnlock(struct nvidia_par *par, int Lock) | 57 | void NVLockUnlock(struct nvidia_par *par, int Lock) |
57 | { | 58 | { |
@@ -848,7 +849,7 @@ void NVCalcStateExt(struct nvidia_par *par, | |||
848 | int width, | 849 | int width, |
849 | int hDisplaySize, int height, int dotClock, int flags) | 850 | int hDisplaySize, int height, int dotClock, int flags) |
850 | { | 851 | { |
851 | int pixelDepth, VClk; | 852 | int pixelDepth, VClk = 0; |
852 | /* | 853 | /* |
853 | * Save mode parameters. | 854 | * Save mode parameters. |
854 | */ | 855 | */ |
@@ -938,15 +939,24 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
938 | 939 | ||
939 | if (par->Architecture == NV_ARCH_04) { | 940 | if (par->Architecture == NV_ARCH_04) { |
940 | NV_WR32(par->PFB, 0x0200, state->config); | 941 | NV_WR32(par->PFB, 0x0200, state->config); |
941 | } else if ((par->Chipset & 0xfff0) == 0x0090) { | 942 | } else if ((par->Architecture < NV_ARCH_40) || |
942 | for (i = 0; i < 15; i++) { | 943 | (par->Chipset & 0xfff0) == 0x0040) { |
943 | NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); | ||
944 | NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1); | ||
945 | } | ||
946 | } else { | ||
947 | for (i = 0; i < 8; i++) { | 944 | for (i = 0; i < 8; i++) { |
948 | NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0); | 945 | NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0); |
949 | NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1); | 946 | NV_WR32(par->PFB, 0x0244 + (i * 0x10), |
947 | par->FbMapSize - 1); | ||
948 | } | ||
949 | } else { | ||
950 | int regions = 12; | ||
951 | |||
952 | if (((par->Chipset & 0xfff0) == 0x0090) || | ||
953 | ((par->Chipset & 0xfff0) == 0x01D0) || | ||
954 | ((par->Chipset & 0xfff0) == 0x0290)) | ||
955 | regions = 15; | ||
956 | for(i = 0; i < regions; i++) { | ||
957 | NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); | ||
958 | NV_WR32(par->PFB, 0x0604 + (i * 0x10), | ||
959 | par->FbMapSize - 1); | ||
950 | } | 960 | } |
951 | } | 961 | } |
952 | 962 | ||
@@ -1182,11 +1192,17 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1182 | NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF); | 1192 | NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF); |
1183 | } else { | 1193 | } else { |
1184 | if (par->Architecture >= NV_ARCH_40) { | 1194 | if (par->Architecture >= NV_ARCH_40) { |
1195 | u32 tmp; | ||
1196 | |||
1185 | NV_WR32(par->PGRAPH, 0x0084, 0x401287c0); | 1197 | NV_WR32(par->PGRAPH, 0x0084, 0x401287c0); |
1186 | NV_WR32(par->PGRAPH, 0x008C, 0x60de8051); | 1198 | NV_WR32(par->PGRAPH, 0x008C, 0x60de8051); |
1187 | NV_WR32(par->PGRAPH, 0x0090, 0x00008000); | 1199 | NV_WR32(par->PGRAPH, 0x0090, 0x00008000); |
1188 | NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f); | 1200 | NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f); |
1189 | 1201 | ||
1202 | tmp = NV_RD32(par->REGS, 0x1540) & 0xff; | ||
1203 | for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++); | ||
1204 | NV_WR32(par->PGRAPH, 0x5000, i); | ||
1205 | |||
1190 | if ((par->Chipset & 0xfff0) == 0x0040) { | 1206 | if ((par->Chipset & 0xfff0) == 0x0040) { |
1191 | NV_WR32(par->PGRAPH, 0x09b0, | 1207 | NV_WR32(par->PGRAPH, 0x09b0, |
1192 | 0x83280fff); | 1208 | 0x83280fff); |
@@ -1211,6 +1227,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1211 | 0xffff7fff); | 1227 | 0xffff7fff); |
1212 | break; | 1228 | break; |
1213 | case 0x00C0: | 1229 | case 0x00C0: |
1230 | case 0x0120: | ||
1214 | NV_WR32(par->PGRAPH, 0x0828, | 1231 | NV_WR32(par->PGRAPH, 0x0828, |
1215 | 0x007596ff); | 1232 | 0x007596ff); |
1216 | NV_WR32(par->PGRAPH, 0x082C, | 1233 | NV_WR32(par->PGRAPH, 0x082C, |
@@ -1245,6 +1262,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1245 | 0x00100000); | 1262 | 0x00100000); |
1246 | break; | 1263 | break; |
1247 | case 0x0090: | 1264 | case 0x0090: |
1265 | case 0x0290: | ||
1248 | NV_WR32(par->PRAMDAC, 0x0608, | 1266 | NV_WR32(par->PRAMDAC, 0x0608, |
1249 | NV_RD32(par->PRAMDAC, 0x0608) | | 1267 | NV_RD32(par->PRAMDAC, 0x0608) | |
1250 | 0x00100000); | 1268 | 0x00100000); |
@@ -1310,14 +1328,44 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1310 | } | 1328 | } |
1311 | } | 1329 | } |
1312 | 1330 | ||
1313 | if ((par->Chipset & 0xfff0) == 0x0090) { | 1331 | if ((par->Architecture < NV_ARCH_40) || |
1314 | for (i = 0; i < 60; i++) | 1332 | ((par->Chipset & 0xfff0) == 0x0040)) { |
1315 | NV_WR32(par->PGRAPH, 0x0D00 + i, | 1333 | for (i = 0; i < 32; i++) { |
1316 | NV_RD32(par->PFB, 0x0600 + i)); | 1334 | NV_WR32(par->PGRAPH, 0x0900 + i*4, |
1335 | NV_RD32(par->PFB, 0x0240 +i*4)); | ||
1336 | NV_WR32(par->PGRAPH, 0x6900 + i*4, | ||
1337 | NV_RD32(par->PFB, 0x0240 +i*4)); | ||
1338 | } | ||
1317 | } else { | 1339 | } else { |
1318 | for (i = 0; i < 32; i++) | 1340 | if (((par->Chipset & 0xfff0) == 0x0090) || |
1319 | NV_WR32(par->PGRAPH, 0x0900 + i, | 1341 | ((par->Chipset & 0xfff0) == 0x01D0) || |
1320 | NV_RD32(par->PFB, 0x0240 + i)); | 1342 | ((par->Chipset & 0xfff0) == 0x0290)) { |
1343 | for (i = 0; i < 60; i++) { | ||
1344 | NV_WR32(par->PGRAPH, | ||
1345 | 0x0D00 + i*4, | ||
1346 | NV_RD32(par->PFB, | ||
1347 | 0x0600 + i*4)); | ||
1348 | NV_WR32(par->PGRAPH, | ||
1349 | 0x6900 + i*4, | ||
1350 | NV_RD32(par->PFB, | ||
1351 | 0x0600 + i*4)); | ||
1352 | } | ||
1353 | } else { | ||
1354 | for (i = 0; i < 48; i++) { | ||
1355 | NV_WR32(par->PGRAPH, | ||
1356 | 0x0900 + i*4, | ||
1357 | NV_RD32(par->PFB, | ||
1358 | 0x0600 + i*4)); | ||
1359 | if(((par->Chipset & 0xfff0) | ||
1360 | != 0x0160) && | ||
1361 | ((par->Chipset & 0xfff0) | ||
1362 | != 0x0220)) | ||
1363 | NV_WR32(par->PGRAPH, | ||
1364 | 0x6900 + i*4, | ||
1365 | NV_RD32(par->PFB, | ||
1366 | 0x0600 + i*4)); | ||
1367 | } | ||
1368 | } | ||
1321 | } | 1369 | } |
1322 | 1370 | ||
1323 | if (par->Architecture >= NV_ARCH_40) { | 1371 | if (par->Architecture >= NV_ARCH_40) { |
@@ -1338,7 +1386,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1338 | NV_WR32(par->PGRAPH, 0x0868, | 1386 | NV_WR32(par->PGRAPH, 0x0868, |
1339 | par->FbMapSize - 1); | 1387 | par->FbMapSize - 1); |
1340 | } else { | 1388 | } else { |
1341 | if((par->Chipset & 0xfff0) == 0x0090) { | 1389 | if ((par->Chipset & 0xfff0) == 0x0090 || |
1390 | (par->Chipset & 0xfff0) == 0x01D0 || | ||
1391 | (par->Chipset & 0xfff0) == 0x0290) { | ||
1342 | NV_WR32(par->PGRAPH, 0x0DF0, | 1392 | NV_WR32(par->PGRAPH, 0x0DF0, |
1343 | NV_RD32(par->PFB, 0x0200)); | 1393 | NV_RD32(par->PFB, 0x0200)); |
1344 | NV_WR32(par->PGRAPH, 0x0DF4, | 1394 | NV_WR32(par->PGRAPH, 0x0DF4, |
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 12f2884d3f0b..bd9eca05e146 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c | |||
@@ -46,7 +46,7 @@ static void nvidia_gpio_setscl(void *data, int state) | |||
46 | 46 | ||
47 | static void nvidia_gpio_setsda(void *data, int state) | 47 | static void nvidia_gpio_setsda(void *data, int state) |
48 | { | 48 | { |
49 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 49 | struct nvidia_i2c_chan *chan = data; |
50 | struct nvidia_par *par = chan->par; | 50 | struct nvidia_par *par = chan->par; |
51 | u32 val; | 51 | u32 val; |
52 | 52 | ||
@@ -64,7 +64,7 @@ static void nvidia_gpio_setsda(void *data, int state) | |||
64 | 64 | ||
65 | static int nvidia_gpio_getscl(void *data) | 65 | static int nvidia_gpio_getscl(void *data) |
66 | { | 66 | { |
67 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 67 | struct nvidia_i2c_chan *chan = data; |
68 | struct nvidia_par *par = chan->par; | 68 | struct nvidia_par *par = chan->par; |
69 | u32 val = 0; | 69 | u32 val = 0; |
70 | 70 | ||
@@ -79,7 +79,7 @@ static int nvidia_gpio_getscl(void *data) | |||
79 | 79 | ||
80 | static int nvidia_gpio_getsda(void *data) | 80 | static int nvidia_gpio_getsda(void *data) |
81 | { | 81 | { |
82 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 82 | struct nvidia_i2c_chan *chan = data; |
83 | struct nvidia_par *par = chan->par; | 83 | struct nvidia_par *par = chan->par; |
84 | u32 val = 0; | 84 | u32 val = 0; |
85 | 85 | ||
@@ -136,13 +136,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par) | |||
136 | par->chan[2].par = par; | 136 | par->chan[2].par = par; |
137 | 137 | ||
138 | par->chan[0].ddc_base = 0x3e; | 138 | par->chan[0].ddc_base = 0x3e; |
139 | nvidia_setup_i2c_bus(&par->chan[0], "BUS1"); | 139 | nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0"); |
140 | 140 | ||
141 | par->chan[1].ddc_base = 0x36; | 141 | par->chan[1].ddc_base = 0x36; |
142 | nvidia_setup_i2c_bus(&par->chan[1], "BUS2"); | 142 | nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1"); |
143 | 143 | ||
144 | par->chan[2].ddc_base = 0x50; | 144 | par->chan[2].ddc_base = 0x50; |
145 | nvidia_setup_i2c_bus(&par->chan[2], "BUS3"); | 145 | nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2"); |
146 | } | 146 | } |
147 | 147 | ||
148 | void nvidia_delete_i2c_busses(struct nvidia_par *par) | 148 | void nvidia_delete_i2c_busses(struct nvidia_par *par) |
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h index 3353103e8b0b..b149a690ee0f 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/nvidia/nv_proto.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #define __NV_PROTO_H__ | 4 | #define __NV_PROTO_H__ |
5 | 5 | ||
6 | /* in nv_setup.c */ | 6 | /* in nv_setup.c */ |
7 | void NVCommonSetup(struct fb_info *info); | 7 | int NVCommonSetup(struct fb_info *info); |
8 | void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value); | 8 | void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value); |
9 | u8 NVReadCrtc(struct nvidia_par *par, u8 index); | 9 | u8 NVReadCrtc(struct nvidia_par *par, u8 index); |
10 | void NVWriteGr(struct nvidia_par *par, u8 index, u8 value); | 10 | void NVWriteGr(struct nvidia_par *par, u8 index, u8 value); |
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index 1f06a9f1bd0f..a18a9aebf05f 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c | |||
@@ -285,28 +285,34 @@ static void nv10GetConfig(struct nvidia_par *par) | |||
285 | par->CrystalFreqKHz = 27000; | 285 | par->CrystalFreqKHz = 27000; |
286 | } | 286 | } |
287 | 287 | ||
288 | par->CursorStart = (par->RamAmountKBytes - 96) * 1024; | ||
289 | par->CURSOR = NULL; /* can't set this here */ | 288 | par->CURSOR = NULL; /* can't set this here */ |
290 | par->MinVClockFreqKHz = 12000; | 289 | par->MinVClockFreqKHz = 12000; |
291 | par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; | 290 | par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; |
292 | } | 291 | } |
293 | 292 | ||
294 | void NVCommonSetup(struct fb_info *info) | 293 | int NVCommonSetup(struct fb_info *info) |
295 | { | 294 | { |
296 | struct nvidia_par *par = info->par; | 295 | struct nvidia_par *par = info->par; |
297 | struct fb_var_screeninfo var; | 296 | struct fb_var_screeninfo *var; |
298 | u16 implementation = par->Chipset & 0x0ff0; | 297 | u16 implementation = par->Chipset & 0x0ff0; |
299 | u8 *edidA = NULL, *edidB = NULL; | 298 | u8 *edidA = NULL, *edidB = NULL; |
300 | struct fb_monspecs monitorA, monitorB; | 299 | struct fb_monspecs *monitorA, *monitorB; |
301 | struct fb_monspecs *monA = NULL, *monB = NULL; | 300 | struct fb_monspecs *monA = NULL, *monB = NULL; |
302 | int mobile = 0; | 301 | int mobile = 0; |
303 | int tvA = 0; | 302 | int tvA = 0; |
304 | int tvB = 0; | 303 | int tvB = 0; |
305 | int FlatPanel = -1; /* really means the CRTC is slaved */ | 304 | int FlatPanel = -1; /* really means the CRTC is slaved */ |
306 | int Television = 0; | 305 | int Television = 0; |
306 | int err = 0; | ||
307 | 307 | ||
308 | memset(&monitorA, 0, sizeof(struct fb_monspecs)); | 308 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); |
309 | memset(&monitorB, 0, sizeof(struct fb_monspecs)); | 309 | monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); |
310 | monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); | ||
311 | |||
312 | if (!var || !monitorA || !monitorB) { | ||
313 | err = -ENOMEM; | ||
314 | goto done; | ||
315 | } | ||
310 | 316 | ||
311 | par->PRAMIN = par->REGS + (0x00710000 / 4); | 317 | par->PRAMIN = par->REGS + (0x00710000 / 4); |
312 | par->PCRTC0 = par->REGS + (0x00600000 / 4); | 318 | par->PCRTC0 = par->REGS + (0x00600000 / 4); |
@@ -382,6 +388,8 @@ void NVCommonSetup(struct fb_info *info) | |||
382 | case 0x0146: | 388 | case 0x0146: |
383 | case 0x0147: | 389 | case 0x0147: |
384 | case 0x0148: | 390 | case 0x0148: |
391 | case 0x0098: | ||
392 | case 0x0099: | ||
385 | mobile = 1; | 393 | mobile = 1; |
386 | break; | 394 | break; |
387 | default: | 395 | default: |
@@ -406,9 +414,9 @@ void NVCommonSetup(struct fb_info *info) | |||
406 | par->CRTCnumber = 0; | 414 | par->CRTCnumber = 0; |
407 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) | 415 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) |
408 | nvidia_probe_of_connector(info, 1, &edidA); | 416 | nvidia_probe_of_connector(info, 1, &edidA); |
409 | if (edidA && !fb_parse_edid(edidA, &var)) { | 417 | if (edidA && !fb_parse_edid(edidA, var)) { |
410 | printk("nvidiafb: EDID found from BUS1\n"); | 418 | printk("nvidiafb: EDID found from BUS1\n"); |
411 | monA = &monitorA; | 419 | monA = monitorA; |
412 | fb_edid_to_monspecs(edidA, monA); | 420 | fb_edid_to_monspecs(edidA, monA); |
413 | FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; | 421 | FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; |
414 | 422 | ||
@@ -494,17 +502,17 @@ void NVCommonSetup(struct fb_info *info) | |||
494 | 502 | ||
495 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) | 503 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) |
496 | nvidia_probe_of_connector(info, 1, &edidA); | 504 | nvidia_probe_of_connector(info, 1, &edidA); |
497 | if (edidA && !fb_parse_edid(edidA, &var)) { | 505 | if (edidA && !fb_parse_edid(edidA, var)) { |
498 | printk("nvidiafb: EDID found from BUS1\n"); | 506 | printk("nvidiafb: EDID found from BUS1\n"); |
499 | monA = &monitorA; | 507 | monA = monitorA; |
500 | fb_edid_to_monspecs(edidA, monA); | 508 | fb_edid_to_monspecs(edidA, monA); |
501 | } | 509 | } |
502 | 510 | ||
503 | if (nvidia_probe_i2c_connector(info, 2, &edidB)) | 511 | if (nvidia_probe_i2c_connector(info, 2, &edidB)) |
504 | nvidia_probe_of_connector(info, 2, &edidB); | 512 | nvidia_probe_of_connector(info, 2, &edidB); |
505 | if (edidB && !fb_parse_edid(edidB, &var)) { | 513 | if (edidB && !fb_parse_edid(edidB, var)) { |
506 | printk("nvidiafb: EDID found from BUS2\n"); | 514 | printk("nvidiafb: EDID found from BUS2\n"); |
507 | monB = &monitorB; | 515 | monB = monitorB; |
508 | fb_edid_to_monspecs(edidB, monB); | 516 | fb_edid_to_monspecs(edidB, monB); |
509 | } | 517 | } |
510 | 518 | ||
@@ -639,4 +647,9 @@ void NVCommonSetup(struct fb_info *info) | |||
639 | 647 | ||
640 | kfree(edidA); | 648 | kfree(edidA); |
641 | kfree(edidB); | 649 | kfree(edidB); |
650 | done: | ||
651 | kfree(var); | ||
652 | kfree(monitorA); | ||
653 | kfree(monitorB); | ||
654 | return err; | ||
642 | } | 655 | } |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index bee09c6e48f6..dbcb8962e57d 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -284,6 +284,16 @@ static struct pci_device_id nvidiafb_pci_tbl[] = { | |||
284 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 284 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
285 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, | 285 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, |
286 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 286 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
287 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1, | ||
288 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
289 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1, | ||
290 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
291 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2, | ||
292 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
293 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1, | ||
294 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
295 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, | ||
296 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
287 | {PCI_VENDOR_ID_NVIDIA, 0x0252, | 297 | {PCI_VENDOR_ID_NVIDIA, 0x0252, |
288 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 298 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
289 | {PCI_VENDOR_ID_NVIDIA, 0x0313, | 299 | {PCI_VENDOR_ID_NVIDIA, 0x0313, |
@@ -418,6 +428,7 @@ static int noaccel __devinitdata = 0; | |||
418 | static int noscale __devinitdata = 0; | 428 | static int noscale __devinitdata = 0; |
419 | static int paneltweak __devinitdata = 0; | 429 | static int paneltweak __devinitdata = 0; |
420 | static int vram __devinitdata = 0; | 430 | static int vram __devinitdata = 0; |
431 | static int bpp __devinitdata = 8; | ||
421 | #ifdef CONFIG_MTRR | 432 | #ifdef CONFIG_MTRR |
422 | static int nomtrr __devinitdata = 0; | 433 | static int nomtrr __devinitdata = 0; |
423 | #endif | 434 | #endif |
@@ -485,7 +496,7 @@ static int nvidia_backlight_levels[] = { | |||
485 | 496 | ||
486 | static int nvidia_set_backlight_enable(int on, int level, void *data) | 497 | static int nvidia_set_backlight_enable(int on, int level, void *data) |
487 | { | 498 | { |
488 | struct nvidia_par *par = (struct nvidia_par *)data; | 499 | struct nvidia_par *par = data; |
489 | u32 tmp_pcrt, tmp_pmc, fpcontrol; | 500 | u32 tmp_pcrt, tmp_pmc, fpcontrol; |
490 | 501 | ||
491 | tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; | 502 | tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; |
@@ -1382,24 +1393,36 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1382 | info->monspecs.modedb_len, &info->modelist); | 1393 | info->monspecs.modedb_len, &info->modelist); |
1383 | fb_var_to_videomode(&modedb, &nvidiafb_default_var); | 1394 | fb_var_to_videomode(&modedb, &nvidiafb_default_var); |
1384 | 1395 | ||
1396 | switch (bpp) { | ||
1397 | case 0 ... 8: | ||
1398 | bpp = 8; | ||
1399 | break; | ||
1400 | case 9 ... 16: | ||
1401 | bpp = 16; | ||
1402 | break; | ||
1403 | default: | ||
1404 | bpp = 32; | ||
1405 | break; | ||
1406 | } | ||
1407 | |||
1385 | if (specs->modedb != NULL) { | 1408 | if (specs->modedb != NULL) { |
1386 | struct fb_videomode *modedb; | 1409 | struct fb_videomode *modedb; |
1387 | 1410 | ||
1388 | modedb = fb_find_best_display(specs, &info->modelist); | 1411 | modedb = fb_find_best_display(specs, &info->modelist); |
1389 | fb_videomode_to_var(&nvidiafb_default_var, modedb); | 1412 | fb_videomode_to_var(&nvidiafb_default_var, modedb); |
1390 | nvidiafb_default_var.bits_per_pixel = 8; | 1413 | nvidiafb_default_var.bits_per_pixel = bpp; |
1391 | } else if (par->fpWidth && par->fpHeight) { | 1414 | } else if (par->fpWidth && par->fpHeight) { |
1392 | char buf[16]; | 1415 | char buf[16]; |
1393 | 1416 | ||
1394 | memset(buf, 0, 16); | 1417 | memset(buf, 0, 16); |
1395 | snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight); | 1418 | snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight); |
1396 | fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, | 1419 | fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, |
1397 | specs->modedb_len, &modedb, 8); | 1420 | specs->modedb_len, &modedb, bpp); |
1398 | } | 1421 | } |
1399 | 1422 | ||
1400 | if (mode_option) | 1423 | if (mode_option) |
1401 | fb_find_mode(&nvidiafb_default_var, info, mode_option, | 1424 | fb_find_mode(&nvidiafb_default_var, info, mode_option, |
1402 | specs->modedb, specs->modedb_len, &modedb, 8); | 1425 | specs->modedb, specs->modedb_len, &modedb, bpp); |
1403 | 1426 | ||
1404 | info->var = nvidiafb_default_var; | 1427 | info->var = nvidiafb_default_var; |
1405 | info->fix.visual = (info->var.bits_per_pixel == 8) ? | 1428 | info->fix.visual = (info->var.bits_per_pixel == 8) ? |
@@ -1448,11 +1471,34 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1448 | return nvidiafb_check_var(&info->var, info); | 1471 | return nvidiafb_check_var(&info->var, info); |
1449 | } | 1472 | } |
1450 | 1473 | ||
1451 | static u32 __devinit nvidia_get_arch(struct pci_dev *pd) | 1474 | static u32 __devinit nvidia_get_chipset(struct fb_info *info) |
1452 | { | 1475 | { |
1476 | struct nvidia_par *par = info->par; | ||
1477 | u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; | ||
1478 | |||
1479 | printk("nvidiafb: PCI id - %x\n", id); | ||
1480 | if ((id & 0xfff0) == 0x00f0) { | ||
1481 | /* pci-e */ | ||
1482 | printk("nvidiafb: PCI-E card\n"); | ||
1483 | id = NV_RD32(par->REGS, 0x1800); | ||
1484 | |||
1485 | if ((id & 0x0000ffff) == 0x000010DE) | ||
1486 | id = 0x10DE0000 | (id >> 16); | ||
1487 | else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ | ||
1488 | id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | | ||
1489 | ((id >> 8) & 0x000000ff); | ||
1490 | } | ||
1491 | |||
1492 | printk("nvidiafb: Actual id - %x\n", id); | ||
1493 | return id; | ||
1494 | } | ||
1495 | |||
1496 | static u32 __devinit nvidia_get_arch(struct fb_info *info) | ||
1497 | { | ||
1498 | struct nvidia_par *par = info->par; | ||
1453 | u32 arch = 0; | 1499 | u32 arch = 0; |
1454 | 1500 | ||
1455 | switch (pd->device & 0x0ff0) { | 1501 | switch (par->Chipset & 0x0ff0) { |
1456 | case 0x0100: /* GeForce 256 */ | 1502 | case 0x0100: /* GeForce 256 */ |
1457 | case 0x0110: /* GeForce2 MX */ | 1503 | case 0x0110: /* GeForce2 MX */ |
1458 | case 0x0150: /* GeForce2 */ | 1504 | case 0x0150: /* GeForce2 */ |
@@ -1485,6 +1531,8 @@ static u32 __devinit nvidia_get_arch(struct pci_dev *pd) | |||
1485 | case 0x0210: | 1531 | case 0x0210: |
1486 | case 0x0220: | 1532 | case 0x0220: |
1487 | case 0x0230: | 1533 | case 0x0230: |
1534 | case 0x0290: | ||
1535 | case 0x0390: | ||
1488 | arch = NV_ARCH_40; | 1536 | arch = NV_ARCH_40; |
1489 | break; | 1537 | break; |
1490 | case 0x0020: /* TNT, TNT2 */ | 1538 | case 0x0020: /* TNT, TNT2 */ |
@@ -1513,7 +1561,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1513 | if (!info) | 1561 | if (!info) |
1514 | goto err_out; | 1562 | goto err_out; |
1515 | 1563 | ||
1516 | par = (struct nvidia_par *)info->par; | 1564 | par = info->par; |
1517 | par->pci_dev = pd; | 1565 | par->pci_dev = pd; |
1518 | 1566 | ||
1519 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); | 1567 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); |
@@ -1533,18 +1581,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1533 | goto err_out_request; | 1581 | goto err_out_request; |
1534 | } | 1582 | } |
1535 | 1583 | ||
1536 | par->Architecture = nvidia_get_arch(pd); | ||
1537 | |||
1538 | par->Chipset = (pd->vendor << 16) | pd->device; | ||
1539 | printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); | ||
1540 | |||
1541 | if (par->Architecture == 0) { | ||
1542 | printk(KERN_ERR PFX "unknown NV_ARCH\n"); | ||
1543 | goto err_out_free_base0; | ||
1544 | } | ||
1545 | |||
1546 | sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); | ||
1547 | |||
1548 | par->FlatPanel = flatpanel; | 1584 | par->FlatPanel = flatpanel; |
1549 | if (flatpanel == 1) | 1585 | if (flatpanel == 1) |
1550 | printk(KERN_INFO PFX "flatpanel support enabled\n"); | 1586 | printk(KERN_INFO PFX "flatpanel support enabled\n"); |
@@ -1570,7 +1606,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1570 | goto err_out_free_base0; | 1606 | goto err_out_free_base0; |
1571 | } | 1607 | } |
1572 | 1608 | ||
1573 | NVCommonSetup(info); | 1609 | par->Chipset = nvidia_get_chipset(info); |
1610 | printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); | ||
1611 | par->Architecture = nvidia_get_arch(info); | ||
1612 | |||
1613 | if (par->Architecture == 0) { | ||
1614 | printk(KERN_ERR PFX "unknown NV_ARCH\n"); | ||
1615 | goto err_out_arch; | ||
1616 | } | ||
1617 | |||
1618 | sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); | ||
1619 | |||
1620 | if (NVCommonSetup(info)) | ||
1621 | goto err_out_arch; | ||
1574 | 1622 | ||
1575 | par->FbAddress = nvidiafb_fix.smem_start; | 1623 | par->FbAddress = nvidiafb_fix.smem_start; |
1576 | par->FbMapSize = par->RamAmountKBytes * 1024; | 1624 | par->FbMapSize = par->RamAmountKBytes * 1024; |
@@ -1581,10 +1629,15 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1581 | if (par->FbMapSize > 64 * 1024 * 1024) | 1629 | if (par->FbMapSize > 64 * 1024 * 1024) |
1582 | par->FbMapSize = 64 * 1024 * 1024; | 1630 | par->FbMapSize = 64 * 1024 * 1024; |
1583 | 1631 | ||
1584 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | 1632 | if(par->Architecture >= NV_ARCH_40) |
1633 | par->FbUsableSize = par->FbMapSize - (560 * 1024); | ||
1634 | else | ||
1635 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | ||
1585 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : | 1636 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : |
1586 | 16 * 1024; | 1637 | 16 * 1024; |
1587 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; | 1638 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; |
1639 | par->CursorStart = par->FbUsableSize + (32 * 1024); | ||
1640 | |||
1588 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); | 1641 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); |
1589 | info->screen_size = par->FbUsableSize; | 1642 | info->screen_size = par->FbUsableSize; |
1590 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; | 1643 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; |
@@ -1640,21 +1693,22 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1640 | NVTRACE_LEAVE(); | 1693 | NVTRACE_LEAVE(); |
1641 | return 0; | 1694 | return 0; |
1642 | 1695 | ||
1643 | err_out_iounmap_fb: | 1696 | err_out_iounmap_fb: |
1644 | iounmap(info->screen_base); | 1697 | iounmap(info->screen_base); |
1645 | err_out_free_base1: | 1698 | err_out_free_base1: |
1646 | fb_destroy_modedb(info->monspecs.modedb); | 1699 | fb_destroy_modedb(info->monspecs.modedb); |
1647 | nvidia_delete_i2c_busses(par); | 1700 | nvidia_delete_i2c_busses(par); |
1701 | err_out_arch: | ||
1648 | iounmap(par->REGS); | 1702 | iounmap(par->REGS); |
1649 | err_out_free_base0: | 1703 | err_out_free_base0: |
1650 | pci_release_regions(pd); | 1704 | pci_release_regions(pd); |
1651 | err_out_request: | 1705 | err_out_request: |
1652 | pci_disable_device(pd); | 1706 | pci_disable_device(pd); |
1653 | err_out_enable: | 1707 | err_out_enable: |
1654 | kfree(info->pixmap.addr); | 1708 | kfree(info->pixmap.addr); |
1655 | err_out_kfree: | 1709 | err_out_kfree: |
1656 | framebuffer_release(info); | 1710 | framebuffer_release(info); |
1657 | err_out: | 1711 | err_out: |
1658 | return -ENODEV; | 1712 | return -ENODEV; |
1659 | } | 1713 | } |
1660 | 1714 | ||
@@ -1729,6 +1783,8 @@ static int __devinit nvidiafb_setup(char *options) | |||
1729 | #endif | 1783 | #endif |
1730 | } else if (!strncmp(this_opt, "fpdither:", 9)) { | 1784 | } else if (!strncmp(this_opt, "fpdither:", 9)) { |
1731 | fpdither = simple_strtol(this_opt+9, NULL, 0); | 1785 | fpdither = simple_strtol(this_opt+9, NULL, 0); |
1786 | } else if (!strncmp(this_opt, "bpp:", 4)) { | ||
1787 | bpp = simple_strtoul(this_opt+4, NULL, 0); | ||
1732 | } else | 1788 | } else |
1733 | mode_option = this_opt; | 1789 | mode_option = this_opt; |
1734 | } | 1790 | } |
@@ -1804,6 +1860,11 @@ module_param(vram, int, 0); | |||
1804 | MODULE_PARM_DESC(vram, | 1860 | MODULE_PARM_DESC(vram, |
1805 | "amount of framebuffer memory to remap in MiB" | 1861 | "amount of framebuffer memory to remap in MiB" |
1806 | "(default=0 - remap entire memory)"); | 1862 | "(default=0 - remap entire memory)"); |
1863 | module_param(mode_option, charp, 0); | ||
1864 | MODULE_PARM_DESC(mode_option, "Specify initial video mode"); | ||
1865 | module_param(bpp, int, 0); | ||
1866 | MODULE_PARM_DESC(bpp, "pixel width in bits" | ||
1867 | "(default=8)"); | ||
1807 | #ifdef CONFIG_MTRR | 1868 | #ifdef CONFIG_MTRR |
1808 | module_param(nomtrr, bool, 0); | 1869 | module_param(nomtrr, bool, 0); |
1809 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " | 1870 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 0277ce031e5e..5fe197943deb 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -91,6 +91,7 @@ struct pm2fb_par | |||
91 | u32 mem_config; /* MemConfig reg at probe */ | 91 | u32 mem_config; /* MemConfig reg at probe */ |
92 | u32 mem_control; /* MemControl reg at probe */ | 92 | u32 mem_control; /* MemControl reg at probe */ |
93 | u32 boot_address; /* BootAddress reg at probe */ | 93 | u32 boot_address; /* BootAddress reg at probe */ |
94 | u32 palette[16]; | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | /* | 97 | /* |
@@ -674,7 +675,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
674 | */ | 675 | */ |
675 | static int pm2fb_set_par(struct fb_info *info) | 676 | static int pm2fb_set_par(struct fb_info *info) |
676 | { | 677 | { |
677 | struct pm2fb_par *par = (struct pm2fb_par *) info->par; | 678 | struct pm2fb_par *par = info->par; |
678 | u32 pixclock; | 679 | u32 pixclock; |
679 | u32 width, height, depth; | 680 | u32 width, height, depth; |
680 | u32 hsstart, hsend, hbend, htotal; | 681 | u32 hsstart, hsend, hbend, htotal; |
@@ -854,7 +855,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
854 | unsigned blue, unsigned transp, | 855 | unsigned blue, unsigned transp, |
855 | struct fb_info *info) | 856 | struct fb_info *info) |
856 | { | 857 | { |
857 | struct pm2fb_par *par = (struct pm2fb_par *) info->par; | 858 | struct pm2fb_par *par = info->par; |
858 | 859 | ||
859 | if (regno >= info->cmap.len) /* no. of hw registers */ | 860 | if (regno >= info->cmap.len) /* no. of hw registers */ |
860 | return 1; | 861 | return 1; |
@@ -929,7 +930,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
929 | case 16: | 930 | case 16: |
930 | case 24: | 931 | case 24: |
931 | case 32: | 932 | case 32: |
932 | ((u32*)(info->pseudo_palette))[regno] = v; | 933 | par->palette[regno] = v; |
933 | break; | 934 | break; |
934 | } | 935 | } |
935 | return 0; | 936 | return 0; |
@@ -955,7 +956,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
955 | static int pm2fb_pan_display(struct fb_var_screeninfo *var, | 956 | static int pm2fb_pan_display(struct fb_var_screeninfo *var, |
956 | struct fb_info *info) | 957 | struct fb_info *info) |
957 | { | 958 | { |
958 | struct pm2fb_par *p = (struct pm2fb_par *) info->par; | 959 | struct pm2fb_par *p = info->par; |
959 | u32 base; | 960 | u32 base; |
960 | u32 depth; | 961 | u32 depth; |
961 | u32 xres; | 962 | u32 xres; |
@@ -987,7 +988,7 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var, | |||
987 | */ | 988 | */ |
988 | static int pm2fb_blank(int blank_mode, struct fb_info *info) | 989 | static int pm2fb_blank(int blank_mode, struct fb_info *info) |
989 | { | 990 | { |
990 | struct pm2fb_par *par = (struct pm2fb_par *) info->par; | 991 | struct pm2fb_par *par = info->par; |
991 | u32 video = par->video; | 992 | u32 video = par->video; |
992 | 993 | ||
993 | DPRINTK("blank_mode %d\n", blank_mode); | 994 | DPRINTK("blank_mode %d\n", blank_mode); |
@@ -1054,8 +1055,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1054 | { | 1055 | { |
1055 | struct pm2fb_par *default_par; | 1056 | struct pm2fb_par *default_par; |
1056 | struct fb_info *info; | 1057 | struct fb_info *info; |
1057 | int size, err; | 1058 | int err, err_retval = -ENXIO; |
1058 | int err_retval = -ENXIO; | ||
1059 | 1059 | ||
1060 | err = pci_enable_device(pdev); | 1060 | err = pci_enable_device(pdev); |
1061 | if ( err ) { | 1061 | if ( err ) { |
@@ -1063,11 +1063,10 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1063 | return err; | 1063 | return err; |
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | size = sizeof(struct pm2fb_par) + 256 * sizeof(u32); | 1066 | info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); |
1067 | info = framebuffer_alloc(size, &pdev->dev); | ||
1068 | if ( !info ) | 1067 | if ( !info ) |
1069 | return -ENOMEM; | 1068 | return -ENOMEM; |
1070 | default_par = (struct pm2fb_par *) info->par; | 1069 | default_par = info->par; |
1071 | 1070 | ||
1072 | switch (pdev->device) { | 1071 | switch (pdev->device) { |
1073 | case PCI_DEVICE_ID_TI_TVP4020: | 1072 | case PCI_DEVICE_ID_TI_TVP4020: |
@@ -1171,7 +1170,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1171 | 1170 | ||
1172 | info->fbops = &pm2fb_ops; | 1171 | info->fbops = &pm2fb_ops; |
1173 | info->fix = pm2fb_fix; | 1172 | info->fix = pm2fb_fix; |
1174 | info->pseudo_palette = (void *)(default_par + 1); | 1173 | info->pseudo_palette = default_par->palette; |
1175 | info->flags = FBINFO_DEFAULT | | 1174 | info->flags = FBINFO_DEFAULT | |
1176 | FBINFO_HWACCEL_YPAN; | 1175 | FBINFO_HWACCEL_YPAN; |
1177 | 1176 | ||
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 3e9f96e9237d..6c19ab6afb01 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -630,7 +630,7 @@ static void riva_load_video_mode(struct fb_info *info) | |||
630 | int bpp, width, hDisplaySize, hDisplay, hStart, | 630 | int bpp, width, hDisplaySize, hDisplay, hStart, |
631 | hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock; | 631 | hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock; |
632 | int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd; | 632 | int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd; |
633 | struct riva_par *par = (struct riva_par *) info->par; | 633 | struct riva_par *par = info->par; |
634 | struct riva_regs newmode; | 634 | struct riva_regs newmode; |
635 | 635 | ||
636 | NVTRACE_ENTER(); | 636 | NVTRACE_ENTER(); |
@@ -925,7 +925,7 @@ riva_set_rop_solid(struct riva_par *par, int rop) | |||
925 | 925 | ||
926 | static void riva_setup_accel(struct fb_info *info) | 926 | static void riva_setup_accel(struct fb_info *info) |
927 | { | 927 | { |
928 | struct riva_par *par = (struct riva_par *) info->par; | 928 | struct riva_par *par = info->par; |
929 | 929 | ||
930 | RIVA_FIFO_FREE(par->riva, Clip, 2); | 930 | RIVA_FIFO_FREE(par->riva, Clip, 2); |
931 | NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0); | 931 | NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0); |
@@ -979,7 +979,7 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var) | |||
979 | #ifdef CONFIG_PMAC_BACKLIGHT | 979 | #ifdef CONFIG_PMAC_BACKLIGHT |
980 | static int riva_set_backlight_enable(int on, int level, void *data) | 980 | static int riva_set_backlight_enable(int on, int level, void *data) |
981 | { | 981 | { |
982 | struct riva_par *par = (struct riva_par *)data; | 982 | struct riva_par *par = data; |
983 | U032 tmp_pcrt, tmp_pmc; | 983 | U032 tmp_pcrt, tmp_pmc; |
984 | 984 | ||
985 | tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; | 985 | tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; |
@@ -1008,7 +1008,7 @@ static int riva_set_backlight_level(int level, void *data) | |||
1008 | 1008 | ||
1009 | static int rivafb_open(struct fb_info *info, int user) | 1009 | static int rivafb_open(struct fb_info *info, int user) |
1010 | { | 1010 | { |
1011 | struct riva_par *par = (struct riva_par *) info->par; | 1011 | struct riva_par *par = info->par; |
1012 | int cnt = atomic_read(&par->ref_count); | 1012 | int cnt = atomic_read(&par->ref_count); |
1013 | 1013 | ||
1014 | NVTRACE_ENTER(); | 1014 | NVTRACE_ENTER(); |
@@ -1034,7 +1034,7 @@ static int rivafb_open(struct fb_info *info, int user) | |||
1034 | 1034 | ||
1035 | static int rivafb_release(struct fb_info *info, int user) | 1035 | static int rivafb_release(struct fb_info *info, int user) |
1036 | { | 1036 | { |
1037 | struct riva_par *par = (struct riva_par *) info->par; | 1037 | struct riva_par *par = info->par; |
1038 | int cnt = atomic_read(&par->ref_count); | 1038 | int cnt = atomic_read(&par->ref_count); |
1039 | 1039 | ||
1040 | NVTRACE_ENTER(); | 1040 | NVTRACE_ENTER(); |
@@ -1057,7 +1057,7 @@ static int rivafb_release(struct fb_info *info, int user) | |||
1057 | static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 1057 | static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
1058 | { | 1058 | { |
1059 | struct fb_videomode *mode; | 1059 | struct fb_videomode *mode; |
1060 | struct riva_par *par = (struct riva_par *) info->par; | 1060 | struct riva_par *par = info->par; |
1061 | int nom, den; /* translating from pixels->bytes */ | 1061 | int nom, den; /* translating from pixels->bytes */ |
1062 | int mode_valid = 0; | 1062 | int mode_valid = 0; |
1063 | 1063 | ||
@@ -1166,7 +1166,7 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
1166 | 1166 | ||
1167 | static int rivafb_set_par(struct fb_info *info) | 1167 | static int rivafb_set_par(struct fb_info *info) |
1168 | { | 1168 | { |
1169 | struct riva_par *par = (struct riva_par *) info->par; | 1169 | struct riva_par *par = info->par; |
1170 | 1170 | ||
1171 | NVTRACE_ENTER(); | 1171 | NVTRACE_ENTER(); |
1172 | /* vgaHWunlock() + riva unlock (0x7F) */ | 1172 | /* vgaHWunlock() + riva unlock (0x7F) */ |
@@ -1205,43 +1205,19 @@ static int rivafb_set_par(struct fb_info *info) | |||
1205 | static int rivafb_pan_display(struct fb_var_screeninfo *var, | 1205 | static int rivafb_pan_display(struct fb_var_screeninfo *var, |
1206 | struct fb_info *info) | 1206 | struct fb_info *info) |
1207 | { | 1207 | { |
1208 | struct riva_par *par = (struct riva_par *)info->par; | 1208 | struct riva_par *par = info->par; |
1209 | unsigned int base; | 1209 | unsigned int base; |
1210 | 1210 | ||
1211 | NVTRACE_ENTER(); | 1211 | NVTRACE_ENTER(); |
1212 | if (var->xoffset > (var->xres_virtual - var->xres)) | ||
1213 | return -EINVAL; | ||
1214 | if (var->yoffset > (var->yres_virtual - var->yres)) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | if (var->vmode & FB_VMODE_YWRAP) { | ||
1218 | if (var->yoffset < 0 | ||
1219 | || var->yoffset >= info->var.yres_virtual | ||
1220 | || var->xoffset) return -EINVAL; | ||
1221 | } else { | ||
1222 | if (var->xoffset + info->var.xres > info->var.xres_virtual || | ||
1223 | var->yoffset + info->var.yres > info->var.yres_virtual) | ||
1224 | return -EINVAL; | ||
1225 | } | ||
1226 | |||
1227 | base = var->yoffset * info->fix.line_length + var->xoffset; | 1212 | base = var->yoffset * info->fix.line_length + var->xoffset; |
1228 | |||
1229 | par->riva.SetStartAddress(&par->riva, base); | 1213 | par->riva.SetStartAddress(&par->riva, base); |
1230 | |||
1231 | info->var.xoffset = var->xoffset; | ||
1232 | info->var.yoffset = var->yoffset; | ||
1233 | |||
1234 | if (var->vmode & FB_VMODE_YWRAP) | ||
1235 | info->var.vmode |= FB_VMODE_YWRAP; | ||
1236 | else | ||
1237 | info->var.vmode &= ~FB_VMODE_YWRAP; | ||
1238 | NVTRACE_LEAVE(); | 1214 | NVTRACE_LEAVE(); |
1239 | return 0; | 1215 | return 0; |
1240 | } | 1216 | } |
1241 | 1217 | ||
1242 | static int rivafb_blank(int blank, struct fb_info *info) | 1218 | static int rivafb_blank(int blank, struct fb_info *info) |
1243 | { | 1219 | { |
1244 | struct riva_par *par= (struct riva_par *)info->par; | 1220 | struct riva_par *par= info->par; |
1245 | unsigned char tmp, vesa; | 1221 | unsigned char tmp, vesa; |
1246 | 1222 | ||
1247 | tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */ | 1223 | tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */ |
@@ -1304,7 +1280,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1304 | unsigned blue, unsigned transp, | 1280 | unsigned blue, unsigned transp, |
1305 | struct fb_info *info) | 1281 | struct fb_info *info) |
1306 | { | 1282 | { |
1307 | struct riva_par *par = (struct riva_par *)info->par; | 1283 | struct riva_par *par = info->par; |
1308 | RIVA_HW_INST *chip = &par->riva; | 1284 | RIVA_HW_INST *chip = &par->riva; |
1309 | int i; | 1285 | int i; |
1310 | 1286 | ||
@@ -1393,7 +1369,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1393 | */ | 1369 | */ |
1394 | static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 1370 | static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
1395 | { | 1371 | { |
1396 | struct riva_par *par = (struct riva_par *) info->par; | 1372 | struct riva_par *par = info->par; |
1397 | u_int color, rop = 0; | 1373 | u_int color, rop = 0; |
1398 | 1374 | ||
1399 | if ((info->flags & FBINFO_HWACCEL_DISABLED)) { | 1375 | if ((info->flags & FBINFO_HWACCEL_DISABLED)) { |
@@ -1449,7 +1425,7 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect | |||
1449 | */ | 1425 | */ |
1450 | static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 1426 | static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
1451 | { | 1427 | { |
1452 | struct riva_par *par = (struct riva_par *) info->par; | 1428 | struct riva_par *par = info->par; |
1453 | 1429 | ||
1454 | if ((info->flags & FBINFO_HWACCEL_DISABLED)) { | 1430 | if ((info->flags & FBINFO_HWACCEL_DISABLED)) { |
1455 | cfb_copyarea(info, region); | 1431 | cfb_copyarea(info, region); |
@@ -1495,7 +1471,7 @@ static inline void convert_bgcolor_16(u32 *col) | |||
1495 | static void rivafb_imageblit(struct fb_info *info, | 1471 | static void rivafb_imageblit(struct fb_info *info, |
1496 | const struct fb_image *image) | 1472 | const struct fb_image *image) |
1497 | { | 1473 | { |
1498 | struct riva_par *par = (struct riva_par *) info->par; | 1474 | struct riva_par *par = info->par; |
1499 | u32 fgx = 0, bgx = 0, width, tmp; | 1475 | u32 fgx = 0, bgx = 0, width, tmp; |
1500 | u8 *cdat = (u8 *) image->data; | 1476 | u8 *cdat = (u8 *) image->data; |
1501 | volatile u32 __iomem *d; | 1477 | volatile u32 __iomem *d; |
@@ -1580,7 +1556,7 @@ static void rivafb_imageblit(struct fb_info *info, | |||
1580 | */ | 1556 | */ |
1581 | static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1557 | static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1582 | { | 1558 | { |
1583 | struct riva_par *par = (struct riva_par *) info->par; | 1559 | struct riva_par *par = info->par; |
1584 | u8 data[MAX_CURS * MAX_CURS/8]; | 1560 | u8 data[MAX_CURS * MAX_CURS/8]; |
1585 | int i, set = cursor->set; | 1561 | int i, set = cursor->set; |
1586 | u16 fg, bg; | 1562 | u16 fg, bg; |
@@ -1664,7 +1640,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1664 | 1640 | ||
1665 | static int rivafb_sync(struct fb_info *info) | 1641 | static int rivafb_sync(struct fb_info *info) |
1666 | { | 1642 | { |
1667 | struct riva_par *par = (struct riva_par *)info->par; | 1643 | struct riva_par *par = info->par; |
1668 | 1644 | ||
1669 | wait_for_idle(par); | 1645 | wait_for_idle(par); |
1670 | return 0; | 1646 | return 0; |
@@ -1696,7 +1672,7 @@ static struct fb_ops riva_fb_ops = { | |||
1696 | static int __devinit riva_set_fbinfo(struct fb_info *info) | 1672 | static int __devinit riva_set_fbinfo(struct fb_info *info) |
1697 | { | 1673 | { |
1698 | unsigned int cmap_len; | 1674 | unsigned int cmap_len; |
1699 | struct riva_par *par = (struct riva_par *) info->par; | 1675 | struct riva_par *par = info->par; |
1700 | 1676 | ||
1701 | NVTRACE_ENTER(); | 1677 | NVTRACE_ENTER(); |
1702 | info->flags = FBINFO_DEFAULT | 1678 | info->flags = FBINFO_DEFAULT |
@@ -1733,7 +1709,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info) | |||
1733 | #ifdef CONFIG_PPC_OF | 1709 | #ifdef CONFIG_PPC_OF |
1734 | static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) | 1710 | static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) |
1735 | { | 1711 | { |
1736 | struct riva_par *par = (struct riva_par *) info->par; | 1712 | struct riva_par *par = info->par; |
1737 | struct device_node *dp; | 1713 | struct device_node *dp; |
1738 | unsigned char *pedid = NULL; | 1714 | unsigned char *pedid = NULL; |
1739 | unsigned char *disptype = NULL; | 1715 | unsigned char *disptype = NULL; |
@@ -1767,7 +1743,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) | |||
1767 | #if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF) | 1743 | #if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF) |
1768 | static int __devinit riva_get_EDID_i2c(struct fb_info *info) | 1744 | static int __devinit riva_get_EDID_i2c(struct fb_info *info) |
1769 | { | 1745 | { |
1770 | struct riva_par *par = (struct riva_par *) info->par; | 1746 | struct riva_par *par = info->par; |
1771 | struct fb_var_screeninfo var; | 1747 | struct fb_var_screeninfo var; |
1772 | int i; | 1748 | int i; |
1773 | 1749 | ||
@@ -1837,7 +1813,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev) | |||
1837 | static void __devinit riva_get_edidinfo(struct fb_info *info) | 1813 | static void __devinit riva_get_edidinfo(struct fb_info *info) |
1838 | { | 1814 | { |
1839 | struct fb_var_screeninfo *var = &rivafb_default_var; | 1815 | struct fb_var_screeninfo *var = &rivafb_default_var; |
1840 | struct riva_par *par = (struct riva_par *) info->par; | 1816 | struct riva_par *par = info->par; |
1841 | 1817 | ||
1842 | fb_edid_to_monspecs(par->EDID, &info->monspecs); | 1818 | fb_edid_to_monspecs(par->EDID, &info->monspecs); |
1843 | fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len, | 1819 | fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len, |
@@ -1909,7 +1885,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd, | |||
1909 | ret = -ENOMEM; | 1885 | ret = -ENOMEM; |
1910 | goto err_ret; | 1886 | goto err_ret; |
1911 | } | 1887 | } |
1912 | default_par = (struct riva_par *) info->par; | 1888 | default_par = info->par; |
1913 | default_par->pdev = pd; | 1889 | default_par->pdev = pd; |
1914 | 1890 | ||
1915 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); | 1891 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); |
@@ -2070,7 +2046,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd, | |||
2070 | 2046 | ||
2071 | err_iounmap_screen_base: | 2047 | err_iounmap_screen_base: |
2072 | #ifdef CONFIG_FB_RIVA_I2C | 2048 | #ifdef CONFIG_FB_RIVA_I2C |
2073 | riva_delete_i2c_busses((struct riva_par *) info->par); | 2049 | riva_delete_i2c_busses(info->par); |
2074 | #endif | 2050 | #endif |
2075 | iounmap(info->screen_base); | 2051 | iounmap(info->screen_base); |
2076 | err_iounmap_pramin: | 2052 | err_iounmap_pramin: |
@@ -2093,7 +2069,7 @@ err_ret: | |||
2093 | static void __exit rivafb_remove(struct pci_dev *pd) | 2069 | static void __exit rivafb_remove(struct pci_dev *pd) |
2094 | { | 2070 | { |
2095 | struct fb_info *info = pci_get_drvdata(pd); | 2071 | struct fb_info *info = pci_get_drvdata(pd); |
2096 | struct riva_par *par = (struct riva_par *) info->par; | 2072 | struct riva_par *par = info->par; |
2097 | 2073 | ||
2098 | NVTRACE_ENTER(); | 2074 | NVTRACE_ENTER(); |
2099 | if (!info) | 2075 | if (!info) |
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 77151d8e0766..8b1967fc116a 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static void riva_gpio_setscl(void* data, int state) | 31 | static void riva_gpio_setscl(void* data, int state) |
32 | { | 32 | { |
33 | struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; | 33 | struct riva_i2c_chan *chan = data; |
34 | struct riva_par *par = chan->par; | 34 | struct riva_par *par = chan->par; |
35 | u32 val; | 35 | u32 val; |
36 | 36 | ||
@@ -48,7 +48,7 @@ static void riva_gpio_setscl(void* data, int state) | |||
48 | 48 | ||
49 | static void riva_gpio_setsda(void* data, int state) | 49 | static void riva_gpio_setsda(void* data, int state) |
50 | { | 50 | { |
51 | struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; | 51 | struct riva_i2c_chan *chan = data; |
52 | struct riva_par *par = chan->par; | 52 | struct riva_par *par = chan->par; |
53 | u32 val; | 53 | u32 val; |
54 | 54 | ||
@@ -66,7 +66,7 @@ static void riva_gpio_setsda(void* data, int state) | |||
66 | 66 | ||
67 | static int riva_gpio_getscl(void* data) | 67 | static int riva_gpio_getscl(void* data) |
68 | { | 68 | { |
69 | struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; | 69 | struct riva_i2c_chan *chan = data; |
70 | struct riva_par *par = chan->par; | 70 | struct riva_par *par = chan->par; |
71 | u32 val = 0; | 71 | u32 val = 0; |
72 | 72 | ||
@@ -81,7 +81,7 @@ static int riva_gpio_getscl(void* data) | |||
81 | 81 | ||
82 | static int riva_gpio_getsda(void* data) | 82 | static int riva_gpio_getsda(void* data) |
83 | { | 83 | { |
84 | struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; | 84 | struct riva_i2c_chan *chan = data; |
85 | struct riva_par *par = chan->par; | 85 | struct riva_par *par = chan->par; |
86 | u32 val = 0; | 86 | u32 val = 0; |
87 | 87 | ||
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index fe99d17a21d7..d574dd3c9c8a 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -552,7 +552,7 @@ static inline void modify_gpio(void __iomem *reg, | |||
552 | * s3c2410fb_init_registers - Initialise all LCD-related registers | 552 | * s3c2410fb_init_registers - Initialise all LCD-related registers |
553 | */ | 553 | */ |
554 | 554 | ||
555 | int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) | 555 | static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) |
556 | { | 556 | { |
557 | unsigned long flags; | 557 | unsigned long flags; |
558 | 558 | ||
@@ -634,7 +634,7 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r) | |||
634 | 634 | ||
635 | static char driver_name[]="s3c2410fb"; | 635 | static char driver_name[]="s3c2410fb"; |
636 | 636 | ||
637 | int __init s3c2410fb_probe(struct platform_device *pdev) | 637 | static int __init s3c2410fb_probe(struct platform_device *pdev) |
638 | { | 638 | { |
639 | struct s3c2410fb_info *info; | 639 | struct s3c2410fb_info *info; |
640 | struct fb_info *fbinfo; | 640 | struct fb_info *fbinfo; |
@@ -667,8 +667,6 @@ int __init s3c2410fb_probe(struct platform_device *pdev) | |||
667 | info->fb = fbinfo; | 667 | info->fb = fbinfo; |
668 | platform_set_drvdata(pdev, fbinfo); | 668 | platform_set_drvdata(pdev, fbinfo); |
669 | 669 | ||
670 | s3c2410fb_init_registers(info); | ||
671 | |||
672 | dprintk("devinit\n"); | 670 | dprintk("devinit\n"); |
673 | 671 | ||
674 | strcpy(fbinfo->fix.id, driver_name); | 672 | strcpy(fbinfo->fix.id, driver_name); |
@@ -701,8 +699,8 @@ int __init s3c2410fb_probe(struct platform_device *pdev) | |||
701 | fbinfo->var.yres_virtual = mach_info->yres.defval; | 699 | fbinfo->var.yres_virtual = mach_info->yres.defval; |
702 | fbinfo->var.bits_per_pixel = mach_info->bpp.defval; | 700 | fbinfo->var.bits_per_pixel = mach_info->bpp.defval; |
703 | 701 | ||
704 | fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) +1; | 702 | fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; |
705 | fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) +1; | 703 | fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1; |
706 | fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; | 704 | fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; |
707 | 705 | ||
708 | fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1; | 706 | fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1; |
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 3c98457783c4..00719a91479f 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | static void savage4_gpio_setscl(void *data, int val) | 50 | static void savage4_gpio_setscl(void *data, int val) |
51 | { | 51 | { |
52 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 52 | struct savagefb_i2c_chan *chan = data; |
53 | unsigned int r; | 53 | unsigned int r; |
54 | 54 | ||
55 | r = readl(chan->ioaddr + chan->reg); | 55 | r = readl(chan->ioaddr + chan->reg); |
@@ -63,7 +63,7 @@ static void savage4_gpio_setscl(void *data, int val) | |||
63 | 63 | ||
64 | static void savage4_gpio_setsda(void *data, int val) | 64 | static void savage4_gpio_setsda(void *data, int val) |
65 | { | 65 | { |
66 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 66 | struct savagefb_i2c_chan *chan = data; |
67 | 67 | ||
68 | unsigned int r; | 68 | unsigned int r; |
69 | r = readl(chan->ioaddr + chan->reg); | 69 | r = readl(chan->ioaddr + chan->reg); |
@@ -77,21 +77,21 @@ static void savage4_gpio_setsda(void *data, int val) | |||
77 | 77 | ||
78 | static int savage4_gpio_getscl(void *data) | 78 | static int savage4_gpio_getscl(void *data) |
79 | { | 79 | { |
80 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 80 | struct savagefb_i2c_chan *chan = data; |
81 | 81 | ||
82 | return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SCL_IN)); | 82 | return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SCL_IN)); |
83 | } | 83 | } |
84 | 84 | ||
85 | static int savage4_gpio_getsda(void *data) | 85 | static int savage4_gpio_getsda(void *data) |
86 | { | 86 | { |
87 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 87 | struct savagefb_i2c_chan *chan = data; |
88 | 88 | ||
89 | return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SDA_IN)); | 89 | return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SDA_IN)); |
90 | } | 90 | } |
91 | 91 | ||
92 | static void prosavage_gpio_setscl(void* data, int val) | 92 | static void prosavage_gpio_setscl(void* data, int val) |
93 | { | 93 | { |
94 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 94 | struct savagefb_i2c_chan *chan = data; |
95 | u32 r; | 95 | u32 r; |
96 | 96 | ||
97 | SET_CR_IX(chan->ioaddr, chan->reg); | 97 | SET_CR_IX(chan->ioaddr, chan->reg); |
@@ -107,7 +107,7 @@ static void prosavage_gpio_setscl(void* data, int val) | |||
107 | 107 | ||
108 | static void prosavage_gpio_setsda(void* data, int val) | 108 | static void prosavage_gpio_setsda(void* data, int val) |
109 | { | 109 | { |
110 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 110 | struct savagefb_i2c_chan *chan = data; |
111 | unsigned int r; | 111 | unsigned int r; |
112 | 112 | ||
113 | SET_CR_IX(chan->ioaddr, chan->reg); | 113 | SET_CR_IX(chan->ioaddr, chan->reg); |
@@ -123,7 +123,7 @@ static void prosavage_gpio_setsda(void* data, int val) | |||
123 | 123 | ||
124 | static int prosavage_gpio_getscl(void* data) | 124 | static int prosavage_gpio_getscl(void* data) |
125 | { | 125 | { |
126 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 126 | struct savagefb_i2c_chan *chan = data; |
127 | 127 | ||
128 | SET_CR_IX(chan->ioaddr, chan->reg); | 128 | SET_CR_IX(chan->ioaddr, chan->reg); |
129 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN)); | 129 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN)); |
@@ -131,7 +131,7 @@ static int prosavage_gpio_getscl(void* data) | |||
131 | 131 | ||
132 | static int prosavage_gpio_getsda(void* data) | 132 | static int prosavage_gpio_getsda(void* data) |
133 | { | 133 | { |
134 | struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; | 134 | struct savagefb_i2c_chan *chan = data; |
135 | 135 | ||
136 | SET_CR_IX(chan->ioaddr, chan->reg); | 136 | SET_CR_IX(chan->ioaddr, chan->reg); |
137 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN)); | 137 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN)); |
@@ -140,10 +140,9 @@ static int prosavage_gpio_getsda(void* data) | |||
140 | static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, | 140 | static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, |
141 | const char *name) | 141 | const char *name) |
142 | { | 142 | { |
143 | int (*add_bus)(struct i2c_adapter *) = symbol_get(i2c_bit_add_bus); | ||
144 | int rc = 0; | 143 | int rc = 0; |
145 | 144 | ||
146 | if (add_bus && chan->par) { | 145 | if (chan->par) { |
147 | strcpy(chan->adapter.name, name); | 146 | strcpy(chan->adapter.name, name); |
148 | chan->adapter.owner = THIS_MODULE; | 147 | chan->adapter.owner = THIS_MODULE; |
149 | chan->adapter.id = I2C_HW_B_SAVAGE; | 148 | chan->adapter.id = I2C_HW_B_SAVAGE; |
@@ -161,7 +160,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, | |||
161 | chan->algo.setscl(chan, 1); | 160 | chan->algo.setscl(chan, 1); |
162 | udelay(20); | 161 | udelay(20); |
163 | 162 | ||
164 | rc = add_bus(&chan->adapter); | 163 | rc = i2c_bit_add_bus(&chan->adapter); |
165 | 164 | ||
166 | if (rc == 0) | 165 | if (rc == 0) |
167 | dev_dbg(&chan->par->pcidev->dev, | 166 | dev_dbg(&chan->par->pcidev->dev, |
@@ -169,8 +168,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, | |||
169 | else | 168 | else |
170 | dev_warn(&chan->par->pcidev->dev, | 169 | dev_warn(&chan->par->pcidev->dev, |
171 | "Failed to register I2C bus %s.\n", name); | 170 | "Failed to register I2C bus %s.\n", name); |
172 | |||
173 | symbol_put(i2c_bit_add_bus); | ||
174 | } else | 171 | } else |
175 | chan->par = NULL; | 172 | chan->par = NULL; |
176 | 173 | ||
@@ -179,7 +176,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, | |||
179 | 176 | ||
180 | void savagefb_create_i2c_busses(struct fb_info *info) | 177 | void savagefb_create_i2c_busses(struct fb_info *info) |
181 | { | 178 | { |
182 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 179 | struct savagefb_par *par = info->par; |
183 | par->chan.par = par; | 180 | par->chan.par = par; |
184 | 181 | ||
185 | switch(info->fix.accel) { | 182 | switch(info->fix.accel) { |
@@ -193,6 +190,7 @@ void savagefb_create_i2c_busses(struct fb_info *info) | |||
193 | par->chan.algo.getscl = prosavage_gpio_getscl; | 190 | par->chan.algo.getscl = prosavage_gpio_getscl; |
194 | break; | 191 | break; |
195 | case FB_ACCEL_SAVAGE4: | 192 | case FB_ACCEL_SAVAGE4: |
193 | case FB_ACCEL_SAVAGE2000: | ||
196 | par->chan.reg = 0xff20; | 194 | par->chan.reg = 0xff20; |
197 | par->chan.ioaddr = par->mmio.vbase; | 195 | par->chan.ioaddr = par->mmio.vbase; |
198 | par->chan.algo.setsda = savage4_gpio_setsda; | 196 | par->chan.algo.setsda = savage4_gpio_setsda; |
@@ -209,14 +207,10 @@ void savagefb_create_i2c_busses(struct fb_info *info) | |||
209 | 207 | ||
210 | void savagefb_delete_i2c_busses(struct fb_info *info) | 208 | void savagefb_delete_i2c_busses(struct fb_info *info) |
211 | { | 209 | { |
212 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 210 | struct savagefb_par *par = info->par; |
213 | int (*del_bus)(struct i2c_adapter *) = | ||
214 | symbol_get(i2c_bit_del_bus); | ||
215 | 211 | ||
216 | if (del_bus && par->chan.par) { | 212 | if (par->chan.par) |
217 | del_bus(&par->chan.adapter); | 213 | i2c_bit_del_bus(&par->chan.adapter); |
218 | symbol_put(i2c_bit_del_bus); | ||
219 | } | ||
220 | 214 | ||
221 | par->chan.par = NULL; | 215 | par->chan.par = NULL; |
222 | } | 216 | } |
@@ -224,8 +218,6 @@ void savagefb_delete_i2c_busses(struct fb_info *info) | |||
224 | static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) | 218 | static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) |
225 | { | 219 | { |
226 | u8 start = 0x0; | 220 | u8 start = 0x0; |
227 | int (*transfer)(struct i2c_adapter *, struct i2c_msg *, int) = | ||
228 | symbol_get(i2c_transfer); | ||
229 | struct i2c_msg msgs[] = { | 221 | struct i2c_msg msgs[] = { |
230 | { | 222 | { |
231 | .addr = SAVAGE_DDC, | 223 | .addr = SAVAGE_DDC, |
@@ -239,21 +231,19 @@ static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) | |||
239 | }; | 231 | }; |
240 | u8 *buf = NULL; | 232 | u8 *buf = NULL; |
241 | 233 | ||
242 | if (transfer && chan->par) { | 234 | if (chan->par) { |
243 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | 235 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); |
244 | 236 | ||
245 | if (buf) { | 237 | if (buf) { |
246 | msgs[1].buf = buf; | 238 | msgs[1].buf = buf; |
247 | 239 | ||
248 | if (transfer(&chan->adapter, msgs, 2) != 2) { | 240 | if (i2c_transfer(&chan->adapter, msgs, 2) != 2) { |
249 | dev_dbg(&chan->par->pcidev->dev, | 241 | dev_dbg(&chan->par->pcidev->dev, |
250 | "Unable to read EDID block.\n"); | 242 | "Unable to read EDID block.\n"); |
251 | kfree(buf); | 243 | kfree(buf); |
252 | buf = NULL; | 244 | buf = NULL; |
253 | } | 245 | } |
254 | } | 246 | } |
255 | |||
256 | symbol_put(i2c_transfer); | ||
257 | } | 247 | } |
258 | 248 | ||
259 | return buf; | 249 | return buf; |
diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/savage/savagefb_accel.c index bac8ea3a0108..bbcc055d3bb7 100644 --- a/drivers/video/savage/savagefb_accel.c +++ b/drivers/video/savage/savagefb_accel.c | |||
@@ -21,7 +21,7 @@ static u32 savagefb_rop[] = { | |||
21 | 21 | ||
22 | int savagefb_sync(struct fb_info *info) | 22 | int savagefb_sync(struct fb_info *info) |
23 | { | 23 | { |
24 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 24 | struct savagefb_par *par = info->par; |
25 | 25 | ||
26 | par->SavageWaitIdle(par); | 26 | par->SavageWaitIdle(par); |
27 | return 0; | 27 | return 0; |
@@ -29,7 +29,7 @@ int savagefb_sync(struct fb_info *info) | |||
29 | 29 | ||
30 | void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 30 | void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
31 | { | 31 | { |
32 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 32 | struct savagefb_par *par = info->par; |
33 | int sx = region->sx, dx = region->dx; | 33 | int sx = region->sx, dx = region->dx; |
34 | int sy = region->sy, dy = region->dy; | 34 | int sy = region->sy, dy = region->dy; |
35 | int cmd; | 35 | int cmd; |
@@ -63,7 +63,7 @@ void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
63 | 63 | ||
64 | void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 64 | void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
65 | { | 65 | { |
66 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 66 | struct savagefb_par *par = info->par; |
67 | int cmd, color; | 67 | int cmd, color; |
68 | 68 | ||
69 | if (!rect->width || !rect->height) | 69 | if (!rect->width || !rect->height) |
@@ -90,7 +90,7 @@ void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
90 | 90 | ||
91 | void savagefb_imageblit(struct fb_info *info, const struct fb_image *image) | 91 | void savagefb_imageblit(struct fb_info *info, const struct fb_image *image) |
92 | { | 92 | { |
93 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 93 | struct savagefb_par *par = info->par; |
94 | int fg, bg, size, i, width; | 94 | int fg, bg, size, i, width; |
95 | int cmd; | 95 | int cmd; |
96 | u32 *src = (u32 *) image->data; | 96 | u32 *src = (u32 *) image->data; |
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 09e2f2841901..ab727eaa7f43 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -686,7 +686,7 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode | |||
686 | static int savagefb_check_var (struct fb_var_screeninfo *var, | 686 | static int savagefb_check_var (struct fb_var_screeninfo *var, |
687 | struct fb_info *info) | 687 | struct fb_info *info) |
688 | { | 688 | { |
689 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 689 | struct savagefb_par *par = info->par; |
690 | int memlen, vramlen, mode_valid = 0; | 690 | int memlen, vramlen, mode_valid = 0; |
691 | 691 | ||
692 | DBG("savagefb_check_var"); | 692 | DBG("savagefb_check_var"); |
@@ -1025,7 +1025,7 @@ static int savagefb_setcolreg(unsigned regno, | |||
1025 | unsigned transp, | 1025 | unsigned transp, |
1026 | struct fb_info *info) | 1026 | struct fb_info *info) |
1027 | { | 1027 | { |
1028 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1028 | struct savagefb_par *par = info->par; |
1029 | 1029 | ||
1030 | if (regno >= NR_PALETTE) | 1030 | if (regno >= NR_PALETTE) |
1031 | return -EINVAL; | 1031 | return -EINVAL; |
@@ -1328,7 +1328,7 @@ static void savagefb_set_fix(struct fb_info *info) | |||
1328 | #if defined(CONFIG_FB_SAVAGE_ACCEL) | 1328 | #if defined(CONFIG_FB_SAVAGE_ACCEL) |
1329 | static void savagefb_set_clip(struct fb_info *info) | 1329 | static void savagefb_set_clip(struct fb_info *info) |
1330 | { | 1330 | { |
1331 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1331 | struct savagefb_par *par = info->par; |
1332 | int cmd; | 1332 | int cmd; |
1333 | 1333 | ||
1334 | cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; | 1334 | cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; |
@@ -1342,7 +1342,7 @@ static void savagefb_set_clip(struct fb_info *info) | |||
1342 | 1342 | ||
1343 | static int savagefb_set_par (struct fb_info *info) | 1343 | static int savagefb_set_par (struct fb_info *info) |
1344 | { | 1344 | { |
1345 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1345 | struct savagefb_par *par = info->par; |
1346 | struct fb_var_screeninfo *var = &info->var; | 1346 | struct fb_var_screeninfo *var = &info->var; |
1347 | int err; | 1347 | int err; |
1348 | 1348 | ||
@@ -1381,29 +1381,9 @@ static int savagefb_set_par (struct fb_info *info) | |||
1381 | static int savagefb_pan_display (struct fb_var_screeninfo *var, | 1381 | static int savagefb_pan_display (struct fb_var_screeninfo *var, |
1382 | struct fb_info *info) | 1382 | struct fb_info *info) |
1383 | { | 1383 | { |
1384 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1384 | struct savagefb_par *par = info->par; |
1385 | u_int y_bottom; | ||
1386 | |||
1387 | y_bottom = var->yoffset; | ||
1388 | |||
1389 | if (!(var->vmode & FB_VMODE_YWRAP)) | ||
1390 | y_bottom += var->yres; | ||
1391 | |||
1392 | if (var->xoffset > (var->xres_virtual - var->xres)) | ||
1393 | return -EINVAL; | ||
1394 | if (y_bottom > info->var.yres_virtual) | ||
1395 | return -EINVAL; | ||
1396 | 1385 | ||
1397 | savagefb_update_start (par, var); | 1386 | savagefb_update_start (par, var); |
1398 | |||
1399 | info->var.xoffset = var->xoffset; | ||
1400 | info->var.yoffset = var->yoffset; | ||
1401 | |||
1402 | if (var->vmode & FB_VMODE_YWRAP) | ||
1403 | info->var.vmode |= FB_VMODE_YWRAP; | ||
1404 | else | ||
1405 | info->var.vmode &= ~FB_VMODE_YWRAP; | ||
1406 | |||
1407 | return 0; | 1387 | return 0; |
1408 | } | 1388 | } |
1409 | 1389 | ||
@@ -1534,7 +1514,7 @@ static void savage_disable_mmio (struct savagefb_par *par) | |||
1534 | 1514 | ||
1535 | static int __devinit savage_map_mmio (struct fb_info *info) | 1515 | static int __devinit savage_map_mmio (struct fb_info *info) |
1536 | { | 1516 | { |
1537 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1517 | struct savagefb_par *par = info->par; |
1538 | DBG ("savage_map_mmio"); | 1518 | DBG ("savage_map_mmio"); |
1539 | 1519 | ||
1540 | if (S3_SAVAGE3D_SERIES (par->chip)) | 1520 | if (S3_SAVAGE3D_SERIES (par->chip)) |
@@ -1567,7 +1547,7 @@ static int __devinit savage_map_mmio (struct fb_info *info) | |||
1567 | 1547 | ||
1568 | static void __devinit savage_unmap_mmio (struct fb_info *info) | 1548 | static void __devinit savage_unmap_mmio (struct fb_info *info) |
1569 | { | 1549 | { |
1570 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1550 | struct savagefb_par *par = info->par; |
1571 | DBG ("savage_unmap_mmio"); | 1551 | DBG ("savage_unmap_mmio"); |
1572 | 1552 | ||
1573 | savage_disable_mmio(par); | 1553 | savage_disable_mmio(par); |
@@ -1581,7 +1561,7 @@ static void __devinit savage_unmap_mmio (struct fb_info *info) | |||
1581 | static int __devinit savage_map_video (struct fb_info *info, | 1561 | static int __devinit savage_map_video (struct fb_info *info, |
1582 | int video_len) | 1562 | int video_len) |
1583 | { | 1563 | { |
1584 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1564 | struct savagefb_par *par = info->par; |
1585 | int resource; | 1565 | int resource; |
1586 | 1566 | ||
1587 | DBG("savage_map_video"); | 1567 | DBG("savage_map_video"); |
@@ -1619,7 +1599,7 @@ static int __devinit savage_map_video (struct fb_info *info, | |||
1619 | 1599 | ||
1620 | static void __devinit savage_unmap_video (struct fb_info *info) | 1600 | static void __devinit savage_unmap_video (struct fb_info *info) |
1621 | { | 1601 | { |
1622 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1602 | struct savagefb_par *par = info->par; |
1623 | 1603 | ||
1624 | DBG("savage_unmap_video"); | 1604 | DBG("savage_unmap_video"); |
1625 | 1605 | ||
@@ -1869,7 +1849,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info, | |||
1869 | struct pci_dev *dev, | 1849 | struct pci_dev *dev, |
1870 | const struct pci_device_id *id) | 1850 | const struct pci_device_id *id) |
1871 | { | 1851 | { |
1872 | struct savagefb_par *par = (struct savagefb_par *)info->par; | 1852 | struct savagefb_par *par = info->par; |
1873 | int err = 0; | 1853 | int err = 0; |
1874 | 1854 | ||
1875 | par->pcidev = dev; | 1855 | par->pcidev = dev; |
@@ -2139,8 +2119,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev, | |||
2139 | 2119 | ||
2140 | static void __devexit savagefb_remove (struct pci_dev *dev) | 2120 | static void __devexit savagefb_remove (struct pci_dev *dev) |
2141 | { | 2121 | { |
2142 | struct fb_info *info = | 2122 | struct fb_info *info = pci_get_drvdata(dev); |
2143 | (struct fb_info *)pci_get_drvdata(dev); | ||
2144 | 2123 | ||
2145 | DBG("savagefb_remove"); | 2124 | DBG("savagefb_remove"); |
2146 | 2125 | ||
@@ -2174,9 +2153,8 @@ static void __devexit savagefb_remove (struct pci_dev *dev) | |||
2174 | 2153 | ||
2175 | static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) | 2154 | static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) |
2176 | { | 2155 | { |
2177 | struct fb_info *info = | 2156 | struct fb_info *info = pci_get_drvdata(dev); |
2178 | (struct fb_info *)pci_get_drvdata(dev); | 2157 | struct savagefb_par *par = info->par; |
2179 | struct savagefb_par *par = (struct savagefb_par *)info->par; | ||
2180 | 2158 | ||
2181 | DBG("savagefb_suspend"); | 2159 | DBG("savagefb_suspend"); |
2182 | 2160 | ||
@@ -2210,9 +2188,8 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) | |||
2210 | 2188 | ||
2211 | static int savagefb_resume (struct pci_dev* dev) | 2189 | static int savagefb_resume (struct pci_dev* dev) |
2212 | { | 2190 | { |
2213 | struct fb_info *info = | 2191 | struct fb_info *info = pci_get_drvdata(dev); |
2214 | (struct fb_info *)pci_get_drvdata(dev); | 2192 | struct savagefb_par *par = info->par; |
2215 | struct savagefb_par *par = (struct savagefb_par *)info->par; | ||
2216 | int cur_state = par->pm_state; | 2193 | int cur_state = par->pm_state; |
2217 | 2194 | ||
2218 | DBG("savage_resume"); | 2195 | DBG("savage_resume"); |
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index a01e7ecc15ed..9b707771d757 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c | |||
@@ -115,7 +115,8 @@ static struct fb_fix_screeninfo xxxfb_fix __initdata = { | |||
115 | /* | 115 | /* |
116 | * If your driver supports multiple boards or it supports multiple | 116 | * If your driver supports multiple boards or it supports multiple |
117 | * framebuffers, you should make these arrays, or allocate them | 117 | * framebuffers, you should make these arrays, or allocate them |
118 | * dynamically (using kmalloc()). | 118 | * dynamically using framebuffer_alloc() and free them with |
119 | * framebuffer_release(). | ||
119 | */ | 120 | */ |
120 | static struct fb_info info; | 121 | static struct fb_info info; |
121 | 122 | ||
@@ -179,18 +180,31 @@ static int xxxfb_release(const struct fb_info *info, int user) | |||
179 | * intent to only test a mode and not actually set it. The stuff in | 180 | * intent to only test a mode and not actually set it. The stuff in |
180 | * modedb.c is a example of this. If the var passed in is slightly | 181 | * modedb.c is a example of this. If the var passed in is slightly |
181 | * off by what the hardware can support then we alter the var PASSED in | 182 | * off by what the hardware can support then we alter the var PASSED in |
182 | * to what we can do. If the hardware doesn't support mode change | 183 | * to what we can do. |
183 | * a -EINVAL will be returned by the upper layers. You don't need to | 184 | * |
184 | * implement this function then. If you hardware doesn't support | 185 | * For values that are off, this function must round them _up_ to the |
185 | * changing the resolution then this function is not needed. In this | 186 | * next value that is supported by the hardware. If the value is |
186 | * case the driver woudl just provide a var that represents the static | 187 | * greater than the highest value supported by the hardware, then this |
187 | * state the screen is in. | 188 | * function must return -EINVAL. |
189 | * | ||
190 | * Exception to the above rule: Some drivers have a fixed mode, ie, | ||
191 | * the hardware is already set at boot up, and cannot be changed. In | ||
192 | * this case, it is more acceptable that this function just return | ||
193 | * a copy of the currently working var (info->var). Better is to not | ||
194 | * implement this function, as the upper layer will do the copying | ||
195 | * of the current var for you. | ||
196 | * | ||
197 | * Note: This is the only function where the contents of var can be | ||
198 | * freely adjusted after the driver has been registered. If you find | ||
199 | * that you have code outside of this function that alters the content | ||
200 | * of var, then you are doing something wrong. Note also that the | ||
201 | * contents of info->var must be left untouched at all times after | ||
202 | * driver registration. | ||
188 | * | 203 | * |
189 | * Returns negative errno on error, or zero on success. | 204 | * Returns negative errno on error, or zero on success. |
190 | */ | 205 | */ |
191 | static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 206 | static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
192 | { | 207 | { |
193 | const struct xxx_par *par = (const struct xxx_par *) info->par; | ||
194 | /* ... */ | 208 | /* ... */ |
195 | return 0; | 209 | return 0; |
196 | } | 210 | } |
@@ -204,14 +218,39 @@ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
204 | * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in | 218 | * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in |
205 | * fb_info since we are using that data. This means we depend on the | 219 | * fb_info since we are using that data. This means we depend on the |
206 | * data in var inside fb_info to be supported by the hardware. | 220 | * data in var inside fb_info to be supported by the hardware. |
207 | * xxxfb_check_var is always called before xxxfb_set_par to ensure this. | 221 | * |
222 | * This function is also used to recover/restore the hardware to a | ||
223 | * known working state. | ||
224 | * | ||
225 | * xxxfb_check_var is always called before xxxfb_set_par to ensure that | ||
226 | * the contents of var is always valid. | ||
227 | * | ||
208 | * Again if you can't change the resolution you don't need this function. | 228 | * Again if you can't change the resolution you don't need this function. |
209 | * | 229 | * |
230 | * However, even if your hardware does not support mode changing, | ||
231 | * a set_par might be needed to at least initialize the hardware to | ||
232 | * a known working state, especially if it came back from another | ||
233 | * process that also modifies the same hardware, such as X. | ||
234 | * | ||
235 | * If this is the case, a combination such as the following should work: | ||
236 | * | ||
237 | * static int xxxfb_check_var(struct fb_var_screeninfo *var, | ||
238 | * struct fb_info *info) | ||
239 | * { | ||
240 | * *var = info->var; | ||
241 | * return 0; | ||
242 | * } | ||
243 | * | ||
244 | * static int xxxfb_set_par(struct fb_info *info) | ||
245 | * { | ||
246 | * init your hardware here | ||
247 | * } | ||
248 | * | ||
210 | * Returns negative errno on error, or zero on success. | 249 | * Returns negative errno on error, or zero on success. |
211 | */ | 250 | */ |
212 | static int xxxfb_set_par(struct fb_info *info) | 251 | static int xxxfb_set_par(struct fb_info *info) |
213 | { | 252 | { |
214 | struct xxx_par *par = (struct xxx_par *) info->par; | 253 | struct xxx_par *par = info->par; |
215 | /* ... */ | 254 | /* ... */ |
216 | return 0; | 255 | return 0; |
217 | } | 256 | } |
@@ -258,70 +297,110 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
258 | * var->{color}.offset contains start of bitfield | 297 | * var->{color}.offset contains start of bitfield |
259 | * var->{color}.length contains length of bitfield | 298 | * var->{color}.length contains length of bitfield |
260 | * {hardwarespecific} contains width of DAC | 299 | * {hardwarespecific} contains width of DAC |
261 | * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) | 300 | * pseudo_palette[X] is programmed to (X << red.offset) | |
301 | * (X << green.offset) | | ||
302 | * (X << blue.offset) | ||
262 | * RAMDAC[X] is programmed to (red, green, blue) | 303 | * RAMDAC[X] is programmed to (red, green, blue) |
304 | * color depth = SUM(var->{color}.length) | ||
263 | * | 305 | * |
264 | * Pseudocolor: | 306 | * Pseudocolor: |
265 | * uses offset = 0 && length = DAC register width. | ||
266 | * var->{color}.offset is 0 | 307 | * var->{color}.offset is 0 |
267 | * var->{color}.length contains widht of DAC | 308 | * var->{color}.length contains width of DAC or the number of unique |
268 | * cmap is not used | 309 | * colors available (color depth) |
269 | * DAC[X] is programmed to (red, green, blue) | 310 | * pseudo_palette is not used |
311 | * RAMDAC[X] is programmed to (red, green, blue) | ||
312 | * color depth = var->{color}.length | ||
313 | * | ||
314 | * Static pseudocolor: | ||
315 | * same as Pseudocolor, but the RAMDAC is not programmed (read-only) | ||
316 | * | ||
317 | * Mono01/Mono10: | ||
318 | * Has only 2 values, black on white or white on black (fg on bg), | ||
319 | * var->{color}.offset is 0 | ||
320 | * white = (1 << var->{color}.length) - 1, black = 0 | ||
321 | * pseudo_palette is not used | ||
322 | * RAMDAC does not exist | ||
323 | * color depth is always 2 | ||
324 | * | ||
270 | * Truecolor: | 325 | * Truecolor: |
271 | * does not use RAMDAC (usually has 3 of them). | 326 | * does not use RAMDAC (usually has 3 of them). |
272 | * var->{color}.offset contains start of bitfield | 327 | * var->{color}.offset contains start of bitfield |
273 | * var->{color}.length contains length of bitfield | 328 | * var->{color}.length contains length of bitfield |
274 | * cmap is programmed to (red << red.offset) | (green << green.offset) | | 329 | * pseudo_palette is programmed to (red << red.offset) | |
275 | * (blue << blue.offset) | (transp << transp.offset) | 330 | * (green << green.offset) | |
331 | * (blue << blue.offset) | | ||
332 | * (transp << transp.offset) | ||
276 | * RAMDAC does not exist | 333 | * RAMDAC does not exist |
334 | * color depth = SUM(var->{color}.length}) | ||
335 | * | ||
336 | * The color depth is used by fbcon for choosing the logo and also | ||
337 | * for color palette transformation if color depth < 4 | ||
338 | * | ||
339 | * As can be seen from the above, the field bits_per_pixel is _NOT_ | ||
340 | * a criteria for describing the color visual. | ||
341 | * | ||
342 | * A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor, | ||
343 | * and higher than that, true/directcolor. This is incorrect, one needs | ||
344 | * to look at the fix->visual. | ||
345 | * | ||
346 | * Another common mistake is using bits_per_pixel to calculate the color | ||
347 | * depth. The bits_per_pixel field does not directly translate to color | ||
348 | * depth. You have to compute for the color depth (using the color | ||
349 | * bitfields) and fix->visual as seen above. | ||
350 | */ | ||
351 | |||
352 | /* | ||
353 | * This is the point where the color is converted to something that | ||
354 | * is acceptable by the hardware. | ||
277 | */ | 355 | */ |
278 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) | 356 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) |
279 | switch (info->fix.visual) { | 357 | red = CNVT_TOHW(red, info->var.red.length); |
280 | case FB_VISUAL_TRUECOLOR: | 358 | green = CNVT_TOHW(green, info->var.green.length); |
281 | case FB_VISUAL_PSEUDOCOLOR: | 359 | blue = CNVT_TOHW(blue, info->var.blue.length); |
282 | red = CNVT_TOHW(red, info->var.red.length); | 360 | transp = CNVT_TOHW(transp, info->var.transp.length); |
283 | green = CNVT_TOHW(green, info->var.green.length); | ||
284 | blue = CNVT_TOHW(blue, info->var.blue.length); | ||
285 | transp = CNVT_TOHW(transp, info->var.transp.length); | ||
286 | break; | ||
287 | case FB_VISUAL_DIRECTCOLOR: | ||
288 | /* example here assumes 8 bit DAC. Might be different | ||
289 | * for your hardware */ | ||
290 | red = CNVT_TOHW(red, 8); | ||
291 | green = CNVT_TOHW(green, 8); | ||
292 | blue = CNVT_TOHW(blue, 8); | ||
293 | /* hey, there is bug in transp handling... */ | ||
294 | transp = CNVT_TOHW(transp, 8); | ||
295 | break; | ||
296 | } | ||
297 | #undef CNVT_TOHW | 361 | #undef CNVT_TOHW |
298 | /* Truecolor has hardware independent palette */ | 362 | /* |
299 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | 363 | * This is the point where the function feeds the color to the hardware |
300 | u32 v; | 364 | * palette after converting the colors to something acceptable by |
301 | 365 | * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and | |
302 | if (regno >= 16) | 366 | * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette. |
303 | return -EINVAL; | 367 | * If you have code that writes to the hardware CLUT, and it's not |
304 | 368 | * any of the above visuals, then you are doing something wrong. | |
305 | v = (red << info->var.red.offset) | | 369 | */ |
306 | (green << info->var.green.offset) | | 370 | if (info->fix.visual == FB_VISUAL_DIRECTCOLOR || |
307 | (blue << info->var.blue.offset) | | 371 | info->fix.visual == FB_VISUAL_TRUECOLOR) |
308 | (transp << info->var.transp.offset); | 372 | write_{red|green|blue|transp}_to_clut(); |
309 | 373 | ||
310 | switch (info->var.bits_per_pixel) { | 374 | /* This is the point were you need to fill up the contents of |
311 | case 8: | 375 | * info->pseudo_palette. This structure is used _only_ by fbcon, thus |
312 | /* Yes some hand held devices have this. */ | 376 | * it only contains 16 entries to match the number of colors supported |
313 | ((u8*)(info->pseudo_palette))[regno] = v; | 377 | * by the console. The pseudo_palette is used only if the visual is |
314 | break; | 378 | * in directcolor or truecolor mode. With other visuals, the |
315 | case 16: | 379 | * pseudo_palette is not used. (This might change in the future.) |
316 | ((u16*)(info->pseudo_palette))[regno] = v; | 380 | * |
317 | break; | 381 | * The contents of the pseudo_palette is in raw pixel format. Ie, each |
318 | case 24: | 382 | * entry can be written directly to the framebuffer without any conversion. |
319 | case 32: | 383 | * The pseudo_palette is (void *). However, if using the generic |
320 | ((u32*)(info->pseudo_palette))[regno] = v; | 384 | * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette |
321 | break; | 385 | * must be casted to (u32 *) _regardless_ of the bits per pixel. If the |
322 | } | 386 | * driver is using its own drawing functions, then it can use whatever |
323 | return 0; | 387 | * size it wants. |
388 | */ | ||
389 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
390 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
391 | u32 v; | ||
392 | |||
393 | if (regno >= 16) | ||
394 | return -EINVAL; | ||
395 | |||
396 | v = (red << info->var.red.offset) | | ||
397 | (green << info->var.green.offset) | | ||
398 | (blue << info->var.blue.offset) | | ||
399 | (transp << info->var.transp.offset); | ||
400 | |||
401 | ((u32*)(info->pseudo_palette))[regno] = v; | ||
324 | } | 402 | } |
403 | |||
325 | /* ... */ | 404 | /* ... */ |
326 | return 0; | 405 | return 0; |
327 | } | 406 | } |
@@ -340,6 +419,17 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
340 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, | 419 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, |
341 | const struct fb_info *info) | 420 | const struct fb_info *info) |
342 | { | 421 | { |
422 | /* | ||
423 | * If your hardware does not support panning, _do_ _not_ implement this | ||
424 | * function. Creating a dummy function will just confuse user apps. | ||
425 | */ | ||
426 | |||
427 | /* | ||
428 | * Note that even if this function is fully functional, a setting of | ||
429 | * 0 in both xpanstep and ypanstep means that this function will never | ||
430 | * get called. | ||
431 | */ | ||
432 | |||
343 | /* ... */ | 433 | /* ... */ |
344 | return 0; | 434 | return 0; |
345 | } | 435 | } |
@@ -349,15 +439,20 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var, | |||
349 | * @blank_mode: the blank mode we want. | 439 | * @blank_mode: the blank mode we want. |
350 | * @info: frame buffer structure that represents a single frame buffer | 440 | * @info: frame buffer structure that represents a single frame buffer |
351 | * | 441 | * |
352 | * Blank the screen if blank_mode != 0, else unblank. Return 0 if | 442 | * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank. |
353 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a | 443 | * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to |
354 | * video mode which doesn't support it. Implements VESA suspend | 444 | * e.g. a video mode which doesn't support it. |
355 | * and powerdown modes on hardware that supports disabling hsync/vsync: | ||
356 | * blank_mode == 2: suspend vsync | ||
357 | * blank_mode == 3: suspend hsync | ||
358 | * blank_mode == 4: powerdown | ||
359 | * | 445 | * |
360 | * Returns negative errno on error, or zero on success. | 446 | * Implements VESA suspend and powerdown modes on hardware that supports |
447 | * disabling hsync/vsync: | ||
448 | * | ||
449 | * FB_BLANK_NORMAL = display is blanked, syncs are on. | ||
450 | * FB_BLANK_HSYNC_SUSPEND = hsync off | ||
451 | * FB_BLANK_VSYNC_SUSPEND = vsync off | ||
452 | * FB_BLANK_POWERDOWN = hsync and vsync off | ||
453 | * | ||
454 | * If implementing this function, at least support FB_BLANK_UNBLANK. | ||
455 | * Return !0 for any modes that are unimplemented. | ||
361 | * | 456 | * |
362 | */ | 457 | */ |
363 | static int xxxfb_blank(int blank_mode, const struct fb_info *info) | 458 | static int xxxfb_blank(int blank_mode, const struct fb_info *info) |
@@ -454,6 +549,14 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) | |||
454 | * @data: The actual data used to construct the image on the display. | 549 | * @data: The actual data used to construct the image on the display. |
455 | * @cmap: The colormap used for color images. | 550 | * @cmap: The colormap used for color images. |
456 | */ | 551 | */ |
552 | |||
553 | /* | ||
554 | * The generic function, cfb_imageblit, expects that the bitmap scanlines are | ||
555 | * padded to the next byte. Most hardware accelerators may require padding to | ||
556 | * the next u16 or the next u32. If that is the case, the driver can specify | ||
557 | * this by setting info->pixmap.scan_align = 2 or 4. See a more | ||
558 | * comprehensive description of the pixmap below. | ||
559 | */ | ||
457 | } | 560 | } |
458 | 561 | ||
459 | /** | 562 | /** |
@@ -517,6 +620,7 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
517 | */ | 620 | */ |
518 | void xxxfb_rotate(struct fb_info *info, int angle) | 621 | void xxxfb_rotate(struct fb_info *info, int angle) |
519 | { | 622 | { |
623 | /* Will be deprecated */ | ||
520 | } | 624 | } |
521 | 625 | ||
522 | /** | 626 | /** |
@@ -540,6 +644,9 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait) | |||
540 | * so we can have consistent display output. | 644 | * so we can have consistent display output. |
541 | * | 645 | * |
542 | * @info: frame buffer structure that represents a single frame buffer | 646 | * @info: frame buffer structure that represents a single frame buffer |
647 | * | ||
648 | * If the driver has implemented its own hardware-based drawing function, | ||
649 | * implementing this function is highly recommended. | ||
543 | */ | 650 | */ |
544 | void xxxfb_sync(struct fb_info *info) | 651 | void xxxfb_sync(struct fb_info *info) |
545 | { | 652 | { |
@@ -549,20 +656,25 @@ void xxxfb_sync(struct fb_info *info) | |||
549 | * Initialization | 656 | * Initialization |
550 | */ | 657 | */ |
551 | 658 | ||
552 | int __init xxxfb_init(void) | 659 | /* static int __init xxfb_probe (struct device *device) -- for platform devs */ |
660 | static int __init xxxfb_probe(struct pci_dev *dev, | ||
661 | const_struct pci_device_id *ent) | ||
553 | { | 662 | { |
663 | struct fb_info *info; | ||
664 | struct xxx_par *par; | ||
665 | struct device = &dev->dev; /* for pci drivers */ | ||
554 | int cmap_len, retval; | 666 | int cmap_len, retval; |
555 | 667 | ||
556 | /* | 668 | /* |
557 | * For kernel boot options (in 'video=xxxfb:<options>' format) | 669 | * Dynamically allocate info and par |
558 | */ | 670 | */ |
559 | #ifndef MODULE | 671 | info = framebuffer_alloc(sizeof(struct xxx_par), device); |
560 | char *option = NULL; | ||
561 | 672 | ||
562 | if (fb_get_options("xxxfb", &option)) | 673 | if (!info) { |
563 | return -ENODEV; | 674 | /* goto error path */ |
564 | xxxfb_setup(option); | 675 | } |
565 | #endif | 676 | |
677 | par = info->par; | ||
566 | 678 | ||
567 | /* | 679 | /* |
568 | * Here we set the screen_base to the virtual memory address | 680 | * Here we set the screen_base to the virtual memory address |
@@ -570,18 +682,87 @@ int __init xxxfb_init(void) | |||
570 | * from the bus layer and then translate it to virtual memory | 682 | * from the bus layer and then translate it to virtual memory |
571 | * space via ioremap. Consult ioport.h. | 683 | * space via ioremap. Consult ioport.h. |
572 | */ | 684 | */ |
573 | info.screen_base = framebuffer_virtual_memory; | 685 | info->screen_base = framebuffer_virtual_memory; |
574 | info.fbops = &xxxfb_ops; | 686 | info->fbops = &xxxfb_ops; |
575 | info.fix = xxxfb_fix; | 687 | info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be |
576 | info.pseudo_palette = pseudo_palette; | 688 | * used, so mark it as __initdata |
577 | 689 | */ | |
690 | info->pseudo_palette = pseudo_palette; /* The pseudopalette is an | ||
691 | * 16-member array | ||
692 | */ | ||
578 | /* | 693 | /* |
579 | * Set up flags to indicate what sort of acceleration your | 694 | * Set up flags to indicate what sort of acceleration your |
580 | * driver can provide (pan/wrap/copyarea/etc.) and whether it | 695 | * driver can provide (pan/wrap/copyarea/etc.) and whether it |
581 | * is a module -- see FBINFO_* in include/linux/fb.h | 696 | * is a module -- see FBINFO_* in include/linux/fb.h |
697 | * | ||
698 | * If your hardware can support any of the hardware accelerated functions | ||
699 | * fbcon performance will improve if info->flags is set properly. | ||
700 | * | ||
701 | * FBINFO_HWACCEL_COPYAREA - hardware moves | ||
702 | * FBINFO_HWACCEL_FILLRECT - hardware fills | ||
703 | * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion | ||
704 | * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis | ||
705 | * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis | ||
706 | * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled | ||
707 | * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion | ||
708 | * FBINFO_MISC_TILEBLITTING - hardware can do tile blits | ||
709 | * | ||
710 | * NOTE: These are for fbcon use only. | ||
711 | */ | ||
712 | info->flags = FBINFO_DEFAULT; | ||
713 | |||
714 | /********************* This stage is optional ******************************/ | ||
715 | /* | ||
716 | * The struct pixmap is a scratch pad for the drawing functions. This | ||
717 | * is where the monochrome bitmap is constructed by the higher layers | ||
718 | * and then passed to the accelerator. For drivers that uses | ||
719 | * cfb_imageblit, you can skip this part. For those that have a more | ||
720 | * rigorous requirement, this stage is needed | ||
721 | */ | ||
722 | |||
723 | /* PIXMAP_SIZE should be small enough to optimize drawing, but not | ||
724 | * large enough that memory is wasted. A safe size is | ||
725 | * (max_xres * max_font_height/8). max_xres is driver dependent, | ||
726 | * max_font_height is 32. | ||
727 | */ | ||
728 | info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL); | ||
729 | if (!info->pixmap.addr) { | ||
730 | /* goto error */ | ||
731 | } | ||
732 | |||
733 | info->pixmap.size = PIXMAP_SIZE; | ||
734 | |||
735 | /* | ||
736 | * FB_PIXMAP_SYSTEM - memory is in system ram | ||
737 | * FB_PIXMAP_IO - memory is iomapped | ||
738 | * FB_PIXMAP_SYNC - if set, will call fb_sync() per access to pixmap, | ||
739 | * usually if FB_PIXMAP_IO is set. | ||
740 | * | ||
741 | * Currently, FB_PIXMAP_IO is unimplemented. | ||
742 | */ | ||
743 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
744 | |||
745 | /* | ||
746 | * scan_align is the number of padding for each scanline. It is in bytes. | ||
747 | * Thus for accelerators that need padding to the next u32, put 4 here. | ||
748 | */ | ||
749 | info->pixmap.scan_align = 4; | ||
750 | |||
751 | /* | ||
752 | * buf_align is the amount to be padded for the buffer. For example, | ||
753 | * the i810fb needs a scan_align of 2 but expects it to be fed with | ||
754 | * dwords, so a buf_align = 4 is required. | ||
582 | */ | 755 | */ |
583 | info.flags = FBINFO_DEFAULT; | 756 | info->pixmap.buf_align = 4; |
584 | info.par = current_par; | 757 | |
758 | /* access_align is how many bits can be accessed from the framebuffer | ||
759 | * ie. some epson cards allow 16-bit access only. Most drivers will | ||
760 | * be safe with u32 here. | ||
761 | * | ||
762 | * NOTE: This field is currently unused. | ||
763 | */ | ||
764 | info->pixmap.scan_align = 32 | ||
765 | /***************************** End optional stage ***************************/ | ||
585 | 766 | ||
586 | /* | 767 | /* |
587 | * This should give a reasonable default video mode. The following is | 768 | * This should give a reasonable default video mode. The following is |
@@ -590,42 +771,145 @@ int __init xxxfb_init(void) | |||
590 | if (!mode_option) | 771 | if (!mode_option) |
591 | mode_option = "640x480@60"; | 772 | mode_option = "640x480@60"; |
592 | 773 | ||
593 | retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); | 774 | retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8); |
594 | 775 | ||
595 | if (!retval || retval == 4) | 776 | if (!retval || retval == 4) |
596 | return -EINVAL; | 777 | return -EINVAL; |
597 | 778 | ||
598 | /* This has to been done !!! */ | 779 | /* This has to been done !!! */ |
599 | fb_alloc_cmap(&info.cmap, cmap_len, 0); | 780 | fb_alloc_cmap(info->cmap, cmap_len, 0); |
600 | 781 | ||
601 | /* | 782 | /* |
602 | * The following is done in the case of having hardware with a static | 783 | * The following is done in the case of having hardware with a static |
603 | * mode. If we are setting the mode ourselves we don't call this. | 784 | * mode. If we are setting the mode ourselves we don't call this. |
604 | */ | 785 | */ |
605 | info.var = xxxfb_var; | 786 | info->var = xxxfb_var; |
606 | 787 | ||
607 | if (register_framebuffer(&info) < 0) | 788 | /* |
789 | * For drivers that can... | ||
790 | */ | ||
791 | xxxfb_check_var(&info->var, info); | ||
792 | |||
793 | /* | ||
794 | * Does a call to fb_set_par() before register_framebuffer needed? This | ||
795 | * will depend on you and the hardware. If you are sure that your driver | ||
796 | * is the only device in the system, a call to fb_set_par() is safe. | ||
797 | * | ||
798 | * Hardware in x86 systems has a VGA core. Calling set_par() at this | ||
799 | * point will corrupt the VGA console, so it might be safer to skip a | ||
800 | * call to set_par here and just allow fbcon to do it for you. | ||
801 | */ | ||
802 | /* xxxfb_set_par(info); */ | ||
803 | |||
804 | if (register_framebuffer(info) < 0) | ||
608 | return -EINVAL; | 805 | return -EINVAL; |
609 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, | 806 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, |
610 | info.fix.id); | 807 | info->fix.id); |
808 | pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */ | ||
611 | return 0; | 809 | return 0; |
612 | } | 810 | } |
613 | 811 | ||
614 | /* | 812 | /* |
615 | * Cleanup | 813 | * Cleanup |
616 | */ | 814 | */ |
815 | /* static void __exit xxxfb_remove(struct device *device) */ | ||
816 | static void __exit xxxfb_remove(struct pci_dev *dev) | ||
817 | { | ||
818 | struct fb_info *info = pci_get_drv_data(dev); | ||
819 | /* or dev_get_drv_data(device); */ | ||
820 | |||
821 | if (info) { | ||
822 | unregister_framebuffer(info); | ||
823 | fb_dealloc_cmap(&info.cmap); | ||
824 | /* ... */ | ||
825 | framebuffer_release(info); | ||
826 | } | ||
827 | |||
828 | return 0; | ||
829 | } | ||
617 | 830 | ||
618 | static void __exit xxxfb_cleanup(void) | 831 | #if CONFIG_PCI |
832 | /* For PCI drivers */ | ||
833 | static struct pci_driver xxxfb_driver = { | ||
834 | .name = "xxxfb", | ||
835 | .id_table = xxxfb_devices, | ||
836 | .probe = xxxfb_probe, | ||
837 | .remove = __devexit_p(xxxfb_remove), | ||
838 | .suspend = xxxfb_suspend, /* optional */ | ||
839 | .resume = xxxfb_resume, /* optional */ | ||
840 | }; | ||
841 | |||
842 | static int __init xxxfb_init(void) | ||
619 | { | 843 | { |
620 | /* | 844 | /* |
621 | * If your driver supports multiple boards, you should unregister and | 845 | * For kernel boot options (in 'video=xxxfb:<options>' format) |
622 | * clean up all instances. | 846 | */ |
623 | */ | 847 | #ifndef MODULE |
848 | char *option = NULL; | ||
624 | 849 | ||
625 | unregister_framebuffer(info); | 850 | if (fb_get_options("xxxfb", &option)) |
626 | fb_dealloc_cmap(&info.cmap); | 851 | return -ENODEV; |
627 | /* ... */ | 852 | xxxfb_setup(option); |
853 | #endif | ||
854 | |||
855 | return pci_register_driver(&xxxfb_driver); | ||
856 | } | ||
857 | |||
858 | static void __exit xxxfb_exit(void) | ||
859 | { | ||
860 | pci_unregister_driver(&xxxfb_driver); | ||
628 | } | 861 | } |
862 | #else | ||
863 | #include <linux/platform_device.h> | ||
864 | /* for platform devices */ | ||
865 | static struct device_driver xxxfb_driver = { | ||
866 | .name = "xxxfb", | ||
867 | .bus = &platform_bus_type, | ||
868 | .probe = xxxfb_probe, | ||
869 | .remove = xxxfb_remove, | ||
870 | .suspend = xxxfb_suspend, /* optional */ | ||
871 | .resume = xxxfb_resume, /* optional */ | ||
872 | }; | ||
873 | |||
874 | static struct platform_device xxxfb_device = { | ||
875 | .name = "xxxfb", | ||
876 | }; | ||
877 | |||
878 | static int __init xxxfb_init(void) | ||
879 | { | ||
880 | int ret; | ||
881 | /* | ||
882 | * For kernel boot options (in 'video=xxxfb:<options>' format) | ||
883 | */ | ||
884 | #ifndef MODULE | ||
885 | char *option = NULL; | ||
886 | |||
887 | if (fb_get_options("xxxfb", &option)) | ||
888 | return -ENODEV; | ||
889 | xxxfb_setup(option); | ||
890 | #endif | ||
891 | ret = driver_register(&xxxfb_driver); | ||
892 | |||
893 | if (!ret) { | ||
894 | ret = platform_device_register(&xxxfb_device); | ||
895 | if (ret) | ||
896 | driver_unregister(&xxxfb_driver); | ||
897 | } | ||
898 | |||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | static void __exit xxxfb_exit(void) | ||
903 | { | ||
904 | platform_device_unregister(&xxxfb_device); | ||
905 | driver_unregister(&xxxfb_driver); | ||
906 | } | ||
907 | #endif | ||
908 | |||
909 | MODULE_LICENSE("GPL"); | ||
910 | module_init(xxxfb_init); | ||
911 | module_exit(xxxfb_exit); | ||
912 | |||
629 | 913 | ||
630 | /* | 914 | /* |
631 | * Setup | 915 | * Setup |
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index e0f14df840d9..8a5ce210bb27 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c | |||
@@ -382,7 +382,7 @@ static void sstfb_clear_screen(struct fb_info *info) | |||
382 | static int sstfb_check_var(struct fb_var_screeninfo *var, | 382 | static int sstfb_check_var(struct fb_var_screeninfo *var, |
383 | struct fb_info *info) | 383 | struct fb_info *info) |
384 | { | 384 | { |
385 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 385 | struct sstfb_par *par = info->par; |
386 | int hSyncOff = var->xres + var->right_margin + var->left_margin; | 386 | int hSyncOff = var->xres + var->right_margin + var->left_margin; |
387 | int vSyncOff = var->yres + var->lower_margin + var->upper_margin; | 387 | int vSyncOff = var->yres + var->lower_margin + var->upper_margin; |
388 | int vBackPorch = var->left_margin, yDim = var->yres; | 388 | int vBackPorch = var->left_margin, yDim = var->yres; |
@@ -542,7 +542,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
542 | */ | 542 | */ |
543 | static int sstfb_set_par(struct fb_info *info) | 543 | static int sstfb_set_par(struct fb_info *info) |
544 | { | 544 | { |
545 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 545 | struct sstfb_par *par = info->par; |
546 | u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0; | 546 | u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0; |
547 | struct pci_dev *sst_dev = par->dev; | 547 | struct pci_dev *sst_dev = par->dev; |
548 | unsigned int freq; | 548 | unsigned int freq; |
@@ -748,13 +748,14 @@ static int sstfb_set_par(struct fb_info *info) | |||
748 | static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | 748 | static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
749 | u_int transp, struct fb_info *info) | 749 | u_int transp, struct fb_info *info) |
750 | { | 750 | { |
751 | struct sstfb_par *par = info->par; | ||
751 | u32 col; | 752 | u32 col; |
752 | 753 | ||
753 | f_dddprintk("sstfb_setcolreg\n"); | 754 | f_dddprintk("sstfb_setcolreg\n"); |
754 | f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n", | 755 | f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n", |
755 | regno, red, green, blue, transp); | 756 | regno, red, green, blue, transp); |
756 | if (regno >= 16) | 757 | if (regno > 15) |
757 | return -EINVAL; | 758 | return 0; |
758 | 759 | ||
759 | red >>= (16 - info->var.red.length); | 760 | red >>= (16 - info->var.red.length); |
760 | green >>= (16 - info->var.green.length); | 761 | green >>= (16 - info->var.green.length); |
@@ -765,7 +766,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
765 | | (blue << info->var.blue.offset) | 766 | | (blue << info->var.blue.offset) |
766 | | (transp << info->var.transp.offset); | 767 | | (transp << info->var.transp.offset); |
767 | 768 | ||
768 | ((u32 *)info->pseudo_palette)[regno] = col; | 769 | par->palette[regno] = col; |
769 | 770 | ||
770 | return 0; | 771 | return 0; |
771 | } | 772 | } |
@@ -773,7 +774,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
773 | static int sstfb_ioctl(struct inode *inode, struct file *file, | 774 | static int sstfb_ioctl(struct inode *inode, struct file *file, |
774 | u_int cmd, u_long arg, struct fb_info *info ) | 775 | u_int cmd, u_long arg, struct fb_info *info ) |
775 | { | 776 | { |
776 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 777 | struct sstfb_par *par = info->par; |
777 | struct pci_dev *sst_dev = par->dev; | 778 | struct pci_dev *sst_dev = par->dev; |
778 | u32 fbiinit0, tmp, val; | 779 | u32 fbiinit0, tmp, val; |
779 | u_long p; | 780 | u_long p; |
@@ -830,7 +831,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file, | |||
830 | #if 0 | 831 | #if 0 |
831 | static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | 832 | static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) |
832 | { | 833 | { |
833 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 834 | struct sstfb_par *par = info->par; |
834 | u32 stride = info->fix.line_length; | 835 | u32 stride = info->fix.line_length; |
835 | 836 | ||
836 | if (!IS_VOODOO2(par)) | 837 | if (!IS_VOODOO2(par)) |
@@ -855,7 +856,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
855 | */ | 856 | */ |
856 | static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 857 | static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
857 | { | 858 | { |
858 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 859 | struct sstfb_par *par = info->par; |
859 | u32 stride = info->fix.line_length; | 860 | u32 stride = info->fix.line_length; |
860 | 861 | ||
861 | if (!IS_VOODOO2(par)) | 862 | if (!IS_VOODOO2(par)) |
@@ -925,7 +926,7 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize) | |||
925 | 926 | ||
926 | static int __devinit sst_detect_att(struct fb_info *info) | 927 | static int __devinit sst_detect_att(struct fb_info *info) |
927 | { | 928 | { |
928 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 929 | struct sstfb_par *par = info->par; |
929 | int i, mir, dir; | 930 | int i, mir, dir; |
930 | 931 | ||
931 | for (i=0; i<3; i++) { | 932 | for (i=0; i<3; i++) { |
@@ -950,7 +951,7 @@ static int __devinit sst_detect_att(struct fb_info *info) | |||
950 | 951 | ||
951 | static int __devinit sst_detect_ti(struct fb_info *info) | 952 | static int __devinit sst_detect_ti(struct fb_info *info) |
952 | { | 953 | { |
953 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 954 | struct sstfb_par *par = info->par; |
954 | int i, mir, dir; | 955 | int i, mir, dir; |
955 | 956 | ||
956 | for (i = 0; i<3; i++) { | 957 | for (i = 0; i<3; i++) { |
@@ -986,7 +987,7 @@ static int __devinit sst_detect_ti(struct fb_info *info) | |||
986 | */ | 987 | */ |
987 | static int __devinit sst_detect_ics(struct fb_info *info) | 988 | static int __devinit sst_detect_ics(struct fb_info *info) |
988 | { | 989 | { |
989 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 990 | struct sstfb_par *par = info->par; |
990 | int m_clk0_1, m_clk0_7, m_clk1_b; | 991 | int m_clk0_1, m_clk0_7, m_clk1_b; |
991 | int n_clk0_1, n_clk0_7, n_clk1_b; | 992 | int n_clk0_1, n_clk0_7, n_clk1_b; |
992 | int i; | 993 | int i; |
@@ -1023,7 +1024,7 @@ static int __devinit sst_detect_ics(struct fb_info *info) | |||
1023 | static int sst_set_pll_att_ti(struct fb_info *info, | 1024 | static int sst_set_pll_att_ti(struct fb_info *info, |
1024 | const struct pll_timing *t, const int clock) | 1025 | const struct pll_timing *t, const int clock) |
1025 | { | 1026 | { |
1026 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1027 | struct sstfb_par *par = info->par; |
1027 | u8 cr0, cc; | 1028 | u8 cr0, cc; |
1028 | 1029 | ||
1029 | /* enable indexed mode */ | 1030 | /* enable indexed mode */ |
@@ -1077,7 +1078,7 @@ static int sst_set_pll_att_ti(struct fb_info *info, | |||
1077 | static int sst_set_pll_ics(struct fb_info *info, | 1078 | static int sst_set_pll_ics(struct fb_info *info, |
1078 | const struct pll_timing *t, const int clock) | 1079 | const struct pll_timing *t, const int clock) |
1079 | { | 1080 | { |
1080 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1081 | struct sstfb_par *par = info->par; |
1081 | u8 pll_ctrl; | 1082 | u8 pll_ctrl; |
1082 | 1083 | ||
1083 | sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL); | 1084 | sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL); |
@@ -1114,7 +1115,7 @@ static int sst_set_pll_ics(struct fb_info *info, | |||
1114 | 1115 | ||
1115 | static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) | 1116 | static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) |
1116 | { | 1117 | { |
1117 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1118 | struct sstfb_par *par = info->par; |
1118 | u8 cr0; | 1119 | u8 cr0; |
1119 | 1120 | ||
1120 | sst_dac_write(DACREG_WMA, 0); /* backdoor */ | 1121 | sst_dac_write(DACREG_WMA, 0); /* backdoor */ |
@@ -1149,7 +1150,7 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) | |||
1149 | 1150 | ||
1150 | static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) | 1151 | static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) |
1151 | { | 1152 | { |
1152 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1153 | struct sstfb_par *par = info->par; |
1153 | 1154 | ||
1154 | switch(bpp) { | 1155 | switch(bpp) { |
1155 | case 16: | 1156 | case 16: |
@@ -1308,7 +1309,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) | |||
1308 | 1309 | ||
1309 | static void __devexit sst_shutdown(struct fb_info *info) | 1310 | static void __devexit sst_shutdown(struct fb_info *info) |
1310 | { | 1311 | { |
1311 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1312 | struct sstfb_par *par = info->par; |
1312 | struct pci_dev *dev = par->dev; | 1313 | struct pci_dev *dev = par->dev; |
1313 | struct pll_timing gfx_timings; | 1314 | struct pll_timing gfx_timings; |
1314 | int Fout; | 1315 | int Fout; |
@@ -1394,12 +1395,6 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1394 | struct sst_spec *spec; | 1395 | struct sst_spec *spec; |
1395 | int err; | 1396 | int err; |
1396 | 1397 | ||
1397 | struct all_info { | ||
1398 | struct fb_info info; | ||
1399 | struct sstfb_par par; | ||
1400 | u32 pseudo_palette[16]; | ||
1401 | } *all; | ||
1402 | |||
1403 | /* Enable device in PCI config. */ | 1398 | /* Enable device in PCI config. */ |
1404 | if ((err=pci_enable_device(pdev))) { | 1399 | if ((err=pci_enable_device(pdev))) { |
1405 | eprintk("cannot enable device\n"); | 1400 | eprintk("cannot enable device\n"); |
@@ -1407,14 +1402,13 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1407 | } | 1402 | } |
1408 | 1403 | ||
1409 | /* Allocate the fb and par structures. */ | 1404 | /* Allocate the fb and par structures. */ |
1410 | all = kmalloc(sizeof(*all), GFP_KERNEL); | 1405 | info = framebuffer_alloc(sizeof(struct sstfb_par), &pdev->dev); |
1411 | if (!all) | 1406 | if (!info) |
1412 | return -ENOMEM; | 1407 | return -ENOMEM; |
1413 | memset(all, 0, sizeof(*all)); | 1408 | |
1414 | pci_set_drvdata(pdev, all); | 1409 | pci_set_drvdata(pdev, info); |
1415 | 1410 | ||
1416 | info = &all->info; | 1411 | par = info->par; |
1417 | par = info->par = &all->par; | ||
1418 | fix = &info->fix; | 1412 | fix = &info->fix; |
1419 | 1413 | ||
1420 | par->type = id->driver_data; | 1414 | par->type = id->driver_data; |
@@ -1471,7 +1465,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1471 | 1465 | ||
1472 | info->flags = FBINFO_DEFAULT; | 1466 | info->flags = FBINFO_DEFAULT; |
1473 | info->fbops = &sstfb_ops; | 1467 | info->fbops = &sstfb_ops; |
1474 | info->pseudo_palette = &all->pseudo_palette; | 1468 | info->pseudo_palette = par->palette; |
1475 | 1469 | ||
1476 | fix->type = FB_TYPE_PACKED_PIXELS; | 1470 | fix->type = FB_TYPE_PACKED_PIXELS; |
1477 | fix->visual = FB_VISUAL_TRUECOLOR; | 1471 | fix->visual = FB_VISUAL_TRUECOLOR; |
@@ -1527,7 +1521,7 @@ fail_mmio_remap: | |||
1527 | fail_fb_mem: | 1521 | fail_fb_mem: |
1528 | release_mem_region(fix->mmio_start, info->fix.mmio_len); | 1522 | release_mem_region(fix->mmio_start, info->fix.mmio_len); |
1529 | fail_mmio_mem: | 1523 | fail_mmio_mem: |
1530 | kfree(info); | 1524 | framebuffer_release(info); |
1531 | return -ENXIO; /* no voodoo detected */ | 1525 | return -ENXIO; /* no voodoo detected */ |
1532 | } | 1526 | } |
1533 | 1527 | ||
@@ -1537,7 +1531,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev) | |||
1537 | struct fb_info *info; | 1531 | struct fb_info *info; |
1538 | 1532 | ||
1539 | info = pci_get_drvdata(pdev); | 1533 | info = pci_get_drvdata(pdev); |
1540 | par = (struct sstfb_par *) info->par; | 1534 | par = info->par; |
1541 | 1535 | ||
1542 | sst_shutdown(info); | 1536 | sst_shutdown(info); |
1543 | unregister_framebuffer(info); | 1537 | unregister_framebuffer(info); |
@@ -1545,7 +1539,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev) | |||
1545 | iounmap(par->mmio_vbase); | 1539 | iounmap(par->mmio_vbase); |
1546 | release_mem_region(info->fix.smem_start, 0x400000); | 1540 | release_mem_region(info->fix.smem_start, 0x400000); |
1547 | release_mem_region(info->fix.mmio_start, info->fix.mmio_len); | 1541 | release_mem_region(info->fix.mmio_start, info->fix.mmio_len); |
1548 | kfree(info); | 1542 | framebuffer_release(info); |
1549 | } | 1543 | } |
1550 | 1544 | ||
1551 | 1545 | ||
@@ -1613,7 +1607,7 @@ static int sstfb_dump_regs(struct fb_info *info) | |||
1613 | 1607 | ||
1614 | const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]); | 1608 | const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]); |
1615 | const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]); | 1609 | const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]); |
1616 | struct sstfb_par *par = (struct sstfb_par *) info->par; | 1610 | struct sstfb_par *par = info->par; |
1617 | struct pci_dev *dev = par->dev; | 1611 | struct pci_dev *dev = par->dev; |
1618 | u32 pci_res[pci_s]; | 1612 | u32 pci_res[pci_s]; |
1619 | u32 sst_res[sst_s]; | 1613 | u32 sst_res[sst_s]; |
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 9d53387e6a66..3e7baf4c9fa8 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -291,7 +291,7 @@ static inline void banshee_make_room(struct tdfx_par *par, int size) | |||
291 | 291 | ||
292 | static int banshee_wait_idle(struct fb_info *info) | 292 | static int banshee_wait_idle(struct fb_info *info) |
293 | { | 293 | { |
294 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 294 | struct tdfx_par *par = info->par; |
295 | int i = 0; | 295 | int i = 0; |
296 | 296 | ||
297 | banshee_make_room(par, 1); | 297 | banshee_make_room(par, 1); |
@@ -364,7 +364,7 @@ static u32 do_calc_pll(int freq, int* freq_out) | |||
364 | 364 | ||
365 | static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) | 365 | static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) |
366 | { | 366 | { |
367 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 367 | struct tdfx_par *par = info->par; |
368 | int i; | 368 | int i; |
369 | 369 | ||
370 | banshee_wait_idle(info); | 370 | banshee_wait_idle(info); |
@@ -469,7 +469,7 @@ static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) | |||
469 | 469 | ||
470 | static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) | 470 | static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) |
471 | { | 471 | { |
472 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 472 | struct tdfx_par *par = info->par; |
473 | u32 lpitch; | 473 | u32 lpitch; |
474 | 474 | ||
475 | if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && | 475 | if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && |
@@ -558,7 +558,7 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) | |||
558 | 558 | ||
559 | static int tdfxfb_set_par(struct fb_info *info) | 559 | static int tdfxfb_set_par(struct fb_info *info) |
560 | { | 560 | { |
561 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 561 | struct tdfx_par *par = info->par; |
562 | u32 hdispend, hsyncsta, hsyncend, htotal; | 562 | u32 hdispend, hsyncsta, hsyncend, htotal; |
563 | u32 hd, hs, he, ht, hbs, hbe; | 563 | u32 hd, hs, he, ht, hbs, hbe; |
564 | u32 vd, vs, ve, vt, vbs, vbe; | 564 | u32 vd, vs, ve, vt, vbs, vbe; |
@@ -780,7 +780,7 @@ static int tdfxfb_set_par(struct fb_info *info) | |||
780 | static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | 780 | static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, |
781 | unsigned blue,unsigned transp,struct fb_info *info) | 781 | unsigned blue,unsigned transp,struct fb_info *info) |
782 | { | 782 | { |
783 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 783 | struct tdfx_par *par = info->par; |
784 | u32 rgbcol; | 784 | u32 rgbcol; |
785 | 785 | ||
786 | if (regno >= info->cmap.len || regno > 255) return 1; | 786 | if (regno >= info->cmap.len || regno > 255) return 1; |
@@ -794,11 +794,15 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
794 | break; | 794 | break; |
795 | /* Truecolor has no hardware color palettes. */ | 795 | /* Truecolor has no hardware color palettes. */ |
796 | case FB_VISUAL_TRUECOLOR: | 796 | case FB_VISUAL_TRUECOLOR: |
797 | rgbcol = (CNVT_TOHW( red, info->var.red.length) << info->var.red.offset) | | 797 | rgbcol = (CNVT_TOHW( red, info->var.red.length) << |
798 | (CNVT_TOHW( green, info->var.green.length) << info->var.green.offset) | | 798 | info->var.red.offset) | |
799 | (CNVT_TOHW( blue, info->var.blue.length) << info->var.blue.offset) | | 799 | (CNVT_TOHW( green, info->var.green.length) << |
800 | (CNVT_TOHW( transp, info->var.transp.length) << info->var.transp.offset); | 800 | info->var.green.offset) | |
801 | ((u32*)(info->pseudo_palette))[regno] = rgbcol; | 801 | (CNVT_TOHW( blue, info->var.blue.length) << |
802 | info->var.blue.offset) | | ||
803 | (CNVT_TOHW( transp, info->var.transp.length) << | ||
804 | info->var.transp.offset); | ||
805 | par->palette[regno] = rgbcol; | ||
802 | break; | 806 | break; |
803 | default: | 807 | default: |
804 | DPRINTK("bad depth %u\n", info->var.bits_per_pixel); | 808 | DPRINTK("bad depth %u\n", info->var.bits_per_pixel); |
@@ -810,7 +814,7 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
810 | /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ | 814 | /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ |
811 | static int tdfxfb_blank(int blank, struct fb_info *info) | 815 | static int tdfxfb_blank(int blank, struct fb_info *info) |
812 | { | 816 | { |
813 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 817 | struct tdfx_par *par = info->par; |
814 | u32 dacmode, state = 0, vgablank = 0; | 818 | u32 dacmode, state = 0, vgablank = 0; |
815 | 819 | ||
816 | dacmode = tdfx_inl(par, DACMODE); | 820 | dacmode = tdfx_inl(par, DACMODE); |
@@ -855,7 +859,7 @@ static int tdfxfb_blank(int blank, struct fb_info *info) | |||
855 | static int tdfxfb_pan_display(struct fb_var_screeninfo *var, | 859 | static int tdfxfb_pan_display(struct fb_var_screeninfo *var, |
856 | struct fb_info *info) | 860 | struct fb_info *info) |
857 | { | 861 | { |
858 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 862 | struct tdfx_par *par = info->par; |
859 | u32 addr; | 863 | u32 addr; |
860 | 864 | ||
861 | if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) | 865 | if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) |
@@ -878,7 +882,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, | |||
878 | */ | 882 | */ |
879 | static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 883 | static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
880 | { | 884 | { |
881 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 885 | struct tdfx_par *par = info->par; |
882 | u32 bpp = info->var.bits_per_pixel; | 886 | u32 bpp = info->var.bits_per_pixel; |
883 | u32 stride = info->fix.line_length; | 887 | u32 stride = info->fix.line_length; |
884 | u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); | 888 | u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); |
@@ -894,7 +898,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect | |||
894 | if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { | 898 | if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { |
895 | tdfx_outl(par, COLORFORE, rect->color); | 899 | tdfx_outl(par, COLORFORE, rect->color); |
896 | } else { /* FB_VISUAL_TRUECOLOR */ | 900 | } else { /* FB_VISUAL_TRUECOLOR */ |
897 | tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[rect->color]); | 901 | tdfx_outl(par, COLORFORE, par->palette[rect->color]); |
898 | } | 902 | } |
899 | tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); | 903 | tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); |
900 | tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); | 904 | tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); |
@@ -906,7 +910,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect | |||
906 | */ | 910 | */ |
907 | static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | 911 | static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) |
908 | { | 912 | { |
909 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 913 | struct tdfx_par *par = info->par; |
910 | u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; | 914 | u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; |
911 | u32 bpp = info->var.bits_per_pixel; | 915 | u32 bpp = info->var.bits_per_pixel; |
912 | u32 stride = info->fix.line_length; | 916 | u32 stride = info->fix.line_length; |
@@ -938,7 +942,7 @@ static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area | |||
938 | 942 | ||
939 | static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) | 943 | static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) |
940 | { | 944 | { |
941 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 945 | struct tdfx_par *par = info->par; |
942 | int size = image->height * ((image->width * image->depth + 7)>>3); | 946 | int size = image->height * ((image->width * image->depth + 7)>>3); |
943 | int fifo_free; | 947 | int fifo_free; |
944 | int i, stride = info->fix.line_length; | 948 | int i, stride = info->fix.line_length; |
@@ -961,8 +965,10 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
961 | break; | 965 | break; |
962 | case FB_VISUAL_TRUECOLOR: | 966 | case FB_VISUAL_TRUECOLOR: |
963 | default: | 967 | default: |
964 | tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[image->fg_color]); | 968 | tdfx_outl(par, COLORFORE, |
965 | tdfx_outl(par, COLORBACK, ((u32*)(info->pseudo_palette))[image->bg_color]); | 969 | par->palette[image->fg_color]); |
970 | tdfx_outl(par, COLORBACK, | ||
971 | par->palette[image->bg_color]); | ||
966 | } | 972 | } |
967 | #ifdef __BIG_ENDIAN | 973 | #ifdef __BIG_ENDIAN |
968 | srcfmt = 0x400000 | BIT(20); | 974 | srcfmt = 0x400000 | BIT(20); |
@@ -1007,7 +1013,7 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1007 | #ifdef TDFX_HARDWARE_CURSOR | 1013 | #ifdef TDFX_HARDWARE_CURSOR |
1008 | static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1014 | static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
1009 | { | 1015 | { |
1010 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 1016 | struct tdfx_par *par = info->par; |
1011 | unsigned long flags; | 1017 | unsigned long flags; |
1012 | 1018 | ||
1013 | /* | 1019 | /* |
@@ -1157,18 +1163,17 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, | |||
1157 | { | 1163 | { |
1158 | struct tdfx_par *default_par; | 1164 | struct tdfx_par *default_par; |
1159 | struct fb_info *info; | 1165 | struct fb_info *info; |
1160 | int size, err, lpitch; | 1166 | int err, lpitch; |
1161 | 1167 | ||
1162 | if ((err = pci_enable_device(pdev))) { | 1168 | if ((err = pci_enable_device(pdev))) { |
1163 | printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err); | 1169 | printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err); |
1164 | return err; | 1170 | return err; |
1165 | } | 1171 | } |
1166 | 1172 | ||
1167 | size = sizeof(struct tdfx_par)+256*sizeof(u32); | 1173 | info = framebuffer_alloc(sizeof(struct tdfx_par), &pdev->dev); |
1168 | 1174 | ||
1169 | info = framebuffer_alloc(size, &pdev->dev); | 1175 | if (!info) |
1170 | 1176 | return -ENOMEM; | |
1171 | if (!info) return -ENOMEM; | ||
1172 | 1177 | ||
1173 | default_par = info->par; | 1178 | default_par = info->par; |
1174 | 1179 | ||
@@ -1248,7 +1253,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, | |||
1248 | 1253 | ||
1249 | info->fbops = &tdfxfb_ops; | 1254 | info->fbops = &tdfxfb_ops; |
1250 | info->fix = tdfx_fix; | 1255 | info->fix = tdfx_fix; |
1251 | info->pseudo_palette = (void *)(default_par + 1); | 1256 | info->pseudo_palette = default_par->palette; |
1252 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1257 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
1253 | #ifdef CONFIG_FB_3DFX_ACCEL | 1258 | #ifdef CONFIG_FB_3DFX_ACCEL |
1254 | info->flags |= FBINFO_HWACCEL_FILLRECT | | 1259 | info->flags |= FBINFO_HWACCEL_FILLRECT | |
@@ -1307,7 +1312,7 @@ out_err: | |||
1307 | } | 1312 | } |
1308 | 1313 | ||
1309 | #ifndef MODULE | 1314 | #ifndef MODULE |
1310 | void tdfxfb_setup(char *options) | 1315 | static void tdfxfb_setup(char *options) |
1311 | { | 1316 | { |
1312 | char* this_opt; | 1317 | char* this_opt; |
1313 | 1318 | ||
@@ -1340,7 +1345,7 @@ void tdfxfb_setup(char *options) | |||
1340 | static void __devexit tdfxfb_remove(struct pci_dev *pdev) | 1345 | static void __devexit tdfxfb_remove(struct pci_dev *pdev) |
1341 | { | 1346 | { |
1342 | struct fb_info *info = pci_get_drvdata(pdev); | 1347 | struct fb_info *info = pci_get_drvdata(pdev); |
1343 | struct tdfx_par *par = (struct tdfx_par *) info->par; | 1348 | struct tdfx_par *par = info->par; |
1344 | 1349 | ||
1345 | unregister_framebuffer(info); | 1350 | unregister_framebuffer(info); |
1346 | iounmap(par->regbase_virt); | 1351 | iounmap(par->regbase_virt); |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 3e58ddc2bc38..8982e540214c 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -57,7 +57,6 @@ static unsigned short *pmi_base = NULL; | |||
57 | static void (*pmi_start)(void); | 57 | static void (*pmi_start)(void); |
58 | static void (*pmi_pal)(void); | 58 | static void (*pmi_pal)(void); |
59 | static int depth; | 59 | static int depth; |
60 | static int vga_compat; | ||
61 | 60 | ||
62 | /* --------------------------------------------------------------------- */ | 61 | /* --------------------------------------------------------------------- */ |
63 | 62 | ||
@@ -67,15 +66,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, | |||
67 | #ifdef __i386__ | 66 | #ifdef __i386__ |
68 | int offset; | 67 | int offset; |
69 | 68 | ||
70 | if (!ypan) | ||
71 | return -EINVAL; | ||
72 | if (var->xoffset) | ||
73 | return -EINVAL; | ||
74 | if (var->yoffset > var->yres_virtual) | ||
75 | return -EINVAL; | ||
76 | if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual) | ||
77 | return -EINVAL; | ||
78 | |||
79 | offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4; | 69 | offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4; |
80 | 70 | ||
81 | __asm__ __volatile__( | 71 | __asm__ __volatile__( |
@@ -90,37 +80,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, | |||
90 | return 0; | 80 | return 0; |
91 | } | 81 | } |
92 | 82 | ||
93 | static int vesafb_blank(int blank, struct fb_info *info) | ||
94 | { | ||
95 | int err = 1; | ||
96 | |||
97 | if (vga_compat) { | ||
98 | int loop = 10000; | ||
99 | u8 seq = 0, crtc17 = 0; | ||
100 | |||
101 | if (blank == FB_BLANK_POWERDOWN) { | ||
102 | seq = 0x20; | ||
103 | crtc17 = 0x00; | ||
104 | err = 0; | ||
105 | } else { | ||
106 | seq = 0x00; | ||
107 | crtc17 = 0x80; | ||
108 | err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL; | ||
109 | } | ||
110 | |||
111 | vga_wseq(NULL, 0x00, 0x01); | ||
112 | seq |= vga_rseq(NULL, 0x01) & ~0x20; | ||
113 | vga_wseq(NULL, 0x00, seq); | ||
114 | |||
115 | crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80; | ||
116 | while (loop--); | ||
117 | vga_wcrt(NULL, 0x17, crtc17); | ||
118 | vga_wseq(NULL, 0x00, 0x03); | ||
119 | } | ||
120 | |||
121 | return err; | ||
122 | } | ||
123 | |||
124 | static void vesa_setpalette(int regno, unsigned red, unsigned green, | 83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, |
125 | unsigned blue) | 84 | unsigned blue) |
126 | { | 85 | { |
@@ -205,7 +164,6 @@ static struct fb_ops vesafb_ops = { | |||
205 | .owner = THIS_MODULE, | 164 | .owner = THIS_MODULE, |
206 | .fb_setcolreg = vesafb_setcolreg, | 165 | .fb_setcolreg = vesafb_setcolreg, |
207 | .fb_pan_display = vesafb_pan_display, | 166 | .fb_pan_display = vesafb_pan_display, |
208 | .fb_blank = vesafb_blank, | ||
209 | .fb_fillrect = cfb_fillrect, | 167 | .fb_fillrect = cfb_fillrect, |
210 | .fb_copyarea = cfb_copyarea, | 168 | .fb_copyarea = cfb_copyarea, |
211 | .fb_imageblit = cfb_imageblit, | 169 | .fb_imageblit = cfb_imageblit, |
@@ -459,9 +417,8 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
459 | info->flags = FBINFO_FLAG_DEFAULT | | 417 | info->flags = FBINFO_FLAG_DEFAULT | |
460 | (ypan) ? FBINFO_HWACCEL_YPAN : 0; | 418 | (ypan) ? FBINFO_HWACCEL_YPAN : 0; |
461 | 419 | ||
462 | vga_compat = (screen_info.capabilities & 2) ? 0 : 1; | 420 | if (!ypan) |
463 | printk("vesafb: Mode is %sVGA compatible\n", | 421 | info->fbops->fb_pan_display = NULL; |
464 | (vga_compat) ? "" : "not "); | ||
465 | 422 | ||
466 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | 423 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { |
467 | err = -ENOMEM; | 424 | err = -ENOMEM; |
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 226ae8a88482..f3f16fd9f231 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c | |||
@@ -705,15 +705,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
705 | static int vga16fb_pan_display(struct fb_var_screeninfo *var, | 705 | static int vga16fb_pan_display(struct fb_var_screeninfo *var, |
706 | struct fb_info *info) | 706 | struct fb_info *info) |
707 | { | 707 | { |
708 | if (var->xoffset + info->var.xres > info->var.xres_virtual || | ||
709 | var->yoffset + info->var.yres > info->var.yres_virtual) | ||
710 | return -EINVAL; | ||
711 | |||
712 | vga16fb_pan_var(info, var); | 708 | vga16fb_pan_var(info, var); |
713 | |||
714 | info->var.xoffset = var->xoffset; | ||
715 | info->var.yoffset = var->yoffset; | ||
716 | info->var.vmode &= ~FB_VMODE_YWRAP; | ||
717 | return 0; | 709 | return 0; |
718 | } | 710 | } |
719 | 711 | ||
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index d9e01daee630..15179ec62339 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c | |||
@@ -356,10 +356,11 @@ int save_vga(struct vgastate *state) | |||
356 | { | 356 | { |
357 | struct regstate *saved; | 357 | struct regstate *saved; |
358 | 358 | ||
359 | saved = kmalloc(sizeof(struct regstate), GFP_KERNEL); | 359 | saved = kzalloc(sizeof(struct regstate), GFP_KERNEL); |
360 | |||
360 | if (saved == NULL) | 361 | if (saved == NULL) |
361 | return 1; | 362 | return 1; |
362 | memset (saved, 0, sizeof(struct regstate)); | 363 | |
363 | state->vidstate = (void *)saved; | 364 | state->vidstate = (void *)saved; |
364 | 365 | ||
365 | if (state->flags & VGA_SAVE_CMAP) { | 366 | if (state->flags & VGA_SAVE_CMAP) { |