diff options
Diffstat (limited to 'drivers/char')
94 files changed, 6671 insertions, 6530 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 929d4fa73fd9..5dce3877eee5 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -80,6 +80,15 @@ config VT_HW_CONSOLE_BINDING | |||
80 | information. For framebuffer console users, please refer to | 80 | information. For framebuffer console users, please refer to |
81 | <file:Documentation/fb/fbcon.txt>. | 81 | <file:Documentation/fb/fbcon.txt>. |
82 | 82 | ||
83 | config DEVKMEM | ||
84 | bool "/dev/kmem virtual device support" | ||
85 | default y | ||
86 | help | ||
87 | Say Y here if you want to support the /dev/kmem device. The | ||
88 | /dev/kmem device is rarely used, but can be used for certain | ||
89 | kind of kernel debugging operations. | ||
90 | When in doubt, say "N". | ||
91 | |||
83 | config SERIAL_NONSTANDARD | 92 | config SERIAL_NONSTANDARD |
84 | bool "Non-standard serial port support" | 93 | bool "Non-standard serial port support" |
85 | depends on HAS_IOMEM | 94 | depends on HAS_IOMEM |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index c69f79598e47..99e6a406efb4 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | //#define AGP_DEBUG 1 | 36 | //#define AGP_DEBUG 1 |
37 | #ifdef AGP_DEBUG | 37 | #ifdef AGP_DEBUG |
38 | #define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __FUNCTION__ , ## y) | 38 | #define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __func__ , ## y) |
39 | #else | 39 | #else |
40 | #define DBG(x,y...) do { } while (0) | 40 | #define DBG(x,y...) do { } while (0) |
41 | #endif | 41 | #endif |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 3d468f502d2d..37457e5a4f2b 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -832,33 +832,34 @@ static void change_speed(struct async_struct *info, | |||
832 | local_irq_restore(flags); | 832 | local_irq_restore(flags); |
833 | } | 833 | } |
834 | 834 | ||
835 | static void rs_put_char(struct tty_struct *tty, unsigned char ch) | 835 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) |
836 | { | 836 | { |
837 | struct async_struct *info; | 837 | struct async_struct *info; |
838 | unsigned long flags; | 838 | unsigned long flags; |
839 | 839 | ||
840 | if (!tty) | 840 | if (!tty) |
841 | return; | 841 | return 0; |
842 | 842 | ||
843 | info = tty->driver_data; | 843 | info = tty->driver_data; |
844 | 844 | ||
845 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | 845 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
846 | return; | 846 | return 0; |
847 | 847 | ||
848 | if (!info->xmit.buf) | 848 | if (!info->xmit.buf) |
849 | return; | 849 | return 0; |
850 | 850 | ||
851 | local_irq_save(flags); | 851 | local_irq_save(flags); |
852 | if (CIRC_SPACE(info->xmit.head, | 852 | if (CIRC_SPACE(info->xmit.head, |
853 | info->xmit.tail, | 853 | info->xmit.tail, |
854 | SERIAL_XMIT_SIZE) == 0) { | 854 | SERIAL_XMIT_SIZE) == 0) { |
855 | local_irq_restore(flags); | 855 | local_irq_restore(flags); |
856 | return; | 856 | return 0; |
857 | } | 857 | } |
858 | 858 | ||
859 | info->xmit.buf[info->xmit.head++] = ch; | 859 | info->xmit.buf[info->xmit.head++] = ch; |
860 | info->xmit.head &= SERIAL_XMIT_SIZE-1; | 860 | info->xmit.head &= SERIAL_XMIT_SIZE-1; |
861 | local_irq_restore(flags); | 861 | local_irq_restore(flags); |
862 | return 1; | ||
862 | } | 863 | } |
863 | 864 | ||
864 | static void rs_flush_chars(struct tty_struct *tty) | 865 | static void rs_flush_chars(struct tty_struct *tty) |
@@ -1074,6 +1075,7 @@ static int get_serial_info(struct async_struct * info, | |||
1074 | if (!retinfo) | 1075 | if (!retinfo) |
1075 | return -EFAULT; | 1076 | return -EFAULT; |
1076 | memset(&tmp, 0, sizeof(tmp)); | 1077 | memset(&tmp, 0, sizeof(tmp)); |
1078 | lock_kernel(); | ||
1077 | tmp.type = state->type; | 1079 | tmp.type = state->type; |
1078 | tmp.line = state->line; | 1080 | tmp.line = state->line; |
1079 | tmp.port = state->port; | 1081 | tmp.port = state->port; |
@@ -1084,6 +1086,7 @@ static int get_serial_info(struct async_struct * info, | |||
1084 | tmp.close_delay = state->close_delay; | 1086 | tmp.close_delay = state->close_delay; |
1085 | tmp.closing_wait = state->closing_wait; | 1087 | tmp.closing_wait = state->closing_wait; |
1086 | tmp.custom_divisor = state->custom_divisor; | 1088 | tmp.custom_divisor = state->custom_divisor; |
1089 | unlock_kernel(); | ||
1087 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1090 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
1088 | return -EFAULT; | 1091 | return -EFAULT; |
1089 | return 0; | 1092 | return 0; |
@@ -1099,13 +1102,17 @@ static int set_serial_info(struct async_struct * info, | |||
1099 | 1102 | ||
1100 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1103 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
1101 | return -EFAULT; | 1104 | return -EFAULT; |
1105 | |||
1106 | lock_kernel(); | ||
1102 | state = info->state; | 1107 | state = info->state; |
1103 | old_state = *state; | 1108 | old_state = *state; |
1104 | 1109 | ||
1105 | change_irq = new_serial.irq != state->irq; | 1110 | change_irq = new_serial.irq != state->irq; |
1106 | change_port = (new_serial.port != state->port); | 1111 | change_port = (new_serial.port != state->port); |
1107 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) | 1112 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { |
1113 | unlock_kernel(); | ||
1108 | return -EINVAL; | 1114 | return -EINVAL; |
1115 | } | ||
1109 | 1116 | ||
1110 | if (!serial_isroot()) { | 1117 | if (!serial_isroot()) { |
1111 | if ((new_serial.baud_base != state->baud_base) || | 1118 | if ((new_serial.baud_base != state->baud_base) || |
@@ -1122,8 +1129,10 @@ static int set_serial_info(struct async_struct * info, | |||
1122 | goto check_and_exit; | 1129 | goto check_and_exit; |
1123 | } | 1130 | } |
1124 | 1131 | ||
1125 | if (new_serial.baud_base < 9600) | 1132 | if (new_serial.baud_base < 9600) { |
1133 | unlock_kernel(); | ||
1126 | return -EINVAL; | 1134 | return -EINVAL; |
1135 | } | ||
1127 | 1136 | ||
1128 | /* | 1137 | /* |
1129 | * OK, past this point, all the error checking has been done. | 1138 | * OK, past this point, all the error checking has been done. |
@@ -1157,6 +1166,7 @@ check_and_exit: | |||
1157 | } | 1166 | } |
1158 | } else | 1167 | } else |
1159 | retval = startup(info); | 1168 | retval = startup(info); |
1169 | unlock_kernel(); | ||
1160 | return retval; | 1170 | return retval; |
1161 | } | 1171 | } |
1162 | 1172 | ||
@@ -1496,8 +1506,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1496 | rs_wait_until_sent(tty, info->timeout); | 1506 | rs_wait_until_sent(tty, info->timeout); |
1497 | } | 1507 | } |
1498 | shutdown(info); | 1508 | shutdown(info); |
1499 | if (tty->driver->flush_buffer) | 1509 | rs_flush_buffer(tty); |
1500 | tty->driver->flush_buffer(tty); | ||
1501 | 1510 | ||
1502 | tty_ldisc_flush(tty); | 1511 | tty_ldisc_flush(tty); |
1503 | tty->closing = 0; | 1512 | tty->closing = 0; |
@@ -1530,6 +1539,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1530 | return; /* Just in case.... */ | 1539 | return; /* Just in case.... */ |
1531 | 1540 | ||
1532 | orig_jiffies = jiffies; | 1541 | orig_jiffies = jiffies; |
1542 | |||
1543 | lock_kernel(); | ||
1533 | /* | 1544 | /* |
1534 | * Set the check interval to be 1/5 of the estimated time to | 1545 | * Set the check interval to be 1/5 of the estimated time to |
1535 | * send a single character, and make it at least 1. The check | 1546 | * send a single character, and make it at least 1. The check |
@@ -1570,6 +1581,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1570 | break; | 1581 | break; |
1571 | } | 1582 | } |
1572 | __set_current_state(TASK_RUNNING); | 1583 | __set_current_state(TASK_RUNNING); |
1584 | unlock_kernel(); | ||
1573 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1585 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1574 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1586 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1575 | #endif | 1587 | #endif |
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 17d54315e146..cdd876dbb2b0 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/poll.h> | 14 | #include <linux/poll.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
17 | #include <linux/seq_file.h> | ||
17 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
18 | #include <linux/apm_bios.h> | 19 | #include <linux/apm_bios.h> |
19 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
@@ -493,11 +494,10 @@ static struct miscdevice apm_device = { | |||
493 | * -1: Unknown | 494 | * -1: Unknown |
494 | * 8) min = minutes; sec = seconds | 495 | * 8) min = minutes; sec = seconds |
495 | */ | 496 | */ |
496 | static int apm_get_info(char *buf, char **start, off_t fpos, int length) | 497 | static int proc_apm_show(struct seq_file *m, void *v) |
497 | { | 498 | { |
498 | struct apm_power_info info; | 499 | struct apm_power_info info; |
499 | char *units; | 500 | char *units; |
500 | int ret; | ||
501 | 501 | ||
502 | info.ac_line_status = 0xff; | 502 | info.ac_line_status = 0xff; |
503 | info.battery_status = 0xff; | 503 | info.battery_status = 0xff; |
@@ -515,14 +515,27 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
515 | case 1: units = "sec"; break; | 515 | case 1: units = "sec"; break; |
516 | } | 516 | } |
517 | 517 | ||
518 | ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", | 518 | seq_printf(m, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", |
519 | driver_version, APM_32_BIT_SUPPORT, | 519 | driver_version, APM_32_BIT_SUPPORT, |
520 | info.ac_line_status, info.battery_status, | 520 | info.ac_line_status, info.battery_status, |
521 | info.battery_flag, info.battery_life, | 521 | info.battery_flag, info.battery_life, |
522 | info.time, units); | 522 | info.time, units); |
523 | 523 | ||
524 | return ret; | 524 | return 0; |
525 | } | 525 | } |
526 | |||
527 | static int proc_apm_open(struct inode *inode, struct file *file) | ||
528 | { | ||
529 | return single_open(file, proc_apm_show, NULL); | ||
530 | } | ||
531 | |||
532 | static const struct file_operations apm_proc_fops = { | ||
533 | .owner = THIS_MODULE, | ||
534 | .open = proc_apm_open, | ||
535 | .read = seq_read, | ||
536 | .llseek = seq_lseek, | ||
537 | .release = single_release, | ||
538 | }; | ||
526 | #endif | 539 | #endif |
527 | 540 | ||
528 | static int kapmd(void *arg) | 541 | static int kapmd(void *arg) |
@@ -593,7 +606,7 @@ static int __init apm_init(void) | |||
593 | wake_up_process(kapmd_tsk); | 606 | wake_up_process(kapmd_tsk); |
594 | 607 | ||
595 | #ifdef CONFIG_PROC_FS | 608 | #ifdef CONFIG_PROC_FS |
596 | create_proc_info_entry("apm", 0, NULL, apm_get_info); | 609 | proc_create("apm", 0, NULL, &apm_proc_fops); |
597 | #endif | 610 | #endif |
598 | 611 | ||
599 | ret = misc_register(&apm_device); | 612 | ret = misc_register(&apm_device); |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index a7c4990b5b6b..31d08b641f5b 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -199,7 +199,7 @@ static int __init applicom_init(void) | |||
199 | if (pci_enable_device(dev)) | 199 | if (pci_enable_device(dev)) |
200 | return -EIO; | 200 | return -EIO; |
201 | 201 | ||
202 | RamIO = ioremap(pci_resource_start(dev, 0), LEN_RAM_IO); | 202 | RamIO = ioremap_nocache(pci_resource_start(dev, 0), LEN_RAM_IO); |
203 | 203 | ||
204 | if (!RamIO) { | 204 | if (!RamIO) { |
205 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory " | 205 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory " |
@@ -254,7 +254,7 @@ static int __init applicom_init(void) | |||
254 | /* Now try the specified ISA cards */ | 254 | /* Now try the specified ISA cards */ |
255 | 255 | ||
256 | for (i = 0; i < MAX_ISA_BOARD; i++) { | 256 | for (i = 0; i < MAX_ISA_BOARD; i++) { |
257 | RamIO = ioremap(mem + (LEN_RAM_IO * i), LEN_RAM_IO); | 257 | RamIO = ioremap_nocache(mem + (LEN_RAM_IO * i), LEN_RAM_IO); |
258 | 258 | ||
259 | if (!RamIO) { | 259 | if (!RamIO) { |
260 | printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1); | 260 | printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1); |
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index 6b104e45a322..4246b8e36cb3 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
@@ -277,6 +277,7 @@ u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode) | |||
277 | return p->inverse_translations[m][glyph]; | 277 | return p->inverse_translations[m][glyph]; |
278 | } | 278 | } |
279 | } | 279 | } |
280 | EXPORT_SYMBOL_GPL(inverse_translate); | ||
280 | 281 | ||
281 | static void update_user_maps(void) | 282 | static void update_user_maps(void) |
282 | { | 283 | { |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e4f579c3e245..ef73e72daedc 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -21,7 +21,6 @@ | |||
21 | * | 21 | * |
22 | * This version supports shared IRQ's (only for PCI boards). | 22 | * This version supports shared IRQ's (only for PCI boards). |
23 | * | 23 | * |
24 | * $Log: cyclades.c,v $ | ||
25 | * Prevent users from opening non-existing Z ports. | 24 | * Prevent users from opening non-existing Z ports. |
26 | * | 25 | * |
27 | * Revision 2.3.2.8 2000/07/06 18:14:16 ivan | 26 | * Revision 2.3.2.8 2000/07/06 18:14:16 ivan |
@@ -62,7 +61,7 @@ | |||
62 | * Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined; | 61 | * Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined; |
63 | * | 62 | * |
64 | * Revision 2.3.2.2 1999/10/01 11:27:43 ivan | 63 | * Revision 2.3.2.2 1999/10/01 11:27:43 ivan |
65 | * Fixed bug in cyz_poll that would make all ports but port 0 | 64 | * Fixed bug in cyz_poll that would make all ports but port 0 |
66 | * unable to transmit/receive data (Cyclades-Z only); | 65 | * unable to transmit/receive data (Cyclades-Z only); |
67 | * Implemented logic to prevent the RX buffer from being stuck with data | 66 | * Implemented logic to prevent the RX buffer from being stuck with data |
68 | * due to a driver / firmware race condition in interrupt op mode | 67 | * due to a driver / firmware race condition in interrupt op mode |
@@ -83,25 +82,25 @@ | |||
83 | * Revision 2.3.1.1 1999/07/15 16:45:53 ivan | 82 | * Revision 2.3.1.1 1999/07/15 16:45:53 ivan |
84 | * Removed CY_PROC conditional compilation; | 83 | * Removed CY_PROC conditional compilation; |
85 | * Implemented SMP-awareness for the driver; | 84 | * Implemented SMP-awareness for the driver; |
86 | * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off] | 85 | * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off] |
87 | * functions; | 86 | * functions; |
88 | * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs | 87 | * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs |
89 | * (irq=NN) as parameters (only for ISA boards); | 88 | * (irq=NN) as parameters (only for ISA boards); |
90 | * Fixed bug in set_line_char that would prevent the Cyclades-Z | 89 | * Fixed bug in set_line_char that would prevent the Cyclades-Z |
91 | * ports from being configured at speeds above 115.2Kbps; | 90 | * ports from being configured at speeds above 115.2Kbps; |
92 | * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control | 91 | * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control |
93 | * switching from working properly; | 92 | * switching from working properly; |
94 | * The driver now only prints IRQ info for the Cyclades-Z if it's | 93 | * The driver now only prints IRQ info for the Cyclades-Z if it's |
95 | * configured to work in interrupt mode; | 94 | * configured to work in interrupt mode; |
96 | * | 95 | * |
97 | * Revision 2.2.2.3 1999/06/28 11:13:29 ivan | 96 | * Revision 2.2.2.3 1999/06/28 11:13:29 ivan |
98 | * Added support for interrupt mode operation for the Z cards; | 97 | * Added support for interrupt mode operation for the Z cards; |
99 | * Removed the driver inactivity control for the Z; | 98 | * Removed the driver inactivity control for the Z; |
100 | * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when | 99 | * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when |
101 | * the Z firmware is not loaded yet; | 100 | * the Z firmware is not loaded yet; |
102 | * Replaced the "manual" Z Tx flush buffer by a call to a FW command of | 101 | * Replaced the "manual" Z Tx flush buffer by a call to a FW command of |
103 | * same functionality; | 102 | * same functionality; |
104 | * Implemented workaround for IRQ setting loss on the PCI configuration | 103 | * Implemented workaround for IRQ setting loss on the PCI configuration |
105 | * registers after a PCI bridge EEPROM reload (affects PLX9060 only); | 104 | * registers after a PCI bridge EEPROM reload (affects PLX9060 only); |
106 | * | 105 | * |
107 | * Revision 2.2.2.2 1999/05/14 17:18:15 ivan | 106 | * Revision 2.2.2.2 1999/05/14 17:18:15 ivan |
@@ -112,22 +111,22 @@ | |||
112 | * BREAK implementation changed in order to make use of the 'break_ctl' | 111 | * BREAK implementation changed in order to make use of the 'break_ctl' |
113 | * TTY facility; | 112 | * TTY facility; |
114 | * Fixed typo in TTY structure field 'driver_name'; | 113 | * Fixed typo in TTY structure field 'driver_name'; |
115 | * Included a PCI bridge reset and EEPROM reload in the board | 114 | * Included a PCI bridge reset and EEPROM reload in the board |
116 | * initialization code (for both Y and Z series). | 115 | * initialization code (for both Y and Z series). |
117 | * | 116 | * |
118 | * Revision 2.2.2.1 1999/04/08 16:17:43 ivan | 117 | * Revision 2.2.2.1 1999/04/08 16:17:43 ivan |
119 | * Fixed a bug in cy_wait_until_sent that was preventing the port to be | 118 | * Fixed a bug in cy_wait_until_sent that was preventing the port to be |
120 | * closed properly after a SIGINT; | 119 | * closed properly after a SIGINT; |
121 | * Module usage counter scheme revisited; | 120 | * Module usage counter scheme revisited; |
122 | * Added support to the upcoming Y PCI boards (i.e., support to additional | 121 | * Added support to the upcoming Y PCI boards (i.e., support to additional |
123 | * PCI Device ID's). | 122 | * PCI Device ID's). |
124 | * | 123 | * |
125 | * Revision 2.2.1.10 1999/01/20 16:14:29 ivan | 124 | * Revision 2.2.1.10 1999/01/20 16:14:29 ivan |
126 | * Removed all unnecessary page-alignement operations in ioremap calls | 125 | * Removed all unnecessary page-alignement operations in ioremap calls |
127 | * (ioremap is currently safe for these operations). | 126 | * (ioremap is currently safe for these operations). |
128 | * | 127 | * |
129 | * Revision 2.2.1.9 1998/12/30 18:18:30 ivan | 128 | * Revision 2.2.1.9 1998/12/30 18:18:30 ivan |
130 | * Changed access to PLX PCI bridge registers from I/O to MMIO, in | 129 | * Changed access to PLX PCI bridge registers from I/O to MMIO, in |
131 | * order to make PLX9050-based boards work with certain motherboards. | 130 | * order to make PLX9050-based boards work with certain motherboards. |
132 | * | 131 | * |
133 | * Revision 2.2.1.8 1998/11/13 12:46:20 ivan | 132 | * Revision 2.2.1.8 1998/11/13 12:46:20 ivan |
@@ -148,7 +147,7 @@ | |||
148 | * Fixed Cyclom-4Yo hardware detection bug. | 147 | * Fixed Cyclom-4Yo hardware detection bug. |
149 | * | 148 | * |
150 | * Revision 2.2.1.4 1998/08/04 11:02:50 ivan | 149 | * Revision 2.2.1.4 1998/08/04 11:02:50 ivan |
151 | * /proc/cyclades implementation with great collaboration of | 150 | * /proc/cyclades implementation with great collaboration of |
152 | * Marc Lewis <marc@blarg.net>; | 151 | * Marc Lewis <marc@blarg.net>; |
153 | * cyy_interrupt was changed to avoid occurrence of kernel oopses | 152 | * cyy_interrupt was changed to avoid occurrence of kernel oopses |
154 | * during PPP operation. | 153 | * during PPP operation. |
@@ -157,7 +156,7 @@ | |||
157 | * General code review in order to comply with 2.1 kernel standards; | 156 | * General code review in order to comply with 2.1 kernel standards; |
158 | * data loss prevention for slow devices revisited (cy_wait_until_sent | 157 | * data loss prevention for slow devices revisited (cy_wait_until_sent |
159 | * was created); | 158 | * was created); |
160 | * removed conditional compilation for new/old PCI structure support | 159 | * removed conditional compilation for new/old PCI structure support |
161 | * (now the driver only supports the new PCI structure). | 160 | * (now the driver only supports the new PCI structure). |
162 | * | 161 | * |
163 | * Revision 2.2.1.1 1998/03/19 16:43:12 ivan | 162 | * Revision 2.2.1.1 1998/03/19 16:43:12 ivan |
@@ -168,7 +167,7 @@ | |||
168 | * cleaned up the data loss fix; | 167 | * cleaned up the data loss fix; |
169 | * fixed XON/XOFF handling once more (Cyclades-Z); | 168 | * fixed XON/XOFF handling once more (Cyclades-Z); |
170 | * general review of the driver routines; | 169 | * general review of the driver routines; |
171 | * introduction of a mechanism to prevent data loss with slow | 170 | * introduction of a mechanism to prevent data loss with slow |
172 | * printers, by forcing a delay before closing the port. | 171 | * printers, by forcing a delay before closing the port. |
173 | * | 172 | * |
174 | * Revision 2.1.1.2 1998/02/17 16:50:00 ivan | 173 | * Revision 2.1.1.2 1998/02/17 16:50:00 ivan |
@@ -182,12 +181,12 @@ | |||
182 | * Code review for the module cleanup routine; | 181 | * Code review for the module cleanup routine; |
183 | * fixed RTS and DTR status report for new CD1400's in get_modem_info; | 182 | * fixed RTS and DTR status report for new CD1400's in get_modem_info; |
184 | * includes anonymous changes regarding signal_pending. | 183 | * includes anonymous changes regarding signal_pending. |
185 | * | 184 | * |
186 | * Revision 2.1 1997/11/01 17:42:41 ivan | 185 | * Revision 2.1 1997/11/01 17:42:41 ivan |
187 | * Changes in the driver to support Alpha systems (except 8Zo V_1); | 186 | * Changes in the driver to support Alpha systems (except 8Zo V_1); |
188 | * BREAK fix for the Cyclades-Z boards; | 187 | * BREAK fix for the Cyclades-Z boards; |
189 | * driver inactivity control by FW implemented; | 188 | * driver inactivity control by FW implemented; |
190 | * introduction of flag that allows driver to take advantage of | 189 | * introduction of flag that allows driver to take advantage of |
191 | * a special CD1400 feature related to HW flow control; | 190 | * a special CD1400 feature related to HW flow control; |
192 | * added support for the CD1400 rev. J (Cyclom-Y boards); | 191 | * added support for the CD1400 rev. J (Cyclom-Y boards); |
193 | * introduction of ioctls to: | 192 | * introduction of ioctls to: |
@@ -196,17 +195,17 @@ | |||
196 | * - adjust the polling interval (Cyclades-Z); | 195 | * - adjust the polling interval (Cyclades-Z); |
197 | * | 196 | * |
198 | * Revision 1.36.4.33 1997/06/27 19:00:00 ivan | 197 | * Revision 1.36.4.33 1997/06/27 19:00:00 ivan |
199 | * Fixes related to kernel version conditional | 198 | * Fixes related to kernel version conditional |
200 | * compilation. | 199 | * compilation. |
201 | * | 200 | * |
202 | * Revision 1.36.4.32 1997/06/14 19:30:00 ivan | 201 | * Revision 1.36.4.32 1997/06/14 19:30:00 ivan |
203 | * Compatibility issues between kernels 2.0.x and | 202 | * Compatibility issues between kernels 2.0.x and |
204 | * 2.1.x (mainly related to clear_bit function). | 203 | * 2.1.x (mainly related to clear_bit function). |
205 | * | 204 | * |
206 | * Revision 1.36.4.31 1997/06/03 15:30:00 ivan | 205 | * Revision 1.36.4.31 1997/06/03 15:30:00 ivan |
207 | * Changes to define the memory window according to the | 206 | * Changes to define the memory window according to the |
208 | * board type. | 207 | * board type. |
209 | * | 208 | * |
210 | * Revision 1.36.4.30 1997/05/16 15:30:00 daniel | 209 | * Revision 1.36.4.30 1997/05/16 15:30:00 daniel |
211 | * Changes to support new cycladesZ boards. | 210 | * Changes to support new cycladesZ boards. |
212 | * | 211 | * |
@@ -624,7 +623,7 @@ | |||
624 | #undef CY_PCI_DEBUG | 623 | #undef CY_PCI_DEBUG |
625 | 624 | ||
626 | /* | 625 | /* |
627 | * Include section | 626 | * Include section |
628 | */ | 627 | */ |
629 | #include <linux/module.h> | 628 | #include <linux/module.h> |
630 | #include <linux/errno.h> | 629 | #include <linux/errno.h> |
@@ -649,9 +648,9 @@ | |||
649 | #include <linux/firmware.h> | 648 | #include <linux/firmware.h> |
650 | 649 | ||
651 | #include <asm/system.h> | 650 | #include <asm/system.h> |
652 | #include <asm/io.h> | 651 | #include <linux/io.h> |
653 | #include <asm/irq.h> | 652 | #include <asm/irq.h> |
654 | #include <asm/uaccess.h> | 653 | #include <linux/uaccess.h> |
655 | 654 | ||
656 | #include <linux/kernel.h> | 655 | #include <linux/kernel.h> |
657 | #include <linux/pci.h> | 656 | #include <linux/pci.h> |
@@ -668,10 +667,10 @@ static void cy_send_xchar(struct tty_struct *tty, char ch); | |||
668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ | 667 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
669 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) | 668 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) |
670 | 669 | ||
671 | #define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \ | 670 | #define ISZLOADED(card) (((ZO_V1 == readl(&((struct RUNTIME_9060 __iomem *) \ |
672 | ((card).ctl_addr))->mail_box_0)) || \ | 671 | ((card).ctl_addr))->mail_box_0)) || \ |
673 | Z_FPGA_CHECK(card)) && \ | 672 | Z_FPGA_CHECK(card)) && \ |
674 | (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \ | 673 | (ZFIRM_ID == readl(&((struct FIRM_ID __iomem *) \ |
675 | ((card).base_addr+ID_ADDRESS))->signature))) | 674 | ((card).base_addr+ID_ADDRESS))->signature))) |
676 | 675 | ||
677 | #ifndef SERIAL_XMIT_SIZE | 676 | #ifndef SERIAL_XMIT_SIZE |
@@ -809,12 +808,12 @@ static char baud_cor3[] = { /* receive threshold */ | |||
809 | 808 | ||
810 | /* | 809 | /* |
811 | * The Cyclades driver implements HW flow control as any serial driver. | 810 | * The Cyclades driver implements HW flow control as any serial driver. |
812 | * The cyclades_port structure member rflow and the vector rflow_thr | 811 | * The cyclades_port structure member rflow and the vector rflow_thr |
813 | * allows us to take advantage of a special feature in the CD1400 to avoid | 812 | * allows us to take advantage of a special feature in the CD1400 to avoid |
814 | * data loss even when the system interrupt latency is too high. These flags | 813 | * data loss even when the system interrupt latency is too high. These flags |
815 | * are to be used only with very special applications. Setting these flags | 814 | * are to be used only with very special applications. Setting these flags |
816 | * requires the use of a special cable (DTR and RTS reversed). In the new | 815 | * requires the use of a special cable (DTR and RTS reversed). In the new |
817 | * CD1400-based boards (rev. 6.00 or later), there is no need for special | 816 | * CD1400-based boards (rev. 6.00 or later), there is no need for special |
818 | * cables. | 817 | * cables. |
819 | */ | 818 | */ |
820 | 819 | ||
@@ -841,14 +840,22 @@ static int cy_chip_offset[] = { 0x0000, | |||
841 | 840 | ||
842 | #ifdef CONFIG_PCI | 841 | #ifdef CONFIG_PCI |
843 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { | 842 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { |
844 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ | 843 | /* PCI < 1Mb */ |
845 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, /* PCI > 1Mb */ | 844 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, |
846 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, /* 4Y PCI < 1Mb */ | 845 | /* PCI > 1Mb */ |
847 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, /* 4Y PCI > 1Mb */ | 846 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, |
848 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, /* 8Y PCI < 1Mb */ | 847 | /* 4Y PCI < 1Mb */ |
849 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, /* 8Y PCI > 1Mb */ | 848 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, |
850 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, /* Z PCI < 1Mb */ | 849 | /* 4Y PCI > 1Mb */ |
851 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, /* Z PCI > 1Mb */ | 850 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, |
851 | /* 8Y PCI < 1Mb */ | ||
852 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, | ||
853 | /* 8Y PCI > 1Mb */ | ||
854 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, | ||
855 | /* Z PCI < 1Mb */ | ||
856 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, | ||
857 | /* Z PCI > 1Mb */ | ||
858 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, | ||
852 | { } /* end of table */ | 859 | { } /* end of table */ |
853 | }; | 860 | }; |
854 | MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); | 861 | MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); |
@@ -905,15 +912,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
905 | 912 | ||
906 | This function is only called from inside spinlock-protected code. | 913 | This function is only called from inside spinlock-protected code. |
907 | */ | 914 | */ |
908 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) | 915 | static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index) |
909 | { | 916 | { |
910 | unsigned int i; | 917 | unsigned int i; |
911 | 918 | ||
912 | /* Check to see that the previous command has completed */ | 919 | /* Check to see that the previous command has completed */ |
913 | for (i = 0; i < 100; i++) { | 920 | for (i = 0; i < 100; i++) { |
914 | if (readb(base_addr + (CyCCR << index)) == 0) { | 921 | if (readb(base_addr + (CyCCR << index)) == 0) |
915 | break; | 922 | break; |
916 | } | ||
917 | udelay(10L); | 923 | udelay(10L); |
918 | } | 924 | } |
919 | /* if the CCR never cleared, the previous command | 925 | /* if the CCR never cleared, the previous command |
@@ -929,7 +935,7 @@ static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) | |||
929 | 935 | ||
930 | #ifdef CONFIG_ISA | 936 | #ifdef CONFIG_ISA |
931 | /* ISA interrupt detection code */ | 937 | /* ISA interrupt detection code */ |
932 | static unsigned detect_isa_irq(void __iomem * address) | 938 | static unsigned detect_isa_irq(void __iomem *address) |
933 | { | 939 | { |
934 | int irq; | 940 | int irq; |
935 | unsigned long irqs, flags; | 941 | unsigned long irqs, flags; |
@@ -1038,7 +1044,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
1038 | if (info->flags & ASYNC_SAK) | 1044 | if (info->flags & ASYNC_SAK) |
1039 | do_SAK(tty); | 1045 | do_SAK(tty); |
1040 | } else if (data & CyFRAME) { | 1046 | } else if (data & CyFRAME) { |
1041 | tty_insert_flip_char( tty, | 1047 | tty_insert_flip_char(tty, |
1042 | readb(base_addr + (CyRDSR << | 1048 | readb(base_addr + (CyRDSR << |
1043 | index)), TTY_FRAME); | 1049 | index)), TTY_FRAME); |
1044 | info->icount.rx++; | 1050 | info->icount.rx++; |
@@ -1320,7 +1326,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1320 | 1326 | ||
1321 | if (unlikely(cinfo == NULL)) { | 1327 | if (unlikely(cinfo == NULL)) { |
1322 | #ifdef CY_DEBUG_INTERRUPTS | 1328 | #ifdef CY_DEBUG_INTERRUPTS |
1323 | printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq); | 1329 | printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n", |
1330 | irq); | ||
1324 | #endif | 1331 | #endif |
1325 | return IRQ_NONE; /* spurious interrupt */ | 1332 | return IRQ_NONE; /* spurious interrupt */ |
1326 | } | 1333 | } |
@@ -1375,12 +1382,12 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1375 | 1382 | ||
1376 | /***********************************************************/ | 1383 | /***********************************************************/ |
1377 | /********* End of block of Cyclom-Y specific code **********/ | 1384 | /********* End of block of Cyclom-Y specific code **********/ |
1378 | /******** Start of block of Cyclades-Z specific code *********/ | 1385 | /******** Start of block of Cyclades-Z specific code *******/ |
1379 | /***********************************************************/ | 1386 | /***********************************************************/ |
1380 | 1387 | ||
1381 | static int | 1388 | static int |
1382 | cyz_fetch_msg(struct cyclades_card *cinfo, | 1389 | cyz_fetch_msg(struct cyclades_card *cinfo, |
1383 | __u32 * channel, __u8 * cmd, __u32 * param) | 1390 | __u32 *channel, __u8 *cmd, __u32 *param) |
1384 | { | 1391 | { |
1385 | struct FIRM_ID __iomem *firm_id; | 1392 | struct FIRM_ID __iomem *firm_id; |
1386 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1393 | struct ZFW_CTRL __iomem *zfw_ctrl; |
@@ -1388,9 +1395,8 @@ cyz_fetch_msg(struct cyclades_card *cinfo, | |||
1388 | unsigned long loc_doorbell; | 1395 | unsigned long loc_doorbell; |
1389 | 1396 | ||
1390 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1397 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1391 | if (!ISZLOADED(*cinfo)) { | 1398 | if (!ISZLOADED(*cinfo)) |
1392 | return -1; | 1399 | return -1; |
1393 | } | ||
1394 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1400 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1395 | board_ctrl = &zfw_ctrl->board_ctrl; | 1401 | board_ctrl = &zfw_ctrl->board_ctrl; |
1396 | 1402 | ||
@@ -1418,9 +1424,9 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1418 | unsigned int index; | 1424 | unsigned int index; |
1419 | 1425 | ||
1420 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1426 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1421 | if (!ISZLOADED(*cinfo)) { | 1427 | if (!ISZLOADED(*cinfo)) |
1422 | return -1; | 1428 | return -1; |
1423 | } | 1429 | |
1424 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1430 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1425 | board_ctrl = &zfw_ctrl->board_ctrl; | 1431 | board_ctrl = &zfw_ctrl->board_ctrl; |
1426 | 1432 | ||
@@ -1428,9 +1434,8 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1428 | pci_doorbell = | 1434 | pci_doorbell = |
1429 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; | 1435 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; |
1430 | while ((readl(pci_doorbell) & 0xff) != 0) { | 1436 | while ((readl(pci_doorbell) & 0xff) != 0) { |
1431 | if (index++ == 1000) { | 1437 | if (index++ == 1000) |
1432 | return (int)(readl(pci_doorbell) & 0xff); | 1438 | return (int)(readl(pci_doorbell) & 0xff); |
1433 | } | ||
1434 | udelay(50L); | 1439 | udelay(50L); |
1435 | } | 1440 | } |
1436 | cy_writel(&board_ctrl->hcmd_channel, channel); | 1441 | cy_writel(&board_ctrl->hcmd_channel, channel); |
@@ -1504,7 +1509,8 @@ static void cyz_handle_rx(struct cyclades_port *info, | |||
1504 | while (len--) { | 1509 | while (len--) { |
1505 | data = readb(cinfo->base_addr + rx_bufaddr + | 1510 | data = readb(cinfo->base_addr + rx_bufaddr + |
1506 | new_rx_get); | 1511 | new_rx_get); |
1507 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); | 1512 | new_rx_get = (new_rx_get + 1) & |
1513 | (rx_bufsize - 1); | ||
1508 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 1514 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1509 | info->idle_stats.recv_bytes++; | 1515 | info->idle_stats.recv_bytes++; |
1510 | info->icount.rx++; | 1516 | info->icount.rx++; |
@@ -1636,7 +1642,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1636 | special_count = 0; | 1642 | special_count = 0; |
1637 | delta_count = 0; | 1643 | delta_count = 0; |
1638 | info = &cinfo->ports[channel]; | 1644 | info = &cinfo->ports[channel]; |
1639 | if ((tty = info->tty) == NULL) | 1645 | tty = info->tty; |
1646 | if (tty == NULL) | ||
1640 | continue; | 1647 | continue; |
1641 | 1648 | ||
1642 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 1649 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
@@ -1732,7 +1739,8 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id) | |||
1732 | 1739 | ||
1733 | if (unlikely(cinfo == NULL)) { | 1740 | if (unlikely(cinfo == NULL)) { |
1734 | #ifdef CY_DEBUG_INTERRUPTS | 1741 | #ifdef CY_DEBUG_INTERRUPTS |
1735 | printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq); | 1742 | printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n", |
1743 | irq); | ||
1736 | #endif | 1744 | #endif |
1737 | return IRQ_NONE; /* spurious interrupt */ | 1745 | return IRQ_NONE; /* spurious interrupt */ |
1738 | } | 1746 | } |
@@ -1851,9 +1859,8 @@ static int startup(struct cyclades_port *info) | |||
1851 | } | 1859 | } |
1852 | 1860 | ||
1853 | if (!info->type) { | 1861 | if (!info->type) { |
1854 | if (info->tty) { | 1862 | if (info->tty) |
1855 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 1863 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
1856 | } | ||
1857 | free_page(page); | 1864 | free_page(page); |
1858 | goto errout; | 1865 | goto errout; |
1859 | } | 1866 | } |
@@ -1904,9 +1911,8 @@ static int startup(struct cyclades_port *info) | |||
1904 | readb(base_addr + (CySRER << index)) | CyRxData); | 1911 | readb(base_addr + (CySRER << index)) | CyRxData); |
1905 | info->flags |= ASYNC_INITIALIZED; | 1912 | info->flags |= ASYNC_INITIALIZED; |
1906 | 1913 | ||
1907 | if (info->tty) { | 1914 | if (info->tty) |
1908 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 1915 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
1909 | } | ||
1910 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 1916 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
1911 | info->breakon = info->breakoff = 0; | 1917 | info->breakon = info->breakoff = 0; |
1912 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); | 1918 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); |
@@ -1925,9 +1931,8 @@ static int startup(struct cyclades_port *info) | |||
1925 | base_addr = card->base_addr; | 1931 | base_addr = card->base_addr; |
1926 | 1932 | ||
1927 | firm_id = base_addr + ID_ADDRESS; | 1933 | firm_id = base_addr + ID_ADDRESS; |
1928 | if (!ISZLOADED(*card)) { | 1934 | if (!ISZLOADED(*card)) |
1929 | return -ENODEV; | 1935 | return -ENODEV; |
1930 | } | ||
1931 | 1936 | ||
1932 | zfw_ctrl = card->base_addr + | 1937 | zfw_ctrl = card->base_addr + |
1933 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1938 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
@@ -1990,9 +1995,8 @@ static int startup(struct cyclades_port *info) | |||
1990 | /* enable send, recv, modem !!! */ | 1995 | /* enable send, recv, modem !!! */ |
1991 | 1996 | ||
1992 | info->flags |= ASYNC_INITIALIZED; | 1997 | info->flags |= ASYNC_INITIALIZED; |
1993 | if (info->tty) { | 1998 | if (info->tty) |
1994 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 1999 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
1995 | } | ||
1996 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 2000 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
1997 | info->breakon = info->breakoff = 0; | 2001 | info->breakon = info->breakoff = 0; |
1998 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); | 2002 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); |
@@ -2061,9 +2065,8 @@ static void shutdown(struct cyclades_port *info) | |||
2061 | void __iomem *base_addr; | 2065 | void __iomem *base_addr; |
2062 | int chip, channel, index; | 2066 | int chip, channel, index; |
2063 | 2067 | ||
2064 | if (!(info->flags & ASYNC_INITIALIZED)) { | 2068 | if (!(info->flags & ASYNC_INITIALIZED)) |
2065 | return; | 2069 | return; |
2066 | } | ||
2067 | 2070 | ||
2068 | card = info->card; | 2071 | card = info->card; |
2069 | channel = info->line - card->first_line; | 2072 | channel = info->line - card->first_line; |
@@ -2105,9 +2108,8 @@ static void shutdown(struct cyclades_port *info) | |||
2105 | /* it may be appropriate to clear _XMIT at | 2108 | /* it may be appropriate to clear _XMIT at |
2106 | some later date (after testing)!!! */ | 2109 | some later date (after testing)!!! */ |
2107 | 2110 | ||
2108 | if (info->tty) { | 2111 | if (info->tty) |
2109 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 2112 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2110 | } | ||
2111 | info->flags &= ~ASYNC_INITIALIZED; | 2113 | info->flags &= ~ASYNC_INITIALIZED; |
2112 | spin_unlock_irqrestore(&card->card_lock, flags); | 2114 | spin_unlock_irqrestore(&card->card_lock, flags); |
2113 | } else { | 2115 | } else { |
@@ -2124,9 +2126,8 @@ static void shutdown(struct cyclades_port *info) | |||
2124 | #endif | 2126 | #endif |
2125 | 2127 | ||
2126 | firm_id = base_addr + ID_ADDRESS; | 2128 | firm_id = base_addr + ID_ADDRESS; |
2127 | if (!ISZLOADED(*card)) { | 2129 | if (!ISZLOADED(*card)) |
2128 | return; | 2130 | return; |
2129 | } | ||
2130 | 2131 | ||
2131 | zfw_ctrl = card->base_addr + | 2132 | zfw_ctrl = card->base_addr + |
2132 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2133 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
@@ -2157,9 +2158,8 @@ static void shutdown(struct cyclades_port *info) | |||
2157 | #endif | 2158 | #endif |
2158 | } | 2159 | } |
2159 | 2160 | ||
2160 | if (info->tty) { | 2161 | if (info->tty) |
2161 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 2162 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2162 | } | ||
2163 | info->flags &= ~ASYNC_INITIALIZED; | 2163 | info->flags &= ~ASYNC_INITIALIZED; |
2164 | 2164 | ||
2165 | spin_unlock_irqrestore(&card->card_lock, flags); | 2165 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -2204,7 +2204,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2204 | * If non-blocking mode is set, then make the check up front | 2204 | * If non-blocking mode is set, then make the check up front |
2205 | * and then exit. | 2205 | * and then exit. |
2206 | */ | 2206 | */ |
2207 | if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { | 2207 | if ((filp->f_flags & O_NONBLOCK) || |
2208 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
2208 | info->flags |= ASYNC_NORMAL_ACTIVE; | 2209 | info->flags |= ASYNC_NORMAL_ACTIVE; |
2209 | return 0; | 2210 | return 0; |
2210 | } | 2211 | } |
@@ -2301,7 +2302,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2301 | return -EINVAL; | 2302 | return -EINVAL; |
2302 | } | 2303 | } |
2303 | 2304 | ||
2304 | zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff); | 2305 | zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr) |
2306 | & 0xfffff); | ||
2305 | board_ctrl = &zfw_ctrl->board_ctrl; | 2307 | board_ctrl = &zfw_ctrl->board_ctrl; |
2306 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2308 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2307 | 2309 | ||
@@ -2378,9 +2380,9 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2378 | int retval; | 2380 | int retval; |
2379 | 2381 | ||
2380 | line = tty->index; | 2382 | line = tty->index; |
2381 | if ((tty->index < 0) || (NR_PORTS <= line)) { | 2383 | if (tty->index < 0 || NR_PORTS <= line) |
2382 | return -ENODEV; | 2384 | return -ENODEV; |
2383 | } | 2385 | |
2384 | for (i = 0; i < NR_CARDS; i++) | 2386 | for (i = 0; i < NR_CARDS; i++) |
2385 | if (line < cy_card[i].first_line + cy_card[i].nports && | 2387 | if (line < cy_card[i].first_line + cy_card[i].nports && |
2386 | line >= cy_card[i].first_line) | 2388 | line >= cy_card[i].first_line) |
@@ -2388,9 +2390,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2388 | if (i >= NR_CARDS) | 2390 | if (i >= NR_CARDS) |
2389 | return -ENODEV; | 2391 | return -ENODEV; |
2390 | info = &cy_card[i].ports[line - cy_card[i].first_line]; | 2392 | info = &cy_card[i].ports[line - cy_card[i].first_line]; |
2391 | if (info->line < 0) { | 2393 | if (info->line < 0) |
2392 | return -ENODEV; | 2394 | return -ENODEV; |
2393 | } | ||
2394 | 2395 | ||
2395 | /* If the card's firmware hasn't been loaded, | 2396 | /* If the card's firmware hasn't been loaded, |
2396 | treat it as absent from the system. This | 2397 | treat it as absent from the system. This |
@@ -2456,9 +2457,9 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2456 | #endif | 2457 | #endif |
2457 | tty->driver_data = info; | 2458 | tty->driver_data = info; |
2458 | info->tty = tty; | 2459 | info->tty = tty; |
2459 | if (serial_paranoia_check(info, tty->name, "cy_open")) { | 2460 | if (serial_paranoia_check(info, tty->name, "cy_open")) |
2460 | return -ENODEV; | 2461 | return -ENODEV; |
2461 | } | 2462 | |
2462 | #ifdef CY_DEBUG_OPEN | 2463 | #ifdef CY_DEBUG_OPEN |
2463 | printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, | 2464 | printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, |
2464 | info->count); | 2465 | info->count); |
@@ -2482,9 +2483,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2482 | * Start up serial port | 2483 | * Start up serial port |
2483 | */ | 2484 | */ |
2484 | retval = startup(info); | 2485 | retval = startup(info); |
2485 | if (retval) { | 2486 | if (retval) |
2486 | return retval; | 2487 | return retval; |
2487 | } | ||
2488 | 2488 | ||
2489 | retval = block_til_ready(tty, filp, info); | 2489 | retval = block_til_ready(tty, filp, info); |
2490 | if (retval) { | 2490 | if (retval) { |
@@ -2522,6 +2522,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2522 | return; /* Just in case.... */ | 2522 | return; /* Just in case.... */ |
2523 | 2523 | ||
2524 | orig_jiffies = jiffies; | 2524 | orig_jiffies = jiffies; |
2525 | lock_kernel(); | ||
2525 | /* | 2526 | /* |
2526 | * Set the check interval to be 1/5 of the estimated time to | 2527 | * Set the check interval to be 1/5 of the estimated time to |
2527 | * send a single character, and make it at least 1. The check | 2528 | * send a single character, and make it at least 1. The check |
@@ -2573,11 +2574,47 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2573 | } | 2574 | } |
2574 | /* Run one more char cycle */ | 2575 | /* Run one more char cycle */ |
2575 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 2576 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
2577 | unlock_kernel(); | ||
2576 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2578 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2577 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); | 2579 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); |
2578 | #endif | 2580 | #endif |
2579 | } | 2581 | } |
2580 | 2582 | ||
2583 | static void cy_flush_buffer(struct tty_struct *tty) | ||
2584 | { | ||
2585 | struct cyclades_port *info = tty->driver_data; | ||
2586 | struct cyclades_card *card; | ||
2587 | int channel, retval; | ||
2588 | unsigned long flags; | ||
2589 | |||
2590 | #ifdef CY_DEBUG_IO | ||
2591 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); | ||
2592 | #endif | ||
2593 | |||
2594 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | ||
2595 | return; | ||
2596 | |||
2597 | card = info->card; | ||
2598 | channel = info->line - card->first_line; | ||
2599 | |||
2600 | spin_lock_irqsave(&card->card_lock, flags); | ||
2601 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
2602 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2603 | |||
2604 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board | ||
2605 | buffers as well */ | ||
2606 | spin_lock_irqsave(&card->card_lock, flags); | ||
2607 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); | ||
2608 | if (retval != 0) { | ||
2609 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " | ||
2610 | "was %x\n", info->line, retval); | ||
2611 | } | ||
2612 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2613 | } | ||
2614 | tty_wakeup(tty); | ||
2615 | } /* cy_flush_buffer */ | ||
2616 | |||
2617 | |||
2581 | /* | 2618 | /* |
2582 | * This routine is called when a particular tty device is closed. | 2619 | * This routine is called when a particular tty device is closed. |
2583 | */ | 2620 | */ |
@@ -2591,9 +2628,8 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2591 | printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line); | 2628 | printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line); |
2592 | #endif | 2629 | #endif |
2593 | 2630 | ||
2594 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { | 2631 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) |
2595 | return; | 2632 | return; |
2596 | } | ||
2597 | 2633 | ||
2598 | card = info->card; | 2634 | card = info->card; |
2599 | 2635 | ||
@@ -2641,9 +2677,9 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2641 | */ | 2677 | */ |
2642 | tty->closing = 1; | 2678 | tty->closing = 1; |
2643 | spin_unlock_irqrestore(&card->card_lock, flags); | 2679 | spin_unlock_irqrestore(&card->card_lock, flags); |
2644 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { | 2680 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) |
2645 | tty_wait_until_sent(tty, info->closing_wait); | 2681 | tty_wait_until_sent(tty, info->closing_wait); |
2646 | } | 2682 | |
2647 | spin_lock_irqsave(&card->card_lock, flags); | 2683 | spin_lock_irqsave(&card->card_lock, flags); |
2648 | 2684 | ||
2649 | if (!IS_CYC_Z(*card)) { | 2685 | if (!IS_CYC_Z(*card)) { |
@@ -2657,15 +2693,16 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2657 | cy_writeb(base_addr + (CySRER << index), | 2693 | cy_writeb(base_addr + (CySRER << index), |
2658 | readb(base_addr + (CySRER << index)) & ~CyRxData); | 2694 | readb(base_addr + (CySRER << index)) & ~CyRxData); |
2659 | if (info->flags & ASYNC_INITIALIZED) { | 2695 | if (info->flags & ASYNC_INITIALIZED) { |
2660 | /* Waiting for on-board buffers to be empty before closing | 2696 | /* Waiting for on-board buffers to be empty before |
2661 | the port */ | 2697 | closing the port */ |
2662 | spin_unlock_irqrestore(&card->card_lock, flags); | 2698 | spin_unlock_irqrestore(&card->card_lock, flags); |
2663 | cy_wait_until_sent(tty, info->timeout); | 2699 | cy_wait_until_sent(tty, info->timeout); |
2664 | spin_lock_irqsave(&card->card_lock, flags); | 2700 | spin_lock_irqsave(&card->card_lock, flags); |
2665 | } | 2701 | } |
2666 | } else { | 2702 | } else { |
2667 | #ifdef Z_WAKE | 2703 | #ifdef Z_WAKE |
2668 | /* Waiting for on-board buffers to be empty before closing the port */ | 2704 | /* Waiting for on-board buffers to be empty before closing |
2705 | the port */ | ||
2669 | void __iomem *base_addr = card->base_addr; | 2706 | void __iomem *base_addr = card->base_addr; |
2670 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; | 2707 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; |
2671 | struct ZFW_CTRL __iomem *zfw_ctrl = | 2708 | struct ZFW_CTRL __iomem *zfw_ctrl = |
@@ -2689,8 +2726,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2689 | 2726 | ||
2690 | spin_unlock_irqrestore(&card->card_lock, flags); | 2727 | spin_unlock_irqrestore(&card->card_lock, flags); |
2691 | shutdown(info); | 2728 | shutdown(info); |
2692 | if (tty->driver->flush_buffer) | 2729 | cy_flush_buffer(tty); |
2693 | tty->driver->flush_buffer(tty); | ||
2694 | tty_ldisc_flush(tty); | 2730 | tty_ldisc_flush(tty); |
2695 | spin_lock_irqsave(&card->card_lock, flags); | 2731 | spin_lock_irqsave(&card->card_lock, flags); |
2696 | 2732 | ||
@@ -2738,17 +2774,16 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2738 | printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); | 2774 | printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); |
2739 | #endif | 2775 | #endif |
2740 | 2776 | ||
2741 | if (serial_paranoia_check(info, tty->name, "cy_write")) { | 2777 | if (serial_paranoia_check(info, tty->name, "cy_write")) |
2742 | return 0; | 2778 | return 0; |
2743 | } | ||
2744 | 2779 | ||
2745 | if (!info->xmit_buf) | 2780 | if (!info->xmit_buf) |
2746 | return 0; | 2781 | return 0; |
2747 | 2782 | ||
2748 | spin_lock_irqsave(&info->card->card_lock, flags); | 2783 | spin_lock_irqsave(&info->card->card_lock, flags); |
2749 | while (1) { | 2784 | while (1) { |
2750 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), | 2785 | c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1)); |
2751 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); | 2786 | c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head)); |
2752 | 2787 | ||
2753 | if (c <= 0) | 2788 | if (c <= 0) |
2754 | break; | 2789 | break; |
@@ -2766,9 +2801,9 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2766 | info->idle_stats.xmit_bytes += ret; | 2801 | info->idle_stats.xmit_bytes += ret; |
2767 | info->idle_stats.xmit_idle = jiffies; | 2802 | info->idle_stats.xmit_idle = jiffies; |
2768 | 2803 | ||
2769 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { | 2804 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) |
2770 | start_xmit(info); | 2805 | start_xmit(info); |
2771 | } | 2806 | |
2772 | return ret; | 2807 | return ret; |
2773 | } /* cy_write */ | 2808 | } /* cy_write */ |
2774 | 2809 | ||
@@ -2779,7 +2814,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2779 | * done stuffing characters into the driver. If there is no room | 2814 | * done stuffing characters into the driver. If there is no room |
2780 | * in the queue, the character is ignored. | 2815 | * in the queue, the character is ignored. |
2781 | */ | 2816 | */ |
2782 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) | 2817 | static int cy_put_char(struct tty_struct *tty, unsigned char ch) |
2783 | { | 2818 | { |
2784 | struct cyclades_port *info = tty->driver_data; | 2819 | struct cyclades_port *info = tty->driver_data; |
2785 | unsigned long flags; | 2820 | unsigned long flags; |
@@ -2789,15 +2824,15 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2789 | #endif | 2824 | #endif |
2790 | 2825 | ||
2791 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 2826 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
2792 | return; | 2827 | return 0; |
2793 | 2828 | ||
2794 | if (!info->xmit_buf) | 2829 | if (!info->xmit_buf) |
2795 | return; | 2830 | return 0; |
2796 | 2831 | ||
2797 | spin_lock_irqsave(&info->card->card_lock, flags); | 2832 | spin_lock_irqsave(&info->card->card_lock, flags); |
2798 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { | 2833 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { |
2799 | spin_unlock_irqrestore(&info->card->card_lock, flags); | 2834 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2800 | return; | 2835 | return 0; |
2801 | } | 2836 | } |
2802 | 2837 | ||
2803 | info->xmit_buf[info->xmit_head++] = ch; | 2838 | info->xmit_buf[info->xmit_head++] = ch; |
@@ -2806,11 +2841,12 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2806 | info->idle_stats.xmit_bytes++; | 2841 | info->idle_stats.xmit_bytes++; |
2807 | info->idle_stats.xmit_idle = jiffies; | 2842 | info->idle_stats.xmit_idle = jiffies; |
2808 | spin_unlock_irqrestore(&info->card->card_lock, flags); | 2843 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2844 | return 1; | ||
2809 | } /* cy_put_char */ | 2845 | } /* cy_put_char */ |
2810 | 2846 | ||
2811 | /* | 2847 | /* |
2812 | * This routine is called by the kernel after it has written a | 2848 | * This routine is called by the kernel after it has written a |
2813 | * series of characters to the tty device using put_char(). | 2849 | * series of characters to the tty device using put_char(). |
2814 | */ | 2850 | */ |
2815 | static void cy_flush_chars(struct tty_struct *tty) | 2851 | static void cy_flush_chars(struct tty_struct *tty) |
2816 | { | 2852 | { |
@@ -2882,6 +2918,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
2882 | int char_count; | 2918 | int char_count; |
2883 | __u32 tx_put, tx_get, tx_bufsize; | 2919 | __u32 tx_put, tx_get, tx_bufsize; |
2884 | 2920 | ||
2921 | lock_kernel(); | ||
2885 | firm_id = card->base_addr + ID_ADDRESS; | 2922 | firm_id = card->base_addr + ID_ADDRESS; |
2886 | zfw_ctrl = card->base_addr + | 2923 | zfw_ctrl = card->base_addr + |
2887 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2924 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
@@ -2899,6 +2936,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
2899 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", | 2936 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2900 | info->line, info->xmit_cnt + char_count); | 2937 | info->line, info->xmit_cnt + char_count); |
2901 | #endif | 2938 | #endif |
2939 | unlock_kernel(); | ||
2902 | return info->xmit_cnt + char_count; | 2940 | return info->xmit_cnt + char_count; |
2903 | } | 2941 | } |
2904 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 2942 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
@@ -2950,12 +2988,12 @@ static void set_line_char(struct cyclades_port *info) | |||
2950 | int baud, baud_rate = 0; | 2988 | int baud, baud_rate = 0; |
2951 | int i; | 2989 | int i; |
2952 | 2990 | ||
2953 | if (!info->tty || !info->tty->termios) { | 2991 | if (!info->tty || !info->tty->termios) |
2954 | return; | 2992 | return; |
2955 | } | 2993 | |
2956 | if (info->line == -1) { | 2994 | if (info->line == -1) |
2957 | return; | 2995 | return; |
2958 | } | 2996 | |
2959 | cflag = info->tty->termios->c_cflag; | 2997 | cflag = info->tty->termios->c_cflag; |
2960 | iflag = info->tty->termios->c_iflag; | 2998 | iflag = info->tty->termios->c_iflag; |
2961 | 2999 | ||
@@ -2994,13 +3032,11 @@ static void set_line_char(struct cyclades_port *info) | |||
2994 | } | 3032 | } |
2995 | /* find the baud index */ | 3033 | /* find the baud index */ |
2996 | for (i = 0; i < 20; i++) { | 3034 | for (i = 0; i < 20; i++) { |
2997 | if (baud == baud_table[i]) { | 3035 | if (baud == baud_table[i]) |
2998 | break; | 3036 | break; |
2999 | } | ||
3000 | } | 3037 | } |
3001 | if (i == 20) { | 3038 | if (i == 20) |
3002 | i = 19; /* CD1400_MAX_SPEED */ | 3039 | i = 19; /* CD1400_MAX_SPEED */ |
3003 | } | ||
3004 | 3040 | ||
3005 | if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == | 3041 | if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == |
3006 | ASYNC_SPD_CUST) { | 3042 | ASYNC_SPD_CUST) { |
@@ -3059,18 +3095,16 @@ static void set_line_char(struct cyclades_port *info) | |||
3059 | info->cor1 = Cy_8_BITS; | 3095 | info->cor1 = Cy_8_BITS; |
3060 | break; | 3096 | break; |
3061 | } | 3097 | } |
3062 | if (cflag & CSTOPB) { | 3098 | if (cflag & CSTOPB) |
3063 | info->cor1 |= Cy_2_STOP; | 3099 | info->cor1 |= Cy_2_STOP; |
3064 | } | 3100 | |
3065 | if (cflag & PARENB) { | 3101 | if (cflag & PARENB) { |
3066 | if (cflag & PARODD) { | 3102 | if (cflag & PARODD) |
3067 | info->cor1 |= CyPARITY_O; | 3103 | info->cor1 |= CyPARITY_O; |
3068 | } else { | 3104 | else |
3069 | info->cor1 |= CyPARITY_E; | 3105 | info->cor1 |= CyPARITY_E; |
3070 | } | 3106 | } else |
3071 | } else { | ||
3072 | info->cor1 |= CyPARITY_NONE; | 3107 | info->cor1 |= CyPARITY_NONE; |
3073 | } | ||
3074 | 3108 | ||
3075 | /* CTS flow control flag */ | 3109 | /* CTS flow control flag */ |
3076 | if (cflag & CRTSCTS) { | 3110 | if (cflag & CRTSCTS) { |
@@ -3123,7 +3157,8 @@ static void set_line_char(struct cyclades_port *info) | |||
3123 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | | 3157 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | |
3124 | CyCOR3ch, index); | 3158 | CyCOR3ch, index); |
3125 | 3159 | ||
3126 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); /* !!! Is this needed? */ | 3160 | /* !!! Is this needed? */ |
3161 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | ||
3127 | cy_writeb(base_addr + (CyRTPR << index), | 3162 | cy_writeb(base_addr + (CyRTPR << index), |
3128 | (info->default_timeout ? info->default_timeout : 0x02)); | 3163 | (info->default_timeout ? info->default_timeout : 0x02)); |
3129 | /* 10ms rx timeout */ | 3164 | /* 10ms rx timeout */ |
@@ -3191,9 +3226,8 @@ static void set_line_char(struct cyclades_port *info) | |||
3191 | #endif | 3226 | #endif |
3192 | } | 3227 | } |
3193 | 3228 | ||
3194 | if (info->tty) { | 3229 | if (info->tty) |
3195 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 3230 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3196 | } | ||
3197 | spin_unlock_irqrestore(&card->card_lock, flags); | 3231 | spin_unlock_irqrestore(&card->card_lock, flags); |
3198 | 3232 | ||
3199 | } else { | 3233 | } else { |
@@ -3206,9 +3240,8 @@ static void set_line_char(struct cyclades_port *info) | |||
3206 | int retval; | 3240 | int retval; |
3207 | 3241 | ||
3208 | firm_id = card->base_addr + ID_ADDRESS; | 3242 | firm_id = card->base_addr + ID_ADDRESS; |
3209 | if (!ISZLOADED(*card)) { | 3243 | if (!ISZLOADED(*card)) |
3210 | return; | 3244 | return; |
3211 | } | ||
3212 | 3245 | ||
3213 | zfw_ctrl = card->base_addr + | 3246 | zfw_ctrl = card->base_addr + |
3214 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3247 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
@@ -3268,14 +3301,12 @@ static void set_line_char(struct cyclades_port *info) | |||
3268 | readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); | 3301 | readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); |
3269 | } | 3302 | } |
3270 | if (cflag & PARENB) { | 3303 | if (cflag & PARENB) { |
3271 | if (cflag & PARODD) { | 3304 | if (cflag & PARODD) |
3272 | cy_writel(&ch_ctrl->comm_parity, C_PR_ODD); | 3305 | cy_writel(&ch_ctrl->comm_parity, C_PR_ODD); |
3273 | } else { | 3306 | else |
3274 | cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN); | 3307 | cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN); |
3275 | } | 3308 | } else |
3276 | } else { | ||
3277 | cy_writel(&ch_ctrl->comm_parity, C_PR_NONE); | 3309 | cy_writel(&ch_ctrl->comm_parity, C_PR_NONE); |
3278 | } | ||
3279 | 3310 | ||
3280 | /* CTS flow control flag */ | 3311 | /* CTS flow control flag */ |
3281 | if (cflag & CRTSCTS) { | 3312 | if (cflag & CRTSCTS) { |
@@ -3305,11 +3336,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3305 | } | 3336 | } |
3306 | 3337 | ||
3307 | /* CD sensitivity */ | 3338 | /* CD sensitivity */ |
3308 | if (cflag & CLOCAL) { | 3339 | if (cflag & CLOCAL) |
3309 | info->flags &= ~ASYNC_CHECK_CD; | 3340 | info->flags &= ~ASYNC_CHECK_CD; |
3310 | } else { | 3341 | else |
3311 | info->flags |= ASYNC_CHECK_CD; | 3342 | info->flags |= ASYNC_CHECK_CD; |
3312 | } | ||
3313 | 3343 | ||
3314 | if (baud == 0) { /* baud rate is zero, turn off line */ | 3344 | if (baud == 0) { /* baud rate is zero, turn off line */ |
3315 | cy_writel(&ch_ctrl->rs_control, | 3345 | cy_writel(&ch_ctrl->rs_control, |
@@ -3325,21 +3355,20 @@ static void set_line_char(struct cyclades_port *info) | |||
3325 | #endif | 3355 | #endif |
3326 | } | 3356 | } |
3327 | 3357 | ||
3328 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L); | 3358 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); |
3329 | if (retval != 0) { | 3359 | if (retval != 0) { |
3330 | printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " | 3360 | printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " |
3331 | "was %x\n", info->line, retval); | 3361 | "was %x\n", info->line, retval); |
3332 | } | 3362 | } |
3333 | 3363 | ||
3334 | if (info->tty) { | 3364 | if (info->tty) |
3335 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 3365 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3336 | } | ||
3337 | } | 3366 | } |
3338 | } /* set_line_char */ | 3367 | } /* set_line_char */ |
3339 | 3368 | ||
3340 | static int | 3369 | static int |
3341 | get_serial_info(struct cyclades_port *info, | 3370 | get_serial_info(struct cyclades_port *info, |
3342 | struct serial_struct __user * retinfo) | 3371 | struct serial_struct __user *retinfo) |
3343 | { | 3372 | { |
3344 | struct serial_struct tmp; | 3373 | struct serial_struct tmp; |
3345 | struct cyclades_card *cinfo = info->card; | 3374 | struct cyclades_card *cinfo = info->card; |
@@ -3363,7 +3392,7 @@ get_serial_info(struct cyclades_port *info, | |||
3363 | 3392 | ||
3364 | static int | 3393 | static int |
3365 | set_serial_info(struct cyclades_port *info, | 3394 | set_serial_info(struct cyclades_port *info, |
3366 | struct serial_struct __user * new_info) | 3395 | struct serial_struct __user *new_info) |
3367 | { | 3396 | { |
3368 | struct serial_struct new_serial; | 3397 | struct serial_struct new_serial; |
3369 | struct cyclades_port old_info; | 3398 | struct cyclades_port old_info; |
@@ -3417,7 +3446,7 @@ check_and_exit: | |||
3417 | * transmit holding register is empty. This functionality | 3446 | * transmit holding register is empty. This functionality |
3418 | * allows an RS485 driver to be written in user space. | 3447 | * allows an RS485 driver to be written in user space. |
3419 | */ | 3448 | */ |
3420 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) | 3449 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) |
3421 | { | 3450 | { |
3422 | struct cyclades_card *card; | 3451 | struct cyclades_card *card; |
3423 | int chip, channel, index; | 3452 | int chip, channel, index; |
@@ -3461,9 +3490,11 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3461 | struct BOARD_CTRL __iomem *board_ctrl; | 3490 | struct BOARD_CTRL __iomem *board_ctrl; |
3462 | struct CH_CTRL __iomem *ch_ctrl; | 3491 | struct CH_CTRL __iomem *ch_ctrl; |
3463 | 3492 | ||
3464 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 3493 | if (serial_paranoia_check(info, tty->name, __func__)) |
3465 | return -ENODEV; | 3494 | return -ENODEV; |
3466 | 3495 | ||
3496 | lock_kernel(); | ||
3497 | |||
3467 | card = info->card; | 3498 | card = info->card; |
3468 | channel = info->line - card->first_line; | 3499 | channel = info->line - card->first_line; |
3469 | if (!IS_CYC_Z(*card)) { | 3500 | if (!IS_CYC_Z(*card)) { |
@@ -3506,10 +3537,12 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3506 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); | 3537 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); |
3507 | } else { | 3538 | } else { |
3508 | result = 0; | 3539 | result = 0; |
3540 | unlock_kernel(); | ||
3509 | return -ENODEV; | 3541 | return -ENODEV; |
3510 | } | 3542 | } |
3511 | 3543 | ||
3512 | } | 3544 | } |
3545 | unlock_kernel(); | ||
3513 | return result; | 3546 | return result; |
3514 | } /* cy_tiomget */ | 3547 | } /* cy_tiomget */ |
3515 | 3548 | ||
@@ -3528,7 +3561,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3528 | struct CH_CTRL __iomem *ch_ctrl; | 3561 | struct CH_CTRL __iomem *ch_ctrl; |
3529 | int retval; | 3562 | int retval; |
3530 | 3563 | ||
3531 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 3564 | if (serial_paranoia_check(info, tty->name, __func__)) |
3532 | return -ENODEV; | 3565 | return -ENODEV; |
3533 | 3566 | ||
3534 | card = info->card; | 3567 | card = info->card; |
@@ -3727,8 +3760,8 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3727 | spin_unlock_irqrestore(&card->card_lock, flags); | 3760 | spin_unlock_irqrestore(&card->card_lock, flags); |
3728 | } /* cy_break */ | 3761 | } /* cy_break */ |
3729 | 3762 | ||
3730 | static int | 3763 | static int get_mon_info(struct cyclades_port *info, |
3731 | get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) | 3764 | struct cyclades_monitor __user *mon) |
3732 | { | 3765 | { |
3733 | 3766 | ||
3734 | if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) | 3767 | if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) |
@@ -3767,8 +3800,8 @@ static int set_threshold(struct cyclades_port *info, unsigned long value) | |||
3767 | return 0; | 3800 | return 0; |
3768 | } /* set_threshold */ | 3801 | } /* set_threshold */ |
3769 | 3802 | ||
3770 | static int | 3803 | static int get_threshold(struct cyclades_port *info, |
3771 | get_threshold(struct cyclades_port *info, unsigned long __user * value) | 3804 | unsigned long __user *value) |
3772 | { | 3805 | { |
3773 | struct cyclades_card *card; | 3806 | struct cyclades_card *card; |
3774 | void __iomem *base_addr; | 3807 | void __iomem *base_addr; |
@@ -3789,15 +3822,15 @@ get_threshold(struct cyclades_port *info, unsigned long __user * value) | |||
3789 | return 0; | 3822 | return 0; |
3790 | } /* get_threshold */ | 3823 | } /* get_threshold */ |
3791 | 3824 | ||
3792 | static int | 3825 | static int set_default_threshold(struct cyclades_port *info, |
3793 | set_default_threshold(struct cyclades_port *info, unsigned long value) | 3826 | unsigned long value) |
3794 | { | 3827 | { |
3795 | info->default_threshold = value & 0x0f; | 3828 | info->default_threshold = value & 0x0f; |
3796 | return 0; | 3829 | return 0; |
3797 | } /* set_default_threshold */ | 3830 | } /* set_default_threshold */ |
3798 | 3831 | ||
3799 | static int | 3832 | static int get_default_threshold(struct cyclades_port *info, |
3800 | get_default_threshold(struct cyclades_port *info, unsigned long __user * value) | 3833 | unsigned long __user *value) |
3801 | { | 3834 | { |
3802 | return put_user(info->default_threshold, value); | 3835 | return put_user(info->default_threshold, value); |
3803 | } /* get_default_threshold */ | 3836 | } /* get_default_threshold */ |
@@ -3824,7 +3857,8 @@ static int set_timeout(struct cyclades_port *info, unsigned long value) | |||
3824 | return 0; | 3857 | return 0; |
3825 | } /* set_timeout */ | 3858 | } /* set_timeout */ |
3826 | 3859 | ||
3827 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) | 3860 | static int get_timeout(struct cyclades_port *info, |
3861 | unsigned long __user *value) | ||
3828 | { | 3862 | { |
3829 | struct cyclades_card *card; | 3863 | struct cyclades_card *card; |
3830 | void __iomem *base_addr; | 3864 | void __iomem *base_addr; |
@@ -3851,8 +3885,8 @@ static int set_default_timeout(struct cyclades_port *info, unsigned long value) | |||
3851 | return 0; | 3885 | return 0; |
3852 | } /* set_default_timeout */ | 3886 | } /* set_default_timeout */ |
3853 | 3887 | ||
3854 | static int | 3888 | static int get_default_timeout(struct cyclades_port *info, |
3855 | get_default_timeout(struct cyclades_port *info, unsigned long __user * value) | 3889 | unsigned long __user *value) |
3856 | { | 3890 | { |
3857 | return put_user(info->default_timeout, value); | 3891 | return put_user(info->default_timeout, value); |
3858 | } /* get_default_timeout */ | 3892 | } /* get_default_timeout */ |
@@ -3880,6 +3914,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
3880 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", | 3914 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", |
3881 | info->line, cmd, arg); | 3915 | info->line, cmd, arg); |
3882 | #endif | 3916 | #endif |
3917 | lock_kernel(); | ||
3883 | 3918 | ||
3884 | switch (cmd) { | 3919 | switch (cmd) { |
3885 | case CYGETMON: | 3920 | case CYGETMON: |
@@ -3936,7 +3971,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
3936 | break; | 3971 | break; |
3937 | #endif /* CONFIG_CYZ_INTR */ | 3972 | #endif /* CONFIG_CYZ_INTR */ |
3938 | case CYSETWAIT: | 3973 | case CYSETWAIT: |
3939 | info->closing_wait = (unsigned short)arg *HZ / 100; | 3974 | info->closing_wait = (unsigned short)arg * HZ / 100; |
3940 | ret_val = 0; | 3975 | ret_val = 0; |
3941 | break; | 3976 | break; |
3942 | case CYGETWAIT: | 3977 | case CYGETWAIT: |
@@ -3988,47 +4023,47 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
3988 | p_cuser = argp; | 4023 | p_cuser = argp; |
3989 | ret_val = put_user(cnow.cts, &p_cuser->cts); | 4024 | ret_val = put_user(cnow.cts, &p_cuser->cts); |
3990 | if (ret_val) | 4025 | if (ret_val) |
3991 | return ret_val; | 4026 | break; |
3992 | ret_val = put_user(cnow.dsr, &p_cuser->dsr); | 4027 | ret_val = put_user(cnow.dsr, &p_cuser->dsr); |
3993 | if (ret_val) | 4028 | if (ret_val) |
3994 | return ret_val; | 4029 | break; |
3995 | ret_val = put_user(cnow.rng, &p_cuser->rng); | 4030 | ret_val = put_user(cnow.rng, &p_cuser->rng); |
3996 | if (ret_val) | 4031 | if (ret_val) |
3997 | return ret_val; | 4032 | break; |
3998 | ret_val = put_user(cnow.dcd, &p_cuser->dcd); | 4033 | ret_val = put_user(cnow.dcd, &p_cuser->dcd); |
3999 | if (ret_val) | 4034 | if (ret_val) |
4000 | return ret_val; | 4035 | break; |
4001 | ret_val = put_user(cnow.rx, &p_cuser->rx); | 4036 | ret_val = put_user(cnow.rx, &p_cuser->rx); |
4002 | if (ret_val) | 4037 | if (ret_val) |
4003 | return ret_val; | 4038 | break; |
4004 | ret_val = put_user(cnow.tx, &p_cuser->tx); | 4039 | ret_val = put_user(cnow.tx, &p_cuser->tx); |
4005 | if (ret_val) | 4040 | if (ret_val) |
4006 | return ret_val; | 4041 | break; |
4007 | ret_val = put_user(cnow.frame, &p_cuser->frame); | 4042 | ret_val = put_user(cnow.frame, &p_cuser->frame); |
4008 | if (ret_val) | 4043 | if (ret_val) |
4009 | return ret_val; | 4044 | break; |
4010 | ret_val = put_user(cnow.overrun, &p_cuser->overrun); | 4045 | ret_val = put_user(cnow.overrun, &p_cuser->overrun); |
4011 | if (ret_val) | 4046 | if (ret_val) |
4012 | return ret_val; | 4047 | break; |
4013 | ret_val = put_user(cnow.parity, &p_cuser->parity); | 4048 | ret_val = put_user(cnow.parity, &p_cuser->parity); |
4014 | if (ret_val) | 4049 | if (ret_val) |
4015 | return ret_val; | 4050 | break; |
4016 | ret_val = put_user(cnow.brk, &p_cuser->brk); | 4051 | ret_val = put_user(cnow.brk, &p_cuser->brk); |
4017 | if (ret_val) | 4052 | if (ret_val) |
4018 | return ret_val; | 4053 | break; |
4019 | ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | 4054 | ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); |
4020 | if (ret_val) | 4055 | if (ret_val) |
4021 | return ret_val; | 4056 | break; |
4022 | ret_val = 0; | 4057 | ret_val = 0; |
4023 | break; | 4058 | break; |
4024 | default: | 4059 | default: |
4025 | ret_val = -ENOIOCTLCMD; | 4060 | ret_val = -ENOIOCTLCMD; |
4026 | } | 4061 | } |
4062 | unlock_kernel(); | ||
4027 | 4063 | ||
4028 | #ifdef CY_DEBUG_OTHER | 4064 | #ifdef CY_DEBUG_OTHER |
4029 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); | 4065 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); |
4030 | #endif | 4066 | #endif |
4031 | |||
4032 | return ret_val; | 4067 | return ret_val; |
4033 | } /* cy_ioctl */ | 4068 | } /* cy_ioctl */ |
4034 | 4069 | ||
@@ -4113,9 +4148,8 @@ static void cy_throttle(struct tty_struct *tty) | |||
4113 | tty->ldisc.chars_in_buffer(tty), info->line); | 4148 | tty->ldisc.chars_in_buffer(tty), info->line); |
4114 | #endif | 4149 | #endif |
4115 | 4150 | ||
4116 | if (serial_paranoia_check(info, tty->name, "cy_throttle")) { | 4151 | if (serial_paranoia_check(info, tty->name, "cy_throttle")) |
4117 | return; | 4152 | return; |
4118 | } | ||
4119 | 4153 | ||
4120 | card = info->card; | 4154 | card = info->card; |
4121 | 4155 | ||
@@ -4169,12 +4203,11 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4169 | char buf[64]; | 4203 | char buf[64]; |
4170 | 4204 | ||
4171 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", | 4205 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", |
4172 | tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line); | 4206 | tty_name(tty, buf), tty_chars_in_buffer(tty), info->line); |
4173 | #endif | 4207 | #endif |
4174 | 4208 | ||
4175 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { | 4209 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) |
4176 | return; | 4210 | return; |
4177 | } | ||
4178 | 4211 | ||
4179 | if (I_IXOFF(tty)) { | 4212 | if (I_IXOFF(tty)) { |
4180 | if (info->x_char) | 4213 | if (info->x_char) |
@@ -4269,47 +4302,14 @@ static void cy_start(struct tty_struct *tty) | |||
4269 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); | 4302 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
4270 | 4303 | ||
4271 | spin_lock_irqsave(&cinfo->card_lock, flags); | 4304 | spin_lock_irqsave(&cinfo->card_lock, flags); |
4272 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ | 4305 | cy_writeb(base_addr + (CyCAR << index), |
4306 | (u_char) (channel & 0x0003)); /* index channel */ | ||
4273 | cy_writeb(base_addr + (CySRER << index), | 4307 | cy_writeb(base_addr + (CySRER << index), |
4274 | readb(base_addr + (CySRER << index)) | CyTxRdy); | 4308 | readb(base_addr + (CySRER << index)) | CyTxRdy); |
4275 | spin_unlock_irqrestore(&cinfo->card_lock, flags); | 4309 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
4276 | } | 4310 | } |
4277 | } /* cy_start */ | 4311 | } /* cy_start */ |
4278 | 4312 | ||
4279 | static void cy_flush_buffer(struct tty_struct *tty) | ||
4280 | { | ||
4281 | struct cyclades_port *info = tty->driver_data; | ||
4282 | struct cyclades_card *card; | ||
4283 | int channel, retval; | ||
4284 | unsigned long flags; | ||
4285 | |||
4286 | #ifdef CY_DEBUG_IO | ||
4287 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); | ||
4288 | #endif | ||
4289 | |||
4290 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | ||
4291 | return; | ||
4292 | |||
4293 | card = info->card; | ||
4294 | channel = info->line - card->first_line; | ||
4295 | |||
4296 | spin_lock_irqsave(&card->card_lock, flags); | ||
4297 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
4298 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
4299 | |||
4300 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board | ||
4301 | buffers as well */ | ||
4302 | spin_lock_irqsave(&card->card_lock, flags); | ||
4303 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); | ||
4304 | if (retval != 0) { | ||
4305 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " | ||
4306 | "was %x\n", info->line, retval); | ||
4307 | } | ||
4308 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
4309 | } | ||
4310 | tty_wakeup(tty); | ||
4311 | } /* cy_flush_buffer */ | ||
4312 | |||
4313 | /* | 4313 | /* |
4314 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. | 4314 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. |
4315 | */ | 4315 | */ |
@@ -4406,10 +4406,11 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4406 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | 4406 | info->cor3 = 0x08; /* _very_ small rcv threshold */ |
4407 | 4407 | ||
4408 | chip_number = (port - cinfo->first_line) / 4; | 4408 | chip_number = (port - cinfo->first_line) / 4; |
4409 | if ((info->chip_rev = readb(cinfo->base_addr + | 4409 | info->chip_rev = readb(cinfo->base_addr + |
4410 | (cy_chip_offset[chip_number] << | 4410 | (cy_chip_offset[chip_number] << index) + |
4411 | index) + (CyGFRCR << index))) >= | 4411 | (CyGFRCR << index)); |
4412 | CD1400_REV_J) { | 4412 | |
4413 | if (info->chip_rev >= CD1400_REV_J) { | ||
4413 | /* It is a CD1400 rev. J or later */ | 4414 | /* It is a CD1400 rev. J or later */ |
4414 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | 4415 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ |
4415 | info->tco = baud_co_60[13]; /* Tx CO */ | 4416 | info->tco = baud_co_60[13]; /* Tx CO */ |
@@ -4454,7 +4455,8 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, | |||
4454 | /* Cy_ClrIntr is 0x1800 */ | 4455 | /* Cy_ClrIntr is 0x1800 */ |
4455 | udelay(500L); | 4456 | udelay(500L); |
4456 | 4457 | ||
4457 | for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; chip_number++) { | 4458 | for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; |
4459 | chip_number++) { | ||
4458 | base_addr = | 4460 | base_addr = |
4459 | true_base_addr + (cy_chip_offset[chip_number] << index); | 4461 | true_base_addr + (cy_chip_offset[chip_number] << index); |
4460 | mdelay(1); | 4462 | mdelay(1); |
@@ -4555,12 +4557,11 @@ static int __init cy_detect_isa(void) | |||
4555 | /* scan the address table probing for Cyclom-Y/ISA boards */ | 4557 | /* scan the address table probing for Cyclom-Y/ISA boards */ |
4556 | for (i = 0; i < NR_ISA_ADDRS; i++) { | 4558 | for (i = 0; i < NR_ISA_ADDRS; i++) { |
4557 | unsigned int isa_address = cy_isa_addresses[i]; | 4559 | unsigned int isa_address = cy_isa_addresses[i]; |
4558 | if (isa_address == 0x0000) { | 4560 | if (isa_address == 0x0000) |
4559 | return nboard; | 4561 | return nboard; |
4560 | } | ||
4561 | 4562 | ||
4562 | /* probe for CD1400... */ | 4563 | /* probe for CD1400... */ |
4563 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); | 4564 | cy_isa_address = ioremap_nocache(isa_address, CyISA_Ywin); |
4564 | if (cy_isa_address == NULL) { | 4565 | if (cy_isa_address == NULL) { |
4565 | printk(KERN_ERR "Cyclom-Y/ISA: can't remap base " | 4566 | printk(KERN_ERR "Cyclom-Y/ISA: can't remap base " |
4566 | "address\n"); | 4567 | "address\n"); |
@@ -4847,12 +4848,10 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr, | |||
4847 | if (mailbox != 0) { | 4848 | if (mailbox != 0) { |
4848 | /* set window to last 512K of RAM */ | 4849 | /* set window to last 512K of RAM */ |
4849 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE); | 4850 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE); |
4850 | //sleep(1); | ||
4851 | for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) | 4851 | for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) |
4852 | cy_writeb(tmp, 255); | 4852 | cy_writeb(tmp, 255); |
4853 | /* set window to beginning of RAM */ | 4853 | /* set window to beginning of RAM */ |
4854 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); | 4854 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); |
4855 | //sleep(1); | ||
4856 | } | 4855 | } |
4857 | 4856 | ||
4858 | retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL); | 4857 | retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL); |
@@ -5382,7 +5381,8 @@ static void __exit cy_cleanup_module(void) | |||
5382 | del_timer_sync(&cyz_timerlist); | 5381 | del_timer_sync(&cyz_timerlist); |
5383 | #endif /* CONFIG_CYZ_INTR */ | 5382 | #endif /* CONFIG_CYZ_INTR */ |
5384 | 5383 | ||
5385 | if ((e1 = tty_unregister_driver(cy_serial_driver))) | 5384 | e1 = tty_unregister_driver(cy_serial_driver); |
5385 | if (e1) | ||
5386 | printk(KERN_ERR "failed to unregister Cyclades serial " | 5386 | printk(KERN_ERR "failed to unregister Cyclades serial " |
5387 | "driver(%d)\n", e1); | 5387 | "driver(%d)\n", e1); |
5388 | 5388 | ||
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index ecee3547a13f..213b3ca3468e 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -160,7 +160,7 @@ struct drm_device; | |||
160 | * \param arg arguments | 160 | * \param arg arguments |
161 | */ | 161 | */ |
162 | #define DRM_ERROR(fmt, arg...) \ | 162 | #define DRM_ERROR(fmt, arg...) \ |
163 | printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg) | 163 | printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg) |
164 | 164 | ||
165 | /** | 165 | /** |
166 | * Memory error output. | 166 | * Memory error output. |
@@ -170,7 +170,7 @@ struct drm_device; | |||
170 | * \param arg arguments | 170 | * \param arg arguments |
171 | */ | 171 | */ |
172 | #define DRM_MEM_ERROR(area, fmt, arg...) \ | 172 | #define DRM_MEM_ERROR(area, fmt, arg...) \ |
173 | printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \ | 173 | printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __func__, \ |
174 | drm_mem_stats[area].name , ##arg) | 174 | drm_mem_stats[area].name , ##arg) |
175 | 175 | ||
176 | #define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) | 176 | #define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) |
@@ -187,7 +187,7 @@ struct drm_device; | |||
187 | if ( drm_debug ) \ | 187 | if ( drm_debug ) \ |
188 | printk(KERN_DEBUG \ | 188 | printk(KERN_DEBUG \ |
189 | "[" DRM_NAME ":%s] " fmt , \ | 189 | "[" DRM_NAME ":%s] " fmt , \ |
190 | __FUNCTION__ , ##arg); \ | 190 | __func__ , ##arg); \ |
191 | } while (0) | 191 | } while (0) |
192 | #else | 192 | #else |
193 | #define DRM_DEBUG(fmt, arg...) do { } while (0) | 193 | #define DRM_DEBUG(fmt, arg...) do { } while (0) |
@@ -238,7 +238,7 @@ do { \ | |||
238 | if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ | 238 | if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ |
239 | dev->lock.file_priv != file_priv ) { \ | 239 | dev->lock.file_priv != file_priv ) { \ |
240 | DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ | 240 | DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ |
241 | __FUNCTION__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ | 241 | __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ |
242 | dev->lock.file_priv, file_priv ); \ | 242 | dev->lock.file_priv, file_priv ); \ |
243 | return -EINVAL; \ | 243 | return -EINVAL; \ |
244 | } \ | 244 | } \ |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 7a1d9a782ddb..9a32169e88fb 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -34,7 +34,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
34 | struct drm_minor *drm_minor = to_drm_minor(dev); | 34 | struct drm_minor *drm_minor = to_drm_minor(dev); |
35 | struct drm_device *drm_dev = drm_minor->dev; | 35 | struct drm_device *drm_dev = drm_minor->dev; |
36 | 36 | ||
37 | printk(KERN_ERR "%s\n", __FUNCTION__); | 37 | printk(KERN_ERR "%s\n", __func__); |
38 | 38 | ||
39 | if (drm_dev->driver->suspend) | 39 | if (drm_dev->driver->suspend) |
40 | return drm_dev->driver->suspend(drm_dev, state); | 40 | return drm_dev->driver->suspend(drm_dev, state); |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 60c9376be486..a86ab30b4620 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -692,7 +692,7 @@ static void i830EmitState(struct drm_device * dev) | |||
692 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; | 692 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; |
693 | unsigned int dirty = sarea_priv->dirty; | 693 | unsigned int dirty = sarea_priv->dirty; |
694 | 694 | ||
695 | DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); | 695 | DRM_DEBUG("%s %x\n", __func__, dirty); |
696 | 696 | ||
697 | if (dirty & I830_UPLOAD_BUFFERS) { | 697 | if (dirty & I830_UPLOAD_BUFFERS) { |
698 | i830EmitDestVerified(dev, sarea_priv->BufferState); | 698 | i830EmitDestVerified(dev, sarea_priv->BufferState); |
@@ -1043,7 +1043,7 @@ static void i830_dma_dispatch_flip(struct drm_device * dev) | |||
1043 | RING_LOCALS; | 1043 | RING_LOCALS; |
1044 | 1044 | ||
1045 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", | 1045 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", |
1046 | __FUNCTION__, | 1046 | __func__, |
1047 | dev_priv->current_page, | 1047 | dev_priv->current_page, |
1048 | dev_priv->sarea_priv->pf_current_page); | 1048 | dev_priv->sarea_priv->pf_current_page); |
1049 | 1049 | ||
@@ -1206,7 +1206,7 @@ static void i830_dma_quiescent(struct drm_device * dev) | |||
1206 | OUT_RING(0); | 1206 | OUT_RING(0); |
1207 | ADVANCE_LP_RING(); | 1207 | ADVANCE_LP_RING(); |
1208 | 1208 | ||
1209 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); | 1209 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | static int i830_flush_queue(struct drm_device * dev) | 1212 | static int i830_flush_queue(struct drm_device * dev) |
@@ -1223,7 +1223,7 @@ static int i830_flush_queue(struct drm_device * dev) | |||
1223 | OUT_RING(0); | 1223 | OUT_RING(0); |
1224 | ADVANCE_LP_RING(); | 1224 | ADVANCE_LP_RING(); |
1225 | 1225 | ||
1226 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); | 1226 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); |
1227 | 1227 | ||
1228 | for (i = 0; i < dma->buf_count; i++) { | 1228 | for (i = 0; i < dma->buf_count; i++) { |
1229 | struct drm_buf *buf = dma->buflist[i]; | 1229 | struct drm_buf *buf = dma->buflist[i]; |
@@ -1344,7 +1344,7 @@ static void i830_do_init_pageflip(struct drm_device * dev) | |||
1344 | { | 1344 | { |
1345 | drm_i830_private_t *dev_priv = dev->dev_private; | 1345 | drm_i830_private_t *dev_priv = dev->dev_private; |
1346 | 1346 | ||
1347 | DRM_DEBUG("%s\n", __FUNCTION__); | 1347 | DRM_DEBUG("%s\n", __func__); |
1348 | dev_priv->page_flipping = 1; | 1348 | dev_priv->page_flipping = 1; |
1349 | dev_priv->current_page = 0; | 1349 | dev_priv->current_page = 0; |
1350 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 1350 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
@@ -1354,7 +1354,7 @@ static int i830_do_cleanup_pageflip(struct drm_device * dev) | |||
1354 | { | 1354 | { |
1355 | drm_i830_private_t *dev_priv = dev->dev_private; | 1355 | drm_i830_private_t *dev_priv = dev->dev_private; |
1356 | 1356 | ||
1357 | DRM_DEBUG("%s\n", __FUNCTION__); | 1357 | DRM_DEBUG("%s\n", __func__); |
1358 | if (dev_priv->current_page != 0) | 1358 | if (dev_priv->current_page != 0) |
1359 | i830_dma_dispatch_flip(dev); | 1359 | i830_dma_dispatch_flip(dev); |
1360 | 1360 | ||
@@ -1367,7 +1367,7 @@ static int i830_flip_bufs(struct drm_device *dev, void *data, | |||
1367 | { | 1367 | { |
1368 | drm_i830_private_t *dev_priv = dev->dev_private; | 1368 | drm_i830_private_t *dev_priv = dev->dev_private; |
1369 | 1369 | ||
1370 | DRM_DEBUG("%s\n", __FUNCTION__); | 1370 | DRM_DEBUG("%s\n", __func__); |
1371 | 1371 | ||
1372 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1372 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1373 | 1373 | ||
@@ -1437,7 +1437,7 @@ static int i830_getparam(struct drm_device *dev, void *data, | |||
1437 | int value; | 1437 | int value; |
1438 | 1438 | ||
1439 | if (!dev_priv) { | 1439 | if (!dev_priv) { |
1440 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | 1440 | DRM_ERROR("%s called with no initialization\n", __func__); |
1441 | return -EINVAL; | 1441 | return -EINVAL; |
1442 | } | 1442 | } |
1443 | 1443 | ||
@@ -1464,7 +1464,7 @@ static int i830_setparam(struct drm_device *dev, void *data, | |||
1464 | drm_i830_setparam_t *param = data; | 1464 | drm_i830_setparam_t *param = data; |
1465 | 1465 | ||
1466 | if (!dev_priv) { | 1466 | if (!dev_priv) { |
1467 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | 1467 | DRM_ERROR("%s called with no initialization\n", __func__); |
1468 | return -EINVAL; | 1468 | return -EINVAL; |
1469 | } | 1469 | } |
1470 | 1470 | ||
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index 4caba8c54455..b5bf8cc0fdaa 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h | |||
@@ -158,7 +158,7 @@ extern int i830_driver_device_is_agp(struct drm_device * dev); | |||
158 | if (I830_VERBOSE) \ | 158 | if (I830_VERBOSE) \ |
159 | printk("BEGIN_LP_RING(%d)\n", (n)); \ | 159 | printk("BEGIN_LP_RING(%d)\n", (n)); \ |
160 | if (dev_priv->ring.space < n*4) \ | 160 | if (dev_priv->ring.space < n*4) \ |
161 | i830_wait_ring(dev, n*4, __FUNCTION__); \ | 161 | i830_wait_ring(dev, n*4, __func__); \ |
162 | outcount = 0; \ | 162 | outcount = 0; \ |
163 | outring = dev_priv->ring.tail; \ | 163 | outring = dev_priv->ring.tail; \ |
164 | ringmask = dev_priv->ring.tail_mask; \ | 164 | ringmask = dev_priv->ring.tail_mask; \ |
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c index a33db5f0967f..91ec2bb497e9 100644 --- a/drivers/char/drm/i830_irq.c +++ b/drivers/char/drm/i830_irq.c | |||
@@ -58,7 +58,7 @@ static int i830_emit_irq(struct drm_device * dev) | |||
58 | drm_i830_private_t *dev_priv = dev->dev_private; | 58 | drm_i830_private_t *dev_priv = dev->dev_private; |
59 | RING_LOCALS; | 59 | RING_LOCALS; |
60 | 60 | ||
61 | DRM_DEBUG("%s\n", __FUNCTION__); | 61 | DRM_DEBUG("%s\n", __func__); |
62 | 62 | ||
63 | atomic_inc(&dev_priv->irq_emitted); | 63 | atomic_inc(&dev_priv->irq_emitted); |
64 | 64 | ||
@@ -77,7 +77,7 @@ static int i830_wait_irq(struct drm_device * dev, int irq_nr) | |||
77 | unsigned long end = jiffies + HZ * 3; | 77 | unsigned long end = jiffies + HZ * 3; |
78 | int ret = 0; | 78 | int ret = 0; |
79 | 79 | ||
80 | DRM_DEBUG("%s\n", __FUNCTION__); | 80 | DRM_DEBUG("%s\n", __func__); |
81 | 81 | ||
82 | if (atomic_read(&dev_priv->irq_received) >= irq_nr) | 82 | if (atomic_read(&dev_priv->irq_received) >= irq_nr) |
83 | return 0; | 83 | return 0; |
@@ -124,7 +124,7 @@ int i830_irq_emit(struct drm_device *dev, void *data, | |||
124 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 124 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
125 | 125 | ||
126 | if (!dev_priv) { | 126 | if (!dev_priv) { |
127 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | 127 | DRM_ERROR("%s called with no initialization\n", __func__); |
128 | return -EINVAL; | 128 | return -EINVAL; |
129 | } | 129 | } |
130 | 130 | ||
@@ -147,7 +147,7 @@ int i830_irq_wait(struct drm_device *dev, void *data, | |||
147 | drm_i830_irq_wait_t *irqwait = data; | 147 | drm_i830_irq_wait_t *irqwait = data; |
148 | 148 | ||
149 | if (!dev_priv) { | 149 | if (!dev_priv) { |
150 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | 150 | DRM_ERROR("%s called with no initialization\n", __func__); |
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | } | 152 | } |
153 | 153 | ||
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index ef7bf143a80c..f47e46e3529f 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -194,7 +194,7 @@ static int i915_dma_resume(struct drm_device * dev) | |||
194 | { | 194 | { |
195 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 195 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
196 | 196 | ||
197 | DRM_DEBUG("%s\n", __FUNCTION__); | 197 | DRM_DEBUG("%s\n", __func__); |
198 | 198 | ||
199 | if (!dev_priv->sarea) { | 199 | if (!dev_priv->sarea) { |
200 | DRM_ERROR("can not find sarea!\n"); | 200 | DRM_ERROR("can not find sarea!\n"); |
@@ -609,7 +609,7 @@ static int i915_quiescent(struct drm_device * dev) | |||
609 | drm_i915_private_t *dev_priv = dev->dev_private; | 609 | drm_i915_private_t *dev_priv = dev->dev_private; |
610 | 610 | ||
611 | i915_kernel_lost_context(dev); | 611 | i915_kernel_lost_context(dev); |
612 | return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); | 612 | return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); |
613 | } | 613 | } |
614 | 614 | ||
615 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 615 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index c614d78b3dfd..db7001f22561 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
@@ -272,7 +272,7 @@ extern void i915_mem_release(struct drm_device * dev, | |||
272 | if (I915_VERBOSE) \ | 272 | if (I915_VERBOSE) \ |
273 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ | 273 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ |
274 | if (dev_priv->ring.space < (n)*4) \ | 274 | if (dev_priv->ring.space < (n)*4) \ |
275 | i915_wait_ring(dev, (n)*4, __FUNCTION__); \ | 275 | i915_wait_ring(dev, (n)*4, __func__); \ |
276 | outcount = 0; \ | 276 | outcount = 0; \ |
277 | outring = dev_priv->ring.tail; \ | 277 | outring = dev_priv->ring.tail; \ |
278 | ringmask = dev_priv->ring.tail_mask; \ | 278 | ringmask = dev_priv->ring.tail_mask; \ |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 9072e4a1894e..f6f6c92bf771 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -894,7 +894,7 @@ static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr) | |||
894 | #if RADEON_FIFO_DEBUG | 894 | #if RADEON_FIFO_DEBUG |
895 | static void radeon_status(drm_radeon_private_t * dev_priv) | 895 | static void radeon_status(drm_radeon_private_t * dev_priv) |
896 | { | 896 | { |
897 | printk("%s:\n", __FUNCTION__); | 897 | printk("%s:\n", __func__); |
898 | printk("RBBM_STATUS = 0x%08x\n", | 898 | printk("RBBM_STATUS = 0x%08x\n", |
899 | (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); | 899 | (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); |
900 | printk("CP_RB_RTPR = 0x%08x\n", | 900 | printk("CP_RB_RTPR = 0x%08x\n", |
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c index 59146e3365ba..ea35ab2c9909 100644 --- a/drivers/char/ds1286.c +++ b/drivers/char/ds1286.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/bcd.h> | 40 | #include <linux/bcd.h> |
41 | #include <linux/proc_fs.h> | 41 | #include <linux/proc_fs.h> |
42 | #include <linux/jiffies.h> | ||
42 | 43 | ||
43 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
44 | #include <asm/system.h> | 45 | #include <asm/system.h> |
@@ -451,7 +452,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) | |||
451 | */ | 452 | */ |
452 | 453 | ||
453 | if (ds1286_is_updating() != 0) | 454 | if (ds1286_is_updating() != 0) |
454 | while (jiffies - uip_watchdog < 2*HZ/100) | 455 | while (time_before(jiffies, uip_watchdog + 2*HZ/100)) |
455 | barrier(); | 456 | barrier(); |
456 | 457 | ||
457 | /* | 458 | /* |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index ffd747c5dff0..60a4df7dac12 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -38,8 +38,8 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <asm/uaccess.h> | 41 | #include <linux/uaccess.h> |
42 | #include <asm/io.h> | 42 | #include <linux/io.h> |
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/pci.h> | 44 | #include <linux/pci.h> |
45 | #include "digiPCI.h" | 45 | #include "digiPCI.h" |
@@ -73,7 +73,8 @@ static int invalid_lilo_config; | |||
73 | */ | 73 | */ |
74 | static DEFINE_SPINLOCK(epca_lock); | 74 | static DEFINE_SPINLOCK(epca_lock); |
75 | 75 | ||
76 | /* MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. */ | 76 | /* MAXBOARDS is typically 12, but ISA and EISA cards are restricted |
77 | to 7 below. */ | ||
77 | static struct board_info boards[MAXBOARDS]; | 78 | static struct board_info boards[MAXBOARDS]; |
78 | 79 | ||
79 | static struct tty_driver *pc_driver; | 80 | static struct tty_driver *pc_driver; |
@@ -157,13 +158,12 @@ static void epca_error(int, char *); | |||
157 | static void pc_close(struct tty_struct *, struct file *); | 158 | static void pc_close(struct tty_struct *, struct file *); |
158 | static void shutdown(struct channel *); | 159 | static void shutdown(struct channel *); |
159 | static void pc_hangup(struct tty_struct *); | 160 | static void pc_hangup(struct tty_struct *); |
160 | static void pc_put_char(struct tty_struct *, unsigned char); | ||
161 | static int pc_write_room(struct tty_struct *); | 161 | static int pc_write_room(struct tty_struct *); |
162 | static int pc_chars_in_buffer(struct tty_struct *); | 162 | static int pc_chars_in_buffer(struct tty_struct *); |
163 | static void pc_flush_buffer(struct tty_struct *); | 163 | static void pc_flush_buffer(struct tty_struct *); |
164 | static void pc_flush_chars(struct tty_struct *); | 164 | static void pc_flush_chars(struct tty_struct *); |
165 | static int block_til_ready(struct tty_struct *, struct file *, | 165 | static int block_til_ready(struct tty_struct *, struct file *, |
166 | struct channel *); | 166 | struct channel *); |
167 | static int pc_open(struct tty_struct *, struct file *); | 167 | static int pc_open(struct tty_struct *, struct file *); |
168 | static void post_fep_init(unsigned int crd); | 168 | static void post_fep_init(unsigned int crd); |
169 | static void epcapoll(unsigned long); | 169 | static void epcapoll(unsigned long); |
@@ -175,18 +175,18 @@ static unsigned termios2digi_c(struct channel *ch, unsigned); | |||
175 | static void epcaparam(struct tty_struct *, struct channel *); | 175 | static void epcaparam(struct tty_struct *, struct channel *); |
176 | static void receive_data(struct channel *); | 176 | static void receive_data(struct channel *); |
177 | static int pc_ioctl(struct tty_struct *, struct file *, | 177 | static int pc_ioctl(struct tty_struct *, struct file *, |
178 | unsigned int, unsigned long); | 178 | unsigned int, unsigned long); |
179 | static int info_ioctl(struct tty_struct *, struct file *, | 179 | static int info_ioctl(struct tty_struct *, struct file *, |
180 | unsigned int, unsigned long); | 180 | unsigned int, unsigned long); |
181 | static void pc_set_termios(struct tty_struct *, struct ktermios *); | 181 | static void pc_set_termios(struct tty_struct *, struct ktermios *); |
182 | static void do_softint(struct work_struct *work); | 182 | static void do_softint(struct work_struct *work); |
183 | static void pc_stop(struct tty_struct *); | 183 | static void pc_stop(struct tty_struct *); |
184 | static void pc_start(struct tty_struct *); | 184 | static void pc_start(struct tty_struct *); |
185 | static void pc_throttle(struct tty_struct * tty); | 185 | static void pc_throttle(struct tty_struct *tty); |
186 | static void pc_unthrottle(struct tty_struct *tty); | 186 | static void pc_unthrottle(struct tty_struct *tty); |
187 | static void digi_send_break(struct channel *ch, int msec); | 187 | static void digi_send_break(struct channel *ch, int msec); |
188 | static void setup_empty_event(struct tty_struct *tty, struct channel *ch); | 188 | static void setup_empty_event(struct tty_struct *tty, struct channel *ch); |
189 | void epca_setup(char *, int *); | 189 | static void epca_setup(char *, int *); |
190 | 190 | ||
191 | static int pc_write(struct tty_struct *, const unsigned char *, int); | 191 | static int pc_write(struct tty_struct *, const unsigned char *, int); |
192 | static int pc_init(void); | 192 | static int pc_init(void); |
@@ -243,7 +243,7 @@ static void assertmemoff(struct channel *ch) | |||
243 | /* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ | 243 | /* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ |
244 | static void pcxem_memwinon(struct board_info *b, unsigned int win) | 244 | static void pcxem_memwinon(struct board_info *b, unsigned int win) |
245 | { | 245 | { |
246 | outb_p(FEPWIN|win, b->port + 1); | 246 | outb_p(FEPWIN | win, b->port + 1); |
247 | } | 247 | } |
248 | 248 | ||
249 | static void pcxem_memwinoff(struct board_info *b, unsigned int win) | 249 | static void pcxem_memwinoff(struct board_info *b, unsigned int win) |
@@ -253,7 +253,7 @@ static void pcxem_memwinoff(struct board_info *b, unsigned int win) | |||
253 | 253 | ||
254 | static void pcxem_globalwinon(struct channel *ch) | 254 | static void pcxem_globalwinon(struct channel *ch) |
255 | { | 255 | { |
256 | outb_p( FEPWIN, (int)ch->board->port + 1); | 256 | outb_p(FEPWIN, (int)ch->board->port + 1); |
257 | } | 257 | } |
258 | 258 | ||
259 | static void pcxem_rxwinon(struct channel *ch) | 259 | static void pcxem_rxwinon(struct channel *ch) |
@@ -394,7 +394,7 @@ static struct channel *verifyChannel(struct tty_struct *tty) | |||
394 | */ | 394 | */ |
395 | if (tty) { | 395 | if (tty) { |
396 | struct channel *ch = (struct channel *)tty->driver_data; | 396 | struct channel *ch = (struct channel *)tty->driver_data; |
397 | if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) { | 397 | if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) { |
398 | if (ch->magic == EPCA_MAGIC) | 398 | if (ch->magic == EPCA_MAGIC) |
399 | return ch; | 399 | return ch; |
400 | } | 400 | } |
@@ -414,7 +414,7 @@ static void pc_sched_event(struct channel *ch, int event) | |||
414 | 414 | ||
415 | static void epca_error(int line, char *msg) | 415 | static void epca_error(int line, char *msg) |
416 | { | 416 | { |
417 | printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg); | 417 | printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg); |
418 | } | 418 | } |
419 | 419 | ||
420 | static void pc_close(struct tty_struct *tty, struct file *filp) | 420 | static void pc_close(struct tty_struct *tty, struct file *filp) |
@@ -425,7 +425,8 @@ static void pc_close(struct tty_struct *tty, struct file *filp) | |||
425 | * verifyChannel returns the channel from the tty struct if it is | 425 | * verifyChannel returns the channel from the tty struct if it is |
426 | * valid. This serves as a sanity check. | 426 | * valid. This serves as a sanity check. |
427 | */ | 427 | */ |
428 | if ((ch = verifyChannel(tty)) != NULL) { | 428 | ch = verifyChannel(tty); |
429 | if (ch != NULL) { | ||
429 | spin_lock_irqsave(&epca_lock, flags); | 430 | spin_lock_irqsave(&epca_lock, flags); |
430 | if (tty_hung_up_p(filp)) { | 431 | if (tty_hung_up_p(filp)) { |
431 | spin_unlock_irqrestore(&epca_lock, flags); | 432 | spin_unlock_irqrestore(&epca_lock, flags); |
@@ -440,7 +441,6 @@ static void pc_close(struct tty_struct *tty, struct file *filp) | |||
440 | spin_unlock_irqrestore(&epca_lock, flags); | 441 | spin_unlock_irqrestore(&epca_lock, flags); |
441 | return; | 442 | return; |
442 | } | 443 | } |
443 | |||
444 | /* Port open only once go ahead with shutdown & reset */ | 444 | /* Port open only once go ahead with shutdown & reset */ |
445 | BUG_ON(ch->count < 0); | 445 | BUG_ON(ch->count < 0); |
446 | 446 | ||
@@ -455,12 +455,13 @@ static void pc_close(struct tty_struct *tty, struct file *filp) | |||
455 | spin_unlock_irqrestore(&epca_lock, flags); | 455 | spin_unlock_irqrestore(&epca_lock, flags); |
456 | 456 | ||
457 | if (ch->asyncflags & ASYNC_INITIALIZED) { | 457 | if (ch->asyncflags & ASYNC_INITIALIZED) { |
458 | /* Setup an event to indicate when the transmit buffer empties */ | 458 | /* Setup an event to indicate when the |
459 | transmit buffer empties */ | ||
459 | setup_empty_event(tty, ch); | 460 | setup_empty_event(tty, ch); |
460 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 461 | /* 30 seconds timeout */ |
462 | tty_wait_until_sent(tty, 3000); | ||
461 | } | 463 | } |
462 | if (tty->driver->flush_buffer) | 464 | pc_flush_buffer(tty); |
463 | tty->driver->flush_buffer(tty); | ||
464 | 465 | ||
465 | tty_ldisc_flush(tty); | 466 | tty_ldisc_flush(tty); |
466 | shutdown(ch); | 467 | shutdown(ch); |
@@ -477,7 +478,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp) | |||
477 | wake_up_interruptible(&ch->open_wait); | 478 | wake_up_interruptible(&ch->open_wait); |
478 | } | 479 | } |
479 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | | 480 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | |
480 | ASYNC_CLOSING); | 481 | ASYNC_CLOSING); |
481 | wake_up_interruptible(&ch->close_wait); | 482 | wake_up_interruptible(&ch->close_wait); |
482 | } | 483 | } |
483 | } | 484 | } |
@@ -524,16 +525,15 @@ static void shutdown(struct channel *ch) | |||
524 | static void pc_hangup(struct tty_struct *tty) | 525 | static void pc_hangup(struct tty_struct *tty) |
525 | { | 526 | { |
526 | struct channel *ch; | 527 | struct channel *ch; |
527 | |||
528 | /* | 528 | /* |
529 | * verifyChannel returns the channel from the tty struct if it is | 529 | * verifyChannel returns the channel from the tty struct if it is |
530 | * valid. This serves as a sanity check. | 530 | * valid. This serves as a sanity check. |
531 | */ | 531 | */ |
532 | if ((ch = verifyChannel(tty)) != NULL) { | 532 | ch = verifyChannel(tty); |
533 | if (ch != NULL) { | ||
533 | unsigned long flags; | 534 | unsigned long flags; |
534 | 535 | ||
535 | if (tty->driver->flush_buffer) | 536 | pc_flush_buffer(tty); |
536 | tty->driver->flush_buffer(tty); | ||
537 | tty_ldisc_flush(tty); | 537 | tty_ldisc_flush(tty); |
538 | shutdown(ch); | 538 | shutdown(ch); |
539 | 539 | ||
@@ -548,7 +548,7 @@ static void pc_hangup(struct tty_struct *tty) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | static int pc_write(struct tty_struct *tty, | 550 | static int pc_write(struct tty_struct *tty, |
551 | const unsigned char *buf, int bytesAvailable) | 551 | const unsigned char *buf, int bytesAvailable) |
552 | { | 552 | { |
553 | unsigned int head, tail; | 553 | unsigned int head, tail; |
554 | int dataLen; | 554 | int dataLen; |
@@ -572,7 +572,8 @@ static int pc_write(struct tty_struct *tty, | |||
572 | * verifyChannel returns the channel from the tty struct if it is | 572 | * verifyChannel returns the channel from the tty struct if it is |
573 | * valid. This serves as a sanity check. | 573 | * valid. This serves as a sanity check. |
574 | */ | 574 | */ |
575 | if ((ch = verifyChannel(tty)) == NULL) | 575 | ch = verifyChannel(tty); |
576 | if (ch == NULL) | ||
576 | return 0; | 577 | return 0; |
577 | 578 | ||
578 | /* Make a pointer to the channel data structure found on the board. */ | 579 | /* Make a pointer to the channel data structure found on the board. */ |
@@ -645,26 +646,19 @@ static int pc_write(struct tty_struct *tty, | |||
645 | return amountCopied; | 646 | return amountCopied; |
646 | } | 647 | } |
647 | 648 | ||
648 | static void pc_put_char(struct tty_struct *tty, unsigned char c) | ||
649 | { | ||
650 | pc_write(tty, &c, 1); | ||
651 | } | ||
652 | |||
653 | static int pc_write_room(struct tty_struct *tty) | 649 | static int pc_write_room(struct tty_struct *tty) |
654 | { | 650 | { |
655 | int remain; | 651 | int remain = 0; |
656 | struct channel *ch; | 652 | struct channel *ch; |
657 | unsigned long flags; | 653 | unsigned long flags; |
658 | unsigned int head, tail; | 654 | unsigned int head, tail; |
659 | struct board_chan __iomem *bc; | 655 | struct board_chan __iomem *bc; |
660 | |||
661 | remain = 0; | ||
662 | |||
663 | /* | 656 | /* |
664 | * verifyChannel returns the channel from the tty struct if it is | 657 | * verifyChannel returns the channel from the tty struct if it is |
665 | * valid. This serves as a sanity check. | 658 | * valid. This serves as a sanity check. |
666 | */ | 659 | */ |
667 | if ((ch = verifyChannel(tty)) != NULL) { | 660 | ch = verifyChannel(tty); |
661 | if (ch != NULL) { | ||
668 | spin_lock_irqsave(&epca_lock, flags); | 662 | spin_lock_irqsave(&epca_lock, flags); |
669 | globalwinon(ch); | 663 | globalwinon(ch); |
670 | 664 | ||
@@ -676,8 +670,8 @@ static int pc_write_room(struct tty_struct *tty) | |||
676 | tail = readw(&bc->tout); | 670 | tail = readw(&bc->tout); |
677 | /* Wrap tail if necessary */ | 671 | /* Wrap tail if necessary */ |
678 | tail &= (ch->txbufsize - 1); | 672 | tail &= (ch->txbufsize - 1); |
679 | 673 | remain = tail - head - 1; | |
680 | if ((remain = tail - head - 1) < 0 ) | 674 | if (remain < 0) |
681 | remain += ch->txbufsize; | 675 | remain += ch->txbufsize; |
682 | 676 | ||
683 | if (remain && (ch->statusflags & LOWWAIT) == 0) { | 677 | if (remain && (ch->statusflags & LOWWAIT) == 0) { |
@@ -699,12 +693,12 @@ static int pc_chars_in_buffer(struct tty_struct *tty) | |||
699 | unsigned long flags; | 693 | unsigned long flags; |
700 | struct channel *ch; | 694 | struct channel *ch; |
701 | struct board_chan __iomem *bc; | 695 | struct board_chan __iomem *bc; |
702 | |||
703 | /* | 696 | /* |
704 | * verifyChannel returns the channel from the tty struct if it is | 697 | * verifyChannel returns the channel from the tty struct if it is |
705 | * valid. This serves as a sanity check. | 698 | * valid. This serves as a sanity check. |
706 | */ | 699 | */ |
707 | if ((ch = verifyChannel(tty)) == NULL) | 700 | ch = verifyChannel(tty); |
701 | if (ch == NULL) | ||
708 | return 0; | 702 | return 0; |
709 | 703 | ||
710 | spin_lock_irqsave(&epca_lock, flags); | 704 | spin_lock_irqsave(&epca_lock, flags); |
@@ -715,7 +709,8 @@ static int pc_chars_in_buffer(struct tty_struct *tty) | |||
715 | head = readw(&bc->tin); | 709 | head = readw(&bc->tin); |
716 | ctail = readw(&ch->mailbox->cout); | 710 | ctail = readw(&ch->mailbox->cout); |
717 | 711 | ||
718 | if (tail == head && readw(&ch->mailbox->cin) == ctail && readb(&bc->tbusy) == 0) | 712 | if (tail == head && readw(&ch->mailbox->cin) == ctail && |
713 | readb(&bc->tbusy) == 0) | ||
719 | chars = 0; | 714 | chars = 0; |
720 | else { /* Begin if some space on the card has been used */ | 715 | else { /* Begin if some space on the card has been used */ |
721 | head = readw(&bc->tin) & (ch->txbufsize - 1); | 716 | head = readw(&bc->tin) & (ch->txbufsize - 1); |
@@ -725,7 +720,8 @@ static int pc_chars_in_buffer(struct tty_struct *tty) | |||
725 | * pc_write_room here we are finding the amount of bytes in the | 720 | * pc_write_room here we are finding the amount of bytes in the |
726 | * buffer filled. Not the amount of bytes empty. | 721 | * buffer filled. Not the amount of bytes empty. |
727 | */ | 722 | */ |
728 | if ((remain = tail - head - 1) < 0 ) | 723 | remain = tail - head - 1; |
724 | if (remain < 0) | ||
729 | remain += ch->txbufsize; | 725 | remain += ch->txbufsize; |
730 | chars = (int)(ch->txbufsize - remain); | 726 | chars = (int)(ch->txbufsize - remain); |
731 | /* | 727 | /* |
@@ -736,7 +732,7 @@ static int pc_chars_in_buffer(struct tty_struct *tty) | |||
736 | * transmit buffer empties. | 732 | * transmit buffer empties. |
737 | */ | 733 | */ |
738 | if (!(ch->statusflags & EMPTYWAIT)) | 734 | if (!(ch->statusflags & EMPTYWAIT)) |
739 | setup_empty_event(tty,ch); | 735 | setup_empty_event(tty, ch); |
740 | } /* End if some space on the card has been used */ | 736 | } /* End if some space on the card has been used */ |
741 | memoff(ch); | 737 | memoff(ch); |
742 | spin_unlock_irqrestore(&epca_lock, flags); | 738 | spin_unlock_irqrestore(&epca_lock, flags); |
@@ -754,7 +750,8 @@ static void pc_flush_buffer(struct tty_struct *tty) | |||
754 | * verifyChannel returns the channel from the tty struct if it is | 750 | * verifyChannel returns the channel from the tty struct if it is |
755 | * valid. This serves as a sanity check. | 751 | * valid. This serves as a sanity check. |
756 | */ | 752 | */ |
757 | if ((ch = verifyChannel(tty)) == NULL) | 753 | ch = verifyChannel(tty); |
754 | if (ch == NULL) | ||
758 | return; | 755 | return; |
759 | 756 | ||
760 | spin_lock_irqsave(&epca_lock, flags); | 757 | spin_lock_irqsave(&epca_lock, flags); |
@@ -775,23 +772,25 @@ static void pc_flush_chars(struct tty_struct *tty) | |||
775 | * verifyChannel returns the channel from the tty struct if it is | 772 | * verifyChannel returns the channel from the tty struct if it is |
776 | * valid. This serves as a sanity check. | 773 | * valid. This serves as a sanity check. |
777 | */ | 774 | */ |
778 | if ((ch = verifyChannel(tty)) != NULL) { | 775 | ch = verifyChannel(tty); |
776 | if (ch != NULL) { | ||
779 | unsigned long flags; | 777 | unsigned long flags; |
780 | spin_lock_irqsave(&epca_lock, flags); | 778 | spin_lock_irqsave(&epca_lock, flags); |
781 | /* | 779 | /* |
782 | * If not already set and the transmitter is busy setup an | 780 | * If not already set and the transmitter is busy setup an |
783 | * event to indicate when the transmit empties. | 781 | * event to indicate when the transmit empties. |
784 | */ | 782 | */ |
785 | if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT)) | 783 | if ((ch->statusflags & TXBUSY) && |
786 | setup_empty_event(tty,ch); | 784 | !(ch->statusflags & EMPTYWAIT)) |
785 | setup_empty_event(tty, ch); | ||
787 | spin_unlock_irqrestore(&epca_lock, flags); | 786 | spin_unlock_irqrestore(&epca_lock, flags); |
788 | } | 787 | } |
789 | } | 788 | } |
790 | 789 | ||
791 | static int block_til_ready(struct tty_struct *tty, | 790 | static int block_til_ready(struct tty_struct *tty, |
792 | struct file *filp, struct channel *ch) | 791 | struct file *filp, struct channel *ch) |
793 | { | 792 | { |
794 | DECLARE_WAITQUEUE(wait,current); | 793 | DECLARE_WAITQUEUE(wait, current); |
795 | int retval, do_clocal = 0; | 794 | int retval, do_clocal = 0; |
796 | unsigned long flags; | 795 | unsigned long flags; |
797 | 796 | ||
@@ -839,8 +838,7 @@ static int block_til_ready(struct tty_struct *tty, | |||
839 | while (1) { | 838 | while (1) { |
840 | set_current_state(TASK_INTERRUPTIBLE); | 839 | set_current_state(TASK_INTERRUPTIBLE); |
841 | if (tty_hung_up_p(filp) || | 840 | if (tty_hung_up_p(filp) || |
842 | !(ch->asyncflags & ASYNC_INITIALIZED)) | 841 | !(ch->asyncflags & ASYNC_INITIALIZED)) { |
843 | { | ||
844 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) | 842 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) |
845 | retval = -EAGAIN; | 843 | retval = -EAGAIN; |
846 | else | 844 | else |
@@ -880,7 +878,7 @@ static int block_til_ready(struct tty_struct *tty, | |||
880 | return 0; | 878 | return 0; |
881 | } | 879 | } |
882 | 880 | ||
883 | static int pc_open(struct tty_struct *tty, struct file * filp) | 881 | static int pc_open(struct tty_struct *tty, struct file *filp) |
884 | { | 882 | { |
885 | struct channel *ch; | 883 | struct channel *ch; |
886 | unsigned long flags; | 884 | unsigned long flags; |
@@ -923,7 +921,8 @@ static int pc_open(struct tty_struct *tty, struct file * filp) | |||
923 | return(-ENODEV); | 921 | return(-ENODEV); |
924 | } | 922 | } |
925 | 923 | ||
926 | if ((bc = ch->brdchan) == 0) { | 924 | bc = ch->brdchan; |
925 | if (bc == NULL) { | ||
927 | tty->driver_data = NULL; | 926 | tty->driver_data = NULL; |
928 | return -ENODEV; | 927 | return -ENODEV; |
929 | } | 928 | } |
@@ -964,7 +963,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp) | |||
964 | * The below routine generally sets up parity, baud, flow control | 963 | * The below routine generally sets up parity, baud, flow control |
965 | * issues, etc.... It effect both control flags and input flags. | 964 | * issues, etc.... It effect both control flags and input flags. |
966 | */ | 965 | */ |
967 | epcaparam(tty,ch); | 966 | epcaparam(tty, ch); |
968 | ch->asyncflags |= ASYNC_INITIALIZED; | 967 | ch->asyncflags |= ASYNC_INITIALIZED; |
969 | memoff(ch); | 968 | memoff(ch); |
970 | spin_unlock_irqrestore(&epca_lock, flags); | 969 | spin_unlock_irqrestore(&epca_lock, flags); |
@@ -1002,8 +1001,8 @@ static void __exit epca_module_exit(void) | |||
1002 | 1001 | ||
1003 | del_timer_sync(&epca_timer); | 1002 | del_timer_sync(&epca_timer); |
1004 | 1003 | ||
1005 | if (tty_unregister_driver(pc_driver) || tty_unregister_driver(pc_info)) | 1004 | if (tty_unregister_driver(pc_driver) || |
1006 | { | 1005 | tty_unregister_driver(pc_info)) { |
1007 | printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); | 1006 | printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); |
1008 | return; | 1007 | return; |
1009 | } | 1008 | } |
@@ -1034,7 +1033,6 @@ static const struct tty_operations pc_ops = { | |||
1034 | .flush_buffer = pc_flush_buffer, | 1033 | .flush_buffer = pc_flush_buffer, |
1035 | .chars_in_buffer = pc_chars_in_buffer, | 1034 | .chars_in_buffer = pc_chars_in_buffer, |
1036 | .flush_chars = pc_flush_chars, | 1035 | .flush_chars = pc_flush_chars, |
1037 | .put_char = pc_put_char, | ||
1038 | .ioctl = pc_ioctl, | 1036 | .ioctl = pc_ioctl, |
1039 | .set_termios = pc_set_termios, | 1037 | .set_termios = pc_set_termios, |
1040 | .stop = pc_stop, | 1038 | .stop = pc_stop, |
@@ -1044,7 +1042,7 @@ static const struct tty_operations pc_ops = { | |||
1044 | .hangup = pc_hangup, | 1042 | .hangup = pc_hangup, |
1045 | }; | 1043 | }; |
1046 | 1044 | ||
1047 | static int info_open(struct tty_struct *tty, struct file * filp) | 1045 | static int info_open(struct tty_struct *tty, struct file *filp) |
1048 | { | 1046 | { |
1049 | return 0; | 1047 | return 0; |
1050 | } | 1048 | } |
@@ -1099,7 +1097,7 @@ static int __init pc_init(void) | |||
1099 | * Set up interrupt, we will worry about memory allocation in | 1097 | * Set up interrupt, we will worry about memory allocation in |
1100 | * post_fep_init. | 1098 | * post_fep_init. |
1101 | */ | 1099 | */ |
1102 | printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION); | 1100 | printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION); |
1103 | 1101 | ||
1104 | /* | 1102 | /* |
1105 | * NOTE : This code assumes that the number of ports found in the | 1103 | * NOTE : This code assumes that the number of ports found in the |
@@ -1252,7 +1250,7 @@ static int __init pc_init(void) | |||
1252 | if ((board_id & 0x30) == 0x30) | 1250 | if ((board_id & 0x30) == 0x30) |
1253 | bd->memory_seg = 0x8000; | 1251 | bd->memory_seg = 0x8000; |
1254 | } else | 1252 | } else |
1255 | printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port); | 1253 | printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port); |
1256 | break; | 1254 | break; |
1257 | } | 1255 | } |
1258 | } | 1256 | } |
@@ -1326,12 +1324,12 @@ static void post_fep_init(unsigned int crd) | |||
1326 | */ | 1324 | */ |
1327 | /* PCI cards are already remapped at this point ISA are not */ | 1325 | /* PCI cards are already remapped at this point ISA are not */ |
1328 | bd->numports = readw(bd->re_map_membase + XEMPORTS); | 1326 | bd->numports = readw(bd->re_map_membase + XEMPORTS); |
1329 | epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports"); | 1327 | epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports"); |
1330 | nbdevs += (bd->numports); | 1328 | nbdevs += (bd->numports); |
1331 | } else { | 1329 | } else { |
1332 | /* Fix up the mappings for ISA/EISA etc */ | 1330 | /* Fix up the mappings for ISA/EISA etc */ |
1333 | /* FIXME: 64K - can we be smarter ? */ | 1331 | /* FIXME: 64K - can we be smarter ? */ |
1334 | bd->re_map_membase = ioremap(bd->membase, 0x10000); | 1332 | bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000); |
1335 | } | 1333 | } |
1336 | 1334 | ||
1337 | if (crd != 0) | 1335 | if (crd != 0) |
@@ -1362,7 +1360,8 @@ static void post_fep_init(unsigned int crd) | |||
1362 | * XEPORTS (address 0xc22) points at the number of channels the card | 1360 | * XEPORTS (address 0xc22) points at the number of channels the card |
1363 | * supports. (For 64XE, XI, XEM, and XR use 0xc02) | 1361 | * supports. (For 64XE, XI, XEM, and XR use 0xc02) |
1364 | */ | 1362 | */ |
1365 | if ((bd->type == PCXEVE || bd->type == PCXE) && (readw(memaddr + XEPORTS) < 3)) | 1363 | if ((bd->type == PCXEVE || bd->type == PCXE) && |
1364 | (readw(memaddr + XEPORTS) < 3)) | ||
1366 | shrinkmem = 1; | 1365 | shrinkmem = 1; |
1367 | if (bd->type < PCIXEM) | 1366 | if (bd->type < PCIXEM) |
1368 | if (!request_region((int)bd->port, 4, board_desc[bd->type])) | 1367 | if (!request_region((int)bd->port, 4, board_desc[bd->type])) |
@@ -1461,10 +1460,12 @@ static void post_fep_init(unsigned int crd) | |||
1461 | 1460 | ||
1462 | case PCXEVE: | 1461 | case PCXEVE: |
1463 | case PCXE: | 1462 | case PCXE: |
1464 | ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff); | 1463 | ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) |
1464 | & 0x1fff); | ||
1465 | ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); | 1465 | ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); |
1466 | ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff); | 1466 | ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) |
1467 | ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 ); | 1467 | & 0x1fff); |
1468 | ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9); | ||
1468 | break; | 1469 | break; |
1469 | 1470 | ||
1470 | case PCXI: | 1471 | case PCXI: |
@@ -1518,8 +1519,9 @@ static void post_fep_init(unsigned int crd) | |||
1518 | } | 1519 | } |
1519 | 1520 | ||
1520 | printk(KERN_INFO | 1521 | printk(KERN_INFO |
1521 | "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", | 1522 | "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", |
1522 | VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports); | 1523 | VERSION, board_desc[bd->type], (long)bd->port, |
1524 | (long)bd->membase, bd->numports); | ||
1523 | memwinoff(bd, 0); | 1525 | memwinoff(bd, 0); |
1524 | } | 1526 | } |
1525 | 1527 | ||
@@ -1527,7 +1529,7 @@ static void epcapoll(unsigned long ignored) | |||
1527 | { | 1529 | { |
1528 | unsigned long flags; | 1530 | unsigned long flags; |
1529 | int crd; | 1531 | int crd; |
1530 | volatile unsigned int head, tail; | 1532 | unsigned int head, tail; |
1531 | struct channel *ch; | 1533 | struct channel *ch; |
1532 | struct board_info *bd; | 1534 | struct board_info *bd; |
1533 | 1535 | ||
@@ -1593,7 +1595,9 @@ static void doevent(int crd) | |||
1593 | chan0 = card_ptr[crd]; | 1595 | chan0 = card_ptr[crd]; |
1594 | epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); | 1596 | epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); |
1595 | assertgwinon(chan0); | 1597 | assertgwinon(chan0); |
1596 | while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) { /* Begin while something in event queue */ | 1598 | while ((tail = readw(&chan0->mailbox->eout)) != |
1599 | (head = readw(&chan0->mailbox->ein))) { | ||
1600 | /* Begin while something in event queue */ | ||
1597 | assertgwinon(chan0); | 1601 | assertgwinon(chan0); |
1598 | eventbuf = bd->re_map_membase + tail + ISTART; | 1602 | eventbuf = bd->re_map_membase + tail + ISTART; |
1599 | /* Get the channel the event occurred on */ | 1603 | /* Get the channel the event occurred on */ |
@@ -1617,7 +1621,8 @@ static void doevent(int crd) | |||
1617 | goto next; | 1621 | goto next; |
1618 | } | 1622 | } |
1619 | 1623 | ||
1620 | if ((bc = ch->brdchan) == NULL) | 1624 | bc = ch->brdchan; |
1625 | if (bc == NULL) | ||
1621 | goto next; | 1626 | goto next; |
1622 | 1627 | ||
1623 | if (event & DATA_IND) { /* Begin DATA_IND */ | 1628 | if (event & DATA_IND) { /* Begin DATA_IND */ |
@@ -1629,10 +1634,11 @@ static void doevent(int crd) | |||
1629 | /* A modem signal change has been indicated */ | 1634 | /* A modem signal change has been indicated */ |
1630 | ch->imodem = mstat; | 1635 | ch->imodem = mstat; |
1631 | if (ch->asyncflags & ASYNC_CHECK_CD) { | 1636 | if (ch->asyncflags & ASYNC_CHECK_CD) { |
1632 | if (mstat & ch->dcd) /* We are now receiving dcd */ | 1637 | /* We are now receiving dcd */ |
1638 | if (mstat & ch->dcd) | ||
1633 | wake_up_interruptible(&ch->open_wait); | 1639 | wake_up_interruptible(&ch->open_wait); |
1634 | else | 1640 | else /* No dcd; hangup */ |
1635 | pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */ | 1641 | pc_sched_event(ch, EPCA_EVENT_HANGUP); |
1636 | } | 1642 | } |
1637 | } | 1643 | } |
1638 | tty = ch->tty; | 1644 | tty = ch->tty; |
@@ -1647,7 +1653,8 @@ static void doevent(int crd) | |||
1647 | tty_wakeup(tty); | 1653 | tty_wakeup(tty); |
1648 | } | 1654 | } |
1649 | } else if (event & EMPTYTX_IND) { | 1655 | } else if (event & EMPTYTX_IND) { |
1650 | /* This event is generated by setup_empty_event */ | 1656 | /* This event is generated by |
1657 | setup_empty_event */ | ||
1651 | ch->statusflags &= ~TXBUSY; | 1658 | ch->statusflags &= ~TXBUSY; |
1652 | if (ch->statusflags & EMPTYWAIT) { | 1659 | if (ch->statusflags & EMPTYWAIT) { |
1653 | ch->statusflags &= ~EMPTYWAIT; | 1660 | ch->statusflags &= ~EMPTYWAIT; |
@@ -1655,7 +1662,7 @@ static void doevent(int crd) | |||
1655 | } | 1662 | } |
1656 | } | 1663 | } |
1657 | } | 1664 | } |
1658 | next: | 1665 | next: |
1659 | globalwinon(ch); | 1666 | globalwinon(ch); |
1660 | BUG_ON(!bc); | 1667 | BUG_ON(!bc); |
1661 | writew(1, &bc->idata); | 1668 | writew(1, &bc->idata); |
@@ -1665,7 +1672,7 @@ static void doevent(int crd) | |||
1665 | } | 1672 | } |
1666 | 1673 | ||
1667 | static void fepcmd(struct channel *ch, int cmd, int word_or_byte, | 1674 | static void fepcmd(struct channel *ch, int cmd, int word_or_byte, |
1668 | int byte2, int ncmds, int bytecmd) | 1675 | int byte2, int ncmds, int bytecmd) |
1669 | { | 1676 | { |
1670 | unchar __iomem *memaddr; | 1677 | unchar __iomem *memaddr; |
1671 | unsigned int head, cmdTail, cmdStart, cmdMax; | 1678 | unsigned int head, cmdTail, cmdStart, cmdMax; |
@@ -1690,8 +1697,10 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte, | |||
1690 | memaddr = ch->board->re_map_membase; | 1697 | memaddr = ch->board->re_map_membase; |
1691 | 1698 | ||
1692 | if (head >= (cmdMax - cmdStart) || (head & 03)) { | 1699 | if (head >= (cmdMax - cmdStart) || (head & 03)) { |
1693 | printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", __LINE__, cmd, head); | 1700 | printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", |
1694 | printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", __LINE__, cmdMax, cmdStart); | 1701 | __LINE__, cmd, head); |
1702 | printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", | ||
1703 | __LINE__, cmdMax, cmdStart); | ||
1695 | return; | 1704 | return; |
1696 | } | 1705 | } |
1697 | if (bytecmd) { | 1706 | if (bytecmd) { |
@@ -1770,7 +1779,7 @@ static unsigned termios2digi_h(struct channel *ch, unsigned cflag) | |||
1770 | static unsigned termios2digi_i(struct channel *ch, unsigned iflag) | 1779 | static unsigned termios2digi_i(struct channel *ch, unsigned iflag) |
1771 | { | 1780 | { |
1772 | unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | | 1781 | unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | |
1773 | INPCK | ISTRIP|IXON|IXANY|IXOFF); | 1782 | INPCK | ISTRIP | IXON | IXANY | IXOFF); |
1774 | if (ch->digiext.digi_flags & DIGI_AIXON) | 1783 | if (ch->digiext.digi_flags & DIGI_AIXON) |
1775 | res |= IAIXON; | 1784 | res |= IAIXON; |
1776 | return res; | 1785 | return res; |
@@ -1838,7 +1847,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) | |||
1838 | unsigned mval, hflow, cflag, iflag; | 1847 | unsigned mval, hflow, cflag, iflag; |
1839 | 1848 | ||
1840 | bc = ch->brdchan; | 1849 | bc = ch->brdchan; |
1841 | epcaassert(bc !=0, "bc out of range"); | 1850 | epcaassert(bc != NULL, "bc out of range"); |
1842 | 1851 | ||
1843 | assertgwinon(ch); | 1852 | assertgwinon(ch); |
1844 | ts = tty->termios; | 1853 | ts = tty->termios; |
@@ -1884,8 +1893,10 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) | |||
1884 | * Command sets channels iflag structure on the board. Such | 1893 | * Command sets channels iflag structure on the board. Such |
1885 | * things as input soft flow control, handling of parity | 1894 | * things as input soft flow control, handling of parity |
1886 | * errors, and break handling are all set here. | 1895 | * errors, and break handling are all set here. |
1896 | * | ||
1897 | * break handling, parity handling, input stripping, | ||
1898 | * flow control chars | ||
1887 | */ | 1899 | */ |
1888 | /* break handling, parity handling, input stripping, flow control chars */ | ||
1889 | fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); | 1900 | fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); |
1890 | } | 1901 | } |
1891 | /* | 1902 | /* |
@@ -1981,7 +1992,7 @@ static void receive_data(struct channel *ch) | |||
1981 | return; | 1992 | return; |
1982 | 1993 | ||
1983 | /* If CREAD bit is off or device not open, set TX tail to head */ | 1994 | /* If CREAD bit is off or device not open, set TX tail to head */ |
1984 | if (!tty || !ts || !(ts->c_cflag & CREAD)) { | 1995 | if (!tty || !ts || !(ts->c_cflag & CREAD)) { |
1985 | writew(head, &bc->rout); | 1996 | writew(head, &bc->rout); |
1986 | return; | 1997 | return; |
1987 | } | 1998 | } |
@@ -1991,18 +2002,21 @@ static void receive_data(struct channel *ch) | |||
1991 | 2002 | ||
1992 | if (readb(&bc->orun)) { | 2003 | if (readb(&bc->orun)) { |
1993 | writeb(0, &bc->orun); | 2004 | writeb(0, &bc->orun); |
1994 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name); | 2005 | printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n", |
2006 | tty->name); | ||
1995 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 2007 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1996 | } | 2008 | } |
1997 | rxwinon(ch); | 2009 | rxwinon(ch); |
1998 | while (bytesAvailable > 0) { /* Begin while there is data on the card */ | 2010 | while (bytesAvailable > 0) { |
2011 | /* Begin while there is data on the card */ | ||
1999 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; | 2012 | wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; |
2000 | /* | 2013 | /* |
2001 | * Even if head has wrapped around only report the amount of | 2014 | * Even if head has wrapped around only report the amount of |
2002 | * data to be equal to the size - tail. Remember memcpy can't | 2015 | * data to be equal to the size - tail. Remember memcpy can't |
2003 | * automaticly wrap around the receive buffer. | 2016 | * automaticly wrap around the receive buffer. |
2004 | */ | 2017 | */ |
2005 | dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable; | 2018 | dataToRead = (wrapgap < bytesAvailable) ? wrapgap |
2019 | : bytesAvailable; | ||
2006 | /* Make sure we don't overflow the buffer */ | 2020 | /* Make sure we don't overflow the buffer */ |
2007 | dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); | 2021 | dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); |
2008 | if (dataToRead == 0) | 2022 | if (dataToRead == 0) |
@@ -2153,14 +2167,14 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file, | |||
2153 | * The below routine generally sets up parity, baud, flow control | 2167 | * The below routine generally sets up parity, baud, flow control |
2154 | * issues, etc.... It effect both control flags and input flags. | 2168 | * issues, etc.... It effect both control flags and input flags. |
2155 | */ | 2169 | */ |
2156 | epcaparam(tty,ch); | 2170 | epcaparam(tty, ch); |
2157 | memoff(ch); | 2171 | memoff(ch); |
2158 | spin_unlock_irqrestore(&epca_lock, flags); | 2172 | spin_unlock_irqrestore(&epca_lock, flags); |
2159 | return 0; | 2173 | return 0; |
2160 | } | 2174 | } |
2161 | 2175 | ||
2162 | static int pc_ioctl(struct tty_struct *tty, struct file * file, | 2176 | static int pc_ioctl(struct tty_struct *tty, struct file *file, |
2163 | unsigned int cmd, unsigned long arg) | 2177 | unsigned int cmd, unsigned long arg) |
2164 | { | 2178 | { |
2165 | digiflow_t dflow; | 2179 | digiflow_t dflow; |
2166 | int retval; | 2180 | int retval; |
@@ -2175,7 +2189,6 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2175 | bc = ch->brdchan; | 2189 | bc = ch->brdchan; |
2176 | else | 2190 | else |
2177 | return -EINVAL; | 2191 | return -EINVAL; |
2178 | |||
2179 | /* | 2192 | /* |
2180 | * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in | 2193 | * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in |
2181 | * /usr/src/linux/drivers/char for a good example. In particular think | 2194 | * /usr/src/linux/drivers/char for a good example. In particular think |
@@ -2186,9 +2199,10 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2186 | retval = tty_check_change(tty); | 2199 | retval = tty_check_change(tty); |
2187 | if (retval) | 2200 | if (retval) |
2188 | return retval; | 2201 | return retval; |
2189 | /* Setup an event to indicate when the transmit buffer empties */ | 2202 | /* Setup an event to indicate when the transmit |
2203 | buffer empties */ | ||
2190 | spin_lock_irqsave(&epca_lock, flags); | 2204 | spin_lock_irqsave(&epca_lock, flags); |
2191 | setup_empty_event(tty,ch); | 2205 | setup_empty_event(tty, ch); |
2192 | spin_unlock_irqrestore(&epca_lock, flags); | 2206 | spin_unlock_irqrestore(&epca_lock, flags); |
2193 | tty_wait_until_sent(tty, 0); | 2207 | tty_wait_until_sent(tty, 0); |
2194 | if (!arg) | 2208 | if (!arg) |
@@ -2198,29 +2212,14 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2198 | retval = tty_check_change(tty); | 2212 | retval = tty_check_change(tty); |
2199 | if (retval) | 2213 | if (retval) |
2200 | return retval; | 2214 | return retval; |
2201 | 2215 | /* Setup an event to indicate when the transmit buffer | |
2202 | /* Setup an event to indicate when the transmit buffer empties */ | 2216 | empties */ |
2203 | spin_lock_irqsave(&epca_lock, flags); | 2217 | spin_lock_irqsave(&epca_lock, flags); |
2204 | setup_empty_event(tty,ch); | 2218 | setup_empty_event(tty, ch); |
2205 | spin_unlock_irqrestore(&epca_lock, flags); | 2219 | spin_unlock_irqrestore(&epca_lock, flags); |
2206 | tty_wait_until_sent(tty, 0); | 2220 | tty_wait_until_sent(tty, 0); |
2207 | digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4); | 2221 | digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4); |
2208 | return 0; | 2222 | return 0; |
2209 | case TIOCGSOFTCAR: | ||
2210 | if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg)) | ||
2211 | return -EFAULT; | ||
2212 | return 0; | ||
2213 | case TIOCSSOFTCAR: | ||
2214 | { | ||
2215 | unsigned int value; | ||
2216 | |||
2217 | if (get_user(value, (unsigned __user *)argp)) | ||
2218 | return -EFAULT; | ||
2219 | tty->termios->c_cflag = | ||
2220 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
2221 | (value ? CLOCAL : 0)); | ||
2222 | return 0; | ||
2223 | } | ||
2224 | case TIOCMODG: | 2223 | case TIOCMODG: |
2225 | mflag = pc_tiocmget(tty, file); | 2224 | mflag = pc_tiocmget(tty, file); |
2226 | if (put_user(mflag, (unsigned long __user *)argp)) | 2225 | if (put_user(mflag, (unsigned long __user *)argp)) |
@@ -2253,10 +2252,12 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2253 | break; | 2252 | break; |
2254 | case DIGI_SETAW: | 2253 | case DIGI_SETAW: |
2255 | case DIGI_SETAF: | 2254 | case DIGI_SETAF: |
2255 | lock_kernel(); | ||
2256 | if (cmd == DIGI_SETAW) { | 2256 | if (cmd == DIGI_SETAW) { |
2257 | /* Setup an event to indicate when the transmit buffer empties */ | 2257 | /* Setup an event to indicate when the transmit |
2258 | buffer empties */ | ||
2258 | spin_lock_irqsave(&epca_lock, flags); | 2259 | spin_lock_irqsave(&epca_lock, flags); |
2259 | setup_empty_event(tty,ch); | 2260 | setup_empty_event(tty, ch); |
2260 | spin_unlock_irqrestore(&epca_lock, flags); | 2261 | spin_unlock_irqrestore(&epca_lock, flags); |
2261 | tty_wait_until_sent(tty, 0); | 2262 | tty_wait_until_sent(tty, 0); |
2262 | } else { | 2263 | } else { |
@@ -2264,6 +2265,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2264 | if (tty->ldisc.flush_buffer) | 2265 | if (tty->ldisc.flush_buffer) |
2265 | tty->ldisc.flush_buffer(tty); | 2266 | tty->ldisc.flush_buffer(tty); |
2266 | } | 2267 | } |
2268 | unlock_kernel(); | ||
2267 | /* Fall Thru */ | 2269 | /* Fall Thru */ |
2268 | case DIGI_SETA: | 2270 | case DIGI_SETA: |
2269 | if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) | 2271 | if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) |
@@ -2285,7 +2287,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2285 | * control issues, etc.... It effect both control flags and | 2287 | * control issues, etc.... It effect both control flags and |
2286 | * input flags. | 2288 | * input flags. |
2287 | */ | 2289 | */ |
2288 | epcaparam(tty,ch); | 2290 | epcaparam(tty, ch); |
2289 | memoff(ch); | 2291 | memoff(ch); |
2290 | spin_unlock_irqrestore(&epca_lock, flags); | 2292 | spin_unlock_irqrestore(&epca_lock, flags); |
2291 | break; | 2293 | break; |
@@ -2321,18 +2323,21 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2321 | if (copy_from_user(&dflow, argp, sizeof(dflow))) | 2323 | if (copy_from_user(&dflow, argp, sizeof(dflow))) |
2322 | return -EFAULT; | 2324 | return -EFAULT; |
2323 | 2325 | ||
2324 | if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */ | 2326 | if (dflow.startc != startc || dflow.stopc != stopc) { |
2327 | /* Begin if setflow toggled */ | ||
2325 | spin_lock_irqsave(&epca_lock, flags); | 2328 | spin_lock_irqsave(&epca_lock, flags); |
2326 | globalwinon(ch); | 2329 | globalwinon(ch); |
2327 | 2330 | ||
2328 | if (cmd == DIGI_SETFLOW) { | 2331 | if (cmd == DIGI_SETFLOW) { |
2329 | ch->fepstartc = ch->startc = dflow.startc; | 2332 | ch->fepstartc = ch->startc = dflow.startc; |
2330 | ch->fepstopc = ch->stopc = dflow.stopc; | 2333 | ch->fepstopc = ch->stopc = dflow.stopc; |
2331 | fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); | 2334 | fepcmd(ch, SONOFFC, ch->fepstartc, |
2335 | ch->fepstopc, 0, 1); | ||
2332 | } else { | 2336 | } else { |
2333 | ch->fepstartca = ch->startca = dflow.startc; | 2337 | ch->fepstartca = ch->startca = dflow.startc; |
2334 | ch->fepstopca = ch->stopca = dflow.stopc; | 2338 | ch->fepstopca = ch->stopca = dflow.stopc; |
2335 | fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); | 2339 | fepcmd(ch, SAUXONOFFC, ch->fepstartca, |
2340 | ch->fepstopca, 0, 1); | ||
2336 | } | 2341 | } |
2337 | 2342 | ||
2338 | if (ch->statusflags & TXSTOPPED) | 2343 | if (ch->statusflags & TXSTOPPED) |
@@ -2356,7 +2361,9 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
2356 | * verifyChannel returns the channel from the tty struct if it is | 2361 | * verifyChannel returns the channel from the tty struct if it is |
2357 | * valid. This serves as a sanity check. | 2362 | * valid. This serves as a sanity check. |
2358 | */ | 2363 | */ |
2359 | if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */ | 2364 | ch = verifyChannel(tty); |
2365 | |||
2366 | if (ch != NULL) { /* Begin if channel valid */ | ||
2360 | spin_lock_irqsave(&epca_lock, flags); | 2367 | spin_lock_irqsave(&epca_lock, flags); |
2361 | globalwinon(ch); | 2368 | globalwinon(ch); |
2362 | epcaparam(tty, ch); | 2369 | epcaparam(tty, ch); |
@@ -2383,7 +2390,7 @@ static void do_softint(struct work_struct *work) | |||
2383 | 2390 | ||
2384 | if (tty && tty->driver_data) { | 2391 | if (tty && tty->driver_data) { |
2385 | if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { | 2392 | if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { |
2386 | tty_hangup(tty); /* FIXME: module removal race here - AKPM */ | 2393 | tty_hangup(tty); |
2387 | wake_up_interruptible(&ch->open_wait); | 2394 | wake_up_interruptible(&ch->open_wait); |
2388 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | 2395 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; |
2389 | } | 2396 | } |
@@ -2403,9 +2410,11 @@ static void pc_stop(struct tty_struct *tty) | |||
2403 | * verifyChannel returns the channel from the tty struct if it is | 2410 | * verifyChannel returns the channel from the tty struct if it is |
2404 | * valid. This serves as a sanity check. | 2411 | * valid. This serves as a sanity check. |
2405 | */ | 2412 | */ |
2406 | if ((ch = verifyChannel(tty)) != NULL) { | 2413 | ch = verifyChannel(tty); |
2414 | if (ch != NULL) { | ||
2407 | spin_lock_irqsave(&epca_lock, flags); | 2415 | spin_lock_irqsave(&epca_lock, flags); |
2408 | if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */ | 2416 | if ((ch->statusflags & TXSTOPPED) == 0) { |
2417 | /* Begin if transmit stop requested */ | ||
2409 | globalwinon(ch); | 2418 | globalwinon(ch); |
2410 | /* STOP transmitting now !! */ | 2419 | /* STOP transmitting now !! */ |
2411 | fepcmd(ch, PAUSETX, 0, 0, 0, 0); | 2420 | fepcmd(ch, PAUSETX, 0, 0, 0, 0); |
@@ -2423,11 +2432,14 @@ static void pc_start(struct tty_struct *tty) | |||
2423 | * verifyChannel returns the channel from the tty struct if it is | 2432 | * verifyChannel returns the channel from the tty struct if it is |
2424 | * valid. This serves as a sanity check. | 2433 | * valid. This serves as a sanity check. |
2425 | */ | 2434 | */ |
2426 | if ((ch = verifyChannel(tty)) != NULL) { | 2435 | ch = verifyChannel(tty); |
2436 | if (ch != NULL) { | ||
2427 | unsigned long flags; | 2437 | unsigned long flags; |
2428 | spin_lock_irqsave(&epca_lock, flags); | 2438 | spin_lock_irqsave(&epca_lock, flags); |
2429 | /* Just in case output was resumed because of a change in Digi-flow */ | 2439 | /* Just in case output was resumed because of a change |
2430 | if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */ | 2440 | in Digi-flow */ |
2441 | if (ch->statusflags & TXSTOPPED) { | ||
2442 | /* Begin transmit resume requested */ | ||
2431 | struct board_chan __iomem *bc; | 2443 | struct board_chan __iomem *bc; |
2432 | globalwinon(ch); | 2444 | globalwinon(ch); |
2433 | bc = ch->brdchan; | 2445 | bc = ch->brdchan; |
@@ -2457,7 +2469,8 @@ static void pc_throttle(struct tty_struct *tty) | |||
2457 | * verifyChannel returns the channel from the tty struct if it is | 2469 | * verifyChannel returns the channel from the tty struct if it is |
2458 | * valid. This serves as a sanity check. | 2470 | * valid. This serves as a sanity check. |
2459 | */ | 2471 | */ |
2460 | if ((ch = verifyChannel(tty)) != NULL) { | 2472 | ch = verifyChannel(tty); |
2473 | if (ch != NULL) { | ||
2461 | spin_lock_irqsave(&epca_lock, flags); | 2474 | spin_lock_irqsave(&epca_lock, flags); |
2462 | if ((ch->statusflags & RXSTOPPED) == 0) { | 2475 | if ((ch->statusflags & RXSTOPPED) == 0) { |
2463 | globalwinon(ch); | 2476 | globalwinon(ch); |
@@ -2477,8 +2490,10 @@ static void pc_unthrottle(struct tty_struct *tty) | |||
2477 | * verifyChannel returns the channel from the tty struct if it is | 2490 | * verifyChannel returns the channel from the tty struct if it is |
2478 | * valid. This serves as a sanity check. | 2491 | * valid. This serves as a sanity check. |
2479 | */ | 2492 | */ |
2480 | if ((ch = verifyChannel(tty)) != NULL) { | 2493 | ch = verifyChannel(tty); |
2481 | /* Just in case output was resumed because of a change in Digi-flow */ | 2494 | if (ch != NULL) { |
2495 | /* Just in case output was resumed because of a change | ||
2496 | in Digi-flow */ | ||
2482 | spin_lock_irqsave(&epca_lock, flags); | 2497 | spin_lock_irqsave(&epca_lock, flags); |
2483 | if (ch->statusflags & RXSTOPPED) { | 2498 | if (ch->statusflags & RXSTOPPED) { |
2484 | globalwinon(ch); | 2499 | globalwinon(ch); |
@@ -2490,7 +2505,7 @@ static void pc_unthrottle(struct tty_struct *tty) | |||
2490 | } | 2505 | } |
2491 | } | 2506 | } |
2492 | 2507 | ||
2493 | void digi_send_break(struct channel *ch, int msec) | 2508 | static void digi_send_break(struct channel *ch, int msec) |
2494 | { | 2509 | { |
2495 | unsigned long flags; | 2510 | unsigned long flags; |
2496 | 2511 | ||
@@ -2523,7 +2538,7 @@ static void setup_empty_event(struct tty_struct *tty, struct channel *ch) | |||
2523 | memoff(ch); | 2538 | memoff(ch); |
2524 | } | 2539 | } |
2525 | 2540 | ||
2526 | void epca_setup(char *str, int *ints) | 2541 | static void epca_setup(char *str, int *ints) |
2527 | { | 2542 | { |
2528 | struct board_info board; | 2543 | struct board_info board; |
2529 | int index, loop, last; | 2544 | int index, loop, last; |
@@ -2552,14 +2567,16 @@ void epca_setup(char *str, int *ints) | |||
2552 | * instructing the driver to ignore epcaconfig.) For | 2567 | * instructing the driver to ignore epcaconfig.) For |
2553 | * this reason we check for 2. | 2568 | * this reason we check for 2. |
2554 | */ | 2569 | */ |
2555 | if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */ | 2570 | if (board.status == 2) { |
2571 | /* Begin ignore epcaconfig as well as lilo cmd line */ | ||
2556 | nbdevs = 0; | 2572 | nbdevs = 0; |
2557 | num_cards = 0; | 2573 | num_cards = 0; |
2558 | return; | 2574 | return; |
2559 | } /* End ignore epcaconfig as well as lilo cmd line */ | 2575 | } /* End ignore epcaconfig as well as lilo cmd line */ |
2560 | 2576 | ||
2561 | if (board.status > 2) { | 2577 | if (board.status > 2) { |
2562 | printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status); | 2578 | printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", |
2579 | board.status); | ||
2563 | invalid_lilo_config = 1; | 2580 | invalid_lilo_config = 1; |
2564 | setup_error_code |= INVALID_BOARD_STATUS; | 2581 | setup_error_code |= INVALID_BOARD_STATUS; |
2565 | return; | 2582 | return; |
@@ -2613,7 +2630,8 @@ void epca_setup(char *str, int *ints) | |||
2613 | case 6: | 2630 | case 6: |
2614 | board.membase = ints[index]; | 2631 | board.membase = ints[index]; |
2615 | if (ints[index] <= 0) { | 2632 | if (ints[index] <= 0) { |
2616 | printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase); | 2633 | printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n", |
2634 | (unsigned int)board.membase); | ||
2617 | invalid_lilo_config = 1; | 2635 | invalid_lilo_config = 1; |
2618 | setup_error_code |= INVALID_MEM_BASE; | 2636 | setup_error_code |= INVALID_MEM_BASE; |
2619 | return; | 2637 | return; |
@@ -2744,7 +2762,7 @@ void epca_setup(char *str, int *ints) | |||
2744 | t2++; | 2762 | t2++; |
2745 | 2763 | ||
2746 | if (*t2) { | 2764 | if (*t2) { |
2747 | printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str); | 2765 | printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str); |
2748 | invalid_lilo_config = 1; | 2766 | invalid_lilo_config = 1; |
2749 | setup_error_code |= INVALID_MEM_BASE; | 2767 | setup_error_code |= INVALID_MEM_BASE; |
2750 | return; | 2768 | return; |
@@ -2766,7 +2784,7 @@ void epca_setup(char *str, int *ints) | |||
2766 | 2784 | ||
2767 | /* I should REALLY validate the stuff here */ | 2785 | /* I should REALLY validate the stuff here */ |
2768 | /* Copies our local copy of board into boards */ | 2786 | /* Copies our local copy of board into boards */ |
2769 | memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board)); | 2787 | memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board)); |
2770 | /* Does this get called once per lilo arg are what ? */ | 2788 | /* Does this get called once per lilo arg are what ? */ |
2771 | printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", | 2789 | printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", |
2772 | num_cards, board_desc[board.type], | 2790 | num_cards, board_desc[board.type], |
@@ -2807,9 +2825,9 @@ static int __devinit epca_init_one(struct pci_dev *pdev, | |||
2807 | if (board_idx >= MAXBOARDS) | 2825 | if (board_idx >= MAXBOARDS) |
2808 | goto err_out; | 2826 | goto err_out; |
2809 | 2827 | ||
2810 | addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx); | 2828 | addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx); |
2811 | if (!addr) { | 2829 | if (!addr) { |
2812 | printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n", | 2830 | printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n", |
2813 | epca_info_tbl[info_idx].bar_idx); | 2831 | epca_info_tbl[info_idx].bar_idx); |
2814 | goto err_out; | 2832 | goto err_out; |
2815 | } | 2833 | } |
@@ -2820,28 +2838,29 @@ static int __devinit epca_init_one(struct pci_dev *pdev, | |||
2820 | boards[board_idx].port = addr + PCI_IO_OFFSET; | 2838 | boards[board_idx].port = addr + PCI_IO_OFFSET; |
2821 | boards[board_idx].membase = addr; | 2839 | boards[board_idx].membase = addr; |
2822 | 2840 | ||
2823 | if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) { | 2841 | if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) { |
2824 | printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", | 2842 | printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", |
2825 | 0x200000, addr + PCI_IO_OFFSET); | 2843 | 0x200000, addr + PCI_IO_OFFSET); |
2826 | goto err_out; | 2844 | goto err_out; |
2827 | } | 2845 | } |
2828 | 2846 | ||
2829 | boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000); | 2847 | boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET, |
2848 | 0x200000); | ||
2830 | if (!boards[board_idx].re_map_port) { | 2849 | if (!boards[board_idx].re_map_port) { |
2831 | printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", | 2850 | printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", |
2832 | 0x200000, addr + PCI_IO_OFFSET); | 2851 | 0x200000, addr + PCI_IO_OFFSET); |
2833 | goto err_out_free_pciio; | 2852 | goto err_out_free_pciio; |
2834 | } | 2853 | } |
2835 | 2854 | ||
2836 | if (!request_mem_region (addr, 0x200000, "epca")) { | 2855 | if (!request_mem_region(addr, 0x200000, "epca")) { |
2837 | printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", | 2856 | printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", |
2838 | 0x200000, addr); | 2857 | 0x200000, addr); |
2839 | goto err_out_free_iounmap; | 2858 | goto err_out_free_iounmap; |
2840 | } | 2859 | } |
2841 | 2860 | ||
2842 | boards[board_idx].re_map_membase = ioremap(addr, 0x200000); | 2861 | boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000); |
2843 | if (!boards[board_idx].re_map_membase) { | 2862 | if (!boards[board_idx].re_map_membase) { |
2844 | printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", | 2863 | printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", |
2845 | 0x200000, addr + PCI_IO_OFFSET); | 2864 | 0x200000, addr + PCI_IO_OFFSET); |
2846 | goto err_out_free_memregion; | 2865 | goto err_out_free_memregion; |
2847 | } | 2866 | } |
@@ -2858,11 +2877,11 @@ static int __devinit epca_init_one(struct pci_dev *pdev, | |||
2858 | return 0; | 2877 | return 0; |
2859 | 2878 | ||
2860 | err_out_free_memregion: | 2879 | err_out_free_memregion: |
2861 | release_mem_region (addr, 0x200000); | 2880 | release_mem_region(addr, 0x200000); |
2862 | err_out_free_iounmap: | 2881 | err_out_free_iounmap: |
2863 | iounmap (boards[board_idx].re_map_port); | 2882 | iounmap(boards[board_idx].re_map_port); |
2864 | err_out_free_pciio: | 2883 | err_out_free_pciio: |
2865 | release_mem_region (addr + PCI_IO_OFFSET, 0x200000); | 2884 | release_mem_region(addr + PCI_IO_OFFSET, 0x200000); |
2866 | err_out: | 2885 | err_out: |
2867 | return -ENODEV; | 2886 | return -ENODEV; |
2868 | } | 2887 | } |
@@ -2878,9 +2897,9 @@ static struct pci_device_id epca_pci_tbl[] = { | |||
2878 | 2897 | ||
2879 | MODULE_DEVICE_TABLE(pci, epca_pci_tbl); | 2898 | MODULE_DEVICE_TABLE(pci, epca_pci_tbl); |
2880 | 2899 | ||
2881 | int __init init_PCI (void) | 2900 | static int __init init_PCI(void) |
2882 | { | 2901 | { |
2883 | memset (&epca_driver, 0, sizeof (epca_driver)); | 2902 | memset(&epca_driver, 0, sizeof(epca_driver)); |
2884 | epca_driver.name = "epca"; | 2903 | epca_driver.name = "epca"; |
2885 | epca_driver.id_table = epca_pci_tbl; | 2904 | epca_driver.id_table = epca_pci_tbl; |
2886 | epca_driver.probe = epca_init_one; | 2905 | epca_driver.probe = epca_init_one; |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index f3fe62067344..84840ba13ff0 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now | 8 | * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now |
9 | * much more extensible to support other serial cards based on the | 9 | * much more extensible to support other serial cards based on the |
10 | * 16450/16550A UART's. Added support for the AST FourPort and the | 10 | * 16450/16550A UART's. Added support for the AST FourPort and the |
11 | * Accent Async board. | 11 | * Accent Async board. |
12 | * | 12 | * |
13 | * set_serial_info fixed to set the flags, custom divisor, and uart | 13 | * set_serial_info fixed to set the flags, custom divisor, and uart |
14 | * type fields. Fix suggested by Michael K. Johnson 12/12/92. | 14 | * type fields. Fix suggested by Michael K. Johnson 12/12/92. |
@@ -61,11 +61,11 @@ | |||
61 | #include <linux/bitops.h> | 61 | #include <linux/bitops.h> |
62 | 62 | ||
63 | #include <asm/system.h> | 63 | #include <asm/system.h> |
64 | #include <asm/io.h> | 64 | #include <linux/io.h> |
65 | 65 | ||
66 | #include <asm/dma.h> | 66 | #include <asm/dma.h> |
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <asm/uaccess.h> | 68 | #include <linux/uaccess.h> |
69 | 69 | ||
70 | #include <linux/hayesesp.h> | 70 | #include <linux/hayesesp.h> |
71 | 71 | ||
@@ -127,8 +127,10 @@ static struct tty_driver *esp_driver; | |||
127 | #undef SERIAL_DEBUG_FLOW | 127 | #undef SERIAL_DEBUG_FLOW |
128 | 128 | ||
129 | #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) | 129 | #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) |
130 | #define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ | 130 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ |
131 | tty->name, (info->flags), serial_driver.refcount,info->count,tty->count,s) | 131 | tty->name, info->flags, \ |
132 | serial_driver.refcount, \ | ||
133 | info->count, tty->count, s) | ||
132 | #else | 134 | #else |
133 | #define DBG_CNT(s) | 135 | #define DBG_CNT(s) |
134 | #endif | 136 | #endif |
@@ -189,7 +191,7 @@ static inline void serial_out(struct esp_struct *info, int offset, | |||
189 | */ | 191 | */ |
190 | static void rs_stop(struct tty_struct *tty) | 192 | static void rs_stop(struct tty_struct *tty) |
191 | { | 193 | { |
192 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 194 | struct esp_struct *info = tty->driver_data; |
193 | unsigned long flags; | 195 | unsigned long flags; |
194 | 196 | ||
195 | if (serial_paranoia_check(info, tty->name, "rs_stop")) | 197 | if (serial_paranoia_check(info, tty->name, "rs_stop")) |
@@ -206,12 +208,12 @@ static void rs_stop(struct tty_struct *tty) | |||
206 | 208 | ||
207 | static void rs_start(struct tty_struct *tty) | 209 | static void rs_start(struct tty_struct *tty) |
208 | { | 210 | { |
209 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 211 | struct esp_struct *info = tty->driver_data; |
210 | unsigned long flags; | 212 | unsigned long flags; |
211 | 213 | ||
212 | if (serial_paranoia_check(info, tty->name, "rs_start")) | 214 | if (serial_paranoia_check(info, tty->name, "rs_start")) |
213 | return; | 215 | return; |
214 | 216 | ||
215 | spin_lock_irqsave(&info->lock, flags); | 217 | spin_lock_irqsave(&info->lock, flags); |
216 | if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) { | 218 | if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) { |
217 | info->IER |= UART_IER_THRI; | 219 | info->IER |= UART_IER_THRI; |
@@ -233,7 +235,7 @@ static void rs_start(struct tty_struct *tty) | |||
233 | * rs_interrupt() should try to keep the interrupt handler as fast as | 235 | * rs_interrupt() should try to keep the interrupt handler as fast as |
234 | * possible. After you are done making modifications, it is not a bad | 236 | * possible. After you are done making modifications, it is not a bad |
235 | * idea to do: | 237 | * idea to do: |
236 | * | 238 | * |
237 | * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c | 239 | * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c |
238 | * | 240 | * |
239 | * and look at the resulting assemble code in serial.s. | 241 | * and look at the resulting assemble code in serial.s. |
@@ -290,7 +292,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | |||
290 | } | 292 | } |
291 | 293 | ||
292 | status_mask = (info->read_status_mask >> 2) & 0x07; | 294 | status_mask = (info->read_status_mask >> 2) & 0x07; |
293 | 295 | ||
294 | for (i = 0; i < num_bytes - 1; i += 2) { | 296 | for (i = 0; i < num_bytes - 1; i += 2) { |
295 | *((unsigned short *)(pio_buf->data + i)) = | 297 | *((unsigned short *)(pio_buf->data + i)) = |
296 | inw(info->port + UART_ESI_RX); | 298 | inw(info->port + UART_ESI_RX); |
@@ -325,8 +327,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | |||
325 | flag = TTY_BREAK; | 327 | flag = TTY_BREAK; |
326 | if (info->flags & ASYNC_SAK) | 328 | if (info->flags & ASYNC_SAK) |
327 | do_SAK(tty); | 329 | do_SAK(tty); |
328 | } | 330 | } else if (err_buf->data[i] & 0x02) |
329 | else if (err_buf->data[i] & 0x02) | ||
330 | flag = TTY_FRAME; | 331 | flag = TTY_FRAME; |
331 | else if (err_buf->data[i] & 0x01) | 332 | else if (err_buf->data[i] & 0x01) |
332 | flag = TTY_PARITY; | 333 | flag = TTY_PARITY; |
@@ -341,23 +342,29 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | |||
341 | release_pio_buffer(err_buf); | 342 | release_pio_buffer(err_buf); |
342 | } | 343 | } |
343 | 344 | ||
344 | static inline void receive_chars_dma(struct esp_struct *info, int num_bytes) | 345 | static void program_isa_dma(int dma, int dir, unsigned long addr, int len) |
345 | { | 346 | { |
346 | unsigned long flags; | 347 | unsigned long flags; |
348 | |||
349 | flags = claim_dma_lock(); | ||
350 | disable_dma(dma); | ||
351 | clear_dma_ff(dma); | ||
352 | set_dma_mode(dma, dir); | ||
353 | set_dma_addr(dma, addr); | ||
354 | set_dma_count(dma, len); | ||
355 | enable_dma(dma); | ||
356 | release_dma_lock(flags); | ||
357 | } | ||
358 | |||
359 | static void receive_chars_dma(struct esp_struct *info, int num_bytes) | ||
360 | { | ||
347 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | 361 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; |
348 | dma_bytes = num_bytes; | 362 | dma_bytes = num_bytes; |
349 | info->stat_flags |= ESP_STAT_DMA_RX; | 363 | info->stat_flags |= ESP_STAT_DMA_RX; |
350 | 364 | ||
351 | flags=claim_dma_lock(); | 365 | program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer), |
352 | disable_dma(dma); | 366 | dma_bytes); |
353 | clear_dma_ff(dma); | 367 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX); |
354 | set_dma_mode(dma, DMA_MODE_READ); | ||
355 | set_dma_addr(dma, isa_virt_to_bus(dma_buffer)); | ||
356 | set_dma_count(dma, dma_bytes); | ||
357 | enable_dma(dma); | ||
358 | release_dma_lock(flags); | ||
359 | |||
360 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX); | ||
361 | } | 368 | } |
362 | 369 | ||
363 | static inline void receive_chars_dma_done(struct esp_struct *info, | 370 | static inline void receive_chars_dma_done(struct esp_struct *info, |
@@ -366,22 +373,22 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
366 | struct tty_struct *tty = info->tty; | 373 | struct tty_struct *tty = info->tty; |
367 | int num_bytes; | 374 | int num_bytes; |
368 | unsigned long flags; | 375 | unsigned long flags; |
369 | 376 | ||
370 | flags=claim_dma_lock(); | 377 | flags = claim_dma_lock(); |
371 | disable_dma(dma); | 378 | disable_dma(dma); |
372 | clear_dma_ff(dma); | 379 | clear_dma_ff(dma); |
373 | 380 | ||
374 | info->stat_flags &= ~ESP_STAT_DMA_RX; | 381 | info->stat_flags &= ~ESP_STAT_DMA_RX; |
375 | num_bytes = dma_bytes - get_dma_residue(dma); | 382 | num_bytes = dma_bytes - get_dma_residue(dma); |
376 | release_dma_lock(flags); | 383 | release_dma_lock(flags); |
377 | 384 | ||
378 | info->icount.rx += num_bytes; | 385 | info->icount.rx += num_bytes; |
379 | 386 | ||
380 | if (num_bytes > 0) { | 387 | if (num_bytes > 0) { |
381 | tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); | 388 | tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); |
382 | 389 | ||
383 | status &= (0x1c & info->read_status_mask); | 390 | status &= (0x1c & info->read_status_mask); |
384 | 391 | ||
385 | /* Is the status significant or do we throw the last byte ? */ | 392 | /* Is the status significant or do we throw the last byte ? */ |
386 | if (!(status & info->ignore_status_mask)) { | 393 | if (!(status & info->ignore_status_mask)) { |
387 | int statflag = 0; | 394 | int statflag = 0; |
@@ -393,13 +400,13 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
393 | do_SAK(tty); | 400 | do_SAK(tty); |
394 | } else if (status & 0x08) { | 401 | } else if (status & 0x08) { |
395 | statflag = TTY_FRAME; | 402 | statflag = TTY_FRAME; |
396 | (info->icount.frame)++; | 403 | info->icount.frame++; |
397 | } | 404 | } else if (status & 0x04) { |
398 | else if (status & 0x04) { | ||
399 | statflag = TTY_PARITY; | 405 | statflag = TTY_PARITY; |
400 | (info->icount.parity)++; | 406 | info->icount.parity++; |
401 | } | 407 | } |
402 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); | 408 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], |
409 | statflag); | ||
403 | } | 410 | } |
404 | tty_schedule_flip(tty); | 411 | tty_schedule_flip(tty); |
405 | } | 412 | } |
@@ -484,8 +491,6 @@ static inline void transmit_chars_pio(struct esp_struct *info, | |||
484 | /* Caller must hold info->lock */ | 491 | /* Caller must hold info->lock */ |
485 | static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes) | 492 | static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes) |
486 | { | 493 | { |
487 | unsigned long flags; | ||
488 | |||
489 | dma_bytes = num_bytes; | 494 | dma_bytes = num_bytes; |
490 | 495 | ||
491 | if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) { | 496 | if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) { |
@@ -517,26 +522,18 @@ static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes) | |||
517 | } | 522 | } |
518 | 523 | ||
519 | info->stat_flags |= ESP_STAT_DMA_TX; | 524 | info->stat_flags |= ESP_STAT_DMA_TX; |
520 | 525 | ||
521 | flags=claim_dma_lock(); | 526 | program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer), |
522 | disable_dma(dma); | 527 | dma_bytes); |
523 | clear_dma_ff(dma); | 528 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); |
524 | set_dma_mode(dma, DMA_MODE_WRITE); | ||
525 | set_dma_addr(dma, isa_virt_to_bus(dma_buffer)); | ||
526 | set_dma_count(dma, dma_bytes); | ||
527 | enable_dma(dma); | ||
528 | release_dma_lock(flags); | ||
529 | |||
530 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); | ||
531 | } | 529 | } |
532 | 530 | ||
533 | static inline void transmit_chars_dma_done(struct esp_struct *info) | 531 | static inline void transmit_chars_dma_done(struct esp_struct *info) |
534 | { | 532 | { |
535 | int num_bytes; | 533 | int num_bytes; |
536 | unsigned long flags; | 534 | unsigned long flags; |
537 | |||
538 | 535 | ||
539 | flags=claim_dma_lock(); | 536 | flags = claim_dma_lock(); |
540 | disable_dma(dma); | 537 | disable_dma(dma); |
541 | clear_dma_ff(dma); | 538 | clear_dma_ff(dma); |
542 | 539 | ||
@@ -547,27 +544,21 @@ static inline void transmit_chars_dma_done(struct esp_struct *info) | |||
547 | if (dma_bytes != num_bytes) { | 544 | if (dma_bytes != num_bytes) { |
548 | dma_bytes -= num_bytes; | 545 | dma_bytes -= num_bytes; |
549 | memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes); | 546 | memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes); |
550 | 547 | ||
551 | flags=claim_dma_lock(); | 548 | program_isa_dma(dma, DMA_MODE_WRITE, |
552 | disable_dma(dma); | 549 | isa_virt_to_bus(dma_buffer), dma_bytes); |
553 | clear_dma_ff(dma); | 550 | |
554 | set_dma_mode(dma, DMA_MODE_WRITE); | 551 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); |
555 | set_dma_addr(dma, isa_virt_to_bus(dma_buffer)); | ||
556 | set_dma_count(dma, dma_bytes); | ||
557 | enable_dma(dma); | ||
558 | release_dma_lock(flags); | ||
559 | |||
560 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); | ||
561 | } else { | 552 | } else { |
562 | dma_bytes = 0; | 553 | dma_bytes = 0; |
563 | info->stat_flags &= ~ESP_STAT_DMA_TX; | 554 | info->stat_flags &= ~ESP_STAT_DMA_TX; |
564 | } | 555 | } |
565 | } | 556 | } |
566 | 557 | ||
567 | static inline void check_modem_status(struct esp_struct *info) | 558 | static void check_modem_status(struct esp_struct *info) |
568 | { | 559 | { |
569 | int status; | 560 | int status; |
570 | 561 | ||
571 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | 562 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); |
572 | status = serial_in(info, UART_ESI_STAT2); | 563 | status = serial_in(info, UART_ESI_STAT2); |
573 | 564 | ||
@@ -588,7 +579,7 @@ static inline void check_modem_status(struct esp_struct *info) | |||
588 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) | 579 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) |
589 | printk("ttys%d CD now %s...", info->line, | 580 | printk("ttys%d CD now %s...", info->line, |
590 | (status & UART_MSR_DCD) ? "on" : "off"); | 581 | (status & UART_MSR_DCD) ? "on" : "off"); |
591 | #endif | 582 | #endif |
592 | if (status & UART_MSR_DCD) | 583 | if (status & UART_MSR_DCD) |
593 | wake_up_interruptible(&info->open_wait); | 584 | wake_up_interruptible(&info->open_wait); |
594 | else { | 585 | else { |
@@ -605,7 +596,7 @@ static inline void check_modem_status(struct esp_struct *info) | |||
605 | */ | 596 | */ |
606 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | 597 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) |
607 | { | 598 | { |
608 | struct esp_struct * info; | 599 | struct esp_struct *info; |
609 | unsigned err_status; | 600 | unsigned err_status; |
610 | unsigned int scratch; | 601 | unsigned int scratch; |
611 | 602 | ||
@@ -617,7 +608,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
617 | scratch = serial_in(info, UART_ESI_SID); | 608 | scratch = serial_in(info, UART_ESI_SID); |
618 | 609 | ||
619 | spin_lock(&info->lock); | 610 | spin_lock(&info->lock); |
620 | 611 | ||
621 | if (!info->tty) { | 612 | if (!info->tty) { |
622 | spin_unlock(&info->lock); | 613 | spin_unlock(&info->lock); |
623 | return IRQ_NONE; | 614 | return IRQ_NONE; |
@@ -637,7 +628,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
637 | if (err_status & 0x80) /* Start break */ | 628 | if (err_status & 0x80) /* Start break */ |
638 | wake_up_interruptible(&info->break_wait); | 629 | wake_up_interruptible(&info->break_wait); |
639 | } | 630 | } |
640 | 631 | ||
641 | if ((scratch & 0x88) || /* DMA completed or timed out */ | 632 | if ((scratch & 0x88) || /* DMA completed or timed out */ |
642 | (err_status & 0x1c) /* receive error */) { | 633 | (err_status & 0x1c) /* receive error */) { |
643 | if (info->stat_flags & ESP_STAT_DMA_RX) | 634 | if (info->stat_flags & ESP_STAT_DMA_RX) |
@@ -667,7 +658,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
667 | receive_chars_dma(info, num_bytes); | 658 | receive_chars_dma(info, num_bytes); |
668 | } | 659 | } |
669 | } | 660 | } |
670 | 661 | ||
671 | if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && | 662 | if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && |
672 | (scratch & 0x02) && (info->IER & UART_IER_THRI)) { | 663 | (scratch & 0x02) && (info->IER & UART_IER_THRI)) { |
673 | if ((info->xmit_cnt <= 0) || info->tty->stopped) { | 664 | if ((info->xmit_cnt <= 0) || info->tty->stopped) { |
@@ -722,11 +713,11 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
722 | * --------------------------------------------------------------- | 713 | * --------------------------------------------------------------- |
723 | */ | 714 | */ |
724 | 715 | ||
725 | static inline void esp_basic_init(struct esp_struct * info) | 716 | static void esp_basic_init(struct esp_struct *info) |
726 | { | 717 | { |
727 | /* put ESPC in enhanced mode */ | 718 | /* put ESPC in enhanced mode */ |
728 | serial_out(info, UART_ESI_CMD1, ESI_SET_MODE); | 719 | serial_out(info, UART_ESI_CMD1, ESI_SET_MODE); |
729 | 720 | ||
730 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | 721 | if (info->stat_flags & ESP_STAT_NEVER_DMA) |
731 | serial_out(info, UART_ESI_CMD2, 0x01); | 722 | serial_out(info, UART_ESI_CMD2, 0x01); |
732 | else | 723 | else |
@@ -783,13 +774,13 @@ static inline void esp_basic_init(struct esp_struct * info) | |||
783 | serial_out(info, UART_ESI_CMD2, 0xff); | 774 | serial_out(info, UART_ESI_CMD2, 0xff); |
784 | } | 775 | } |
785 | 776 | ||
786 | static int startup(struct esp_struct * info) | 777 | static int startup(struct esp_struct *info) |
787 | { | 778 | { |
788 | unsigned long flags; | 779 | unsigned long flags; |
789 | int retval=0; | 780 | int retval = 0; |
790 | unsigned int num_chars; | 781 | unsigned int num_chars; |
791 | 782 | ||
792 | spin_lock_irqsave(&info->lock, flags); | 783 | spin_lock_irqsave(&info->lock, flags); |
793 | 784 | ||
794 | if (info->flags & ASYNC_INITIALIZED) | 785 | if (info->flags & ASYNC_INITIALIZED) |
795 | goto out; | 786 | goto out; |
@@ -802,7 +793,8 @@ static int startup(struct esp_struct * info) | |||
802 | } | 793 | } |
803 | 794 | ||
804 | #ifdef SERIAL_DEBUG_OPEN | 795 | #ifdef SERIAL_DEBUG_OPEN |
805 | printk("starting up ttys%d (irq %d)...", info->line, info->irq); | 796 | printk(KERN_DEBUG "starting up ttys%d (irq %d)...", |
797 | info->line, info->irq); | ||
806 | #endif | 798 | #endif |
807 | 799 | ||
808 | /* Flush the RX buffer. Using the ESI flush command may cause */ | 800 | /* Flush the RX buffer. Using the ESI flush command may cause */ |
@@ -863,7 +855,7 @@ static int startup(struct esp_struct * info) | |||
863 | dma_buffer = NULL; | 855 | dma_buffer = NULL; |
864 | info->stat_flags |= ESP_STAT_USE_PIO; | 856 | info->stat_flags |= ESP_STAT_USE_PIO; |
865 | } | 857 | } |
866 | 858 | ||
867 | } | 859 | } |
868 | 860 | ||
869 | info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; | 861 | info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; |
@@ -872,7 +864,7 @@ static int startup(struct esp_struct * info) | |||
872 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | 864 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); |
873 | serial_out(info, UART_ESI_CMD2, UART_MCR); | 865 | serial_out(info, UART_ESI_CMD2, UART_MCR); |
874 | serial_out(info, UART_ESI_CMD2, info->MCR); | 866 | serial_out(info, UART_ESI_CMD2, info->MCR); |
875 | 867 | ||
876 | /* | 868 | /* |
877 | * Finally, enable interrupts | 869 | * Finally, enable interrupts |
878 | */ | 870 | */ |
@@ -881,7 +873,7 @@ static int startup(struct esp_struct * info) | |||
881 | UART_IER_DMA_TC; | 873 | UART_IER_DMA_TC; |
882 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | 874 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); |
883 | serial_out(info, UART_ESI_CMD2, info->IER); | 875 | serial_out(info, UART_ESI_CMD2, info->IER); |
884 | 876 | ||
885 | if (info->tty) | 877 | if (info->tty) |
886 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 878 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
887 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 879 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
@@ -900,7 +892,7 @@ static int startup(struct esp_struct * info) | |||
900 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 892 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
901 | info->tty->alt_speed = 460800; | 893 | info->tty->alt_speed = 460800; |
902 | } | 894 | } |
903 | 895 | ||
904 | /* | 896 | /* |
905 | * set the speed of the serial port | 897 | * set the speed of the serial port |
906 | */ | 898 | */ |
@@ -918,7 +910,7 @@ out_unlocked: | |||
918 | * This routine will shutdown a serial port; interrupts are disabled, and | 910 | * This routine will shutdown a serial port; interrupts are disabled, and |
919 | * DTR is dropped if the hangup on close termio flag is on. | 911 | * DTR is dropped if the hangup on close termio flag is on. |
920 | */ | 912 | */ |
921 | static void shutdown(struct esp_struct * info) | 913 | static void shutdown(struct esp_struct *info) |
922 | { | 914 | { |
923 | unsigned long flags, f; | 915 | unsigned long flags, f; |
924 | 916 | ||
@@ -929,7 +921,7 @@ static void shutdown(struct esp_struct * info) | |||
929 | printk("Shutting down serial port %d (irq %d)....", info->line, | 921 | printk("Shutting down serial port %d (irq %d)....", info->line, |
930 | info->irq); | 922 | info->irq); |
931 | #endif | 923 | #endif |
932 | 924 | ||
933 | spin_lock_irqsave(&info->lock, flags); | 925 | spin_lock_irqsave(&info->lock, flags); |
934 | /* | 926 | /* |
935 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq | 927 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq |
@@ -941,14 +933,14 @@ static void shutdown(struct esp_struct * info) | |||
941 | /* stop a DMA transfer on the port being closed */ | 933 | /* stop a DMA transfer on the port being closed */ |
942 | /* DMA lock is higher priority always */ | 934 | /* DMA lock is higher priority always */ |
943 | if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) { | 935 | if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) { |
944 | f=claim_dma_lock(); | 936 | f = claim_dma_lock(); |
945 | disable_dma(dma); | 937 | disable_dma(dma); |
946 | clear_dma_ff(dma); | 938 | clear_dma_ff(dma); |
947 | release_dma_lock(f); | 939 | release_dma_lock(f); |
948 | 940 | ||
949 | dma_bytes = 0; | 941 | dma_bytes = 0; |
950 | } | 942 | } |
951 | 943 | ||
952 | /* | 944 | /* |
953 | * Free the IRQ | 945 | * Free the IRQ |
954 | */ | 946 | */ |
@@ -970,7 +962,7 @@ static void shutdown(struct esp_struct * info) | |||
970 | free_pages((unsigned long)dma_buffer, | 962 | free_pages((unsigned long)dma_buffer, |
971 | get_order(DMA_BUFFER_SZ)); | 963 | get_order(DMA_BUFFER_SZ)); |
972 | dma_buffer = NULL; | 964 | dma_buffer = NULL; |
973 | } | 965 | } |
974 | } | 966 | } |
975 | 967 | ||
976 | if (info->xmit_buf) { | 968 | if (info->xmit_buf) { |
@@ -992,7 +984,7 @@ static void shutdown(struct esp_struct * info) | |||
992 | 984 | ||
993 | if (info->tty) | 985 | if (info->tty) |
994 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 986 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
995 | 987 | ||
996 | info->flags &= ~ASYNC_INITIALIZED; | 988 | info->flags &= ~ASYNC_INITIALIZED; |
997 | spin_unlock_irqrestore(&info->lock, flags); | 989 | spin_unlock_irqrestore(&info->lock, flags); |
998 | } | 990 | } |
@@ -1005,7 +997,7 @@ static void change_speed(struct esp_struct *info) | |||
1005 | { | 997 | { |
1006 | unsigned short port; | 998 | unsigned short port; |
1007 | int quot = 0; | 999 | int quot = 0; |
1008 | unsigned cflag,cval; | 1000 | unsigned cflag, cval; |
1009 | int baud, bits; | 1001 | int baud, bits; |
1010 | unsigned char flow1 = 0, flow2 = 0; | 1002 | unsigned char flow1 = 0, flow2 = 0; |
1011 | unsigned long flags; | 1003 | unsigned long flags; |
@@ -1014,14 +1006,14 @@ static void change_speed(struct esp_struct *info) | |||
1014 | return; | 1006 | return; |
1015 | cflag = info->tty->termios->c_cflag; | 1007 | cflag = info->tty->termios->c_cflag; |
1016 | port = info->port; | 1008 | port = info->port; |
1017 | 1009 | ||
1018 | /* byte size and parity */ | 1010 | /* byte size and parity */ |
1019 | switch (cflag & CSIZE) { | 1011 | switch (cflag & CSIZE) { |
1020 | case CS5: cval = 0x00; bits = 7; break; | 1012 | case CS5: cval = 0x00; bits = 7; break; |
1021 | case CS6: cval = 0x01; bits = 8; break; | 1013 | case CS6: cval = 0x01; bits = 8; break; |
1022 | case CS7: cval = 0x02; bits = 9; break; | 1014 | case CS7: cval = 0x02; bits = 9; break; |
1023 | case CS8: cval = 0x03; bits = 10; break; | 1015 | case CS8: cval = 0x03; bits = 10; break; |
1024 | default: cval = 0x00; bits = 7; break; | 1016 | default: cval = 0x00; bits = 7; break; |
1025 | } | 1017 | } |
1026 | if (cflag & CSTOPB) { | 1018 | if (cflag & CSTOPB) { |
1027 | cval |= 0x04; | 1019 | cval |= 0x04; |
@@ -1037,14 +1029,12 @@ static void change_speed(struct esp_struct *info) | |||
1037 | if (cflag & CMSPAR) | 1029 | if (cflag & CMSPAR) |
1038 | cval |= UART_LCR_SPAR; | 1030 | cval |= UART_LCR_SPAR; |
1039 | #endif | 1031 | #endif |
1040 | |||
1041 | baud = tty_get_baud_rate(info->tty); | 1032 | baud = tty_get_baud_rate(info->tty); |
1042 | if (baud == 38400 && | 1033 | if (baud == 38400 && |
1043 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) | 1034 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) |
1044 | quot = info->custom_divisor; | 1035 | quot = info->custom_divisor; |
1045 | else { | 1036 | else { |
1046 | if (baud == 134) | 1037 | if (baud == 134) /* Special case since 134 is really 134.5 */ |
1047 | /* Special case since 134 is really 134.5 */ | ||
1048 | quot = (2*BASE_BAUD / 269); | 1038 | quot = (2*BASE_BAUD / 269); |
1049 | else if (baud) | 1039 | else if (baud) |
1050 | quot = BASE_BAUD / baud; | 1040 | quot = BASE_BAUD / baud; |
@@ -1052,7 +1042,12 @@ static void change_speed(struct esp_struct *info) | |||
1052 | /* If the quotient is ever zero, default to 9600 bps */ | 1042 | /* If the quotient is ever zero, default to 9600 bps */ |
1053 | if (!quot) | 1043 | if (!quot) |
1054 | quot = BASE_BAUD / 9600; | 1044 | quot = BASE_BAUD / 9600; |
1055 | 1045 | ||
1046 | if (baud) { | ||
1047 | /* Actual rate */ | ||
1048 | baud = BASE_BAUD/quot; | ||
1049 | tty_encode_baud_rate(info->tty, baud, baud); | ||
1050 | } | ||
1056 | info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50); | 1051 | info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50); |
1057 | 1052 | ||
1058 | /* CTS flow control flag and modem status interrupts */ | 1053 | /* CTS flow control flag and modem status interrupts */ |
@@ -1066,10 +1061,8 @@ static void change_speed(struct esp_struct *info) | |||
1066 | info->flags &= ~ASYNC_CTS_FLOW; | 1061 | info->flags &= ~ASYNC_CTS_FLOW; |
1067 | if (cflag & CLOCAL) | 1062 | if (cflag & CLOCAL) |
1068 | info->flags &= ~ASYNC_CHECK_CD; | 1063 | info->flags &= ~ASYNC_CHECK_CD; |
1069 | else { | 1064 | else |
1070 | info->flags |= ASYNC_CHECK_CD; | 1065 | info->flags |= ASYNC_CHECK_CD; |
1071 | /* info->IER |= UART_IER_MSI; */ | ||
1072 | } | ||
1073 | 1066 | ||
1074 | /* | 1067 | /* |
1075 | * Set up parity check flag | 1068 | * Set up parity check flag |
@@ -1079,7 +1072,7 @@ static void change_speed(struct esp_struct *info) | |||
1079 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 1072 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
1080 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) | 1073 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) |
1081 | info->read_status_mask |= UART_LSR_BI; | 1074 | info->read_status_mask |= UART_LSR_BI; |
1082 | 1075 | ||
1083 | info->ignore_status_mask = 0; | 1076 | info->ignore_status_mask = 0; |
1084 | #if 0 | 1077 | #if 0 |
1085 | /* This should be safe, but for some broken bits of hardware... */ | 1078 | /* This should be safe, but for some broken bits of hardware... */ |
@@ -1092,7 +1085,7 @@ static void change_speed(struct esp_struct *info) | |||
1092 | info->ignore_status_mask |= UART_LSR_BI; | 1085 | info->ignore_status_mask |= UART_LSR_BI; |
1093 | info->read_status_mask |= UART_LSR_BI; | 1086 | info->read_status_mask |= UART_LSR_BI; |
1094 | /* | 1087 | /* |
1095 | * If we're ignore parity and break indicators, ignore | 1088 | * If we're ignore parity and break indicators, ignore |
1096 | * overruns too. (For real raw support). | 1089 | * overruns too. (For real raw support). |
1097 | */ | 1090 | */ |
1098 | if (I_IGNPAR(info->tty)) { | 1091 | if (I_IGNPAR(info->tty)) { |
@@ -1130,19 +1123,19 @@ static void change_speed(struct esp_struct *info) | |||
1130 | serial_out(info, UART_ESI_CMD2, 0x10); | 1123 | serial_out(info, UART_ESI_CMD2, 0x10); |
1131 | serial_out(info, UART_ESI_CMD2, 0x21); | 1124 | serial_out(info, UART_ESI_CMD2, 0x21); |
1132 | switch (cflag & CSIZE) { | 1125 | switch (cflag & CSIZE) { |
1133 | case CS5: | 1126 | case CS5: |
1134 | serial_out(info, UART_ESI_CMD2, 0x1f); | 1127 | serial_out(info, UART_ESI_CMD2, 0x1f); |
1135 | break; | 1128 | break; |
1136 | case CS6: | 1129 | case CS6: |
1137 | serial_out(info, UART_ESI_CMD2, 0x3f); | 1130 | serial_out(info, UART_ESI_CMD2, 0x3f); |
1138 | break; | 1131 | break; |
1139 | case CS7: | 1132 | case CS7: |
1140 | case CS8: | 1133 | case CS8: |
1141 | serial_out(info, UART_ESI_CMD2, 0x7f); | 1134 | serial_out(info, UART_ESI_CMD2, 0x7f); |
1142 | break; | 1135 | break; |
1143 | default: | 1136 | default: |
1144 | serial_out(info, UART_ESI_CMD2, 0xff); | 1137 | serial_out(info, UART_ESI_CMD2, 0xff); |
1145 | break; | 1138 | break; |
1146 | } | 1139 | } |
1147 | } | 1140 | } |
1148 | 1141 | ||
@@ -1156,31 +1149,34 @@ static void change_speed(struct esp_struct *info) | |||
1156 | spin_unlock_irqrestore(&info->lock, flags); | 1149 | spin_unlock_irqrestore(&info->lock, flags); |
1157 | } | 1150 | } |
1158 | 1151 | ||
1159 | static void rs_put_char(struct tty_struct *tty, unsigned char ch) | 1152 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) |
1160 | { | 1153 | { |
1161 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1154 | struct esp_struct *info = tty->driver_data; |
1162 | unsigned long flags; | 1155 | unsigned long flags; |
1156 | int ret = 0; | ||
1163 | 1157 | ||
1164 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | 1158 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
1165 | return; | 1159 | return 0; |
1166 | 1160 | ||
1167 | if (!info->xmit_buf) | 1161 | if (!info->xmit_buf) |
1168 | return; | 1162 | return 0; |
1169 | 1163 | ||
1170 | spin_lock_irqsave(&info->lock, flags); | 1164 | spin_lock_irqsave(&info->lock, flags); |
1171 | if (info->xmit_cnt < ESP_XMIT_SIZE - 1) { | 1165 | if (info->xmit_cnt < ESP_XMIT_SIZE - 1) { |
1172 | info->xmit_buf[info->xmit_head++] = ch; | 1166 | info->xmit_buf[info->xmit_head++] = ch; |
1173 | info->xmit_head &= ESP_XMIT_SIZE-1; | 1167 | info->xmit_head &= ESP_XMIT_SIZE-1; |
1174 | info->xmit_cnt++; | 1168 | info->xmit_cnt++; |
1169 | ret = 1; | ||
1175 | } | 1170 | } |
1176 | spin_unlock_irqrestore(&info->lock, flags); | 1171 | spin_unlock_irqrestore(&info->lock, flags); |
1172 | return ret; | ||
1177 | } | 1173 | } |
1178 | 1174 | ||
1179 | static void rs_flush_chars(struct tty_struct *tty) | 1175 | static void rs_flush_chars(struct tty_struct *tty) |
1180 | { | 1176 | { |
1181 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1177 | struct esp_struct *info = tty->driver_data; |
1182 | unsigned long flags; | 1178 | unsigned long flags; |
1183 | 1179 | ||
1184 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) | 1180 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) |
1185 | return; | 1181 | return; |
1186 | 1182 | ||
@@ -1198,11 +1194,11 @@ out: | |||
1198 | spin_unlock_irqrestore(&info->lock, flags); | 1194 | spin_unlock_irqrestore(&info->lock, flags); |
1199 | } | 1195 | } |
1200 | 1196 | ||
1201 | static int rs_write(struct tty_struct * tty, | 1197 | static int rs_write(struct tty_struct *tty, |
1202 | const unsigned char *buf, int count) | 1198 | const unsigned char *buf, int count) |
1203 | { | 1199 | { |
1204 | int c, t, ret = 0; | 1200 | int c, t, ret = 0; |
1205 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1201 | struct esp_struct *info = tty->driver_data; |
1206 | unsigned long flags; | 1202 | unsigned long flags; |
1207 | 1203 | ||
1208 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 1204 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
@@ -1210,19 +1206,19 @@ static int rs_write(struct tty_struct * tty, | |||
1210 | 1206 | ||
1211 | if (!info->xmit_buf) | 1207 | if (!info->xmit_buf) |
1212 | return 0; | 1208 | return 0; |
1213 | 1209 | ||
1214 | while (1) { | 1210 | while (1) { |
1215 | /* Thanks to R. Wolff for suggesting how to do this with */ | 1211 | /* Thanks to R. Wolff for suggesting how to do this with */ |
1216 | /* interrupts enabled */ | 1212 | /* interrupts enabled */ |
1217 | 1213 | ||
1218 | c = count; | 1214 | c = count; |
1219 | t = ESP_XMIT_SIZE - info->xmit_cnt - 1; | 1215 | t = ESP_XMIT_SIZE - info->xmit_cnt - 1; |
1220 | 1216 | ||
1221 | if (t < c) | 1217 | if (t < c) |
1222 | c = t; | 1218 | c = t; |
1223 | 1219 | ||
1224 | t = ESP_XMIT_SIZE - info->xmit_head; | 1220 | t = ESP_XMIT_SIZE - info->xmit_head; |
1225 | 1221 | ||
1226 | if (t < c) | 1222 | if (t < c) |
1227 | c = t; | 1223 | c = t; |
1228 | 1224 | ||
@@ -1252,10 +1248,10 @@ static int rs_write(struct tty_struct * tty, | |||
1252 | 1248 | ||
1253 | static int rs_write_room(struct tty_struct *tty) | 1249 | static int rs_write_room(struct tty_struct *tty) |
1254 | { | 1250 | { |
1255 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1251 | struct esp_struct *info = tty->driver_data; |
1256 | int ret; | 1252 | int ret; |
1257 | unsigned long flags; | 1253 | unsigned long flags; |
1258 | 1254 | ||
1259 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) | 1255 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) |
1260 | return 0; | 1256 | return 0; |
1261 | 1257 | ||
@@ -1270,8 +1266,8 @@ static int rs_write_room(struct tty_struct *tty) | |||
1270 | 1266 | ||
1271 | static int rs_chars_in_buffer(struct tty_struct *tty) | 1267 | static int rs_chars_in_buffer(struct tty_struct *tty) |
1272 | { | 1268 | { |
1273 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1269 | struct esp_struct *info = tty->driver_data; |
1274 | 1270 | ||
1275 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) | 1271 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) |
1276 | return 0; | 1272 | return 0; |
1277 | return info->xmit_cnt; | 1273 | return info->xmit_cnt; |
@@ -1279,9 +1275,9 @@ static int rs_chars_in_buffer(struct tty_struct *tty) | |||
1279 | 1275 | ||
1280 | static void rs_flush_buffer(struct tty_struct *tty) | 1276 | static void rs_flush_buffer(struct tty_struct *tty) |
1281 | { | 1277 | { |
1282 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1278 | struct esp_struct *info = tty->driver_data; |
1283 | unsigned long flags; | 1279 | unsigned long flags; |
1284 | 1280 | ||
1285 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | 1281 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) |
1286 | return; | 1282 | return; |
1287 | spin_lock_irqsave(&info->lock, flags); | 1283 | spin_lock_irqsave(&info->lock, flags); |
@@ -1293,20 +1289,20 @@ static void rs_flush_buffer(struct tty_struct *tty) | |||
1293 | /* | 1289 | /* |
1294 | * ------------------------------------------------------------ | 1290 | * ------------------------------------------------------------ |
1295 | * rs_throttle() | 1291 | * rs_throttle() |
1296 | * | 1292 | * |
1297 | * This routine is called by the upper-layer tty layer to signal that | 1293 | * This routine is called by the upper-layer tty layer to signal that |
1298 | * incoming characters should be throttled. | 1294 | * incoming characters should be throttled. |
1299 | * ------------------------------------------------------------ | 1295 | * ------------------------------------------------------------ |
1300 | */ | 1296 | */ |
1301 | static void rs_throttle(struct tty_struct * tty) | 1297 | static void rs_throttle(struct tty_struct *tty) |
1302 | { | 1298 | { |
1303 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1299 | struct esp_struct *info = tty->driver_data; |
1304 | unsigned long flags; | 1300 | unsigned long flags; |
1305 | #ifdef SERIAL_DEBUG_THROTTLE | 1301 | #ifdef SERIAL_DEBUG_THROTTLE |
1306 | char buf[64]; | 1302 | char buf[64]; |
1307 | 1303 | ||
1308 | printk("throttle %s: %d....\n", tty_name(tty, buf), | 1304 | printk("throttle %s: %d....\n", tty_name(tty, buf), |
1309 | tty->ldisc.chars_in_buffer(tty)); | 1305 | tty_chars_in_buffer(tty)); |
1310 | #endif | 1306 | #endif |
1311 | 1307 | ||
1312 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) | 1308 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) |
@@ -1321,20 +1317,20 @@ static void rs_throttle(struct tty_struct * tty) | |||
1321 | spin_unlock_irqrestore(&info->lock, flags); | 1317 | spin_unlock_irqrestore(&info->lock, flags); |
1322 | } | 1318 | } |
1323 | 1319 | ||
1324 | static void rs_unthrottle(struct tty_struct * tty) | 1320 | static void rs_unthrottle(struct tty_struct *tty) |
1325 | { | 1321 | { |
1326 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1322 | struct esp_struct *info = tty->driver_data; |
1327 | unsigned long flags; | 1323 | unsigned long flags; |
1328 | #ifdef SERIAL_DEBUG_THROTTLE | 1324 | #ifdef SERIAL_DEBUG_THROTTLE |
1329 | char buf[64]; | 1325 | char buf[64]; |
1330 | 1326 | ||
1331 | printk("unthrottle %s: %d....\n", tty_name(tty, buf), | 1327 | printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf), |
1332 | tty->ldisc.chars_in_buffer(tty)); | 1328 | tty_chars_in_buffer(tty)); |
1333 | #endif | 1329 | #endif |
1334 | 1330 | ||
1335 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) | 1331 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) |
1336 | return; | 1332 | return; |
1337 | 1333 | ||
1338 | spin_lock_irqsave(&info->lock, flags); | 1334 | spin_lock_irqsave(&info->lock, flags); |
1339 | info->IER |= UART_IER_RDI; | 1335 | info->IER |= UART_IER_RDI; |
1340 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | 1336 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); |
@@ -1350,11 +1346,12 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
1350 | * ------------------------------------------------------------ | 1346 | * ------------------------------------------------------------ |
1351 | */ | 1347 | */ |
1352 | 1348 | ||
1353 | static int get_serial_info(struct esp_struct * info, | 1349 | static int get_serial_info(struct esp_struct *info, |
1354 | struct serial_struct __user *retinfo) | 1350 | struct serial_struct __user *retinfo) |
1355 | { | 1351 | { |
1356 | struct serial_struct tmp; | 1352 | struct serial_struct tmp; |
1357 | 1353 | ||
1354 | lock_kernel(); | ||
1358 | memset(&tmp, 0, sizeof(tmp)); | 1355 | memset(&tmp, 0, sizeof(tmp)); |
1359 | tmp.type = PORT_16550A; | 1356 | tmp.type = PORT_16550A; |
1360 | tmp.line = info->line; | 1357 | tmp.line = info->line; |
@@ -1367,20 +1364,22 @@ static int get_serial_info(struct esp_struct * info, | |||
1367 | tmp.closing_wait = info->closing_wait; | 1364 | tmp.closing_wait = info->closing_wait; |
1368 | tmp.custom_divisor = info->custom_divisor; | 1365 | tmp.custom_divisor = info->custom_divisor; |
1369 | tmp.hub6 = 0; | 1366 | tmp.hub6 = 0; |
1370 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1367 | unlock_kernel(); |
1368 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
1371 | return -EFAULT; | 1369 | return -EFAULT; |
1372 | return 0; | 1370 | return 0; |
1373 | } | 1371 | } |
1374 | 1372 | ||
1375 | static int get_esp_config(struct esp_struct * info, | 1373 | static int get_esp_config(struct esp_struct *info, |
1376 | struct hayes_esp_config __user *retinfo) | 1374 | struct hayes_esp_config __user *retinfo) |
1377 | { | 1375 | { |
1378 | struct hayes_esp_config tmp; | 1376 | struct hayes_esp_config tmp; |
1379 | 1377 | ||
1380 | if (!retinfo) | 1378 | if (!retinfo) |
1381 | return -EFAULT; | 1379 | return -EFAULT; |
1382 | 1380 | ||
1383 | memset(&tmp, 0, sizeof(tmp)); | 1381 | memset(&tmp, 0, sizeof(tmp)); |
1382 | lock_kernel(); | ||
1384 | tmp.rx_timeout = info->config.rx_timeout; | 1383 | tmp.rx_timeout = info->config.rx_timeout; |
1385 | tmp.rx_trigger = info->config.rx_trigger; | 1384 | tmp.rx_trigger = info->config.rx_trigger; |
1386 | tmp.tx_trigger = info->config.tx_trigger; | 1385 | tmp.tx_trigger = info->config.tx_trigger; |
@@ -1388,11 +1387,12 @@ static int get_esp_config(struct esp_struct * info, | |||
1388 | tmp.flow_on = info->config.flow_on; | 1387 | tmp.flow_on = info->config.flow_on; |
1389 | tmp.pio_threshold = info->config.pio_threshold; | 1388 | tmp.pio_threshold = info->config.pio_threshold; |
1390 | tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma); | 1389 | tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma); |
1390 | unlock_kernel(); | ||
1391 | 1391 | ||
1392 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; | 1392 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; |
1393 | } | 1393 | } |
1394 | 1394 | ||
1395 | static int set_serial_info(struct esp_struct * info, | 1395 | static int set_serial_info(struct esp_struct *info, |
1396 | struct serial_struct __user *new_info) | 1396 | struct serial_struct __user *new_info) |
1397 | { | 1397 | { |
1398 | struct serial_struct new_serial; | 1398 | struct serial_struct new_serial; |
@@ -1401,7 +1401,7 @@ static int set_serial_info(struct esp_struct * info, | |||
1401 | int retval = 0; | 1401 | int retval = 0; |
1402 | struct esp_struct *current_async; | 1402 | struct esp_struct *current_async; |
1403 | 1403 | ||
1404 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1404 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
1405 | return -EFAULT; | 1405 | return -EFAULT; |
1406 | old_info = *info; | 1406 | old_info = *info; |
1407 | 1407 | ||
@@ -1422,7 +1422,7 @@ static int set_serial_info(struct esp_struct * info, | |||
1422 | return -EINVAL; | 1422 | return -EINVAL; |
1423 | 1423 | ||
1424 | if (!capable(CAP_SYS_ADMIN)) { | 1424 | if (!capable(CAP_SYS_ADMIN)) { |
1425 | if (change_irq || | 1425 | if (change_irq || |
1426 | (new_serial.close_delay != info->close_delay) || | 1426 | (new_serial.close_delay != info->close_delay) || |
1427 | ((new_serial.flags & ~ASYNC_USR_MASK) != | 1427 | ((new_serial.flags & ~ASYNC_USR_MASK) != |
1428 | (info->flags & ~ASYNC_USR_MASK))) | 1428 | (info->flags & ~ASYNC_USR_MASK))) |
@@ -1507,8 +1507,8 @@ static int set_serial_info(struct esp_struct * info, | |||
1507 | return retval; | 1507 | return retval; |
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | static int set_esp_config(struct esp_struct * info, | 1510 | static int set_esp_config(struct esp_struct *info, |
1511 | struct hayes_esp_config __user * new_info) | 1511 | struct hayes_esp_config __user *new_info) |
1512 | { | 1512 | { |
1513 | struct hayes_esp_config new_config; | 1513 | struct hayes_esp_config new_config; |
1514 | unsigned int change_dma; | 1514 | unsigned int change_dma; |
@@ -1550,7 +1550,6 @@ static int set_esp_config(struct esp_struct * info, | |||
1550 | if (new_config.dma_channel) { | 1550 | if (new_config.dma_channel) { |
1551 | /* PIO mode to DMA mode transition OR */ | 1551 | /* PIO mode to DMA mode transition OR */ |
1552 | /* change current DMA channel */ | 1552 | /* change current DMA channel */ |
1553 | |||
1554 | current_async = ports; | 1553 | current_async = ports; |
1555 | 1554 | ||
1556 | while (current_async) { | 1555 | while (current_async) { |
@@ -1559,16 +1558,15 @@ static int set_esp_config(struct esp_struct * info, | |||
1559 | return -EBUSY; | 1558 | return -EBUSY; |
1560 | } else if (current_async->count) | 1559 | } else if (current_async->count) |
1561 | return -EBUSY; | 1560 | return -EBUSY; |
1562 | 1561 | ||
1563 | current_async = | 1562 | current_async = current_async->next_port; |
1564 | current_async->next_port; | ||
1565 | } | 1563 | } |
1566 | 1564 | ||
1567 | shutdown(info); | 1565 | shutdown(info); |
1568 | dma = new_config.dma_channel; | 1566 | dma = new_config.dma_channel; |
1569 | info->stat_flags &= ~ESP_STAT_NEVER_DMA; | 1567 | info->stat_flags &= ~ESP_STAT_NEVER_DMA; |
1570 | 1568 | ||
1571 | /* all ports must use the same DMA channel */ | 1569 | /* all ports must use the same DMA channel */ |
1572 | 1570 | ||
1573 | spin_lock_irqsave(&info->lock, flags); | 1571 | spin_lock_irqsave(&info->lock, flags); |
1574 | current_async = ports; | 1572 | current_async = ports; |
@@ -1580,7 +1578,6 @@ static int set_esp_config(struct esp_struct * info, | |||
1580 | spin_unlock_irqrestore(&info->lock, flags); | 1578 | spin_unlock_irqrestore(&info->lock, flags); |
1581 | } else { | 1579 | } else { |
1582 | /* DMA mode to PIO mode only */ | 1580 | /* DMA mode to PIO mode only */ |
1583 | |||
1584 | if (info->count > 1) | 1581 | if (info->count > 1) |
1585 | return -EBUSY; | 1582 | return -EBUSY; |
1586 | 1583 | ||
@@ -1596,8 +1593,6 @@ static int set_esp_config(struct esp_struct * info, | |||
1596 | 1593 | ||
1597 | if ((new_config.flow_off != info->config.flow_off) || | 1594 | if ((new_config.flow_off != info->config.flow_off) || |
1598 | (new_config.flow_on != info->config.flow_on)) { | 1595 | (new_config.flow_on != info->config.flow_on)) { |
1599 | unsigned long flags; | ||
1600 | |||
1601 | info->config.flow_off = new_config.flow_off; | 1596 | info->config.flow_off = new_config.flow_off; |
1602 | info->config.flow_on = new_config.flow_on; | 1597 | info->config.flow_on = new_config.flow_on; |
1603 | 1598 | ||
@@ -1612,8 +1607,6 @@ static int set_esp_config(struct esp_struct * info, | |||
1612 | 1607 | ||
1613 | if ((new_config.rx_trigger != info->config.rx_trigger) || | 1608 | if ((new_config.rx_trigger != info->config.rx_trigger) || |
1614 | (new_config.tx_trigger != info->config.tx_trigger)) { | 1609 | (new_config.tx_trigger != info->config.tx_trigger)) { |
1615 | unsigned long flags; | ||
1616 | |||
1617 | info->config.rx_trigger = new_config.rx_trigger; | 1610 | info->config.rx_trigger = new_config.rx_trigger; |
1618 | info->config.tx_trigger = new_config.tx_trigger; | 1611 | info->config.tx_trigger = new_config.tx_trigger; |
1619 | spin_lock_irqsave(&info->lock, flags); | 1612 | spin_lock_irqsave(&info->lock, flags); |
@@ -1628,8 +1621,6 @@ static int set_esp_config(struct esp_struct * info, | |||
1628 | } | 1621 | } |
1629 | 1622 | ||
1630 | if (new_config.rx_timeout != info->config.rx_timeout) { | 1623 | if (new_config.rx_timeout != info->config.rx_timeout) { |
1631 | unsigned long flags; | ||
1632 | |||
1633 | info->config.rx_timeout = new_config.rx_timeout; | 1624 | info->config.rx_timeout = new_config.rx_timeout; |
1634 | spin_lock_irqsave(&info->lock, flags); | 1625 | spin_lock_irqsave(&info->lock, flags); |
1635 | 1626 | ||
@@ -1657,9 +1648,9 @@ static int set_esp_config(struct esp_struct * info, | |||
1657 | * release the bus after transmitting. This must be done when | 1648 | * release the bus after transmitting. This must be done when |
1658 | * the transmit shift register is empty, not be done when the | 1649 | * the transmit shift register is empty, not be done when the |
1659 | * transmit holding register is empty. This functionality | 1650 | * transmit holding register is empty. This functionality |
1660 | * allows an RS485 driver to be written in user space. | 1651 | * allows an RS485 driver to be written in user space. |
1661 | */ | 1652 | */ |
1662 | static int get_lsr_info(struct esp_struct * info, unsigned int __user *value) | 1653 | static int get_lsr_info(struct esp_struct *info, unsigned int __user *value) |
1663 | { | 1654 | { |
1664 | unsigned char status; | 1655 | unsigned char status; |
1665 | unsigned int result; | 1656 | unsigned int result; |
@@ -1670,17 +1661,17 @@ static int get_lsr_info(struct esp_struct * info, unsigned int __user *value) | |||
1670 | status = serial_in(info, UART_ESI_STAT1); | 1661 | status = serial_in(info, UART_ESI_STAT1); |
1671 | spin_unlock_irqrestore(&info->lock, flags); | 1662 | spin_unlock_irqrestore(&info->lock, flags); |
1672 | result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); | 1663 | result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); |
1673 | return put_user(result,value); | 1664 | return put_user(result, value); |
1674 | } | 1665 | } |
1675 | 1666 | ||
1676 | 1667 | ||
1677 | static int esp_tiocmget(struct tty_struct *tty, struct file *file) | 1668 | static int esp_tiocmget(struct tty_struct *tty, struct file *file) |
1678 | { | 1669 | { |
1679 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 1670 | struct esp_struct *info = tty->driver_data; |
1680 | unsigned char control, status; | 1671 | unsigned char control, status; |
1681 | unsigned long flags; | 1672 | unsigned long flags; |
1682 | 1673 | ||
1683 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 1674 | if (serial_paranoia_check(info, tty->name, __func__)) |
1684 | return -ENODEV; | 1675 | return -ENODEV; |
1685 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1676 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1686 | return -EIO; | 1677 | return -EIO; |
@@ -1703,10 +1694,10 @@ static int esp_tiocmget(struct tty_struct *tty, struct file *file) | |||
1703 | static int esp_tiocmset(struct tty_struct *tty, struct file *file, | 1694 | static int esp_tiocmset(struct tty_struct *tty, struct file *file, |
1704 | unsigned int set, unsigned int clear) | 1695 | unsigned int set, unsigned int clear) |
1705 | { | 1696 | { |
1706 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 1697 | struct esp_struct *info = tty->driver_data; |
1707 | unsigned long flags; | 1698 | unsigned long flags; |
1708 | 1699 | ||
1709 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 1700 | if (serial_paranoia_check(info, tty->name, __func__)) |
1710 | return -ENODEV; | 1701 | return -ENODEV; |
1711 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1702 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1712 | return -EIO; | 1703 | return -EIO; |
@@ -1736,9 +1727,9 @@ static int esp_tiocmset(struct tty_struct *tty, struct file *file, | |||
1736 | */ | 1727 | */ |
1737 | static void esp_break(struct tty_struct *tty, int break_state) | 1728 | static void esp_break(struct tty_struct *tty, int break_state) |
1738 | { | 1729 | { |
1739 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 1730 | struct esp_struct *info = tty->driver_data; |
1740 | unsigned long flags; | 1731 | unsigned long flags; |
1741 | 1732 | ||
1742 | if (serial_paranoia_check(info, tty->name, "esp_break")) | 1733 | if (serial_paranoia_check(info, tty->name, "esp_break")) |
1743 | return; | 1734 | return; |
1744 | 1735 | ||
@@ -1758,14 +1749,15 @@ static void esp_break(struct tty_struct *tty, int break_state) | |||
1758 | } | 1749 | } |
1759 | } | 1750 | } |
1760 | 1751 | ||
1761 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 1752 | static int rs_ioctl(struct tty_struct *tty, struct file *file, |
1762 | unsigned int cmd, unsigned long arg) | 1753 | unsigned int cmd, unsigned long arg) |
1763 | { | 1754 | { |
1764 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 1755 | struct esp_struct *info = tty->driver_data; |
1765 | struct async_icount cprev, cnow; /* kernel counter temps */ | 1756 | struct async_icount cprev, cnow; /* kernel counter temps */ |
1766 | struct serial_icounter_struct __user *p_cuser; /* user space */ | 1757 | struct serial_icounter_struct __user *p_cuser; /* user space */ |
1767 | void __user *argp = (void __user *)arg; | 1758 | void __user *argp = (void __user *)arg; |
1768 | unsigned long flags; | 1759 | unsigned long flags; |
1760 | int ret; | ||
1769 | 1761 | ||
1770 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1762 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
1771 | return -ENODEV; | 1763 | return -ENODEV; |
@@ -1778,97 +1770,93 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1778 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1770 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1779 | return -EIO; | 1771 | return -EIO; |
1780 | } | 1772 | } |
1781 | |||
1782 | switch (cmd) { | ||
1783 | case TIOCGSERIAL: | ||
1784 | return get_serial_info(info, argp); | ||
1785 | case TIOCSSERIAL: | ||
1786 | return set_serial_info(info, argp); | ||
1787 | case TIOCSERCONFIG: | ||
1788 | /* do not reconfigure after initial configuration */ | ||
1789 | return 0; | ||
1790 | |||
1791 | case TIOCSERGWILD: | ||
1792 | return put_user(0L, (unsigned long __user *)argp); | ||
1793 | 1773 | ||
1794 | case TIOCSERGETLSR: /* Get line status register */ | 1774 | switch (cmd) { |
1795 | return get_lsr_info(info, argp); | 1775 | case TIOCGSERIAL: |
1796 | 1776 | return get_serial_info(info, argp); | |
1797 | case TIOCSERSWILD: | 1777 | case TIOCSSERIAL: |
1798 | if (!capable(CAP_SYS_ADMIN)) | 1778 | lock_kernel(); |
1799 | return -EPERM; | 1779 | ret = set_serial_info(info, argp); |
1800 | return 0; | 1780 | unlock_kernel(); |
1801 | 1781 | return ret; | |
1802 | /* | 1782 | case TIOCSERGWILD: |
1803 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | 1783 | return put_user(0L, (unsigned long __user *)argp); |
1804 | * - mask passed in arg for lines of interest | 1784 | case TIOCSERGETLSR: /* Get line status register */ |
1805 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | 1785 | return get_lsr_info(info, argp); |
1806 | * Caller should use TIOCGICOUNT to see which one it was | 1786 | case TIOCSERSWILD: |
1807 | */ | 1787 | if (!capable(CAP_SYS_ADMIN)) |
1808 | case TIOCMIWAIT: | 1788 | return -EPERM; |
1789 | return 0; | ||
1790 | /* | ||
1791 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | ||
1792 | * - mask passed in arg for lines of interest | ||
1793 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | ||
1794 | * Caller should use TIOCGICOUNT to see which one it was | ||
1795 | */ | ||
1796 | case TIOCMIWAIT: | ||
1797 | spin_lock_irqsave(&info->lock, flags); | ||
1798 | cprev = info->icount; /* note the counters on entry */ | ||
1799 | spin_unlock_irqrestore(&info->lock, flags); | ||
1800 | while (1) { | ||
1801 | /* FIXME: convert to new style wakeup */ | ||
1802 | interruptible_sleep_on(&info->delta_msr_wait); | ||
1803 | /* see if a signal did it */ | ||
1804 | if (signal_pending(current)) | ||
1805 | return -ERESTARTSYS; | ||
1809 | spin_lock_irqsave(&info->lock, flags); | 1806 | spin_lock_irqsave(&info->lock, flags); |
1810 | cprev = info->icount; /* note the counters on entry */ | 1807 | cnow = info->icount; /* atomic copy */ |
1811 | spin_unlock_irqrestore(&info->lock, flags); | 1808 | spin_unlock_irqrestore(&info->lock, flags); |
1812 | while (1) { | 1809 | if (cnow.rng == cprev.rng && |
1813 | /* FIXME: convert to new style wakeup */ | 1810 | cnow.dsr == cprev.dsr && |
1814 | interruptible_sleep_on(&info->delta_msr_wait); | 1811 | cnow.dcd == cprev.dcd && |
1815 | /* see if a signal did it */ | 1812 | cnow.cts == cprev.cts) |
1816 | if (signal_pending(current)) | 1813 | return -EIO; /* no change => error */ |
1817 | return -ERESTARTSYS; | 1814 | if (((arg & TIOCM_RNG) && |
1818 | spin_lock_irqsave(&info->lock, flags); | 1815 | (cnow.rng != cprev.rng)) || |
1819 | cnow = info->icount; /* atomic copy */ | 1816 | ((arg & TIOCM_DSR) && |
1820 | spin_unlock_irqrestore(&info->lock, flags); | 1817 | (cnow.dsr != cprev.dsr)) || |
1821 | if (cnow.rng == cprev.rng && | 1818 | ((arg & TIOCM_CD) && |
1822 | cnow.dsr == cprev.dsr && | 1819 | (cnow.dcd != cprev.dcd)) || |
1823 | cnow.dcd == cprev.dcd && | 1820 | ((arg & TIOCM_CTS) && |
1824 | cnow.cts == cprev.cts) | 1821 | (cnow.cts != cprev.cts))) { |
1825 | return -EIO; /* no change => error */ | 1822 | return 0; |
1826 | if (((arg & TIOCM_RNG) && | ||
1827 | (cnow.rng != cprev.rng)) || | ||
1828 | ((arg & TIOCM_DSR) && | ||
1829 | (cnow.dsr != cprev.dsr)) || | ||
1830 | ((arg & TIOCM_CD) && | ||
1831 | (cnow.dcd != cprev.dcd)) || | ||
1832 | ((arg & TIOCM_CTS) && | ||
1833 | (cnow.cts != cprev.cts)) ) { | ||
1834 | return 0; | ||
1835 | } | ||
1836 | cprev = cnow; | ||
1837 | } | 1823 | } |
1838 | /* NOTREACHED */ | 1824 | cprev = cnow; |
1839 | 1825 | } | |
1840 | /* | 1826 | /* NOTREACHED */ |
1841 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | 1827 | /* |
1842 | * Return: write counters to the user passed counter struct | 1828 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) |
1843 | * NB: both 1->0 and 0->1 transitions are counted except for | 1829 | * Return: write counters to the user passed counter struct |
1844 | * RI where only 0->1 is counted. | 1830 | * NB: both 1->0 and 0->1 transitions are counted except for |
1845 | */ | 1831 | * RI where only 0->1 is counted. |
1846 | case TIOCGICOUNT: | 1832 | */ |
1847 | spin_lock_irqsave(&info->lock, flags); | 1833 | case TIOCGICOUNT: |
1848 | cnow = info->icount; | 1834 | spin_lock_irqsave(&info->lock, flags); |
1849 | spin_unlock_irqrestore(&info->lock, flags); | 1835 | cnow = info->icount; |
1850 | p_cuser = argp; | 1836 | spin_unlock_irqrestore(&info->lock, flags); |
1851 | if (put_user(cnow.cts, &p_cuser->cts) || | 1837 | p_cuser = argp; |
1852 | put_user(cnow.dsr, &p_cuser->dsr) || | 1838 | if (put_user(cnow.cts, &p_cuser->cts) || |
1853 | put_user(cnow.rng, &p_cuser->rng) || | 1839 | put_user(cnow.dsr, &p_cuser->dsr) || |
1854 | put_user(cnow.dcd, &p_cuser->dcd)) | 1840 | put_user(cnow.rng, &p_cuser->rng) || |
1855 | return -EFAULT; | 1841 | put_user(cnow.dcd, &p_cuser->dcd)) |
1856 | 1842 | return -EFAULT; | |
1857 | return 0; | 1843 | return 0; |
1858 | case TIOCGHAYESESP: | 1844 | case TIOCGHAYESESP: |
1859 | return get_esp_config(info, argp); | 1845 | return get_esp_config(info, argp); |
1860 | case TIOCSHAYESESP: | 1846 | case TIOCSHAYESESP: |
1861 | return set_esp_config(info, argp); | 1847 | lock_kernel(); |
1862 | 1848 | ret = set_esp_config(info, argp); | |
1863 | default: | 1849 | unlock_kernel(); |
1864 | return -ENOIOCTLCMD; | 1850 | return ret; |
1865 | } | 1851 | default: |
1852 | return -ENOIOCTLCMD; | ||
1853 | } | ||
1866 | return 0; | 1854 | return 0; |
1867 | } | 1855 | } |
1868 | 1856 | ||
1869 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 1857 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
1870 | { | 1858 | { |
1871 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1859 | struct esp_struct *info = tty->driver_data; |
1872 | unsigned long flags; | 1860 | unsigned long flags; |
1873 | 1861 | ||
1874 | change_speed(info); | 1862 | change_speed(info); |
@@ -1905,32 +1893,33 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1905 | /* | 1893 | /* |
1906 | * ------------------------------------------------------------ | 1894 | * ------------------------------------------------------------ |
1907 | * rs_close() | 1895 | * rs_close() |
1908 | * | 1896 | * |
1909 | * This routine is called when the serial port gets closed. First, we | 1897 | * This routine is called when the serial port gets closed. First, we |
1910 | * wait for the last remaining data to be sent. Then, we unlink its | 1898 | * wait for the last remaining data to be sent. Then, we unlink its |
1911 | * async structure from the interrupt chain if necessary, and we free | 1899 | * async structure from the interrupt chain if necessary, and we free |
1912 | * that IRQ if nothing is left in the chain. | 1900 | * that IRQ if nothing is left in the chain. |
1913 | * ------------------------------------------------------------ | 1901 | * ------------------------------------------------------------ |
1914 | */ | 1902 | */ |
1915 | static void rs_close(struct tty_struct *tty, struct file * filp) | 1903 | static void rs_close(struct tty_struct *tty, struct file *filp) |
1916 | { | 1904 | { |
1917 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 1905 | struct esp_struct *info = tty->driver_data; |
1918 | unsigned long flags; | 1906 | unsigned long flags; |
1919 | 1907 | ||
1920 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1908 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) |
1921 | return; | 1909 | return; |
1922 | 1910 | ||
1923 | spin_lock_irqsave(&info->lock, flags); | 1911 | spin_lock_irqsave(&info->lock, flags); |
1924 | 1912 | ||
1925 | if (tty_hung_up_p(filp)) { | 1913 | if (tty_hung_up_p(filp)) { |
1926 | DBG_CNT("before DEC-hung"); | 1914 | DBG_CNT("before DEC-hung"); |
1927 | goto out; | 1915 | goto out; |
1928 | } | 1916 | } |
1929 | 1917 | ||
1930 | #ifdef SERIAL_DEBUG_OPEN | 1918 | #ifdef SERIAL_DEBUG_OPEN |
1931 | printk("rs_close ttys%d, count = %d\n", info->line, info->count); | 1919 | printk(KERN_DEBUG "rs_close ttys%d, count = %d\n", |
1920 | info->line, info->count); | ||
1932 | #endif | 1921 | #endif |
1933 | if ((tty->count == 1) && (info->count != 1)) { | 1922 | if (tty->count == 1 && info->count != 1) { |
1934 | /* | 1923 | /* |
1935 | * Uh, oh. tty->count is 1, which means that the tty | 1924 | * Uh, oh. tty->count is 1, which means that the tty |
1936 | * structure will be freed. Info->count should always | 1925 | * structure will be freed. Info->count should always |
@@ -1938,12 +1927,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1938 | * one, we've got real problems, since it means the | 1927 | * one, we've got real problems, since it means the |
1939 | * serial port won't be shutdown. | 1928 | * serial port won't be shutdown. |
1940 | */ | 1929 | */ |
1941 | printk("rs_close: bad serial port count; tty->count is 1, " | 1930 | printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->count is %d\n", info->count); |
1942 | "info->count is %d\n", info->count); | ||
1943 | info->count = 1; | 1931 | info->count = 1; |
1944 | } | 1932 | } |
1945 | if (--info->count < 0) { | 1933 | if (--info->count < 0) { |
1946 | printk("rs_close: bad serial port count for ttys%d: %d\n", | 1934 | printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", |
1947 | info->line, info->count); | 1935 | info->line, info->count); |
1948 | info->count = 0; | 1936 | info->count = 0; |
1949 | } | 1937 | } |
@@ -1955,7 +1943,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1955 | 1943 | ||
1956 | spin_unlock_irqrestore(&info->lock, flags); | 1944 | spin_unlock_irqrestore(&info->lock, flags); |
1957 | /* | 1945 | /* |
1958 | * Now we wait for the transmit buffer to clear; and we notify | 1946 | * Now we wait for the transmit buffer to clear; and we notify |
1959 | * the line discipline to only process XON/XOFF characters. | 1947 | * the line discipline to only process XON/XOFF characters. |
1960 | */ | 1948 | */ |
1961 | tty->closing = 1; | 1949 | tty->closing = 1; |
@@ -1990,16 +1978,14 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1990 | rs_wait_until_sent(tty, info->timeout); | 1978 | rs_wait_until_sent(tty, info->timeout); |
1991 | } | 1979 | } |
1992 | shutdown(info); | 1980 | shutdown(info); |
1993 | if (tty->driver->flush_buffer) | 1981 | rs_flush_buffer(tty); |
1994 | tty->driver->flush_buffer(tty); | ||
1995 | tty_ldisc_flush(tty); | 1982 | tty_ldisc_flush(tty); |
1996 | tty->closing = 0; | 1983 | tty->closing = 0; |
1997 | info->tty = NULL; | 1984 | info->tty = NULL; |
1998 | 1985 | ||
1999 | if (info->blocked_open) { | 1986 | if (info->blocked_open) { |
2000 | if (info->close_delay) { | 1987 | if (info->close_delay) |
2001 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | 1988 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); |
2002 | } | ||
2003 | wake_up_interruptible(&info->open_wait); | 1989 | wake_up_interruptible(&info->open_wait); |
2004 | } | 1990 | } |
2005 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1991 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
@@ -2012,7 +1998,7 @@ out: | |||
2012 | 1998 | ||
2013 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | 1999 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) |
2014 | { | 2000 | { |
2015 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 2001 | struct esp_struct *info = tty->driver_data; |
2016 | unsigned long orig_jiffies, char_time; | 2002 | unsigned long orig_jiffies, char_time; |
2017 | unsigned long flags; | 2003 | unsigned long flags; |
2018 | 2004 | ||
@@ -2036,10 +2022,10 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2036 | msleep_interruptible(jiffies_to_msecs(char_time)); | 2022 | msleep_interruptible(jiffies_to_msecs(char_time)); |
2037 | 2023 | ||
2038 | if (signal_pending(current)) | 2024 | if (signal_pending(current)) |
2039 | break; | 2025 | return; |
2040 | 2026 | ||
2041 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 2027 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
2042 | break; | 2028 | return; |
2043 | 2029 | ||
2044 | spin_lock_irqsave(&info->lock, flags); | 2030 | spin_lock_irqsave(&info->lock, flags); |
2045 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | 2031 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); |
@@ -2054,11 +2040,11 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2054 | */ | 2040 | */ |
2055 | static void esp_hangup(struct tty_struct *tty) | 2041 | static void esp_hangup(struct tty_struct *tty) |
2056 | { | 2042 | { |
2057 | struct esp_struct * info = (struct esp_struct *)tty->driver_data; | 2043 | struct esp_struct *info = tty->driver_data; |
2058 | 2044 | ||
2059 | if (serial_paranoia_check(info, tty->name, "esp_hangup")) | 2045 | if (serial_paranoia_check(info, tty->name, "esp_hangup")) |
2060 | return; | 2046 | return; |
2061 | 2047 | ||
2062 | rs_flush_buffer(tty); | 2048 | rs_flush_buffer(tty); |
2063 | shutdown(info); | 2049 | shutdown(info); |
2064 | info->count = 0; | 2050 | info->count = 0; |
@@ -2072,7 +2058,7 @@ static void esp_hangup(struct tty_struct *tty) | |||
2072 | * esp_open() and friends | 2058 | * esp_open() and friends |
2073 | * ------------------------------------------------------------ | 2059 | * ------------------------------------------------------------ |
2074 | */ | 2060 | */ |
2075 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | 2061 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
2076 | struct esp_struct *info) | 2062 | struct esp_struct *info) |
2077 | { | 2063 | { |
2078 | DECLARE_WAITQUEUE(wait, current); | 2064 | DECLARE_WAITQUEUE(wait, current); |
@@ -2121,11 +2107,11 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
2121 | retval = 0; | 2107 | retval = 0; |
2122 | add_wait_queue(&info->open_wait, &wait); | 2108 | add_wait_queue(&info->open_wait, &wait); |
2123 | #ifdef SERIAL_DEBUG_OPEN | 2109 | #ifdef SERIAL_DEBUG_OPEN |
2124 | printk("block_til_ready before block: ttys%d, count = %d\n", | 2110 | printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", |
2125 | info->line, info->count); | 2111 | info->line, info->count); |
2126 | #endif | 2112 | #endif |
2127 | spin_lock_irqsave(&info->lock, flags); | 2113 | spin_lock_irqsave(&info->lock, flags); |
2128 | if (!tty_hung_up_p(filp)) | 2114 | if (!tty_hung_up_p(filp)) |
2129 | info->count--; | 2115 | info->count--; |
2130 | info->blocked_open++; | 2116 | info->blocked_open++; |
2131 | while (1) { | 2117 | while (1) { |
@@ -2147,7 +2133,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
2147 | if (info->flags & ASYNC_HUP_NOTIFY) | 2133 | if (info->flags & ASYNC_HUP_NOTIFY) |
2148 | retval = -EAGAIN; | 2134 | retval = -EAGAIN; |
2149 | else | 2135 | else |
2150 | retval = -ERESTARTSYS; | 2136 | retval = -ERESTARTSYS; |
2151 | #else | 2137 | #else |
2152 | retval = -EAGAIN; | 2138 | retval = -EAGAIN; |
2153 | #endif | 2139 | #endif |
@@ -2166,7 +2152,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
2166 | break; | 2152 | break; |
2167 | } | 2153 | } |
2168 | #ifdef SERIAL_DEBUG_OPEN | 2154 | #ifdef SERIAL_DEBUG_OPEN |
2169 | printk("block_til_ready blocking: ttys%d, count = %d\n", | 2155 | printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", |
2170 | info->line, info->count); | 2156 | info->line, info->count); |
2171 | #endif | 2157 | #endif |
2172 | spin_unlock_irqrestore(&info->lock, flags); | 2158 | spin_unlock_irqrestore(&info->lock, flags); |
@@ -2180,14 +2166,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
2180 | info->blocked_open--; | 2166 | info->blocked_open--; |
2181 | spin_unlock_irqrestore(&info->lock, flags); | 2167 | spin_unlock_irqrestore(&info->lock, flags); |
2182 | #ifdef SERIAL_DEBUG_OPEN | 2168 | #ifdef SERIAL_DEBUG_OPEN |
2183 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 2169 | printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", |
2184 | info->line, info->count); | 2170 | info->line, info->count); |
2185 | #endif | 2171 | #endif |
2186 | if (retval) | 2172 | if (retval) |
2187 | return retval; | 2173 | return retval; |
2188 | info->flags |= ASYNC_NORMAL_ACTIVE; | 2174 | info->flags |= ASYNC_NORMAL_ACTIVE; |
2189 | return 0; | 2175 | return 0; |
2190 | } | 2176 | } |
2191 | 2177 | ||
2192 | /* | 2178 | /* |
2193 | * This routine is called whenever a serial port is opened. It | 2179 | * This routine is called whenever a serial port is opened. It |
@@ -2195,7 +2181,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
2195 | * the IRQ chain. It also performs the serial-specific | 2181 | * the IRQ chain. It also performs the serial-specific |
2196 | * initialization for the tty structure. | 2182 | * initialization for the tty structure. |
2197 | */ | 2183 | */ |
2198 | static int esp_open(struct tty_struct *tty, struct file * filp) | 2184 | static int esp_open(struct tty_struct *tty, struct file *filp) |
2199 | { | 2185 | { |
2200 | struct esp_struct *info; | 2186 | struct esp_struct *info; |
2201 | int retval, line; | 2187 | int retval, line; |
@@ -2218,7 +2204,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2218 | } | 2204 | } |
2219 | 2205 | ||
2220 | #ifdef SERIAL_DEBUG_OPEN | 2206 | #ifdef SERIAL_DEBUG_OPEN |
2221 | printk("esp_open %s, count = %d\n", tty->name, info->count); | 2207 | printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->count); |
2222 | #endif | 2208 | #endif |
2223 | spin_lock_irqsave(&info->lock, flags); | 2209 | spin_lock_irqsave(&info->lock, flags); |
2224 | info->count++; | 2210 | info->count++; |
@@ -2226,7 +2212,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2226 | info->tty = tty; | 2212 | info->tty = tty; |
2227 | 2213 | ||
2228 | spin_unlock_irqrestore(&info->lock, flags); | 2214 | spin_unlock_irqrestore(&info->lock, flags); |
2229 | 2215 | ||
2230 | /* | 2216 | /* |
2231 | * Start up serial port | 2217 | * Start up serial port |
2232 | */ | 2218 | */ |
@@ -2237,14 +2223,13 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2237 | retval = block_til_ready(tty, filp, info); | 2223 | retval = block_til_ready(tty, filp, info); |
2238 | if (retval) { | 2224 | if (retval) { |
2239 | #ifdef SERIAL_DEBUG_OPEN | 2225 | #ifdef SERIAL_DEBUG_OPEN |
2240 | printk("esp_open returning after block_til_ready with %d\n", | 2226 | printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n", |
2241 | retval); | 2227 | retval); |
2242 | #endif | 2228 | #endif |
2243 | return retval; | 2229 | return retval; |
2244 | } | 2230 | } |
2245 | |||
2246 | #ifdef SERIAL_DEBUG_OPEN | 2231 | #ifdef SERIAL_DEBUG_OPEN |
2247 | printk("esp_open %s successful...", tty->name); | 2232 | printk(KERN_DEBUG "esp_open %s successful...", tty->name); |
2248 | #endif | 2233 | #endif |
2249 | return 0; | 2234 | return 0; |
2250 | } | 2235 | } |
@@ -2262,10 +2247,10 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2262 | * number, and identifies which options were configured into this | 2247 | * number, and identifies which options were configured into this |
2263 | * driver. | 2248 | * driver. |
2264 | */ | 2249 | */ |
2265 | 2250 | ||
2266 | static inline void show_serial_version(void) | 2251 | static void show_serial_version(void) |
2267 | { | 2252 | { |
2268 | printk(KERN_INFO "%s version %s (DMA %u)\n", | 2253 | printk(KERN_INFO "%s version %s (DMA %u)\n", |
2269 | serial_name, serial_version, dma); | 2254 | serial_name, serial_version, dma); |
2270 | } | 2255 | } |
2271 | 2256 | ||
@@ -2273,7 +2258,7 @@ static inline void show_serial_version(void) | |||
2273 | * This routine is called by espserial_init() to initialize a specific serial | 2258 | * This routine is called by espserial_init() to initialize a specific serial |
2274 | * port. | 2259 | * port. |
2275 | */ | 2260 | */ |
2276 | static inline int autoconfig(struct esp_struct * info) | 2261 | static int autoconfig(struct esp_struct *info) |
2277 | { | 2262 | { |
2278 | int port_detected = 0; | 2263 | int port_detected = 0; |
2279 | unsigned long flags; | 2264 | unsigned long flags; |
@@ -2349,14 +2334,14 @@ static const struct tty_operations esp_ops = { | |||
2349 | static int __init espserial_init(void) | 2334 | static int __init espserial_init(void) |
2350 | { | 2335 | { |
2351 | int i, offset; | 2336 | int i, offset; |
2352 | struct esp_struct * info; | 2337 | struct esp_struct *info; |
2353 | struct esp_struct *last_primary = NULL; | 2338 | struct esp_struct *last_primary = NULL; |
2354 | int esp[] = {0x100,0x140,0x180,0x200,0x240,0x280,0x300,0x380}; | 2339 | int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 }; |
2355 | 2340 | ||
2356 | esp_driver = alloc_tty_driver(NR_PORTS); | 2341 | esp_driver = alloc_tty_driver(NR_PORTS); |
2357 | if (!esp_driver) | 2342 | if (!esp_driver) |
2358 | return -ENOMEM; | 2343 | return -ENOMEM; |
2359 | 2344 | ||
2360 | for (i = 0; i < NR_PRIMARY; i++) { | 2345 | for (i = 0; i < NR_PRIMARY; i++) { |
2361 | if (irq[i] != 0) { | 2346 | if (irq[i] != 0) { |
2362 | if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) || | 2347 | if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) || |
@@ -2378,20 +2363,20 @@ static int __init espserial_init(void) | |||
2378 | 2363 | ||
2379 | if ((flow_off < 1) || (flow_off > 1023)) | 2364 | if ((flow_off < 1) || (flow_off > 1023)) |
2380 | flow_off = 1016; | 2365 | flow_off = 1016; |
2381 | 2366 | ||
2382 | if ((flow_on < 1) || (flow_on > 1023)) | 2367 | if ((flow_on < 1) || (flow_on > 1023)) |
2383 | flow_on = 944; | 2368 | flow_on = 944; |
2384 | 2369 | ||
2385 | if ((rx_timeout < 0) || (rx_timeout > 255)) | 2370 | if ((rx_timeout < 0) || (rx_timeout > 255)) |
2386 | rx_timeout = 128; | 2371 | rx_timeout = 128; |
2387 | 2372 | ||
2388 | if (flow_on >= flow_off) | 2373 | if (flow_on >= flow_off) |
2389 | flow_on = flow_off - 1; | 2374 | flow_on = flow_off - 1; |
2390 | 2375 | ||
2391 | show_serial_version(); | 2376 | show_serial_version(); |
2392 | 2377 | ||
2393 | /* Initialize the tty_driver structure */ | 2378 | /* Initialize the tty_driver structure */ |
2394 | 2379 | ||
2395 | esp_driver->owner = THIS_MODULE; | 2380 | esp_driver->owner = THIS_MODULE; |
2396 | esp_driver->name = "ttyP"; | 2381 | esp_driver->name = "ttyP"; |
2397 | esp_driver->major = ESP_IN_MAJOR; | 2382 | esp_driver->major = ESP_IN_MAJOR; |
@@ -2401,10 +2386,11 @@ static int __init espserial_init(void) | |||
2401 | esp_driver->init_termios = tty_std_termios; | 2386 | esp_driver->init_termios = tty_std_termios; |
2402 | esp_driver->init_termios.c_cflag = | 2387 | esp_driver->init_termios.c_cflag = |
2403 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2388 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2389 | esp_driver->init_termios.c_ispeed = 9600; | ||
2390 | esp_driver->init_termios.c_ospeed = 9600; | ||
2404 | esp_driver->flags = TTY_DRIVER_REAL_RAW; | 2391 | esp_driver->flags = TTY_DRIVER_REAL_RAW; |
2405 | tty_set_operations(esp_driver, &esp_ops); | 2392 | tty_set_operations(esp_driver, &esp_ops); |
2406 | if (tty_register_driver(esp_driver)) | 2393 | if (tty_register_driver(esp_driver)) { |
2407 | { | ||
2408 | printk(KERN_ERR "Couldn't register esp serial driver"); | 2394 | printk(KERN_ERR "Couldn't register esp serial driver"); |
2409 | put_tty_driver(esp_driver); | 2395 | put_tty_driver(esp_driver); |
2410 | return 1; | 2396 | return 1; |
@@ -2412,8 +2398,7 @@ static int __init espserial_init(void) | |||
2412 | 2398 | ||
2413 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); | 2399 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); |
2414 | 2400 | ||
2415 | if (!info) | 2401 | if (!info) { |
2416 | { | ||
2417 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); | 2402 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); |
2418 | tty_unregister_driver(esp_driver); | 2403 | tty_unregister_driver(esp_driver); |
2419 | put_tty_driver(esp_driver); | 2404 | put_tty_driver(esp_driver); |
@@ -2476,10 +2461,8 @@ static int __init espserial_init(void) | |||
2476 | info->stat_flags |= ESP_STAT_NEVER_DMA; | 2461 | info->stat_flags |= ESP_STAT_NEVER_DMA; |
2477 | 2462 | ||
2478 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); | 2463 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); |
2479 | if (!info) | 2464 | if (!info) { |
2480 | { | 2465 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); |
2481 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); | ||
2482 | |||
2483 | /* allow use of the already detected ports */ | 2466 | /* allow use of the already detected ports */ |
2484 | return 0; | 2467 | return 0; |
2485 | } | 2468 | } |
@@ -2503,22 +2486,20 @@ static int __init espserial_init(void) | |||
2503 | return 0; | 2486 | return 0; |
2504 | } | 2487 | } |
2505 | 2488 | ||
2506 | static void __exit espserial_exit(void) | 2489 | static void __exit espserial_exit(void) |
2507 | { | 2490 | { |
2508 | int e1; | 2491 | int e1; |
2509 | struct esp_struct *temp_async; | 2492 | struct esp_struct *temp_async; |
2510 | struct esp_pio_buffer *pio_buf; | 2493 | struct esp_pio_buffer *pio_buf; |
2511 | 2494 | ||
2512 | /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ | 2495 | e1 = tty_unregister_driver(esp_driver); |
2513 | if ((e1 = tty_unregister_driver(esp_driver))) | 2496 | if (e1) |
2514 | printk("SERIAL: failed to unregister serial driver (%d)\n", | 2497 | printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1); |
2515 | e1); | ||
2516 | put_tty_driver(esp_driver); | 2498 | put_tty_driver(esp_driver); |
2517 | 2499 | ||
2518 | while (ports) { | 2500 | while (ports) { |
2519 | if (ports->port) { | 2501 | if (ports->port) |
2520 | release_region(ports->port, REGION_SIZE); | 2502 | release_region(ports->port, REGION_SIZE); |
2521 | } | ||
2522 | temp_async = ports->next_port; | 2503 | temp_async = ports->next_port; |
2523 | kfree(ports); | 2504 | kfree(ports); |
2524 | ports = temp_async; | 2505 | ports = temp_async; |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 7ed7da1d99cf..252f73e48596 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -40,27 +40,27 @@ static int gs_debug; | |||
40 | #define gs_dprintk(f, str...) /* nothing */ | 40 | #define gs_dprintk(f, str...) /* nothing */ |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__) | 43 | #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__) |
44 | #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__) | 44 | #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__) |
45 | 45 | ||
46 | #define RS_EVENT_WRITE_WAKEUP 1 | 46 | #define RS_EVENT_WRITE_WAKEUP 1 |
47 | 47 | ||
48 | module_param(gs_debug, int, 0644); | 48 | module_param(gs_debug, int, 0644); |
49 | 49 | ||
50 | 50 | ||
51 | void gs_put_char(struct tty_struct * tty, unsigned char ch) | 51 | int gs_put_char(struct tty_struct * tty, unsigned char ch) |
52 | { | 52 | { |
53 | struct gs_port *port; | 53 | struct gs_port *port; |
54 | 54 | ||
55 | func_enter (); | 55 | func_enter (); |
56 | 56 | ||
57 | if (!tty) return; | 57 | if (!tty) return 0; |
58 | 58 | ||
59 | port = tty->driver_data; | 59 | port = tty->driver_data; |
60 | 60 | ||
61 | if (!port) return; | 61 | if (!port) return 0; |
62 | 62 | ||
63 | if (! (port->flags & ASYNC_INITIALIZED)) return; | 63 | if (! (port->flags & ASYNC_INITIALIZED)) return 0; |
64 | 64 | ||
65 | /* Take a lock on the serial tranmit buffer! */ | 65 | /* Take a lock on the serial tranmit buffer! */ |
66 | mutex_lock(& port->port_write_mutex); | 66 | mutex_lock(& port->port_write_mutex); |
@@ -68,7 +68,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch) | |||
68 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { | 68 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { |
69 | /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ | 69 | /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ |
70 | mutex_unlock(&port->port_write_mutex); | 70 | mutex_unlock(&port->port_write_mutex); |
71 | return; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | port->xmit_buf[port->xmit_head++] = ch; | 74 | port->xmit_buf[port->xmit_head++] = ch; |
@@ -77,6 +77,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch) | |||
77 | 77 | ||
78 | mutex_unlock(&port->port_write_mutex); | 78 | mutex_unlock(&port->port_write_mutex); |
79 | func_exit (); | 79 | func_exit (); |
80 | return 1; | ||
80 | } | 81 | } |
81 | 82 | ||
82 | 83 | ||
@@ -586,8 +587,7 @@ void gs_close(struct tty_struct * tty, struct file * filp) | |||
586 | 587 | ||
587 | port->flags &= ~GS_ACTIVE; | 588 | port->flags &= ~GS_ACTIVE; |
588 | 589 | ||
589 | if (tty->driver->flush_buffer) | 590 | gs_flush_buffer(tty); |
590 | tty->driver->flush_buffer(tty); | ||
591 | 591 | ||
592 | tty_ldisc_flush(tty); | 592 | tty_ldisc_flush(tty); |
593 | tty->closing = 0; | 593 | tty->closing = 0; |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 1399971be689..e7fb0bca3667 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -308,7 +308,7 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
308 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | 308 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, |
309 | PAGE_SIZE, vma->vm_page_prot)) { | 309 | PAGE_SIZE, vma->vm_page_prot)) { |
310 | printk(KERN_ERR "%s: io_remap_pfn_range failed\n", | 310 | printk(KERN_ERR "%s: io_remap_pfn_range failed\n", |
311 | __FUNCTION__); | 311 | __func__); |
312 | return -EAGAIN; | 312 | return -EAGAIN; |
313 | } | 313 | } |
314 | 314 | ||
@@ -748,7 +748,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
748 | */ | 748 | */ |
749 | if (hpet_is_known(hdp)) { | 749 | if (hpet_is_known(hdp)) { |
750 | printk(KERN_DEBUG "%s: duplicate HPET ignored\n", | 750 | printk(KERN_DEBUG "%s: duplicate HPET ignored\n", |
751 | __FUNCTION__); | 751 | __func__); |
752 | return 0; | 752 | return 0; |
753 | } | 753 | } |
754 | 754 | ||
@@ -869,7 +869,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
869 | 869 | ||
870 | if (hpet_is_known(hdp)) { | 870 | if (hpet_is_known(hdp)) { |
871 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | 871 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
872 | __FUNCTION__, hdp->hd_phys_address); | 872 | __func__, hdp->hd_phys_address); |
873 | iounmap(hdp->hd_address); | 873 | iounmap(hdp->hd_address); |
874 | return AE_ALREADY_EXISTS; | 874 | return AE_ALREADY_EXISTS; |
875 | } | 875 | } |
@@ -886,7 +886,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
886 | 886 | ||
887 | if (hpet_is_known(hdp)) { | 887 | if (hpet_is_known(hdp)) { |
888 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | 888 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
889 | __FUNCTION__, hdp->hd_phys_address); | 889 | __func__, hdp->hd_phys_address); |
890 | iounmap(hdp->hd_address); | 890 | iounmap(hdp->hd_address); |
891 | return AE_ALREADY_EXISTS; | 891 | return AE_ALREADY_EXISTS; |
892 | } | 892 | } |
@@ -925,7 +925,7 @@ static int hpet_acpi_add(struct acpi_device *device) | |||
925 | return -ENODEV; | 925 | return -ENODEV; |
926 | 926 | ||
927 | if (!data.hd_address || !data.hd_nirqs) { | 927 | if (!data.hd_address || !data.hd_nirqs) { |
928 | printk("%s: no address or irqs in _CRS\n", __FUNCTION__); | 928 | printk("%s: no address or irqs in _CRS\n", __func__); |
929 | return -ENODEV; | 929 | return -ENODEV; |
930 | } | 930 | } |
931 | 931 | ||
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index d5a752da322f..59c6f9ab94e4 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -246,7 +246,7 @@ static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to) | |||
246 | { | 246 | { |
247 | int remaining = (int)(hp->inbuf_end - read_to); | 247 | int remaining = (int)(hp->inbuf_end - read_to); |
248 | 248 | ||
249 | pr_debug("%s: %i chars remain\n", __FUNCTION__, remaining); | 249 | pr_debug("%s: %i chars remain\n", __func__, remaining); |
250 | 250 | ||
251 | if (read_to != hp->inbuf) | 251 | if (read_to != hp->inbuf) |
252 | memmove(hp->inbuf, read_to, remaining); | 252 | memmove(hp->inbuf, read_to, remaining); |
@@ -365,7 +365,7 @@ static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno) | |||
365 | packet.u.version = HVSI_VERSION; | 365 | packet.u.version = HVSI_VERSION; |
366 | packet.query_seqno = query_seqno+1; | 366 | packet.query_seqno = query_seqno+1; |
367 | 367 | ||
368 | pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len); | 368 | pr_debug("%s: sending %i bytes\n", __func__, packet.len); |
369 | dbg_dump_hex((uint8_t*)&packet, packet.len); | 369 | dbg_dump_hex((uint8_t*)&packet, packet.len); |
370 | 370 | ||
371 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); | 371 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); |
@@ -437,7 +437,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp, | |||
437 | return NULL; | 437 | return NULL; |
438 | 438 | ||
439 | if (overflow > 0) { | 439 | if (overflow > 0) { |
440 | pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __FUNCTION__); | 440 | pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__); |
441 | datalen = TTY_THRESHOLD_THROTTLE; | 441 | datalen = TTY_THRESHOLD_THROTTLE; |
442 | } | 442 | } |
443 | 443 | ||
@@ -448,7 +448,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp, | |||
448 | * we still have more data to deliver, so we need to save off the | 448 | * we still have more data to deliver, so we need to save off the |
449 | * overflow and send it later | 449 | * overflow and send it later |
450 | */ | 450 | */ |
451 | pr_debug("%s: deferring overflow\n", __FUNCTION__); | 451 | pr_debug("%s: deferring overflow\n", __func__); |
452 | memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow); | 452 | memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow); |
453 | hp->n_throttle = overflow; | 453 | hp->n_throttle = overflow; |
454 | } | 454 | } |
@@ -474,11 +474,11 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip, | |||
474 | 474 | ||
475 | chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); | 475 | chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); |
476 | if (chunklen == 0) { | 476 | if (chunklen == 0) { |
477 | pr_debug("%s: 0-length read\n", __FUNCTION__); | 477 | pr_debug("%s: 0-length read\n", __func__); |
478 | return 0; | 478 | return 0; |
479 | } | 479 | } |
480 | 480 | ||
481 | pr_debug("%s: got %i bytes\n", __FUNCTION__, chunklen); | 481 | pr_debug("%s: got %i bytes\n", __func__, chunklen); |
482 | dbg_dump_hex(hp->inbuf_end, chunklen); | 482 | dbg_dump_hex(hp->inbuf_end, chunklen); |
483 | 483 | ||
484 | hp->inbuf_end += chunklen; | 484 | hp->inbuf_end += chunklen; |
@@ -495,7 +495,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip, | |||
495 | continue; | 495 | continue; |
496 | } | 496 | } |
497 | 497 | ||
498 | pr_debug("%s: handling %i-byte packet\n", __FUNCTION__, | 498 | pr_debug("%s: handling %i-byte packet\n", __func__, |
499 | len_packet(packet)); | 499 | len_packet(packet)); |
500 | dbg_dump_packet(packet); | 500 | dbg_dump_packet(packet); |
501 | 501 | ||
@@ -526,7 +526,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip, | |||
526 | packet += len_packet(packet); | 526 | packet += len_packet(packet); |
527 | 527 | ||
528 | if (*hangup || *handshake) { | 528 | if (*hangup || *handshake) { |
529 | pr_debug("%s: hangup or handshake\n", __FUNCTION__); | 529 | pr_debug("%s: hangup or handshake\n", __func__); |
530 | /* | 530 | /* |
531 | * we need to send the hangup now before receiving any more data. | 531 | * we need to send the hangup now before receiving any more data. |
532 | * If we get "data, hangup, data", we can't deliver the second | 532 | * If we get "data, hangup, data", we can't deliver the second |
@@ -543,7 +543,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip, | |||
543 | 543 | ||
544 | static void hvsi_send_overflow(struct hvsi_struct *hp) | 544 | static void hvsi_send_overflow(struct hvsi_struct *hp) |
545 | { | 545 | { |
546 | pr_debug("%s: delivering %i bytes overflow\n", __FUNCTION__, | 546 | pr_debug("%s: delivering %i bytes overflow\n", __func__, |
547 | hp->n_throttle); | 547 | hp->n_throttle); |
548 | 548 | ||
549 | hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); | 549 | hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); |
@@ -563,7 +563,7 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg) | |||
563 | unsigned long flags; | 563 | unsigned long flags; |
564 | int again = 1; | 564 | int again = 1; |
565 | 565 | ||
566 | pr_debug("%s\n", __FUNCTION__); | 566 | pr_debug("%s\n", __func__); |
567 | 567 | ||
568 | while (again) { | 568 | while (again) { |
569 | spin_lock_irqsave(&hp->lock, flags); | 569 | spin_lock_irqsave(&hp->lock, flags); |
@@ -647,7 +647,7 @@ static int hvsi_query(struct hvsi_struct *hp, uint16_t verb) | |||
647 | packet.seqno = atomic_inc_return(&hp->seqno); | 647 | packet.seqno = atomic_inc_return(&hp->seqno); |
648 | packet.verb = verb; | 648 | packet.verb = verb; |
649 | 649 | ||
650 | pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len); | 650 | pr_debug("%s: sending %i bytes\n", __func__, packet.len); |
651 | dbg_dump_hex((uint8_t*)&packet, packet.len); | 651 | dbg_dump_hex((uint8_t*)&packet, packet.len); |
652 | 652 | ||
653 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); | 653 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); |
@@ -674,7 +674,7 @@ static int hvsi_get_mctrl(struct hvsi_struct *hp) | |||
674 | return ret; | 674 | return ret; |
675 | } | 675 | } |
676 | 676 | ||
677 | pr_debug("%s: mctrl 0x%x\n", __FUNCTION__, hp->mctrl); | 677 | pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl); |
678 | 678 | ||
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
@@ -694,7 +694,7 @@ static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl) | |||
694 | if (mctrl & TIOCM_DTR) | 694 | if (mctrl & TIOCM_DTR) |
695 | packet.word = HVSI_TSDTR; | 695 | packet.word = HVSI_TSDTR; |
696 | 696 | ||
697 | pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len); | 697 | pr_debug("%s: sending %i bytes\n", __func__, packet.len); |
698 | dbg_dump_hex((uint8_t*)&packet, packet.len); | 698 | dbg_dump_hex((uint8_t*)&packet, packet.len); |
699 | 699 | ||
700 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); | 700 | wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); |
@@ -790,7 +790,7 @@ static void hvsi_close_protocol(struct hvsi_struct *hp) | |||
790 | packet.len = 6; | 790 | packet.len = 6; |
791 | packet.verb = VSV_CLOSE_PROTOCOL; | 791 | packet.verb = VSV_CLOSE_PROTOCOL; |
792 | 792 | ||
793 | pr_debug("%s: sending %i bytes\n", __FUNCTION__, packet.len); | 793 | pr_debug("%s: sending %i bytes\n", __func__, packet.len); |
794 | dbg_dump_hex((uint8_t*)&packet, packet.len); | 794 | dbg_dump_hex((uint8_t*)&packet, packet.len); |
795 | 795 | ||
796 | hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); | 796 | hvc_put_chars(hp->vtermno, (char *)&packet, packet.len); |
@@ -803,7 +803,7 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp) | |||
803 | int line = tty->index; | 803 | int line = tty->index; |
804 | int ret; | 804 | int ret; |
805 | 805 | ||
806 | pr_debug("%s\n", __FUNCTION__); | 806 | pr_debug("%s\n", __func__); |
807 | 807 | ||
808 | if (line < 0 || line >= hvsi_count) | 808 | if (line < 0 || line >= hvsi_count) |
809 | return -ENODEV; | 809 | return -ENODEV; |
@@ -868,7 +868,7 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp) | |||
868 | struct hvsi_struct *hp = tty->driver_data; | 868 | struct hvsi_struct *hp = tty->driver_data; |
869 | unsigned long flags; | 869 | unsigned long flags; |
870 | 870 | ||
871 | pr_debug("%s\n", __FUNCTION__); | 871 | pr_debug("%s\n", __func__); |
872 | 872 | ||
873 | if (tty_hung_up_p(filp)) | 873 | if (tty_hung_up_p(filp)) |
874 | return; | 874 | return; |
@@ -920,7 +920,7 @@ static void hvsi_hangup(struct tty_struct *tty) | |||
920 | struct hvsi_struct *hp = tty->driver_data; | 920 | struct hvsi_struct *hp = tty->driver_data; |
921 | unsigned long flags; | 921 | unsigned long flags; |
922 | 922 | ||
923 | pr_debug("%s\n", __FUNCTION__); | 923 | pr_debug("%s\n", __func__); |
924 | 924 | ||
925 | spin_lock_irqsave(&hp->lock, flags); | 925 | spin_lock_irqsave(&hp->lock, flags); |
926 | 926 | ||
@@ -942,7 +942,7 @@ static void hvsi_push(struct hvsi_struct *hp) | |||
942 | n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); | 942 | n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); |
943 | if (n > 0) { | 943 | if (n > 0) { |
944 | /* success */ | 944 | /* success */ |
945 | pr_debug("%s: wrote %i chars\n", __FUNCTION__, n); | 945 | pr_debug("%s: wrote %i chars\n", __func__, n); |
946 | hp->n_outbuf = 0; | 946 | hp->n_outbuf = 0; |
947 | } else if (n == -EIO) { | 947 | } else if (n == -EIO) { |
948 | __set_state(hp, HVSI_FSP_DIED); | 948 | __set_state(hp, HVSI_FSP_DIED); |
@@ -965,7 +965,7 @@ static void hvsi_write_worker(struct work_struct *work) | |||
965 | 965 | ||
966 | spin_lock_irqsave(&hp->lock, flags); | 966 | spin_lock_irqsave(&hp->lock, flags); |
967 | 967 | ||
968 | pr_debug("%s: %i chars in buffer\n", __FUNCTION__, hp->n_outbuf); | 968 | pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); |
969 | 969 | ||
970 | if (!is_open(hp)) { | 970 | if (!is_open(hp)) { |
971 | /* | 971 | /* |
@@ -983,7 +983,7 @@ static void hvsi_write_worker(struct work_struct *work) | |||
983 | schedule_delayed_work(&hp->writer, 10); | 983 | schedule_delayed_work(&hp->writer, 10); |
984 | else { | 984 | else { |
985 | #ifdef DEBUG | 985 | #ifdef DEBUG |
986 | pr_debug("%s: outbuf emptied after %li jiffies\n", __FUNCTION__, | 986 | pr_debug("%s: outbuf emptied after %li jiffies\n", __func__, |
987 | jiffies - start_j); | 987 | jiffies - start_j); |
988 | start_j = 0; | 988 | start_j = 0; |
989 | #endif /* DEBUG */ | 989 | #endif /* DEBUG */ |
@@ -1020,11 +1020,11 @@ static int hvsi_write(struct tty_struct *tty, | |||
1020 | 1020 | ||
1021 | spin_lock_irqsave(&hp->lock, flags); | 1021 | spin_lock_irqsave(&hp->lock, flags); |
1022 | 1022 | ||
1023 | pr_debug("%s: %i chars in buffer\n", __FUNCTION__, hp->n_outbuf); | 1023 | pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); |
1024 | 1024 | ||
1025 | if (!is_open(hp)) { | 1025 | if (!is_open(hp)) { |
1026 | /* we're either closing or not yet open; don't accept data */ | 1026 | /* we're either closing or not yet open; don't accept data */ |
1027 | pr_debug("%s: not open\n", __FUNCTION__); | 1027 | pr_debug("%s: not open\n", __func__); |
1028 | goto out; | 1028 | goto out; |
1029 | } | 1029 | } |
1030 | 1030 | ||
@@ -1058,7 +1058,7 @@ out: | |||
1058 | spin_unlock_irqrestore(&hp->lock, flags); | 1058 | spin_unlock_irqrestore(&hp->lock, flags); |
1059 | 1059 | ||
1060 | if (total != origcount) | 1060 | if (total != origcount) |
1061 | pr_debug("%s: wanted %i, only wrote %i\n", __FUNCTION__, origcount, | 1061 | pr_debug("%s: wanted %i, only wrote %i\n", __func__, origcount, |
1062 | total); | 1062 | total); |
1063 | 1063 | ||
1064 | return total; | 1064 | return total; |
@@ -1072,7 +1072,7 @@ static void hvsi_throttle(struct tty_struct *tty) | |||
1072 | { | 1072 | { |
1073 | struct hvsi_struct *hp = (struct hvsi_struct *)tty->driver_data; | 1073 | struct hvsi_struct *hp = (struct hvsi_struct *)tty->driver_data; |
1074 | 1074 | ||
1075 | pr_debug("%s\n", __FUNCTION__); | 1075 | pr_debug("%s\n", __func__); |
1076 | 1076 | ||
1077 | h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); | 1077 | h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); |
1078 | } | 1078 | } |
@@ -1083,7 +1083,7 @@ static void hvsi_unthrottle(struct tty_struct *tty) | |||
1083 | unsigned long flags; | 1083 | unsigned long flags; |
1084 | int shouldflip = 0; | 1084 | int shouldflip = 0; |
1085 | 1085 | ||
1086 | pr_debug("%s\n", __FUNCTION__); | 1086 | pr_debug("%s\n", __func__); |
1087 | 1087 | ||
1088 | spin_lock_irqsave(&hp->lock, flags); | 1088 | spin_lock_irqsave(&hp->lock, flags); |
1089 | if (hp->n_throttle) { | 1089 | if (hp->n_throttle) { |
@@ -1302,7 +1302,7 @@ static int __init hvsi_console_init(void) | |||
1302 | hp->virq = irq_create_mapping(NULL, irq[0]); | 1302 | hp->virq = irq_create_mapping(NULL, irq[0]); |
1303 | if (hp->virq == NO_IRQ) { | 1303 | if (hp->virq == NO_IRQ) { |
1304 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", | 1304 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", |
1305 | __FUNCTION__, irq[0]); | 1305 | __func__, irq[0]); |
1306 | continue; | 1306 | continue; |
1307 | } | 1307 | } |
1308 | 1308 | ||
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 8609b8236c67..b60d425ce8d1 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -77,11 +77,16 @@ static int power_status; | |||
77 | module_param(power_status, bool, 0600); | 77 | module_param(power_status, bool, 0600); |
78 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); | 78 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); |
79 | 79 | ||
80 | static int fan_mult = I8K_FAN_MULT; | ||
81 | module_param(fan_mult, int, 0); | ||
82 | MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with"); | ||
83 | |||
80 | static int i8k_open_fs(struct inode *inode, struct file *file); | 84 | static int i8k_open_fs(struct inode *inode, struct file *file); |
81 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, | 85 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, |
82 | unsigned long); | 86 | unsigned long); |
83 | 87 | ||
84 | static const struct file_operations i8k_fops = { | 88 | static const struct file_operations i8k_fops = { |
89 | .owner = THIS_MODULE, | ||
85 | .open = i8k_open_fs, | 90 | .open = i8k_open_fs, |
86 | .read = seq_read, | 91 | .read = seq_read, |
87 | .llseek = seq_lseek, | 92 | .llseek = seq_lseek, |
@@ -238,7 +243,7 @@ static int i8k_get_fan_speed(int fan) | |||
238 | struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; | 243 | struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; |
239 | 244 | ||
240 | regs.ebx = fan & 0xff; | 245 | regs.ebx = fan & 0xff; |
241 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * I8K_FAN_MULT; | 246 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * fan_mult; |
242 | } | 247 | } |
243 | 248 | ||
244 | /* | 249 | /* |
@@ -554,13 +559,10 @@ static int __init i8k_init(void) | |||
554 | return -ENODEV; | 559 | return -ENODEV; |
555 | 560 | ||
556 | /* Register the proc entry */ | 561 | /* Register the proc entry */ |
557 | proc_i8k = create_proc_entry("i8k", 0, NULL); | 562 | proc_i8k = proc_create("i8k", 0, NULL, &i8k_fops); |
558 | if (!proc_i8k) | 563 | if (!proc_i8k) |
559 | return -ENOENT; | 564 | return -ENOENT; |
560 | 565 | ||
561 | proc_i8k->proc_fops = &i8k_fops; | ||
562 | proc_i8k->owner = THIS_MODULE; | ||
563 | |||
564 | printk(KERN_INFO | 566 | printk(KERN_INFO |
565 | "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n", | 567 | "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n", |
566 | I8K_VERSION); | 568 | I8K_VERSION); |
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c index 61ef013b8445..3601017f58cf 100644 --- a/drivers/char/ip2/i2ellis.c +++ b/drivers/char/ip2/i2ellis.c | |||
@@ -53,7 +53,7 @@ static int ii2Safe; // Safe I/O address for delay routine | |||
53 | 53 | ||
54 | static int iiDelayed; // Set when the iiResetDelay function is | 54 | static int iiDelayed; // Set when the iiResetDelay function is |
55 | // called. Cleared when ANY board is reset. | 55 | // called. Cleared when ANY board is reset. |
56 | static rwlock_t Dl_spinlock; | 56 | static DEFINE_RWLOCK(Dl_spinlock); |
57 | 57 | ||
58 | //******** | 58 | //******** |
59 | //* Code * | 59 | //* Code * |
@@ -82,7 +82,6 @@ static rwlock_t Dl_spinlock; | |||
82 | static void | 82 | static void |
83 | iiEllisInit(void) | 83 | iiEllisInit(void) |
84 | { | 84 | { |
85 | LOCK_INIT(&Dl_spinlock); | ||
86 | } | 85 | } |
87 | 86 | ||
88 | //****************************************************************************** | 87 | //****************************************************************************** |
@@ -132,7 +131,7 @@ iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) | |||
132 | || (address & 0x7) | 131 | || (address & 0x7) |
133 | ) | 132 | ) |
134 | { | 133 | { |
135 | COMPLETE(pB,I2EE_BADADDR); | 134 | I2_COMPLETE(pB, I2EE_BADADDR); |
136 | } | 135 | } |
137 | 136 | ||
138 | // Initialize accelerators | 137 | // Initialize accelerators |
@@ -152,7 +151,7 @@ iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) | |||
152 | pB->i2eValid = I2E_MAGIC; | 151 | pB->i2eValid = I2E_MAGIC; |
153 | pB->i2eState = II_STATE_COLD; | 152 | pB->i2eState = II_STATE_COLD; |
154 | 153 | ||
155 | COMPLETE(pB, I2EE_GOOD); | 154 | I2_COMPLETE(pB, I2EE_GOOD); |
156 | } | 155 | } |
157 | 156 | ||
158 | //****************************************************************************** | 157 | //****************************************************************************** |
@@ -177,12 +176,12 @@ iiReset(i2eBordStrPtr pB) | |||
177 | // Magic number should be set, else even the address is suspect | 176 | // Magic number should be set, else even the address is suspect |
178 | if (pB->i2eValid != I2E_MAGIC) | 177 | if (pB->i2eValid != I2E_MAGIC) |
179 | { | 178 | { |
180 | COMPLETE(pB, I2EE_BADMAGIC); | 179 | I2_COMPLETE(pB, I2EE_BADMAGIC); |
181 | } | 180 | } |
182 | 181 | ||
183 | OUTB(pB->i2eBase + FIFO_RESET, 0); // Any data will do | 182 | outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */ |
184 | iiDelay(pB, 50); // Pause between resets | 183 | iiDelay(pB, 50); // Pause between resets |
185 | OUTB(pB->i2eBase + FIFO_RESET, 0); // Second reset | 184 | outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */ |
186 | 185 | ||
187 | // We must wait before even attempting to read anything from the FIFO: the | 186 | // We must wait before even attempting to read anything from the FIFO: the |
188 | // board's P.O.S.T may actually attempt to read and write its end of the | 187 | // board's P.O.S.T may actually attempt to read and write its end of the |
@@ -203,7 +202,7 @@ iiReset(i2eBordStrPtr pB) | |||
203 | // Ensure anything which would have been of use to standard loadware is | 202 | // Ensure anything which would have been of use to standard loadware is |
204 | // blanked out, since board has now forgotten everything!. | 203 | // blanked out, since board has now forgotten everything!. |
205 | 204 | ||
206 | pB->i2eUsingIrq = IRQ_UNDEFINED; // Not set up to use an interrupt yet | 205 | pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */ |
207 | pB->i2eWaitingForEmptyFifo = 0; | 206 | pB->i2eWaitingForEmptyFifo = 0; |
208 | pB->i2eOutMailWaiting = 0; | 207 | pB->i2eOutMailWaiting = 0; |
209 | pB->i2eChannelPtr = NULL; | 208 | pB->i2eChannelPtr = NULL; |
@@ -215,7 +214,7 @@ iiReset(i2eBordStrPtr pB) | |||
215 | pB->i2eFatalTrap = NULL; | 214 | pB->i2eFatalTrap = NULL; |
216 | pB->i2eFatal = 0; | 215 | pB->i2eFatal = 0; |
217 | 216 | ||
218 | COMPLETE(pB, I2EE_GOOD); | 217 | I2_COMPLETE(pB, I2EE_GOOD); |
219 | } | 218 | } |
220 | 219 | ||
221 | //****************************************************************************** | 220 | //****************************************************************************** |
@@ -235,14 +234,14 @@ static int | |||
235 | iiResetDelay(i2eBordStrPtr pB) | 234 | iiResetDelay(i2eBordStrPtr pB) |
236 | { | 235 | { |
237 | if (pB->i2eValid != I2E_MAGIC) { | 236 | if (pB->i2eValid != I2E_MAGIC) { |
238 | COMPLETE(pB, I2EE_BADMAGIC); | 237 | I2_COMPLETE(pB, I2EE_BADMAGIC); |
239 | } | 238 | } |
240 | if (pB->i2eState != II_STATE_RESET) { | 239 | if (pB->i2eState != II_STATE_RESET) { |
241 | COMPLETE(pB, I2EE_BADSTATE); | 240 | I2_COMPLETE(pB, I2EE_BADSTATE); |
242 | } | 241 | } |
243 | iiDelay(pB,2000); /* Now we wait for two seconds. */ | 242 | iiDelay(pB,2000); /* Now we wait for two seconds. */ |
244 | iiDelayed = 1; /* Delay has been called: ok to initialize */ | 243 | iiDelayed = 1; /* Delay has been called: ok to initialize */ |
245 | COMPLETE(pB, I2EE_GOOD); | 244 | I2_COMPLETE(pB, I2EE_GOOD); |
246 | } | 245 | } |
247 | 246 | ||
248 | //****************************************************************************** | 247 | //****************************************************************************** |
@@ -273,12 +272,12 @@ iiInitialize(i2eBordStrPtr pB) | |||
273 | 272 | ||
274 | if (pB->i2eValid != I2E_MAGIC) | 273 | if (pB->i2eValid != I2E_MAGIC) |
275 | { | 274 | { |
276 | COMPLETE(pB, I2EE_BADMAGIC); | 275 | I2_COMPLETE(pB, I2EE_BADMAGIC); |
277 | } | 276 | } |
278 | 277 | ||
279 | if (pB->i2eState != II_STATE_RESET || !iiDelayed) | 278 | if (pB->i2eState != II_STATE_RESET || !iiDelayed) |
280 | { | 279 | { |
281 | COMPLETE(pB, I2EE_BADSTATE); | 280 | I2_COMPLETE(pB, I2EE_BADSTATE); |
282 | } | 281 | } |
283 | 282 | ||
284 | // In case there is a failure short of our completely reading the power-up | 283 | // In case there is a failure short of our completely reading the power-up |
@@ -291,13 +290,12 @@ iiInitialize(i2eBordStrPtr pB) | |||
291 | for (itemp = 0; itemp < sizeof(porStr); itemp++) | 290 | for (itemp = 0; itemp < sizeof(porStr); itemp++) |
292 | { | 291 | { |
293 | // We expect the entire message is ready. | 292 | // We expect the entire message is ready. |
294 | if (HAS_NO_INPUT(pB)) | 293 | if (!I2_HAS_INPUT(pB)) { |
295 | { | ||
296 | pB->i2ePomSize = itemp; | 294 | pB->i2ePomSize = itemp; |
297 | COMPLETE(pB, I2EE_PORM_SHORT); | 295 | I2_COMPLETE(pB, I2EE_PORM_SHORT); |
298 | } | 296 | } |
299 | 297 | ||
300 | pB->i2ePom.c[itemp] = c = BYTE_FROM(pB); | 298 | pB->i2ePom.c[itemp] = c = inb(pB->i2eData); |
301 | 299 | ||
302 | // We check the magic numbers as soon as they are supposed to be read | 300 | // We check the magic numbers as soon as they are supposed to be read |
303 | // (rather than after) to minimize effect of reading something we | 301 | // (rather than after) to minimize effect of reading something we |
@@ -306,22 +304,22 @@ iiInitialize(i2eBordStrPtr pB) | |||
306 | (itemp == POR_2_INDEX && c != POR_MAGIC_2)) | 304 | (itemp == POR_2_INDEX && c != POR_MAGIC_2)) |
307 | { | 305 | { |
308 | pB->i2ePomSize = itemp+1; | 306 | pB->i2ePomSize = itemp+1; |
309 | COMPLETE(pB, I2EE_BADMAGIC); | 307 | I2_COMPLETE(pB, I2EE_BADMAGIC); |
310 | } | 308 | } |
311 | } | 309 | } |
312 | 310 | ||
313 | pB->i2ePomSize = itemp; | 311 | pB->i2ePomSize = itemp; |
314 | 312 | ||
315 | // Ensure that this was all the data... | 313 | // Ensure that this was all the data... |
316 | if (HAS_INPUT(pB)) | 314 | if (I2_HAS_INPUT(pB)) |
317 | COMPLETE(pB, I2EE_PORM_LONG); | 315 | I2_COMPLETE(pB, I2EE_PORM_LONG); |
318 | 316 | ||
319 | // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: | 317 | // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: |
320 | // Implying we will not be able to download any code either: That's ok: the | 318 | // Implying we will not be able to download any code either: That's ok: the |
321 | // condition is pretty explicit. | 319 | // condition is pretty explicit. |
322 | if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) | 320 | if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) |
323 | { | 321 | { |
324 | COMPLETE(pB, I2EE_POSTERR); | 322 | I2_COMPLETE(pB, I2EE_POSTERR); |
325 | } | 323 | } |
326 | 324 | ||
327 | // Determine anything which must be done differently depending on the family | 325 | // Determine anything which must be done differently depending on the family |
@@ -332,7 +330,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
332 | 330 | ||
333 | pB->i2eFifoStyle = FIFO_II; | 331 | pB->i2eFifoStyle = FIFO_II; |
334 | pB->i2eFifoSize = 512; // 512 bytes, always | 332 | pB->i2eFifoSize = 512; // 512 bytes, always |
335 | pB->i2eDataWidth16 = NO; | 333 | pB->i2eDataWidth16 = false; |
336 | 334 | ||
337 | pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit | 335 | pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit |
338 | // slot, we do allow it to be done (documentation!) | 336 | // slot, we do allow it to be done (documentation!) |
@@ -354,7 +352,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
354 | // should always be consistent for IntelliPort-II. Ditto below... | 352 | // should always be consistent for IntelliPort-II. Ditto below... |
355 | if (pB->i2ePom.e.porPorts1 != 4) | 353 | if (pB->i2ePom.e.porPorts1 != 4) |
356 | { | 354 | { |
357 | COMPLETE(pB, I2EE_INCONSIST); | 355 | I2_COMPLETE(pB, I2EE_INCONSIST); |
358 | } | 356 | } |
359 | break; | 357 | break; |
360 | 358 | ||
@@ -364,7 +362,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
364 | pB->i2eChannelMap[0] = 0xff; // Eight port | 362 | pB->i2eChannelMap[0] = 0xff; // Eight port |
365 | if (pB->i2ePom.e.porPorts1 != 8) | 363 | if (pB->i2ePom.e.porPorts1 != 8) |
366 | { | 364 | { |
367 | COMPLETE(pB, I2EE_INCONSIST); | 365 | I2_COMPLETE(pB, I2EE_INCONSIST); |
368 | } | 366 | } |
369 | break; | 367 | break; |
370 | 368 | ||
@@ -373,7 +371,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
373 | pB->i2eChannelMap[0] = 0x3f; // Six Port | 371 | pB->i2eChannelMap[0] = 0x3f; // Six Port |
374 | if (pB->i2ePom.e.porPorts1 != 6) | 372 | if (pB->i2ePom.e.porPorts1 != 6) |
375 | { | 373 | { |
376 | COMPLETE(pB, I2EE_INCONSIST); | 374 | I2_COMPLETE(pB, I2EE_INCONSIST); |
377 | } | 375 | } |
378 | break; | 376 | break; |
379 | } | 377 | } |
@@ -402,7 +400,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
402 | 400 | ||
403 | if (itemp < 8 || itemp > 15) | 401 | if (itemp < 8 || itemp > 15) |
404 | { | 402 | { |
405 | COMPLETE(pB, I2EE_INCONSIST); | 403 | I2_COMPLETE(pB, I2EE_INCONSIST); |
406 | } | 404 | } |
407 | pB->i2eFifoSize = (1 << itemp); | 405 | pB->i2eFifoSize = (1 << itemp); |
408 | 406 | ||
@@ -450,26 +448,26 @@ iiInitialize(i2eBordStrPtr pB) | |||
450 | switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) | 448 | switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) |
451 | { | 449 | { |
452 | case POR_BUS_SLOT16 | POR_BUS_DIP16: | 450 | case POR_BUS_SLOT16 | POR_BUS_DIP16: |
453 | pB->i2eDataWidth16 = YES; | 451 | pB->i2eDataWidth16 = true; |
454 | pB->i2eMaxIrq = 15; | 452 | pB->i2eMaxIrq = 15; |
455 | break; | 453 | break; |
456 | 454 | ||
457 | case POR_BUS_SLOT16: | 455 | case POR_BUS_SLOT16: |
458 | pB->i2eDataWidth16 = NO; | 456 | pB->i2eDataWidth16 = false; |
459 | pB->i2eMaxIrq = 15; | 457 | pB->i2eMaxIrq = 15; |
460 | break; | 458 | break; |
461 | 459 | ||
462 | case 0: | 460 | case 0: |
463 | case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. | 461 | case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. |
464 | default: | 462 | default: |
465 | pB->i2eDataWidth16 = NO; | 463 | pB->i2eDataWidth16 = false; |
466 | pB->i2eMaxIrq = 7; | 464 | pB->i2eMaxIrq = 7; |
467 | break; | 465 | break; |
468 | } | 466 | } |
469 | break; // POR_ID_FIIEX case | 467 | break; // POR_ID_FIIEX case |
470 | 468 | ||
471 | default: // Unknown type of board | 469 | default: // Unknown type of board |
472 | COMPLETE(pB, I2EE_BAD_FAMILY); | 470 | I2_COMPLETE(pB, I2EE_BAD_FAMILY); |
473 | break; | 471 | break; |
474 | } // End the switch based on family | 472 | } // End the switch based on family |
475 | 473 | ||
@@ -483,17 +481,14 @@ iiInitialize(i2eBordStrPtr pB) | |||
483 | { | 481 | { |
484 | case POR_BUS_T_ISA: | 482 | case POR_BUS_T_ISA: |
485 | case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. | 483 | case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. |
486 | pB->i2eChangeIrq = YES; | ||
487 | break; | ||
488 | case POR_BUS_T_MCA: | 484 | case POR_BUS_T_MCA: |
489 | case POR_BUS_T_EISA: | 485 | case POR_BUS_T_EISA: |
490 | pB->i2eChangeIrq = NO; | ||
491 | break; | 486 | break; |
492 | default: | 487 | default: |
493 | COMPLETE(pB, I2EE_BADBUS); | 488 | I2_COMPLETE(pB, I2EE_BADBUS); |
494 | } | 489 | } |
495 | 490 | ||
496 | if (pB->i2eDataWidth16 == YES) | 491 | if (pB->i2eDataWidth16) |
497 | { | 492 | { |
498 | pB->i2eWriteBuf = iiWriteBuf16; | 493 | pB->i2eWriteBuf = iiWriteBuf16; |
499 | pB->i2eReadBuf = iiReadBuf16; | 494 | pB->i2eReadBuf = iiReadBuf16; |
@@ -529,7 +524,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
529 | break; | 524 | break; |
530 | 525 | ||
531 | default: | 526 | default: |
532 | COMPLETE(pB, I2EE_INCONSIST); | 527 | I2_COMPLETE(pB, I2EE_INCONSIST); |
533 | } | 528 | } |
534 | 529 | ||
535 | // Initialize state information. | 530 | // Initialize state information. |
@@ -549,7 +544,7 @@ iiInitialize(i2eBordStrPtr pB) | |||
549 | // Everything is ok now, return with good status/ | 544 | // Everything is ok now, return with good status/ |
550 | 545 | ||
551 | pB->i2eValid = I2E_MAGIC; | 546 | pB->i2eValid = I2E_MAGIC; |
552 | COMPLETE(pB, I2EE_GOOD); | 547 | I2_COMPLETE(pB, I2EE_GOOD); |
553 | } | 548 | } |
554 | 549 | ||
555 | //****************************************************************************** | 550 | //****************************************************************************** |
@@ -658,7 +653,7 @@ ii2DelayIO(unsigned int mseconds) | |||
658 | while(mseconds--) { | 653 | while(mseconds--) { |
659 | int i = ii2DelValue; | 654 | int i = ii2DelValue; |
660 | while ( i-- ) { | 655 | while ( i-- ) { |
661 | INB ( ii2Safe ); | 656 | inb(ii2Safe); |
662 | } | 657 | } |
663 | } | 658 | } |
664 | } | 659 | } |
@@ -709,11 +704,11 @@ iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count) | |||
709 | { | 704 | { |
710 | // Rudimentary sanity checking here. | 705 | // Rudimentary sanity checking here. |
711 | if (pB->i2eValid != I2E_MAGIC) | 706 | if (pB->i2eValid != I2E_MAGIC) |
712 | COMPLETE(pB, I2EE_INVALID); | 707 | I2_COMPLETE(pB, I2EE_INVALID); |
713 | 708 | ||
714 | OUTSW ( pB->i2eData, address, count); | 709 | I2_OUTSW(pB->i2eData, address, count); |
715 | 710 | ||
716 | COMPLETE(pB, I2EE_GOOD); | 711 | I2_COMPLETE(pB, I2EE_GOOD); |
717 | } | 712 | } |
718 | 713 | ||
719 | //****************************************************************************** | 714 | //****************************************************************************** |
@@ -738,11 +733,11 @@ iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count) | |||
738 | { | 733 | { |
739 | /* Rudimentary sanity checking here */ | 734 | /* Rudimentary sanity checking here */ |
740 | if (pB->i2eValid != I2E_MAGIC) | 735 | if (pB->i2eValid != I2E_MAGIC) |
741 | COMPLETE(pB, I2EE_INVALID); | 736 | I2_COMPLETE(pB, I2EE_INVALID); |
742 | 737 | ||
743 | OUTSB ( pB->i2eData, address, count ); | 738 | I2_OUTSB(pB->i2eData, address, count); |
744 | 739 | ||
745 | COMPLETE(pB, I2EE_GOOD); | 740 | I2_COMPLETE(pB, I2EE_GOOD); |
746 | } | 741 | } |
747 | 742 | ||
748 | //****************************************************************************** | 743 | //****************************************************************************** |
@@ -767,11 +762,11 @@ iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count) | |||
767 | { | 762 | { |
768 | // Rudimentary sanity checking here. | 763 | // Rudimentary sanity checking here. |
769 | if (pB->i2eValid != I2E_MAGIC) | 764 | if (pB->i2eValid != I2E_MAGIC) |
770 | COMPLETE(pB, I2EE_INVALID); | 765 | I2_COMPLETE(pB, I2EE_INVALID); |
771 | 766 | ||
772 | INSW ( pB->i2eData, address, count); | 767 | I2_INSW(pB->i2eData, address, count); |
773 | 768 | ||
774 | COMPLETE(pB, I2EE_GOOD); | 769 | I2_COMPLETE(pB, I2EE_GOOD); |
775 | } | 770 | } |
776 | 771 | ||
777 | //****************************************************************************** | 772 | //****************************************************************************** |
@@ -796,11 +791,11 @@ iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) | |||
796 | { | 791 | { |
797 | // Rudimentary sanity checking here. | 792 | // Rudimentary sanity checking here. |
798 | if (pB->i2eValid != I2E_MAGIC) | 793 | if (pB->i2eValid != I2E_MAGIC) |
799 | COMPLETE(pB, I2EE_INVALID); | 794 | I2_COMPLETE(pB, I2EE_INVALID); |
800 | 795 | ||
801 | INSB ( pB->i2eData, address, count); | 796 | I2_INSB(pB->i2eData, address, count); |
802 | 797 | ||
803 | COMPLETE(pB, I2EE_GOOD); | 798 | I2_COMPLETE(pB, I2EE_GOOD); |
804 | } | 799 | } |
805 | 800 | ||
806 | //****************************************************************************** | 801 | //****************************************************************************** |
@@ -820,7 +815,7 @@ iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) | |||
820 | static unsigned short | 815 | static unsigned short |
821 | iiReadWord16(i2eBordStrPtr pB) | 816 | iiReadWord16(i2eBordStrPtr pB) |
822 | { | 817 | { |
823 | return (unsigned short)( INW(pB->i2eData) ); | 818 | return inw(pB->i2eData); |
824 | } | 819 | } |
825 | 820 | ||
826 | //****************************************************************************** | 821 | //****************************************************************************** |
@@ -842,9 +837,9 @@ iiReadWord8(i2eBordStrPtr pB) | |||
842 | { | 837 | { |
843 | unsigned short urs; | 838 | unsigned short urs; |
844 | 839 | ||
845 | urs = INB ( pB->i2eData ); | 840 | urs = inb(pB->i2eData); |
846 | 841 | ||
847 | return ( ( INB ( pB->i2eData ) << 8 ) | urs ); | 842 | return (inb(pB->i2eData) << 8) | urs; |
848 | } | 843 | } |
849 | 844 | ||
850 | //****************************************************************************** | 845 | //****************************************************************************** |
@@ -865,7 +860,7 @@ iiReadWord8(i2eBordStrPtr pB) | |||
865 | static void | 860 | static void |
866 | iiWriteWord16(i2eBordStrPtr pB, unsigned short value) | 861 | iiWriteWord16(i2eBordStrPtr pB, unsigned short value) |
867 | { | 862 | { |
868 | WORD_TO(pB, (int)value); | 863 | outw((int)value, pB->i2eData); |
869 | } | 864 | } |
870 | 865 | ||
871 | //****************************************************************************** | 866 | //****************************************************************************** |
@@ -886,8 +881,8 @@ iiWriteWord16(i2eBordStrPtr pB, unsigned short value) | |||
886 | static void | 881 | static void |
887 | iiWriteWord8(i2eBordStrPtr pB, unsigned short value) | 882 | iiWriteWord8(i2eBordStrPtr pB, unsigned short value) |
888 | { | 883 | { |
889 | BYTE_TO(pB, (char)value); | 884 | outb((char)value, pB->i2eData); |
890 | BYTE_TO(pB, (char)(value >> 8) ); | 885 | outb((char)(value >> 8), pB->i2eData); |
891 | } | 886 | } |
892 | 887 | ||
893 | //****************************************************************************** | 888 | //****************************************************************************** |
@@ -939,30 +934,30 @@ iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay) | |||
939 | // interrupts of any kind. | 934 | // interrupts of any kind. |
940 | 935 | ||
941 | 936 | ||
942 | WRITE_LOCK_IRQSAVE(&Dl_spinlock,flags) | 937 | write_lock_irqsave(&Dl_spinlock, flags); |
943 | OUTB(pB->i2ePointer, SEL_COMMAND); | 938 | outb(SEL_COMMAND, pB->i2ePointer); |
944 | OUTB(pB->i2ePointer, SEL_CMD_SH); | 939 | outb(SEL_CMD_SH, pB->i2ePointer); |
945 | 940 | ||
946 | itemp = INB(pB->i2eStatus); | 941 | itemp = inb(pB->i2eStatus); |
947 | 942 | ||
948 | OUTB(pB->i2ePointer, SEL_COMMAND); | 943 | outb(SEL_COMMAND, pB->i2ePointer); |
949 | OUTB(pB->i2ePointer, SEL_CMD_UNSH); | 944 | outb(SEL_CMD_UNSH, pB->i2ePointer); |
950 | 945 | ||
951 | if (itemp & ST_IN_EMPTY) | 946 | if (itemp & ST_IN_EMPTY) |
952 | { | 947 | { |
953 | UPDATE_FIFO_ROOM(pB); | 948 | I2_UPDATE_FIFO_ROOM(pB); |
954 | WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags) | 949 | write_unlock_irqrestore(&Dl_spinlock, flags); |
955 | COMPLETE(pB, I2EE_GOOD); | 950 | I2_COMPLETE(pB, I2EE_GOOD); |
956 | } | 951 | } |
957 | 952 | ||
958 | WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags) | 953 | write_unlock_irqrestore(&Dl_spinlock, flags); |
959 | 954 | ||
960 | if (mSdelay-- == 0) | 955 | if (mSdelay-- == 0) |
961 | break; | 956 | break; |
962 | 957 | ||
963 | iiDelay(pB, 1); /* 1 mS granularity on checking condition */ | 958 | iiDelay(pB, 1); /* 1 mS granularity on checking condition */ |
964 | } | 959 | } |
965 | COMPLETE(pB, I2EE_TXE_TIME); | 960 | I2_COMPLETE(pB, I2EE_TXE_TIME); |
966 | } | 961 | } |
967 | 962 | ||
968 | //****************************************************************************** | 963 | //****************************************************************************** |
@@ -1002,21 +997,21 @@ iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay) | |||
1002 | // you will generally not want to service interrupts or in any way | 997 | // you will generally not want to service interrupts or in any way |
1003 | // disrupt the assumptions implicit in the larger context. | 998 | // disrupt the assumptions implicit in the larger context. |
1004 | 999 | ||
1005 | WRITE_LOCK_IRQSAVE(&Dl_spinlock,flags) | 1000 | write_lock_irqsave(&Dl_spinlock, flags); |
1006 | 1001 | ||
1007 | if (INB(pB->i2eStatus) & STE_OUT_MT) { | 1002 | if (inb(pB->i2eStatus) & STE_OUT_MT) { |
1008 | UPDATE_FIFO_ROOM(pB); | 1003 | I2_UPDATE_FIFO_ROOM(pB); |
1009 | WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags) | 1004 | write_unlock_irqrestore(&Dl_spinlock, flags); |
1010 | COMPLETE(pB, I2EE_GOOD); | 1005 | I2_COMPLETE(pB, I2EE_GOOD); |
1011 | } | 1006 | } |
1012 | WRITE_UNLOCK_IRQRESTORE(&Dl_spinlock,flags) | 1007 | write_unlock_irqrestore(&Dl_spinlock, flags); |
1013 | 1008 | ||
1014 | if (mSdelay-- == 0) | 1009 | if (mSdelay-- == 0) |
1015 | break; | 1010 | break; |
1016 | 1011 | ||
1017 | iiDelay(pB, 1); // 1 mS granularity on checking condition | 1012 | iiDelay(pB, 1); // 1 mS granularity on checking condition |
1018 | } | 1013 | } |
1019 | COMPLETE(pB, I2EE_TXE_TIME); | 1014 | I2_COMPLETE(pB, I2EE_TXE_TIME); |
1020 | } | 1015 | } |
1021 | 1016 | ||
1022 | //****************************************************************************** | 1017 | //****************************************************************************** |
@@ -1038,8 +1033,8 @@ static int | |||
1038 | iiTxMailEmptyII(i2eBordStrPtr pB) | 1033 | iiTxMailEmptyII(i2eBordStrPtr pB) |
1039 | { | 1034 | { |
1040 | int port = pB->i2ePointer; | 1035 | int port = pB->i2ePointer; |
1041 | OUTB ( port, SEL_OUTMAIL ); | 1036 | outb(SEL_OUTMAIL, port); |
1042 | return ( INB(port) == 0 ); | 1037 | return inb(port) == 0; |
1043 | } | 1038 | } |
1044 | 1039 | ||
1045 | //****************************************************************************** | 1040 | //****************************************************************************** |
@@ -1060,7 +1055,7 @@ iiTxMailEmptyII(i2eBordStrPtr pB) | |||
1060 | static int | 1055 | static int |
1061 | iiTxMailEmptyIIEX(i2eBordStrPtr pB) | 1056 | iiTxMailEmptyIIEX(i2eBordStrPtr pB) |
1062 | { | 1057 | { |
1063 | return !(INB(pB->i2eStatus) & STE_OUT_MAIL); | 1058 | return !(inb(pB->i2eStatus) & STE_OUT_MAIL); |
1064 | } | 1059 | } |
1065 | 1060 | ||
1066 | //****************************************************************************** | 1061 | //****************************************************************************** |
@@ -1084,10 +1079,10 @@ iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) | |||
1084 | { | 1079 | { |
1085 | int port = pB->i2ePointer; | 1080 | int port = pB->i2ePointer; |
1086 | 1081 | ||
1087 | OUTB(port, SEL_OUTMAIL); | 1082 | outb(SEL_OUTMAIL, port); |
1088 | if (INB(port) == 0) { | 1083 | if (inb(port) == 0) { |
1089 | OUTB(port, SEL_OUTMAIL); | 1084 | outb(SEL_OUTMAIL, port); |
1090 | OUTB(port, mail); | 1085 | outb(mail, port); |
1091 | return 1; | 1086 | return 1; |
1092 | } | 1087 | } |
1093 | return 0; | 1088 | return 0; |
@@ -1112,10 +1107,9 @@ iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) | |||
1112 | static int | 1107 | static int |
1113 | iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) | 1108 | iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) |
1114 | { | 1109 | { |
1115 | if(INB(pB->i2eStatus) & STE_OUT_MAIL) { | 1110 | if (inb(pB->i2eStatus) & STE_OUT_MAIL) |
1116 | return 0; | 1111 | return 0; |
1117 | } | 1112 | outb(mail, pB->i2eXMail); |
1118 | OUTB(pB->i2eXMail, mail); | ||
1119 | return 1; | 1113 | return 1; |
1120 | } | 1114 | } |
1121 | 1115 | ||
@@ -1136,9 +1130,9 @@ iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) | |||
1136 | static unsigned short | 1130 | static unsigned short |
1137 | iiGetMailII(i2eBordStrPtr pB) | 1131 | iiGetMailII(i2eBordStrPtr pB) |
1138 | { | 1132 | { |
1139 | if (HAS_MAIL(pB)) { | 1133 | if (I2_HAS_MAIL(pB)) { |
1140 | OUTB(pB->i2ePointer, SEL_INMAIL); | 1134 | outb(SEL_INMAIL, pB->i2ePointer); |
1141 | return INB(pB->i2ePointer); | 1135 | return inb(pB->i2ePointer); |
1142 | } else { | 1136 | } else { |
1143 | return NO_MAIL_HERE; | 1137 | return NO_MAIL_HERE; |
1144 | } | 1138 | } |
@@ -1161,11 +1155,10 @@ iiGetMailII(i2eBordStrPtr pB) | |||
1161 | static unsigned short | 1155 | static unsigned short |
1162 | iiGetMailIIEX(i2eBordStrPtr pB) | 1156 | iiGetMailIIEX(i2eBordStrPtr pB) |
1163 | { | 1157 | { |
1164 | if (HAS_MAIL(pB)) { | 1158 | if (I2_HAS_MAIL(pB)) |
1165 | return INB(pB->i2eXMail); | 1159 | return inb(pB->i2eXMail); |
1166 | } else { | 1160 | else |
1167 | return NO_MAIL_HERE; | 1161 | return NO_MAIL_HERE; |
1168 | } | ||
1169 | } | 1162 | } |
1170 | 1163 | ||
1171 | //****************************************************************************** | 1164 | //****************************************************************************** |
@@ -1184,8 +1177,8 @@ iiGetMailIIEX(i2eBordStrPtr pB) | |||
1184 | static void | 1177 | static void |
1185 | iiEnableMailIrqII(i2eBordStrPtr pB) | 1178 | iiEnableMailIrqII(i2eBordStrPtr pB) |
1186 | { | 1179 | { |
1187 | OUTB(pB->i2ePointer, SEL_MASK); | 1180 | outb(SEL_MASK, pB->i2ePointer); |
1188 | OUTB(pB->i2ePointer, ST_IN_MAIL); | 1181 | outb(ST_IN_MAIL, pB->i2ePointer); |
1189 | } | 1182 | } |
1190 | 1183 | ||
1191 | //****************************************************************************** | 1184 | //****************************************************************************** |
@@ -1204,7 +1197,7 @@ iiEnableMailIrqII(i2eBordStrPtr pB) | |||
1204 | static void | 1197 | static void |
1205 | iiEnableMailIrqIIEX(i2eBordStrPtr pB) | 1198 | iiEnableMailIrqIIEX(i2eBordStrPtr pB) |
1206 | { | 1199 | { |
1207 | OUTB(pB->i2eXMask, MX_IN_MAIL); | 1200 | outb(MX_IN_MAIL, pB->i2eXMask); |
1208 | } | 1201 | } |
1209 | 1202 | ||
1210 | //****************************************************************************** | 1203 | //****************************************************************************** |
@@ -1223,8 +1216,8 @@ iiEnableMailIrqIIEX(i2eBordStrPtr pB) | |||
1223 | static void | 1216 | static void |
1224 | iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) | 1217 | iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) |
1225 | { | 1218 | { |
1226 | OUTB(pB->i2ePointer, SEL_MASK); | 1219 | outb(SEL_MASK, pB->i2ePointer); |
1227 | OUTB(pB->i2ePointer, value); | 1220 | outb(value, pB->i2ePointer); |
1228 | } | 1221 | } |
1229 | 1222 | ||
1230 | //****************************************************************************** | 1223 | //****************************************************************************** |
@@ -1243,7 +1236,7 @@ iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) | |||
1243 | static void | 1236 | static void |
1244 | iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) | 1237 | iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) |
1245 | { | 1238 | { |
1246 | OUTB(pB->i2eXMask, value); | 1239 | outb(value, pB->i2eXMask); |
1247 | } | 1240 | } |
1248 | 1241 | ||
1249 | //****************************************************************************** | 1242 | //****************************************************************************** |
@@ -1354,9 +1347,8 @@ iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard) | |||
1354 | // immediately and be harmless, though not strictly necessary. | 1347 | // immediately and be harmless, though not strictly necessary. |
1355 | itemp = MAX_DLOAD_ACK_TIME/10; | 1348 | itemp = MAX_DLOAD_ACK_TIME/10; |
1356 | while (--itemp) { | 1349 | while (--itemp) { |
1357 | if (HAS_INPUT(pB)) { | 1350 | if (I2_HAS_INPUT(pB)) { |
1358 | switch(BYTE_FROM(pB)) | 1351 | switch (inb(pB->i2eData)) { |
1359 | { | ||
1360 | case LOADWARE_OK: | 1352 | case LOADWARE_OK: |
1361 | pB->i2eState = | 1353 | pB->i2eState = |
1362 | isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; | 1354 | isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; |
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h index 433305062fb8..c88a64e527aa 100644 --- a/drivers/char/ip2/i2ellis.h +++ b/drivers/char/ip2/i2ellis.h | |||
@@ -185,10 +185,6 @@ typedef struct _i2eBordStr | |||
185 | // The highest allowable IRQ, based on the | 185 | // The highest allowable IRQ, based on the |
186 | // slot size. | 186 | // slot size. |
187 | 187 | ||
188 | unsigned char i2eChangeIrq; | ||
189 | // Whether tis valid to change IRQ's | ||
190 | // ISA = ok, EISA, MicroChannel, no | ||
191 | |||
192 | // Accelerators for various addresses on the board | 188 | // Accelerators for various addresses on the board |
193 | int i2eBase; // I/O Address of the Board | 189 | int i2eBase; // I/O Address of the Board |
194 | int i2eData; // From here data transfers happen | 190 | int i2eData; // From here data transfers happen |
@@ -431,12 +427,6 @@ typedef struct _i2eBordStr | |||
431 | // Manifests for i2eBordStr: | 427 | // Manifests for i2eBordStr: |
432 | //------------------------------------------- | 428 | //------------------------------------------- |
433 | 429 | ||
434 | #define YES 1 | ||
435 | #define NO 0 | ||
436 | |||
437 | #define NULLFUNC (void (*)(void))0 | ||
438 | #define NULLPTR (void *)0 | ||
439 | |||
440 | typedef void (*delayFunc_t)(unsigned int); | 430 | typedef void (*delayFunc_t)(unsigned int); |
441 | 431 | ||
442 | // i2eValid | 432 | // i2eValid |
@@ -494,8 +484,8 @@ typedef void (*delayFunc_t)(unsigned int); | |||
494 | 484 | ||
495 | // i2eUsingIrq | 485 | // i2eUsingIrq |
496 | // | 486 | // |
497 | #define IRQ_UNDEFINED 0x1352 // No valid irq (or polling = 0) can ever | 487 | #define I2_IRQ_UNDEFINED 0x1352 /* No valid irq (or polling = 0) can |
498 | // promote to this! | 488 | * ever promote to this! */ |
499 | //------------------------------------------ | 489 | //------------------------------------------ |
500 | // Handy Macros for i2ellis.c and others | 490 | // Handy Macros for i2ellis.c and others |
501 | // Note these are common to -II and -IIEX | 491 | // Note these are common to -II and -IIEX |
@@ -504,41 +494,14 @@ typedef void (*delayFunc_t)(unsigned int); | |||
504 | // Given a pointer to the board structure, does the input FIFO have any data or | 494 | // Given a pointer to the board structure, does the input FIFO have any data or |
505 | // not? | 495 | // not? |
506 | // | 496 | // |
507 | #define HAS_INPUT(pB) !(INB(pB->i2eStatus) & ST_IN_EMPTY) | 497 | #define I2_HAS_INPUT(pB) !(inb(pB->i2eStatus) & ST_IN_EMPTY) |
508 | #define HAS_NO_INPUT(pB) (INB(pB->i2eStatus) & ST_IN_EMPTY) | ||
509 | |||
510 | // Given a pointer to board structure, read a byte or word from the fifo | ||
511 | // | ||
512 | #define BYTE_FROM(pB) (unsigned char)INB(pB->i2eData) | ||
513 | #define WORD_FROM(pB) (unsigned short)INW(pB->i2eData) | ||
514 | |||
515 | // Given a pointer to board structure, is there room for any data to be written | ||
516 | // to the data fifo? | ||
517 | // | ||
518 | #define HAS_OUTROOM(pB) !(INB(pB->i2eStatus) & ST_OUT_FULL) | ||
519 | #define HAS_NO_OUTROOM(pB) (INB(pB->i2eStatus) & ST_OUT_FULL) | ||
520 | |||
521 | // Given a pointer to board structure, write a single byte to the fifo | ||
522 | // structure. Note that for 16-bit interfaces, the high order byte is undefined | ||
523 | // and unknown. | ||
524 | // | ||
525 | #define BYTE_TO(pB, c) OUTB(pB->i2eData,(c)) | ||
526 | |||
527 | // Write a word to the fifo structure. For 8-bit interfaces, this may have | ||
528 | // unknown results. | ||
529 | // | ||
530 | #define WORD_TO(pB, c) OUTW(pB->i2eData,(c)) | ||
531 | 498 | ||
532 | // Given a pointer to the board structure, is there anything in the incoming | 499 | // Given a pointer to the board structure, is there anything in the incoming |
533 | // mailbox? | 500 | // mailbox? |
534 | // | 501 | // |
535 | #define HAS_MAIL(pB) (INB(pB->i2eStatus) & ST_IN_MAIL) | 502 | #define I2_HAS_MAIL(pB) (inb(pB->i2eStatus) & ST_IN_MAIL) |
536 | 503 | ||
537 | #define UPDATE_FIFO_ROOM(pB) (pB)->i2eFifoRemains=(pB)->i2eFifoSize | 504 | #define I2_UPDATE_FIFO_ROOM(pB) ((pB)->i2eFifoRemains = (pB)->i2eFifoSize) |
538 | |||
539 | // Handy macro to round up a number (like the buffer write and read routines do) | ||
540 | // | ||
541 | #define ROUNDUP(number) (((number)+1) & (~1)) | ||
542 | 505 | ||
543 | //------------------------------------------ | 506 | //------------------------------------------ |
544 | // Function Declarations for i2ellis.c | 507 | // Function Declarations for i2ellis.c |
@@ -593,20 +556,11 @@ static int iiDownloadBlock(i2eBordStrPtr, loadHdrStrPtr, int); | |||
593 | // | 556 | // |
594 | static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int); | 557 | static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int); |
595 | 558 | ||
596 | // Called indirectly always. Needed externally so the routine might be | ||
597 | // SPECIFIED as an argument to iiReset() | ||
598 | // | ||
599 | //static void ii2DelayIO(unsigned int); // N-millisecond delay using | ||
600 | //hardware spin | ||
601 | //static void ii2DelayTimer(unsigned int); // N-millisecond delay using Linux | ||
602 | //timer | ||
603 | |||
604 | // Many functions defined here return True if good, False otherwise, with an | 559 | // Many functions defined here return True if good, False otherwise, with an |
605 | // error code in i2eError field. Here is a handy macro for setting the error | 560 | // error code in i2eError field. Here is a handy macro for setting the error |
606 | // code and returning. | 561 | // code and returning. |
607 | // | 562 | // |
608 | #define COMPLETE(pB,code) \ | 563 | #define I2_COMPLETE(pB,code) do { \ |
609 | do { \ | ||
610 | pB->i2eError = code; \ | 564 | pB->i2eError = code; \ |
611 | return (code == I2EE_GOOD);\ | 565 | return (code == I2EE_GOOD);\ |
612 | } while (0) | 566 | } while (0) |
diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h index 15fe04e748f4..8aa6e7ab8d5b 100644 --- a/drivers/char/ip2/i2hw.h +++ b/drivers/char/ip2/i2hw.h | |||
@@ -129,7 +129,6 @@ registers, use byte operations only. | |||
129 | //------------------------------------------------ | 129 | //------------------------------------------------ |
130 | // | 130 | // |
131 | #include "ip2types.h" | 131 | #include "ip2types.h" |
132 | #include "i2os.h" /* For any o.s., compiler, or host-related issues */ | ||
133 | 132 | ||
134 | //------------------------------------------------------------------------- | 133 | //------------------------------------------------------------------------- |
135 | // Manifests for the I/O map: | 134 | // Manifests for the I/O map: |
@@ -644,5 +643,10 @@ typedef union _loadHdrStr | |||
644 | #define ABS_BIGGEST_BOX 16 // Absolute the most ports per box | 643 | #define ABS_BIGGEST_BOX 16 // Absolute the most ports per box |
645 | #define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX) | 644 | #define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX) |
646 | 645 | ||
646 | #define I2_OUTSW(port, addr, count) outsw((port), (addr), (((count)+1)/2)) | ||
647 | #define I2_OUTSB(port, addr, count) outsb((port), (addr), (((count)+1))&-2) | ||
648 | #define I2_INSW(port, addr, count) insw((port), (addr), (((count)+1)/2)) | ||
649 | #define I2_INSB(port, addr, count) insb((port), (addr), (((count)+1))&-2) | ||
650 | |||
647 | #endif // I2HW_H | 651 | #endif // I2HW_H |
648 | 652 | ||
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index 9c25320121ef..938879cc7bcc 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c | |||
@@ -227,17 +227,17 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) | |||
227 | i2ChanStrPtr *ppCh; | 227 | i2ChanStrPtr *ppCh; |
228 | 228 | ||
229 | if (pB->i2eValid != I2E_MAGIC) { | 229 | if (pB->i2eValid != I2E_MAGIC) { |
230 | COMPLETE(pB, I2EE_BADMAGIC); | 230 | I2_COMPLETE(pB, I2EE_BADMAGIC); |
231 | } | 231 | } |
232 | if (pB->i2eState != II_STATE_STDLOADED) { | 232 | if (pB->i2eState != II_STATE_STDLOADED) { |
233 | COMPLETE(pB, I2EE_BADSTATE); | 233 | I2_COMPLETE(pB, I2EE_BADSTATE); |
234 | } | 234 | } |
235 | 235 | ||
236 | LOCK_INIT(&pB->read_fifo_spinlock); | 236 | rwlock_init(&pB->read_fifo_spinlock); |
237 | LOCK_INIT(&pB->write_fifo_spinlock); | 237 | rwlock_init(&pB->write_fifo_spinlock); |
238 | LOCK_INIT(&pB->Dbuf_spinlock); | 238 | rwlock_init(&pB->Dbuf_spinlock); |
239 | LOCK_INIT(&pB->Bbuf_spinlock); | 239 | rwlock_init(&pB->Bbuf_spinlock); |
240 | LOCK_INIT(&pB->Fbuf_spinlock); | 240 | rwlock_init(&pB->Fbuf_spinlock); |
241 | 241 | ||
242 | // NO LOCK needed yet - this is init | 242 | // NO LOCK needed yet - this is init |
243 | 243 | ||
@@ -259,10 +259,10 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) | |||
259 | if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { | 259 | if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { |
260 | continue; | 260 | continue; |
261 | } | 261 | } |
262 | LOCK_INIT(&pCh->Ibuf_spinlock); | 262 | rwlock_init(&pCh->Ibuf_spinlock); |
263 | LOCK_INIT(&pCh->Obuf_spinlock); | 263 | rwlock_init(&pCh->Obuf_spinlock); |
264 | LOCK_INIT(&pCh->Cbuf_spinlock); | 264 | rwlock_init(&pCh->Cbuf_spinlock); |
265 | LOCK_INIT(&pCh->Pbuf_spinlock); | 265 | rwlock_init(&pCh->Pbuf_spinlock); |
266 | // NO LOCK needed yet - this is init | 266 | // NO LOCK needed yet - this is init |
267 | // Set up validity flag according to support level | 267 | // Set up validity flag according to support level |
268 | if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { | 268 | if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { |
@@ -347,7 +347,7 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) | |||
347 | } | 347 | } |
348 | // No need to check for wrap here; this is initialization. | 348 | // No need to check for wrap here; this is initialization. |
349 | pB->i2Fbuf_stuff = stuffIndex; | 349 | pB->i2Fbuf_stuff = stuffIndex; |
350 | COMPLETE(pB, I2EE_GOOD); | 350 | I2_COMPLETE(pB, I2EE_GOOD); |
351 | 351 | ||
352 | } | 352 | } |
353 | 353 | ||
@@ -374,7 +374,7 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type) | |||
374 | 374 | ||
375 | case NEED_INLINE: | 375 | case NEED_INLINE: |
376 | 376 | ||
377 | WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags); | 377 | write_lock_irqsave(&pB->Dbuf_spinlock, flags); |
378 | if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) | 378 | if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) |
379 | { | 379 | { |
380 | queueIndex = pB->i2Dbuf_strip; | 380 | queueIndex = pB->i2Dbuf_strip; |
@@ -386,12 +386,12 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type) | |||
386 | pB->i2Dbuf_strip = queueIndex; | 386 | pB->i2Dbuf_strip = queueIndex; |
387 | pCh->channelNeeds &= ~NEED_INLINE; | 387 | pCh->channelNeeds &= ~NEED_INLINE; |
388 | } | 388 | } |
389 | WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); | 389 | write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); |
390 | break; | 390 | break; |
391 | 391 | ||
392 | case NEED_BYPASS: | 392 | case NEED_BYPASS: |
393 | 393 | ||
394 | WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags); | 394 | write_lock_irqsave(&pB->Bbuf_spinlock, flags); |
395 | if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) | 395 | if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) |
396 | { | 396 | { |
397 | queueIndex = pB->i2Bbuf_strip; | 397 | queueIndex = pB->i2Bbuf_strip; |
@@ -403,12 +403,12 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type) | |||
403 | pB->i2Bbuf_strip = queueIndex; | 403 | pB->i2Bbuf_strip = queueIndex; |
404 | pCh->channelNeeds &= ~NEED_BYPASS; | 404 | pCh->channelNeeds &= ~NEED_BYPASS; |
405 | } | 405 | } |
406 | WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); | 406 | write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); |
407 | break; | 407 | break; |
408 | 408 | ||
409 | case NEED_FLOW: | 409 | case NEED_FLOW: |
410 | 410 | ||
411 | WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags); | 411 | write_lock_irqsave(&pB->Fbuf_spinlock, flags); |
412 | if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) | 412 | if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) |
413 | { | 413 | { |
414 | queueIndex = pB->i2Fbuf_strip; | 414 | queueIndex = pB->i2Fbuf_strip; |
@@ -420,7 +420,7 @@ i2DeQueueNeeds(i2eBordStrPtr pB, int type) | |||
420 | pB->i2Fbuf_strip = queueIndex; | 420 | pB->i2Fbuf_strip = queueIndex; |
421 | pCh->channelNeeds &= ~NEED_FLOW; | 421 | pCh->channelNeeds &= ~NEED_FLOW; |
422 | } | 422 | } |
423 | WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); | 423 | write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); |
424 | break; | 424 | break; |
425 | default: | 425 | default: |
426 | printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); | 426 | printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); |
@@ -453,7 +453,7 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) | |||
453 | 453 | ||
454 | case NEED_INLINE: | 454 | case NEED_INLINE: |
455 | 455 | ||
456 | WRITE_LOCK_IRQSAVE(&pB->Dbuf_spinlock,flags); | 456 | write_lock_irqsave(&pB->Dbuf_spinlock, flags); |
457 | if ( !(pCh->channelNeeds & NEED_INLINE) ) | 457 | if ( !(pCh->channelNeeds & NEED_INLINE) ) |
458 | { | 458 | { |
459 | pCh->channelNeeds |= NEED_INLINE; | 459 | pCh->channelNeeds |= NEED_INLINE; |
@@ -463,12 +463,12 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) | |||
463 | queueIndex = 0; | 463 | queueIndex = 0; |
464 | pB->i2Dbuf_stuff = queueIndex; | 464 | pB->i2Dbuf_stuff = queueIndex; |
465 | } | 465 | } |
466 | WRITE_UNLOCK_IRQRESTORE(&pB->Dbuf_spinlock,flags); | 466 | write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); |
467 | break; | 467 | break; |
468 | 468 | ||
469 | case NEED_BYPASS: | 469 | case NEED_BYPASS: |
470 | 470 | ||
471 | WRITE_LOCK_IRQSAVE(&pB->Bbuf_spinlock,flags); | 471 | write_lock_irqsave(&pB->Bbuf_spinlock, flags); |
472 | if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) | 472 | if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) |
473 | { | 473 | { |
474 | pCh->channelNeeds |= NEED_BYPASS; | 474 | pCh->channelNeeds |= NEED_BYPASS; |
@@ -478,12 +478,12 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) | |||
478 | queueIndex = 0; | 478 | queueIndex = 0; |
479 | pB->i2Bbuf_stuff = queueIndex; | 479 | pB->i2Bbuf_stuff = queueIndex; |
480 | } | 480 | } |
481 | WRITE_UNLOCK_IRQRESTORE(&pB->Bbuf_spinlock,flags); | 481 | write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); |
482 | break; | 482 | break; |
483 | 483 | ||
484 | case NEED_FLOW: | 484 | case NEED_FLOW: |
485 | 485 | ||
486 | WRITE_LOCK_IRQSAVE(&pB->Fbuf_spinlock,flags); | 486 | write_lock_irqsave(&pB->Fbuf_spinlock, flags); |
487 | if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) | 487 | if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) |
488 | { | 488 | { |
489 | pCh->channelNeeds |= NEED_FLOW; | 489 | pCh->channelNeeds |= NEED_FLOW; |
@@ -493,7 +493,7 @@ i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) | |||
493 | queueIndex = 0; | 493 | queueIndex = 0; |
494 | pB->i2Fbuf_stuff = queueIndex; | 494 | pB->i2Fbuf_stuff = queueIndex; |
495 | } | 495 | } |
496 | WRITE_UNLOCK_IRQRESTORE(&pB->Fbuf_spinlock,flags); | 496 | write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); |
497 | break; | 497 | break; |
498 | 498 | ||
499 | case NEED_CREDIT: | 499 | case NEED_CREDIT: |
@@ -562,9 +562,8 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, | |||
562 | pB = pCh->pMyBord; | 562 | pB = pCh->pMyBord; |
563 | 563 | ||
564 | // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT | 564 | // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT |
565 | if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == IRQ_UNDEFINED) { | 565 | if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED) |
566 | return -2; | 566 | return -2; |
567 | } | ||
568 | // If the board has gone fatal, return bad, and also hit the trap routine if | 567 | // If the board has gone fatal, return bad, and also hit the trap routine if |
569 | // it exists. | 568 | // it exists. |
570 | if (pB->i2eFatal) { | 569 | if (pB->i2eFatal) { |
@@ -620,13 +619,13 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, | |||
620 | switch(type) { | 619 | switch(type) { |
621 | case PTYPE_INLINE: | 620 | case PTYPE_INLINE: |
622 | lock_var_p = &pCh->Obuf_spinlock; | 621 | lock_var_p = &pCh->Obuf_spinlock; |
623 | WRITE_LOCK_IRQSAVE(lock_var_p,flags); | 622 | write_lock_irqsave(lock_var_p, flags); |
624 | stuffIndex = pCh->Obuf_stuff; | 623 | stuffIndex = pCh->Obuf_stuff; |
625 | bufroom = pCh->Obuf_strip - stuffIndex; | 624 | bufroom = pCh->Obuf_strip - stuffIndex; |
626 | break; | 625 | break; |
627 | case PTYPE_BYPASS: | 626 | case PTYPE_BYPASS: |
628 | lock_var_p = &pCh->Cbuf_spinlock; | 627 | lock_var_p = &pCh->Cbuf_spinlock; |
629 | WRITE_LOCK_IRQSAVE(lock_var_p,flags); | 628 | write_lock_irqsave(lock_var_p, flags); |
630 | stuffIndex = pCh->Cbuf_stuff; | 629 | stuffIndex = pCh->Cbuf_stuff; |
631 | bufroom = pCh->Cbuf_strip - stuffIndex; | 630 | bufroom = pCh->Cbuf_strip - stuffIndex; |
632 | break; | 631 | break; |
@@ -645,7 +644,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, | |||
645 | break; /* from for()- Enough room: goto proceed */ | 644 | break; /* from for()- Enough room: goto proceed */ |
646 | } | 645 | } |
647 | ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); | 646 | ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); |
648 | WRITE_UNLOCK_IRQRESTORE(lock_var_p, flags); | 647 | write_unlock_irqrestore(lock_var_p, flags); |
649 | } else | 648 | } else |
650 | ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); | 649 | ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); |
651 | 650 | ||
@@ -747,7 +746,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, | |||
747 | { | 746 | { |
748 | case PTYPE_INLINE: | 747 | case PTYPE_INLINE: |
749 | pCh->Obuf_stuff = stuffIndex; // Store buffer pointer | 748 | pCh->Obuf_stuff = stuffIndex; // Store buffer pointer |
750 | WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 749 | write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
751 | 750 | ||
752 | pB->debugInlineQueued++; | 751 | pB->debugInlineQueued++; |
753 | // Add the channel pointer to list of channels needing service (first | 752 | // Add the channel pointer to list of channels needing service (first |
@@ -757,7 +756,7 @@ i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, | |||
757 | 756 | ||
758 | case PTYPE_BYPASS: | 757 | case PTYPE_BYPASS: |
759 | pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer | 758 | pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer |
760 | WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags); | 759 | write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); |
761 | 760 | ||
762 | pB->debugBypassQueued++; | 761 | pB->debugBypassQueued++; |
763 | // Add the channel pointer to list of channels needing service (first | 762 | // Add the channel pointer to list of channels needing service (first |
@@ -840,7 +839,7 @@ i2Input(i2ChanStrPtr pCh) | |||
840 | count = -1; | 839 | count = -1; |
841 | goto i2Input_exit; | 840 | goto i2Input_exit; |
842 | } | 841 | } |
843 | WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags); | 842 | write_lock_irqsave(&pCh->Ibuf_spinlock, flags); |
844 | 843 | ||
845 | // initialize some accelerators and private copies | 844 | // initialize some accelerators and private copies |
846 | stripIndex = pCh->Ibuf_strip; | 845 | stripIndex = pCh->Ibuf_strip; |
@@ -850,7 +849,7 @@ i2Input(i2ChanStrPtr pCh) | |||
850 | // If buffer is empty or requested data count was 0, (trivial case) return | 849 | // If buffer is empty or requested data count was 0, (trivial case) return |
851 | // without any further thought. | 850 | // without any further thought. |
852 | if ( count == 0 ) { | 851 | if ( count == 0 ) { |
853 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 852 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
854 | goto i2Input_exit; | 853 | goto i2Input_exit; |
855 | } | 854 | } |
856 | // Adjust for buffer wrap | 855 | // Adjust for buffer wrap |
@@ -891,10 +890,10 @@ i2Input(i2ChanStrPtr pCh) | |||
891 | 890 | ||
892 | if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { | 891 | if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { |
893 | pCh->sinceLastFlow -= pCh->whenSendFlow; | 892 | pCh->sinceLastFlow -= pCh->whenSendFlow; |
894 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 893 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
895 | i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); | 894 | i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); |
896 | } else { | 895 | } else { |
897 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 896 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
898 | } | 897 | } |
899 | 898 | ||
900 | i2Input_exit: | 899 | i2Input_exit: |
@@ -926,7 +925,7 @@ i2InputFlush(i2ChanStrPtr pCh) | |||
926 | 925 | ||
927 | ip2trace (CHANN, ITRC_INPUT, 10, 0); | 926 | ip2trace (CHANN, ITRC_INPUT, 10, 0); |
928 | 927 | ||
929 | WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags); | 928 | write_lock_irqsave(&pCh->Ibuf_spinlock, flags); |
930 | count = pCh->Ibuf_stuff - pCh->Ibuf_strip; | 929 | count = pCh->Ibuf_stuff - pCh->Ibuf_strip; |
931 | 930 | ||
932 | // Adjust for buffer wrap | 931 | // Adjust for buffer wrap |
@@ -947,10 +946,10 @@ i2InputFlush(i2ChanStrPtr pCh) | |||
947 | if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) | 946 | if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) |
948 | { | 947 | { |
949 | pCh->sinceLastFlow -= pCh->whenSendFlow; | 948 | pCh->sinceLastFlow -= pCh->whenSendFlow; |
950 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 949 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
951 | i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); | 950 | i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); |
952 | } else { | 951 | } else { |
953 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 952 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
954 | } | 953 | } |
955 | 954 | ||
956 | ip2trace (CHANN, ITRC_INPUT, 19, 1, count); | 955 | ip2trace (CHANN, ITRC_INPUT, 19, 1, count); |
@@ -979,9 +978,9 @@ i2InputAvailable(i2ChanStrPtr pCh) | |||
979 | 978 | ||
980 | 979 | ||
981 | // initialize some accelerators and private copies | 980 | // initialize some accelerators and private copies |
982 | READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags); | 981 | read_lock_irqsave(&pCh->Ibuf_spinlock, flags); |
983 | count = pCh->Ibuf_stuff - pCh->Ibuf_strip; | 982 | count = pCh->Ibuf_stuff - pCh->Ibuf_strip; |
984 | READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags); | 983 | read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
985 | 984 | ||
986 | // Adjust for buffer wrap | 985 | // Adjust for buffer wrap |
987 | if (count < 0) | 986 | if (count < 0) |
@@ -1045,9 +1044,9 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) | |||
1045 | while ( count > 0 ) { | 1044 | while ( count > 0 ) { |
1046 | 1045 | ||
1047 | // How much room in output buffer is there? | 1046 | // How much room in output buffer is there? |
1048 | READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags); | 1047 | read_lock_irqsave(&pCh->Obuf_spinlock, flags); |
1049 | amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; | 1048 | amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; |
1050 | READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 1049 | read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
1051 | if (amountToMove < 0) { | 1050 | if (amountToMove < 0) { |
1052 | amountToMove += OBUF_SIZE; | 1051 | amountToMove += OBUF_SIZE; |
1053 | } | 1052 | } |
@@ -1075,7 +1074,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) | |||
1075 | if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) | 1074 | if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) |
1076 | && amountToMove > 0 ) | 1075 | && amountToMove > 0 ) |
1077 | { | 1076 | { |
1078 | WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags); | 1077 | write_lock_irqsave(&pCh->Obuf_spinlock, flags); |
1079 | stuffIndex = pCh->Obuf_stuff; | 1078 | stuffIndex = pCh->Obuf_stuff; |
1080 | 1079 | ||
1081 | // Had room to move some data: don't know whether the block size, | 1080 | // Had room to move some data: don't know whether the block size, |
@@ -1102,7 +1101,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) | |||
1102 | } | 1101 | } |
1103 | pCh->Obuf_stuff = stuffIndex; | 1102 | pCh->Obuf_stuff = stuffIndex; |
1104 | 1103 | ||
1105 | WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 1104 | write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
1106 | 1105 | ||
1107 | ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); | 1106 | ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); |
1108 | 1107 | ||
@@ -1352,9 +1351,9 @@ i2OutputFree(i2ChanStrPtr pCh) | |||
1352 | if ( !i2Validate ( pCh ) ) { | 1351 | if ( !i2Validate ( pCh ) ) { |
1353 | return -1; | 1352 | return -1; |
1354 | } | 1353 | } |
1355 | READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags); | 1354 | read_lock_irqsave(&pCh->Obuf_spinlock, flags); |
1356 | amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; | 1355 | amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; |
1357 | READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 1356 | read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
1358 | 1357 | ||
1359 | if (amountToMove < 0) { | 1358 | if (amountToMove < 0) { |
1360 | amountToMove += OBUF_SIZE; | 1359 | amountToMove += OBUF_SIZE; |
@@ -1464,11 +1463,11 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1464 | 1463 | ||
1465 | // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); | 1464 | // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); |
1466 | 1465 | ||
1467 | while (HAS_INPUT(pB)) { | 1466 | while (I2_HAS_INPUT(pB)) { |
1468 | // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); | 1467 | // ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); |
1469 | 1468 | ||
1470 | // Process packet from fifo a one atomic unit | 1469 | // Process packet from fifo a one atomic unit |
1471 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock,bflags); | 1470 | write_lock_irqsave(&pB->read_fifo_spinlock, bflags); |
1472 | 1471 | ||
1473 | // The first word (or two bytes) will have channel number and type of | 1472 | // The first word (or two bytes) will have channel number and type of |
1474 | // packet, possibly other information | 1473 | // packet, possibly other information |
@@ -1490,7 +1489,8 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1490 | // sick! | 1489 | // sick! |
1491 | if ( ((unsigned int)count) > IBUF_SIZE ) { | 1490 | if ( ((unsigned int)count) > IBUF_SIZE ) { |
1492 | pB->i2eFatal = 2; | 1491 | pB->i2eFatal = 2; |
1493 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags); | 1492 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1493 | bflags); | ||
1494 | return; /* Bail out ASAP */ | 1494 | return; /* Bail out ASAP */ |
1495 | } | 1495 | } |
1496 | // Channel is illegally big ? | 1496 | // Channel is illegally big ? |
@@ -1498,7 +1498,8 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1498 | (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) | 1498 | (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) |
1499 | { | 1499 | { |
1500 | iiReadBuf(pB, junkBuffer, count); | 1500 | iiReadBuf(pB, junkBuffer, count); |
1501 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags); | 1501 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1502 | bflags); | ||
1502 | break; /* From switch: ready for next packet */ | 1503 | break; /* From switch: ready for next packet */ |
1503 | } | 1504 | } |
1504 | 1505 | ||
@@ -1512,14 +1513,15 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1512 | if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) | 1513 | if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) |
1513 | { | 1514 | { |
1514 | pCh->hotKeyIn = iiReadWord(pB) & 0xff; | 1515 | pCh->hotKeyIn = iiReadWord(pB) & 0xff; |
1515 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags); | 1516 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1517 | bflags); | ||
1516 | i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); | 1518 | i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); |
1517 | break; /* From the switch: ready for next packet */ | 1519 | break; /* From the switch: ready for next packet */ |
1518 | } | 1520 | } |
1519 | 1521 | ||
1520 | // Normal data! We crudely assume there is room for the data in our | 1522 | // Normal data! We crudely assume there is room for the data in our |
1521 | // buffer because the board wouldn't have exceeded his credit limit. | 1523 | // buffer because the board wouldn't have exceeded his credit limit. |
1522 | WRITE_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,cflags); | 1524 | write_lock_irqsave(&pCh->Ibuf_spinlock, cflags); |
1523 | // We have 2 locks now | 1525 | // We have 2 locks now |
1524 | stuffIndex = pCh->Ibuf_stuff; | 1526 | stuffIndex = pCh->Ibuf_stuff; |
1525 | amountToRead = IBUF_SIZE - stuffIndex; | 1527 | amountToRead = IBUF_SIZE - stuffIndex; |
@@ -1562,8 +1564,9 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1562 | 1564 | ||
1563 | // Update stuff index | 1565 | // Update stuff index |
1564 | pCh->Ibuf_stuff = stuffIndex; | 1566 | pCh->Ibuf_stuff = stuffIndex; |
1565 | WRITE_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,cflags); | 1567 | write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags); |
1566 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags); | 1568 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1569 | bflags); | ||
1567 | 1570 | ||
1568 | #ifdef USE_IQ | 1571 | #ifdef USE_IQ |
1569 | schedule_work(&pCh->tqueue_input); | 1572 | schedule_work(&pCh->tqueue_input); |
@@ -1585,7 +1588,8 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1585 | 1588 | ||
1586 | iiReadBuf(pB, cmdBuffer, count); | 1589 | iiReadBuf(pB, cmdBuffer, count); |
1587 | // We can release early with buffer grab | 1590 | // We can release early with buffer grab |
1588 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock,bflags); | 1591 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1592 | bflags); | ||
1589 | 1593 | ||
1590 | pc = cmdBuffer; | 1594 | pc = cmdBuffer; |
1591 | pcLimit = &(cmdBuffer[count]); | 1595 | pcLimit = &(cmdBuffer[count]); |
@@ -1830,12 +1834,12 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1830 | default: // Neither packet? should be impossible | 1834 | default: // Neither packet? should be impossible |
1831 | ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, | 1835 | ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, |
1832 | PTYPE_OF(pB->i2eLeadoffWord) ); | 1836 | PTYPE_OF(pB->i2eLeadoffWord) ); |
1833 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, | 1837 | write_unlock_irqrestore(&pB->read_fifo_spinlock, |
1834 | bflags); | 1838 | bflags); |
1835 | 1839 | ||
1836 | break; | 1840 | break; |
1837 | } // End of switch on type of packets | 1841 | } // End of switch on type of packets |
1838 | } //while(board HAS_INPUT) | 1842 | } /*while(board I2_HAS_INPUT)*/ |
1839 | 1843 | ||
1840 | ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); | 1844 | ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); |
1841 | 1845 | ||
@@ -1858,7 +1862,7 @@ i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) | |||
1858 | { | 1862 | { |
1859 | int rc = 0; | 1863 | int rc = 0; |
1860 | unsigned long flags; | 1864 | unsigned long flags; |
1861 | WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags); | 1865 | write_lock_irqsave(&pB->write_fifo_spinlock, flags); |
1862 | if (!pB->i2eWaitingForEmptyFifo) { | 1866 | if (!pB->i2eWaitingForEmptyFifo) { |
1863 | if (pB->i2eFifoRemains > (count+reserve)) { | 1867 | if (pB->i2eFifoRemains > (count+reserve)) { |
1864 | pB->i2eFifoRemains -= count; | 1868 | pB->i2eFifoRemains -= count; |
@@ -1867,7 +1871,7 @@ i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) | |||
1867 | rc = count; | 1871 | rc = count; |
1868 | } | 1872 | } |
1869 | } | 1873 | } |
1870 | WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags); | 1874 | write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); |
1871 | return rc; | 1875 | return rc; |
1872 | } | 1876 | } |
1873 | //****************************************************************************** | 1877 | //****************************************************************************** |
@@ -1898,7 +1902,7 @@ i2StuffFifoBypass(i2eBordStrPtr pB) | |||
1898 | while ( --bailout && notClogged && | 1902 | while ( --bailout && notClogged && |
1899 | (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) | 1903 | (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) |
1900 | { | 1904 | { |
1901 | WRITE_LOCK_IRQSAVE(&pCh->Cbuf_spinlock,flags); | 1905 | write_lock_irqsave(&pCh->Cbuf_spinlock, flags); |
1902 | stripIndex = pCh->Cbuf_strip; | 1906 | stripIndex = pCh->Cbuf_strip; |
1903 | 1907 | ||
1904 | // as long as there are packets for this channel... | 1908 | // as long as there are packets for this channel... |
@@ -1906,7 +1910,7 @@ i2StuffFifoBypass(i2eBordStrPtr pB) | |||
1906 | while (stripIndex != pCh->Cbuf_stuff) { | 1910 | while (stripIndex != pCh->Cbuf_stuff) { |
1907 | pRemove = &(pCh->Cbuf[stripIndex]); | 1911 | pRemove = &(pCh->Cbuf[stripIndex]); |
1908 | packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); | 1912 | packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); |
1909 | paddedSize = ROUNDUP(packetSize); | 1913 | paddedSize = roundup(packetSize, 2); |
1910 | 1914 | ||
1911 | if (paddedSize > 0) { | 1915 | if (paddedSize > 0) { |
1912 | if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { | 1916 | if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { |
@@ -1930,7 +1934,7 @@ WriteDBGBuf("BYPS", pRemove, paddedSize); | |||
1930 | // Done with this channel. Move to next, removing this one from | 1934 | // Done with this channel. Move to next, removing this one from |
1931 | // the queue of channels if we cleaned it out (i.e., didn't get clogged. | 1935 | // the queue of channels if we cleaned it out (i.e., didn't get clogged. |
1932 | pCh->Cbuf_strip = stripIndex; | 1936 | pCh->Cbuf_strip = stripIndex; |
1933 | WRITE_UNLOCK_IRQRESTORE(&pCh->Cbuf_spinlock,flags); | 1937 | write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); |
1934 | } // Either clogged or finished all the work | 1938 | } // Either clogged or finished all the work |
1935 | 1939 | ||
1936 | #ifdef IP2DEBUG_TRACE | 1940 | #ifdef IP2DEBUG_TRACE |
@@ -1954,7 +1958,7 @@ static inline void | |||
1954 | i2StuffFifoFlow(i2eBordStrPtr pB) | 1958 | i2StuffFifoFlow(i2eBordStrPtr pB) |
1955 | { | 1959 | { |
1956 | i2ChanStrPtr pCh; | 1960 | i2ChanStrPtr pCh; |
1957 | unsigned short paddedSize = ROUNDUP(sizeof(flowIn)); | 1961 | unsigned short paddedSize = roundup(sizeof(flowIn), 2); |
1958 | 1962 | ||
1959 | ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, | 1963 | ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, |
1960 | pB->i2eFifoRemains, paddedSize ); | 1964 | pB->i2eFifoRemains, paddedSize ); |
@@ -2010,7 +2014,7 @@ i2StuffFifoInline(i2eBordStrPtr pB) | |||
2010 | while ( --bailout && notClogged && | 2014 | while ( --bailout && notClogged && |
2011 | (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) | 2015 | (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) |
2012 | { | 2016 | { |
2013 | WRITE_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags); | 2017 | write_lock_irqsave(&pCh->Obuf_spinlock, flags); |
2014 | stripIndex = pCh->Obuf_strip; | 2018 | stripIndex = pCh->Obuf_strip; |
2015 | 2019 | ||
2016 | ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); | 2020 | ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); |
@@ -2031,7 +2035,7 @@ i2StuffFifoInline(i2eBordStrPtr pB) | |||
2031 | packetSize = flowsize + sizeof(i2CmdHeader); | 2035 | packetSize = flowsize + sizeof(i2CmdHeader); |
2032 | } | 2036 | } |
2033 | flowsize = CREDIT_USAGE(flowsize); | 2037 | flowsize = CREDIT_USAGE(flowsize); |
2034 | paddedSize = ROUNDUP(packetSize); | 2038 | paddedSize = roundup(packetSize, 2); |
2035 | 2039 | ||
2036 | ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); | 2040 | ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); |
2037 | 2041 | ||
@@ -2086,7 +2090,7 @@ WriteDBGBuf("DATA", pRemove, paddedSize); | |||
2086 | // Done with this channel. Move to next, removing this one from the | 2090 | // Done with this channel. Move to next, removing this one from the |
2087 | // queue of channels if we cleaned it out (i.e., didn't get clogged. | 2091 | // queue of channels if we cleaned it out (i.e., didn't get clogged. |
2088 | pCh->Obuf_strip = stripIndex; | 2092 | pCh->Obuf_strip = stripIndex; |
2089 | WRITE_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 2093 | write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
2090 | if ( notClogged ) | 2094 | if ( notClogged ) |
2091 | { | 2095 | { |
2092 | 2096 | ||
@@ -2190,10 +2194,11 @@ i2ServiceBoard ( i2eBordStrPtr pB ) | |||
2190 | 2194 | ||
2191 | if (inmail & MB_OUT_STRIPPED) { | 2195 | if (inmail & MB_OUT_STRIPPED) { |
2192 | pB->i2eFifoOutInts++; | 2196 | pB->i2eFifoOutInts++; |
2193 | WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags); | 2197 | write_lock_irqsave(&pB->write_fifo_spinlock, flags); |
2194 | pB->i2eFifoRemains = pB->i2eFifoSize; | 2198 | pB->i2eFifoRemains = pB->i2eFifoSize; |
2195 | pB->i2eWaitingForEmptyFifo = 0; | 2199 | pB->i2eWaitingForEmptyFifo = 0; |
2196 | WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags); | 2200 | write_unlock_irqrestore(&pB->write_fifo_spinlock, |
2201 | flags); | ||
2197 | 2202 | ||
2198 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); | 2203 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); |
2199 | 2204 | ||
diff --git a/drivers/char/ip2/i2os.h b/drivers/char/ip2/i2os.h deleted file mode 100644 index eff9b542d699..000000000000 --- a/drivers/char/ip2/i2os.h +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * (c) 1999 by Computone Corporation | ||
4 | * | ||
5 | ******************************************************************************** | ||
6 | * | ||
7 | * | ||
8 | * PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport | ||
9 | * serial I/O controllers. | ||
10 | * | ||
11 | * DESCRIPTION: Defines, definitions and includes which are heavily dependent | ||
12 | * on O/S, host, compiler, etc. This file is tailored for: | ||
13 | * Linux v2.0.0 and later | ||
14 | * Gnu gcc c2.7.2 | ||
15 | * 80x86 architecture | ||
16 | * | ||
17 | *******************************************************************************/ | ||
18 | |||
19 | #ifndef I2OS_H /* To prevent multiple includes */ | ||
20 | #define I2OS_H 1 | ||
21 | |||
22 | //------------------------------------------------- | ||
23 | // Required Includes | ||
24 | //------------------------------------------------- | ||
25 | |||
26 | #include "ip2types.h" | ||
27 | #include <asm/io.h> /* For inb, etc */ | ||
28 | |||
29 | //------------------------------------ | ||
30 | // Defines for I/O instructions: | ||
31 | //------------------------------------ | ||
32 | |||
33 | #define INB(port) inb(port) | ||
34 | #define OUTB(port,value) outb((value),(port)) | ||
35 | #define INW(port) inw(port) | ||
36 | #define OUTW(port,value) outw((value),(port)) | ||
37 | #define OUTSW(port,addr,count) outsw((port),(addr),(((count)+1)/2)) | ||
38 | #define OUTSB(port,addr,count) outsb((port),(addr),(((count)+1))&-2) | ||
39 | #define INSW(port,addr,count) insw((port),(addr),(((count)+1)/2)) | ||
40 | #define INSB(port,addr,count) insb((port),(addr),(((count)+1))&-2) | ||
41 | |||
42 | //-------------------------------------------- | ||
43 | // Interrupt control | ||
44 | //-------------------------------------------- | ||
45 | |||
46 | #define LOCK_INIT(a) rwlock_init(a) | ||
47 | |||
48 | #define SAVE_AND_DISABLE_INTS(a,b) { \ | ||
49 | /* printk("get_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
50 | spin_lock_irqsave(a,b); \ | ||
51 | } | ||
52 | |||
53 | #define RESTORE_INTS(a,b) { \ | ||
54 | /* printk("rel_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
55 | spin_unlock_irqrestore(a,b); \ | ||
56 | } | ||
57 | |||
58 | #define READ_LOCK_IRQSAVE(a,b) { \ | ||
59 | /* printk("get_read_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
60 | read_lock_irqsave(a,b); \ | ||
61 | } | ||
62 | |||
63 | #define READ_UNLOCK_IRQRESTORE(a,b) { \ | ||
64 | /* printk("rel_read_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
65 | read_unlock_irqrestore(a,b); \ | ||
66 | } | ||
67 | |||
68 | #define WRITE_LOCK_IRQSAVE(a,b) { \ | ||
69 | /* printk("get_write_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
70 | write_lock_irqsave(a,b); \ | ||
71 | } | ||
72 | |||
73 | #define WRITE_UNLOCK_IRQRESTORE(a,b) { \ | ||
74 | /* printk("rel_write_lock: 0x%x,%4d,%s\n",(int)a,__LINE__,__FILE__);*/ \ | ||
75 | write_unlock_irqrestore(a,b); \ | ||
76 | } | ||
77 | |||
78 | |||
79 | //------------------------------------------------------------------------------ | ||
80 | // Hardware-delay loop | ||
81 | // | ||
82 | // Probably used in only one place (see i2ellis.c) but this helps keep things | ||
83 | // together. Note we have unwound the IN instructions. On machines with a | ||
84 | // reasonable cache, the eight instructions (1 byte each) should fit in cache | ||
85 | // nicely, and on un-cached machines, the code-fetch would tend not to dominate. | ||
86 | // Note that cx is shifted so that "count" still reflects the total number of | ||
87 | // iterations assuming no unwinding. | ||
88 | //------------------------------------------------------------------------------ | ||
89 | |||
90 | //#define DELAY1MS(port,count,label) | ||
91 | |||
92 | //------------------------------------------------------------------------------ | ||
93 | // Macros to switch to a new stack, saving stack pointers, and to restore the | ||
94 | // old stack (Used, for example, in i2lib.c) "heap" is the address of some | ||
95 | // buffer which will become the new stack (working down from highest address). | ||
96 | // The two words at the two lowest addresses in this stack are for storing the | ||
97 | // SS and SP. | ||
98 | //------------------------------------------------------------------------------ | ||
99 | |||
100 | //#define TO_NEW_STACK(heap,size) | ||
101 | //#define TO_OLD_STACK(heap) | ||
102 | |||
103 | //------------------------------------------------------------------------------ | ||
104 | // Macros to save the original IRQ vectors and masks, and to patch in new ones. | ||
105 | //------------------------------------------------------------------------------ | ||
106 | |||
107 | //#define SAVE_IRQ_MASKS(dest) | ||
108 | //#define WRITE_IRQ_MASKS(src) | ||
109 | //#define SAVE_IRQ_VECTOR(value,dest) | ||
110 | //#define WRITE_IRQ_VECTOR(value,src) | ||
111 | |||
112 | //------------------------------------------------------------------------------ | ||
113 | // Macro to copy data from one far pointer to another. | ||
114 | //------------------------------------------------------------------------------ | ||
115 | |||
116 | #define I2_MOVE_DATA(fpSource,fpDest,count) memmove(fpDest,fpSource,count); | ||
117 | |||
118 | //------------------------------------------------------------------------------ | ||
119 | // Macros to issue eoi's to host interrupt control (IBM AT 8259-style). | ||
120 | //------------------------------------------------------------------------------ | ||
121 | |||
122 | //#define MASTER_EOI | ||
123 | //#define SLAVE_EOI | ||
124 | |||
125 | #endif /* I2OS_H */ | ||
126 | |||
127 | |||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index b1d6cad84282..70957acaa960 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -133,8 +133,9 @@ | |||
133 | *****************/ | 133 | *****************/ |
134 | 134 | ||
135 | #include <linux/proc_fs.h> | 135 | #include <linux/proc_fs.h> |
136 | #include <linux/seq_file.h> | ||
136 | 137 | ||
137 | static int ip2_read_procmem(char *, char **, off_t, int); | 138 | static const struct file_operations ip2mem_proc_fops; |
138 | static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); | 139 | static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); |
139 | 140 | ||
140 | /********************/ | 141 | /********************/ |
@@ -168,7 +169,7 @@ static int Fip_firmware_size; | |||
168 | static int ip2_open(PTTY, struct file *); | 169 | static int ip2_open(PTTY, struct file *); |
169 | static void ip2_close(PTTY, struct file *); | 170 | static void ip2_close(PTTY, struct file *); |
170 | static int ip2_write(PTTY, const unsigned char *, int); | 171 | static int ip2_write(PTTY, const unsigned char *, int); |
171 | static void ip2_putchar(PTTY, unsigned char); | 172 | static int ip2_putchar(PTTY, unsigned char); |
172 | static void ip2_flush_chars(PTTY); | 173 | static void ip2_flush_chars(PTTY); |
173 | static int ip2_write_room(PTTY); | 174 | static int ip2_write_room(PTTY); |
174 | static int ip2_chars_in_buf(PTTY); | 175 | static int ip2_chars_in_buf(PTTY); |
@@ -354,14 +355,15 @@ have_requested_irq( char irq ) | |||
354 | /* the driver initialisation function and returns what it returns. */ | 355 | /* the driver initialisation function and returns what it returns. */ |
355 | /******************************************************************************/ | 356 | /******************************************************************************/ |
356 | #ifdef MODULE | 357 | #ifdef MODULE |
357 | int | 358 | static int __init |
358 | init_module(void) | 359 | ip2_init_module(void) |
359 | { | 360 | { |
360 | #ifdef IP2DEBUG_INIT | 361 | #ifdef IP2DEBUG_INIT |
361 | printk (KERN_DEBUG "Loading module ...\n" ); | 362 | printk (KERN_DEBUG "Loading module ...\n" ); |
362 | #endif | 363 | #endif |
363 | return 0; | 364 | return 0; |
364 | } | 365 | } |
366 | module_init(ip2_init_module); | ||
365 | #endif /* MODULE */ | 367 | #endif /* MODULE */ |
366 | 368 | ||
367 | /******************************************************************************/ | 369 | /******************************************************************************/ |
@@ -380,8 +382,8 @@ init_module(void) | |||
380 | /* driver should be returned since it may be unloaded from memory. */ | 382 | /* driver should be returned since it may be unloaded from memory. */ |
381 | /******************************************************************************/ | 383 | /******************************************************************************/ |
382 | #ifdef MODULE | 384 | #ifdef MODULE |
383 | void | 385 | void __exit |
384 | cleanup_module(void) | 386 | ip2_cleanup_module(void) |
385 | { | 387 | { |
386 | int err; | 388 | int err; |
387 | int i; | 389 | int i; |
@@ -423,7 +425,7 @@ cleanup_module(void) | |||
423 | } | 425 | } |
424 | put_tty_driver(ip2_tty_driver); | 426 | put_tty_driver(ip2_tty_driver); |
425 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); | 427 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); |
426 | remove_proc_entry("ip2mem", &proc_root); | 428 | remove_proc_entry("ip2mem", NULL); |
427 | 429 | ||
428 | // free memory | 430 | // free memory |
429 | for (i = 0; i < IP2_MAX_BOARDS; i++) { | 431 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
@@ -451,6 +453,7 @@ cleanup_module(void) | |||
451 | printk (KERN_DEBUG "IP2 Unloaded\n" ); | 453 | printk (KERN_DEBUG "IP2 Unloaded\n" ); |
452 | #endif | 454 | #endif |
453 | } | 455 | } |
456 | module_exit(ip2_cleanup_module); | ||
454 | #endif /* MODULE */ | 457 | #endif /* MODULE */ |
455 | 458 | ||
456 | static const struct tty_operations ip2_ops = { | 459 | static const struct tty_operations ip2_ops = { |
@@ -695,7 +698,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
695 | } | 698 | } |
696 | } | 699 | } |
697 | /* Register the read_procmem thing */ | 700 | /* Register the read_procmem thing */ |
698 | if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) { | 701 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { |
699 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); | 702 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); |
700 | } else { | 703 | } else { |
701 | 704 | ||
@@ -1049,9 +1052,9 @@ set_irq( int boardnum, int boardIrq ) | |||
1049 | * Write to FIFO; don't bother to adjust fifo capacity for this, since | 1052 | * Write to FIFO; don't bother to adjust fifo capacity for this, since |
1050 | * board will respond almost immediately after SendMail hit. | 1053 | * board will respond almost immediately after SendMail hit. |
1051 | */ | 1054 | */ |
1052 | WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags); | 1055 | write_lock_irqsave(&pB->write_fifo_spinlock, flags); |
1053 | iiWriteBuf(pB, tempCommand, 4); | 1056 | iiWriteBuf(pB, tempCommand, 4); |
1054 | WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags); | 1057 | write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); |
1055 | pB->i2eUsingIrq = boardIrq; | 1058 | pB->i2eUsingIrq = boardIrq; |
1056 | pB->i2eOutMailWaiting |= MB_OUT_STUFFED; | 1059 | pB->i2eOutMailWaiting |= MB_OUT_STUFFED; |
1057 | 1060 | ||
@@ -1069,9 +1072,9 @@ set_irq( int boardnum, int boardIrq ) | |||
1069 | (CMD_OF(tempCommand))[4] = 64; // chars | 1072 | (CMD_OF(tempCommand))[4] = 64; // chars |
1070 | 1073 | ||
1071 | (CMD_OF(tempCommand))[5] = 87; // HW_TEST | 1074 | (CMD_OF(tempCommand))[5] = 87; // HW_TEST |
1072 | WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags); | 1075 | write_lock_irqsave(&pB->write_fifo_spinlock, flags); |
1073 | iiWriteBuf(pB, tempCommand, 8); | 1076 | iiWriteBuf(pB, tempCommand, 8); |
1074 | WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags); | 1077 | write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); |
1075 | 1078 | ||
1076 | CHANNEL_OF(tempCommand) = 0; | 1079 | CHANNEL_OF(tempCommand) = 0; |
1077 | PTYPE_OF(tempCommand) = PTYPE_BYPASS; | 1080 | PTYPE_OF(tempCommand) = PTYPE_BYPASS; |
@@ -1086,9 +1089,9 @@ set_irq( int boardnum, int boardIrq ) | |||
1086 | CMD_COUNT_OF(tempCommand) = 2; | 1089 | CMD_COUNT_OF(tempCommand) = 2; |
1087 | (CMD_OF(tempCommand))[0] = 44; /* get ping */ | 1090 | (CMD_OF(tempCommand))[0] = 44; /* get ping */ |
1088 | (CMD_OF(tempCommand))[1] = 200; /* 200 ms */ | 1091 | (CMD_OF(tempCommand))[1] = 200; /* 200 ms */ |
1089 | WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags); | 1092 | write_lock_irqsave(&pB->write_fifo_spinlock, flags); |
1090 | iiWriteBuf(pB, tempCommand, 4); | 1093 | iiWriteBuf(pB, tempCommand, 4); |
1091 | WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags); | 1094 | write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); |
1092 | #endif | 1095 | #endif |
1093 | 1096 | ||
1094 | iiEnableMailIrq(pB); | 1097 | iiEnableMailIrq(pB); |
@@ -1267,12 +1270,12 @@ static void do_input(struct work_struct *work) | |||
1267 | 1270 | ||
1268 | // Data input | 1271 | // Data input |
1269 | if ( pCh->pTTY != NULL ) { | 1272 | if ( pCh->pTTY != NULL ) { |
1270 | READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags) | 1273 | read_lock_irqsave(&pCh->Ibuf_spinlock, flags); |
1271 | if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) { | 1274 | if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) { |
1272 | READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags) | 1275 | read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
1273 | i2Input( pCh ); | 1276 | i2Input( pCh ); |
1274 | } else | 1277 | } else |
1275 | READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags) | 1278 | read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
1276 | } else { | 1279 | } else { |
1277 | ip2trace(CHANN, ITRC_INPUT, 22, 0 ); | 1280 | ip2trace(CHANN, ITRC_INPUT, 22, 0 ); |
1278 | 1281 | ||
@@ -1613,10 +1616,8 @@ ip2_close( PTTY tty, struct file *pFile ) | |||
1613 | 1616 | ||
1614 | serviceOutgoingFifo ( pCh->pMyBord ); | 1617 | serviceOutgoingFifo ( pCh->pMyBord ); |
1615 | 1618 | ||
1616 | if ( tty->driver->flush_buffer ) | 1619 | tty_ldisc_flush(tty); |
1617 | tty->driver->flush_buffer(tty); | 1620 | tty_driver_flush_buffer(tty); |
1618 | if ( tty->ldisc.flush_buffer ) | ||
1619 | tty->ldisc.flush_buffer(tty); | ||
1620 | tty->closing = 0; | 1621 | tty->closing = 0; |
1621 | 1622 | ||
1622 | pCh->pTTY = NULL; | 1623 | pCh->pTTY = NULL; |
@@ -1716,9 +1717,9 @@ ip2_write( PTTY tty, const unsigned char *pData, int count) | |||
1716 | ip2_flush_chars( tty ); | 1717 | ip2_flush_chars( tty ); |
1717 | 1718 | ||
1718 | /* This is the actual move bit. Make sure it does what we need!!!!! */ | 1719 | /* This is the actual move bit. Make sure it does what we need!!!!! */ |
1719 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1720 | write_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1720 | bytesSent = i2Output( pCh, pData, count); | 1721 | bytesSent = i2Output( pCh, pData, count); |
1721 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1722 | write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1722 | 1723 | ||
1723 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); | 1724 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); |
1724 | 1725 | ||
@@ -1735,7 +1736,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count) | |||
1735 | /* */ | 1736 | /* */ |
1736 | /* */ | 1737 | /* */ |
1737 | /******************************************************************************/ | 1738 | /******************************************************************************/ |
1738 | static void | 1739 | static int |
1739 | ip2_putchar( PTTY tty, unsigned char ch ) | 1740 | ip2_putchar( PTTY tty, unsigned char ch ) |
1740 | { | 1741 | { |
1741 | i2ChanStrPtr pCh = tty->driver_data; | 1742 | i2ChanStrPtr pCh = tty->driver_data; |
@@ -1743,13 +1744,14 @@ ip2_putchar( PTTY tty, unsigned char ch ) | |||
1743 | 1744 | ||
1744 | // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); | 1745 | // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); |
1745 | 1746 | ||
1746 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1747 | write_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1747 | pCh->Pbuf[pCh->Pbuf_stuff++] = ch; | 1748 | pCh->Pbuf[pCh->Pbuf_stuff++] = ch; |
1748 | if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) { | 1749 | if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) { |
1749 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1750 | write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1750 | ip2_flush_chars( tty ); | 1751 | ip2_flush_chars( tty ); |
1751 | } else | 1752 | } else |
1752 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1753 | write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1754 | return 1; | ||
1753 | 1755 | ||
1754 | // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); | 1756 | // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); |
1755 | } | 1757 | } |
@@ -1769,7 +1771,7 @@ ip2_flush_chars( PTTY tty ) | |||
1769 | i2ChanStrPtr pCh = tty->driver_data; | 1771 | i2ChanStrPtr pCh = tty->driver_data; |
1770 | unsigned long flags; | 1772 | unsigned long flags; |
1771 | 1773 | ||
1772 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1774 | write_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1773 | if ( pCh->Pbuf_stuff ) { | 1775 | if ( pCh->Pbuf_stuff ) { |
1774 | 1776 | ||
1775 | // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); | 1777 | // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); |
@@ -1783,7 +1785,7 @@ ip2_flush_chars( PTTY tty ) | |||
1783 | } | 1785 | } |
1784 | pCh->Pbuf_stuff -= strip; | 1786 | pCh->Pbuf_stuff -= strip; |
1785 | } | 1787 | } |
1786 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1788 | write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1787 | } | 1789 | } |
1788 | 1790 | ||
1789 | /******************************************************************************/ | 1791 | /******************************************************************************/ |
@@ -1801,9 +1803,9 @@ ip2_write_room ( PTTY tty ) | |||
1801 | i2ChanStrPtr pCh = tty->driver_data; | 1803 | i2ChanStrPtr pCh = tty->driver_data; |
1802 | unsigned long flags; | 1804 | unsigned long flags; |
1803 | 1805 | ||
1804 | READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1806 | read_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1805 | bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff; | 1807 | bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff; |
1806 | READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1808 | read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1807 | 1809 | ||
1808 | ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree ); | 1810 | ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree ); |
1809 | 1811 | ||
@@ -1833,12 +1835,12 @@ ip2_chars_in_buf ( PTTY tty ) | |||
1833 | pCh->Obuf_char_count + pCh->Pbuf_stuff, | 1835 | pCh->Obuf_char_count + pCh->Pbuf_stuff, |
1834 | pCh->Obuf_char_count, pCh->Pbuf_stuff ); | 1836 | pCh->Obuf_char_count, pCh->Pbuf_stuff ); |
1835 | #endif | 1837 | #endif |
1836 | READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags); | 1838 | read_lock_irqsave(&pCh->Obuf_spinlock, flags); |
1837 | rc = pCh->Obuf_char_count; | 1839 | rc = pCh->Obuf_char_count; |
1838 | READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags); | 1840 | read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); |
1839 | READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1841 | read_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1840 | rc += pCh->Pbuf_stuff; | 1842 | rc += pCh->Pbuf_stuff; |
1841 | READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1843 | read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1842 | return rc; | 1844 | return rc; |
1843 | } | 1845 | } |
1844 | 1846 | ||
@@ -1862,9 +1864,9 @@ ip2_flush_buffer( PTTY tty ) | |||
1862 | #ifdef IP2DEBUG_WRITE | 1864 | #ifdef IP2DEBUG_WRITE |
1863 | printk (KERN_DEBUG "IP2: flush buffer\n" ); | 1865 | printk (KERN_DEBUG "IP2: flush buffer\n" ); |
1864 | #endif | 1866 | #endif |
1865 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1867 | write_lock_irqsave(&pCh->Pbuf_spinlock, flags); |
1866 | pCh->Pbuf_stuff = 0; | 1868 | pCh->Pbuf_stuff = 0; |
1867 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1869 | write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); |
1868 | i2FlushOutput( pCh ); | 1870 | i2FlushOutput( pCh ); |
1869 | ip2_owake(tty); | 1871 | ip2_owake(tty); |
1870 | 1872 | ||
@@ -1950,15 +1952,15 @@ ip2_unthrottle ( PTTY tty ) | |||
1950 | pCh->throttled = 0; | 1952 | pCh->throttled = 0; |
1951 | i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); | 1953 | i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); |
1952 | serviceOutgoingFifo( pCh->pMyBord ); | 1954 | serviceOutgoingFifo( pCh->pMyBord ); |
1953 | READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags) | 1955 | read_lock_irqsave(&pCh->Ibuf_spinlock, flags); |
1954 | if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) { | 1956 | if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) { |
1955 | READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags) | 1957 | read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
1956 | #ifdef IP2DEBUG_READ | 1958 | #ifdef IP2DEBUG_READ |
1957 | printk (KERN_DEBUG "i2Input called from unthrottle\n" ); | 1959 | printk (KERN_DEBUG "i2Input called from unthrottle\n" ); |
1958 | #endif | 1960 | #endif |
1959 | i2Input( pCh ); | 1961 | i2Input( pCh ); |
1960 | } else | 1962 | } else |
1961 | READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags) | 1963 | read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); |
1962 | } | 1964 | } |
1963 | 1965 | ||
1964 | static void | 1966 | static void |
@@ -2201,9 +2203,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2201 | * for masking). Caller should use TIOCGICOUNT to see which one it was | 2203 | * for masking). Caller should use TIOCGICOUNT to see which one it was |
2202 | */ | 2204 | */ |
2203 | case TIOCMIWAIT: | 2205 | case TIOCMIWAIT: |
2204 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); | 2206 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); |
2205 | cprev = pCh->icount; /* note the counters on entry */ | 2207 | cprev = pCh->icount; /* note the counters on entry */ |
2206 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); | 2208 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); |
2207 | i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, | 2209 | i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, |
2208 | CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); | 2210 | CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); |
2209 | init_waitqueue_entry(&wait, current); | 2211 | init_waitqueue_entry(&wait, current); |
@@ -2223,9 +2225,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2223 | rc = -ERESTARTSYS; | 2225 | rc = -ERESTARTSYS; |
2224 | break; | 2226 | break; |
2225 | } | 2227 | } |
2226 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); | 2228 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); |
2227 | cnow = pCh->icount; /* atomic copy */ | 2229 | cnow = pCh->icount; /* atomic copy */ |
2228 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); | 2230 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); |
2229 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 2231 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
2230 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { | 2232 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { |
2231 | rc = -EIO; /* no change => rc */ | 2233 | rc = -EIO; /* no change => rc */ |
@@ -2263,9 +2265,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2263 | case TIOCGICOUNT: | 2265 | case TIOCGICOUNT: |
2264 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); | 2266 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); |
2265 | 2267 | ||
2266 | WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags); | 2268 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); |
2267 | cnow = pCh->icount; | 2269 | cnow = pCh->icount; |
2268 | WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags); | 2270 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); |
2269 | p_cuser = argp; | 2271 | p_cuser = argp; |
2270 | rc = put_user(cnow.cts, &p_cuser->cts); | 2272 | rc = put_user(cnow.cts, &p_cuser->cts); |
2271 | rc = put_user(cnow.dsr, &p_cuser->dsr); | 2273 | rc = put_user(cnow.dsr, &p_cuser->dsr); |
@@ -2871,7 +2873,7 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) | |||
2871 | case 65: /* Board - ip2stat */ | 2873 | case 65: /* Board - ip2stat */ |
2872 | if ( pB ) { | 2874 | if ( pB ) { |
2873 | rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); | 2875 | rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); |
2874 | rc = put_user(INB(pB->i2eStatus), | 2876 | rc = put_user(inb(pB->i2eStatus), |
2875 | (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); | 2877 | (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); |
2876 | } else { | 2878 | } else { |
2877 | rc = -ENODEV; | 2879 | rc = -ENODEV; |
@@ -2967,65 +2969,61 @@ ip2_ipl_open( struct inode *pInode, struct file *pFile ) | |||
2967 | } | 2969 | } |
2968 | return 0; | 2970 | return 0; |
2969 | } | 2971 | } |
2970 | /******************************************************************************/ | ||
2971 | /* Function: ip2_read_procmem */ | ||
2972 | /* Parameters: */ | ||
2973 | /* */ | ||
2974 | /* Returns: Length of output */ | ||
2975 | /* */ | ||
2976 | /* Description: */ | ||
2977 | /* Supplies some driver operating parameters */ | ||
2978 | /* Not real useful unless your debugging the fifo */ | ||
2979 | /* */ | ||
2980 | /******************************************************************************/ | ||
2981 | |||
2982 | #define LIMIT (PAGE_SIZE - 120) | ||
2983 | 2972 | ||
2984 | static int | 2973 | static int |
2985 | ip2_read_procmem(char *buf, char **start, off_t offset, int len) | 2974 | proc_ip2mem_show(struct seq_file *m, void *v) |
2986 | { | 2975 | { |
2987 | i2eBordStrPtr pB; | 2976 | i2eBordStrPtr pB; |
2988 | i2ChanStrPtr pCh; | 2977 | i2ChanStrPtr pCh; |
2989 | PTTY tty; | 2978 | PTTY tty; |
2990 | int i; | 2979 | int i; |
2991 | 2980 | ||
2992 | len = 0; | ||
2993 | |||
2994 | #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n" | 2981 | #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n" |
2995 | #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n" | 2982 | #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n" |
2996 | #define FMTLIN3 " 0x%04x 0x%04x rc flow\n" | 2983 | #define FMTLIN3 " 0x%04x 0x%04x rc flow\n" |
2997 | 2984 | ||
2998 | len += sprintf(buf+len,"\n"); | 2985 | seq_printf(m,"\n"); |
2999 | 2986 | ||
3000 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 2987 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { |
3001 | pB = i2BoardPtrTable[i]; | 2988 | pB = i2BoardPtrTable[i]; |
3002 | if ( pB ) { | 2989 | if ( pB ) { |
3003 | len += sprintf(buf+len,"board %d:\n",i); | 2990 | seq_printf(m,"board %d:\n",i); |
3004 | len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n", | 2991 | seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n", |
3005 | pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting); | 2992 | pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting); |
3006 | } | 2993 | } |
3007 | } | 2994 | } |
3008 | 2995 | ||
3009 | len += sprintf(buf+len,"#: tty flags, port flags, cflags, iflags\n"); | 2996 | seq_printf(m,"#: tty flags, port flags, cflags, iflags\n"); |
3010 | for (i=0; i < IP2_MAX_PORTS; i++) { | 2997 | for (i=0; i < IP2_MAX_PORTS; i++) { |
3011 | if (len > LIMIT) | ||
3012 | break; | ||
3013 | pCh = DevTable[i]; | 2998 | pCh = DevTable[i]; |
3014 | if (pCh) { | 2999 | if (pCh) { |
3015 | tty = pCh->pTTY; | 3000 | tty = pCh->pTTY; |
3016 | if (tty && tty->count) { | 3001 | if (tty && tty->count) { |
3017 | len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags, | 3002 | seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags, |
3018 | tty->termios->c_cflag,tty->termios->c_iflag); | 3003 | tty->termios->c_cflag,tty->termios->c_iflag); |
3019 | 3004 | ||
3020 | len += sprintf(buf+len,FMTLIN2, | 3005 | seq_printf(m,FMTLIN2, |
3021 | pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds); | 3006 | pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds); |
3022 | len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room); | 3007 | seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room); |
3023 | } | 3008 | } |
3024 | } | 3009 | } |
3025 | } | 3010 | } |
3026 | return len; | 3011 | return 0; |
3012 | } | ||
3013 | |||
3014 | static int proc_ip2mem_open(struct inode *inode, struct file *file) | ||
3015 | { | ||
3016 | return single_open(file, proc_ip2mem_show, NULL); | ||
3027 | } | 3017 | } |
3028 | 3018 | ||
3019 | static const struct file_operations ip2mem_proc_fops = { | ||
3020 | .owner = THIS_MODULE, | ||
3021 | .open = proc_ip2mem_open, | ||
3022 | .read = seq_read, | ||
3023 | .llseek = seq_lseek, | ||
3024 | .release = single_release, | ||
3025 | }; | ||
3026 | |||
3029 | /* | 3027 | /* |
3030 | * This is the handler for /proc/tty/driver/ip2 | 3028 | * This is the handler for /proc/tty/driver/ip2 |
3031 | * | 3029 | * |
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 553f0a408eda..eb8a1a8c188e 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile | |||
@@ -9,7 +9,3 @@ obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o | |||
9 | obj-$(CONFIG_IPMI_SI) += ipmi_si.o | 9 | obj-$(CONFIG_IPMI_SI) += ipmi_si.o |
10 | obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o | 10 | obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o |
11 | obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o | 11 | obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o |
12 | |||
13 | ipmi_si.o: $(ipmi_si-objs) | ||
14 | $(LD) -r -o $@ $(ipmi_si-objs) | ||
15 | |||
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index e736119b6497..7b98c067190a 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -37,26 +37,32 @@ | |||
37 | #define BT_DEBUG_ENABLE 1 /* Generic messages */ | 37 | #define BT_DEBUG_ENABLE 1 /* Generic messages */ |
38 | #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */ | 38 | #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */ |
39 | #define BT_DEBUG_STATES 4 /* Verbose look at state changes */ | 39 | #define BT_DEBUG_STATES 4 /* Verbose look at state changes */ |
40 | /* BT_DEBUG_OFF must be zero to correspond to the default uninitialized | 40 | /* |
41 | value */ | 41 | * BT_DEBUG_OFF must be zero to correspond to the default uninitialized |
42 | * value | ||
43 | */ | ||
42 | 44 | ||
43 | static int bt_debug; /* 0 == BT_DEBUG_OFF */ | 45 | static int bt_debug; /* 0 == BT_DEBUG_OFF */ |
44 | 46 | ||
45 | module_param(bt_debug, int, 0644); | 47 | module_param(bt_debug, int, 0644); |
46 | MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); | 48 | MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); |
47 | 49 | ||
48 | /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds, | 50 | /* |
49 | and 64 byte buffers. However, one HP implementation wants 255 bytes of | 51 | * Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds, |
50 | buffer (with a documented message of 160 bytes) so go for the max. | 52 | * and 64 byte buffers. However, one HP implementation wants 255 bytes of |
51 | Since the Open IPMI architecture is single-message oriented at this | 53 | * buffer (with a documented message of 160 bytes) so go for the max. |
52 | stage, the queue depth of BT is of no concern. */ | 54 | * Since the Open IPMI architecture is single-message oriented at this |
55 | * stage, the queue depth of BT is of no concern. | ||
56 | */ | ||
53 | 57 | ||
54 | #define BT_NORMAL_TIMEOUT 5 /* seconds */ | 58 | #define BT_NORMAL_TIMEOUT 5 /* seconds */ |
55 | #define BT_NORMAL_RETRY_LIMIT 2 | 59 | #define BT_NORMAL_RETRY_LIMIT 2 |
56 | #define BT_RESET_DELAY 6 /* seconds after warm reset */ | 60 | #define BT_RESET_DELAY 6 /* seconds after warm reset */ |
57 | 61 | ||
58 | /* States are written in chronological order and usually cover | 62 | /* |
59 | multiple rows of the state table discussion in the IPMI spec. */ | 63 | * States are written in chronological order and usually cover |
64 | * multiple rows of the state table discussion in the IPMI spec. | ||
65 | */ | ||
60 | 66 | ||
61 | enum bt_states { | 67 | enum bt_states { |
62 | BT_STATE_IDLE = 0, /* Order is critical in this list */ | 68 | BT_STATE_IDLE = 0, /* Order is critical in this list */ |
@@ -76,10 +82,12 @@ enum bt_states { | |||
76 | BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */ | 82 | BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */ |
77 | }; | 83 | }; |
78 | 84 | ||
79 | /* Macros seen at the end of state "case" blocks. They help with legibility | 85 | /* |
80 | and debugging. */ | 86 | * Macros seen at the end of state "case" blocks. They help with legibility |
87 | * and debugging. | ||
88 | */ | ||
81 | 89 | ||
82 | #define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; } | 90 | #define BT_STATE_CHANGE(X, Y) { bt->state = X; return Y; } |
83 | 91 | ||
84 | #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; } | 92 | #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; } |
85 | 93 | ||
@@ -110,11 +118,13 @@ struct si_sm_data { | |||
110 | #define BT_H_BUSY 0x40 | 118 | #define BT_H_BUSY 0x40 |
111 | #define BT_B_BUSY 0x80 | 119 | #define BT_B_BUSY 0x80 |
112 | 120 | ||
113 | /* Some bits are toggled on each write: write once to set it, once | 121 | /* |
114 | more to clear it; writing a zero does nothing. To absolutely | 122 | * Some bits are toggled on each write: write once to set it, once |
115 | clear it, check its state and write if set. This avoids the "get | 123 | * more to clear it; writing a zero does nothing. To absolutely |
116 | current then use as mask" scheme to modify one bit. Note that the | 124 | * clear it, check its state and write if set. This avoids the "get |
117 | variable "bt" is hardcoded into these macros. */ | 125 | * current then use as mask" scheme to modify one bit. Note that the |
126 | * variable "bt" is hardcoded into these macros. | ||
127 | */ | ||
118 | 128 | ||
119 | #define BT_STATUS bt->io->inputb(bt->io, 0) | 129 | #define BT_STATUS bt->io->inputb(bt->io, 0) |
120 | #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x) | 130 | #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x) |
@@ -125,8 +135,10 @@ struct si_sm_data { | |||
125 | #define BT_INTMASK_R bt->io->inputb(bt->io, 2) | 135 | #define BT_INTMASK_R bt->io->inputb(bt->io, 2) |
126 | #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x) | 136 | #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x) |
127 | 137 | ||
128 | /* Convenience routines for debugging. These are not multi-open safe! | 138 | /* |
129 | Note the macros have hardcoded variables in them. */ | 139 | * Convenience routines for debugging. These are not multi-open safe! |
140 | * Note the macros have hardcoded variables in them. | ||
141 | */ | ||
130 | 142 | ||
131 | static char *state2txt(unsigned char state) | 143 | static char *state2txt(unsigned char state) |
132 | { | 144 | { |
@@ -182,7 +194,8 @@ static char *status2txt(unsigned char status) | |||
182 | static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io) | 194 | static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io) |
183 | { | 195 | { |
184 | memset(bt, 0, sizeof(struct si_sm_data)); | 196 | memset(bt, 0, sizeof(struct si_sm_data)); |
185 | if (bt->io != io) { /* external: one-time only things */ | 197 | if (bt->io != io) { |
198 | /* external: one-time only things */ | ||
186 | bt->io = io; | 199 | bt->io = io; |
187 | bt->seq = 0; | 200 | bt->seq = 0; |
188 | } | 201 | } |
@@ -229,7 +242,7 @@ static int bt_start_transaction(struct si_sm_data *bt, | |||
229 | printk(KERN_WARNING "BT: +++++++++++++++++ New command\n"); | 242 | printk(KERN_WARNING "BT: +++++++++++++++++ New command\n"); |
230 | printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2); | 243 | printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2); |
231 | for (i = 0; i < size; i ++) | 244 | for (i = 0; i < size; i ++) |
232 | printk (" %02x", data[i]); | 245 | printk(" %02x", data[i]); |
233 | printk("\n"); | 246 | printk("\n"); |
234 | } | 247 | } |
235 | bt->write_data[0] = size + 1; /* all data plus seq byte */ | 248 | bt->write_data[0] = size + 1; /* all data plus seq byte */ |
@@ -246,8 +259,10 @@ static int bt_start_transaction(struct si_sm_data *bt, | |||
246 | return 0; | 259 | return 0; |
247 | } | 260 | } |
248 | 261 | ||
249 | /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE | 262 | /* |
250 | it calls this. Strip out the length and seq bytes. */ | 263 | * After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE |
264 | * it calls this. Strip out the length and seq bytes. | ||
265 | */ | ||
251 | 266 | ||
252 | static int bt_get_result(struct si_sm_data *bt, | 267 | static int bt_get_result(struct si_sm_data *bt, |
253 | unsigned char *data, | 268 | unsigned char *data, |
@@ -269,10 +284,10 @@ static int bt_get_result(struct si_sm_data *bt, | |||
269 | memcpy(data + 2, bt->read_data + 4, msg_len - 2); | 284 | memcpy(data + 2, bt->read_data + 4, msg_len - 2); |
270 | 285 | ||
271 | if (bt_debug & BT_DEBUG_MSG) { | 286 | if (bt_debug & BT_DEBUG_MSG) { |
272 | printk (KERN_WARNING "BT: result %d bytes:", msg_len); | 287 | printk(KERN_WARNING "BT: result %d bytes:", msg_len); |
273 | for (i = 0; i < msg_len; i++) | 288 | for (i = 0; i < msg_len; i++) |
274 | printk(" %02x", data[i]); | 289 | printk(" %02x", data[i]); |
275 | printk ("\n"); | 290 | printk("\n"); |
276 | } | 291 | } |
277 | return msg_len; | 292 | return msg_len; |
278 | } | 293 | } |
@@ -292,8 +307,10 @@ static void reset_flags(struct si_sm_data *bt) | |||
292 | BT_INTMASK_W(BT_BMC_HWRST); | 307 | BT_INTMASK_W(BT_BMC_HWRST); |
293 | } | 308 | } |
294 | 309 | ||
295 | /* Get rid of an unwanted/stale response. This should only be needed for | 310 | /* |
296 | BMCs that support multiple outstanding requests. */ | 311 | * Get rid of an unwanted/stale response. This should only be needed for |
312 | * BMCs that support multiple outstanding requests. | ||
313 | */ | ||
297 | 314 | ||
298 | static void drain_BMC2HOST(struct si_sm_data *bt) | 315 | static void drain_BMC2HOST(struct si_sm_data *bt) |
299 | { | 316 | { |
@@ -326,8 +343,8 @@ static inline void write_all_bytes(struct si_sm_data *bt) | |||
326 | printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", | 343 | printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", |
327 | bt->write_count, bt->seq); | 344 | bt->write_count, bt->seq); |
328 | for (i = 0; i < bt->write_count; i++) | 345 | for (i = 0; i < bt->write_count; i++) |
329 | printk (" %02x", bt->write_data[i]); | 346 | printk(" %02x", bt->write_data[i]); |
330 | printk ("\n"); | 347 | printk("\n"); |
331 | } | 348 | } |
332 | for (i = 0; i < bt->write_count; i++) | 349 | for (i = 0; i < bt->write_count; i++) |
333 | HOST2BMC(bt->write_data[i]); | 350 | HOST2BMC(bt->write_data[i]); |
@@ -337,8 +354,10 @@ static inline int read_all_bytes(struct si_sm_data *bt) | |||
337 | { | 354 | { |
338 | unsigned char i; | 355 | unsigned char i; |
339 | 356 | ||
340 | /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode. | 357 | /* |
341 | Keep layout of first four bytes aligned with write_data[] */ | 358 | * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode. |
359 | * Keep layout of first four bytes aligned with write_data[] | ||
360 | */ | ||
342 | 361 | ||
343 | bt->read_data[0] = BMC2HOST; | 362 | bt->read_data[0] = BMC2HOST; |
344 | bt->read_count = bt->read_data[0]; | 363 | bt->read_count = bt->read_data[0]; |
@@ -362,8 +381,8 @@ static inline int read_all_bytes(struct si_sm_data *bt) | |||
362 | if (max > 16) | 381 | if (max > 16) |
363 | max = 16; | 382 | max = 16; |
364 | for (i = 0; i < max; i++) | 383 | for (i = 0; i < max; i++) |
365 | printk (" %02x", bt->read_data[i]); | 384 | printk(KERN_CONT " %02x", bt->read_data[i]); |
366 | printk ("%s\n", bt->read_count == max ? "" : " ..."); | 385 | printk(KERN_CONT "%s\n", bt->read_count == max ? "" : " ..."); |
367 | } | 386 | } |
368 | 387 | ||
369 | /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */ | 388 | /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */ |
@@ -402,8 +421,10 @@ static enum si_sm_result error_recovery(struct si_sm_data *bt, | |||
402 | printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */ | 421 | printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */ |
403 | reason, STATE2TXT, STATUS2TXT); | 422 | reason, STATE2TXT, STATUS2TXT); |
404 | 423 | ||
405 | /* Per the IPMI spec, retries are based on the sequence number | 424 | /* |
406 | known only to this module, so manage a restart here. */ | 425 | * Per the IPMI spec, retries are based on the sequence number |
426 | * known only to this module, so manage a restart here. | ||
427 | */ | ||
407 | (bt->error_retries)++; | 428 | (bt->error_retries)++; |
408 | if (bt->error_retries < bt->BT_CAP_retries) { | 429 | if (bt->error_retries < bt->BT_CAP_retries) { |
409 | printk("%d retries left\n", | 430 | printk("%d retries left\n", |
@@ -412,8 +433,8 @@ static enum si_sm_result error_recovery(struct si_sm_data *bt, | |||
412 | return SI_SM_CALL_WITHOUT_DELAY; | 433 | return SI_SM_CALL_WITHOUT_DELAY; |
413 | } | 434 | } |
414 | 435 | ||
415 | printk("failed %d retries, sending error response\n", | 436 | printk(KERN_WARNING "failed %d retries, sending error response\n", |
416 | bt->BT_CAP_retries); | 437 | bt->BT_CAP_retries); |
417 | if (!bt->nonzero_status) | 438 | if (!bt->nonzero_status) |
418 | printk(KERN_ERR "IPMI BT: stuck, try power cycle\n"); | 439 | printk(KERN_ERR "IPMI BT: stuck, try power cycle\n"); |
419 | 440 | ||
@@ -424,8 +445,10 @@ static enum si_sm_result error_recovery(struct si_sm_data *bt, | |||
424 | return SI_SM_CALL_WITHOUT_DELAY; | 445 | return SI_SM_CALL_WITHOUT_DELAY; |
425 | } | 446 | } |
426 | 447 | ||
427 | /* Concoct a useful error message, set up the next state, and | 448 | /* |
428 | be done with this sequence. */ | 449 | * Concoct a useful error message, set up the next state, and |
450 | * be done with this sequence. | ||
451 | */ | ||
429 | 452 | ||
430 | bt->state = BT_STATE_IDLE; | 453 | bt->state = BT_STATE_IDLE; |
431 | switch (cCode) { | 454 | switch (cCode) { |
@@ -461,10 +484,12 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
461 | last_printed = bt->state; | 484 | last_printed = bt->state; |
462 | } | 485 | } |
463 | 486 | ||
464 | /* Commands that time out may still (eventually) provide a response. | 487 | /* |
465 | This stale response will get in the way of a new response so remove | 488 | * Commands that time out may still (eventually) provide a response. |
466 | it if possible (hopefully during IDLE). Even if it comes up later | 489 | * This stale response will get in the way of a new response so remove |
467 | it will be rejected by its (now-forgotten) seq number. */ | 490 | * it if possible (hopefully during IDLE). Even if it comes up later |
491 | * it will be rejected by its (now-forgotten) seq number. | ||
492 | */ | ||
468 | 493 | ||
469 | if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) { | 494 | if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) { |
470 | drain_BMC2HOST(bt); | 495 | drain_BMC2HOST(bt); |
@@ -472,7 +497,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
472 | } | 497 | } |
473 | 498 | ||
474 | if ((bt->state != BT_STATE_IDLE) && | 499 | if ((bt->state != BT_STATE_IDLE) && |
475 | (bt->state < BT_STATE_PRINTME)) { /* check timeout */ | 500 | (bt->state < BT_STATE_PRINTME)) { |
501 | /* check timeout */ | ||
476 | bt->timeout -= time; | 502 | bt->timeout -= time; |
477 | if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) | 503 | if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) |
478 | return error_recovery(bt, | 504 | return error_recovery(bt, |
@@ -482,8 +508,10 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
482 | 508 | ||
483 | switch (bt->state) { | 509 | switch (bt->state) { |
484 | 510 | ||
485 | /* Idle state first checks for asynchronous messages from another | 511 | /* |
486 | channel, then does some opportunistic housekeeping. */ | 512 | * Idle state first checks for asynchronous messages from another |
513 | * channel, then does some opportunistic housekeeping. | ||
514 | */ | ||
487 | 515 | ||
488 | case BT_STATE_IDLE: | 516 | case BT_STATE_IDLE: |
489 | if (status & BT_SMS_ATN) { | 517 | if (status & BT_SMS_ATN) { |
@@ -531,16 +559,19 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
531 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); | 559 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); |
532 | BT_CONTROL(BT_H_BUSY); /* set */ | 560 | BT_CONTROL(BT_H_BUSY); /* set */ |
533 | 561 | ||
534 | /* Uncached, ordered writes should just proceeed serially but | 562 | /* |
535 | some BMCs don't clear B2H_ATN with one hit. Fast-path a | 563 | * Uncached, ordered writes should just proceeed serially but |
536 | workaround without too much penalty to the general case. */ | 564 | * some BMCs don't clear B2H_ATN with one hit. Fast-path a |
565 | * workaround without too much penalty to the general case. | ||
566 | */ | ||
537 | 567 | ||
538 | BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */ | 568 | BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */ |
539 | BT_STATE_CHANGE(BT_STATE_CLEAR_B2H, | 569 | BT_STATE_CHANGE(BT_STATE_CLEAR_B2H, |
540 | SI_SM_CALL_WITHOUT_DELAY); | 570 | SI_SM_CALL_WITHOUT_DELAY); |
541 | 571 | ||
542 | case BT_STATE_CLEAR_B2H: | 572 | case BT_STATE_CLEAR_B2H: |
543 | if (status & BT_B2H_ATN) { /* keep hitting it */ | 573 | if (status & BT_B2H_ATN) { |
574 | /* keep hitting it */ | ||
544 | BT_CONTROL(BT_B2H_ATN); | 575 | BT_CONTROL(BT_B2H_ATN); |
545 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); | 576 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); |
546 | } | 577 | } |
@@ -548,7 +579,8 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
548 | SI_SM_CALL_WITHOUT_DELAY); | 579 | SI_SM_CALL_WITHOUT_DELAY); |
549 | 580 | ||
550 | case BT_STATE_READ_BYTES: | 581 | case BT_STATE_READ_BYTES: |
551 | if (!(status & BT_H_BUSY)) /* check in case of retry */ | 582 | if (!(status & BT_H_BUSY)) |
583 | /* check in case of retry */ | ||
552 | BT_CONTROL(BT_H_BUSY); | 584 | BT_CONTROL(BT_H_BUSY); |
553 | BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */ | 585 | BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */ |
554 | i = read_all_bytes(bt); /* true == packet seq match */ | 586 | i = read_all_bytes(bt); /* true == packet seq match */ |
@@ -599,8 +631,10 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
599 | BT_STATE_CHANGE(BT_STATE_XACTION_START, | 631 | BT_STATE_CHANGE(BT_STATE_XACTION_START, |
600 | SI_SM_CALL_WITH_DELAY); | 632 | SI_SM_CALL_WITH_DELAY); |
601 | 633 | ||
602 | /* Get BT Capabilities, using timing of upper level state machine. | 634 | /* |
603 | Set outreqs to prevent infinite loop on timeout. */ | 635 | * Get BT Capabilities, using timing of upper level state machine. |
636 | * Set outreqs to prevent infinite loop on timeout. | ||
637 | */ | ||
604 | case BT_STATE_CAPABILITIES_BEGIN: | 638 | case BT_STATE_CAPABILITIES_BEGIN: |
605 | bt->BT_CAP_outreqs = 1; | 639 | bt->BT_CAP_outreqs = 1; |
606 | { | 640 | { |
@@ -638,10 +672,12 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
638 | 672 | ||
639 | static int bt_detect(struct si_sm_data *bt) | 673 | static int bt_detect(struct si_sm_data *bt) |
640 | { | 674 | { |
641 | /* It's impossible for the BT status and interrupt registers to be | 675 | /* |
642 | all 1's, (assuming a properly functioning, self-initialized BMC) | 676 | * It's impossible for the BT status and interrupt registers to be |
643 | but that's what you get from reading a bogus address, so we | 677 | * all 1's, (assuming a properly functioning, self-initialized BMC) |
644 | test that first. The calling routine uses negative logic. */ | 678 | * but that's what you get from reading a bogus address, so we |
679 | * test that first. The calling routine uses negative logic. | ||
680 | */ | ||
645 | 681 | ||
646 | if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) | 682 | if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) |
647 | return 1; | 683 | return 1; |
@@ -658,8 +694,7 @@ static int bt_size(void) | |||
658 | return sizeof(struct si_sm_data); | 694 | return sizeof(struct si_sm_data); |
659 | } | 695 | } |
660 | 696 | ||
661 | struct si_sm_handlers bt_smi_handlers = | 697 | struct si_sm_handlers bt_smi_handlers = { |
662 | { | ||
663 | .init_data = bt_init_data, | 698 | .init_data = bt_init_data, |
664 | .start_transaction = bt_start_transaction, | 699 | .start_transaction = bt_start_transaction, |
665 | .get_result = bt_get_result, | 700 | .get_result = bt_get_result, |
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index c1b8228cb7b6..80704875794c 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c | |||
@@ -60,37 +60,58 @@ MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); | |||
60 | 60 | ||
61 | /* The states the KCS driver may be in. */ | 61 | /* The states the KCS driver may be in. */ |
62 | enum kcs_states { | 62 | enum kcs_states { |
63 | KCS_IDLE, /* The KCS interface is currently | 63 | /* The KCS interface is currently doing nothing. */ |
64 | doing nothing. */ | 64 | KCS_IDLE, |
65 | KCS_START_OP, /* We are starting an operation. The | 65 | |
66 | data is in the output buffer, but | 66 | /* |
67 | nothing has been done to the | 67 | * We are starting an operation. The data is in the output |
68 | interface yet. This was added to | 68 | * buffer, but nothing has been done to the interface yet. This |
69 | the state machine in the spec to | 69 | * was added to the state machine in the spec to wait for the |
70 | wait for the initial IBF. */ | 70 | * initial IBF. |
71 | KCS_WAIT_WRITE_START, /* We have written a write cmd to the | 71 | */ |
72 | interface. */ | 72 | KCS_START_OP, |
73 | KCS_WAIT_WRITE, /* We are writing bytes to the | 73 | |
74 | interface. */ | 74 | /* We have written a write cmd to the interface. */ |
75 | KCS_WAIT_WRITE_END, /* We have written the write end cmd | 75 | KCS_WAIT_WRITE_START, |
76 | to the interface, and still need to | 76 | |
77 | write the last byte. */ | 77 | /* We are writing bytes to the interface. */ |
78 | KCS_WAIT_READ, /* We are waiting to read data from | 78 | KCS_WAIT_WRITE, |
79 | the interface. */ | 79 | |
80 | KCS_ERROR0, /* State to transition to the error | 80 | /* |
81 | handler, this was added to the | 81 | * We have written the write end cmd to the interface, and |
82 | state machine in the spec to be | 82 | * still need to write the last byte. |
83 | sure IBF was there. */ | 83 | */ |
84 | KCS_ERROR1, /* First stage error handler, wait for | 84 | KCS_WAIT_WRITE_END, |
85 | the interface to respond. */ | 85 | |
86 | KCS_ERROR2, /* The abort cmd has been written, | 86 | /* We are waiting to read data from the interface. */ |
87 | wait for the interface to | 87 | KCS_WAIT_READ, |
88 | respond. */ | 88 | |
89 | KCS_ERROR3, /* We wrote some data to the | 89 | /* |
90 | interface, wait for it to switch to | 90 | * State to transition to the error handler, this was added to |
91 | read mode. */ | 91 | * the state machine in the spec to be sure IBF was there. |
92 | KCS_HOSED /* The hardware failed to follow the | 92 | */ |
93 | state machine. */ | 93 | KCS_ERROR0, |
94 | |||
95 | /* | ||
96 | * First stage error handler, wait for the interface to | ||
97 | * respond. | ||
98 | */ | ||
99 | KCS_ERROR1, | ||
100 | |||
101 | /* | ||
102 | * The abort cmd has been written, wait for the interface to | ||
103 | * respond. | ||
104 | */ | ||
105 | KCS_ERROR2, | ||
106 | |||
107 | /* | ||
108 | * We wrote some data to the interface, wait for it to switch | ||
109 | * to read mode. | ||
110 | */ | ||
111 | KCS_ERROR3, | ||
112 | |||
113 | /* The hardware failed to follow the state machine. */ | ||
114 | KCS_HOSED | ||
94 | }; | 115 | }; |
95 | 116 | ||
96 | #define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH | 117 | #define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH |
@@ -102,8 +123,7 @@ enum kcs_states { | |||
102 | #define MAX_ERROR_RETRIES 10 | 123 | #define MAX_ERROR_RETRIES 10 |
103 | #define ERROR0_OBF_WAIT_JIFFIES (2*HZ) | 124 | #define ERROR0_OBF_WAIT_JIFFIES (2*HZ) |
104 | 125 | ||
105 | struct si_sm_data | 126 | struct si_sm_data { |
106 | { | ||
107 | enum kcs_states state; | 127 | enum kcs_states state; |
108 | struct si_sm_io *io; | 128 | struct si_sm_io *io; |
109 | unsigned char write_data[MAX_KCS_WRITE_SIZE]; | 129 | unsigned char write_data[MAX_KCS_WRITE_SIZE]; |
@@ -187,7 +207,8 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason) | |||
187 | (kcs->error_retries)++; | 207 | (kcs->error_retries)++; |
188 | if (kcs->error_retries > MAX_ERROR_RETRIES) { | 208 | if (kcs->error_retries > MAX_ERROR_RETRIES) { |
189 | if (kcs_debug & KCS_DEBUG_ENABLE) | 209 | if (kcs_debug & KCS_DEBUG_ENABLE) |
190 | printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason); | 210 | printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", |
211 | reason); | ||
191 | kcs->state = KCS_HOSED; | 212 | kcs->state = KCS_HOSED; |
192 | } else { | 213 | } else { |
193 | kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES; | 214 | kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES; |
@@ -271,10 +292,9 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, | |||
271 | 292 | ||
272 | if (kcs_debug & KCS_DEBUG_MSG) { | 293 | if (kcs_debug & KCS_DEBUG_MSG) { |
273 | printk(KERN_DEBUG "start_kcs_transaction -"); | 294 | printk(KERN_DEBUG "start_kcs_transaction -"); |
274 | for (i = 0; i < size; i ++) { | 295 | for (i = 0; i < size; i++) |
275 | printk(" %02x", (unsigned char) (data [i])); | 296 | printk(" %02x", (unsigned char) (data [i])); |
276 | } | 297 | printk("\n"); |
277 | printk ("\n"); | ||
278 | } | 298 | } |
279 | kcs->error_retries = 0; | 299 | kcs->error_retries = 0; |
280 | memcpy(kcs->write_data, data, size); | 300 | memcpy(kcs->write_data, data, size); |
@@ -305,9 +325,11 @@ static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data, | |||
305 | kcs->read_pos = 3; | 325 | kcs->read_pos = 3; |
306 | } | 326 | } |
307 | if (kcs->truncated) { | 327 | if (kcs->truncated) { |
308 | /* Report a truncated error. We might overwrite | 328 | /* |
309 | another error, but that's too bad, the user needs | 329 | * Report a truncated error. We might overwrite |
310 | to know it was truncated. */ | 330 | * another error, but that's too bad, the user needs |
331 | * to know it was truncated. | ||
332 | */ | ||
311 | data[2] = IPMI_ERR_MSG_TRUNCATED; | 333 | data[2] = IPMI_ERR_MSG_TRUNCATED; |
312 | kcs->truncated = 0; | 334 | kcs->truncated = 0; |
313 | } | 335 | } |
@@ -315,9 +337,11 @@ static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data, | |||
315 | return kcs->read_pos; | 337 | return kcs->read_pos; |
316 | } | 338 | } |
317 | 339 | ||
318 | /* This implements the state machine defined in the IPMI manual, see | 340 | /* |
319 | that for details on how this works. Divide that flowchart into | 341 | * This implements the state machine defined in the IPMI manual, see |
320 | sections delimited by "Wait for IBF" and this will become clear. */ | 342 | * that for details on how this works. Divide that flowchart into |
343 | * sections delimited by "Wait for IBF" and this will become clear. | ||
344 | */ | ||
321 | static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | 345 | static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) |
322 | { | 346 | { |
323 | unsigned char status; | 347 | unsigned char status; |
@@ -388,11 +412,12 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
388 | write_next_byte(kcs); | 412 | write_next_byte(kcs); |
389 | } | 413 | } |
390 | break; | 414 | break; |
391 | 415 | ||
392 | case KCS_WAIT_WRITE_END: | 416 | case KCS_WAIT_WRITE_END: |
393 | if (state != KCS_WRITE_STATE) { | 417 | if (state != KCS_WRITE_STATE) { |
394 | start_error_recovery(kcs, | 418 | start_error_recovery(kcs, |
395 | "Not in write state for write end"); | 419 | "Not in write state" |
420 | " for write end"); | ||
396 | break; | 421 | break; |
397 | } | 422 | } |
398 | clear_obf(kcs, status); | 423 | clear_obf(kcs, status); |
@@ -413,13 +438,15 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
413 | return SI_SM_CALL_WITH_DELAY; | 438 | return SI_SM_CALL_WITH_DELAY; |
414 | read_next_byte(kcs); | 439 | read_next_byte(kcs); |
415 | } else { | 440 | } else { |
416 | /* We don't implement this exactly like the state | 441 | /* |
417 | machine in the spec. Some broken hardware | 442 | * We don't implement this exactly like the state |
418 | does not write the final dummy byte to the | 443 | * machine in the spec. Some broken hardware |
419 | read register. Thus obf will never go high | 444 | * does not write the final dummy byte to the |
420 | here. We just go straight to idle, and we | 445 | * read register. Thus obf will never go high |
421 | handle clearing out obf in idle state if it | 446 | * here. We just go straight to idle, and we |
422 | happens to come in. */ | 447 | * handle clearing out obf in idle state if it |
448 | * happens to come in. | ||
449 | */ | ||
423 | clear_obf(kcs, status); | 450 | clear_obf(kcs, status); |
424 | kcs->orig_write_count = 0; | 451 | kcs->orig_write_count = 0; |
425 | kcs->state = KCS_IDLE; | 452 | kcs->state = KCS_IDLE; |
@@ -430,7 +457,8 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
430 | case KCS_ERROR0: | 457 | case KCS_ERROR0: |
431 | clear_obf(kcs, status); | 458 | clear_obf(kcs, status); |
432 | status = read_status(kcs); | 459 | status = read_status(kcs); |
433 | if (GET_STATUS_OBF(status)) /* controller isn't responding */ | 460 | if (GET_STATUS_OBF(status)) |
461 | /* controller isn't responding */ | ||
434 | if (time_before(jiffies, kcs->error0_timeout)) | 462 | if (time_before(jiffies, kcs->error0_timeout)) |
435 | return SI_SM_CALL_WITH_TICK_DELAY; | 463 | return SI_SM_CALL_WITH_TICK_DELAY; |
436 | write_cmd(kcs, KCS_GET_STATUS_ABORT); | 464 | write_cmd(kcs, KCS_GET_STATUS_ABORT); |
@@ -442,7 +470,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
442 | write_data(kcs, 0); | 470 | write_data(kcs, 0); |
443 | kcs->state = KCS_ERROR2; | 471 | kcs->state = KCS_ERROR2; |
444 | break; | 472 | break; |
445 | 473 | ||
446 | case KCS_ERROR2: | 474 | case KCS_ERROR2: |
447 | if (state != KCS_READ_STATE) { | 475 | if (state != KCS_READ_STATE) { |
448 | start_error_recovery(kcs, | 476 | start_error_recovery(kcs, |
@@ -456,7 +484,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
456 | write_data(kcs, KCS_READ_BYTE); | 484 | write_data(kcs, KCS_READ_BYTE); |
457 | kcs->state = KCS_ERROR3; | 485 | kcs->state = KCS_ERROR3; |
458 | break; | 486 | break; |
459 | 487 | ||
460 | case KCS_ERROR3: | 488 | case KCS_ERROR3: |
461 | if (state != KCS_IDLE_STATE) { | 489 | if (state != KCS_IDLE_STATE) { |
462 | start_error_recovery(kcs, | 490 | start_error_recovery(kcs, |
@@ -475,7 +503,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
475 | return SI_SM_TRANSACTION_COMPLETE; | 503 | return SI_SM_TRANSACTION_COMPLETE; |
476 | } | 504 | } |
477 | break; | 505 | break; |
478 | 506 | ||
479 | case KCS_HOSED: | 507 | case KCS_HOSED: |
480 | break; | 508 | break; |
481 | } | 509 | } |
@@ -495,10 +523,12 @@ static int kcs_size(void) | |||
495 | 523 | ||
496 | static int kcs_detect(struct si_sm_data *kcs) | 524 | static int kcs_detect(struct si_sm_data *kcs) |
497 | { | 525 | { |
498 | /* It's impossible for the KCS status register to be all 1's, | 526 | /* |
499 | (assuming a properly functioning, self-initialized BMC) | 527 | * It's impossible for the KCS status register to be all 1's, |
500 | but that's what you get from reading a bogus address, so we | 528 | * (assuming a properly functioning, self-initialized BMC) |
501 | test that first. */ | 529 | * but that's what you get from reading a bogus address, so we |
530 | * test that first. | ||
531 | */ | ||
502 | if (read_status(kcs) == 0xff) | 532 | if (read_status(kcs) == 0xff) |
503 | return 1; | 533 | return 1; |
504 | 534 | ||
@@ -509,8 +539,7 @@ static void kcs_cleanup(struct si_sm_data *kcs) | |||
509 | { | 539 | { |
510 | } | 540 | } |
511 | 541 | ||
512 | struct si_sm_handlers kcs_smi_handlers = | 542 | struct si_sm_handlers kcs_smi_handlers = { |
513 | { | ||
514 | .init_data = init_kcs_data, | 543 | .init_data = init_kcs_data, |
515 | .start_transaction = start_kcs_transaction, | 544 | .start_transaction = start_kcs_transaction, |
516 | .get_result = get_kcs_result, | 545 | .get_result = get_kcs_result, |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 32b2b22996dc..8a59aaa21be5 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | #define PFX "IPMI message handler: " | 48 | #define PFX "IPMI message handler: " |
49 | 49 | ||
50 | #define IPMI_DRIVER_VERSION "39.1" | 50 | #define IPMI_DRIVER_VERSION "39.2" |
51 | 51 | ||
52 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); | 52 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); |
53 | static int ipmi_init_msghandler(void); | 53 | static int ipmi_init_msghandler(void); |
@@ -63,16 +63,16 @@ static struct proc_dir_entry *proc_ipmi_root; | |||
63 | 63 | ||
64 | #define MAX_EVENTS_IN_QUEUE 25 | 64 | #define MAX_EVENTS_IN_QUEUE 25 |
65 | 65 | ||
66 | /* Don't let a message sit in a queue forever, always time it with at lest | 66 | /* |
67 | the max message timer. This is in milliseconds. */ | 67 | * Don't let a message sit in a queue forever, always time it with at lest |
68 | * the max message timer. This is in milliseconds. | ||
69 | */ | ||
68 | #define MAX_MSG_TIMEOUT 60000 | 70 | #define MAX_MSG_TIMEOUT 60000 |
69 | 71 | ||
70 | |||
71 | /* | 72 | /* |
72 | * The main "user" data structure. | 73 | * The main "user" data structure. |
73 | */ | 74 | */ |
74 | struct ipmi_user | 75 | struct ipmi_user { |
75 | { | ||
76 | struct list_head link; | 76 | struct list_head link; |
77 | 77 | ||
78 | /* Set to "0" when the user is destroyed. */ | 78 | /* Set to "0" when the user is destroyed. */ |
@@ -91,8 +91,7 @@ struct ipmi_user | |||
91 | int gets_events; | 91 | int gets_events; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | struct cmd_rcvr | 94 | struct cmd_rcvr { |
95 | { | ||
96 | struct list_head link; | 95 | struct list_head link; |
97 | 96 | ||
98 | ipmi_user_t user; | 97 | ipmi_user_t user; |
@@ -106,12 +105,12 @@ struct cmd_rcvr | |||
106 | * or change any data until the RCU period completes. So we | 105 | * or change any data until the RCU period completes. So we |
107 | * use this next variable during mass deletion so we can have | 106 | * use this next variable during mass deletion so we can have |
108 | * a list and don't have to wait and restart the search on | 107 | * a list and don't have to wait and restart the search on |
109 | * every individual deletion of a command. */ | 108 | * every individual deletion of a command. |
109 | */ | ||
110 | struct cmd_rcvr *next; | 110 | struct cmd_rcvr *next; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | struct seq_table | 113 | struct seq_table { |
114 | { | ||
115 | unsigned int inuse : 1; | 114 | unsigned int inuse : 1; |
116 | unsigned int broadcast : 1; | 115 | unsigned int broadcast : 1; |
117 | 116 | ||
@@ -119,53 +118,60 @@ struct seq_table | |||
119 | unsigned long orig_timeout; | 118 | unsigned long orig_timeout; |
120 | unsigned int retries_left; | 119 | unsigned int retries_left; |
121 | 120 | ||
122 | /* To verify on an incoming send message response that this is | 121 | /* |
123 | the message that the response is for, we keep a sequence id | 122 | * To verify on an incoming send message response that this is |
124 | and increment it every time we send a message. */ | 123 | * the message that the response is for, we keep a sequence id |
124 | * and increment it every time we send a message. | ||
125 | */ | ||
125 | long seqid; | 126 | long seqid; |
126 | 127 | ||
127 | /* This is held so we can properly respond to the message on a | 128 | /* |
128 | timeout, and it is used to hold the temporary data for | 129 | * This is held so we can properly respond to the message on a |
129 | retransmission, too. */ | 130 | * timeout, and it is used to hold the temporary data for |
131 | * retransmission, too. | ||
132 | */ | ||
130 | struct ipmi_recv_msg *recv_msg; | 133 | struct ipmi_recv_msg *recv_msg; |
131 | }; | 134 | }; |
132 | 135 | ||
133 | /* Store the information in a msgid (long) to allow us to find a | 136 | /* |
134 | sequence table entry from the msgid. */ | 137 | * Store the information in a msgid (long) to allow us to find a |
138 | * sequence table entry from the msgid. | ||
139 | */ | ||
135 | #define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff)) | 140 | #define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff)) |
136 | 141 | ||
137 | #define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \ | 142 | #define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \ |
138 | do { \ | 143 | do { \ |
139 | seq = ((msgid >> 26) & 0x3f); \ | 144 | seq = ((msgid >> 26) & 0x3f); \ |
140 | seqid = (msgid & 0x3fffff); \ | 145 | seqid = (msgid & 0x3fffff); \ |
141 | } while (0) | 146 | } while (0) |
142 | 147 | ||
143 | #define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff) | 148 | #define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff) |
144 | 149 | ||
145 | struct ipmi_channel | 150 | struct ipmi_channel { |
146 | { | ||
147 | unsigned char medium; | 151 | unsigned char medium; |
148 | unsigned char protocol; | 152 | unsigned char protocol; |
149 | 153 | ||
150 | /* My slave address. This is initialized to IPMI_BMC_SLAVE_ADDR, | 154 | /* |
151 | but may be changed by the user. */ | 155 | * My slave address. This is initialized to IPMI_BMC_SLAVE_ADDR, |
156 | * but may be changed by the user. | ||
157 | */ | ||
152 | unsigned char address; | 158 | unsigned char address; |
153 | 159 | ||
154 | /* My LUN. This should generally stay the SMS LUN, but just in | 160 | /* |
155 | case... */ | 161 | * My LUN. This should generally stay the SMS LUN, but just in |
162 | * case... | ||
163 | */ | ||
156 | unsigned char lun; | 164 | unsigned char lun; |
157 | }; | 165 | }; |
158 | 166 | ||
159 | #ifdef CONFIG_PROC_FS | 167 | #ifdef CONFIG_PROC_FS |
160 | struct ipmi_proc_entry | 168 | struct ipmi_proc_entry { |
161 | { | ||
162 | char *name; | 169 | char *name; |
163 | struct ipmi_proc_entry *next; | 170 | struct ipmi_proc_entry *next; |
164 | }; | 171 | }; |
165 | #endif | 172 | #endif |
166 | 173 | ||
167 | struct bmc_device | 174 | struct bmc_device { |
168 | { | ||
169 | struct platform_device *dev; | 175 | struct platform_device *dev; |
170 | struct ipmi_device_id id; | 176 | struct ipmi_device_id id; |
171 | unsigned char guid[16]; | 177 | unsigned char guid[16]; |
@@ -186,10 +192,108 @@ struct bmc_device | |||
186 | struct device_attribute aux_firmware_rev_attr; | 192 | struct device_attribute aux_firmware_rev_attr; |
187 | }; | 193 | }; |
188 | 194 | ||
195 | /* | ||
196 | * Various statistics for IPMI, these index stats[] in the ipmi_smi | ||
197 | * structure. | ||
198 | */ | ||
199 | enum ipmi_stat_indexes { | ||
200 | /* Commands we got from the user that were invalid. */ | ||
201 | IPMI_STAT_sent_invalid_commands = 0, | ||
202 | |||
203 | /* Commands we sent to the MC. */ | ||
204 | IPMI_STAT_sent_local_commands, | ||
205 | |||
206 | /* Responses from the MC that were delivered to a user. */ | ||
207 | IPMI_STAT_handled_local_responses, | ||
208 | |||
209 | /* Responses from the MC that were not delivered to a user. */ | ||
210 | IPMI_STAT_unhandled_local_responses, | ||
211 | |||
212 | /* Commands we sent out to the IPMB bus. */ | ||
213 | IPMI_STAT_sent_ipmb_commands, | ||
214 | |||
215 | /* Commands sent on the IPMB that had errors on the SEND CMD */ | ||
216 | IPMI_STAT_sent_ipmb_command_errs, | ||
217 | |||
218 | /* Each retransmit increments this count. */ | ||
219 | IPMI_STAT_retransmitted_ipmb_commands, | ||
220 | |||
221 | /* | ||
222 | * When a message times out (runs out of retransmits) this is | ||
223 | * incremented. | ||
224 | */ | ||
225 | IPMI_STAT_timed_out_ipmb_commands, | ||
226 | |||
227 | /* | ||
228 | * This is like above, but for broadcasts. Broadcasts are | ||
229 | * *not* included in the above count (they are expected to | ||
230 | * time out). | ||
231 | */ | ||
232 | IPMI_STAT_timed_out_ipmb_broadcasts, | ||
233 | |||
234 | /* Responses I have sent to the IPMB bus. */ | ||
235 | IPMI_STAT_sent_ipmb_responses, | ||
236 | |||
237 | /* The response was delivered to the user. */ | ||
238 | IPMI_STAT_handled_ipmb_responses, | ||
239 | |||
240 | /* The response had invalid data in it. */ | ||
241 | IPMI_STAT_invalid_ipmb_responses, | ||
242 | |||
243 | /* The response didn't have anyone waiting for it. */ | ||
244 | IPMI_STAT_unhandled_ipmb_responses, | ||
245 | |||
246 | /* Commands we sent out to the IPMB bus. */ | ||
247 | IPMI_STAT_sent_lan_commands, | ||
248 | |||
249 | /* Commands sent on the IPMB that had errors on the SEND CMD */ | ||
250 | IPMI_STAT_sent_lan_command_errs, | ||
251 | |||
252 | /* Each retransmit increments this count. */ | ||
253 | IPMI_STAT_retransmitted_lan_commands, | ||
254 | |||
255 | /* | ||
256 | * When a message times out (runs out of retransmits) this is | ||
257 | * incremented. | ||
258 | */ | ||
259 | IPMI_STAT_timed_out_lan_commands, | ||
260 | |||
261 | /* Responses I have sent to the IPMB bus. */ | ||
262 | IPMI_STAT_sent_lan_responses, | ||
263 | |||
264 | /* The response was delivered to the user. */ | ||
265 | IPMI_STAT_handled_lan_responses, | ||
266 | |||
267 | /* The response had invalid data in it. */ | ||
268 | IPMI_STAT_invalid_lan_responses, | ||
269 | |||
270 | /* The response didn't have anyone waiting for it. */ | ||
271 | IPMI_STAT_unhandled_lan_responses, | ||
272 | |||
273 | /* The command was delivered to the user. */ | ||
274 | IPMI_STAT_handled_commands, | ||
275 | |||
276 | /* The command had invalid data in it. */ | ||
277 | IPMI_STAT_invalid_commands, | ||
278 | |||
279 | /* The command didn't have anyone waiting for it. */ | ||
280 | IPMI_STAT_unhandled_commands, | ||
281 | |||
282 | /* Invalid data in an event. */ | ||
283 | IPMI_STAT_invalid_events, | ||
284 | |||
285 | /* Events that were received with the proper format. */ | ||
286 | IPMI_STAT_events, | ||
287 | |||
288 | |||
289 | /* This *must* remain last, add new values above this. */ | ||
290 | IPMI_NUM_STATS | ||
291 | }; | ||
292 | |||
293 | |||
189 | #define IPMI_IPMB_NUM_SEQ 64 | 294 | #define IPMI_IPMB_NUM_SEQ 64 |
190 | #define IPMI_MAX_CHANNELS 16 | 295 | #define IPMI_MAX_CHANNELS 16 |
191 | struct ipmi_smi | 296 | struct ipmi_smi { |
192 | { | ||
193 | /* What interface number are we? */ | 297 | /* What interface number are we? */ |
194 | int intf_num; | 298 | int intf_num; |
195 | 299 | ||
@@ -198,8 +302,10 @@ struct ipmi_smi | |||
198 | /* Used for a list of interfaces. */ | 302 | /* Used for a list of interfaces. */ |
199 | struct list_head link; | 303 | struct list_head link; |
200 | 304 | ||
201 | /* The list of upper layers that are using me. seq_lock | 305 | /* |
202 | * protects this. */ | 306 | * The list of upper layers that are using me. seq_lock |
307 | * protects this. | ||
308 | */ | ||
203 | struct list_head users; | 309 | struct list_head users; |
204 | 310 | ||
205 | /* Information to supply to users. */ | 311 | /* Information to supply to users. */ |
@@ -213,10 +319,12 @@ struct ipmi_smi | |||
213 | char *my_dev_name; | 319 | char *my_dev_name; |
214 | char *sysfs_name; | 320 | char *sysfs_name; |
215 | 321 | ||
216 | /* This is the lower-layer's sender routine. Note that you | 322 | /* |
323 | * This is the lower-layer's sender routine. Note that you | ||
217 | * must either be holding the ipmi_interfaces_mutex or be in | 324 | * must either be holding the ipmi_interfaces_mutex or be in |
218 | * an umpreemptible region to use this. You must fetch the | 325 | * an umpreemptible region to use this. You must fetch the |
219 | * value into a local variable and make sure it is not NULL. */ | 326 | * value into a local variable and make sure it is not NULL. |
327 | */ | ||
220 | struct ipmi_smi_handlers *handlers; | 328 | struct ipmi_smi_handlers *handlers; |
221 | void *send_info; | 329 | void *send_info; |
222 | 330 | ||
@@ -229,34 +337,45 @@ struct ipmi_smi | |||
229 | /* Driver-model device for the system interface. */ | 337 | /* Driver-model device for the system interface. */ |
230 | struct device *si_dev; | 338 | struct device *si_dev; |
231 | 339 | ||
232 | /* A table of sequence numbers for this interface. We use the | 340 | /* |
233 | sequence numbers for IPMB messages that go out of the | 341 | * A table of sequence numbers for this interface. We use the |
234 | interface to match them up with their responses. A routine | 342 | * sequence numbers for IPMB messages that go out of the |
235 | is called periodically to time the items in this list. */ | 343 | * interface to match them up with their responses. A routine |
344 | * is called periodically to time the items in this list. | ||
345 | */ | ||
236 | spinlock_t seq_lock; | 346 | spinlock_t seq_lock; |
237 | struct seq_table seq_table[IPMI_IPMB_NUM_SEQ]; | 347 | struct seq_table seq_table[IPMI_IPMB_NUM_SEQ]; |
238 | int curr_seq; | 348 | int curr_seq; |
239 | 349 | ||
240 | /* Messages that were delayed for some reason (out of memory, | 350 | /* |
241 | for instance), will go in here to be processed later in a | 351 | * Messages that were delayed for some reason (out of memory, |
242 | periodic timer interrupt. */ | 352 | * for instance), will go in here to be processed later in a |
353 | * periodic timer interrupt. | ||
354 | */ | ||
243 | spinlock_t waiting_msgs_lock; | 355 | spinlock_t waiting_msgs_lock; |
244 | struct list_head waiting_msgs; | 356 | struct list_head waiting_msgs; |
245 | 357 | ||
246 | /* The list of command receivers that are registered for commands | 358 | /* |
247 | on this interface. */ | 359 | * The list of command receivers that are registered for commands |
360 | * on this interface. | ||
361 | */ | ||
248 | struct mutex cmd_rcvrs_mutex; | 362 | struct mutex cmd_rcvrs_mutex; |
249 | struct list_head cmd_rcvrs; | 363 | struct list_head cmd_rcvrs; |
250 | 364 | ||
251 | /* Events that were queues because no one was there to receive | 365 | /* |
252 | them. */ | 366 | * Events that were queues because no one was there to receive |
367 | * them. | ||
368 | */ | ||
253 | spinlock_t events_lock; /* For dealing with event stuff. */ | 369 | spinlock_t events_lock; /* For dealing with event stuff. */ |
254 | struct list_head waiting_events; | 370 | struct list_head waiting_events; |
255 | unsigned int waiting_events_count; /* How many events in queue? */ | 371 | unsigned int waiting_events_count; /* How many events in queue? */ |
256 | int delivering_events; | 372 | char delivering_events; |
373 | char event_msg_printed; | ||
257 | 374 | ||
258 | /* The event receiver for my BMC, only really used at panic | 375 | /* |
259 | shutdown as a place to store this. */ | 376 | * The event receiver for my BMC, only really used at panic |
377 | * shutdown as a place to store this. | ||
378 | */ | ||
260 | unsigned char event_receiver; | 379 | unsigned char event_receiver; |
261 | unsigned char event_receiver_lun; | 380 | unsigned char event_receiver_lun; |
262 | unsigned char local_sel_device; | 381 | unsigned char local_sel_device; |
@@ -268,14 +387,18 @@ struct ipmi_smi | |||
268 | int auto_maintenance_timeout; | 387 | int auto_maintenance_timeout; |
269 | spinlock_t maintenance_mode_lock; /* Used in a timer... */ | 388 | spinlock_t maintenance_mode_lock; /* Used in a timer... */ |
270 | 389 | ||
271 | /* A cheap hack, if this is non-null and a message to an | 390 | /* |
272 | interface comes in with a NULL user, call this routine with | 391 | * A cheap hack, if this is non-null and a message to an |
273 | it. Note that the message will still be freed by the | 392 | * interface comes in with a NULL user, call this routine with |
274 | caller. This only works on the system interface. */ | 393 | * it. Note that the message will still be freed by the |
394 | * caller. This only works on the system interface. | ||
395 | */ | ||
275 | void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_recv_msg *msg); | 396 | void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_recv_msg *msg); |
276 | 397 | ||
277 | /* When we are scanning the channels for an SMI, this will | 398 | /* |
278 | tell which channel we are scanning. */ | 399 | * When we are scanning the channels for an SMI, this will |
400 | * tell which channel we are scanning. | ||
401 | */ | ||
279 | int curr_channel; | 402 | int curr_channel; |
280 | 403 | ||
281 | /* Channel information */ | 404 | /* Channel information */ |
@@ -285,74 +408,14 @@ struct ipmi_smi | |||
285 | struct proc_dir_entry *proc_dir; | 408 | struct proc_dir_entry *proc_dir; |
286 | char proc_dir_name[10]; | 409 | char proc_dir_name[10]; |
287 | 410 | ||
288 | spinlock_t counter_lock; /* For making counters atomic. */ | 411 | atomic_t stats[IPMI_NUM_STATS]; |
289 | |||
290 | /* Commands we got that were invalid. */ | ||
291 | unsigned int sent_invalid_commands; | ||
292 | |||
293 | /* Commands we sent to the MC. */ | ||
294 | unsigned int sent_local_commands; | ||
295 | /* Responses from the MC that were delivered to a user. */ | ||
296 | unsigned int handled_local_responses; | ||
297 | /* Responses from the MC that were not delivered to a user. */ | ||
298 | unsigned int unhandled_local_responses; | ||
299 | |||
300 | /* Commands we sent out to the IPMB bus. */ | ||
301 | unsigned int sent_ipmb_commands; | ||
302 | /* Commands sent on the IPMB that had errors on the SEND CMD */ | ||
303 | unsigned int sent_ipmb_command_errs; | ||
304 | /* Each retransmit increments this count. */ | ||
305 | unsigned int retransmitted_ipmb_commands; | ||
306 | /* When a message times out (runs out of retransmits) this is | ||
307 | incremented. */ | ||
308 | unsigned int timed_out_ipmb_commands; | ||
309 | |||
310 | /* This is like above, but for broadcasts. Broadcasts are | ||
311 | *not* included in the above count (they are expected to | ||
312 | time out). */ | ||
313 | unsigned int timed_out_ipmb_broadcasts; | ||
314 | 412 | ||
315 | /* Responses I have sent to the IPMB bus. */ | 413 | /* |
316 | unsigned int sent_ipmb_responses; | 414 | * run_to_completion duplicate of smb_info, smi_info |
317 | 415 | * and ipmi_serial_info structures. Used to decrease numbers of | |
318 | /* The response was delivered to the user. */ | 416 | * parameters passed by "low" level IPMI code. |
319 | unsigned int handled_ipmb_responses; | 417 | */ |
320 | /* The response had invalid data in it. */ | 418 | int run_to_completion; |
321 | unsigned int invalid_ipmb_responses; | ||
322 | /* The response didn't have anyone waiting for it. */ | ||
323 | unsigned int unhandled_ipmb_responses; | ||
324 | |||
325 | /* Commands we sent out to the IPMB bus. */ | ||
326 | unsigned int sent_lan_commands; | ||
327 | /* Commands sent on the IPMB that had errors on the SEND CMD */ | ||
328 | unsigned int sent_lan_command_errs; | ||
329 | /* Each retransmit increments this count. */ | ||
330 | unsigned int retransmitted_lan_commands; | ||
331 | /* When a message times out (runs out of retransmits) this is | ||
332 | incremented. */ | ||
333 | unsigned int timed_out_lan_commands; | ||
334 | |||
335 | /* Responses I have sent to the IPMB bus. */ | ||
336 | unsigned int sent_lan_responses; | ||
337 | |||
338 | /* The response was delivered to the user. */ | ||
339 | unsigned int handled_lan_responses; | ||
340 | /* The response had invalid data in it. */ | ||
341 | unsigned int invalid_lan_responses; | ||
342 | /* The response didn't have anyone waiting for it. */ | ||
343 | unsigned int unhandled_lan_responses; | ||
344 | |||
345 | /* The command was delivered to the user. */ | ||
346 | unsigned int handled_commands; | ||
347 | /* The command had invalid data in it. */ | ||
348 | unsigned int invalid_commands; | ||
349 | /* The command didn't have anyone waiting for it. */ | ||
350 | unsigned int unhandled_commands; | ||
351 | |||
352 | /* Invalid data in an event. */ | ||
353 | unsigned int invalid_events; | ||
354 | /* Events that were received with the proper format. */ | ||
355 | unsigned int events; | ||
356 | }; | 419 | }; |
357 | #define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev) | 420 | #define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev) |
358 | 421 | ||
@@ -368,12 +431,19 @@ static DEFINE_MUTEX(ipmidriver_mutex); | |||
368 | static LIST_HEAD(ipmi_interfaces); | 431 | static LIST_HEAD(ipmi_interfaces); |
369 | static DEFINE_MUTEX(ipmi_interfaces_mutex); | 432 | static DEFINE_MUTEX(ipmi_interfaces_mutex); |
370 | 433 | ||
371 | /* List of watchers that want to know when smi's are added and | 434 | /* |
372 | deleted. */ | 435 | * List of watchers that want to know when smi's are added and deleted. |
436 | */ | ||
373 | static LIST_HEAD(smi_watchers); | 437 | static LIST_HEAD(smi_watchers); |
374 | static DEFINE_MUTEX(smi_watchers_mutex); | 438 | static DEFINE_MUTEX(smi_watchers_mutex); |
375 | 439 | ||
376 | 440 | ||
441 | #define ipmi_inc_stat(intf, stat) \ | ||
442 | atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat]) | ||
443 | #define ipmi_get_stat(intf, stat) \ | ||
444 | ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) | ||
445 | |||
446 | |||
377 | static void free_recv_msg_list(struct list_head *q) | 447 | static void free_recv_msg_list(struct list_head *q) |
378 | { | 448 | { |
379 | struct ipmi_recv_msg *msg, *msg2; | 449 | struct ipmi_recv_msg *msg, *msg2; |
@@ -417,10 +487,8 @@ static void clean_up_interface_data(ipmi_smi_t intf) | |||
417 | 487 | ||
418 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { | 488 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { |
419 | if ((intf->seq_table[i].inuse) | 489 | if ((intf->seq_table[i].inuse) |
420 | && (intf->seq_table[i].recv_msg)) | 490 | && (intf->seq_table[i].recv_msg)) |
421 | { | ||
422 | ipmi_free_recv_msg(intf->seq_table[i].recv_msg); | 491 | ipmi_free_recv_msg(intf->seq_table[i].recv_msg); |
423 | } | ||
424 | } | 492 | } |
425 | } | 493 | } |
426 | 494 | ||
@@ -487,6 +555,7 @@ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) | |||
487 | } | 555 | } |
488 | return -ENOMEM; | 556 | return -ENOMEM; |
489 | } | 557 | } |
558 | EXPORT_SYMBOL(ipmi_smi_watcher_register); | ||
490 | 559 | ||
491 | int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) | 560 | int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) |
492 | { | 561 | { |
@@ -495,6 +564,7 @@ int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) | |||
495 | mutex_unlock(&smi_watchers_mutex); | 564 | mutex_unlock(&smi_watchers_mutex); |
496 | return 0; | 565 | return 0; |
497 | } | 566 | } |
567 | EXPORT_SYMBOL(ipmi_smi_watcher_unregister); | ||
498 | 568 | ||
499 | /* | 569 | /* |
500 | * Must be called with smi_watchers_mutex held. | 570 | * Must be called with smi_watchers_mutex held. |
@@ -530,8 +600,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2) | |||
530 | } | 600 | } |
531 | 601 | ||
532 | if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE) | 602 | if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE) |
533 | || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) | 603 | || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { |
534 | { | ||
535 | struct ipmi_ipmb_addr *ipmb_addr1 | 604 | struct ipmi_ipmb_addr *ipmb_addr1 |
536 | = (struct ipmi_ipmb_addr *) addr1; | 605 | = (struct ipmi_ipmb_addr *) addr1; |
537 | struct ipmi_ipmb_addr *ipmb_addr2 | 606 | struct ipmi_ipmb_addr *ipmb_addr2 |
@@ -559,9 +628,8 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2) | |||
559 | 628 | ||
560 | int ipmi_validate_addr(struct ipmi_addr *addr, int len) | 629 | int ipmi_validate_addr(struct ipmi_addr *addr, int len) |
561 | { | 630 | { |
562 | if (len < sizeof(struct ipmi_system_interface_addr)) { | 631 | if (len < sizeof(struct ipmi_system_interface_addr)) |
563 | return -EINVAL; | 632 | return -EINVAL; |
564 | } | ||
565 | 633 | ||
566 | if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { | 634 | if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { |
567 | if (addr->channel != IPMI_BMC_CHANNEL) | 635 | if (addr->channel != IPMI_BMC_CHANNEL) |
@@ -575,23 +643,21 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len) | |||
575 | return -EINVAL; | 643 | return -EINVAL; |
576 | 644 | ||
577 | if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) | 645 | if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) |
578 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) | 646 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { |
579 | { | 647 | if (len < sizeof(struct ipmi_ipmb_addr)) |
580 | if (len < sizeof(struct ipmi_ipmb_addr)) { | ||
581 | return -EINVAL; | 648 | return -EINVAL; |
582 | } | ||
583 | return 0; | 649 | return 0; |
584 | } | 650 | } |
585 | 651 | ||
586 | if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { | 652 | if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { |
587 | if (len < sizeof(struct ipmi_lan_addr)) { | 653 | if (len < sizeof(struct ipmi_lan_addr)) |
588 | return -EINVAL; | 654 | return -EINVAL; |
589 | } | ||
590 | return 0; | 655 | return 0; |
591 | } | 656 | } |
592 | 657 | ||
593 | return -EINVAL; | 658 | return -EINVAL; |
594 | } | 659 | } |
660 | EXPORT_SYMBOL(ipmi_validate_addr); | ||
595 | 661 | ||
596 | unsigned int ipmi_addr_length(int addr_type) | 662 | unsigned int ipmi_addr_length(int addr_type) |
597 | { | 663 | { |
@@ -599,34 +665,28 @@ unsigned int ipmi_addr_length(int addr_type) | |||
599 | return sizeof(struct ipmi_system_interface_addr); | 665 | return sizeof(struct ipmi_system_interface_addr); |
600 | 666 | ||
601 | if ((addr_type == IPMI_IPMB_ADDR_TYPE) | 667 | if ((addr_type == IPMI_IPMB_ADDR_TYPE) |
602 | || (addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) | 668 | || (addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) |
603 | { | ||
604 | return sizeof(struct ipmi_ipmb_addr); | 669 | return sizeof(struct ipmi_ipmb_addr); |
605 | } | ||
606 | 670 | ||
607 | if (addr_type == IPMI_LAN_ADDR_TYPE) | 671 | if (addr_type == IPMI_LAN_ADDR_TYPE) |
608 | return sizeof(struct ipmi_lan_addr); | 672 | return sizeof(struct ipmi_lan_addr); |
609 | 673 | ||
610 | return 0; | 674 | return 0; |
611 | } | 675 | } |
676 | EXPORT_SYMBOL(ipmi_addr_length); | ||
612 | 677 | ||
613 | static void deliver_response(struct ipmi_recv_msg *msg) | 678 | static void deliver_response(struct ipmi_recv_msg *msg) |
614 | { | 679 | { |
615 | if (!msg->user) { | 680 | if (!msg->user) { |
616 | ipmi_smi_t intf = msg->user_msg_data; | 681 | ipmi_smi_t intf = msg->user_msg_data; |
617 | unsigned long flags; | ||
618 | 682 | ||
619 | /* Special handling for NULL users. */ | 683 | /* Special handling for NULL users. */ |
620 | if (intf->null_user_handler) { | 684 | if (intf->null_user_handler) { |
621 | intf->null_user_handler(intf, msg); | 685 | intf->null_user_handler(intf, msg); |
622 | spin_lock_irqsave(&intf->counter_lock, flags); | 686 | ipmi_inc_stat(intf, handled_local_responses); |
623 | intf->handled_local_responses++; | ||
624 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
625 | } else { | 687 | } else { |
626 | /* No handler, so give up. */ | 688 | /* No handler, so give up. */ |
627 | spin_lock_irqsave(&intf->counter_lock, flags); | 689 | ipmi_inc_stat(intf, unhandled_local_responses); |
628 | intf->unhandled_local_responses++; | ||
629 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
630 | } | 690 | } |
631 | ipmi_free_recv_msg(msg); | 691 | ipmi_free_recv_msg(msg); |
632 | } else { | 692 | } else { |
@@ -646,9 +706,11 @@ deliver_err_response(struct ipmi_recv_msg *msg, int err) | |||
646 | deliver_response(msg); | 706 | deliver_response(msg); |
647 | } | 707 | } |
648 | 708 | ||
649 | /* Find the next sequence number not being used and add the given | 709 | /* |
650 | message with the given timeout to the sequence table. This must be | 710 | * Find the next sequence number not being used and add the given |
651 | called with the interface's seq_lock held. */ | 711 | * message with the given timeout to the sequence table. This must be |
712 | * called with the interface's seq_lock held. | ||
713 | */ | ||
652 | static int intf_next_seq(ipmi_smi_t intf, | 714 | static int intf_next_seq(ipmi_smi_t intf, |
653 | struct ipmi_recv_msg *recv_msg, | 715 | struct ipmi_recv_msg *recv_msg, |
654 | unsigned long timeout, | 716 | unsigned long timeout, |
@@ -660,10 +722,8 @@ static int intf_next_seq(ipmi_smi_t intf, | |||
660 | int rv = 0; | 722 | int rv = 0; |
661 | unsigned int i; | 723 | unsigned int i; |
662 | 724 | ||
663 | for (i = intf->curr_seq; | 725 | for (i = intf->curr_seq; (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; |
664 | (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; | 726 | i = (i+1)%IPMI_IPMB_NUM_SEQ) { |
665 | i = (i+1)%IPMI_IPMB_NUM_SEQ) | ||
666 | { | ||
667 | if (!intf->seq_table[i].inuse) | 727 | if (!intf->seq_table[i].inuse) |
668 | break; | 728 | break; |
669 | } | 729 | } |
@@ -671,8 +731,10 @@ static int intf_next_seq(ipmi_smi_t intf, | |||
671 | if (!intf->seq_table[i].inuse) { | 731 | if (!intf->seq_table[i].inuse) { |
672 | intf->seq_table[i].recv_msg = recv_msg; | 732 | intf->seq_table[i].recv_msg = recv_msg; |
673 | 733 | ||
674 | /* Start with the maximum timeout, when the send response | 734 | /* |
675 | comes in we will start the real timer. */ | 735 | * Start with the maximum timeout, when the send response |
736 | * comes in we will start the real timer. | ||
737 | */ | ||
676 | intf->seq_table[i].timeout = MAX_MSG_TIMEOUT; | 738 | intf->seq_table[i].timeout = MAX_MSG_TIMEOUT; |
677 | intf->seq_table[i].orig_timeout = timeout; | 739 | intf->seq_table[i].orig_timeout = timeout; |
678 | intf->seq_table[i].retries_left = retries; | 740 | intf->seq_table[i].retries_left = retries; |
@@ -685,15 +747,17 @@ static int intf_next_seq(ipmi_smi_t intf, | |||
685 | } else { | 747 | } else { |
686 | rv = -EAGAIN; | 748 | rv = -EAGAIN; |
687 | } | 749 | } |
688 | 750 | ||
689 | return rv; | 751 | return rv; |
690 | } | 752 | } |
691 | 753 | ||
692 | /* Return the receive message for the given sequence number and | 754 | /* |
693 | release the sequence number so it can be reused. Some other data | 755 | * Return the receive message for the given sequence number and |
694 | is passed in to be sure the message matches up correctly (to help | 756 | * release the sequence number so it can be reused. Some other data |
695 | guard against message coming in after their timeout and the | 757 | * is passed in to be sure the message matches up correctly (to help |
696 | sequence number being reused). */ | 758 | * guard against message coming in after their timeout and the |
759 | * sequence number being reused). | ||
760 | */ | ||
697 | static int intf_find_seq(ipmi_smi_t intf, | 761 | static int intf_find_seq(ipmi_smi_t intf, |
698 | unsigned char seq, | 762 | unsigned char seq, |
699 | short channel, | 763 | short channel, |
@@ -712,11 +776,9 @@ static int intf_find_seq(ipmi_smi_t intf, | |||
712 | if (intf->seq_table[seq].inuse) { | 776 | if (intf->seq_table[seq].inuse) { |
713 | struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg; | 777 | struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg; |
714 | 778 | ||
715 | if ((msg->addr.channel == channel) | 779 | if ((msg->addr.channel == channel) && (msg->msg.cmd == cmd) |
716 | && (msg->msg.cmd == cmd) | 780 | && (msg->msg.netfn == netfn) |
717 | && (msg->msg.netfn == netfn) | 781 | && (ipmi_addr_equal(addr, &(msg->addr)))) { |
718 | && (ipmi_addr_equal(addr, &(msg->addr)))) | ||
719 | { | ||
720 | *recv_msg = msg; | 782 | *recv_msg = msg; |
721 | intf->seq_table[seq].inuse = 0; | 783 | intf->seq_table[seq].inuse = 0; |
722 | rv = 0; | 784 | rv = 0; |
@@ -741,11 +803,12 @@ static int intf_start_seq_timer(ipmi_smi_t intf, | |||
741 | GET_SEQ_FROM_MSGID(msgid, seq, seqid); | 803 | GET_SEQ_FROM_MSGID(msgid, seq, seqid); |
742 | 804 | ||
743 | spin_lock_irqsave(&(intf->seq_lock), flags); | 805 | spin_lock_irqsave(&(intf->seq_lock), flags); |
744 | /* We do this verification because the user can be deleted | 806 | /* |
745 | while a message is outstanding. */ | 807 | * We do this verification because the user can be deleted |
808 | * while a message is outstanding. | ||
809 | */ | ||
746 | if ((intf->seq_table[seq].inuse) | 810 | if ((intf->seq_table[seq].inuse) |
747 | && (intf->seq_table[seq].seqid == seqid)) | 811 | && (intf->seq_table[seq].seqid == seqid)) { |
748 | { | ||
749 | struct seq_table *ent = &(intf->seq_table[seq]); | 812 | struct seq_table *ent = &(intf->seq_table[seq]); |
750 | ent->timeout = ent->orig_timeout; | 813 | ent->timeout = ent->orig_timeout; |
751 | rv = 0; | 814 | rv = 0; |
@@ -770,11 +833,12 @@ static int intf_err_seq(ipmi_smi_t intf, | |||
770 | GET_SEQ_FROM_MSGID(msgid, seq, seqid); | 833 | GET_SEQ_FROM_MSGID(msgid, seq, seqid); |
771 | 834 | ||
772 | spin_lock_irqsave(&(intf->seq_lock), flags); | 835 | spin_lock_irqsave(&(intf->seq_lock), flags); |
773 | /* We do this verification because the user can be deleted | 836 | /* |
774 | while a message is outstanding. */ | 837 | * We do this verification because the user can be deleted |
838 | * while a message is outstanding. | ||
839 | */ | ||
775 | if ((intf->seq_table[seq].inuse) | 840 | if ((intf->seq_table[seq].inuse) |
776 | && (intf->seq_table[seq].seqid == seqid)) | 841 | && (intf->seq_table[seq].seqid == seqid)) { |
777 | { | ||
778 | struct seq_table *ent = &(intf->seq_table[seq]); | 842 | struct seq_table *ent = &(intf->seq_table[seq]); |
779 | 843 | ||
780 | ent->inuse = 0; | 844 | ent->inuse = 0; |
@@ -800,24 +864,30 @@ int ipmi_create_user(unsigned int if_num, | |||
800 | int rv = 0; | 864 | int rv = 0; |
801 | ipmi_smi_t intf; | 865 | ipmi_smi_t intf; |
802 | 866 | ||
803 | /* There is no module usecount here, because it's not | 867 | /* |
804 | required. Since this can only be used by and called from | 868 | * There is no module usecount here, because it's not |
805 | other modules, they will implicitly use this module, and | 869 | * required. Since this can only be used by and called from |
806 | thus this can't be removed unless the other modules are | 870 | * other modules, they will implicitly use this module, and |
807 | removed. */ | 871 | * thus this can't be removed unless the other modules are |
872 | * removed. | ||
873 | */ | ||
808 | 874 | ||
809 | if (handler == NULL) | 875 | if (handler == NULL) |
810 | return -EINVAL; | 876 | return -EINVAL; |
811 | 877 | ||
812 | /* Make sure the driver is actually initialized, this handles | 878 | /* |
813 | problems with initialization order. */ | 879 | * Make sure the driver is actually initialized, this handles |
880 | * problems with initialization order. | ||
881 | */ | ||
814 | if (!initialized) { | 882 | if (!initialized) { |
815 | rv = ipmi_init_msghandler(); | 883 | rv = ipmi_init_msghandler(); |
816 | if (rv) | 884 | if (rv) |
817 | return rv; | 885 | return rv; |
818 | 886 | ||
819 | /* The init code doesn't return an error if it was turned | 887 | /* |
820 | off, but it won't initialize. Check that. */ | 888 | * The init code doesn't return an error if it was turned |
889 | * off, but it won't initialize. Check that. | ||
890 | */ | ||
821 | if (!initialized) | 891 | if (!initialized) |
822 | return -ENODEV; | 892 | return -ENODEV; |
823 | } | 893 | } |
@@ -858,8 +928,10 @@ int ipmi_create_user(unsigned int if_num, | |||
858 | } | 928 | } |
859 | } | 929 | } |
860 | 930 | ||
861 | /* Hold the lock so intf->handlers is guaranteed to be good | 931 | /* |
862 | * until now */ | 932 | * Hold the lock so intf->handlers is guaranteed to be good |
933 | * until now | ||
934 | */ | ||
863 | mutex_unlock(&ipmi_interfaces_mutex); | 935 | mutex_unlock(&ipmi_interfaces_mutex); |
864 | 936 | ||
865 | new_user->valid = 1; | 937 | new_user->valid = 1; |
@@ -876,6 +948,7 @@ out_kfree: | |||
876 | kfree(new_user); | 948 | kfree(new_user); |
877 | return rv; | 949 | return rv; |
878 | } | 950 | } |
951 | EXPORT_SYMBOL(ipmi_create_user); | ||
879 | 952 | ||
880 | static void free_user(struct kref *ref) | 953 | static void free_user(struct kref *ref) |
881 | { | 954 | { |
@@ -899,8 +972,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
899 | 972 | ||
900 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { | 973 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { |
901 | if (intf->seq_table[i].inuse | 974 | if (intf->seq_table[i].inuse |
902 | && (intf->seq_table[i].recv_msg->user == user)) | 975 | && (intf->seq_table[i].recv_msg->user == user)) { |
903 | { | ||
904 | intf->seq_table[i].inuse = 0; | 976 | intf->seq_table[i].inuse = 0; |
905 | ipmi_free_recv_msg(intf->seq_table[i].recv_msg); | 977 | ipmi_free_recv_msg(intf->seq_table[i].recv_msg); |
906 | } | 978 | } |
@@ -943,6 +1015,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
943 | 1015 | ||
944 | return 0; | 1016 | return 0; |
945 | } | 1017 | } |
1018 | EXPORT_SYMBOL(ipmi_destroy_user); | ||
946 | 1019 | ||
947 | void ipmi_get_version(ipmi_user_t user, | 1020 | void ipmi_get_version(ipmi_user_t user, |
948 | unsigned char *major, | 1021 | unsigned char *major, |
@@ -951,6 +1024,7 @@ void ipmi_get_version(ipmi_user_t user, | |||
951 | *major = user->intf->ipmi_version_major; | 1024 | *major = user->intf->ipmi_version_major; |
952 | *minor = user->intf->ipmi_version_minor; | 1025 | *minor = user->intf->ipmi_version_minor; |
953 | } | 1026 | } |
1027 | EXPORT_SYMBOL(ipmi_get_version); | ||
954 | 1028 | ||
955 | int ipmi_set_my_address(ipmi_user_t user, | 1029 | int ipmi_set_my_address(ipmi_user_t user, |
956 | unsigned int channel, | 1030 | unsigned int channel, |
@@ -961,6 +1035,7 @@ int ipmi_set_my_address(ipmi_user_t user, | |||
961 | user->intf->channels[channel].address = address; | 1035 | user->intf->channels[channel].address = address; |
962 | return 0; | 1036 | return 0; |
963 | } | 1037 | } |
1038 | EXPORT_SYMBOL(ipmi_set_my_address); | ||
964 | 1039 | ||
965 | int ipmi_get_my_address(ipmi_user_t user, | 1040 | int ipmi_get_my_address(ipmi_user_t user, |
966 | unsigned int channel, | 1041 | unsigned int channel, |
@@ -971,6 +1046,7 @@ int ipmi_get_my_address(ipmi_user_t user, | |||
971 | *address = user->intf->channels[channel].address; | 1046 | *address = user->intf->channels[channel].address; |
972 | return 0; | 1047 | return 0; |
973 | } | 1048 | } |
1049 | EXPORT_SYMBOL(ipmi_get_my_address); | ||
974 | 1050 | ||
975 | int ipmi_set_my_LUN(ipmi_user_t user, | 1051 | int ipmi_set_my_LUN(ipmi_user_t user, |
976 | unsigned int channel, | 1052 | unsigned int channel, |
@@ -981,6 +1057,7 @@ int ipmi_set_my_LUN(ipmi_user_t user, | |||
981 | user->intf->channels[channel].lun = LUN & 0x3; | 1057 | user->intf->channels[channel].lun = LUN & 0x3; |
982 | return 0; | 1058 | return 0; |
983 | } | 1059 | } |
1060 | EXPORT_SYMBOL(ipmi_set_my_LUN); | ||
984 | 1061 | ||
985 | int ipmi_get_my_LUN(ipmi_user_t user, | 1062 | int ipmi_get_my_LUN(ipmi_user_t user, |
986 | unsigned int channel, | 1063 | unsigned int channel, |
@@ -991,6 +1068,7 @@ int ipmi_get_my_LUN(ipmi_user_t user, | |||
991 | *address = user->intf->channels[channel].lun; | 1068 | *address = user->intf->channels[channel].lun; |
992 | return 0; | 1069 | return 0; |
993 | } | 1070 | } |
1071 | EXPORT_SYMBOL(ipmi_get_my_LUN); | ||
994 | 1072 | ||
995 | int ipmi_get_maintenance_mode(ipmi_user_t user) | 1073 | int ipmi_get_maintenance_mode(ipmi_user_t user) |
996 | { | 1074 | { |
@@ -1075,6 +1153,11 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
1075 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) | 1153 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) |
1076 | list_move_tail(&msg->link, &msgs); | 1154 | list_move_tail(&msg->link, &msgs); |
1077 | intf->waiting_events_count = 0; | 1155 | intf->waiting_events_count = 0; |
1156 | if (intf->event_msg_printed) { | ||
1157 | printk(KERN_WARNING PFX "Event queue no longer" | ||
1158 | " full\n"); | ||
1159 | intf->event_msg_printed = 0; | ||
1160 | } | ||
1078 | 1161 | ||
1079 | intf->delivering_events = 1; | 1162 | intf->delivering_events = 1; |
1080 | spin_unlock_irqrestore(&intf->events_lock, flags); | 1163 | spin_unlock_irqrestore(&intf->events_lock, flags); |
@@ -1094,6 +1177,7 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
1094 | 1177 | ||
1095 | return 0; | 1178 | return 0; |
1096 | } | 1179 | } |
1180 | EXPORT_SYMBOL(ipmi_set_gets_events); | ||
1097 | 1181 | ||
1098 | static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t intf, | 1182 | static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t intf, |
1099 | unsigned char netfn, | 1183 | unsigned char netfn, |
@@ -1159,6 +1243,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, | |||
1159 | 1243 | ||
1160 | return rv; | 1244 | return rv; |
1161 | } | 1245 | } |
1246 | EXPORT_SYMBOL(ipmi_register_for_cmd); | ||
1162 | 1247 | ||
1163 | int ipmi_unregister_for_cmd(ipmi_user_t user, | 1248 | int ipmi_unregister_for_cmd(ipmi_user_t user, |
1164 | unsigned char netfn, | 1249 | unsigned char netfn, |
@@ -1196,19 +1281,13 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, | |||
1196 | } | 1281 | } |
1197 | return rv; | 1282 | return rv; |
1198 | } | 1283 | } |
1199 | 1284 | EXPORT_SYMBOL(ipmi_unregister_for_cmd); | |
1200 | void ipmi_user_set_run_to_completion(ipmi_user_t user, int val) | ||
1201 | { | ||
1202 | ipmi_smi_t intf = user->intf; | ||
1203 | if (intf->handlers) | ||
1204 | intf->handlers->set_run_to_completion(intf->send_info, val); | ||
1205 | } | ||
1206 | 1285 | ||
1207 | static unsigned char | 1286 | static unsigned char |
1208 | ipmb_checksum(unsigned char *data, int size) | 1287 | ipmb_checksum(unsigned char *data, int size) |
1209 | { | 1288 | { |
1210 | unsigned char csum = 0; | 1289 | unsigned char csum = 0; |
1211 | 1290 | ||
1212 | for (; size > 0; size--, data++) | 1291 | for (; size > 0; size--, data++) |
1213 | csum += *data; | 1292 | csum += *data; |
1214 | 1293 | ||
@@ -1250,8 +1329,10 @@ static inline void format_ipmb_msg(struct ipmi_smi_msg *smi_msg, | |||
1250 | = ipmb_checksum(&(smi_msg->data[i+6]), | 1329 | = ipmb_checksum(&(smi_msg->data[i+6]), |
1251 | smi_msg->data_size-6); | 1330 | smi_msg->data_size-6); |
1252 | 1331 | ||
1253 | /* Add on the checksum size and the offset from the | 1332 | /* |
1254 | broadcast. */ | 1333 | * Add on the checksum size and the offset from the |
1334 | * broadcast. | ||
1335 | */ | ||
1255 | smi_msg->data_size += 1 + i; | 1336 | smi_msg->data_size += 1 + i; |
1256 | 1337 | ||
1257 | smi_msg->msgid = msgid; | 1338 | smi_msg->msgid = msgid; |
@@ -1287,17 +1368,21 @@ static inline void format_lan_msg(struct ipmi_smi_msg *smi_msg, | |||
1287 | = ipmb_checksum(&(smi_msg->data[7]), | 1368 | = ipmb_checksum(&(smi_msg->data[7]), |
1288 | smi_msg->data_size-7); | 1369 | smi_msg->data_size-7); |
1289 | 1370 | ||
1290 | /* Add on the checksum size and the offset from the | 1371 | /* |
1291 | broadcast. */ | 1372 | * Add on the checksum size and the offset from the |
1373 | * broadcast. | ||
1374 | */ | ||
1292 | smi_msg->data_size += 1; | 1375 | smi_msg->data_size += 1; |
1293 | 1376 | ||
1294 | smi_msg->msgid = msgid; | 1377 | smi_msg->msgid = msgid; |
1295 | } | 1378 | } |
1296 | 1379 | ||
1297 | /* Separate from ipmi_request so that the user does not have to be | 1380 | /* |
1298 | supplied in certain circumstances (mainly at panic time). If | 1381 | * Separate from ipmi_request so that the user does not have to be |
1299 | messages are supplied, they will be freed, even if an error | 1382 | * supplied in certain circumstances (mainly at panic time). If |
1300 | occurs. */ | 1383 | * messages are supplied, they will be freed, even if an error |
1384 | * occurs. | ||
1385 | */ | ||
1301 | static int i_ipmi_request(ipmi_user_t user, | 1386 | static int i_ipmi_request(ipmi_user_t user, |
1302 | ipmi_smi_t intf, | 1387 | ipmi_smi_t intf, |
1303 | struct ipmi_addr *addr, | 1388 | struct ipmi_addr *addr, |
@@ -1319,19 +1404,18 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1319 | struct ipmi_smi_handlers *handlers; | 1404 | struct ipmi_smi_handlers *handlers; |
1320 | 1405 | ||
1321 | 1406 | ||
1322 | if (supplied_recv) { | 1407 | if (supplied_recv) |
1323 | recv_msg = supplied_recv; | 1408 | recv_msg = supplied_recv; |
1324 | } else { | 1409 | else { |
1325 | recv_msg = ipmi_alloc_recv_msg(); | 1410 | recv_msg = ipmi_alloc_recv_msg(); |
1326 | if (recv_msg == NULL) { | 1411 | if (recv_msg == NULL) |
1327 | return -ENOMEM; | 1412 | return -ENOMEM; |
1328 | } | ||
1329 | } | 1413 | } |
1330 | recv_msg->user_msg_data = user_msg_data; | 1414 | recv_msg->user_msg_data = user_msg_data; |
1331 | 1415 | ||
1332 | if (supplied_smi) { | 1416 | if (supplied_smi) |
1333 | smi_msg = (struct ipmi_smi_msg *) supplied_smi; | 1417 | smi_msg = (struct ipmi_smi_msg *) supplied_smi; |
1334 | } else { | 1418 | else { |
1335 | smi_msg = ipmi_alloc_smi_msg(); | 1419 | smi_msg = ipmi_alloc_smi_msg(); |
1336 | if (smi_msg == NULL) { | 1420 | if (smi_msg == NULL) { |
1337 | ipmi_free_recv_msg(recv_msg); | 1421 | ipmi_free_recv_msg(recv_msg); |
@@ -1350,8 +1434,10 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1350 | if (user) | 1434 | if (user) |
1351 | kref_get(&user->refcount); | 1435 | kref_get(&user->refcount); |
1352 | recv_msg->msgid = msgid; | 1436 | recv_msg->msgid = msgid; |
1353 | /* Store the message to send in the receive message so timeout | 1437 | /* |
1354 | responses can get the proper response data. */ | 1438 | * Store the message to send in the receive message so timeout |
1439 | * responses can get the proper response data. | ||
1440 | */ | ||
1355 | recv_msg->msg = *msg; | 1441 | recv_msg->msg = *msg; |
1356 | 1442 | ||
1357 | if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { | 1443 | if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { |
@@ -1365,9 +1451,7 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1365 | 1451 | ||
1366 | smi_addr = (struct ipmi_system_interface_addr *) addr; | 1452 | smi_addr = (struct ipmi_system_interface_addr *) addr; |
1367 | if (smi_addr->lun > 3) { | 1453 | if (smi_addr->lun > 3) { |
1368 | spin_lock_irqsave(&intf->counter_lock, flags); | 1454 | ipmi_inc_stat(intf, sent_invalid_commands); |
1369 | intf->sent_invalid_commands++; | ||
1370 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1371 | rv = -EINVAL; | 1455 | rv = -EINVAL; |
1372 | goto out_err; | 1456 | goto out_err; |
1373 | } | 1457 | } |
@@ -1377,13 +1461,12 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1377 | if ((msg->netfn == IPMI_NETFN_APP_REQUEST) | 1461 | if ((msg->netfn == IPMI_NETFN_APP_REQUEST) |
1378 | && ((msg->cmd == IPMI_SEND_MSG_CMD) | 1462 | && ((msg->cmd == IPMI_SEND_MSG_CMD) |
1379 | || (msg->cmd == IPMI_GET_MSG_CMD) | 1463 | || (msg->cmd == IPMI_GET_MSG_CMD) |
1380 | || (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))) | 1464 | || (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))) { |
1381 | { | 1465 | /* |
1382 | /* We don't let the user do these, since we manage | 1466 | * We don't let the user do these, since we manage |
1383 | the sequence numbers. */ | 1467 | * the sequence numbers. |
1384 | spin_lock_irqsave(&intf->counter_lock, flags); | 1468 | */ |
1385 | intf->sent_invalid_commands++; | 1469 | ipmi_inc_stat(intf, sent_invalid_commands); |
1386 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1387 | rv = -EINVAL; | 1470 | rv = -EINVAL; |
1388 | goto out_err; | 1471 | goto out_err; |
1389 | } | 1472 | } |
@@ -1391,14 +1474,12 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1391 | if (((msg->netfn == IPMI_NETFN_APP_REQUEST) | 1474 | if (((msg->netfn == IPMI_NETFN_APP_REQUEST) |
1392 | && ((msg->cmd == IPMI_COLD_RESET_CMD) | 1475 | && ((msg->cmd == IPMI_COLD_RESET_CMD) |
1393 | || (msg->cmd == IPMI_WARM_RESET_CMD))) | 1476 | || (msg->cmd == IPMI_WARM_RESET_CMD))) |
1394 | || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)) | 1477 | || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)) { |
1395 | { | ||
1396 | spin_lock_irqsave(&intf->maintenance_mode_lock, flags); | 1478 | spin_lock_irqsave(&intf->maintenance_mode_lock, flags); |
1397 | intf->auto_maintenance_timeout | 1479 | intf->auto_maintenance_timeout |
1398 | = IPMI_MAINTENANCE_MODE_TIMEOUT; | 1480 | = IPMI_MAINTENANCE_MODE_TIMEOUT; |
1399 | if (!intf->maintenance_mode | 1481 | if (!intf->maintenance_mode |
1400 | && !intf->maintenance_mode_enable) | 1482 | && !intf->maintenance_mode_enable) { |
1401 | { | ||
1402 | intf->maintenance_mode_enable = 1; | 1483 | intf->maintenance_mode_enable = 1; |
1403 | maintenance_mode_update(intf); | 1484 | maintenance_mode_update(intf); |
1404 | } | 1485 | } |
@@ -1407,9 +1488,7 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1407 | } | 1488 | } |
1408 | 1489 | ||
1409 | if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) { | 1490 | if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) { |
1410 | spin_lock_irqsave(&intf->counter_lock, flags); | 1491 | ipmi_inc_stat(intf, sent_invalid_commands); |
1411 | intf->sent_invalid_commands++; | ||
1412 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1413 | rv = -EMSGSIZE; | 1492 | rv = -EMSGSIZE; |
1414 | goto out_err; | 1493 | goto out_err; |
1415 | } | 1494 | } |
@@ -1421,31 +1500,23 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1421 | if (msg->data_len > 0) | 1500 | if (msg->data_len > 0) |
1422 | memcpy(&(smi_msg->data[2]), msg->data, msg->data_len); | 1501 | memcpy(&(smi_msg->data[2]), msg->data, msg->data_len); |
1423 | smi_msg->data_size = msg->data_len + 2; | 1502 | smi_msg->data_size = msg->data_len + 2; |
1424 | spin_lock_irqsave(&intf->counter_lock, flags); | 1503 | ipmi_inc_stat(intf, sent_local_commands); |
1425 | intf->sent_local_commands++; | ||
1426 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1427 | } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) | 1504 | } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) |
1428 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) | 1505 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { |
1429 | { | ||
1430 | struct ipmi_ipmb_addr *ipmb_addr; | 1506 | struct ipmi_ipmb_addr *ipmb_addr; |
1431 | unsigned char ipmb_seq; | 1507 | unsigned char ipmb_seq; |
1432 | long seqid; | 1508 | long seqid; |
1433 | int broadcast = 0; | 1509 | int broadcast = 0; |
1434 | 1510 | ||
1435 | if (addr->channel >= IPMI_MAX_CHANNELS) { | 1511 | if (addr->channel >= IPMI_MAX_CHANNELS) { |
1436 | spin_lock_irqsave(&intf->counter_lock, flags); | 1512 | ipmi_inc_stat(intf, sent_invalid_commands); |
1437 | intf->sent_invalid_commands++; | ||
1438 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1439 | rv = -EINVAL; | 1513 | rv = -EINVAL; |
1440 | goto out_err; | 1514 | goto out_err; |
1441 | } | 1515 | } |
1442 | 1516 | ||
1443 | if (intf->channels[addr->channel].medium | 1517 | if (intf->channels[addr->channel].medium |
1444 | != IPMI_CHANNEL_MEDIUM_IPMB) | 1518 | != IPMI_CHANNEL_MEDIUM_IPMB) { |
1445 | { | 1519 | ipmi_inc_stat(intf, sent_invalid_commands); |
1446 | spin_lock_irqsave(&intf->counter_lock, flags); | ||
1447 | intf->sent_invalid_commands++; | ||
1448 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1449 | rv = -EINVAL; | 1520 | rv = -EINVAL; |
1450 | goto out_err; | 1521 | goto out_err; |
1451 | } | 1522 | } |
@@ -1457,9 +1528,11 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1457 | retries = 4; | 1528 | retries = 4; |
1458 | } | 1529 | } |
1459 | if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) { | 1530 | if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) { |
1460 | /* Broadcasts add a zero at the beginning of the | 1531 | /* |
1461 | message, but otherwise is the same as an IPMB | 1532 | * Broadcasts add a zero at the beginning of the |
1462 | address. */ | 1533 | * message, but otherwise is the same as an IPMB |
1534 | * address. | ||
1535 | */ | ||
1463 | addr->addr_type = IPMI_IPMB_ADDR_TYPE; | 1536 | addr->addr_type = IPMI_IPMB_ADDR_TYPE; |
1464 | broadcast = 1; | 1537 | broadcast = 1; |
1465 | } | 1538 | } |
@@ -1469,21 +1542,19 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1469 | if (retry_time_ms == 0) | 1542 | if (retry_time_ms == 0) |
1470 | retry_time_ms = 1000; | 1543 | retry_time_ms = 1000; |
1471 | 1544 | ||
1472 | /* 9 for the header and 1 for the checksum, plus | 1545 | /* |
1473 | possibly one for the broadcast. */ | 1546 | * 9 for the header and 1 for the checksum, plus |
1547 | * possibly one for the broadcast. | ||
1548 | */ | ||
1474 | if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) { | 1549 | if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) { |
1475 | spin_lock_irqsave(&intf->counter_lock, flags); | 1550 | ipmi_inc_stat(intf, sent_invalid_commands); |
1476 | intf->sent_invalid_commands++; | ||
1477 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1478 | rv = -EMSGSIZE; | 1551 | rv = -EMSGSIZE; |
1479 | goto out_err; | 1552 | goto out_err; |
1480 | } | 1553 | } |
1481 | 1554 | ||
1482 | ipmb_addr = (struct ipmi_ipmb_addr *) addr; | 1555 | ipmb_addr = (struct ipmi_ipmb_addr *) addr; |
1483 | if (ipmb_addr->lun > 3) { | 1556 | if (ipmb_addr->lun > 3) { |
1484 | spin_lock_irqsave(&intf->counter_lock, flags); | 1557 | ipmi_inc_stat(intf, sent_invalid_commands); |
1485 | intf->sent_invalid_commands++; | ||
1486 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1487 | rv = -EINVAL; | 1558 | rv = -EINVAL; |
1488 | goto out_err; | 1559 | goto out_err; |
1489 | } | 1560 | } |
@@ -1491,29 +1562,31 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1491 | memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr)); | 1562 | memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr)); |
1492 | 1563 | ||
1493 | if (recv_msg->msg.netfn & 0x1) { | 1564 | if (recv_msg->msg.netfn & 0x1) { |
1494 | /* It's a response, so use the user's sequence | 1565 | /* |
1495 | from msgid. */ | 1566 | * It's a response, so use the user's sequence |
1496 | spin_lock_irqsave(&intf->counter_lock, flags); | 1567 | * from msgid. |
1497 | intf->sent_ipmb_responses++; | 1568 | */ |
1498 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 1569 | ipmi_inc_stat(intf, sent_ipmb_responses); |
1499 | format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid, | 1570 | format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid, |
1500 | msgid, broadcast, | 1571 | msgid, broadcast, |
1501 | source_address, source_lun); | 1572 | source_address, source_lun); |
1502 | 1573 | ||
1503 | /* Save the receive message so we can use it | 1574 | /* |
1504 | to deliver the response. */ | 1575 | * Save the receive message so we can use it |
1576 | * to deliver the response. | ||
1577 | */ | ||
1505 | smi_msg->user_data = recv_msg; | 1578 | smi_msg->user_data = recv_msg; |
1506 | } else { | 1579 | } else { |
1507 | /* It's a command, so get a sequence for it. */ | 1580 | /* It's a command, so get a sequence for it. */ |
1508 | 1581 | ||
1509 | spin_lock_irqsave(&(intf->seq_lock), flags); | 1582 | spin_lock_irqsave(&(intf->seq_lock), flags); |
1510 | 1583 | ||
1511 | spin_lock(&intf->counter_lock); | 1584 | ipmi_inc_stat(intf, sent_ipmb_commands); |
1512 | intf->sent_ipmb_commands++; | ||
1513 | spin_unlock(&intf->counter_lock); | ||
1514 | 1585 | ||
1515 | /* Create a sequence number with a 1 second | 1586 | /* |
1516 | timeout and 4 retries. */ | 1587 | * Create a sequence number with a 1 second |
1588 | * timeout and 4 retries. | ||
1589 | */ | ||
1517 | rv = intf_next_seq(intf, | 1590 | rv = intf_next_seq(intf, |
1518 | recv_msg, | 1591 | recv_msg, |
1519 | retry_time_ms, | 1592 | retry_time_ms, |
@@ -1522,34 +1595,42 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1522 | &ipmb_seq, | 1595 | &ipmb_seq, |
1523 | &seqid); | 1596 | &seqid); |
1524 | if (rv) { | 1597 | if (rv) { |
1525 | /* We have used up all the sequence numbers, | 1598 | /* |
1526 | probably, so abort. */ | 1599 | * We have used up all the sequence numbers, |
1600 | * probably, so abort. | ||
1601 | */ | ||
1527 | spin_unlock_irqrestore(&(intf->seq_lock), | 1602 | spin_unlock_irqrestore(&(intf->seq_lock), |
1528 | flags); | 1603 | flags); |
1529 | goto out_err; | 1604 | goto out_err; |
1530 | } | 1605 | } |
1531 | 1606 | ||
1532 | /* Store the sequence number in the message, | 1607 | /* |
1533 | so that when the send message response | 1608 | * Store the sequence number in the message, |
1534 | comes back we can start the timer. */ | 1609 | * so that when the send message response |
1610 | * comes back we can start the timer. | ||
1611 | */ | ||
1535 | format_ipmb_msg(smi_msg, msg, ipmb_addr, | 1612 | format_ipmb_msg(smi_msg, msg, ipmb_addr, |
1536 | STORE_SEQ_IN_MSGID(ipmb_seq, seqid), | 1613 | STORE_SEQ_IN_MSGID(ipmb_seq, seqid), |
1537 | ipmb_seq, broadcast, | 1614 | ipmb_seq, broadcast, |
1538 | source_address, source_lun); | 1615 | source_address, source_lun); |
1539 | 1616 | ||
1540 | /* Copy the message into the recv message data, so we | 1617 | /* |
1541 | can retransmit it later if necessary. */ | 1618 | * Copy the message into the recv message data, so we |
1619 | * can retransmit it later if necessary. | ||
1620 | */ | ||
1542 | memcpy(recv_msg->msg_data, smi_msg->data, | 1621 | memcpy(recv_msg->msg_data, smi_msg->data, |
1543 | smi_msg->data_size); | 1622 | smi_msg->data_size); |
1544 | recv_msg->msg.data = recv_msg->msg_data; | 1623 | recv_msg->msg.data = recv_msg->msg_data; |
1545 | recv_msg->msg.data_len = smi_msg->data_size; | 1624 | recv_msg->msg.data_len = smi_msg->data_size; |
1546 | 1625 | ||
1547 | /* We don't unlock until here, because we need | 1626 | /* |
1548 | to copy the completed message into the | 1627 | * We don't unlock until here, because we need |
1549 | recv_msg before we release the lock. | 1628 | * to copy the completed message into the |
1550 | Otherwise, race conditions may bite us. I | 1629 | * recv_msg before we release the lock. |
1551 | know that's pretty paranoid, but I prefer | 1630 | * Otherwise, race conditions may bite us. I |
1552 | to be correct. */ | 1631 | * know that's pretty paranoid, but I prefer |
1632 | * to be correct. | ||
1633 | */ | ||
1553 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 1634 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
1554 | } | 1635 | } |
1555 | } else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { | 1636 | } else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { |
@@ -1558,21 +1639,16 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1558 | long seqid; | 1639 | long seqid; |
1559 | 1640 | ||
1560 | if (addr->channel >= IPMI_MAX_CHANNELS) { | 1641 | if (addr->channel >= IPMI_MAX_CHANNELS) { |
1561 | spin_lock_irqsave(&intf->counter_lock, flags); | 1642 | ipmi_inc_stat(intf, sent_invalid_commands); |
1562 | intf->sent_invalid_commands++; | ||
1563 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1564 | rv = -EINVAL; | 1643 | rv = -EINVAL; |
1565 | goto out_err; | 1644 | goto out_err; |
1566 | } | 1645 | } |
1567 | 1646 | ||
1568 | if ((intf->channels[addr->channel].medium | 1647 | if ((intf->channels[addr->channel].medium |
1569 | != IPMI_CHANNEL_MEDIUM_8023LAN) | 1648 | != IPMI_CHANNEL_MEDIUM_8023LAN) |
1570 | && (intf->channels[addr->channel].medium | 1649 | && (intf->channels[addr->channel].medium |
1571 | != IPMI_CHANNEL_MEDIUM_ASYNC)) | 1650 | != IPMI_CHANNEL_MEDIUM_ASYNC)) { |
1572 | { | 1651 | ipmi_inc_stat(intf, sent_invalid_commands); |
1573 | spin_lock_irqsave(&intf->counter_lock, flags); | ||
1574 | intf->sent_invalid_commands++; | ||
1575 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1576 | rv = -EINVAL; | 1652 | rv = -EINVAL; |
1577 | goto out_err; | 1653 | goto out_err; |
1578 | } | 1654 | } |
@@ -1585,18 +1661,14 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1585 | 1661 | ||
1586 | /* 11 for the header and 1 for the checksum. */ | 1662 | /* 11 for the header and 1 for the checksum. */ |
1587 | if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) { | 1663 | if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) { |
1588 | spin_lock_irqsave(&intf->counter_lock, flags); | 1664 | ipmi_inc_stat(intf, sent_invalid_commands); |
1589 | intf->sent_invalid_commands++; | ||
1590 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1591 | rv = -EMSGSIZE; | 1665 | rv = -EMSGSIZE; |
1592 | goto out_err; | 1666 | goto out_err; |
1593 | } | 1667 | } |
1594 | 1668 | ||
1595 | lan_addr = (struct ipmi_lan_addr *) addr; | 1669 | lan_addr = (struct ipmi_lan_addr *) addr; |
1596 | if (lan_addr->lun > 3) { | 1670 | if (lan_addr->lun > 3) { |
1597 | spin_lock_irqsave(&intf->counter_lock, flags); | 1671 | ipmi_inc_stat(intf, sent_invalid_commands); |
1598 | intf->sent_invalid_commands++; | ||
1599 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1600 | rv = -EINVAL; | 1672 | rv = -EINVAL; |
1601 | goto out_err; | 1673 | goto out_err; |
1602 | } | 1674 | } |
@@ -1604,28 +1676,30 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1604 | memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr)); | 1676 | memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr)); |
1605 | 1677 | ||
1606 | if (recv_msg->msg.netfn & 0x1) { | 1678 | if (recv_msg->msg.netfn & 0x1) { |
1607 | /* It's a response, so use the user's sequence | 1679 | /* |
1608 | from msgid. */ | 1680 | * It's a response, so use the user's sequence |
1609 | spin_lock_irqsave(&intf->counter_lock, flags); | 1681 | * from msgid. |
1610 | intf->sent_lan_responses++; | 1682 | */ |
1611 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 1683 | ipmi_inc_stat(intf, sent_lan_responses); |
1612 | format_lan_msg(smi_msg, msg, lan_addr, msgid, | 1684 | format_lan_msg(smi_msg, msg, lan_addr, msgid, |
1613 | msgid, source_lun); | 1685 | msgid, source_lun); |
1614 | 1686 | ||
1615 | /* Save the receive message so we can use it | 1687 | /* |
1616 | to deliver the response. */ | 1688 | * Save the receive message so we can use it |
1689 | * to deliver the response. | ||
1690 | */ | ||
1617 | smi_msg->user_data = recv_msg; | 1691 | smi_msg->user_data = recv_msg; |
1618 | } else { | 1692 | } else { |
1619 | /* It's a command, so get a sequence for it. */ | 1693 | /* It's a command, so get a sequence for it. */ |
1620 | 1694 | ||
1621 | spin_lock_irqsave(&(intf->seq_lock), flags); | 1695 | spin_lock_irqsave(&(intf->seq_lock), flags); |
1622 | 1696 | ||
1623 | spin_lock(&intf->counter_lock); | 1697 | ipmi_inc_stat(intf, sent_lan_commands); |
1624 | intf->sent_lan_commands++; | ||
1625 | spin_unlock(&intf->counter_lock); | ||
1626 | 1698 | ||
1627 | /* Create a sequence number with a 1 second | 1699 | /* |
1628 | timeout and 4 retries. */ | 1700 | * Create a sequence number with a 1 second |
1701 | * timeout and 4 retries. | ||
1702 | */ | ||
1629 | rv = intf_next_seq(intf, | 1703 | rv = intf_next_seq(intf, |
1630 | recv_msg, | 1704 | recv_msg, |
1631 | retry_time_ms, | 1705 | retry_time_ms, |
@@ -1634,40 +1708,46 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1634 | &ipmb_seq, | 1708 | &ipmb_seq, |
1635 | &seqid); | 1709 | &seqid); |
1636 | if (rv) { | 1710 | if (rv) { |
1637 | /* We have used up all the sequence numbers, | 1711 | /* |
1638 | probably, so abort. */ | 1712 | * We have used up all the sequence numbers, |
1713 | * probably, so abort. | ||
1714 | */ | ||
1639 | spin_unlock_irqrestore(&(intf->seq_lock), | 1715 | spin_unlock_irqrestore(&(intf->seq_lock), |
1640 | flags); | 1716 | flags); |
1641 | goto out_err; | 1717 | goto out_err; |
1642 | } | 1718 | } |
1643 | 1719 | ||
1644 | /* Store the sequence number in the message, | 1720 | /* |
1645 | so that when the send message response | 1721 | * Store the sequence number in the message, |
1646 | comes back we can start the timer. */ | 1722 | * so that when the send message response |
1723 | * comes back we can start the timer. | ||
1724 | */ | ||
1647 | format_lan_msg(smi_msg, msg, lan_addr, | 1725 | format_lan_msg(smi_msg, msg, lan_addr, |
1648 | STORE_SEQ_IN_MSGID(ipmb_seq, seqid), | 1726 | STORE_SEQ_IN_MSGID(ipmb_seq, seqid), |
1649 | ipmb_seq, source_lun); | 1727 | ipmb_seq, source_lun); |
1650 | 1728 | ||
1651 | /* Copy the message into the recv message data, so we | 1729 | /* |
1652 | can retransmit it later if necessary. */ | 1730 | * Copy the message into the recv message data, so we |
1731 | * can retransmit it later if necessary. | ||
1732 | */ | ||
1653 | memcpy(recv_msg->msg_data, smi_msg->data, | 1733 | memcpy(recv_msg->msg_data, smi_msg->data, |
1654 | smi_msg->data_size); | 1734 | smi_msg->data_size); |
1655 | recv_msg->msg.data = recv_msg->msg_data; | 1735 | recv_msg->msg.data = recv_msg->msg_data; |
1656 | recv_msg->msg.data_len = smi_msg->data_size; | 1736 | recv_msg->msg.data_len = smi_msg->data_size; |
1657 | 1737 | ||
1658 | /* We don't unlock until here, because we need | 1738 | /* |
1659 | to copy the completed message into the | 1739 | * We don't unlock until here, because we need |
1660 | recv_msg before we release the lock. | 1740 | * to copy the completed message into the |
1661 | Otherwise, race conditions may bite us. I | 1741 | * recv_msg before we release the lock. |
1662 | know that's pretty paranoid, but I prefer | 1742 | * Otherwise, race conditions may bite us. I |
1663 | to be correct. */ | 1743 | * know that's pretty paranoid, but I prefer |
1744 | * to be correct. | ||
1745 | */ | ||
1664 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 1746 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
1665 | } | 1747 | } |
1666 | } else { | 1748 | } else { |
1667 | /* Unknown address type. */ | 1749 | /* Unknown address type. */ |
1668 | spin_lock_irqsave(&intf->counter_lock, flags); | 1750 | ipmi_inc_stat(intf, sent_invalid_commands); |
1669 | intf->sent_invalid_commands++; | ||
1670 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
1671 | rv = -EINVAL; | 1751 | rv = -EINVAL; |
1672 | goto out_err; | 1752 | goto out_err; |
1673 | } | 1753 | } |
@@ -1735,6 +1815,7 @@ int ipmi_request_settime(ipmi_user_t user, | |||
1735 | retries, | 1815 | retries, |
1736 | retry_time_ms); | 1816 | retry_time_ms); |
1737 | } | 1817 | } |
1818 | EXPORT_SYMBOL(ipmi_request_settime); | ||
1738 | 1819 | ||
1739 | int ipmi_request_supply_msgs(ipmi_user_t user, | 1820 | int ipmi_request_supply_msgs(ipmi_user_t user, |
1740 | struct ipmi_addr *addr, | 1821 | struct ipmi_addr *addr, |
@@ -1766,6 +1847,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1766 | lun, | 1847 | lun, |
1767 | -1, 0); | 1848 | -1, 0); |
1768 | } | 1849 | } |
1850 | EXPORT_SYMBOL(ipmi_request_supply_msgs); | ||
1769 | 1851 | ||
1770 | #ifdef CONFIG_PROC_FS | 1852 | #ifdef CONFIG_PROC_FS |
1771 | static int ipmb_file_read_proc(char *page, char **start, off_t off, | 1853 | static int ipmb_file_read_proc(char *page, char **start, off_t off, |
@@ -1790,7 +1872,7 @@ static int version_file_read_proc(char *page, char **start, off_t off, | |||
1790 | char *out = (char *) page; | 1872 | char *out = (char *) page; |
1791 | ipmi_smi_t intf = data; | 1873 | ipmi_smi_t intf = data; |
1792 | 1874 | ||
1793 | return sprintf(out, "%d.%d\n", | 1875 | return sprintf(out, "%u.%u\n", |
1794 | ipmi_version_major(&intf->bmc->id), | 1876 | ipmi_version_major(&intf->bmc->id), |
1795 | ipmi_version_minor(&intf->bmc->id)); | 1877 | ipmi_version_minor(&intf->bmc->id)); |
1796 | } | 1878 | } |
@@ -1801,65 +1883,65 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
1801 | char *out = (char *) page; | 1883 | char *out = (char *) page; |
1802 | ipmi_smi_t intf = data; | 1884 | ipmi_smi_t intf = data; |
1803 | 1885 | ||
1804 | out += sprintf(out, "sent_invalid_commands: %d\n", | 1886 | out += sprintf(out, "sent_invalid_commands: %u\n", |
1805 | intf->sent_invalid_commands); | 1887 | ipmi_get_stat(intf, sent_invalid_commands)); |
1806 | out += sprintf(out, "sent_local_commands: %d\n", | 1888 | out += sprintf(out, "sent_local_commands: %u\n", |
1807 | intf->sent_local_commands); | 1889 | ipmi_get_stat(intf, sent_local_commands)); |
1808 | out += sprintf(out, "handled_local_responses: %d\n", | 1890 | out += sprintf(out, "handled_local_responses: %u\n", |
1809 | intf->handled_local_responses); | 1891 | ipmi_get_stat(intf, handled_local_responses)); |
1810 | out += sprintf(out, "unhandled_local_responses: %d\n", | 1892 | out += sprintf(out, "unhandled_local_responses: %u\n", |
1811 | intf->unhandled_local_responses); | 1893 | ipmi_get_stat(intf, unhandled_local_responses)); |
1812 | out += sprintf(out, "sent_ipmb_commands: %d\n", | 1894 | out += sprintf(out, "sent_ipmb_commands: %u\n", |
1813 | intf->sent_ipmb_commands); | 1895 | ipmi_get_stat(intf, sent_ipmb_commands)); |
1814 | out += sprintf(out, "sent_ipmb_command_errs: %d\n", | 1896 | out += sprintf(out, "sent_ipmb_command_errs: %u\n", |
1815 | intf->sent_ipmb_command_errs); | 1897 | ipmi_get_stat(intf, sent_ipmb_command_errs)); |
1816 | out += sprintf(out, "retransmitted_ipmb_commands: %d\n", | 1898 | out += sprintf(out, "retransmitted_ipmb_commands: %u\n", |
1817 | intf->retransmitted_ipmb_commands); | 1899 | ipmi_get_stat(intf, retransmitted_ipmb_commands)); |
1818 | out += sprintf(out, "timed_out_ipmb_commands: %d\n", | 1900 | out += sprintf(out, "timed_out_ipmb_commands: %u\n", |
1819 | intf->timed_out_ipmb_commands); | 1901 | ipmi_get_stat(intf, timed_out_ipmb_commands)); |
1820 | out += sprintf(out, "timed_out_ipmb_broadcasts: %d\n", | 1902 | out += sprintf(out, "timed_out_ipmb_broadcasts: %u\n", |
1821 | intf->timed_out_ipmb_broadcasts); | 1903 | ipmi_get_stat(intf, timed_out_ipmb_broadcasts)); |
1822 | out += sprintf(out, "sent_ipmb_responses: %d\n", | 1904 | out += sprintf(out, "sent_ipmb_responses: %u\n", |
1823 | intf->sent_ipmb_responses); | 1905 | ipmi_get_stat(intf, sent_ipmb_responses)); |
1824 | out += sprintf(out, "handled_ipmb_responses: %d\n", | 1906 | out += sprintf(out, "handled_ipmb_responses: %u\n", |
1825 | intf->handled_ipmb_responses); | 1907 | ipmi_get_stat(intf, handled_ipmb_responses)); |
1826 | out += sprintf(out, "invalid_ipmb_responses: %d\n", | 1908 | out += sprintf(out, "invalid_ipmb_responses: %u\n", |
1827 | intf->invalid_ipmb_responses); | 1909 | ipmi_get_stat(intf, invalid_ipmb_responses)); |
1828 | out += sprintf(out, "unhandled_ipmb_responses: %d\n", | 1910 | out += sprintf(out, "unhandled_ipmb_responses: %u\n", |
1829 | intf->unhandled_ipmb_responses); | 1911 | ipmi_get_stat(intf, unhandled_ipmb_responses)); |
1830 | out += sprintf(out, "sent_lan_commands: %d\n", | 1912 | out += sprintf(out, "sent_lan_commands: %u\n", |
1831 | intf->sent_lan_commands); | 1913 | ipmi_get_stat(intf, sent_lan_commands)); |
1832 | out += sprintf(out, "sent_lan_command_errs: %d\n", | 1914 | out += sprintf(out, "sent_lan_command_errs: %u\n", |
1833 | intf->sent_lan_command_errs); | 1915 | ipmi_get_stat(intf, sent_lan_command_errs)); |
1834 | out += sprintf(out, "retransmitted_lan_commands: %d\n", | 1916 | out += sprintf(out, "retransmitted_lan_commands: %u\n", |
1835 | intf->retransmitted_lan_commands); | 1917 | ipmi_get_stat(intf, retransmitted_lan_commands)); |
1836 | out += sprintf(out, "timed_out_lan_commands: %d\n", | 1918 | out += sprintf(out, "timed_out_lan_commands: %u\n", |
1837 | intf->timed_out_lan_commands); | 1919 | ipmi_get_stat(intf, timed_out_lan_commands)); |
1838 | out += sprintf(out, "sent_lan_responses: %d\n", | 1920 | out += sprintf(out, "sent_lan_responses: %u\n", |
1839 | intf->sent_lan_responses); | 1921 | ipmi_get_stat(intf, sent_lan_responses)); |
1840 | out += sprintf(out, "handled_lan_responses: %d\n", | 1922 | out += sprintf(out, "handled_lan_responses: %u\n", |
1841 | intf->handled_lan_responses); | 1923 | ipmi_get_stat(intf, handled_lan_responses)); |
1842 | out += sprintf(out, "invalid_lan_responses: %d\n", | 1924 | out += sprintf(out, "invalid_lan_responses: %u\n", |
1843 | intf->invalid_lan_responses); | 1925 | ipmi_get_stat(intf, invalid_lan_responses)); |
1844 | out += sprintf(out, "unhandled_lan_responses: %d\n", | 1926 | out += sprintf(out, "unhandled_lan_responses: %u\n", |
1845 | intf->unhandled_lan_responses); | 1927 | ipmi_get_stat(intf, unhandled_lan_responses)); |
1846 | out += sprintf(out, "handled_commands: %d\n", | 1928 | out += sprintf(out, "handled_commands: %u\n", |
1847 | intf->handled_commands); | 1929 | ipmi_get_stat(intf, handled_commands)); |
1848 | out += sprintf(out, "invalid_commands: %d\n", | 1930 | out += sprintf(out, "invalid_commands: %u\n", |
1849 | intf->invalid_commands); | 1931 | ipmi_get_stat(intf, invalid_commands)); |
1850 | out += sprintf(out, "unhandled_commands: %d\n", | 1932 | out += sprintf(out, "unhandled_commands: %u\n", |
1851 | intf->unhandled_commands); | 1933 | ipmi_get_stat(intf, unhandled_commands)); |
1852 | out += sprintf(out, "invalid_events: %d\n", | 1934 | out += sprintf(out, "invalid_events: %u\n", |
1853 | intf->invalid_events); | 1935 | ipmi_get_stat(intf, invalid_events)); |
1854 | out += sprintf(out, "events: %d\n", | 1936 | out += sprintf(out, "events: %u\n", |
1855 | intf->events); | 1937 | ipmi_get_stat(intf, events)); |
1856 | 1938 | ||
1857 | return (out - ((char *) page)); | 1939 | return (out - ((char *) page)); |
1858 | } | 1940 | } |
1859 | #endif /* CONFIG_PROC_FS */ | 1941 | #endif /* CONFIG_PROC_FS */ |
1860 | 1942 | ||
1861 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | 1943 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, |
1862 | read_proc_t *read_proc, write_proc_t *write_proc, | 1944 | read_proc_t *read_proc, |
1863 | void *data, struct module *owner) | 1945 | void *data, struct module *owner) |
1864 | { | 1946 | { |
1865 | int rv = 0; | 1947 | int rv = 0; |
@@ -1886,7 +1968,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | |||
1886 | } else { | 1968 | } else { |
1887 | file->data = data; | 1969 | file->data = data; |
1888 | file->read_proc = read_proc; | 1970 | file->read_proc = read_proc; |
1889 | file->write_proc = write_proc; | ||
1890 | file->owner = owner; | 1971 | file->owner = owner; |
1891 | 1972 | ||
1892 | mutex_lock(&smi->proc_entry_lock); | 1973 | mutex_lock(&smi->proc_entry_lock); |
@@ -1899,6 +1980,7 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | |||
1899 | 1980 | ||
1900 | return rv; | 1981 | return rv; |
1901 | } | 1982 | } |
1983 | EXPORT_SYMBOL(ipmi_smi_add_proc_entry); | ||
1902 | 1984 | ||
1903 | static int add_proc_entries(ipmi_smi_t smi, int num) | 1985 | static int add_proc_entries(ipmi_smi_t smi, int num) |
1904 | { | 1986 | { |
@@ -1909,23 +1991,22 @@ static int add_proc_entries(ipmi_smi_t smi, int num) | |||
1909 | smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); | 1991 | smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); |
1910 | if (!smi->proc_dir) | 1992 | if (!smi->proc_dir) |
1911 | rv = -ENOMEM; | 1993 | rv = -ENOMEM; |
1912 | else { | 1994 | else |
1913 | smi->proc_dir->owner = THIS_MODULE; | 1995 | smi->proc_dir->owner = THIS_MODULE; |
1914 | } | ||
1915 | 1996 | ||
1916 | if (rv == 0) | 1997 | if (rv == 0) |
1917 | rv = ipmi_smi_add_proc_entry(smi, "stats", | 1998 | rv = ipmi_smi_add_proc_entry(smi, "stats", |
1918 | stat_file_read_proc, NULL, | 1999 | stat_file_read_proc, |
1919 | smi, THIS_MODULE); | 2000 | smi, THIS_MODULE); |
1920 | 2001 | ||
1921 | if (rv == 0) | 2002 | if (rv == 0) |
1922 | rv = ipmi_smi_add_proc_entry(smi, "ipmb", | 2003 | rv = ipmi_smi_add_proc_entry(smi, "ipmb", |
1923 | ipmb_file_read_proc, NULL, | 2004 | ipmb_file_read_proc, |
1924 | smi, THIS_MODULE); | 2005 | smi, THIS_MODULE); |
1925 | 2006 | ||
1926 | if (rv == 0) | 2007 | if (rv == 0) |
1927 | rv = ipmi_smi_add_proc_entry(smi, "version", | 2008 | rv = ipmi_smi_add_proc_entry(smi, "version", |
1928 | version_file_read_proc, NULL, | 2009 | version_file_read_proc, |
1929 | smi, THIS_MODULE); | 2010 | smi, THIS_MODULE); |
1930 | #endif /* CONFIG_PROC_FS */ | 2011 | #endif /* CONFIG_PROC_FS */ |
1931 | 2012 | ||
@@ -2210,37 +2291,47 @@ static int create_files(struct bmc_device *bmc) | |||
2210 | 2291 | ||
2211 | err = device_create_file(&bmc->dev->dev, | 2292 | err = device_create_file(&bmc->dev->dev, |
2212 | &bmc->device_id_attr); | 2293 | &bmc->device_id_attr); |
2213 | if (err) goto out; | 2294 | if (err) |
2295 | goto out; | ||
2214 | err = device_create_file(&bmc->dev->dev, | 2296 | err = device_create_file(&bmc->dev->dev, |
2215 | &bmc->provides_dev_sdrs_attr); | 2297 | &bmc->provides_dev_sdrs_attr); |
2216 | if (err) goto out_devid; | 2298 | if (err) |
2299 | goto out_devid; | ||
2217 | err = device_create_file(&bmc->dev->dev, | 2300 | err = device_create_file(&bmc->dev->dev, |
2218 | &bmc->revision_attr); | 2301 | &bmc->revision_attr); |
2219 | if (err) goto out_sdrs; | 2302 | if (err) |
2303 | goto out_sdrs; | ||
2220 | err = device_create_file(&bmc->dev->dev, | 2304 | err = device_create_file(&bmc->dev->dev, |
2221 | &bmc->firmware_rev_attr); | 2305 | &bmc->firmware_rev_attr); |
2222 | if (err) goto out_rev; | 2306 | if (err) |
2307 | goto out_rev; | ||
2223 | err = device_create_file(&bmc->dev->dev, | 2308 | err = device_create_file(&bmc->dev->dev, |
2224 | &bmc->version_attr); | 2309 | &bmc->version_attr); |
2225 | if (err) goto out_firm; | 2310 | if (err) |
2311 | goto out_firm; | ||
2226 | err = device_create_file(&bmc->dev->dev, | 2312 | err = device_create_file(&bmc->dev->dev, |
2227 | &bmc->add_dev_support_attr); | 2313 | &bmc->add_dev_support_attr); |
2228 | if (err) goto out_version; | 2314 | if (err) |
2315 | goto out_version; | ||
2229 | err = device_create_file(&bmc->dev->dev, | 2316 | err = device_create_file(&bmc->dev->dev, |
2230 | &bmc->manufacturer_id_attr); | 2317 | &bmc->manufacturer_id_attr); |
2231 | if (err) goto out_add_dev; | 2318 | if (err) |
2319 | goto out_add_dev; | ||
2232 | err = device_create_file(&bmc->dev->dev, | 2320 | err = device_create_file(&bmc->dev->dev, |
2233 | &bmc->product_id_attr); | 2321 | &bmc->product_id_attr); |
2234 | if (err) goto out_manu; | 2322 | if (err) |
2323 | goto out_manu; | ||
2235 | if (bmc->id.aux_firmware_revision_set) { | 2324 | if (bmc->id.aux_firmware_revision_set) { |
2236 | err = device_create_file(&bmc->dev->dev, | 2325 | err = device_create_file(&bmc->dev->dev, |
2237 | &bmc->aux_firmware_rev_attr); | 2326 | &bmc->aux_firmware_rev_attr); |
2238 | if (err) goto out_prod_id; | 2327 | if (err) |
2328 | goto out_prod_id; | ||
2239 | } | 2329 | } |
2240 | if (bmc->guid_set) { | 2330 | if (bmc->guid_set) { |
2241 | err = device_create_file(&bmc->dev->dev, | 2331 | err = device_create_file(&bmc->dev->dev, |
2242 | &bmc->guid_attr); | 2332 | &bmc->guid_attr); |
2243 | if (err) goto out_aux_firm; | 2333 | if (err) |
2334 | goto out_aux_firm; | ||
2244 | } | 2335 | } |
2245 | 2336 | ||
2246 | return 0; | 2337 | return 0; |
@@ -2368,8 +2459,10 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2368 | "ipmi_msghandler:" | 2459 | "ipmi_msghandler:" |
2369 | " Unable to register bmc device: %d\n", | 2460 | " Unable to register bmc device: %d\n", |
2370 | rv); | 2461 | rv); |
2371 | /* Don't go to out_err, you can only do that if | 2462 | /* |
2372 | the device is registered already. */ | 2463 | * Don't go to out_err, you can only do that if |
2464 | * the device is registered already. | ||
2465 | */ | ||
2373 | return rv; | 2466 | return rv; |
2374 | } | 2467 | } |
2375 | 2468 | ||
@@ -2560,17 +2653,18 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
2560 | 2653 | ||
2561 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) | 2654 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) |
2562 | && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) | 2655 | && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) |
2563 | && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD)) | 2656 | && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD)) { |
2564 | { | ||
2565 | /* It's the one we want */ | 2657 | /* It's the one we want */ |
2566 | if (msg->msg.data[0] != 0) { | 2658 | if (msg->msg.data[0] != 0) { |
2567 | /* Got an error from the channel, just go on. */ | 2659 | /* Got an error from the channel, just go on. */ |
2568 | 2660 | ||
2569 | if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) { | 2661 | if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) { |
2570 | /* If the MC does not support this | 2662 | /* |
2571 | command, that is legal. We just | 2663 | * If the MC does not support this |
2572 | assume it has one IPMB at channel | 2664 | * command, that is legal. We just |
2573 | zero. */ | 2665 | * assume it has one IPMB at channel |
2666 | * zero. | ||
2667 | */ | ||
2574 | intf->channels[0].medium | 2668 | intf->channels[0].medium |
2575 | = IPMI_CHANNEL_MEDIUM_IPMB; | 2669 | = IPMI_CHANNEL_MEDIUM_IPMB; |
2576 | intf->channels[0].protocol | 2670 | intf->channels[0].protocol |
@@ -2591,7 +2685,7 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
2591 | intf->channels[chan].medium = msg->msg.data[2] & 0x7f; | 2685 | intf->channels[chan].medium = msg->msg.data[2] & 0x7f; |
2592 | intf->channels[chan].protocol = msg->msg.data[3] & 0x1f; | 2686 | intf->channels[chan].protocol = msg->msg.data[3] & 0x1f; |
2593 | 2687 | ||
2594 | next_channel: | 2688 | next_channel: |
2595 | intf->curr_channel++; | 2689 | intf->curr_channel++; |
2596 | if (intf->curr_channel >= IPMI_MAX_CHANNELS) | 2690 | if (intf->curr_channel >= IPMI_MAX_CHANNELS) |
2597 | wake_up(&intf->waitq); | 2691 | wake_up(&intf->waitq); |
@@ -2619,6 +2713,7 @@ void ipmi_poll_interface(ipmi_user_t user) | |||
2619 | if (intf->handlers->poll) | 2713 | if (intf->handlers->poll) |
2620 | intf->handlers->poll(intf->send_info); | 2714 | intf->handlers->poll(intf->send_info); |
2621 | } | 2715 | } |
2716 | EXPORT_SYMBOL(ipmi_poll_interface); | ||
2622 | 2717 | ||
2623 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | 2718 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, |
2624 | void *send_info, | 2719 | void *send_info, |
@@ -2633,14 +2728,18 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2633 | ipmi_smi_t tintf; | 2728 | ipmi_smi_t tintf; |
2634 | struct list_head *link; | 2729 | struct list_head *link; |
2635 | 2730 | ||
2636 | /* Make sure the driver is actually initialized, this handles | 2731 | /* |
2637 | problems with initialization order. */ | 2732 | * Make sure the driver is actually initialized, this handles |
2733 | * problems with initialization order. | ||
2734 | */ | ||
2638 | if (!initialized) { | 2735 | if (!initialized) { |
2639 | rv = ipmi_init_msghandler(); | 2736 | rv = ipmi_init_msghandler(); |
2640 | if (rv) | 2737 | if (rv) |
2641 | return rv; | 2738 | return rv; |
2642 | /* The init code doesn't return an error if it was turned | 2739 | /* |
2643 | off, but it won't initialize. Check that. */ | 2740 | * The init code doesn't return an error if it was turned |
2741 | * off, but it won't initialize. Check that. | ||
2742 | */ | ||
2644 | if (!initialized) | 2743 | if (!initialized) |
2645 | return -ENODEV; | 2744 | return -ENODEV; |
2646 | } | 2745 | } |
@@ -2688,8 +2787,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2688 | spin_lock_init(&intf->maintenance_mode_lock); | 2787 | spin_lock_init(&intf->maintenance_mode_lock); |
2689 | INIT_LIST_HEAD(&intf->cmd_rcvrs); | 2788 | INIT_LIST_HEAD(&intf->cmd_rcvrs); |
2690 | init_waitqueue_head(&intf->waitq); | 2789 | init_waitqueue_head(&intf->waitq); |
2790 | for (i = 0; i < IPMI_NUM_STATS; i++) | ||
2791 | atomic_set(&intf->stats[i], 0); | ||
2691 | 2792 | ||
2692 | spin_lock_init(&intf->counter_lock); | ||
2693 | intf->proc_dir = NULL; | 2793 | intf->proc_dir = NULL; |
2694 | 2794 | ||
2695 | mutex_lock(&smi_watchers_mutex); | 2795 | mutex_lock(&smi_watchers_mutex); |
@@ -2717,11 +2817,12 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2717 | get_guid(intf); | 2817 | get_guid(intf); |
2718 | 2818 | ||
2719 | if ((intf->ipmi_version_major > 1) | 2819 | if ((intf->ipmi_version_major > 1) |
2720 | || ((intf->ipmi_version_major == 1) | 2820 | || ((intf->ipmi_version_major == 1) |
2721 | && (intf->ipmi_version_minor >= 5))) | 2821 | && (intf->ipmi_version_minor >= 5))) { |
2722 | { | 2822 | /* |
2723 | /* Start scanning the channels to see what is | 2823 | * Start scanning the channels to see what is |
2724 | available. */ | 2824 | * available. |
2825 | */ | ||
2725 | intf->null_user_handler = channel_handler; | 2826 | intf->null_user_handler = channel_handler; |
2726 | intf->curr_channel = 0; | 2827 | intf->curr_channel = 0; |
2727 | rv = send_channel_info_cmd(intf, 0); | 2828 | rv = send_channel_info_cmd(intf, 0); |
@@ -2769,6 +2870,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2769 | 2870 | ||
2770 | return rv; | 2871 | return rv; |
2771 | } | 2872 | } |
2873 | EXPORT_SYMBOL(ipmi_register_smi); | ||
2772 | 2874 | ||
2773 | static void cleanup_smi_msgs(ipmi_smi_t intf) | 2875 | static void cleanup_smi_msgs(ipmi_smi_t intf) |
2774 | { | 2876 | { |
@@ -2803,8 +2905,10 @@ int ipmi_unregister_smi(ipmi_smi_t intf) | |||
2803 | 2905 | ||
2804 | remove_proc_entries(intf); | 2906 | remove_proc_entries(intf); |
2805 | 2907 | ||
2806 | /* Call all the watcher interfaces to tell them that | 2908 | /* |
2807 | an interface is gone. */ | 2909 | * Call all the watcher interfaces to tell them that |
2910 | * an interface is gone. | ||
2911 | */ | ||
2808 | list_for_each_entry(w, &smi_watchers, link) | 2912 | list_for_each_entry(w, &smi_watchers, link) |
2809 | w->smi_gone(intf_num); | 2913 | w->smi_gone(intf_num); |
2810 | mutex_unlock(&smi_watchers_mutex); | 2914 | mutex_unlock(&smi_watchers_mutex); |
@@ -2812,22 +2916,21 @@ int ipmi_unregister_smi(ipmi_smi_t intf) | |||
2812 | kref_put(&intf->refcount, intf_free); | 2916 | kref_put(&intf->refcount, intf_free); |
2813 | return 0; | 2917 | return 0; |
2814 | } | 2918 | } |
2919 | EXPORT_SYMBOL(ipmi_unregister_smi); | ||
2815 | 2920 | ||
2816 | static int handle_ipmb_get_msg_rsp(ipmi_smi_t intf, | 2921 | static int handle_ipmb_get_msg_rsp(ipmi_smi_t intf, |
2817 | struct ipmi_smi_msg *msg) | 2922 | struct ipmi_smi_msg *msg) |
2818 | { | 2923 | { |
2819 | struct ipmi_ipmb_addr ipmb_addr; | 2924 | struct ipmi_ipmb_addr ipmb_addr; |
2820 | struct ipmi_recv_msg *recv_msg; | 2925 | struct ipmi_recv_msg *recv_msg; |
2821 | unsigned long flags; | ||
2822 | 2926 | ||
2823 | 2927 | /* | |
2824 | /* This is 11, not 10, because the response must contain a | 2928 | * This is 11, not 10, because the response must contain a |
2825 | * completion code. */ | 2929 | * completion code. |
2930 | */ | ||
2826 | if (msg->rsp_size < 11) { | 2931 | if (msg->rsp_size < 11) { |
2827 | /* Message not big enough, just ignore it. */ | 2932 | /* Message not big enough, just ignore it. */ |
2828 | spin_lock_irqsave(&intf->counter_lock, flags); | 2933 | ipmi_inc_stat(intf, invalid_ipmb_responses); |
2829 | intf->invalid_ipmb_responses++; | ||
2830 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2831 | return 0; | 2934 | return 0; |
2832 | } | 2935 | } |
2833 | 2936 | ||
@@ -2841,37 +2944,38 @@ static int handle_ipmb_get_msg_rsp(ipmi_smi_t intf, | |||
2841 | ipmb_addr.channel = msg->rsp[3] & 0x0f; | 2944 | ipmb_addr.channel = msg->rsp[3] & 0x0f; |
2842 | ipmb_addr.lun = msg->rsp[7] & 3; | 2945 | ipmb_addr.lun = msg->rsp[7] & 3; |
2843 | 2946 | ||
2844 | /* It's a response from a remote entity. Look up the sequence | 2947 | /* |
2845 | number and handle the response. */ | 2948 | * It's a response from a remote entity. Look up the sequence |
2949 | * number and handle the response. | ||
2950 | */ | ||
2846 | if (intf_find_seq(intf, | 2951 | if (intf_find_seq(intf, |
2847 | msg->rsp[7] >> 2, | 2952 | msg->rsp[7] >> 2, |
2848 | msg->rsp[3] & 0x0f, | 2953 | msg->rsp[3] & 0x0f, |
2849 | msg->rsp[8], | 2954 | msg->rsp[8], |
2850 | (msg->rsp[4] >> 2) & (~1), | 2955 | (msg->rsp[4] >> 2) & (~1), |
2851 | (struct ipmi_addr *) &(ipmb_addr), | 2956 | (struct ipmi_addr *) &(ipmb_addr), |
2852 | &recv_msg)) | 2957 | &recv_msg)) { |
2853 | { | 2958 | /* |
2854 | /* We were unable to find the sequence number, | 2959 | * We were unable to find the sequence number, |
2855 | so just nuke the message. */ | 2960 | * so just nuke the message. |
2856 | spin_lock_irqsave(&intf->counter_lock, flags); | 2961 | */ |
2857 | intf->unhandled_ipmb_responses++; | 2962 | ipmi_inc_stat(intf, unhandled_ipmb_responses); |
2858 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2859 | return 0; | 2963 | return 0; |
2860 | } | 2964 | } |
2861 | 2965 | ||
2862 | memcpy(recv_msg->msg_data, | 2966 | memcpy(recv_msg->msg_data, |
2863 | &(msg->rsp[9]), | 2967 | &(msg->rsp[9]), |
2864 | msg->rsp_size - 9); | 2968 | msg->rsp_size - 9); |
2865 | /* THe other fields matched, so no need to set them, except | 2969 | /* |
2866 | for netfn, which needs to be the response that was | 2970 | * The other fields matched, so no need to set them, except |
2867 | returned, not the request value. */ | 2971 | * for netfn, which needs to be the response that was |
2972 | * returned, not the request value. | ||
2973 | */ | ||
2868 | recv_msg->msg.netfn = msg->rsp[4] >> 2; | 2974 | recv_msg->msg.netfn = msg->rsp[4] >> 2; |
2869 | recv_msg->msg.data = recv_msg->msg_data; | 2975 | recv_msg->msg.data = recv_msg->msg_data; |
2870 | recv_msg->msg.data_len = msg->rsp_size - 10; | 2976 | recv_msg->msg.data_len = msg->rsp_size - 10; |
2871 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | 2977 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; |
2872 | spin_lock_irqsave(&intf->counter_lock, flags); | 2978 | ipmi_inc_stat(intf, handled_ipmb_responses); |
2873 | intf->handled_ipmb_responses++; | ||
2874 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2875 | deliver_response(recv_msg); | 2979 | deliver_response(recv_msg); |
2876 | 2980 | ||
2877 | return 0; | 2981 | return 0; |
@@ -2888,14 +2992,11 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2888 | ipmi_user_t user = NULL; | 2992 | ipmi_user_t user = NULL; |
2889 | struct ipmi_ipmb_addr *ipmb_addr; | 2993 | struct ipmi_ipmb_addr *ipmb_addr; |
2890 | struct ipmi_recv_msg *recv_msg; | 2994 | struct ipmi_recv_msg *recv_msg; |
2891 | unsigned long flags; | ||
2892 | struct ipmi_smi_handlers *handlers; | 2995 | struct ipmi_smi_handlers *handlers; |
2893 | 2996 | ||
2894 | if (msg->rsp_size < 10) { | 2997 | if (msg->rsp_size < 10) { |
2895 | /* Message not big enough, just ignore it. */ | 2998 | /* Message not big enough, just ignore it. */ |
2896 | spin_lock_irqsave(&intf->counter_lock, flags); | 2999 | ipmi_inc_stat(intf, invalid_commands); |
2897 | intf->invalid_commands++; | ||
2898 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2899 | return 0; | 3000 | return 0; |
2900 | } | 3001 | } |
2901 | 3002 | ||
@@ -2919,19 +3020,17 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2919 | 3020 | ||
2920 | if (user == NULL) { | 3021 | if (user == NULL) { |
2921 | /* We didn't find a user, deliver an error response. */ | 3022 | /* We didn't find a user, deliver an error response. */ |
2922 | spin_lock_irqsave(&intf->counter_lock, flags); | 3023 | ipmi_inc_stat(intf, unhandled_commands); |
2923 | intf->unhandled_commands++; | ||
2924 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2925 | 3024 | ||
2926 | msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); | 3025 | msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); |
2927 | msg->data[1] = IPMI_SEND_MSG_CMD; | 3026 | msg->data[1] = IPMI_SEND_MSG_CMD; |
2928 | msg->data[2] = msg->rsp[3]; | 3027 | msg->data[2] = msg->rsp[3]; |
2929 | msg->data[3] = msg->rsp[6]; | 3028 | msg->data[3] = msg->rsp[6]; |
2930 | msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); | 3029 | msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); |
2931 | msg->data[5] = ipmb_checksum(&(msg->data[3]), 2); | 3030 | msg->data[5] = ipmb_checksum(&(msg->data[3]), 2); |
2932 | msg->data[6] = intf->channels[msg->rsp[3] & 0xf].address; | 3031 | msg->data[6] = intf->channels[msg->rsp[3] & 0xf].address; |
2933 | /* rqseq/lun */ | 3032 | /* rqseq/lun */ |
2934 | msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); | 3033 | msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); |
2935 | msg->data[8] = msg->rsp[8]; /* cmd */ | 3034 | msg->data[8] = msg->rsp[8]; /* cmd */ |
2936 | msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE; | 3035 | msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE; |
2937 | msg->data[10] = ipmb_checksum(&(msg->data[6]), 4); | 3036 | msg->data[10] = ipmb_checksum(&(msg->data[6]), 4); |
@@ -2950,23 +3049,25 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2950 | handlers = intf->handlers; | 3049 | handlers = intf->handlers; |
2951 | if (handlers) { | 3050 | if (handlers) { |
2952 | handlers->sender(intf->send_info, msg, 0); | 3051 | handlers->sender(intf->send_info, msg, 0); |
2953 | /* We used the message, so return the value | 3052 | /* |
2954 | that causes it to not be freed or | 3053 | * We used the message, so return the value |
2955 | queued. */ | 3054 | * that causes it to not be freed or |
3055 | * queued. | ||
3056 | */ | ||
2956 | rv = -1; | 3057 | rv = -1; |
2957 | } | 3058 | } |
2958 | rcu_read_unlock(); | 3059 | rcu_read_unlock(); |
2959 | } else { | 3060 | } else { |
2960 | /* Deliver the message to the user. */ | 3061 | /* Deliver the message to the user. */ |
2961 | spin_lock_irqsave(&intf->counter_lock, flags); | 3062 | ipmi_inc_stat(intf, handled_commands); |
2962 | intf->handled_commands++; | ||
2963 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
2964 | 3063 | ||
2965 | recv_msg = ipmi_alloc_recv_msg(); | 3064 | recv_msg = ipmi_alloc_recv_msg(); |
2966 | if (!recv_msg) { | 3065 | if (!recv_msg) { |
2967 | /* We couldn't allocate memory for the | 3066 | /* |
2968 | message, so requeue it for handling | 3067 | * We couldn't allocate memory for the |
2969 | later. */ | 3068 | * message, so requeue it for handling |
3069 | * later. | ||
3070 | */ | ||
2970 | rv = 1; | 3071 | rv = 1; |
2971 | kref_put(&user->refcount, free_user); | 3072 | kref_put(&user->refcount, free_user); |
2972 | } else { | 3073 | } else { |
@@ -2977,8 +3078,10 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2977 | ipmb_addr->lun = msg->rsp[7] & 3; | 3078 | ipmb_addr->lun = msg->rsp[7] & 3; |
2978 | ipmb_addr->channel = msg->rsp[3] & 0xf; | 3079 | ipmb_addr->channel = msg->rsp[3] & 0xf; |
2979 | 3080 | ||
2980 | /* Extract the rest of the message information | 3081 | /* |
2981 | from the IPMB header.*/ | 3082 | * Extract the rest of the message information |
3083 | * from the IPMB header. | ||
3084 | */ | ||
2982 | recv_msg->user = user; | 3085 | recv_msg->user = user; |
2983 | recv_msg->recv_type = IPMI_CMD_RECV_TYPE; | 3086 | recv_msg->recv_type = IPMI_CMD_RECV_TYPE; |
2984 | recv_msg->msgid = msg->rsp[7] >> 2; | 3087 | recv_msg->msgid = msg->rsp[7] >> 2; |
@@ -2986,8 +3089,10 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2986 | recv_msg->msg.cmd = msg->rsp[8]; | 3089 | recv_msg->msg.cmd = msg->rsp[8]; |
2987 | recv_msg->msg.data = recv_msg->msg_data; | 3090 | recv_msg->msg.data = recv_msg->msg_data; |
2988 | 3091 | ||
2989 | /* We chop off 10, not 9 bytes because the checksum | 3092 | /* |
2990 | at the end also needs to be removed. */ | 3093 | * We chop off 10, not 9 bytes because the checksum |
3094 | * at the end also needs to be removed. | ||
3095 | */ | ||
2991 | recv_msg->msg.data_len = msg->rsp_size - 10; | 3096 | recv_msg->msg.data_len = msg->rsp_size - 10; |
2992 | memcpy(recv_msg->msg_data, | 3097 | memcpy(recv_msg->msg_data, |
2993 | &(msg->rsp[9]), | 3098 | &(msg->rsp[9]), |
@@ -3004,16 +3109,15 @@ static int handle_lan_get_msg_rsp(ipmi_smi_t intf, | |||
3004 | { | 3109 | { |
3005 | struct ipmi_lan_addr lan_addr; | 3110 | struct ipmi_lan_addr lan_addr; |
3006 | struct ipmi_recv_msg *recv_msg; | 3111 | struct ipmi_recv_msg *recv_msg; |
3007 | unsigned long flags; | ||
3008 | 3112 | ||
3009 | 3113 | ||
3010 | /* This is 13, not 12, because the response must contain a | 3114 | /* |
3011 | * completion code. */ | 3115 | * This is 13, not 12, because the response must contain a |
3116 | * completion code. | ||
3117 | */ | ||
3012 | if (msg->rsp_size < 13) { | 3118 | if (msg->rsp_size < 13) { |
3013 | /* Message not big enough, just ignore it. */ | 3119 | /* Message not big enough, just ignore it. */ |
3014 | spin_lock_irqsave(&intf->counter_lock, flags); | 3120 | ipmi_inc_stat(intf, invalid_lan_responses); |
3015 | intf->invalid_lan_responses++; | ||
3016 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3017 | return 0; | 3121 | return 0; |
3018 | } | 3122 | } |
3019 | 3123 | ||
@@ -3030,37 +3134,38 @@ static int handle_lan_get_msg_rsp(ipmi_smi_t intf, | |||
3030 | lan_addr.privilege = msg->rsp[3] >> 4; | 3134 | lan_addr.privilege = msg->rsp[3] >> 4; |
3031 | lan_addr.lun = msg->rsp[9] & 3; | 3135 | lan_addr.lun = msg->rsp[9] & 3; |
3032 | 3136 | ||
3033 | /* It's a response from a remote entity. Look up the sequence | 3137 | /* |
3034 | number and handle the response. */ | 3138 | * It's a response from a remote entity. Look up the sequence |
3139 | * number and handle the response. | ||
3140 | */ | ||
3035 | if (intf_find_seq(intf, | 3141 | if (intf_find_seq(intf, |
3036 | msg->rsp[9] >> 2, | 3142 | msg->rsp[9] >> 2, |
3037 | msg->rsp[3] & 0x0f, | 3143 | msg->rsp[3] & 0x0f, |
3038 | msg->rsp[10], | 3144 | msg->rsp[10], |
3039 | (msg->rsp[6] >> 2) & (~1), | 3145 | (msg->rsp[6] >> 2) & (~1), |
3040 | (struct ipmi_addr *) &(lan_addr), | 3146 | (struct ipmi_addr *) &(lan_addr), |
3041 | &recv_msg)) | 3147 | &recv_msg)) { |
3042 | { | 3148 | /* |
3043 | /* We were unable to find the sequence number, | 3149 | * We were unable to find the sequence number, |
3044 | so just nuke the message. */ | 3150 | * so just nuke the message. |
3045 | spin_lock_irqsave(&intf->counter_lock, flags); | 3151 | */ |
3046 | intf->unhandled_lan_responses++; | 3152 | ipmi_inc_stat(intf, unhandled_lan_responses); |
3047 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3048 | return 0; | 3153 | return 0; |
3049 | } | 3154 | } |
3050 | 3155 | ||
3051 | memcpy(recv_msg->msg_data, | 3156 | memcpy(recv_msg->msg_data, |
3052 | &(msg->rsp[11]), | 3157 | &(msg->rsp[11]), |
3053 | msg->rsp_size - 11); | 3158 | msg->rsp_size - 11); |
3054 | /* The other fields matched, so no need to set them, except | 3159 | /* |
3055 | for netfn, which needs to be the response that was | 3160 | * The other fields matched, so no need to set them, except |
3056 | returned, not the request value. */ | 3161 | * for netfn, which needs to be the response that was |
3162 | * returned, not the request value. | ||
3163 | */ | ||
3057 | recv_msg->msg.netfn = msg->rsp[6] >> 2; | 3164 | recv_msg->msg.netfn = msg->rsp[6] >> 2; |
3058 | recv_msg->msg.data = recv_msg->msg_data; | 3165 | recv_msg->msg.data = recv_msg->msg_data; |
3059 | recv_msg->msg.data_len = msg->rsp_size - 12; | 3166 | recv_msg->msg.data_len = msg->rsp_size - 12; |
3060 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | 3167 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; |
3061 | spin_lock_irqsave(&intf->counter_lock, flags); | 3168 | ipmi_inc_stat(intf, handled_lan_responses); |
3062 | intf->handled_lan_responses++; | ||
3063 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3064 | deliver_response(recv_msg); | 3169 | deliver_response(recv_msg); |
3065 | 3170 | ||
3066 | return 0; | 3171 | return 0; |
@@ -3077,13 +3182,10 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
3077 | ipmi_user_t user = NULL; | 3182 | ipmi_user_t user = NULL; |
3078 | struct ipmi_lan_addr *lan_addr; | 3183 | struct ipmi_lan_addr *lan_addr; |
3079 | struct ipmi_recv_msg *recv_msg; | 3184 | struct ipmi_recv_msg *recv_msg; |
3080 | unsigned long flags; | ||
3081 | 3185 | ||
3082 | if (msg->rsp_size < 12) { | 3186 | if (msg->rsp_size < 12) { |
3083 | /* Message not big enough, just ignore it. */ | 3187 | /* Message not big enough, just ignore it. */ |
3084 | spin_lock_irqsave(&intf->counter_lock, flags); | 3188 | ipmi_inc_stat(intf, invalid_commands); |
3085 | intf->invalid_commands++; | ||
3086 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3087 | return 0; | 3189 | return 0; |
3088 | } | 3190 | } |
3089 | 3191 | ||
@@ -3107,23 +3209,23 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
3107 | 3209 | ||
3108 | if (user == NULL) { | 3210 | if (user == NULL) { |
3109 | /* We didn't find a user, just give up. */ | 3211 | /* We didn't find a user, just give up. */ |
3110 | spin_lock_irqsave(&intf->counter_lock, flags); | 3212 | ipmi_inc_stat(intf, unhandled_commands); |
3111 | intf->unhandled_commands++; | ||
3112 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3113 | 3213 | ||
3114 | rv = 0; /* Don't do anything with these messages, just | 3214 | /* |
3115 | allow them to be freed. */ | 3215 | * Don't do anything with these messages, just allow |
3216 | * them to be freed. | ||
3217 | */ | ||
3218 | rv = 0; | ||
3116 | } else { | 3219 | } else { |
3117 | /* Deliver the message to the user. */ | 3220 | /* Deliver the message to the user. */ |
3118 | spin_lock_irqsave(&intf->counter_lock, flags); | 3221 | ipmi_inc_stat(intf, handled_commands); |
3119 | intf->handled_commands++; | ||
3120 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3121 | 3222 | ||
3122 | recv_msg = ipmi_alloc_recv_msg(); | 3223 | recv_msg = ipmi_alloc_recv_msg(); |
3123 | if (!recv_msg) { | 3224 | if (!recv_msg) { |
3124 | /* We couldn't allocate memory for the | 3225 | /* |
3125 | message, so requeue it for handling | 3226 | * We couldn't allocate memory for the |
3126 | later. */ | 3227 | * message, so requeue it for handling later. |
3228 | */ | ||
3127 | rv = 1; | 3229 | rv = 1; |
3128 | kref_put(&user->refcount, free_user); | 3230 | kref_put(&user->refcount, free_user); |
3129 | } else { | 3231 | } else { |
@@ -3137,8 +3239,10 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
3137 | lan_addr->channel = msg->rsp[3] & 0xf; | 3239 | lan_addr->channel = msg->rsp[3] & 0xf; |
3138 | lan_addr->privilege = msg->rsp[3] >> 4; | 3240 | lan_addr->privilege = msg->rsp[3] >> 4; |
3139 | 3241 | ||
3140 | /* Extract the rest of the message information | 3242 | /* |
3141 | from the IPMB header.*/ | 3243 | * Extract the rest of the message information |
3244 | * from the IPMB header. | ||
3245 | */ | ||
3142 | recv_msg->user = user; | 3246 | recv_msg->user = user; |
3143 | recv_msg->recv_type = IPMI_CMD_RECV_TYPE; | 3247 | recv_msg->recv_type = IPMI_CMD_RECV_TYPE; |
3144 | recv_msg->msgid = msg->rsp[9] >> 2; | 3248 | recv_msg->msgid = msg->rsp[9] >> 2; |
@@ -3146,8 +3250,10 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
3146 | recv_msg->msg.cmd = msg->rsp[10]; | 3250 | recv_msg->msg.cmd = msg->rsp[10]; |
3147 | recv_msg->msg.data = recv_msg->msg_data; | 3251 | recv_msg->msg.data = recv_msg->msg_data; |
3148 | 3252 | ||
3149 | /* We chop off 12, not 11 bytes because the checksum | 3253 | /* |
3150 | at the end also needs to be removed. */ | 3254 | * We chop off 12, not 11 bytes because the checksum |
3255 | * at the end also needs to be removed. | ||
3256 | */ | ||
3151 | recv_msg->msg.data_len = msg->rsp_size - 12; | 3257 | recv_msg->msg.data_len = msg->rsp_size - 12; |
3152 | memcpy(recv_msg->msg_data, | 3258 | memcpy(recv_msg->msg_data, |
3153 | &(msg->rsp[11]), | 3259 | &(msg->rsp[11]), |
@@ -3163,7 +3269,7 @@ static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg, | |||
3163 | struct ipmi_smi_msg *msg) | 3269 | struct ipmi_smi_msg *msg) |
3164 | { | 3270 | { |
3165 | struct ipmi_system_interface_addr *smi_addr; | 3271 | struct ipmi_system_interface_addr *smi_addr; |
3166 | 3272 | ||
3167 | recv_msg->msgid = 0; | 3273 | recv_msg->msgid = 0; |
3168 | smi_addr = (struct ipmi_system_interface_addr *) &(recv_msg->addr); | 3274 | smi_addr = (struct ipmi_system_interface_addr *) &(recv_msg->addr); |
3169 | smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 3275 | smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
@@ -3189,9 +3295,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
3189 | 3295 | ||
3190 | if (msg->rsp_size < 19) { | 3296 | if (msg->rsp_size < 19) { |
3191 | /* Message is too small to be an IPMB event. */ | 3297 | /* Message is too small to be an IPMB event. */ |
3192 | spin_lock_irqsave(&intf->counter_lock, flags); | 3298 | ipmi_inc_stat(intf, invalid_events); |
3193 | intf->invalid_events++; | ||
3194 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3195 | return 0; | 3299 | return 0; |
3196 | } | 3300 | } |
3197 | 3301 | ||
@@ -3204,12 +3308,12 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
3204 | 3308 | ||
3205 | spin_lock_irqsave(&intf->events_lock, flags); | 3309 | spin_lock_irqsave(&intf->events_lock, flags); |
3206 | 3310 | ||
3207 | spin_lock(&intf->counter_lock); | 3311 | ipmi_inc_stat(intf, events); |
3208 | intf->events++; | ||
3209 | spin_unlock(&intf->counter_lock); | ||
3210 | 3312 | ||
3211 | /* Allocate and fill in one message for every user that is getting | 3313 | /* |
3212 | events. */ | 3314 | * Allocate and fill in one message for every user that is |
3315 | * getting events. | ||
3316 | */ | ||
3213 | rcu_read_lock(); | 3317 | rcu_read_lock(); |
3214 | list_for_each_entry_rcu(user, &intf->users, link) { | 3318 | list_for_each_entry_rcu(user, &intf->users, link) { |
3215 | if (!user->gets_events) | 3319 | if (!user->gets_events) |
@@ -3223,9 +3327,11 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
3223 | list_del(&recv_msg->link); | 3327 | list_del(&recv_msg->link); |
3224 | ipmi_free_recv_msg(recv_msg); | 3328 | ipmi_free_recv_msg(recv_msg); |
3225 | } | 3329 | } |
3226 | /* We couldn't allocate memory for the | 3330 | /* |
3227 | message, so requeue it for handling | 3331 | * We couldn't allocate memory for the |
3228 | later. */ | 3332 | * message, so requeue it for handling |
3333 | * later. | ||
3334 | */ | ||
3229 | rv = 1; | 3335 | rv = 1; |
3230 | goto out; | 3336 | goto out; |
3231 | } | 3337 | } |
@@ -3246,13 +3352,17 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
3246 | deliver_response(recv_msg); | 3352 | deliver_response(recv_msg); |
3247 | } | 3353 | } |
3248 | } else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) { | 3354 | } else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) { |
3249 | /* No one to receive the message, put it in queue if there's | 3355 | /* |
3250 | not already too many things in the queue. */ | 3356 | * No one to receive the message, put it in queue if there's |
3357 | * not already too many things in the queue. | ||
3358 | */ | ||
3251 | recv_msg = ipmi_alloc_recv_msg(); | 3359 | recv_msg = ipmi_alloc_recv_msg(); |
3252 | if (!recv_msg) { | 3360 | if (!recv_msg) { |
3253 | /* We couldn't allocate memory for the | 3361 | /* |
3254 | message, so requeue it for handling | 3362 | * We couldn't allocate memory for the |
3255 | later. */ | 3363 | * message, so requeue it for handling |
3364 | * later. | ||
3365 | */ | ||
3256 | rv = 1; | 3366 | rv = 1; |
3257 | goto out; | 3367 | goto out; |
3258 | } | 3368 | } |
@@ -3260,11 +3370,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
3260 | copy_event_into_recv_msg(recv_msg, msg); | 3370 | copy_event_into_recv_msg(recv_msg, msg); |
3261 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); | 3371 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); |
3262 | intf->waiting_events_count++; | 3372 | intf->waiting_events_count++; |
3263 | } else { | 3373 | } else if (!intf->event_msg_printed) { |
3264 | /* There's too many things in the queue, discard this | 3374 | /* |
3265 | message. */ | 3375 | * There's too many things in the queue, discard this |
3266 | printk(KERN_WARNING PFX "Event queue full, discarding an" | 3376 | * message. |
3267 | " incoming event\n"); | 3377 | */ |
3378 | printk(KERN_WARNING PFX "Event queue full, discarding" | ||
3379 | " incoming events\n"); | ||
3380 | intf->event_msg_printed = 1; | ||
3268 | } | 3381 | } |
3269 | 3382 | ||
3270 | out: | 3383 | out: |
@@ -3277,16 +3390,15 @@ static int handle_bmc_rsp(ipmi_smi_t intf, | |||
3277 | struct ipmi_smi_msg *msg) | 3390 | struct ipmi_smi_msg *msg) |
3278 | { | 3391 | { |
3279 | struct ipmi_recv_msg *recv_msg; | 3392 | struct ipmi_recv_msg *recv_msg; |
3280 | unsigned long flags; | ||
3281 | struct ipmi_user *user; | 3393 | struct ipmi_user *user; |
3282 | 3394 | ||
3283 | recv_msg = (struct ipmi_recv_msg *) msg->user_data; | 3395 | recv_msg = (struct ipmi_recv_msg *) msg->user_data; |
3284 | if (recv_msg == NULL) | 3396 | if (recv_msg == NULL) { |
3285 | { | 3397 | printk(KERN_WARNING |
3286 | printk(KERN_WARNING"IPMI message received with no owner. This\n" | 3398 | "IPMI message received with no owner. This\n" |
3287 | "could be because of a malformed message, or\n" | 3399 | "could be because of a malformed message, or\n" |
3288 | "because of a hardware error. Contact your\n" | 3400 | "because of a hardware error. Contact your\n" |
3289 | "hardware vender for assistance\n"); | 3401 | "hardware vender for assistance\n"); |
3290 | return 0; | 3402 | return 0; |
3291 | } | 3403 | } |
3292 | 3404 | ||
@@ -3294,16 +3406,12 @@ static int handle_bmc_rsp(ipmi_smi_t intf, | |||
3294 | /* Make sure the user still exists. */ | 3406 | /* Make sure the user still exists. */ |
3295 | if (user && !user->valid) { | 3407 | if (user && !user->valid) { |
3296 | /* The user for the message went away, so give up. */ | 3408 | /* The user for the message went away, so give up. */ |
3297 | spin_lock_irqsave(&intf->counter_lock, flags); | 3409 | ipmi_inc_stat(intf, unhandled_local_responses); |
3298 | intf->unhandled_local_responses++; | ||
3299 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3300 | ipmi_free_recv_msg(recv_msg); | 3410 | ipmi_free_recv_msg(recv_msg); |
3301 | } else { | 3411 | } else { |
3302 | struct ipmi_system_interface_addr *smi_addr; | 3412 | struct ipmi_system_interface_addr *smi_addr; |
3303 | 3413 | ||
3304 | spin_lock_irqsave(&intf->counter_lock, flags); | 3414 | ipmi_inc_stat(intf, handled_local_responses); |
3305 | intf->handled_local_responses++; | ||
3306 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3307 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | 3415 | recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; |
3308 | recv_msg->msgid = msg->msgid; | 3416 | recv_msg->msgid = msg->msgid; |
3309 | smi_addr = ((struct ipmi_system_interface_addr *) | 3417 | smi_addr = ((struct ipmi_system_interface_addr *) |
@@ -3324,9 +3432,11 @@ static int handle_bmc_rsp(ipmi_smi_t intf, | |||
3324 | return 0; | 3432 | return 0; |
3325 | } | 3433 | } |
3326 | 3434 | ||
3327 | /* Handle a new message. Return 1 if the message should be requeued, | 3435 | /* |
3328 | 0 if the message should be freed, or -1 if the message should not | 3436 | * Handle a new message. Return 1 if the message should be requeued, |
3329 | be freed or requeued. */ | 3437 | * 0 if the message should be freed, or -1 if the message should not |
3438 | * be freed or requeued. | ||
3439 | */ | ||
3330 | static int handle_new_recv_msg(ipmi_smi_t intf, | 3440 | static int handle_new_recv_msg(ipmi_smi_t intf, |
3331 | struct ipmi_smi_msg *msg) | 3441 | struct ipmi_smi_msg *msg) |
3332 | { | 3442 | { |
@@ -3351,10 +3461,12 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3351 | msg->rsp[1] = msg->data[1]; | 3461 | msg->rsp[1] = msg->data[1]; |
3352 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; | 3462 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; |
3353 | msg->rsp_size = 3; | 3463 | msg->rsp_size = 3; |
3354 | } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1))/* Netfn */ | 3464 | } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1)) |
3355 | || (msg->rsp[1] != msg->data[1])) /* Command */ | 3465 | || (msg->rsp[1] != msg->data[1])) { |
3356 | { | 3466 | /* |
3357 | /* The response is not even marginally correct. */ | 3467 | * The NetFN and Command in the response is not even |
3468 | * marginally correct. | ||
3469 | */ | ||
3358 | printk(KERN_WARNING PFX "BMC returned incorrect response," | 3470 | printk(KERN_WARNING PFX "BMC returned incorrect response," |
3359 | " expected netfn %x cmd %x, got netfn %x cmd %x\n", | 3471 | " expected netfn %x cmd %x, got netfn %x cmd %x\n", |
3360 | (msg->data[0] >> 2) | 1, msg->data[1], | 3472 | (msg->data[0] >> 2) | 1, msg->data[1], |
@@ -3369,10 +3481,11 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3369 | 3481 | ||
3370 | if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) | 3482 | if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) |
3371 | && (msg->rsp[1] == IPMI_SEND_MSG_CMD) | 3483 | && (msg->rsp[1] == IPMI_SEND_MSG_CMD) |
3372 | && (msg->user_data != NULL)) | 3484 | && (msg->user_data != NULL)) { |
3373 | { | 3485 | /* |
3374 | /* It's a response to a response we sent. For this we | 3486 | * It's a response to a response we sent. For this we |
3375 | deliver a send message response to the user. */ | 3487 | * deliver a send message response to the user. |
3488 | */ | ||
3376 | struct ipmi_recv_msg *recv_msg = msg->user_data; | 3489 | struct ipmi_recv_msg *recv_msg = msg->user_data; |
3377 | 3490 | ||
3378 | requeue = 0; | 3491 | requeue = 0; |
@@ -3398,8 +3511,7 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3398 | recv_msg->msg_data[0] = msg->rsp[2]; | 3511 | recv_msg->msg_data[0] = msg->rsp[2]; |
3399 | deliver_response(recv_msg); | 3512 | deliver_response(recv_msg); |
3400 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) | 3513 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) |
3401 | && (msg->rsp[1] == IPMI_GET_MSG_CMD)) | 3514 | && (msg->rsp[1] == IPMI_GET_MSG_CMD)) { |
3402 | { | ||
3403 | /* It's from the receive queue. */ | 3515 | /* It's from the receive queue. */ |
3404 | chan = msg->rsp[3] & 0xf; | 3516 | chan = msg->rsp[3] & 0xf; |
3405 | if (chan >= IPMI_MAX_CHANNELS) { | 3517 | if (chan >= IPMI_MAX_CHANNELS) { |
@@ -3411,12 +3523,16 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3411 | switch (intf->channels[chan].medium) { | 3523 | switch (intf->channels[chan].medium) { |
3412 | case IPMI_CHANNEL_MEDIUM_IPMB: | 3524 | case IPMI_CHANNEL_MEDIUM_IPMB: |
3413 | if (msg->rsp[4] & 0x04) { | 3525 | if (msg->rsp[4] & 0x04) { |
3414 | /* It's a response, so find the | 3526 | /* |
3415 | requesting message and send it up. */ | 3527 | * It's a response, so find the |
3528 | * requesting message and send it up. | ||
3529 | */ | ||
3416 | requeue = handle_ipmb_get_msg_rsp(intf, msg); | 3530 | requeue = handle_ipmb_get_msg_rsp(intf, msg); |
3417 | } else { | 3531 | } else { |
3418 | /* It's a command to the SMS from some other | 3532 | /* |
3419 | entity. Handle that. */ | 3533 | * It's a command to the SMS from some other |
3534 | * entity. Handle that. | ||
3535 | */ | ||
3420 | requeue = handle_ipmb_get_msg_cmd(intf, msg); | 3536 | requeue = handle_ipmb_get_msg_cmd(intf, msg); |
3421 | } | 3537 | } |
3422 | break; | 3538 | break; |
@@ -3424,25 +3540,30 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3424 | case IPMI_CHANNEL_MEDIUM_8023LAN: | 3540 | case IPMI_CHANNEL_MEDIUM_8023LAN: |
3425 | case IPMI_CHANNEL_MEDIUM_ASYNC: | 3541 | case IPMI_CHANNEL_MEDIUM_ASYNC: |
3426 | if (msg->rsp[6] & 0x04) { | 3542 | if (msg->rsp[6] & 0x04) { |
3427 | /* It's a response, so find the | 3543 | /* |
3428 | requesting message and send it up. */ | 3544 | * It's a response, so find the |
3545 | * requesting message and send it up. | ||
3546 | */ | ||
3429 | requeue = handle_lan_get_msg_rsp(intf, msg); | 3547 | requeue = handle_lan_get_msg_rsp(intf, msg); |
3430 | } else { | 3548 | } else { |
3431 | /* It's a command to the SMS from some other | 3549 | /* |
3432 | entity. Handle that. */ | 3550 | * It's a command to the SMS from some other |
3551 | * entity. Handle that. | ||
3552 | */ | ||
3433 | requeue = handle_lan_get_msg_cmd(intf, msg); | 3553 | requeue = handle_lan_get_msg_cmd(intf, msg); |
3434 | } | 3554 | } |
3435 | break; | 3555 | break; |
3436 | 3556 | ||
3437 | default: | 3557 | default: |
3438 | /* We don't handle the channel type, so just | 3558 | /* |
3439 | * free the message. */ | 3559 | * We don't handle the channel type, so just |
3560 | * free the message. | ||
3561 | */ | ||
3440 | requeue = 0; | 3562 | requeue = 0; |
3441 | } | 3563 | } |
3442 | 3564 | ||
3443 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) | 3565 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) |
3444 | && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) | 3566 | && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) { |
3445 | { | ||
3446 | /* It's an asyncronous event. */ | 3567 | /* It's an asyncronous event. */ |
3447 | requeue = handle_read_event_rsp(intf, msg); | 3568 | requeue = handle_read_event_rsp(intf, msg); |
3448 | } else { | 3569 | } else { |
@@ -3458,71 +3579,82 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3458 | void ipmi_smi_msg_received(ipmi_smi_t intf, | 3579 | void ipmi_smi_msg_received(ipmi_smi_t intf, |
3459 | struct ipmi_smi_msg *msg) | 3580 | struct ipmi_smi_msg *msg) |
3460 | { | 3581 | { |
3461 | unsigned long flags; | 3582 | unsigned long flags = 0; /* keep us warning-free. */ |
3462 | int rv; | 3583 | int rv; |
3584 | int run_to_completion; | ||
3463 | 3585 | ||
3464 | 3586 | ||
3465 | if ((msg->data_size >= 2) | 3587 | if ((msg->data_size >= 2) |
3466 | && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) | 3588 | && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) |
3467 | && (msg->data[1] == IPMI_SEND_MSG_CMD) | 3589 | && (msg->data[1] == IPMI_SEND_MSG_CMD) |
3468 | && (msg->user_data == NULL)) | 3590 | && (msg->user_data == NULL)) { |
3469 | { | 3591 | /* |
3470 | /* This is the local response to a command send, start | 3592 | * This is the local response to a command send, start |
3471 | the timer for these. The user_data will not be | 3593 | * the timer for these. The user_data will not be |
3472 | NULL if this is a response send, and we will let | 3594 | * NULL if this is a response send, and we will let |
3473 | response sends just go through. */ | 3595 | * response sends just go through. |
3474 | 3596 | */ | |
3475 | /* Check for errors, if we get certain errors (ones | 3597 | |
3476 | that mean basically we can try again later), we | 3598 | /* |
3477 | ignore them and start the timer. Otherwise we | 3599 | * Check for errors, if we get certain errors (ones |
3478 | report the error immediately. */ | 3600 | * that mean basically we can try again later), we |
3601 | * ignore them and start the timer. Otherwise we | ||
3602 | * report the error immediately. | ||
3603 | */ | ||
3479 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) | 3604 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) |
3480 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) | 3605 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) |
3481 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) | 3606 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) |
3482 | && (msg->rsp[2] != IPMI_BUS_ERR) | 3607 | && (msg->rsp[2] != IPMI_BUS_ERR) |
3483 | && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) | 3608 | && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) { |
3484 | { | ||
3485 | int chan = msg->rsp[3] & 0xf; | 3609 | int chan = msg->rsp[3] & 0xf; |
3486 | 3610 | ||
3487 | /* Got an error sending the message, handle it. */ | 3611 | /* Got an error sending the message, handle it. */ |
3488 | spin_lock_irqsave(&intf->counter_lock, flags); | ||
3489 | if (chan >= IPMI_MAX_CHANNELS) | 3612 | if (chan >= IPMI_MAX_CHANNELS) |
3490 | ; /* This shouldn't happen */ | 3613 | ; /* This shouldn't happen */ |
3491 | else if ((intf->channels[chan].medium | 3614 | else if ((intf->channels[chan].medium |
3492 | == IPMI_CHANNEL_MEDIUM_8023LAN) | 3615 | == IPMI_CHANNEL_MEDIUM_8023LAN) |
3493 | || (intf->channels[chan].medium | 3616 | || (intf->channels[chan].medium |
3494 | == IPMI_CHANNEL_MEDIUM_ASYNC)) | 3617 | == IPMI_CHANNEL_MEDIUM_ASYNC)) |
3495 | intf->sent_lan_command_errs++; | 3618 | ipmi_inc_stat(intf, sent_lan_command_errs); |
3496 | else | 3619 | else |
3497 | intf->sent_ipmb_command_errs++; | 3620 | ipmi_inc_stat(intf, sent_ipmb_command_errs); |
3498 | spin_unlock_irqrestore(&intf->counter_lock, flags); | ||
3499 | intf_err_seq(intf, msg->msgid, msg->rsp[2]); | 3621 | intf_err_seq(intf, msg->msgid, msg->rsp[2]); |
3500 | } else { | 3622 | } else |
3501 | /* The message was sent, start the timer. */ | 3623 | /* The message was sent, start the timer. */ |
3502 | intf_start_seq_timer(intf, msg->msgid); | 3624 | intf_start_seq_timer(intf, msg->msgid); |
3503 | } | ||
3504 | 3625 | ||
3505 | ipmi_free_smi_msg(msg); | 3626 | ipmi_free_smi_msg(msg); |
3506 | goto out; | 3627 | goto out; |
3507 | } | 3628 | } |
3508 | 3629 | ||
3509 | /* To preserve message order, if the list is not empty, we | 3630 | /* |
3510 | tack this message onto the end of the list. */ | 3631 | * To preserve message order, if the list is not empty, we |
3511 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | 3632 | * tack this message onto the end of the list. |
3633 | */ | ||
3634 | run_to_completion = intf->run_to_completion; | ||
3635 | if (!run_to_completion) | ||
3636 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | ||
3512 | if (!list_empty(&intf->waiting_msgs)) { | 3637 | if (!list_empty(&intf->waiting_msgs)) { |
3513 | list_add_tail(&msg->link, &intf->waiting_msgs); | 3638 | list_add_tail(&msg->link, &intf->waiting_msgs); |
3514 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | 3639 | if (!run_to_completion) |
3640 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | ||
3515 | goto out; | 3641 | goto out; |
3516 | } | 3642 | } |
3517 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | 3643 | if (!run_to_completion) |
3518 | 3644 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | |
3645 | |||
3519 | rv = handle_new_recv_msg(intf, msg); | 3646 | rv = handle_new_recv_msg(intf, msg); |
3520 | if (rv > 0) { | 3647 | if (rv > 0) { |
3521 | /* Could not handle the message now, just add it to a | 3648 | /* |
3522 | list to handle later. */ | 3649 | * Could not handle the message now, just add it to a |
3523 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | 3650 | * list to handle later. |
3651 | */ | ||
3652 | run_to_completion = intf->run_to_completion; | ||
3653 | if (!run_to_completion) | ||
3654 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | ||
3524 | list_add_tail(&msg->link, &intf->waiting_msgs); | 3655 | list_add_tail(&msg->link, &intf->waiting_msgs); |
3525 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | 3656 | if (!run_to_completion) |
3657 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | ||
3526 | } else if (rv == 0) { | 3658 | } else if (rv == 0) { |
3527 | ipmi_free_smi_msg(msg); | 3659 | ipmi_free_smi_msg(msg); |
3528 | } | 3660 | } |
@@ -3530,6 +3662,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, | |||
3530 | out: | 3662 | out: |
3531 | return; | 3663 | return; |
3532 | } | 3664 | } |
3665 | EXPORT_SYMBOL(ipmi_smi_msg_received); | ||
3533 | 3666 | ||
3534 | void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) | 3667 | void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) |
3535 | { | 3668 | { |
@@ -3544,7 +3677,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) | |||
3544 | } | 3677 | } |
3545 | rcu_read_unlock(); | 3678 | rcu_read_unlock(); |
3546 | } | 3679 | } |
3547 | 3680 | EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout); | |
3548 | 3681 | ||
3549 | static struct ipmi_smi_msg * | 3682 | static struct ipmi_smi_msg * |
3550 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | 3683 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, |
@@ -3552,14 +3685,16 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | |||
3552 | { | 3685 | { |
3553 | struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg(); | 3686 | struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg(); |
3554 | if (!smi_msg) | 3687 | if (!smi_msg) |
3555 | /* If we can't allocate the message, then just return, we | 3688 | /* |
3556 | get 4 retries, so this should be ok. */ | 3689 | * If we can't allocate the message, then just return, we |
3690 | * get 4 retries, so this should be ok. | ||
3691 | */ | ||
3557 | return NULL; | 3692 | return NULL; |
3558 | 3693 | ||
3559 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); | 3694 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); |
3560 | smi_msg->data_size = recv_msg->msg.data_len; | 3695 | smi_msg->data_size = recv_msg->msg.data_len; |
3561 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); | 3696 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); |
3562 | 3697 | ||
3563 | #ifdef DEBUG_MSGING | 3698 | #ifdef DEBUG_MSGING |
3564 | { | 3699 | { |
3565 | int m; | 3700 | int m; |
@@ -3594,28 +3729,26 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3594 | ent->inuse = 0; | 3729 | ent->inuse = 0; |
3595 | msg = ent->recv_msg; | 3730 | msg = ent->recv_msg; |
3596 | list_add_tail(&msg->link, timeouts); | 3731 | list_add_tail(&msg->link, timeouts); |
3597 | spin_lock(&intf->counter_lock); | ||
3598 | if (ent->broadcast) | 3732 | if (ent->broadcast) |
3599 | intf->timed_out_ipmb_broadcasts++; | 3733 | ipmi_inc_stat(intf, timed_out_ipmb_broadcasts); |
3600 | else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) | 3734 | else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) |
3601 | intf->timed_out_lan_commands++; | 3735 | ipmi_inc_stat(intf, timed_out_lan_commands); |
3602 | else | 3736 | else |
3603 | intf->timed_out_ipmb_commands++; | 3737 | ipmi_inc_stat(intf, timed_out_ipmb_commands); |
3604 | spin_unlock(&intf->counter_lock); | ||
3605 | } else { | 3738 | } else { |
3606 | struct ipmi_smi_msg *smi_msg; | 3739 | struct ipmi_smi_msg *smi_msg; |
3607 | /* More retries, send again. */ | 3740 | /* More retries, send again. */ |
3608 | 3741 | ||
3609 | /* Start with the max timer, set to normal | 3742 | /* |
3610 | timer after the message is sent. */ | 3743 | * Start with the max timer, set to normal timer after |
3744 | * the message is sent. | ||
3745 | */ | ||
3611 | ent->timeout = MAX_MSG_TIMEOUT; | 3746 | ent->timeout = MAX_MSG_TIMEOUT; |
3612 | ent->retries_left--; | 3747 | ent->retries_left--; |
3613 | spin_lock(&intf->counter_lock); | ||
3614 | if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) | 3748 | if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) |
3615 | intf->retransmitted_lan_commands++; | 3749 | ipmi_inc_stat(intf, retransmitted_lan_commands); |
3616 | else | 3750 | else |
3617 | intf->retransmitted_ipmb_commands++; | 3751 | ipmi_inc_stat(intf, retransmitted_ipmb_commands); |
3618 | spin_unlock(&intf->counter_lock); | ||
3619 | 3752 | ||
3620 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, | 3753 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, |
3621 | ent->seqid); | 3754 | ent->seqid); |
@@ -3624,11 +3757,13 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3624 | 3757 | ||
3625 | spin_unlock_irqrestore(&intf->seq_lock, *flags); | 3758 | spin_unlock_irqrestore(&intf->seq_lock, *flags); |
3626 | 3759 | ||
3627 | /* Send the new message. We send with a zero | 3760 | /* |
3628 | * priority. It timed out, I doubt time is | 3761 | * Send the new message. We send with a zero |
3629 | * that critical now, and high priority | 3762 | * priority. It timed out, I doubt time is that |
3630 | * messages are really only for messages to the | 3763 | * critical now, and high priority messages are really |
3631 | * local MC, which don't get resent. */ | 3764 | * only for messages to the local MC, which don't get |
3765 | * resent. | ||
3766 | */ | ||
3632 | handlers = intf->handlers; | 3767 | handlers = intf->handlers; |
3633 | if (handlers) | 3768 | if (handlers) |
3634 | intf->handlers->sender(intf->send_info, | 3769 | intf->handlers->sender(intf->send_info, |
@@ -3659,16 +3794,20 @@ static void ipmi_timeout_handler(long timeout_period) | |||
3659 | list_del(&smi_msg->link); | 3794 | list_del(&smi_msg->link); |
3660 | ipmi_free_smi_msg(smi_msg); | 3795 | ipmi_free_smi_msg(smi_msg); |
3661 | } else { | 3796 | } else { |
3662 | /* To preserve message order, quit if we | 3797 | /* |
3663 | can't handle a message. */ | 3798 | * To preserve message order, quit if we |
3799 | * can't handle a message. | ||
3800 | */ | ||
3664 | break; | 3801 | break; |
3665 | } | 3802 | } |
3666 | } | 3803 | } |
3667 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); | 3804 | spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); |
3668 | 3805 | ||
3669 | /* Go through the seq table and find any messages that | 3806 | /* |
3670 | have timed out, putting them in the timeouts | 3807 | * Go through the seq table and find any messages that |
3671 | list. */ | 3808 | * have timed out, putting them in the timeouts |
3809 | * list. | ||
3810 | */ | ||
3672 | INIT_LIST_HEAD(&timeouts); | 3811 | INIT_LIST_HEAD(&timeouts); |
3673 | spin_lock_irqsave(&intf->seq_lock, flags); | 3812 | spin_lock_irqsave(&intf->seq_lock, flags); |
3674 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) | 3813 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) |
@@ -3694,8 +3833,7 @@ static void ipmi_timeout_handler(long timeout_period) | |||
3694 | intf->auto_maintenance_timeout | 3833 | intf->auto_maintenance_timeout |
3695 | -= timeout_period; | 3834 | -= timeout_period; |
3696 | if (!intf->maintenance_mode | 3835 | if (!intf->maintenance_mode |
3697 | && (intf->auto_maintenance_timeout <= 0)) | 3836 | && (intf->auto_maintenance_timeout <= 0)) { |
3698 | { | ||
3699 | intf->maintenance_mode_enable = 0; | 3837 | intf->maintenance_mode_enable = 0; |
3700 | maintenance_mode_update(intf); | 3838 | maintenance_mode_update(intf); |
3701 | } | 3839 | } |
@@ -3713,8 +3851,10 @@ static void ipmi_request_event(void) | |||
3713 | struct ipmi_smi_handlers *handlers; | 3851 | struct ipmi_smi_handlers *handlers; |
3714 | 3852 | ||
3715 | rcu_read_lock(); | 3853 | rcu_read_lock(); |
3716 | /* Called from the timer, no need to check if handlers is | 3854 | /* |
3717 | * valid. */ | 3855 | * Called from the timer, no need to check if handlers is |
3856 | * valid. | ||
3857 | */ | ||
3718 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { | 3858 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
3719 | /* No event requests when in maintenance mode. */ | 3859 | /* No event requests when in maintenance mode. */ |
3720 | if (intf->maintenance_mode_enable) | 3860 | if (intf->maintenance_mode_enable) |
@@ -3735,10 +3875,12 @@ static struct timer_list ipmi_timer; | |||
3735 | /* How many jiffies does it take to get to the timeout time. */ | 3875 | /* How many jiffies does it take to get to the timeout time. */ |
3736 | #define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000) | 3876 | #define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000) |
3737 | 3877 | ||
3738 | /* Request events from the queue every second (this is the number of | 3878 | /* |
3739 | IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the | 3879 | * Request events from the queue every second (this is the number of |
3740 | future, IPMI will add a way to know immediately if an event is in | 3880 | * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the |
3741 | the queue and this silliness can go away. */ | 3881 | * future, IPMI will add a way to know immediately if an event is in |
3882 | * the queue and this silliness can go away. | ||
3883 | */ | ||
3742 | #define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) | 3884 | #define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) |
3743 | 3885 | ||
3744 | static atomic_t stop_operation; | 3886 | static atomic_t stop_operation; |
@@ -3782,6 +3924,7 @@ struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) | |||
3782 | } | 3924 | } |
3783 | return rv; | 3925 | return rv; |
3784 | } | 3926 | } |
3927 | EXPORT_SYMBOL(ipmi_alloc_smi_msg); | ||
3785 | 3928 | ||
3786 | static void free_recv_msg(struct ipmi_recv_msg *msg) | 3929 | static void free_recv_msg(struct ipmi_recv_msg *msg) |
3787 | { | 3930 | { |
@@ -3789,7 +3932,7 @@ static void free_recv_msg(struct ipmi_recv_msg *msg) | |||
3789 | kfree(msg); | 3932 | kfree(msg); |
3790 | } | 3933 | } |
3791 | 3934 | ||
3792 | struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) | 3935 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) |
3793 | { | 3936 | { |
3794 | struct ipmi_recv_msg *rv; | 3937 | struct ipmi_recv_msg *rv; |
3795 | 3938 | ||
@@ -3808,6 +3951,7 @@ void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) | |||
3808 | kref_put(&msg->user->refcount, free_user); | 3951 | kref_put(&msg->user->refcount, free_user); |
3809 | msg->done(msg); | 3952 | msg->done(msg); |
3810 | } | 3953 | } |
3954 | EXPORT_SYMBOL(ipmi_free_recv_msg); | ||
3811 | 3955 | ||
3812 | #ifdef CONFIG_IPMI_PANIC_EVENT | 3956 | #ifdef CONFIG_IPMI_PANIC_EVENT |
3813 | 3957 | ||
@@ -3825,8 +3969,7 @@ static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
3825 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) | 3969 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) |
3826 | && (msg->msg.netfn == IPMI_NETFN_SENSOR_EVENT_RESPONSE) | 3970 | && (msg->msg.netfn == IPMI_NETFN_SENSOR_EVENT_RESPONSE) |
3827 | && (msg->msg.cmd == IPMI_GET_EVENT_RECEIVER_CMD) | 3971 | && (msg->msg.cmd == IPMI_GET_EVENT_RECEIVER_CMD) |
3828 | && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) | 3972 | && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { |
3829 | { | ||
3830 | /* A get event receiver command, save it. */ | 3973 | /* A get event receiver command, save it. */ |
3831 | intf->event_receiver = msg->msg.data[1]; | 3974 | intf->event_receiver = msg->msg.data[1]; |
3832 | intf->event_receiver_lun = msg->msg.data[2] & 0x3; | 3975 | intf->event_receiver_lun = msg->msg.data[2] & 0x3; |
@@ -3838,10 +3981,11 @@ static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
3838 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) | 3981 | if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) |
3839 | && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) | 3982 | && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) |
3840 | && (msg->msg.cmd == IPMI_GET_DEVICE_ID_CMD) | 3983 | && (msg->msg.cmd == IPMI_GET_DEVICE_ID_CMD) |
3841 | && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) | 3984 | && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { |
3842 | { | 3985 | /* |
3843 | /* A get device id command, save if we are an event | 3986 | * A get device id command, save if we are an event |
3844 | receiver or generator. */ | 3987 | * receiver or generator. |
3988 | */ | ||
3845 | intf->local_sel_device = (msg->msg.data[6] >> 2) & 1; | 3989 | intf->local_sel_device = (msg->msg.data[6] >> 2) & 1; |
3846 | intf->local_event_generator = (msg->msg.data[6] >> 5) & 1; | 3990 | intf->local_event_generator = (msg->msg.data[6] >> 5) & 1; |
3847 | } | 3991 | } |
@@ -3874,8 +4018,10 @@ static void send_panic_events(char *str) | |||
3874 | data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */ | 4018 | data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */ |
3875 | data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */ | 4019 | data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */ |
3876 | 4020 | ||
3877 | /* Put a few breadcrumbs in. Hopefully later we can add more things | 4021 | /* |
3878 | to make the panic events more useful. */ | 4022 | * Put a few breadcrumbs in. Hopefully later we can add more things |
4023 | * to make the panic events more useful. | ||
4024 | */ | ||
3879 | if (str) { | 4025 | if (str) { |
3880 | data[3] = str[0]; | 4026 | data[3] = str[0]; |
3881 | data[6] = str[1]; | 4027 | data[6] = str[1]; |
@@ -3891,6 +4037,7 @@ static void send_panic_events(char *str) | |||
3891 | /* Interface is not ready. */ | 4037 | /* Interface is not ready. */ |
3892 | continue; | 4038 | continue; |
3893 | 4039 | ||
4040 | intf->run_to_completion = 1; | ||
3894 | /* Send the event announcing the panic. */ | 4041 | /* Send the event announcing the panic. */ |
3895 | intf->handlers->set_run_to_completion(intf->send_info, 1); | 4042 | intf->handlers->set_run_to_completion(intf->send_info, 1); |
3896 | i_ipmi_request(NULL, | 4043 | i_ipmi_request(NULL, |
@@ -3908,9 +4055,11 @@ static void send_panic_events(char *str) | |||
3908 | } | 4055 | } |
3909 | 4056 | ||
3910 | #ifdef CONFIG_IPMI_PANIC_STRING | 4057 | #ifdef CONFIG_IPMI_PANIC_STRING |
3911 | /* On every interface, dump a bunch of OEM event holding the | 4058 | /* |
3912 | string. */ | 4059 | * On every interface, dump a bunch of OEM event holding the |
3913 | if (!str) | 4060 | * string. |
4061 | */ | ||
4062 | if (!str) | ||
3914 | return; | 4063 | return; |
3915 | 4064 | ||
3916 | /* For every registered interface, send the event. */ | 4065 | /* For every registered interface, send the event. */ |
@@ -3931,11 +4080,13 @@ static void send_panic_events(char *str) | |||
3931 | */ | 4080 | */ |
3932 | smp_rmb(); | 4081 | smp_rmb(); |
3933 | 4082 | ||
3934 | /* First job here is to figure out where to send the | 4083 | /* |
3935 | OEM events. There's no way in IPMI to send OEM | 4084 | * First job here is to figure out where to send the |
3936 | events using an event send command, so we have to | 4085 | * OEM events. There's no way in IPMI to send OEM |
3937 | find the SEL to put them in and stick them in | 4086 | * events using an event send command, so we have to |
3938 | there. */ | 4087 | * find the SEL to put them in and stick them in |
4088 | * there. | ||
4089 | */ | ||
3939 | 4090 | ||
3940 | /* Get capabilities from the get device id. */ | 4091 | /* Get capabilities from the get device id. */ |
3941 | intf->local_sel_device = 0; | 4092 | intf->local_sel_device = 0; |
@@ -3983,24 +4134,29 @@ static void send_panic_events(char *str) | |||
3983 | } | 4134 | } |
3984 | intf->null_user_handler = NULL; | 4135 | intf->null_user_handler = NULL; |
3985 | 4136 | ||
3986 | /* Validate the event receiver. The low bit must not | 4137 | /* |
3987 | be 1 (it must be a valid IPMB address), it cannot | 4138 | * Validate the event receiver. The low bit must not |
3988 | be zero, and it must not be my address. */ | 4139 | * be 1 (it must be a valid IPMB address), it cannot |
3989 | if (((intf->event_receiver & 1) == 0) | 4140 | * be zero, and it must not be my address. |
4141 | */ | ||
4142 | if (((intf->event_receiver & 1) == 0) | ||
3990 | && (intf->event_receiver != 0) | 4143 | && (intf->event_receiver != 0) |
3991 | && (intf->event_receiver != intf->channels[0].address)) | 4144 | && (intf->event_receiver != intf->channels[0].address)) { |
3992 | { | 4145 | /* |
3993 | /* The event receiver is valid, send an IPMB | 4146 | * The event receiver is valid, send an IPMB |
3994 | message. */ | 4147 | * message. |
4148 | */ | ||
3995 | ipmb = (struct ipmi_ipmb_addr *) &addr; | 4149 | ipmb = (struct ipmi_ipmb_addr *) &addr; |
3996 | ipmb->addr_type = IPMI_IPMB_ADDR_TYPE; | 4150 | ipmb->addr_type = IPMI_IPMB_ADDR_TYPE; |
3997 | ipmb->channel = 0; /* FIXME - is this right? */ | 4151 | ipmb->channel = 0; /* FIXME - is this right? */ |
3998 | ipmb->lun = intf->event_receiver_lun; | 4152 | ipmb->lun = intf->event_receiver_lun; |
3999 | ipmb->slave_addr = intf->event_receiver; | 4153 | ipmb->slave_addr = intf->event_receiver; |
4000 | } else if (intf->local_sel_device) { | 4154 | } else if (intf->local_sel_device) { |
4001 | /* The event receiver was not valid (or was | 4155 | /* |
4002 | me), but I am an SEL device, just dump it | 4156 | * The event receiver was not valid (or was |
4003 | in my SEL. */ | 4157 | * me), but I am an SEL device, just dump it |
4158 | * in my SEL. | ||
4159 | */ | ||
4004 | si = (struct ipmi_system_interface_addr *) &addr; | 4160 | si = (struct ipmi_system_interface_addr *) &addr; |
4005 | si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 4161 | si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
4006 | si->channel = IPMI_BMC_CHANNEL; | 4162 | si->channel = IPMI_BMC_CHANNEL; |
@@ -4008,7 +4164,6 @@ static void send_panic_events(char *str) | |||
4008 | } else | 4164 | } else |
4009 | continue; /* No where to send the event. */ | 4165 | continue; /* No where to send the event. */ |
4010 | 4166 | ||
4011 | |||
4012 | msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */ | 4167 | msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */ |
4013 | msg.cmd = IPMI_ADD_SEL_ENTRY_CMD; | 4168 | msg.cmd = IPMI_ADD_SEL_ENTRY_CMD; |
4014 | msg.data = data; | 4169 | msg.data = data; |
@@ -4025,8 +4180,10 @@ static void send_panic_events(char *str) | |||
4025 | data[2] = 0xf0; /* OEM event without timestamp. */ | 4180 | data[2] = 0xf0; /* OEM event without timestamp. */ |
4026 | data[3] = intf->channels[0].address; | 4181 | data[3] = intf->channels[0].address; |
4027 | data[4] = j++; /* sequence # */ | 4182 | data[4] = j++; /* sequence # */ |
4028 | /* Always give 11 bytes, so strncpy will fill | 4183 | /* |
4029 | it with zeroes for me. */ | 4184 | * Always give 11 bytes, so strncpy will fill |
4185 | * it with zeroes for me. | ||
4186 | */ | ||
4030 | strncpy(data+5, p, 11); | 4187 | strncpy(data+5, p, 11); |
4031 | p += size; | 4188 | p += size; |
4032 | 4189 | ||
@@ -4043,7 +4200,7 @@ static void send_panic_events(char *str) | |||
4043 | intf->channels[0].lun, | 4200 | intf->channels[0].lun, |
4044 | 0, 1); /* no retry, and no wait. */ | 4201 | 0, 1); /* no retry, and no wait. */ |
4045 | } | 4202 | } |
4046 | } | 4203 | } |
4047 | #endif /* CONFIG_IPMI_PANIC_STRING */ | 4204 | #endif /* CONFIG_IPMI_PANIC_STRING */ |
4048 | } | 4205 | } |
4049 | #endif /* CONFIG_IPMI_PANIC_EVENT */ | 4206 | #endif /* CONFIG_IPMI_PANIC_EVENT */ |
@@ -4052,7 +4209,7 @@ static int has_panicked; | |||
4052 | 4209 | ||
4053 | static int panic_event(struct notifier_block *this, | 4210 | static int panic_event(struct notifier_block *this, |
4054 | unsigned long event, | 4211 | unsigned long event, |
4055 | void *ptr) | 4212 | void *ptr) |
4056 | { | 4213 | { |
4057 | ipmi_smi_t intf; | 4214 | ipmi_smi_t intf; |
4058 | 4215 | ||
@@ -4066,6 +4223,7 @@ static int panic_event(struct notifier_block *this, | |||
4066 | /* Interface is not ready. */ | 4223 | /* Interface is not ready. */ |
4067 | continue; | 4224 | continue; |
4068 | 4225 | ||
4226 | intf->run_to_completion = 1; | ||
4069 | intf->handlers->set_run_to_completion(intf->send_info, 1); | 4227 | intf->handlers->set_run_to_completion(intf->send_info, 1); |
4070 | } | 4228 | } |
4071 | 4229 | ||
@@ -4133,11 +4291,16 @@ static __exit void cleanup_ipmi(void) | |||
4133 | 4291 | ||
4134 | atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block); | 4292 | atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block); |
4135 | 4293 | ||
4136 | /* This can't be called if any interfaces exist, so no worry about | 4294 | /* |
4137 | shutting down the interfaces. */ | 4295 | * This can't be called if any interfaces exist, so no worry |
4296 | * about shutting down the interfaces. | ||
4297 | */ | ||
4138 | 4298 | ||
4139 | /* Tell the timer to stop, then wait for it to stop. This avoids | 4299 | /* |
4140 | problems with race conditions removing the timer here. */ | 4300 | * Tell the timer to stop, then wait for it to stop. This |
4301 | * avoids problems with race conditions removing the timer | ||
4302 | * here. | ||
4303 | */ | ||
4141 | atomic_inc(&stop_operation); | 4304 | atomic_inc(&stop_operation); |
4142 | del_timer_sync(&ipmi_timer); | 4305 | del_timer_sync(&ipmi_timer); |
4143 | 4306 | ||
@@ -4164,31 +4327,6 @@ module_exit(cleanup_ipmi); | |||
4164 | module_init(ipmi_init_msghandler_mod); | 4327 | module_init(ipmi_init_msghandler_mod); |
4165 | MODULE_LICENSE("GPL"); | 4328 | MODULE_LICENSE("GPL"); |
4166 | MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); | 4329 | MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); |
4167 | MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI interface."); | 4330 | MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI" |
4331 | " interface."); | ||
4168 | MODULE_VERSION(IPMI_DRIVER_VERSION); | 4332 | MODULE_VERSION(IPMI_DRIVER_VERSION); |
4169 | |||
4170 | EXPORT_SYMBOL(ipmi_create_user); | ||
4171 | EXPORT_SYMBOL(ipmi_destroy_user); | ||
4172 | EXPORT_SYMBOL(ipmi_get_version); | ||
4173 | EXPORT_SYMBOL(ipmi_request_settime); | ||
4174 | EXPORT_SYMBOL(ipmi_request_supply_msgs); | ||
4175 | EXPORT_SYMBOL(ipmi_poll_interface); | ||
4176 | EXPORT_SYMBOL(ipmi_register_smi); | ||
4177 | EXPORT_SYMBOL(ipmi_unregister_smi); | ||
4178 | EXPORT_SYMBOL(ipmi_register_for_cmd); | ||
4179 | EXPORT_SYMBOL(ipmi_unregister_for_cmd); | ||
4180 | EXPORT_SYMBOL(ipmi_smi_msg_received); | ||
4181 | EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout); | ||
4182 | EXPORT_SYMBOL(ipmi_alloc_smi_msg); | ||
4183 | EXPORT_SYMBOL(ipmi_addr_length); | ||
4184 | EXPORT_SYMBOL(ipmi_validate_addr); | ||
4185 | EXPORT_SYMBOL(ipmi_set_gets_events); | ||
4186 | EXPORT_SYMBOL(ipmi_smi_watcher_register); | ||
4187 | EXPORT_SYMBOL(ipmi_smi_watcher_unregister); | ||
4188 | EXPORT_SYMBOL(ipmi_set_my_address); | ||
4189 | EXPORT_SYMBOL(ipmi_get_my_address); | ||
4190 | EXPORT_SYMBOL(ipmi_set_my_LUN); | ||
4191 | EXPORT_SYMBOL(ipmi_get_my_LUN); | ||
4192 | EXPORT_SYMBOL(ipmi_smi_add_proc_entry); | ||
4193 | EXPORT_SYMBOL(ipmi_user_set_run_to_completion); | ||
4194 | EXPORT_SYMBOL(ipmi_free_recv_msg); | ||
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index b86186de7f07..a261bd735dfb 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -87,7 +87,10 @@ MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " | |||
87 | 87 | ||
88 | /* parameter definition to allow user to flag power cycle */ | 88 | /* parameter definition to allow user to flag power cycle */ |
89 | module_param(poweroff_powercycle, int, 0644); | 89 | module_param(poweroff_powercycle, int, 0644); |
90 | MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); | 90 | MODULE_PARM_DESC(poweroff_powercycle, |
91 | " Set to non-zero to enable power cycle instead of power" | ||
92 | " down. Power cycle is contingent on hardware support," | ||
93 | " otherwise it defaults back to power down."); | ||
91 | 94 | ||
92 | /* Stuff from the get device id command. */ | 95 | /* Stuff from the get device id command. */ |
93 | static unsigned int mfg_id; | 96 | static unsigned int mfg_id; |
@@ -95,22 +98,25 @@ static unsigned int prod_id; | |||
95 | static unsigned char capabilities; | 98 | static unsigned char capabilities; |
96 | static unsigned char ipmi_version; | 99 | static unsigned char ipmi_version; |
97 | 100 | ||
98 | /* We use our own messages for this operation, we don't let the system | 101 | /* |
99 | allocate them, since we may be in a panic situation. The whole | 102 | * We use our own messages for this operation, we don't let the system |
100 | thing is single-threaded, anyway, so multiple messages are not | 103 | * allocate them, since we may be in a panic situation. The whole |
101 | required. */ | 104 | * thing is single-threaded, anyway, so multiple messages are not |
105 | * required. | ||
106 | */ | ||
107 | static atomic_t dummy_count = ATOMIC_INIT(0); | ||
102 | static void dummy_smi_free(struct ipmi_smi_msg *msg) | 108 | static void dummy_smi_free(struct ipmi_smi_msg *msg) |
103 | { | 109 | { |
110 | atomic_dec(&dummy_count); | ||
104 | } | 111 | } |
105 | static void dummy_recv_free(struct ipmi_recv_msg *msg) | 112 | static void dummy_recv_free(struct ipmi_recv_msg *msg) |
106 | { | 113 | { |
114 | atomic_dec(&dummy_count); | ||
107 | } | 115 | } |
108 | static struct ipmi_smi_msg halt_smi_msg = | 116 | static struct ipmi_smi_msg halt_smi_msg = { |
109 | { | ||
110 | .done = dummy_smi_free | 117 | .done = dummy_smi_free |
111 | }; | 118 | }; |
112 | static struct ipmi_recv_msg halt_recv_msg = | 119 | static struct ipmi_recv_msg halt_recv_msg = { |
113 | { | ||
114 | .done = dummy_recv_free | 120 | .done = dummy_recv_free |
115 | }; | 121 | }; |
116 | 122 | ||
@@ -127,8 +133,7 @@ static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data) | |||
127 | complete(comp); | 133 | complete(comp); |
128 | } | 134 | } |
129 | 135 | ||
130 | static struct ipmi_user_hndl ipmi_poweroff_handler = | 136 | static struct ipmi_user_hndl ipmi_poweroff_handler = { |
131 | { | ||
132 | .ipmi_recv_hndl = receive_handler | 137 | .ipmi_recv_hndl = receive_handler |
133 | }; | 138 | }; |
134 | 139 | ||
@@ -152,17 +157,28 @@ static int ipmi_request_wait_for_response(ipmi_user_t user, | |||
152 | return halt_recv_msg.msg.data[0]; | 157 | return halt_recv_msg.msg.data[0]; |
153 | } | 158 | } |
154 | 159 | ||
155 | /* We are in run-to-completion mode, no completion is desired. */ | 160 | /* Wait for message to complete, spinning. */ |
156 | static int ipmi_request_in_rc_mode(ipmi_user_t user, | 161 | static int ipmi_request_in_rc_mode(ipmi_user_t user, |
157 | struct ipmi_addr *addr, | 162 | struct ipmi_addr *addr, |
158 | struct kernel_ipmi_msg *send_msg) | 163 | struct kernel_ipmi_msg *send_msg) |
159 | { | 164 | { |
160 | int rv; | 165 | int rv; |
161 | 166 | ||
167 | atomic_set(&dummy_count, 2); | ||
162 | rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, | 168 | rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, |
163 | &halt_smi_msg, &halt_recv_msg, 0); | 169 | &halt_smi_msg, &halt_recv_msg, 0); |
164 | if (rv) | 170 | if (rv) { |
171 | atomic_set(&dummy_count, 0); | ||
165 | return rv; | 172 | return rv; |
173 | } | ||
174 | |||
175 | /* | ||
176 | * Spin until our message is done. | ||
177 | */ | ||
178 | while (atomic_read(&dummy_count) > 0) { | ||
179 | ipmi_poll_interface(user); | ||
180 | cpu_relax(); | ||
181 | } | ||
166 | 182 | ||
167 | return halt_recv_msg.msg.data[0]; | 183 | return halt_recv_msg.msg.data[0]; |
168 | } | 184 | } |
@@ -184,47 +200,47 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user, | |||
184 | 200 | ||
185 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user); | 201 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user); |
186 | 202 | ||
187 | static void pps_poweroff_atca (ipmi_user_t user) | 203 | static void pps_poweroff_atca(ipmi_user_t user) |
188 | { | 204 | { |
189 | struct ipmi_system_interface_addr smi_addr; | 205 | struct ipmi_system_interface_addr smi_addr; |
190 | struct kernel_ipmi_msg send_msg; | 206 | struct kernel_ipmi_msg send_msg; |
191 | int rv; | 207 | int rv; |
192 | /* | 208 | /* |
193 | * Configure IPMI address for local access | 209 | * Configure IPMI address for local access |
194 | */ | 210 | */ |
195 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 211 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
196 | smi_addr.channel = IPMI_BMC_CHANNEL; | 212 | smi_addr.channel = IPMI_BMC_CHANNEL; |
197 | smi_addr.lun = 0; | 213 | smi_addr.lun = 0; |
198 | 214 | ||
199 | printk(KERN_INFO PFX "PPS powerdown hook used"); | 215 | printk(KERN_INFO PFX "PPS powerdown hook used"); |
200 | 216 | ||
201 | send_msg.netfn = IPMI_NETFN_OEM; | 217 | send_msg.netfn = IPMI_NETFN_OEM; |
202 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; | 218 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; |
203 | send_msg.data = IPMI_ATCA_PPS_IANA; | 219 | send_msg.data = IPMI_ATCA_PPS_IANA; |
204 | send_msg.data_len = 3; | 220 | send_msg.data_len = 3; |
205 | rv = ipmi_request_in_rc_mode(user, | 221 | rv = ipmi_request_in_rc_mode(user, |
206 | (struct ipmi_addr *) &smi_addr, | 222 | (struct ipmi_addr *) &smi_addr, |
207 | &send_msg); | 223 | &send_msg); |
208 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | 224 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { |
209 | printk(KERN_ERR PFX "Unable to send ATCA ," | 225 | printk(KERN_ERR PFX "Unable to send ATCA ," |
210 | " IPMI error 0x%x\n", rv); | 226 | " IPMI error 0x%x\n", rv); |
211 | } | 227 | } |
212 | return; | 228 | return; |
213 | } | 229 | } |
214 | 230 | ||
215 | static int ipmi_atca_detect (ipmi_user_t user) | 231 | static int ipmi_atca_detect(ipmi_user_t user) |
216 | { | 232 | { |
217 | struct ipmi_system_interface_addr smi_addr; | 233 | struct ipmi_system_interface_addr smi_addr; |
218 | struct kernel_ipmi_msg send_msg; | 234 | struct kernel_ipmi_msg send_msg; |
219 | int rv; | 235 | int rv; |
220 | unsigned char data[1]; | 236 | unsigned char data[1]; |
221 | 237 | ||
222 | /* | 238 | /* |
223 | * Configure IPMI address for local access | 239 | * Configure IPMI address for local access |
224 | */ | 240 | */ |
225 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 241 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
226 | smi_addr.channel = IPMI_BMC_CHANNEL; | 242 | smi_addr.channel = IPMI_BMC_CHANNEL; |
227 | smi_addr.lun = 0; | 243 | smi_addr.lun = 0; |
228 | 244 | ||
229 | /* | 245 | /* |
230 | * Use get address info to check and see if we are ATCA | 246 | * Use get address info to check and see if we are ATCA |
@@ -238,28 +254,30 @@ static int ipmi_atca_detect (ipmi_user_t user) | |||
238 | (struct ipmi_addr *) &smi_addr, | 254 | (struct ipmi_addr *) &smi_addr, |
239 | &send_msg); | 255 | &send_msg); |
240 | 256 | ||
241 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id); | 257 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", |
242 | if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) | 258 | mfg_id, prod_id); |
243 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { | 259 | if ((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) |
244 | printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n"); | 260 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { |
261 | printk(KERN_INFO PFX | ||
262 | "Installing Pigeon Point Systems Poweroff Hook\n"); | ||
245 | atca_oem_poweroff_hook = pps_poweroff_atca; | 263 | atca_oem_poweroff_hook = pps_poweroff_atca; |
246 | } | 264 | } |
247 | return !rv; | 265 | return !rv; |
248 | } | 266 | } |
249 | 267 | ||
250 | static void ipmi_poweroff_atca (ipmi_user_t user) | 268 | static void ipmi_poweroff_atca(ipmi_user_t user) |
251 | { | 269 | { |
252 | struct ipmi_system_interface_addr smi_addr; | 270 | struct ipmi_system_interface_addr smi_addr; |
253 | struct kernel_ipmi_msg send_msg; | 271 | struct kernel_ipmi_msg send_msg; |
254 | int rv; | 272 | int rv; |
255 | unsigned char data[4]; | 273 | unsigned char data[4]; |
256 | 274 | ||
257 | /* | 275 | /* |
258 | * Configure IPMI address for local access | 276 | * Configure IPMI address for local access |
259 | */ | 277 | */ |
260 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 278 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
261 | smi_addr.channel = IPMI_BMC_CHANNEL; | 279 | smi_addr.channel = IPMI_BMC_CHANNEL; |
262 | smi_addr.lun = 0; | 280 | smi_addr.lun = 0; |
263 | 281 | ||
264 | printk(KERN_INFO PFX "Powering down via ATCA power command\n"); | 282 | printk(KERN_INFO PFX "Powering down via ATCA power command\n"); |
265 | 283 | ||
@@ -273,23 +291,24 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
273 | data[2] = 0; /* Power Level */ | 291 | data[2] = 0; /* Power Level */ |
274 | data[3] = 0; /* Don't change saved presets */ | 292 | data[3] = 0; /* Don't change saved presets */ |
275 | send_msg.data = data; | 293 | send_msg.data = data; |
276 | send_msg.data_len = sizeof (data); | 294 | send_msg.data_len = sizeof(data); |
277 | rv = ipmi_request_in_rc_mode(user, | 295 | rv = ipmi_request_in_rc_mode(user, |
278 | (struct ipmi_addr *) &smi_addr, | 296 | (struct ipmi_addr *) &smi_addr, |
279 | &send_msg); | 297 | &send_msg); |
280 | /** At this point, the system may be shutting down, and most | 298 | /* |
281 | ** serial drivers (if used) will have interrupts turned off | 299 | * At this point, the system may be shutting down, and most |
282 | ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE | 300 | * serial drivers (if used) will have interrupts turned off |
283 | ** return code | 301 | * it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE |
284 | **/ | 302 | * return code |
285 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | 303 | */ |
304 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
286 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," | 305 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," |
287 | " IPMI error 0x%x\n", rv); | 306 | " IPMI error 0x%x\n", rv); |
288 | goto out; | 307 | goto out; |
289 | } | 308 | } |
290 | 309 | ||
291 | if(atca_oem_poweroff_hook) | 310 | if (atca_oem_poweroff_hook) |
292 | return atca_oem_poweroff_hook(user); | 311 | atca_oem_poweroff_hook(user); |
293 | out: | 312 | out: |
294 | return; | 313 | return; |
295 | } | 314 | } |
@@ -310,13 +329,13 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
310 | #define IPMI_CPI1_PRODUCT_ID 0x000157 | 329 | #define IPMI_CPI1_PRODUCT_ID 0x000157 |
311 | #define IPMI_CPI1_MANUFACTURER_ID 0x0108 | 330 | #define IPMI_CPI1_MANUFACTURER_ID 0x0108 |
312 | 331 | ||
313 | static int ipmi_cpi1_detect (ipmi_user_t user) | 332 | static int ipmi_cpi1_detect(ipmi_user_t user) |
314 | { | 333 | { |
315 | return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID) | 334 | return ((mfg_id == IPMI_CPI1_MANUFACTURER_ID) |
316 | && (prod_id == IPMI_CPI1_PRODUCT_ID)); | 335 | && (prod_id == IPMI_CPI1_PRODUCT_ID)); |
317 | } | 336 | } |
318 | 337 | ||
319 | static void ipmi_poweroff_cpi1 (ipmi_user_t user) | 338 | static void ipmi_poweroff_cpi1(ipmi_user_t user) |
320 | { | 339 | { |
321 | struct ipmi_system_interface_addr smi_addr; | 340 | struct ipmi_system_interface_addr smi_addr; |
322 | struct ipmi_ipmb_addr ipmb_addr; | 341 | struct ipmi_ipmb_addr ipmb_addr; |
@@ -328,12 +347,12 @@ static void ipmi_poweroff_cpi1 (ipmi_user_t user) | |||
328 | unsigned char aer_addr; | 347 | unsigned char aer_addr; |
329 | unsigned char aer_lun; | 348 | unsigned char aer_lun; |
330 | 349 | ||
331 | /* | 350 | /* |
332 | * Configure IPMI address for local access | 351 | * Configure IPMI address for local access |
333 | */ | 352 | */ |
334 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 353 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
335 | smi_addr.channel = IPMI_BMC_CHANNEL; | 354 | smi_addr.channel = IPMI_BMC_CHANNEL; |
336 | smi_addr.lun = 0; | 355 | smi_addr.lun = 0; |
337 | 356 | ||
338 | printk(KERN_INFO PFX "Powering down via CPI1 power command\n"); | 357 | printk(KERN_INFO PFX "Powering down via CPI1 power command\n"); |
339 | 358 | ||
@@ -425,7 +444,7 @@ static void ipmi_poweroff_cpi1 (ipmi_user_t user) | |||
425 | */ | 444 | */ |
426 | 445 | ||
427 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} | 446 | #define DELL_IANA_MFR_ID {0xA2, 0x02, 0x00} |
428 | static int ipmi_dell_chassis_detect (ipmi_user_t user) | 447 | static int ipmi_dell_chassis_detect(ipmi_user_t user) |
429 | { | 448 | { |
430 | const char ipmi_version_major = ipmi_version & 0xF; | 449 | const char ipmi_version_major = ipmi_version & 0xF; |
431 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; | 450 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; |
@@ -444,25 +463,25 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user) | |||
444 | #define IPMI_NETFN_CHASSIS_REQUEST 0 | 463 | #define IPMI_NETFN_CHASSIS_REQUEST 0 |
445 | #define IPMI_CHASSIS_CONTROL_CMD 0x02 | 464 | #define IPMI_CHASSIS_CONTROL_CMD 0x02 |
446 | 465 | ||
447 | static int ipmi_chassis_detect (ipmi_user_t user) | 466 | static int ipmi_chassis_detect(ipmi_user_t user) |
448 | { | 467 | { |
449 | /* Chassis support, use it. */ | 468 | /* Chassis support, use it. */ |
450 | return (capabilities & 0x80); | 469 | return (capabilities & 0x80); |
451 | } | 470 | } |
452 | 471 | ||
453 | static void ipmi_poweroff_chassis (ipmi_user_t user) | 472 | static void ipmi_poweroff_chassis(ipmi_user_t user) |
454 | { | 473 | { |
455 | struct ipmi_system_interface_addr smi_addr; | 474 | struct ipmi_system_interface_addr smi_addr; |
456 | struct kernel_ipmi_msg send_msg; | 475 | struct kernel_ipmi_msg send_msg; |
457 | int rv; | 476 | int rv; |
458 | unsigned char data[1]; | 477 | unsigned char data[1]; |
459 | 478 | ||
460 | /* | 479 | /* |
461 | * Configure IPMI address for local access | 480 | * Configure IPMI address for local access |
462 | */ | 481 | */ |
463 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 482 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
464 | smi_addr.channel = IPMI_BMC_CHANNEL; | 483 | smi_addr.channel = IPMI_BMC_CHANNEL; |
465 | smi_addr.lun = 0; | 484 | smi_addr.lun = 0; |
466 | 485 | ||
467 | powercyclefailed: | 486 | powercyclefailed: |
468 | printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n", | 487 | printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n", |
@@ -525,15 +544,13 @@ static struct poweroff_function poweroff_functions[] = { | |||
525 | 544 | ||
526 | 545 | ||
527 | /* Called on a powerdown request. */ | 546 | /* Called on a powerdown request. */ |
528 | static void ipmi_poweroff_function (void) | 547 | static void ipmi_poweroff_function(void) |
529 | { | 548 | { |
530 | if (!ready) | 549 | if (!ready) |
531 | return; | 550 | return; |
532 | 551 | ||
533 | /* Use run-to-completion mode, since interrupts may be off. */ | 552 | /* Use run-to-completion mode, since interrupts may be off. */ |
534 | ipmi_user_set_run_to_completion(ipmi_user, 1); | ||
535 | specific_poweroff_func(ipmi_user); | 553 | specific_poweroff_func(ipmi_user); |
536 | ipmi_user_set_run_to_completion(ipmi_user, 0); | ||
537 | } | 554 | } |
538 | 555 | ||
539 | /* Wait for an IPMI interface to be installed, the first one installed | 556 | /* Wait for an IPMI interface to be installed, the first one installed |
@@ -561,13 +578,13 @@ static void ipmi_po_new_smi(int if_num, struct device *device) | |||
561 | 578 | ||
562 | ipmi_ifnum = if_num; | 579 | ipmi_ifnum = if_num; |
563 | 580 | ||
564 | /* | 581 | /* |
565 | * Do a get device ide and store some results, since this is | 582 | * Do a get device ide and store some results, since this is |
566 | * used by several functions. | 583 | * used by several functions. |
567 | */ | 584 | */ |
568 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 585 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
569 | smi_addr.channel = IPMI_BMC_CHANNEL; | 586 | smi_addr.channel = IPMI_BMC_CHANNEL; |
570 | smi_addr.lun = 0; | 587 | smi_addr.lun = 0; |
571 | 588 | ||
572 | send_msg.netfn = IPMI_NETFN_APP_REQUEST; | 589 | send_msg.netfn = IPMI_NETFN_APP_REQUEST; |
573 | send_msg.cmd = IPMI_GET_DEVICE_ID_CMD; | 590 | send_msg.cmd = IPMI_GET_DEVICE_ID_CMD; |
@@ -632,8 +649,7 @@ static void ipmi_po_smi_gone(int if_num) | |||
632 | pm_power_off = old_poweroff_func; | 649 | pm_power_off = old_poweroff_func; |
633 | } | 650 | } |
634 | 651 | ||
635 | static struct ipmi_smi_watcher smi_watcher = | 652 | static struct ipmi_smi_watcher smi_watcher = { |
636 | { | ||
637 | .owner = THIS_MODULE, | 653 | .owner = THIS_MODULE, |
638 | .new_smi = ipmi_po_new_smi, | 654 | .new_smi = ipmi_po_new_smi, |
639 | .smi_gone = ipmi_po_smi_gone | 655 | .smi_gone = ipmi_po_smi_gone |
@@ -675,12 +691,12 @@ static struct ctl_table_header *ipmi_table_header; | |||
675 | /* | 691 | /* |
676 | * Startup and shutdown functions. | 692 | * Startup and shutdown functions. |
677 | */ | 693 | */ |
678 | static int ipmi_poweroff_init (void) | 694 | static int ipmi_poweroff_init(void) |
679 | { | 695 | { |
680 | int rv; | 696 | int rv; |
681 | 697 | ||
682 | printk (KERN_INFO "Copyright (C) 2004 MontaVista Software -" | 698 | printk(KERN_INFO "Copyright (C) 2004 MontaVista Software -" |
683 | " IPMI Powerdown via sys_reboot.\n"); | 699 | " IPMI Powerdown via sys_reboot.\n"); |
684 | 700 | ||
685 | if (poweroff_powercycle) | 701 | if (poweroff_powercycle) |
686 | printk(KERN_INFO PFX "Power cycle is enabled.\n"); | 702 | printk(KERN_INFO PFX "Power cycle is enabled.\n"); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4f560d0bb808..5a5455585c1d 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #define SI_USEC_PER_JIFFY (1000000/HZ) | 80 | #define SI_USEC_PER_JIFFY (1000000/HZ) |
81 | #define SI_TIMEOUT_JIFFIES (SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY) | 81 | #define SI_TIMEOUT_JIFFIES (SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY) |
82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a | 82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a |
83 | short timeout */ | 83 | short timeout */ |
84 | 84 | ||
85 | /* Bit for BMC global enables. */ | 85 | /* Bit for BMC global enables. */ |
86 | #define IPMI_BMC_RCV_MSG_INTR 0x01 | 86 | #define IPMI_BMC_RCV_MSG_INTR 0x01 |
@@ -114,14 +114,61 @@ static char *si_to_str[] = { "kcs", "smic", "bt" }; | |||
114 | 114 | ||
115 | #define DEVICE_NAME "ipmi_si" | 115 | #define DEVICE_NAME "ipmi_si" |
116 | 116 | ||
117 | static struct device_driver ipmi_driver = | 117 | static struct device_driver ipmi_driver = { |
118 | { | ||
119 | .name = DEVICE_NAME, | 118 | .name = DEVICE_NAME, |
120 | .bus = &platform_bus_type | 119 | .bus = &platform_bus_type |
121 | }; | 120 | }; |
122 | 121 | ||
123 | struct smi_info | 122 | |
124 | { | 123 | /* |
124 | * Indexes into stats[] in smi_info below. | ||
125 | */ | ||
126 | enum si_stat_indexes { | ||
127 | /* | ||
128 | * Number of times the driver requested a timer while an operation | ||
129 | * was in progress. | ||
130 | */ | ||
131 | SI_STAT_short_timeouts = 0, | ||
132 | |||
133 | /* | ||
134 | * Number of times the driver requested a timer while nothing was in | ||
135 | * progress. | ||
136 | */ | ||
137 | SI_STAT_long_timeouts, | ||
138 | |||
139 | /* Number of times the interface was idle while being polled. */ | ||
140 | SI_STAT_idles, | ||
141 | |||
142 | /* Number of interrupts the driver handled. */ | ||
143 | SI_STAT_interrupts, | ||
144 | |||
145 | /* Number of time the driver got an ATTN from the hardware. */ | ||
146 | SI_STAT_attentions, | ||
147 | |||
148 | /* Number of times the driver requested flags from the hardware. */ | ||
149 | SI_STAT_flag_fetches, | ||
150 | |||
151 | /* Number of times the hardware didn't follow the state machine. */ | ||
152 | SI_STAT_hosed_count, | ||
153 | |||
154 | /* Number of completed messages. */ | ||
155 | SI_STAT_complete_transactions, | ||
156 | |||
157 | /* Number of IPMI events received from the hardware. */ | ||
158 | SI_STAT_events, | ||
159 | |||
160 | /* Number of watchdog pretimeouts. */ | ||
161 | SI_STAT_watchdog_pretimeouts, | ||
162 | |||
163 | /* Number of asyncronous messages received. */ | ||
164 | SI_STAT_incoming_messages, | ||
165 | |||
166 | |||
167 | /* This *must* remain last, add new values above this. */ | ||
168 | SI_NUM_STATS | ||
169 | }; | ||
170 | |||
171 | struct smi_info { | ||
125 | int intf_num; | 172 | int intf_num; |
126 | ipmi_smi_t intf; | 173 | ipmi_smi_t intf; |
127 | struct si_sm_data *si_sm; | 174 | struct si_sm_data *si_sm; |
@@ -134,8 +181,10 @@ struct smi_info | |||
134 | struct ipmi_smi_msg *curr_msg; | 181 | struct ipmi_smi_msg *curr_msg; |
135 | enum si_intf_state si_state; | 182 | enum si_intf_state si_state; |
136 | 183 | ||
137 | /* Used to handle the various types of I/O that can occur with | 184 | /* |
138 | IPMI */ | 185 | * Used to handle the various types of I/O that can occur with |
186 | * IPMI | ||
187 | */ | ||
139 | struct si_sm_io io; | 188 | struct si_sm_io io; |
140 | int (*io_setup)(struct smi_info *info); | 189 | int (*io_setup)(struct smi_info *info); |
141 | void (*io_cleanup)(struct smi_info *info); | 190 | void (*io_cleanup)(struct smi_info *info); |
@@ -146,15 +195,18 @@ struct smi_info | |||
146 | void (*addr_source_cleanup)(struct smi_info *info); | 195 | void (*addr_source_cleanup)(struct smi_info *info); |
147 | void *addr_source_data; | 196 | void *addr_source_data; |
148 | 197 | ||
149 | /* Per-OEM handler, called from handle_flags(). | 198 | /* |
150 | Returns 1 when handle_flags() needs to be re-run | 199 | * Per-OEM handler, called from handle_flags(). Returns 1 |
151 | or 0 indicating it set si_state itself. | 200 | * when handle_flags() needs to be re-run or 0 indicating it |
152 | */ | 201 | * set si_state itself. |
202 | */ | ||
153 | int (*oem_data_avail_handler)(struct smi_info *smi_info); | 203 | int (*oem_data_avail_handler)(struct smi_info *smi_info); |
154 | 204 | ||
155 | /* Flags from the last GET_MSG_FLAGS command, used when an ATTN | 205 | /* |
156 | is set to hold the flags until we are done handling everything | 206 | * Flags from the last GET_MSG_FLAGS command, used when an ATTN |
157 | from the flags. */ | 207 | * is set to hold the flags until we are done handling everything |
208 | * from the flags. | ||
209 | */ | ||
158 | #define RECEIVE_MSG_AVAIL 0x01 | 210 | #define RECEIVE_MSG_AVAIL 0x01 |
159 | #define EVENT_MSG_BUFFER_FULL 0x02 | 211 | #define EVENT_MSG_BUFFER_FULL 0x02 |
160 | #define WDT_PRE_TIMEOUT_INT 0x08 | 212 | #define WDT_PRE_TIMEOUT_INT 0x08 |
@@ -162,25 +214,31 @@ struct smi_info | |||
162 | #define OEM1_DATA_AVAIL 0x40 | 214 | #define OEM1_DATA_AVAIL 0x40 |
163 | #define OEM2_DATA_AVAIL 0x80 | 215 | #define OEM2_DATA_AVAIL 0x80 |
164 | #define OEM_DATA_AVAIL (OEM0_DATA_AVAIL | \ | 216 | #define OEM_DATA_AVAIL (OEM0_DATA_AVAIL | \ |
165 | OEM1_DATA_AVAIL | \ | 217 | OEM1_DATA_AVAIL | \ |
166 | OEM2_DATA_AVAIL) | 218 | OEM2_DATA_AVAIL) |
167 | unsigned char msg_flags; | 219 | unsigned char msg_flags; |
168 | 220 | ||
169 | /* If set to true, this will request events the next time the | 221 | /* |
170 | state machine is idle. */ | 222 | * If set to true, this will request events the next time the |
223 | * state machine is idle. | ||
224 | */ | ||
171 | atomic_t req_events; | 225 | atomic_t req_events; |
172 | 226 | ||
173 | /* If true, run the state machine to completion on every send | 227 | /* |
174 | call. Generally used after a panic to make sure stuff goes | 228 | * If true, run the state machine to completion on every send |
175 | out. */ | 229 | * call. Generally used after a panic to make sure stuff goes |
230 | * out. | ||
231 | */ | ||
176 | int run_to_completion; | 232 | int run_to_completion; |
177 | 233 | ||
178 | /* The I/O port of an SI interface. */ | 234 | /* The I/O port of an SI interface. */ |
179 | int port; | 235 | int port; |
180 | 236 | ||
181 | /* The space between start addresses of the two ports. For | 237 | /* |
182 | instance, if the first port is 0xca2 and the spacing is 4, then | 238 | * The space between start addresses of the two ports. For |
183 | the second port is 0xca6. */ | 239 | * instance, if the first port is 0xca2 and the spacing is 4, then |
240 | * the second port is 0xca6. | ||
241 | */ | ||
184 | unsigned int spacing; | 242 | unsigned int spacing; |
185 | 243 | ||
186 | /* zero if no irq; */ | 244 | /* zero if no irq; */ |
@@ -195,10 +253,12 @@ struct smi_info | |||
195 | /* Used to gracefully stop the timer without race conditions. */ | 253 | /* Used to gracefully stop the timer without race conditions. */ |
196 | atomic_t stop_operation; | 254 | atomic_t stop_operation; |
197 | 255 | ||
198 | /* The driver will disable interrupts when it gets into a | 256 | /* |
199 | situation where it cannot handle messages due to lack of | 257 | * The driver will disable interrupts when it gets into a |
200 | memory. Once that situation clears up, it will re-enable | 258 | * situation where it cannot handle messages due to lack of |
201 | interrupts. */ | 259 | * memory. Once that situation clears up, it will re-enable |
260 | * interrupts. | ||
261 | */ | ||
202 | int interrupt_disabled; | 262 | int interrupt_disabled; |
203 | 263 | ||
204 | /* From the get device id response... */ | 264 | /* From the get device id response... */ |
@@ -208,33 +268,28 @@ struct smi_info | |||
208 | struct device *dev; | 268 | struct device *dev; |
209 | struct platform_device *pdev; | 269 | struct platform_device *pdev; |
210 | 270 | ||
211 | /* True if we allocated the device, false if it came from | 271 | /* |
212 | * someplace else (like PCI). */ | 272 | * True if we allocated the device, false if it came from |
273 | * someplace else (like PCI). | ||
274 | */ | ||
213 | int dev_registered; | 275 | int dev_registered; |
214 | 276 | ||
215 | /* Slave address, could be reported from DMI. */ | 277 | /* Slave address, could be reported from DMI. */ |
216 | unsigned char slave_addr; | 278 | unsigned char slave_addr; |
217 | 279 | ||
218 | /* Counters and things for the proc filesystem. */ | 280 | /* Counters and things for the proc filesystem. */ |
219 | spinlock_t count_lock; | 281 | atomic_t stats[SI_NUM_STATS]; |
220 | unsigned long short_timeouts; | 282 | |
221 | unsigned long long_timeouts; | 283 | struct task_struct *thread; |
222 | unsigned long timeout_restarts; | ||
223 | unsigned long idles; | ||
224 | unsigned long interrupts; | ||
225 | unsigned long attentions; | ||
226 | unsigned long flag_fetches; | ||
227 | unsigned long hosed_count; | ||
228 | unsigned long complete_transactions; | ||
229 | unsigned long events; | ||
230 | unsigned long watchdog_pretimeouts; | ||
231 | unsigned long incoming_messages; | ||
232 | |||
233 | struct task_struct *thread; | ||
234 | 284 | ||
235 | struct list_head link; | 285 | struct list_head link; |
236 | }; | 286 | }; |
237 | 287 | ||
288 | #define smi_inc_stat(smi, stat) \ | ||
289 | atomic_inc(&(smi)->stats[SI_STAT_ ## stat]) | ||
290 | #define smi_get_stat(smi, stat) \ | ||
291 | ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat])) | ||
292 | |||
238 | #define SI_MAX_PARMS 4 | 293 | #define SI_MAX_PARMS 4 |
239 | 294 | ||
240 | static int force_kipmid[SI_MAX_PARMS]; | 295 | static int force_kipmid[SI_MAX_PARMS]; |
@@ -246,7 +301,7 @@ static int try_smi_init(struct smi_info *smi); | |||
246 | static void cleanup_one_si(struct smi_info *to_clean); | 301 | static void cleanup_one_si(struct smi_info *to_clean); |
247 | 302 | ||
248 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); | 303 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
249 | static int register_xaction_notifier(struct notifier_block * nb) | 304 | static int register_xaction_notifier(struct notifier_block *nb) |
250 | { | 305 | { |
251 | return atomic_notifier_chain_register(&xaction_notifier_list, nb); | 306 | return atomic_notifier_chain_register(&xaction_notifier_list, nb); |
252 | } | 307 | } |
@@ -255,7 +310,7 @@ static void deliver_recv_msg(struct smi_info *smi_info, | |||
255 | struct ipmi_smi_msg *msg) | 310 | struct ipmi_smi_msg *msg) |
256 | { | 311 | { |
257 | /* Deliver the message to the upper layer with the lock | 312 | /* Deliver the message to the upper layer with the lock |
258 | released. */ | 313 | released. */ |
259 | spin_unlock(&(smi_info->si_lock)); | 314 | spin_unlock(&(smi_info->si_lock)); |
260 | ipmi_smi_msg_received(smi_info->intf, msg); | 315 | ipmi_smi_msg_received(smi_info->intf, msg); |
261 | spin_lock(&(smi_info->si_lock)); | 316 | spin_lock(&(smi_info->si_lock)); |
@@ -287,9 +342,12 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
287 | struct timeval t; | 342 | struct timeval t; |
288 | #endif | 343 | #endif |
289 | 344 | ||
290 | /* No need to save flags, we aleady have interrupts off and we | 345 | /* |
291 | already hold the SMI lock. */ | 346 | * No need to save flags, we aleady have interrupts off and we |
292 | spin_lock(&(smi_info->msg_lock)); | 347 | * already hold the SMI lock. |
348 | */ | ||
349 | if (!smi_info->run_to_completion) | ||
350 | spin_lock(&(smi_info->msg_lock)); | ||
293 | 351 | ||
294 | /* Pick the high priority queue first. */ | 352 | /* Pick the high priority queue first. */ |
295 | if (!list_empty(&(smi_info->hp_xmit_msgs))) { | 353 | if (!list_empty(&(smi_info->hp_xmit_msgs))) { |
@@ -310,7 +368,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
310 | link); | 368 | link); |
311 | #ifdef DEBUG_TIMING | 369 | #ifdef DEBUG_TIMING |
312 | do_gettimeofday(&t); | 370 | do_gettimeofday(&t); |
313 | printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 371 | printk(KERN_DEBUG "**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
314 | #endif | 372 | #endif |
315 | err = atomic_notifier_call_chain(&xaction_notifier_list, | 373 | err = atomic_notifier_call_chain(&xaction_notifier_list, |
316 | 0, smi_info); | 374 | 0, smi_info); |
@@ -322,14 +380,14 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
322 | smi_info->si_sm, | 380 | smi_info->si_sm, |
323 | smi_info->curr_msg->data, | 381 | smi_info->curr_msg->data, |
324 | smi_info->curr_msg->data_size); | 382 | smi_info->curr_msg->data_size); |
325 | if (err) { | 383 | if (err) |
326 | return_hosed_msg(smi_info, err); | 384 | return_hosed_msg(smi_info, err); |
327 | } | ||
328 | 385 | ||
329 | rv = SI_SM_CALL_WITHOUT_DELAY; | 386 | rv = SI_SM_CALL_WITHOUT_DELAY; |
330 | } | 387 | } |
331 | out: | 388 | out: |
332 | spin_unlock(&(smi_info->msg_lock)); | 389 | if (!smi_info->run_to_completion) |
390 | spin_unlock(&(smi_info->msg_lock)); | ||
333 | 391 | ||
334 | return rv; | 392 | return rv; |
335 | } | 393 | } |
@@ -338,8 +396,10 @@ static void start_enable_irq(struct smi_info *smi_info) | |||
338 | { | 396 | { |
339 | unsigned char msg[2]; | 397 | unsigned char msg[2]; |
340 | 398 | ||
341 | /* If we are enabling interrupts, we have to tell the | 399 | /* |
342 | BMC to use them. */ | 400 | * If we are enabling interrupts, we have to tell the |
401 | * BMC to use them. | ||
402 | */ | ||
343 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 403 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
344 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | 404 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; |
345 | 405 | ||
@@ -371,10 +431,12 @@ static void start_clear_flags(struct smi_info *smi_info) | |||
371 | smi_info->si_state = SI_CLEARING_FLAGS; | 431 | smi_info->si_state = SI_CLEARING_FLAGS; |
372 | } | 432 | } |
373 | 433 | ||
374 | /* When we have a situtaion where we run out of memory and cannot | 434 | /* |
375 | allocate messages, we just leave them in the BMC and run the system | 435 | * When we have a situtaion where we run out of memory and cannot |
376 | polled until we can allocate some memory. Once we have some | 436 | * allocate messages, we just leave them in the BMC and run the system |
377 | memory, we will re-enable the interrupt. */ | 437 | * polled until we can allocate some memory. Once we have some |
438 | * memory, we will re-enable the interrupt. | ||
439 | */ | ||
378 | static inline void disable_si_irq(struct smi_info *smi_info) | 440 | static inline void disable_si_irq(struct smi_info *smi_info) |
379 | { | 441 | { |
380 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 442 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
@@ -396,9 +458,7 @@ static void handle_flags(struct smi_info *smi_info) | |||
396 | retry: | 458 | retry: |
397 | if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { | 459 | if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) { |
398 | /* Watchdog pre-timeout */ | 460 | /* Watchdog pre-timeout */ |
399 | spin_lock(&smi_info->count_lock); | 461 | smi_inc_stat(smi_info, watchdog_pretimeouts); |
400 | smi_info->watchdog_pretimeouts++; | ||
401 | spin_unlock(&smi_info->count_lock); | ||
402 | 462 | ||
403 | start_clear_flags(smi_info); | 463 | start_clear_flags(smi_info); |
404 | smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; | 464 | smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; |
@@ -444,12 +504,11 @@ static void handle_flags(struct smi_info *smi_info) | |||
444 | smi_info->curr_msg->data_size); | 504 | smi_info->curr_msg->data_size); |
445 | smi_info->si_state = SI_GETTING_EVENTS; | 505 | smi_info->si_state = SI_GETTING_EVENTS; |
446 | } else if (smi_info->msg_flags & OEM_DATA_AVAIL && | 506 | } else if (smi_info->msg_flags & OEM_DATA_AVAIL && |
447 | smi_info->oem_data_avail_handler) { | 507 | smi_info->oem_data_avail_handler) { |
448 | if (smi_info->oem_data_avail_handler(smi_info)) | 508 | if (smi_info->oem_data_avail_handler(smi_info)) |
449 | goto retry; | 509 | goto retry; |
450 | } else { | 510 | } else |
451 | smi_info->si_state = SI_NORMAL; | 511 | smi_info->si_state = SI_NORMAL; |
452 | } | ||
453 | } | 512 | } |
454 | 513 | ||
455 | static void handle_transaction_done(struct smi_info *smi_info) | 514 | static void handle_transaction_done(struct smi_info *smi_info) |
@@ -459,7 +518,7 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
459 | struct timeval t; | 518 | struct timeval t; |
460 | 519 | ||
461 | do_gettimeofday(&t); | 520 | do_gettimeofday(&t); |
462 | printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 521 | printk(KERN_DEBUG "**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
463 | #endif | 522 | #endif |
464 | switch (smi_info->si_state) { | 523 | switch (smi_info->si_state) { |
465 | case SI_NORMAL: | 524 | case SI_NORMAL: |
@@ -472,9 +531,11 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
472 | smi_info->curr_msg->rsp, | 531 | smi_info->curr_msg->rsp, |
473 | IPMI_MAX_MSG_LENGTH); | 532 | IPMI_MAX_MSG_LENGTH); |
474 | 533 | ||
475 | /* Do this here becase deliver_recv_msg() releases the | 534 | /* |
476 | lock, and a new message can be put in during the | 535 | * Do this here becase deliver_recv_msg() releases the |
477 | time the lock is released. */ | 536 | * lock, and a new message can be put in during the |
537 | * time the lock is released. | ||
538 | */ | ||
478 | msg = smi_info->curr_msg; | 539 | msg = smi_info->curr_msg; |
479 | smi_info->curr_msg = NULL; | 540 | smi_info->curr_msg = NULL; |
480 | deliver_recv_msg(smi_info, msg); | 541 | deliver_recv_msg(smi_info, msg); |
@@ -488,12 +549,13 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
488 | /* We got the flags from the SMI, now handle them. */ | 549 | /* We got the flags from the SMI, now handle them. */ |
489 | len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4); | 550 | len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4); |
490 | if (msg[2] != 0) { | 551 | if (msg[2] != 0) { |
491 | /* Error fetching flags, just give up for | 552 | /* Error fetching flags, just give up for now. */ |
492 | now. */ | ||
493 | smi_info->si_state = SI_NORMAL; | 553 | smi_info->si_state = SI_NORMAL; |
494 | } else if (len < 4) { | 554 | } else if (len < 4) { |
495 | /* Hmm, no flags. That's technically illegal, but | 555 | /* |
496 | don't use uninitialized data. */ | 556 | * Hmm, no flags. That's technically illegal, but |
557 | * don't use uninitialized data. | ||
558 | */ | ||
497 | smi_info->si_state = SI_NORMAL; | 559 | smi_info->si_state = SI_NORMAL; |
498 | } else { | 560 | } else { |
499 | smi_info->msg_flags = msg[3]; | 561 | smi_info->msg_flags = msg[3]; |
@@ -530,9 +592,11 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
530 | smi_info->curr_msg->rsp, | 592 | smi_info->curr_msg->rsp, |
531 | IPMI_MAX_MSG_LENGTH); | 593 | IPMI_MAX_MSG_LENGTH); |
532 | 594 | ||
533 | /* Do this here becase deliver_recv_msg() releases the | 595 | /* |
534 | lock, and a new message can be put in during the | 596 | * Do this here becase deliver_recv_msg() releases the |
535 | time the lock is released. */ | 597 | * lock, and a new message can be put in during the |
598 | * time the lock is released. | ||
599 | */ | ||
536 | msg = smi_info->curr_msg; | 600 | msg = smi_info->curr_msg; |
537 | smi_info->curr_msg = NULL; | 601 | smi_info->curr_msg = NULL; |
538 | if (msg->rsp[2] != 0) { | 602 | if (msg->rsp[2] != 0) { |
@@ -543,14 +607,14 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
543 | smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; | 607 | smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; |
544 | handle_flags(smi_info); | 608 | handle_flags(smi_info); |
545 | } else { | 609 | } else { |
546 | spin_lock(&smi_info->count_lock); | 610 | smi_inc_stat(smi_info, events); |
547 | smi_info->events++; | 611 | |
548 | spin_unlock(&smi_info->count_lock); | 612 | /* |
549 | 613 | * Do this before we deliver the message | |
550 | /* Do this before we deliver the message | 614 | * because delivering the message releases the |
551 | because delivering the message releases the | 615 | * lock and something else can mess with the |
552 | lock and something else can mess with the | 616 | * state. |
553 | state. */ | 617 | */ |
554 | handle_flags(smi_info); | 618 | handle_flags(smi_info); |
555 | 619 | ||
556 | deliver_recv_msg(smi_info, msg); | 620 | deliver_recv_msg(smi_info, msg); |
@@ -566,9 +630,11 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
566 | smi_info->curr_msg->rsp, | 630 | smi_info->curr_msg->rsp, |
567 | IPMI_MAX_MSG_LENGTH); | 631 | IPMI_MAX_MSG_LENGTH); |
568 | 632 | ||
569 | /* Do this here becase deliver_recv_msg() releases the | 633 | /* |
570 | lock, and a new message can be put in during the | 634 | * Do this here becase deliver_recv_msg() releases the |
571 | time the lock is released. */ | 635 | * lock, and a new message can be put in during the |
636 | * time the lock is released. | ||
637 | */ | ||
572 | msg = smi_info->curr_msg; | 638 | msg = smi_info->curr_msg; |
573 | smi_info->curr_msg = NULL; | 639 | smi_info->curr_msg = NULL; |
574 | if (msg->rsp[2] != 0) { | 640 | if (msg->rsp[2] != 0) { |
@@ -579,14 +645,14 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
579 | smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL; | 645 | smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL; |
580 | handle_flags(smi_info); | 646 | handle_flags(smi_info); |
581 | } else { | 647 | } else { |
582 | spin_lock(&smi_info->count_lock); | 648 | smi_inc_stat(smi_info, incoming_messages); |
583 | smi_info->incoming_messages++; | 649 | |
584 | spin_unlock(&smi_info->count_lock); | 650 | /* |
585 | 651 | * Do this before we deliver the message | |
586 | /* Do this before we deliver the message | 652 | * because delivering the message releases the |
587 | because delivering the message releases the | 653 | * lock and something else can mess with the |
588 | lock and something else can mess with the | 654 | * state. |
589 | state. */ | 655 | */ |
590 | handle_flags(smi_info); | 656 | handle_flags(smi_info); |
591 | 657 | ||
592 | deliver_recv_msg(smi_info, msg); | 658 | deliver_recv_msg(smi_info, msg); |
@@ -674,69 +740,70 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
674 | } | 740 | } |
675 | } | 741 | } |
676 | 742 | ||
677 | /* Called on timeouts and events. Timeouts should pass the elapsed | 743 | /* |
678 | time, interrupts should pass in zero. Must be called with | 744 | * Called on timeouts and events. Timeouts should pass the elapsed |
679 | si_lock held and interrupts disabled. */ | 745 | * time, interrupts should pass in zero. Must be called with |
746 | * si_lock held and interrupts disabled. | ||
747 | */ | ||
680 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | 748 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, |
681 | int time) | 749 | int time) |
682 | { | 750 | { |
683 | enum si_sm_result si_sm_result; | 751 | enum si_sm_result si_sm_result; |
684 | 752 | ||
685 | restart: | 753 | restart: |
686 | /* There used to be a loop here that waited a little while | 754 | /* |
687 | (around 25us) before giving up. That turned out to be | 755 | * There used to be a loop here that waited a little while |
688 | pointless, the minimum delays I was seeing were in the 300us | 756 | * (around 25us) before giving up. That turned out to be |
689 | range, which is far too long to wait in an interrupt. So | 757 | * pointless, the minimum delays I was seeing were in the 300us |
690 | we just run until the state machine tells us something | 758 | * range, which is far too long to wait in an interrupt. So |
691 | happened or it needs a delay. */ | 759 | * we just run until the state machine tells us something |
760 | * happened or it needs a delay. | ||
761 | */ | ||
692 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, time); | 762 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, time); |
693 | time = 0; | 763 | time = 0; |
694 | while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY) | 764 | while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY) |
695 | { | ||
696 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); | 765 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); |
697 | } | ||
698 | 766 | ||
699 | if (si_sm_result == SI_SM_TRANSACTION_COMPLETE) | 767 | if (si_sm_result == SI_SM_TRANSACTION_COMPLETE) { |
700 | { | 768 | smi_inc_stat(smi_info, complete_transactions); |
701 | spin_lock(&smi_info->count_lock); | ||
702 | smi_info->complete_transactions++; | ||
703 | spin_unlock(&smi_info->count_lock); | ||
704 | 769 | ||
705 | handle_transaction_done(smi_info); | 770 | handle_transaction_done(smi_info); |
706 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); | 771 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); |
707 | } | 772 | } else if (si_sm_result == SI_SM_HOSED) { |
708 | else if (si_sm_result == SI_SM_HOSED) | 773 | smi_inc_stat(smi_info, hosed_count); |
709 | { | ||
710 | spin_lock(&smi_info->count_lock); | ||
711 | smi_info->hosed_count++; | ||
712 | spin_unlock(&smi_info->count_lock); | ||
713 | 774 | ||
714 | /* Do the before return_hosed_msg, because that | 775 | /* |
715 | releases the lock. */ | 776 | * Do the before return_hosed_msg, because that |
777 | * releases the lock. | ||
778 | */ | ||
716 | smi_info->si_state = SI_NORMAL; | 779 | smi_info->si_state = SI_NORMAL; |
717 | if (smi_info->curr_msg != NULL) { | 780 | if (smi_info->curr_msg != NULL) { |
718 | /* If we were handling a user message, format | 781 | /* |
719 | a response to send to the upper layer to | 782 | * If we were handling a user message, format |
720 | tell it about the error. */ | 783 | * a response to send to the upper layer to |
784 | * tell it about the error. | ||
785 | */ | ||
721 | return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); | 786 | return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); |
722 | } | 787 | } |
723 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); | 788 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); |
724 | } | 789 | } |
725 | 790 | ||
726 | /* We prefer handling attn over new messages. */ | 791 | /* |
727 | if (si_sm_result == SI_SM_ATTN) | 792 | * We prefer handling attn over new messages. But don't do |
728 | { | 793 | * this if there is not yet an upper layer to handle anything. |
794 | */ | ||
795 | if (likely(smi_info->intf) && si_sm_result == SI_SM_ATTN) { | ||
729 | unsigned char msg[2]; | 796 | unsigned char msg[2]; |
730 | 797 | ||
731 | spin_lock(&smi_info->count_lock); | 798 | smi_inc_stat(smi_info, attentions); |
732 | smi_info->attentions++; | ||
733 | spin_unlock(&smi_info->count_lock); | ||
734 | 799 | ||
735 | /* Got a attn, send down a get message flags to see | 800 | /* |
736 | what's causing it. It would be better to handle | 801 | * Got a attn, send down a get message flags to see |
737 | this in the upper layer, but due to the way | 802 | * what's causing it. It would be better to handle |
738 | interrupts work with the SMI, that's not really | 803 | * this in the upper layer, but due to the way |
739 | possible. */ | 804 | * interrupts work with the SMI, that's not really |
805 | * possible. | ||
806 | */ | ||
740 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 807 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
741 | msg[1] = IPMI_GET_MSG_FLAGS_CMD; | 808 | msg[1] = IPMI_GET_MSG_FLAGS_CMD; |
742 | 809 | ||
@@ -748,20 +815,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | |||
748 | 815 | ||
749 | /* If we are currently idle, try to start the next message. */ | 816 | /* If we are currently idle, try to start the next message. */ |
750 | if (si_sm_result == SI_SM_IDLE) { | 817 | if (si_sm_result == SI_SM_IDLE) { |
751 | spin_lock(&smi_info->count_lock); | 818 | smi_inc_stat(smi_info, idles); |
752 | smi_info->idles++; | ||
753 | spin_unlock(&smi_info->count_lock); | ||
754 | 819 | ||
755 | si_sm_result = start_next_msg(smi_info); | 820 | si_sm_result = start_next_msg(smi_info); |
756 | if (si_sm_result != SI_SM_IDLE) | 821 | if (si_sm_result != SI_SM_IDLE) |
757 | goto restart; | 822 | goto restart; |
758 | } | 823 | } |
759 | 824 | ||
760 | if ((si_sm_result == SI_SM_IDLE) | 825 | if ((si_sm_result == SI_SM_IDLE) |
761 | && (atomic_read(&smi_info->req_events))) | 826 | && (atomic_read(&smi_info->req_events))) { |
762 | { | 827 | /* |
763 | /* We are idle and the upper layer requested that I fetch | 828 | * We are idle and the upper layer requested that I fetch |
764 | events, so do so. */ | 829 | * events, so do so. |
830 | */ | ||
765 | atomic_set(&smi_info->req_events, 0); | 831 | atomic_set(&smi_info->req_events, 0); |
766 | 832 | ||
767 | smi_info->curr_msg = ipmi_alloc_smi_msg(); | 833 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
@@ -803,56 +869,50 @@ static void sender(void *send_info, | |||
803 | return; | 869 | return; |
804 | } | 870 | } |
805 | 871 | ||
806 | spin_lock_irqsave(&(smi_info->msg_lock), flags); | ||
807 | #ifdef DEBUG_TIMING | 872 | #ifdef DEBUG_TIMING |
808 | do_gettimeofday(&t); | 873 | do_gettimeofday(&t); |
809 | printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 874 | printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
810 | #endif | 875 | #endif |
811 | 876 | ||
812 | if (smi_info->run_to_completion) { | 877 | if (smi_info->run_to_completion) { |
813 | /* If we are running to completion, then throw it in | 878 | /* |
814 | the list and run transactions until everything is | 879 | * If we are running to completion, then throw it in |
815 | clear. Priority doesn't matter here. */ | 880 | * the list and run transactions until everything is |
881 | * clear. Priority doesn't matter here. | ||
882 | */ | ||
883 | |||
884 | /* | ||
885 | * Run to completion means we are single-threaded, no | ||
886 | * need for locks. | ||
887 | */ | ||
816 | list_add_tail(&(msg->link), &(smi_info->xmit_msgs)); | 888 | list_add_tail(&(msg->link), &(smi_info->xmit_msgs)); |
817 | 889 | ||
818 | /* We have to release the msg lock and claim the smi | ||
819 | lock in this case, because of race conditions. */ | ||
820 | spin_unlock_irqrestore(&(smi_info->msg_lock), flags); | ||
821 | |||
822 | spin_lock_irqsave(&(smi_info->si_lock), flags); | ||
823 | result = smi_event_handler(smi_info, 0); | 890 | result = smi_event_handler(smi_info, 0); |
824 | while (result != SI_SM_IDLE) { | 891 | while (result != SI_SM_IDLE) { |
825 | udelay(SI_SHORT_TIMEOUT_USEC); | 892 | udelay(SI_SHORT_TIMEOUT_USEC); |
826 | result = smi_event_handler(smi_info, | 893 | result = smi_event_handler(smi_info, |
827 | SI_SHORT_TIMEOUT_USEC); | 894 | SI_SHORT_TIMEOUT_USEC); |
828 | } | 895 | } |
829 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | ||
830 | return; | 896 | return; |
831 | } else { | ||
832 | if (priority > 0) { | ||
833 | list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs)); | ||
834 | } else { | ||
835 | list_add_tail(&(msg->link), &(smi_info->xmit_msgs)); | ||
836 | } | ||
837 | } | 897 | } |
838 | spin_unlock_irqrestore(&(smi_info->msg_lock), flags); | ||
839 | 898 | ||
840 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 899 | spin_lock_irqsave(&smi_info->msg_lock, flags); |
841 | if ((smi_info->si_state == SI_NORMAL) | 900 | if (priority > 0) |
842 | && (smi_info->curr_msg == NULL)) | 901 | list_add_tail(&msg->link, &smi_info->hp_xmit_msgs); |
843 | { | 902 | else |
903 | list_add_tail(&msg->link, &smi_info->xmit_msgs); | ||
904 | spin_unlock_irqrestore(&smi_info->msg_lock, flags); | ||
905 | |||
906 | spin_lock_irqsave(&smi_info->si_lock, flags); | ||
907 | if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) | ||
844 | start_next_msg(smi_info); | 908 | start_next_msg(smi_info); |
845 | } | 909 | spin_unlock_irqrestore(&smi_info->si_lock, flags); |
846 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | ||
847 | } | 910 | } |
848 | 911 | ||
849 | static void set_run_to_completion(void *send_info, int i_run_to_completion) | 912 | static void set_run_to_completion(void *send_info, int i_run_to_completion) |
850 | { | 913 | { |
851 | struct smi_info *smi_info = send_info; | 914 | struct smi_info *smi_info = send_info; |
852 | enum si_sm_result result; | 915 | enum si_sm_result result; |
853 | unsigned long flags; | ||
854 | |||
855 | spin_lock_irqsave(&(smi_info->si_lock), flags); | ||
856 | 916 | ||
857 | smi_info->run_to_completion = i_run_to_completion; | 917 | smi_info->run_to_completion = i_run_to_completion; |
858 | if (i_run_to_completion) { | 918 | if (i_run_to_completion) { |
@@ -863,8 +923,6 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion) | |||
863 | SI_SHORT_TIMEOUT_USEC); | 923 | SI_SHORT_TIMEOUT_USEC); |
864 | } | 924 | } |
865 | } | 925 | } |
866 | |||
867 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | ||
868 | } | 926 | } |
869 | 927 | ||
870 | static int ipmi_thread(void *data) | 928 | static int ipmi_thread(void *data) |
@@ -878,9 +936,8 @@ static int ipmi_thread(void *data) | |||
878 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 936 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
879 | smi_result = smi_event_handler(smi_info, 0); | 937 | smi_result = smi_event_handler(smi_info, 0); |
880 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 938 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
881 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { | 939 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) |
882 | /* do nothing */ | 940 | ; /* do nothing */ |
883 | } | ||
884 | else if (smi_result == SI_SM_CALL_WITH_DELAY) | 941 | else if (smi_result == SI_SM_CALL_WITH_DELAY) |
885 | schedule(); | 942 | schedule(); |
886 | else | 943 | else |
@@ -931,7 +988,7 @@ static void smi_timeout(unsigned long data) | |||
931 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 988 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
932 | #ifdef DEBUG_TIMING | 989 | #ifdef DEBUG_TIMING |
933 | do_gettimeofday(&t); | 990 | do_gettimeofday(&t); |
934 | printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 991 | printk(KERN_DEBUG "**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
935 | #endif | 992 | #endif |
936 | jiffies_now = jiffies; | 993 | jiffies_now = jiffies; |
937 | time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies) | 994 | time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies) |
@@ -945,23 +1002,19 @@ static void smi_timeout(unsigned long data) | |||
945 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 1002 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
946 | /* Running with interrupts, only do long timeouts. */ | 1003 | /* Running with interrupts, only do long timeouts. */ |
947 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 1004 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
948 | spin_lock_irqsave(&smi_info->count_lock, flags); | 1005 | smi_inc_stat(smi_info, long_timeouts); |
949 | smi_info->long_timeouts++; | ||
950 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | ||
951 | goto do_add_timer; | 1006 | goto do_add_timer; |
952 | } | 1007 | } |
953 | 1008 | ||
954 | /* If the state machine asks for a short delay, then shorten | 1009 | /* |
955 | the timer timeout. */ | 1010 | * If the state machine asks for a short delay, then shorten |
1011 | * the timer timeout. | ||
1012 | */ | ||
956 | if (smi_result == SI_SM_CALL_WITH_DELAY) { | 1013 | if (smi_result == SI_SM_CALL_WITH_DELAY) { |
957 | spin_lock_irqsave(&smi_info->count_lock, flags); | 1014 | smi_inc_stat(smi_info, short_timeouts); |
958 | smi_info->short_timeouts++; | ||
959 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | ||
960 | smi_info->si_timer.expires = jiffies + 1; | 1015 | smi_info->si_timer.expires = jiffies + 1; |
961 | } else { | 1016 | } else { |
962 | spin_lock_irqsave(&smi_info->count_lock, flags); | 1017 | smi_inc_stat(smi_info, long_timeouts); |
963 | smi_info->long_timeouts++; | ||
964 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | ||
965 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 1018 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
966 | } | 1019 | } |
967 | 1020 | ||
@@ -979,13 +1032,11 @@ static irqreturn_t si_irq_handler(int irq, void *data) | |||
979 | 1032 | ||
980 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 1033 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
981 | 1034 | ||
982 | spin_lock(&smi_info->count_lock); | 1035 | smi_inc_stat(smi_info, interrupts); |
983 | smi_info->interrupts++; | ||
984 | spin_unlock(&smi_info->count_lock); | ||
985 | 1036 | ||
986 | #ifdef DEBUG_TIMING | 1037 | #ifdef DEBUG_TIMING |
987 | do_gettimeofday(&t); | 1038 | do_gettimeofday(&t); |
988 | printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 1039 | printk(KERN_DEBUG "**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
989 | #endif | 1040 | #endif |
990 | smi_event_handler(smi_info, 0); | 1041 | smi_event_handler(smi_info, 0); |
991 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 1042 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
@@ -1028,7 +1079,7 @@ static int smi_start_processing(void *send_info, | |||
1028 | * The BT interface is efficient enough to not need a thread, | 1079 | * The BT interface is efficient enough to not need a thread, |
1029 | * and there is no need for a thread if we have interrupts. | 1080 | * and there is no need for a thread if we have interrupts. |
1030 | */ | 1081 | */ |
1031 | else if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) | 1082 | else if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) |
1032 | enable = 1; | 1083 | enable = 1; |
1033 | 1084 | ||
1034 | if (enable) { | 1085 | if (enable) { |
@@ -1054,8 +1105,7 @@ static void set_maintenance_mode(void *send_info, int enable) | |||
1054 | atomic_set(&smi_info->req_events, 0); | 1105 | atomic_set(&smi_info->req_events, 0); |
1055 | } | 1106 | } |
1056 | 1107 | ||
1057 | static struct ipmi_smi_handlers handlers = | 1108 | static struct ipmi_smi_handlers handlers = { |
1058 | { | ||
1059 | .owner = THIS_MODULE, | 1109 | .owner = THIS_MODULE, |
1060 | .start_processing = smi_start_processing, | 1110 | .start_processing = smi_start_processing, |
1061 | .sender = sender, | 1111 | .sender = sender, |
@@ -1065,8 +1115,10 @@ static struct ipmi_smi_handlers handlers = | |||
1065 | .poll = poll, | 1115 | .poll = poll, |
1066 | }; | 1116 | }; |
1067 | 1117 | ||
1068 | /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses, | 1118 | /* |
1069 | a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */ | 1119 | * There can be 4 IO ports passed in (with or without IRQs), 4 addresses, |
1120 | * a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS. | ||
1121 | */ | ||
1070 | 1122 | ||
1071 | static LIST_HEAD(smi_infos); | 1123 | static LIST_HEAD(smi_infos); |
1072 | static DEFINE_MUTEX(smi_infos_lock); | 1124 | static DEFINE_MUTEX(smi_infos_lock); |
@@ -1257,10 +1309,9 @@ static void port_cleanup(struct smi_info *info) | |||
1257 | int idx; | 1309 | int idx; |
1258 | 1310 | ||
1259 | if (addr) { | 1311 | if (addr) { |
1260 | for (idx = 0; idx < info->io_size; idx++) { | 1312 | for (idx = 0; idx < info->io_size; idx++) |
1261 | release_region(addr + idx * info->io.regspacing, | 1313 | release_region(addr + idx * info->io.regspacing, |
1262 | info->io.regsize); | 1314 | info->io.regsize); |
1263 | } | ||
1264 | } | 1315 | } |
1265 | } | 1316 | } |
1266 | 1317 | ||
@@ -1274,8 +1325,10 @@ static int port_setup(struct smi_info *info) | |||
1274 | 1325 | ||
1275 | info->io_cleanup = port_cleanup; | 1326 | info->io_cleanup = port_cleanup; |
1276 | 1327 | ||
1277 | /* Figure out the actual inb/inw/inl/etc routine to use based | 1328 | /* |
1278 | upon the register size. */ | 1329 | * Figure out the actual inb/inw/inl/etc routine to use based |
1330 | * upon the register size. | ||
1331 | */ | ||
1279 | switch (info->io.regsize) { | 1332 | switch (info->io.regsize) { |
1280 | case 1: | 1333 | case 1: |
1281 | info->io.inputb = port_inb; | 1334 | info->io.inputb = port_inb; |
@@ -1290,17 +1343,18 @@ static int port_setup(struct smi_info *info) | |||
1290 | info->io.outputb = port_outl; | 1343 | info->io.outputb = port_outl; |
1291 | break; | 1344 | break; |
1292 | default: | 1345 | default: |
1293 | printk("ipmi_si: Invalid register size: %d\n", | 1346 | printk(KERN_WARNING "ipmi_si: Invalid register size: %d\n", |
1294 | info->io.regsize); | 1347 | info->io.regsize); |
1295 | return -EINVAL; | 1348 | return -EINVAL; |
1296 | } | 1349 | } |
1297 | 1350 | ||
1298 | /* Some BIOSes reserve disjoint I/O regions in their ACPI | 1351 | /* |
1352 | * Some BIOSes reserve disjoint I/O regions in their ACPI | ||
1299 | * tables. This causes problems when trying to register the | 1353 | * tables. This causes problems when trying to register the |
1300 | * entire I/O region. Therefore we must register each I/O | 1354 | * entire I/O region. Therefore we must register each I/O |
1301 | * port separately. | 1355 | * port separately. |
1302 | */ | 1356 | */ |
1303 | for (idx = 0; idx < info->io_size; idx++) { | 1357 | for (idx = 0; idx < info->io_size; idx++) { |
1304 | if (request_region(addr + idx * info->io.regspacing, | 1358 | if (request_region(addr + idx * info->io.regspacing, |
1305 | info->io.regsize, DEVICE_NAME) == NULL) { | 1359 | info->io.regsize, DEVICE_NAME) == NULL) { |
1306 | /* Undo allocations */ | 1360 | /* Undo allocations */ |
@@ -1388,8 +1442,10 @@ static int mem_setup(struct smi_info *info) | |||
1388 | 1442 | ||
1389 | info->io_cleanup = mem_cleanup; | 1443 | info->io_cleanup = mem_cleanup; |
1390 | 1444 | ||
1391 | /* Figure out the actual readb/readw/readl/etc routine to use based | 1445 | /* |
1392 | upon the register size. */ | 1446 | * Figure out the actual readb/readw/readl/etc routine to use based |
1447 | * upon the register size. | ||
1448 | */ | ||
1393 | switch (info->io.regsize) { | 1449 | switch (info->io.regsize) { |
1394 | case 1: | 1450 | case 1: |
1395 | info->io.inputb = intf_mem_inb; | 1451 | info->io.inputb = intf_mem_inb; |
@@ -1410,16 +1466,18 @@ static int mem_setup(struct smi_info *info) | |||
1410 | break; | 1466 | break; |
1411 | #endif | 1467 | #endif |
1412 | default: | 1468 | default: |
1413 | printk("ipmi_si: Invalid register size: %d\n", | 1469 | printk(KERN_WARNING "ipmi_si: Invalid register size: %d\n", |
1414 | info->io.regsize); | 1470 | info->io.regsize); |
1415 | return -EINVAL; | 1471 | return -EINVAL; |
1416 | } | 1472 | } |
1417 | 1473 | ||
1418 | /* Calculate the total amount of memory to claim. This is an | 1474 | /* |
1475 | * Calculate the total amount of memory to claim. This is an | ||
1419 | * unusual looking calculation, but it avoids claiming any | 1476 | * unusual looking calculation, but it avoids claiming any |
1420 | * more memory than it has to. It will claim everything | 1477 | * more memory than it has to. It will claim everything |
1421 | * between the first address to the end of the last full | 1478 | * between the first address to the end of the last full |
1422 | * register. */ | 1479 | * register. |
1480 | */ | ||
1423 | mapsize = ((info->io_size * info->io.regspacing) | 1481 | mapsize = ((info->io_size * info->io.regspacing) |
1424 | - (info->io.regspacing - info->io.regsize)); | 1482 | - (info->io.regspacing - info->io.regsize)); |
1425 | 1483 | ||
@@ -1749,9 +1807,11 @@ static __devinit void hardcode_find_bmc(void) | |||
1749 | 1807 | ||
1750 | #include <linux/acpi.h> | 1808 | #include <linux/acpi.h> |
1751 | 1809 | ||
1752 | /* Once we get an ACPI failure, we don't try any more, because we go | 1810 | /* |
1753 | through the tables sequentially. Once we don't find a table, there | 1811 | * Once we get an ACPI failure, we don't try any more, because we go |
1754 | are no more. */ | 1812 | * through the tables sequentially. Once we don't find a table, there |
1813 | * are no more. | ||
1814 | */ | ||
1755 | static int acpi_failure; | 1815 | static int acpi_failure; |
1756 | 1816 | ||
1757 | /* For GPE-type interrupts. */ | 1817 | /* For GPE-type interrupts. */ |
@@ -1765,9 +1825,7 @@ static u32 ipmi_acpi_gpe(void *context) | |||
1765 | 1825 | ||
1766 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 1826 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
1767 | 1827 | ||
1768 | spin_lock(&smi_info->count_lock); | 1828 | smi_inc_stat(smi_info, interrupts); |
1769 | smi_info->interrupts++; | ||
1770 | spin_unlock(&smi_info->count_lock); | ||
1771 | 1829 | ||
1772 | #ifdef DEBUG_TIMING | 1830 | #ifdef DEBUG_TIMING |
1773 | do_gettimeofday(&t); | 1831 | do_gettimeofday(&t); |
@@ -1816,7 +1874,8 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1816 | 1874 | ||
1817 | /* | 1875 | /* |
1818 | * Defined at | 1876 | * Defined at |
1819 | * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf | 1877 | * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/ |
1878 | * Docs/TechPapers/IA64/hpspmi.pdf | ||
1820 | */ | 1879 | */ |
1821 | struct SPMITable { | 1880 | struct SPMITable { |
1822 | s8 Signature[4]; | 1881 | s8 Signature[4]; |
@@ -1838,14 +1897,18 @@ struct SPMITable { | |||
1838 | */ | 1897 | */ |
1839 | u8 InterruptType; | 1898 | u8 InterruptType; |
1840 | 1899 | ||
1841 | /* If bit 0 of InterruptType is set, then this is the SCI | 1900 | /* |
1842 | interrupt in the GPEx_STS register. */ | 1901 | * If bit 0 of InterruptType is set, then this is the SCI |
1902 | * interrupt in the GPEx_STS register. | ||
1903 | */ | ||
1843 | u8 GPE; | 1904 | u8 GPE; |
1844 | 1905 | ||
1845 | s16 Reserved; | 1906 | s16 Reserved; |
1846 | 1907 | ||
1847 | /* If bit 1 of InterruptType is set, then this is the I/O | 1908 | /* |
1848 | APIC/SAPIC interrupt. */ | 1909 | * If bit 1 of InterruptType is set, then this is the I/O |
1910 | * APIC/SAPIC interrupt. | ||
1911 | */ | ||
1849 | u32 GlobalSystemInterrupt; | 1912 | u32 GlobalSystemInterrupt; |
1850 | 1913 | ||
1851 | /* The actual register address. */ | 1914 | /* The actual register address. */ |
@@ -1863,7 +1926,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
1863 | 1926 | ||
1864 | if (spmi->IPMIlegacy != 1) { | 1927 | if (spmi->IPMIlegacy != 1) { |
1865 | printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy); | 1928 | printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy); |
1866 | return -ENODEV; | 1929 | return -ENODEV; |
1867 | } | 1930 | } |
1868 | 1931 | ||
1869 | if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 1932 | if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
@@ -1880,8 +1943,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
1880 | info->addr_source = "ACPI"; | 1943 | info->addr_source = "ACPI"; |
1881 | 1944 | ||
1882 | /* Figure out the interface type. */ | 1945 | /* Figure out the interface type. */ |
1883 | switch (spmi->InterfaceType) | 1946 | switch (spmi->InterfaceType) { |
1884 | { | ||
1885 | case 1: /* KCS */ | 1947 | case 1: /* KCS */ |
1886 | info->si_type = SI_KCS; | 1948 | info->si_type = SI_KCS; |
1887 | break; | 1949 | break; |
@@ -1929,7 +1991,8 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
1929 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | 1991 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
1930 | } else { | 1992 | } else { |
1931 | kfree(info); | 1993 | kfree(info); |
1932 | printk("ipmi_si: Unknown ACPI I/O Address type\n"); | 1994 | printk(KERN_WARNING |
1995 | "ipmi_si: Unknown ACPI I/O Address type\n"); | ||
1933 | return -EIO; | 1996 | return -EIO; |
1934 | } | 1997 | } |
1935 | info->io.addr_data = spmi->addr.address; | 1998 | info->io.addr_data = spmi->addr.address; |
@@ -1963,8 +2026,7 @@ static __devinit void acpi_find_bmc(void) | |||
1963 | #endif | 2026 | #endif |
1964 | 2027 | ||
1965 | #ifdef CONFIG_DMI | 2028 | #ifdef CONFIG_DMI |
1966 | struct dmi_ipmi_data | 2029 | struct dmi_ipmi_data { |
1967 | { | ||
1968 | u8 type; | 2030 | u8 type; |
1969 | u8 addr_space; | 2031 | u8 addr_space; |
1970 | unsigned long base_addr; | 2032 | unsigned long base_addr; |
@@ -1989,11 +2051,10 @@ static int __devinit decode_dmi(const struct dmi_header *dm, | |||
1989 | /* I/O */ | 2051 | /* I/O */ |
1990 | base_addr &= 0xFFFE; | 2052 | base_addr &= 0xFFFE; |
1991 | dmi->addr_space = IPMI_IO_ADDR_SPACE; | 2053 | dmi->addr_space = IPMI_IO_ADDR_SPACE; |
1992 | } | 2054 | } else |
1993 | else { | ||
1994 | /* Memory */ | 2055 | /* Memory */ |
1995 | dmi->addr_space = IPMI_MEM_ADDR_SPACE; | 2056 | dmi->addr_space = IPMI_MEM_ADDR_SPACE; |
1996 | } | 2057 | |
1997 | /* If bit 4 of byte 0x10 is set, then the lsb for the address | 2058 | /* If bit 4 of byte 0x10 is set, then the lsb for the address |
1998 | is odd. */ | 2059 | is odd. */ |
1999 | dmi->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); | 2060 | dmi->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); |
@@ -2002,7 +2063,7 @@ static int __devinit decode_dmi(const struct dmi_header *dm, | |||
2002 | 2063 | ||
2003 | /* The top two bits of byte 0x10 hold the register spacing. */ | 2064 | /* The top two bits of byte 0x10 hold the register spacing. */ |
2004 | reg_spacing = (data[0x10] & 0xC0) >> 6; | 2065 | reg_spacing = (data[0x10] & 0xC0) >> 6; |
2005 | switch(reg_spacing){ | 2066 | switch (reg_spacing) { |
2006 | case 0x00: /* Byte boundaries */ | 2067 | case 0x00: /* Byte boundaries */ |
2007 | dmi->offset = 1; | 2068 | dmi->offset = 1; |
2008 | break; | 2069 | break; |
@@ -2018,12 +2079,14 @@ static int __devinit decode_dmi(const struct dmi_header *dm, | |||
2018 | } | 2079 | } |
2019 | } else { | 2080 | } else { |
2020 | /* Old DMI spec. */ | 2081 | /* Old DMI spec. */ |
2021 | /* Note that technically, the lower bit of the base | 2082 | /* |
2083 | * Note that technically, the lower bit of the base | ||
2022 | * address should be 1 if the address is I/O and 0 if | 2084 | * address should be 1 if the address is I/O and 0 if |
2023 | * the address is in memory. So many systems get that | 2085 | * the address is in memory. So many systems get that |
2024 | * wrong (and all that I have seen are I/O) so we just | 2086 | * wrong (and all that I have seen are I/O) so we just |
2025 | * ignore that bit and assume I/O. Systems that use | 2087 | * ignore that bit and assume I/O. Systems that use |
2026 | * memory should use the newer spec, anyway. */ | 2088 | * memory should use the newer spec, anyway. |
2089 | */ | ||
2027 | dmi->base_addr = base_addr & 0xfffe; | 2090 | dmi->base_addr = base_addr & 0xfffe; |
2028 | dmi->addr_space = IPMI_IO_ADDR_SPACE; | 2091 | dmi->addr_space = IPMI_IO_ADDR_SPACE; |
2029 | dmi->offset = 1; | 2092 | dmi->offset = 1; |
@@ -2230,13 +2293,13 @@ static struct pci_device_id ipmi_pci_devices[] = { | |||
2230 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); | 2293 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); |
2231 | 2294 | ||
2232 | static struct pci_driver ipmi_pci_driver = { | 2295 | static struct pci_driver ipmi_pci_driver = { |
2233 | .name = DEVICE_NAME, | 2296 | .name = DEVICE_NAME, |
2234 | .id_table = ipmi_pci_devices, | 2297 | .id_table = ipmi_pci_devices, |
2235 | .probe = ipmi_pci_probe, | 2298 | .probe = ipmi_pci_probe, |
2236 | .remove = __devexit_p(ipmi_pci_remove), | 2299 | .remove = __devexit_p(ipmi_pci_remove), |
2237 | #ifdef CONFIG_PM | 2300 | #ifdef CONFIG_PM |
2238 | .suspend = ipmi_pci_suspend, | 2301 | .suspend = ipmi_pci_suspend, |
2239 | .resume = ipmi_pci_resume, | 2302 | .resume = ipmi_pci_resume, |
2240 | #endif | 2303 | #endif |
2241 | }; | 2304 | }; |
2242 | #endif /* CONFIG_PCI */ | 2305 | #endif /* CONFIG_PCI */ |
@@ -2306,7 +2369,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, | |||
2306 | info->io.addr_data, info->io.regsize, info->io.regspacing, | 2369 | info->io.addr_data, info->io.regsize, info->io.regspacing, |
2307 | info->irq); | 2370 | info->irq); |
2308 | 2371 | ||
2309 | dev->dev.driver_data = (void*) info; | 2372 | dev->dev.driver_data = (void *) info; |
2310 | 2373 | ||
2311 | return try_smi_init(info); | 2374 | return try_smi_init(info); |
2312 | } | 2375 | } |
@@ -2319,14 +2382,16 @@ static int __devexit ipmi_of_remove(struct of_device *dev) | |||
2319 | 2382 | ||
2320 | static struct of_device_id ipmi_match[] = | 2383 | static struct of_device_id ipmi_match[] = |
2321 | { | 2384 | { |
2322 | { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS }, | 2385 | { .type = "ipmi", .compatible = "ipmi-kcs", |
2323 | { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC }, | 2386 | .data = (void *)(unsigned long) SI_KCS }, |
2324 | { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT }, | 2387 | { .type = "ipmi", .compatible = "ipmi-smic", |
2388 | .data = (void *)(unsigned long) SI_SMIC }, | ||
2389 | { .type = "ipmi", .compatible = "ipmi-bt", | ||
2390 | .data = (void *)(unsigned long) SI_BT }, | ||
2325 | {}, | 2391 | {}, |
2326 | }; | 2392 | }; |
2327 | 2393 | ||
2328 | static struct of_platform_driver ipmi_of_platform_driver = | 2394 | static struct of_platform_driver ipmi_of_platform_driver = { |
2329 | { | ||
2330 | .name = "ipmi", | 2395 | .name = "ipmi", |
2331 | .match_table = ipmi_match, | 2396 | .match_table = ipmi_match, |
2332 | .probe = ipmi_of_probe, | 2397 | .probe = ipmi_of_probe, |
@@ -2347,32 +2412,32 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2347 | if (!resp) | 2412 | if (!resp) |
2348 | return -ENOMEM; | 2413 | return -ENOMEM; |
2349 | 2414 | ||
2350 | /* Do a Get Device ID command, since it comes back with some | 2415 | /* |
2351 | useful info. */ | 2416 | * Do a Get Device ID command, since it comes back with some |
2417 | * useful info. | ||
2418 | */ | ||
2352 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | 2419 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
2353 | msg[1] = IPMI_GET_DEVICE_ID_CMD; | 2420 | msg[1] = IPMI_GET_DEVICE_ID_CMD; |
2354 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | 2421 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); |
2355 | 2422 | ||
2356 | smi_result = smi_info->handlers->event(smi_info->si_sm, 0); | 2423 | smi_result = smi_info->handlers->event(smi_info->si_sm, 0); |
2357 | for (;;) | 2424 | for (;;) { |
2358 | { | ||
2359 | if (smi_result == SI_SM_CALL_WITH_DELAY || | 2425 | if (smi_result == SI_SM_CALL_WITH_DELAY || |
2360 | smi_result == SI_SM_CALL_WITH_TICK_DELAY) { | 2426 | smi_result == SI_SM_CALL_WITH_TICK_DELAY) { |
2361 | schedule_timeout_uninterruptible(1); | 2427 | schedule_timeout_uninterruptible(1); |
2362 | smi_result = smi_info->handlers->event( | 2428 | smi_result = smi_info->handlers->event( |
2363 | smi_info->si_sm, 100); | 2429 | smi_info->si_sm, 100); |
2364 | } | 2430 | } else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { |
2365 | else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) | ||
2366 | { | ||
2367 | smi_result = smi_info->handlers->event( | 2431 | smi_result = smi_info->handlers->event( |
2368 | smi_info->si_sm, 0); | 2432 | smi_info->si_sm, 0); |
2369 | } | 2433 | } else |
2370 | else | ||
2371 | break; | 2434 | break; |
2372 | } | 2435 | } |
2373 | if (smi_result == SI_SM_HOSED) { | 2436 | if (smi_result == SI_SM_HOSED) { |
2374 | /* We couldn't get the state machine to run, so whatever's at | 2437 | /* |
2375 | the port is probably not an IPMI SMI interface. */ | 2438 | * We couldn't get the state machine to run, so whatever's at |
2439 | * the port is probably not an IPMI SMI interface. | ||
2440 | */ | ||
2376 | rv = -ENODEV; | 2441 | rv = -ENODEV; |
2377 | goto out; | 2442 | goto out; |
2378 | } | 2443 | } |
@@ -2405,30 +2470,28 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
2405 | 2470 | ||
2406 | out += sprintf(out, "interrupts_enabled: %d\n", | 2471 | out += sprintf(out, "interrupts_enabled: %d\n", |
2407 | smi->irq && !smi->interrupt_disabled); | 2472 | smi->irq && !smi->interrupt_disabled); |
2408 | out += sprintf(out, "short_timeouts: %ld\n", | 2473 | out += sprintf(out, "short_timeouts: %u\n", |
2409 | smi->short_timeouts); | 2474 | smi_get_stat(smi, short_timeouts)); |
2410 | out += sprintf(out, "long_timeouts: %ld\n", | 2475 | out += sprintf(out, "long_timeouts: %u\n", |
2411 | smi->long_timeouts); | 2476 | smi_get_stat(smi, long_timeouts)); |
2412 | out += sprintf(out, "timeout_restarts: %ld\n", | 2477 | out += sprintf(out, "idles: %u\n", |
2413 | smi->timeout_restarts); | 2478 | smi_get_stat(smi, idles)); |
2414 | out += sprintf(out, "idles: %ld\n", | 2479 | out += sprintf(out, "interrupts: %u\n", |
2415 | smi->idles); | 2480 | smi_get_stat(smi, interrupts)); |
2416 | out += sprintf(out, "interrupts: %ld\n", | 2481 | out += sprintf(out, "attentions: %u\n", |
2417 | smi->interrupts); | 2482 | smi_get_stat(smi, attentions)); |
2418 | out += sprintf(out, "attentions: %ld\n", | 2483 | out += sprintf(out, "flag_fetches: %u\n", |
2419 | smi->attentions); | 2484 | smi_get_stat(smi, flag_fetches)); |
2420 | out += sprintf(out, "flag_fetches: %ld\n", | 2485 | out += sprintf(out, "hosed_count: %u\n", |
2421 | smi->flag_fetches); | 2486 | smi_get_stat(smi, hosed_count)); |
2422 | out += sprintf(out, "hosed_count: %ld\n", | 2487 | out += sprintf(out, "complete_transactions: %u\n", |
2423 | smi->hosed_count); | 2488 | smi_get_stat(smi, complete_transactions)); |
2424 | out += sprintf(out, "complete_transactions: %ld\n", | 2489 | out += sprintf(out, "events: %u\n", |
2425 | smi->complete_transactions); | 2490 | smi_get_stat(smi, events)); |
2426 | out += sprintf(out, "events: %ld\n", | 2491 | out += sprintf(out, "watchdog_pretimeouts: %u\n", |
2427 | smi->events); | 2492 | smi_get_stat(smi, watchdog_pretimeouts)); |
2428 | out += sprintf(out, "watchdog_pretimeouts: %ld\n", | 2493 | out += sprintf(out, "incoming_messages: %u\n", |
2429 | smi->watchdog_pretimeouts); | 2494 | smi_get_stat(smi, incoming_messages)); |
2430 | out += sprintf(out, "incoming_messages: %ld\n", | ||
2431 | smi->incoming_messages); | ||
2432 | 2495 | ||
2433 | return out - page; | 2496 | return out - page; |
2434 | } | 2497 | } |
@@ -2460,7 +2523,7 @@ static int param_read_proc(char *page, char **start, off_t off, | |||
2460 | static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info) | 2523 | static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info) |
2461 | { | 2524 | { |
2462 | smi_info->msg_flags = ((smi_info->msg_flags & ~OEM_DATA_AVAIL) | | 2525 | smi_info->msg_flags = ((smi_info->msg_flags & ~OEM_DATA_AVAIL) | |
2463 | RECEIVE_MSG_AVAIL); | 2526 | RECEIVE_MSG_AVAIL); |
2464 | return 1; | 2527 | return 1; |
2465 | } | 2528 | } |
2466 | 2529 | ||
@@ -2502,10 +2565,9 @@ static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info) | |||
2502 | id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) { | 2565 | id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) { |
2503 | smi_info->oem_data_avail_handler = | 2566 | smi_info->oem_data_avail_handler = |
2504 | oem_data_avail_to_receive_msg_avail; | 2567 | oem_data_avail_to_receive_msg_avail; |
2505 | } | 2568 | } else if (ipmi_version_major(id) < 1 || |
2506 | else if (ipmi_version_major(id) < 1 || | 2569 | (ipmi_version_major(id) == 1 && |
2507 | (ipmi_version_major(id) == 1 && | 2570 | ipmi_version_minor(id) < 5)) { |
2508 | ipmi_version_minor(id) < 5)) { | ||
2509 | smi_info->oem_data_avail_handler = | 2571 | smi_info->oem_data_avail_handler = |
2510 | oem_data_avail_to_receive_msg_avail; | 2572 | oem_data_avail_to_receive_msg_avail; |
2511 | } | 2573 | } |
@@ -2597,8 +2659,10 @@ static void setup_xaction_handlers(struct smi_info *smi_info) | |||
2597 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | 2659 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) |
2598 | { | 2660 | { |
2599 | if (smi_info->intf) { | 2661 | if (smi_info->intf) { |
2600 | /* The timer and thread are only running if the | 2662 | /* |
2601 | interface has been started up and registered. */ | 2663 | * The timer and thread are only running if the |
2664 | * interface has been started up and registered. | ||
2665 | */ | ||
2602 | if (smi_info->thread != NULL) | 2666 | if (smi_info->thread != NULL) |
2603 | kthread_stop(smi_info->thread); | 2667 | kthread_stop(smi_info->thread); |
2604 | del_timer_sync(&smi_info->si_timer); | 2668 | del_timer_sync(&smi_info->si_timer); |
@@ -2676,6 +2740,7 @@ static int is_new_interface(struct smi_info *info) | |||
2676 | static int try_smi_init(struct smi_info *new_smi) | 2740 | static int try_smi_init(struct smi_info *new_smi) |
2677 | { | 2741 | { |
2678 | int rv; | 2742 | int rv; |
2743 | int i; | ||
2679 | 2744 | ||
2680 | if (new_smi->addr_source) { | 2745 | if (new_smi->addr_source) { |
2681 | printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" | 2746 | printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" |
@@ -2722,7 +2787,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2722 | /* Allocate the state machine's data and initialize it. */ | 2787 | /* Allocate the state machine's data and initialize it. */ |
2723 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); | 2788 | new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); |
2724 | if (!new_smi->si_sm) { | 2789 | if (!new_smi->si_sm) { |
2725 | printk(" Could not allocate state machine memory\n"); | 2790 | printk(KERN_ERR "Could not allocate state machine memory\n"); |
2726 | rv = -ENOMEM; | 2791 | rv = -ENOMEM; |
2727 | goto out_err; | 2792 | goto out_err; |
2728 | } | 2793 | } |
@@ -2732,13 +2797,12 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2732 | /* Now that we know the I/O size, we can set up the I/O. */ | 2797 | /* Now that we know the I/O size, we can set up the I/O. */ |
2733 | rv = new_smi->io_setup(new_smi); | 2798 | rv = new_smi->io_setup(new_smi); |
2734 | if (rv) { | 2799 | if (rv) { |
2735 | printk(" Could not set up I/O space\n"); | 2800 | printk(KERN_ERR "Could not set up I/O space\n"); |
2736 | goto out_err; | 2801 | goto out_err; |
2737 | } | 2802 | } |
2738 | 2803 | ||
2739 | spin_lock_init(&(new_smi->si_lock)); | 2804 | spin_lock_init(&(new_smi->si_lock)); |
2740 | spin_lock_init(&(new_smi->msg_lock)); | 2805 | spin_lock_init(&(new_smi->msg_lock)); |
2741 | spin_lock_init(&(new_smi->count_lock)); | ||
2742 | 2806 | ||
2743 | /* Do low-level detection first. */ | 2807 | /* Do low-level detection first. */ |
2744 | if (new_smi->handlers->detect(new_smi->si_sm)) { | 2808 | if (new_smi->handlers->detect(new_smi->si_sm)) { |
@@ -2749,8 +2813,10 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2749 | goto out_err; | 2813 | goto out_err; |
2750 | } | 2814 | } |
2751 | 2815 | ||
2752 | /* Attempt a get device id command. If it fails, we probably | 2816 | /* |
2753 | don't have a BMC here. */ | 2817 | * Attempt a get device id command. If it fails, we probably |
2818 | * don't have a BMC here. | ||
2819 | */ | ||
2754 | rv = try_get_dev_id(new_smi); | 2820 | rv = try_get_dev_id(new_smi); |
2755 | if (rv) { | 2821 | if (rv) { |
2756 | if (new_smi->addr_source) | 2822 | if (new_smi->addr_source) |
@@ -2767,22 +2833,28 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2767 | new_smi->curr_msg = NULL; | 2833 | new_smi->curr_msg = NULL; |
2768 | atomic_set(&new_smi->req_events, 0); | 2834 | atomic_set(&new_smi->req_events, 0); |
2769 | new_smi->run_to_completion = 0; | 2835 | new_smi->run_to_completion = 0; |
2836 | for (i = 0; i < SI_NUM_STATS; i++) | ||
2837 | atomic_set(&new_smi->stats[i], 0); | ||
2770 | 2838 | ||
2771 | new_smi->interrupt_disabled = 0; | 2839 | new_smi->interrupt_disabled = 0; |
2772 | atomic_set(&new_smi->stop_operation, 0); | 2840 | atomic_set(&new_smi->stop_operation, 0); |
2773 | new_smi->intf_num = smi_num; | 2841 | new_smi->intf_num = smi_num; |
2774 | smi_num++; | 2842 | smi_num++; |
2775 | 2843 | ||
2776 | /* Start clearing the flags before we enable interrupts or the | 2844 | /* |
2777 | timer to avoid racing with the timer. */ | 2845 | * Start clearing the flags before we enable interrupts or the |
2846 | * timer to avoid racing with the timer. | ||
2847 | */ | ||
2778 | start_clear_flags(new_smi); | 2848 | start_clear_flags(new_smi); |
2779 | /* IRQ is defined to be set when non-zero. */ | 2849 | /* IRQ is defined to be set when non-zero. */ |
2780 | if (new_smi->irq) | 2850 | if (new_smi->irq) |
2781 | new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; | 2851 | new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; |
2782 | 2852 | ||
2783 | if (!new_smi->dev) { | 2853 | if (!new_smi->dev) { |
2784 | /* If we don't already have a device from something | 2854 | /* |
2785 | * else (like PCI), then register a new one. */ | 2855 | * If we don't already have a device from something |
2856 | * else (like PCI), then register a new one. | ||
2857 | */ | ||
2786 | new_smi->pdev = platform_device_alloc("ipmi_si", | 2858 | new_smi->pdev = platform_device_alloc("ipmi_si", |
2787 | new_smi->intf_num); | 2859 | new_smi->intf_num); |
2788 | if (rv) { | 2860 | if (rv) { |
@@ -2820,7 +2892,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2820 | } | 2892 | } |
2821 | 2893 | ||
2822 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", | 2894 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", |
2823 | type_file_read_proc, NULL, | 2895 | type_file_read_proc, |
2824 | new_smi, THIS_MODULE); | 2896 | new_smi, THIS_MODULE); |
2825 | if (rv) { | 2897 | if (rv) { |
2826 | printk(KERN_ERR | 2898 | printk(KERN_ERR |
@@ -2830,7 +2902,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2830 | } | 2902 | } |
2831 | 2903 | ||
2832 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", | 2904 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", |
2833 | stat_file_read_proc, NULL, | 2905 | stat_file_read_proc, |
2834 | new_smi, THIS_MODULE); | 2906 | new_smi, THIS_MODULE); |
2835 | if (rv) { | 2907 | if (rv) { |
2836 | printk(KERN_ERR | 2908 | printk(KERN_ERR |
@@ -2840,7 +2912,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2840 | } | 2912 | } |
2841 | 2913 | ||
2842 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", | 2914 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", |
2843 | param_read_proc, NULL, | 2915 | param_read_proc, |
2844 | new_smi, THIS_MODULE); | 2916 | new_smi, THIS_MODULE); |
2845 | if (rv) { | 2917 | if (rv) { |
2846 | printk(KERN_ERR | 2918 | printk(KERN_ERR |
@@ -2853,7 +2925,8 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2853 | 2925 | ||
2854 | mutex_unlock(&smi_infos_lock); | 2926 | mutex_unlock(&smi_infos_lock); |
2855 | 2927 | ||
2856 | printk(KERN_INFO "IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); | 2928 | printk(KERN_INFO "IPMI %s interface initialized\n", |
2929 | si_to_str[new_smi->si_type]); | ||
2857 | 2930 | ||
2858 | return 0; | 2931 | return 0; |
2859 | 2932 | ||
@@ -2868,9 +2941,11 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2868 | if (new_smi->irq_cleanup) | 2941 | if (new_smi->irq_cleanup) |
2869 | new_smi->irq_cleanup(new_smi); | 2942 | new_smi->irq_cleanup(new_smi); |
2870 | 2943 | ||
2871 | /* Wait until we know that we are out of any interrupt | 2944 | /* |
2872 | handlers might have been running before we freed the | 2945 | * Wait until we know that we are out of any interrupt |
2873 | interrupt. */ | 2946 | * handlers might have been running before we freed the |
2947 | * interrupt. | ||
2948 | */ | ||
2874 | synchronize_sched(); | 2949 | synchronize_sched(); |
2875 | 2950 | ||
2876 | if (new_smi->si_sm) { | 2951 | if (new_smi->si_sm) { |
@@ -2942,11 +3017,10 @@ static __devinit int init_ipmi_si(void) | |||
2942 | 3017 | ||
2943 | #ifdef CONFIG_PCI | 3018 | #ifdef CONFIG_PCI |
2944 | rv = pci_register_driver(&ipmi_pci_driver); | 3019 | rv = pci_register_driver(&ipmi_pci_driver); |
2945 | if (rv){ | 3020 | if (rv) |
2946 | printk(KERN_ERR | 3021 | printk(KERN_ERR |
2947 | "init_ipmi_si: Unable to register PCI driver: %d\n", | 3022 | "init_ipmi_si: Unable to register PCI driver: %d\n", |
2948 | rv); | 3023 | rv); |
2949 | } | ||
2950 | #endif | 3024 | #endif |
2951 | 3025 | ||
2952 | #ifdef CONFIG_PPC_OF | 3026 | #ifdef CONFIG_PPC_OF |
@@ -2975,7 +3049,8 @@ static __devinit int init_ipmi_si(void) | |||
2975 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3049 | of_unregister_platform_driver(&ipmi_of_platform_driver); |
2976 | #endif | 3050 | #endif |
2977 | driver_unregister(&ipmi_driver); | 3051 | driver_unregister(&ipmi_driver); |
2978 | printk("ipmi_si: Unable to find any System Interface(s)\n"); | 3052 | printk(KERN_WARNING |
3053 | "ipmi_si: Unable to find any System Interface(s)\n"); | ||
2979 | return -ENODEV; | 3054 | return -ENODEV; |
2980 | } else { | 3055 | } else { |
2981 | mutex_unlock(&smi_infos_lock); | 3056 | mutex_unlock(&smi_infos_lock); |
@@ -2997,13 +3072,17 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
2997 | /* Tell the driver that we are shutting down. */ | 3072 | /* Tell the driver that we are shutting down. */ |
2998 | atomic_inc(&to_clean->stop_operation); | 3073 | atomic_inc(&to_clean->stop_operation); |
2999 | 3074 | ||
3000 | /* Make sure the timer and thread are stopped and will not run | 3075 | /* |
3001 | again. */ | 3076 | * Make sure the timer and thread are stopped and will not run |
3077 | * again. | ||
3078 | */ | ||
3002 | wait_for_timer_and_thread(to_clean); | 3079 | wait_for_timer_and_thread(to_clean); |
3003 | 3080 | ||
3004 | /* Timeouts are stopped, now make sure the interrupts are off | 3081 | /* |
3005 | for the device. A little tricky with locks to make sure | 3082 | * Timeouts are stopped, now make sure the interrupts are off |
3006 | there are no races. */ | 3083 | * for the device. A little tricky with locks to make sure |
3084 | * there are no races. | ||
3085 | */ | ||
3007 | spin_lock_irqsave(&to_clean->si_lock, flags); | 3086 | spin_lock_irqsave(&to_clean->si_lock, flags); |
3008 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | 3087 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
3009 | spin_unlock_irqrestore(&to_clean->si_lock, flags); | 3088 | spin_unlock_irqrestore(&to_clean->si_lock, flags); |
@@ -3074,4 +3153,5 @@ module_exit(cleanup_ipmi_si); | |||
3074 | 3153 | ||
3075 | MODULE_LICENSE("GPL"); | 3154 | MODULE_LICENSE("GPL"); |
3076 | MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); | 3155 | MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); |
3077 | MODULE_DESCRIPTION("Interface to the IPMI driver for the KCS, SMIC, and BT system interfaces."); | 3156 | MODULE_DESCRIPTION("Interface to the IPMI driver for the KCS, SMIC, and BT" |
3157 | " system interfaces."); | ||
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h index 4b731b24dc16..df89f73475fb 100644 --- a/drivers/char/ipmi/ipmi_si_sm.h +++ b/drivers/char/ipmi/ipmi_si_sm.h | |||
@@ -34,22 +34,27 @@ | |||
34 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 34 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | /* This is defined by the state machines themselves, it is an opaque | 37 | /* |
38 | data type for them to use. */ | 38 | * This is defined by the state machines themselves, it is an opaque |
39 | * data type for them to use. | ||
40 | */ | ||
39 | struct si_sm_data; | 41 | struct si_sm_data; |
40 | 42 | ||
41 | /* The structure for doing I/O in the state machine. The state | 43 | /* |
42 | machine doesn't have the actual I/O routines, they are done through | 44 | * The structure for doing I/O in the state machine. The state |
43 | this interface. */ | 45 | * machine doesn't have the actual I/O routines, they are done through |
44 | struct si_sm_io | 46 | * this interface. |
45 | { | 47 | */ |
48 | struct si_sm_io { | ||
46 | unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset); | 49 | unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset); |
47 | void (*outputb)(struct si_sm_io *io, | 50 | void (*outputb)(struct si_sm_io *io, |
48 | unsigned int offset, | 51 | unsigned int offset, |
49 | unsigned char b); | 52 | unsigned char b); |
50 | 53 | ||
51 | /* Generic info used by the actual handling routines, the | 54 | /* |
52 | state machine shouldn't touch these. */ | 55 | * Generic info used by the actual handling routines, the |
56 | * state machine shouldn't touch these. | ||
57 | */ | ||
53 | void __iomem *addr; | 58 | void __iomem *addr; |
54 | int regspacing; | 59 | int regspacing; |
55 | int regsize; | 60 | int regsize; |
@@ -59,53 +64,67 @@ struct si_sm_io | |||
59 | }; | 64 | }; |
60 | 65 | ||
61 | /* Results of SMI events. */ | 66 | /* Results of SMI events. */ |
62 | enum si_sm_result | 67 | enum si_sm_result { |
63 | { | ||
64 | SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */ | 68 | SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */ |
65 | SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */ | 69 | SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */ |
66 | SI_SM_CALL_WITH_TICK_DELAY, /* Delay at least 1 tick before calling again. */ | 70 | SI_SM_CALL_WITH_TICK_DELAY,/* Delay >=1 tick before calling again. */ |
67 | SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */ | 71 | SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */ |
68 | SI_SM_IDLE, /* The SM is in idle state. */ | 72 | SI_SM_IDLE, /* The SM is in idle state. */ |
69 | SI_SM_HOSED, /* The hardware violated the state machine. */ | 73 | SI_SM_HOSED, /* The hardware violated the state machine. */ |
70 | SI_SM_ATTN /* The hardware is asserting attn and the | 74 | |
71 | state machine is idle. */ | 75 | /* |
76 | * The hardware is asserting attn and the state machine is | ||
77 | * idle. | ||
78 | */ | ||
79 | SI_SM_ATTN | ||
72 | }; | 80 | }; |
73 | 81 | ||
74 | /* Handlers for the SMI state machine. */ | 82 | /* Handlers for the SMI state machine. */ |
75 | struct si_sm_handlers | 83 | struct si_sm_handlers { |
76 | { | 84 | /* |
77 | /* Put the version number of the state machine here so the | 85 | * Put the version number of the state machine here so the |
78 | upper layer can print it. */ | 86 | * upper layer can print it. |
87 | */ | ||
79 | char *version; | 88 | char *version; |
80 | 89 | ||
81 | /* Initialize the data and return the amount of I/O space to | 90 | /* |
82 | reserve for the space. */ | 91 | * Initialize the data and return the amount of I/O space to |
92 | * reserve for the space. | ||
93 | */ | ||
83 | unsigned int (*init_data)(struct si_sm_data *smi, | 94 | unsigned int (*init_data)(struct si_sm_data *smi, |
84 | struct si_sm_io *io); | 95 | struct si_sm_io *io); |
85 | 96 | ||
86 | /* Start a new transaction in the state machine. This will | 97 | /* |
87 | return -2 if the state machine is not idle, -1 if the size | 98 | * Start a new transaction in the state machine. This will |
88 | is invalid (to large or too small), or 0 if the transaction | 99 | * return -2 if the state machine is not idle, -1 if the size |
89 | is successfully completed. */ | 100 | * is invalid (to large or too small), or 0 if the transaction |
101 | * is successfully completed. | ||
102 | */ | ||
90 | int (*start_transaction)(struct si_sm_data *smi, | 103 | int (*start_transaction)(struct si_sm_data *smi, |
91 | unsigned char *data, unsigned int size); | 104 | unsigned char *data, unsigned int size); |
92 | 105 | ||
93 | /* Return the results after the transaction. This will return | 106 | /* |
94 | -1 if the buffer is too small, zero if no transaction is | 107 | * Return the results after the transaction. This will return |
95 | present, or the actual length of the result data. */ | 108 | * -1 if the buffer is too small, zero if no transaction is |
109 | * present, or the actual length of the result data. | ||
110 | */ | ||
96 | int (*get_result)(struct si_sm_data *smi, | 111 | int (*get_result)(struct si_sm_data *smi, |
97 | unsigned char *data, unsigned int length); | 112 | unsigned char *data, unsigned int length); |
98 | 113 | ||
99 | /* Call this periodically (for a polled interface) or upon | 114 | /* |
100 | receiving an interrupt (for a interrupt-driven interface). | 115 | * Call this periodically (for a polled interface) or upon |
101 | If interrupt driven, you should probably poll this | 116 | * receiving an interrupt (for a interrupt-driven interface). |
102 | periodically when not in idle state. This should be called | 117 | * If interrupt driven, you should probably poll this |
103 | with the time that passed since the last call, if it is | 118 | * periodically when not in idle state. This should be called |
104 | significant. Time is in microseconds. */ | 119 | * with the time that passed since the last call, if it is |
120 | * significant. Time is in microseconds. | ||
121 | */ | ||
105 | enum si_sm_result (*event)(struct si_sm_data *smi, long time); | 122 | enum si_sm_result (*event)(struct si_sm_data *smi, long time); |
106 | 123 | ||
107 | /* Attempt to detect an SMI. Returns 0 on success or nonzero | 124 | /* |
108 | on failure. */ | 125 | * Attempt to detect an SMI. Returns 0 on success or nonzero |
126 | * on failure. | ||
127 | */ | ||
109 | int (*detect)(struct si_sm_data *smi); | 128 | int (*detect)(struct si_sm_data *smi); |
110 | 129 | ||
111 | /* The interface is shutting down, so clean it up. */ | 130 | /* The interface is shutting down, so clean it up. */ |
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c index e64ea7d25d24..faed92971907 100644 --- a/drivers/char/ipmi/ipmi_smic_sm.c +++ b/drivers/char/ipmi/ipmi_smic_sm.c | |||
@@ -85,6 +85,7 @@ enum smic_states { | |||
85 | /* SMIC Flags Register Bits */ | 85 | /* SMIC Flags Register Bits */ |
86 | #define SMIC_RX_DATA_READY 0x80 | 86 | #define SMIC_RX_DATA_READY 0x80 |
87 | #define SMIC_TX_DATA_READY 0x40 | 87 | #define SMIC_TX_DATA_READY 0x40 |
88 | |||
88 | /* | 89 | /* |
89 | * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by | 90 | * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by |
90 | * a few systems, and then only by Systems Management | 91 | * a few systems, and then only by Systems Management |
@@ -104,23 +105,22 @@ enum smic_states { | |||
104 | #define EC_ILLEGAL_COMMAND 0x04 | 105 | #define EC_ILLEGAL_COMMAND 0x04 |
105 | #define EC_BUFFER_FULL 0x05 | 106 | #define EC_BUFFER_FULL 0x05 |
106 | 107 | ||
107 | struct si_sm_data | 108 | struct si_sm_data { |
108 | { | ||
109 | enum smic_states state; | 109 | enum smic_states state; |
110 | struct si_sm_io *io; | 110 | struct si_sm_io *io; |
111 | unsigned char write_data[MAX_SMIC_WRITE_SIZE]; | 111 | unsigned char write_data[MAX_SMIC_WRITE_SIZE]; |
112 | int write_pos; | 112 | int write_pos; |
113 | int write_count; | 113 | int write_count; |
114 | int orig_write_count; | 114 | int orig_write_count; |
115 | unsigned char read_data[MAX_SMIC_READ_SIZE]; | 115 | unsigned char read_data[MAX_SMIC_READ_SIZE]; |
116 | int read_pos; | 116 | int read_pos; |
117 | int truncated; | 117 | int truncated; |
118 | unsigned int error_retries; | 118 | unsigned int error_retries; |
119 | long smic_timeout; | 119 | long smic_timeout; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | static unsigned int init_smic_data (struct si_sm_data *smic, | 122 | static unsigned int init_smic_data(struct si_sm_data *smic, |
123 | struct si_sm_io *io) | 123 | struct si_sm_io *io) |
124 | { | 124 | { |
125 | smic->state = SMIC_IDLE; | 125 | smic->state = SMIC_IDLE; |
126 | smic->io = io; | 126 | smic->io = io; |
@@ -150,11 +150,10 @@ static int start_smic_transaction(struct si_sm_data *smic, | |||
150 | return IPMI_NOT_IN_MY_STATE_ERR; | 150 | return IPMI_NOT_IN_MY_STATE_ERR; |
151 | 151 | ||
152 | if (smic_debug & SMIC_DEBUG_MSG) { | 152 | if (smic_debug & SMIC_DEBUG_MSG) { |
153 | printk(KERN_INFO "start_smic_transaction -"); | 153 | printk(KERN_DEBUG "start_smic_transaction -"); |
154 | for (i = 0; i < size; i ++) { | 154 | for (i = 0; i < size; i++) |
155 | printk (" %02x", (unsigned char) (data [i])); | 155 | printk(" %02x", (unsigned char) data[i]); |
156 | } | 156 | printk("\n"); |
157 | printk ("\n"); | ||
158 | } | 157 | } |
159 | smic->error_retries = 0; | 158 | smic->error_retries = 0; |
160 | memcpy(smic->write_data, data, size); | 159 | memcpy(smic->write_data, data, size); |
@@ -173,11 +172,10 @@ static int smic_get_result(struct si_sm_data *smic, | |||
173 | int i; | 172 | int i; |
174 | 173 | ||
175 | if (smic_debug & SMIC_DEBUG_MSG) { | 174 | if (smic_debug & SMIC_DEBUG_MSG) { |
176 | printk (KERN_INFO "smic_get result -"); | 175 | printk(KERN_DEBUG "smic_get result -"); |
177 | for (i = 0; i < smic->read_pos; i ++) { | 176 | for (i = 0; i < smic->read_pos; i++) |
178 | printk (" %02x", (smic->read_data [i])); | 177 | printk(" %02x", smic->read_data[i]); |
179 | } | 178 | printk("\n"); |
180 | printk ("\n"); | ||
181 | } | 179 | } |
182 | if (length < smic->read_pos) { | 180 | if (length < smic->read_pos) { |
183 | smic->read_pos = length; | 181 | smic->read_pos = length; |
@@ -223,8 +221,8 @@ static inline void write_smic_control(struct si_sm_data *smic, | |||
223 | smic->io->outputb(smic->io, 1, control); | 221 | smic->io->outputb(smic->io, 1, control); |
224 | } | 222 | } |
225 | 223 | ||
226 | static inline void write_si_sm_data (struct si_sm_data *smic, | 224 | static inline void write_si_sm_data(struct si_sm_data *smic, |
227 | unsigned char data) | 225 | unsigned char data) |
228 | { | 226 | { |
229 | smic->io->outputb(smic->io, 0, data); | 227 | smic->io->outputb(smic->io, 0, data); |
230 | } | 228 | } |
@@ -233,10 +231,9 @@ static inline void start_error_recovery(struct si_sm_data *smic, char *reason) | |||
233 | { | 231 | { |
234 | (smic->error_retries)++; | 232 | (smic->error_retries)++; |
235 | if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) { | 233 | if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) { |
236 | if (smic_debug & SMIC_DEBUG_ENABLE) { | 234 | if (smic_debug & SMIC_DEBUG_ENABLE) |
237 | printk(KERN_WARNING | 235 | printk(KERN_WARNING |
238 | "ipmi_smic_drv: smic hosed: %s\n", reason); | 236 | "ipmi_smic_drv: smic hosed: %s\n", reason); |
239 | } | ||
240 | smic->state = SMIC_HOSED; | 237 | smic->state = SMIC_HOSED; |
241 | } else { | 238 | } else { |
242 | smic->write_count = smic->orig_write_count; | 239 | smic->write_count = smic->orig_write_count; |
@@ -254,14 +251,14 @@ static inline void write_next_byte(struct si_sm_data *smic) | |||
254 | (smic->write_count)--; | 251 | (smic->write_count)--; |
255 | } | 252 | } |
256 | 253 | ||
257 | static inline void read_next_byte (struct si_sm_data *smic) | 254 | static inline void read_next_byte(struct si_sm_data *smic) |
258 | { | 255 | { |
259 | if (smic->read_pos >= MAX_SMIC_READ_SIZE) { | 256 | if (smic->read_pos >= MAX_SMIC_READ_SIZE) { |
260 | read_smic_data (smic); | 257 | read_smic_data(smic); |
261 | smic->truncated = 1; | 258 | smic->truncated = 1; |
262 | } else { | 259 | } else { |
263 | smic->read_data[smic->read_pos] = read_smic_data(smic); | 260 | smic->read_data[smic->read_pos] = read_smic_data(smic); |
264 | (smic->read_pos)++; | 261 | smic->read_pos++; |
265 | } | 262 | } |
266 | } | 263 | } |
267 | 264 | ||
@@ -336,7 +333,7 @@ static inline void read_next_byte (struct si_sm_data *smic) | |||
336 | SMIC_SC_SMS_RD_END 0xC6 | 333 | SMIC_SC_SMS_RD_END 0xC6 |
337 | */ | 334 | */ |
338 | 335 | ||
339 | static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | 336 | static enum si_sm_result smic_event(struct si_sm_data *smic, long time) |
340 | { | 337 | { |
341 | unsigned char status; | 338 | unsigned char status; |
342 | unsigned char flags; | 339 | unsigned char flags; |
@@ -347,13 +344,15 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
347 | return SI_SM_HOSED; | 344 | return SI_SM_HOSED; |
348 | } | 345 | } |
349 | if (smic->state != SMIC_IDLE) { | 346 | if (smic->state != SMIC_IDLE) { |
350 | if (smic_debug & SMIC_DEBUG_STATES) { | 347 | if (smic_debug & SMIC_DEBUG_STATES) |
351 | printk(KERN_INFO | 348 | printk(KERN_DEBUG |
352 | "smic_event - smic->smic_timeout = %ld," | 349 | "smic_event - smic->smic_timeout = %ld," |
353 | " time = %ld\n", | 350 | " time = %ld\n", |
354 | smic->smic_timeout, time); | 351 | smic->smic_timeout, time); |
355 | } | 352 | /* |
356 | /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */ | 353 | * FIXME: smic_event is sometimes called with time > |
354 | * SMIC_RETRY_TIMEOUT | ||
355 | */ | ||
357 | if (time < SMIC_RETRY_TIMEOUT) { | 356 | if (time < SMIC_RETRY_TIMEOUT) { |
358 | smic->smic_timeout -= time; | 357 | smic->smic_timeout -= time; |
359 | if (smic->smic_timeout < 0) { | 358 | if (smic->smic_timeout < 0) { |
@@ -366,9 +365,9 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
366 | if (flags & SMIC_FLAG_BSY) | 365 | if (flags & SMIC_FLAG_BSY) |
367 | return SI_SM_CALL_WITH_DELAY; | 366 | return SI_SM_CALL_WITH_DELAY; |
368 | 367 | ||
369 | status = read_smic_status (smic); | 368 | status = read_smic_status(smic); |
370 | if (smic_debug & SMIC_DEBUG_STATES) | 369 | if (smic_debug & SMIC_DEBUG_STATES) |
371 | printk(KERN_INFO | 370 | printk(KERN_DEBUG |
372 | "smic_event - state = %d, flags = 0x%02x," | 371 | "smic_event - state = %d, flags = 0x%02x," |
373 | " status = 0x%02x\n", | 372 | " status = 0x%02x\n", |
374 | smic->state, flags, status); | 373 | smic->state, flags, status); |
@@ -377,9 +376,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
377 | case SMIC_IDLE: | 376 | case SMIC_IDLE: |
378 | /* in IDLE we check for available messages */ | 377 | /* in IDLE we check for available messages */ |
379 | if (flags & SMIC_SMS_DATA_AVAIL) | 378 | if (flags & SMIC_SMS_DATA_AVAIL) |
380 | { | ||
381 | return SI_SM_ATTN; | 379 | return SI_SM_ATTN; |
382 | } | ||
383 | return SI_SM_IDLE; | 380 | return SI_SM_IDLE; |
384 | 381 | ||
385 | case SMIC_START_OP: | 382 | case SMIC_START_OP: |
@@ -391,7 +388,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
391 | 388 | ||
392 | case SMIC_OP_OK: | 389 | case SMIC_OP_OK: |
393 | if (status != SMIC_SC_SMS_READY) { | 390 | if (status != SMIC_SC_SMS_READY) { |
394 | /* this should not happen */ | 391 | /* this should not happen */ |
395 | start_error_recovery(smic, | 392 | start_error_recovery(smic, |
396 | "state = SMIC_OP_OK," | 393 | "state = SMIC_OP_OK," |
397 | " status != SMIC_SC_SMS_READY"); | 394 | " status != SMIC_SC_SMS_READY"); |
@@ -411,8 +408,10 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
411 | "status != SMIC_SC_SMS_WR_START"); | 408 | "status != SMIC_SC_SMS_WR_START"); |
412 | return SI_SM_CALL_WITH_DELAY; | 409 | return SI_SM_CALL_WITH_DELAY; |
413 | } | 410 | } |
414 | /* we must not issue WR_(NEXT|END) unless | 411 | /* |
415 | TX_DATA_READY is set */ | 412 | * we must not issue WR_(NEXT|END) unless |
413 | * TX_DATA_READY is set | ||
414 | * */ | ||
416 | if (flags & SMIC_TX_DATA_READY) { | 415 | if (flags & SMIC_TX_DATA_READY) { |
417 | if (smic->write_count == 1) { | 416 | if (smic->write_count == 1) { |
418 | /* last byte */ | 417 | /* last byte */ |
@@ -424,10 +423,8 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
424 | } | 423 | } |
425 | write_next_byte(smic); | 424 | write_next_byte(smic); |
426 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); | 425 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); |
427 | } | 426 | } else |
428 | else { | ||
429 | return SI_SM_CALL_WITH_DELAY; | 427 | return SI_SM_CALL_WITH_DELAY; |
430 | } | ||
431 | break; | 428 | break; |
432 | 429 | ||
433 | case SMIC_WRITE_NEXT: | 430 | case SMIC_WRITE_NEXT: |
@@ -442,52 +439,48 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
442 | if (smic->write_count == 1) { | 439 | if (smic->write_count == 1) { |
443 | write_smic_control(smic, SMIC_CC_SMS_WR_END); | 440 | write_smic_control(smic, SMIC_CC_SMS_WR_END); |
444 | smic->state = SMIC_WRITE_END; | 441 | smic->state = SMIC_WRITE_END; |
445 | } | 442 | } else { |
446 | else { | ||
447 | write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); | 443 | write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); |
448 | smic->state = SMIC_WRITE_NEXT; | 444 | smic->state = SMIC_WRITE_NEXT; |
449 | } | 445 | } |
450 | write_next_byte(smic); | 446 | write_next_byte(smic); |
451 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); | 447 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); |
452 | } | 448 | } else |
453 | else { | ||
454 | return SI_SM_CALL_WITH_DELAY; | 449 | return SI_SM_CALL_WITH_DELAY; |
455 | } | ||
456 | break; | 450 | break; |
457 | 451 | ||
458 | case SMIC_WRITE_END: | 452 | case SMIC_WRITE_END: |
459 | if (status != SMIC_SC_SMS_WR_END) { | 453 | if (status != SMIC_SC_SMS_WR_END) { |
460 | start_error_recovery (smic, | 454 | start_error_recovery(smic, |
461 | "state = SMIC_WRITE_END, " | 455 | "state = SMIC_WRITE_END, " |
462 | "status != SMIC_SC_SMS_WR_END"); | 456 | "status != SMIC_SC_SMS_WR_END"); |
463 | return SI_SM_CALL_WITH_DELAY; | 457 | return SI_SM_CALL_WITH_DELAY; |
464 | } | 458 | } |
465 | /* data register holds an error code */ | 459 | /* data register holds an error code */ |
466 | data = read_smic_data(smic); | 460 | data = read_smic_data(smic); |
467 | if (data != 0) { | 461 | if (data != 0) { |
468 | if (smic_debug & SMIC_DEBUG_ENABLE) { | 462 | if (smic_debug & SMIC_DEBUG_ENABLE) |
469 | printk(KERN_INFO | 463 | printk(KERN_DEBUG |
470 | "SMIC_WRITE_END: data = %02x\n", data); | 464 | "SMIC_WRITE_END: data = %02x\n", data); |
471 | } | ||
472 | start_error_recovery(smic, | 465 | start_error_recovery(smic, |
473 | "state = SMIC_WRITE_END, " | 466 | "state = SMIC_WRITE_END, " |
474 | "data != SUCCESS"); | 467 | "data != SUCCESS"); |
475 | return SI_SM_CALL_WITH_DELAY; | 468 | return SI_SM_CALL_WITH_DELAY; |
476 | } else { | 469 | } else |
477 | smic->state = SMIC_WRITE2READ; | 470 | smic->state = SMIC_WRITE2READ; |
478 | } | ||
479 | break; | 471 | break; |
480 | 472 | ||
481 | case SMIC_WRITE2READ: | 473 | case SMIC_WRITE2READ: |
482 | /* we must wait for RX_DATA_READY to be set before we | 474 | /* |
483 | can continue */ | 475 | * we must wait for RX_DATA_READY to be set before we |
476 | * can continue | ||
477 | */ | ||
484 | if (flags & SMIC_RX_DATA_READY) { | 478 | if (flags & SMIC_RX_DATA_READY) { |
485 | write_smic_control(smic, SMIC_CC_SMS_RD_START); | 479 | write_smic_control(smic, SMIC_CC_SMS_RD_START); |
486 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); | 480 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); |
487 | smic->state = SMIC_READ_START; | 481 | smic->state = SMIC_READ_START; |
488 | } else { | 482 | } else |
489 | return SI_SM_CALL_WITH_DELAY; | 483 | return SI_SM_CALL_WITH_DELAY; |
490 | } | ||
491 | break; | 484 | break; |
492 | 485 | ||
493 | case SMIC_READ_START: | 486 | case SMIC_READ_START: |
@@ -502,15 +495,16 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
502 | write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); | 495 | write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); |
503 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); | 496 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); |
504 | smic->state = SMIC_READ_NEXT; | 497 | smic->state = SMIC_READ_NEXT; |
505 | } else { | 498 | } else |
506 | return SI_SM_CALL_WITH_DELAY; | 499 | return SI_SM_CALL_WITH_DELAY; |
507 | } | ||
508 | break; | 500 | break; |
509 | 501 | ||
510 | case SMIC_READ_NEXT: | 502 | case SMIC_READ_NEXT: |
511 | switch (status) { | 503 | switch (status) { |
512 | /* smic tells us that this is the last byte to be read | 504 | /* |
513 | --> clean up */ | 505 | * smic tells us that this is the last byte to be read |
506 | * --> clean up | ||
507 | */ | ||
514 | case SMIC_SC_SMS_RD_END: | 508 | case SMIC_SC_SMS_RD_END: |
515 | read_next_byte(smic); | 509 | read_next_byte(smic); |
516 | write_smic_control(smic, SMIC_CC_SMS_RD_END); | 510 | write_smic_control(smic, SMIC_CC_SMS_RD_END); |
@@ -523,9 +517,8 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
523 | write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); | 517 | write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); |
524 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); | 518 | write_smic_flags(smic, flags | SMIC_FLAG_BSY); |
525 | smic->state = SMIC_READ_NEXT; | 519 | smic->state = SMIC_READ_NEXT; |
526 | } else { | 520 | } else |
527 | return SI_SM_CALL_WITH_DELAY; | 521 | return SI_SM_CALL_WITH_DELAY; |
528 | } | ||
529 | break; | 522 | break; |
530 | default: | 523 | default: |
531 | start_error_recovery( | 524 | start_error_recovery( |
@@ -546,10 +539,9 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
546 | data = read_smic_data(smic); | 539 | data = read_smic_data(smic); |
547 | /* data register holds an error code */ | 540 | /* data register holds an error code */ |
548 | if (data != 0) { | 541 | if (data != 0) { |
549 | if (smic_debug & SMIC_DEBUG_ENABLE) { | 542 | if (smic_debug & SMIC_DEBUG_ENABLE) |
550 | printk(KERN_INFO | 543 | printk(KERN_DEBUG |
551 | "SMIC_READ_END: data = %02x\n", data); | 544 | "SMIC_READ_END: data = %02x\n", data); |
552 | } | ||
553 | start_error_recovery(smic, | 545 | start_error_recovery(smic, |
554 | "state = SMIC_READ_END, " | 546 | "state = SMIC_READ_END, " |
555 | "data != SUCCESS"); | 547 | "data != SUCCESS"); |
@@ -565,7 +557,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
565 | 557 | ||
566 | default: | 558 | default: |
567 | if (smic_debug & SMIC_DEBUG_ENABLE) { | 559 | if (smic_debug & SMIC_DEBUG_ENABLE) { |
568 | printk(KERN_WARNING "smic->state = %d\n", smic->state); | 560 | printk(KERN_DEBUG "smic->state = %d\n", smic->state); |
569 | start_error_recovery(smic, "state = UNKNOWN"); | 561 | start_error_recovery(smic, "state = UNKNOWN"); |
570 | return SI_SM_CALL_WITH_DELAY; | 562 | return SI_SM_CALL_WITH_DELAY; |
571 | } | 563 | } |
@@ -576,10 +568,12 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time) | |||
576 | 568 | ||
577 | static int smic_detect(struct si_sm_data *smic) | 569 | static int smic_detect(struct si_sm_data *smic) |
578 | { | 570 | { |
579 | /* It's impossible for the SMIC fnags register to be all 1's, | 571 | /* |
580 | (assuming a properly functioning, self-initialized BMC) | 572 | * It's impossible for the SMIC fnags register to be all 1's, |
581 | but that's what you get from reading a bogus address, so we | 573 | * (assuming a properly functioning, self-initialized BMC) |
582 | test that first. */ | 574 | * but that's what you get from reading a bogus address, so we |
575 | * test that first. | ||
576 | */ | ||
583 | if (read_smic_flags(smic) == 0xff) | 577 | if (read_smic_flags(smic) == 0xff) |
584 | return 1; | 578 | return 1; |
585 | 579 | ||
@@ -595,8 +589,7 @@ static int smic_size(void) | |||
595 | return sizeof(struct si_sm_data); | 589 | return sizeof(struct si_sm_data); |
596 | } | 590 | } |
597 | 591 | ||
598 | struct si_sm_handlers smic_smi_handlers = | 592 | struct si_sm_handlers smic_smi_handlers = { |
599 | { | ||
600 | .init_data = init_smic_data, | 593 | .init_data = init_smic_data, |
601 | .start_transaction = start_smic_transaction, | 594 | .start_transaction = start_smic_transaction, |
602 | .get_result = smic_get_result, | 595 | .get_result = smic_get_result, |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 8f45ca9235ad..1b9a87047817 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -54,13 +54,15 @@ | |||
54 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
55 | 55 | ||
56 | #ifdef CONFIG_X86 | 56 | #ifdef CONFIG_X86 |
57 | /* This is ugly, but I've determined that x86 is the only architecture | 57 | /* |
58 | that can reasonably support the IPMI NMI watchdog timeout at this | 58 | * This is ugly, but I've determined that x86 is the only architecture |
59 | time. If another architecture adds this capability somehow, it | 59 | * that can reasonably support the IPMI NMI watchdog timeout at this |
60 | will have to be a somewhat different mechanism and I have no idea | 60 | * time. If another architecture adds this capability somehow, it |
61 | how it will work. So in the unlikely event that another | 61 | * will have to be a somewhat different mechanism and I have no idea |
62 | architecture supports this, we can figure out a good generic | 62 | * how it will work. So in the unlikely event that another |
63 | mechanism for it at that time. */ | 63 | * architecture supports this, we can figure out a good generic |
64 | * mechanism for it at that time. | ||
65 | */ | ||
64 | #include <asm/kdebug.h> | 66 | #include <asm/kdebug.h> |
65 | #define HAVE_DIE_NMI | 67 | #define HAVE_DIE_NMI |
66 | #endif | 68 | #endif |
@@ -95,9 +97,8 @@ | |||
95 | /* Operations that can be performed on a pretimout. */ | 97 | /* Operations that can be performed on a pretimout. */ |
96 | #define WDOG_PREOP_NONE 0 | 98 | #define WDOG_PREOP_NONE 0 |
97 | #define WDOG_PREOP_PANIC 1 | 99 | #define WDOG_PREOP_PANIC 1 |
98 | #define WDOG_PREOP_GIVE_DATA 2 /* Cause data to be available to | 100 | /* Cause data to be available to read. Doesn't work in NMI mode. */ |
99 | read. Doesn't work in NMI | 101 | #define WDOG_PREOP_GIVE_DATA 2 |
100 | mode. */ | ||
101 | 102 | ||
102 | /* Actions to perform on a full timeout. */ | 103 | /* Actions to perform on a full timeout. */ |
103 | #define WDOG_SET_TIMEOUT_ACT(byte, use) \ | 104 | #define WDOG_SET_TIMEOUT_ACT(byte, use) \ |
@@ -108,8 +109,10 @@ | |||
108 | #define WDOG_TIMEOUT_POWER_DOWN 2 | 109 | #define WDOG_TIMEOUT_POWER_DOWN 2 |
109 | #define WDOG_TIMEOUT_POWER_CYCLE 3 | 110 | #define WDOG_TIMEOUT_POWER_CYCLE 3 |
110 | 111 | ||
111 | /* Byte 3 of the get command, byte 4 of the get response is the | 112 | /* |
112 | pre-timeout in seconds. */ | 113 | * Byte 3 of the get command, byte 4 of the get response is the |
114 | * pre-timeout in seconds. | ||
115 | */ | ||
113 | 116 | ||
114 | /* Bits for setting byte 4 of the set command, byte 5 of the get response. */ | 117 | /* Bits for setting byte 4 of the set command, byte 5 of the get response. */ |
115 | #define WDOG_EXPIRE_CLEAR_BIOS_FRB2 (1 << 1) | 118 | #define WDOG_EXPIRE_CLEAR_BIOS_FRB2 (1 << 1) |
@@ -118,11 +121,13 @@ | |||
118 | #define WDOG_EXPIRE_CLEAR_SMS_OS (1 << 4) | 121 | #define WDOG_EXPIRE_CLEAR_SMS_OS (1 << 4) |
119 | #define WDOG_EXPIRE_CLEAR_OEM (1 << 5) | 122 | #define WDOG_EXPIRE_CLEAR_OEM (1 << 5) |
120 | 123 | ||
121 | /* Setting/getting the watchdog timer value. This is for bytes 5 and | 124 | /* |
122 | 6 (the timeout time) of the set command, and bytes 6 and 7 (the | 125 | * Setting/getting the watchdog timer value. This is for bytes 5 and |
123 | timeout time) and 8 and 9 (the current countdown value) of the | 126 | * 6 (the timeout time) of the set command, and bytes 6 and 7 (the |
124 | response. The timeout value is given in seconds (in the command it | 127 | * timeout time) and 8 and 9 (the current countdown value) of the |
125 | is 100ms intervals). */ | 128 | * response. The timeout value is given in seconds (in the command it |
129 | * is 100ms intervals). | ||
130 | */ | ||
126 | #define WDOG_SET_TIMEOUT(byte1, byte2, val) \ | 131 | #define WDOG_SET_TIMEOUT(byte1, byte2, val) \ |
127 | (byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8) | 132 | (byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8) |
128 | #define WDOG_GET_TIMEOUT(byte1, byte2) \ | 133 | #define WDOG_GET_TIMEOUT(byte1, byte2) \ |
@@ -184,8 +189,10 @@ static int ipmi_set_timeout(int do_heartbeat); | |||
184 | static void ipmi_register_watchdog(int ipmi_intf); | 189 | static void ipmi_register_watchdog(int ipmi_intf); |
185 | static void ipmi_unregister_watchdog(int ipmi_intf); | 190 | static void ipmi_unregister_watchdog(int ipmi_intf); |
186 | 191 | ||
187 | /* If true, the driver will start running as soon as it is configured | 192 | /* |
188 | and ready. */ | 193 | * If true, the driver will start running as soon as it is configured |
194 | * and ready. | ||
195 | */ | ||
189 | static int start_now; | 196 | static int start_now; |
190 | 197 | ||
191 | static int set_param_int(const char *val, struct kernel_param *kp) | 198 | static int set_param_int(const char *val, struct kernel_param *kp) |
@@ -309,10 +316,12 @@ static int ipmi_ignore_heartbeat; | |||
309 | /* Is someone using the watchdog? Only one user is allowed. */ | 316 | /* Is someone using the watchdog? Only one user is allowed. */ |
310 | static unsigned long ipmi_wdog_open; | 317 | static unsigned long ipmi_wdog_open; |
311 | 318 | ||
312 | /* If set to 1, the heartbeat command will set the state to reset and | 319 | /* |
313 | start the timer. The timer doesn't normally run when the driver is | 320 | * If set to 1, the heartbeat command will set the state to reset and |
314 | first opened until the heartbeat is set the first time, this | 321 | * start the timer. The timer doesn't normally run when the driver is |
315 | variable is used to accomplish this. */ | 322 | * first opened until the heartbeat is set the first time, this |
323 | * variable is used to accomplish this. | ||
324 | */ | ||
316 | static int ipmi_start_timer_on_heartbeat; | 325 | static int ipmi_start_timer_on_heartbeat; |
317 | 326 | ||
318 | /* IPMI version of the BMC. */ | 327 | /* IPMI version of the BMC. */ |
@@ -329,10 +338,12 @@ static int nmi_handler_registered; | |||
329 | 338 | ||
330 | static int ipmi_heartbeat(void); | 339 | static int ipmi_heartbeat(void); |
331 | 340 | ||
332 | /* We use a mutex to make sure that only one thing can send a set | 341 | /* |
333 | timeout at one time, because we only have one copy of the data. | 342 | * We use a mutex to make sure that only one thing can send a set |
334 | The mutex is claimed when the set_timeout is sent and freed | 343 | * timeout at one time, because we only have one copy of the data. |
335 | when both messages are free. */ | 344 | * The mutex is claimed when the set_timeout is sent and freed |
345 | * when both messages are free. | ||
346 | */ | ||
336 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); | 347 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); |
337 | static DEFINE_MUTEX(set_timeout_lock); | 348 | static DEFINE_MUTEX(set_timeout_lock); |
338 | static DECLARE_COMPLETION(set_timeout_wait); | 349 | static DECLARE_COMPLETION(set_timeout_wait); |
@@ -346,15 +357,13 @@ static void set_timeout_free_recv(struct ipmi_recv_msg *msg) | |||
346 | if (atomic_dec_and_test(&set_timeout_tofree)) | 357 | if (atomic_dec_and_test(&set_timeout_tofree)) |
347 | complete(&set_timeout_wait); | 358 | complete(&set_timeout_wait); |
348 | } | 359 | } |
349 | static struct ipmi_smi_msg set_timeout_smi_msg = | 360 | static struct ipmi_smi_msg set_timeout_smi_msg = { |
350 | { | ||
351 | .done = set_timeout_free_smi | 361 | .done = set_timeout_free_smi |
352 | }; | 362 | }; |
353 | static struct ipmi_recv_msg set_timeout_recv_msg = | 363 | static struct ipmi_recv_msg set_timeout_recv_msg = { |
354 | { | ||
355 | .done = set_timeout_free_recv | 364 | .done = set_timeout_free_recv |
356 | }; | 365 | }; |
357 | 366 | ||
358 | static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | 367 | static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, |
359 | struct ipmi_recv_msg *recv_msg, | 368 | struct ipmi_recv_msg *recv_msg, |
360 | int *send_heartbeat_now) | 369 | int *send_heartbeat_now) |
@@ -373,13 +382,14 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
373 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 382 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
374 | 383 | ||
375 | if ((ipmi_version_major > 1) | 384 | if ((ipmi_version_major > 1) |
376 | || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) | 385 | || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { |
377 | { | ||
378 | /* This is an IPMI 1.5-only feature. */ | 386 | /* This is an IPMI 1.5-only feature. */ |
379 | data[0] |= WDOG_DONT_STOP_ON_SET; | 387 | data[0] |= WDOG_DONT_STOP_ON_SET; |
380 | } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { | 388 | } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { |
381 | /* In ipmi 1.0, setting the timer stops the watchdog, we | 389 | /* |
382 | need to start it back up again. */ | 390 | * In ipmi 1.0, setting the timer stops the watchdog, we |
391 | * need to start it back up again. | ||
392 | */ | ||
383 | hbnow = 1; | 393 | hbnow = 1; |
384 | } | 394 | } |
385 | 395 | ||
@@ -465,12 +475,10 @@ static void panic_recv_free(struct ipmi_recv_msg *msg) | |||
465 | atomic_dec(&panic_done_count); | 475 | atomic_dec(&panic_done_count); |
466 | } | 476 | } |
467 | 477 | ||
468 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | 478 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = { |
469 | { | ||
470 | .done = panic_smi_free | 479 | .done = panic_smi_free |
471 | }; | 480 | }; |
472 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | 481 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = { |
473 | { | ||
474 | .done = panic_recv_free | 482 | .done = panic_recv_free |
475 | }; | 483 | }; |
476 | 484 | ||
@@ -480,8 +488,10 @@ static void panic_halt_ipmi_heartbeat(void) | |||
480 | struct ipmi_system_interface_addr addr; | 488 | struct ipmi_system_interface_addr addr; |
481 | int rv; | 489 | int rv; |
482 | 490 | ||
483 | /* Don't reset the timer if we have the timer turned off, that | 491 | /* |
484 | re-enables the watchdog. */ | 492 | * Don't reset the timer if we have the timer turned off, that |
493 | * re-enables the watchdog. | ||
494 | */ | ||
485 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 495 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
486 | return; | 496 | return; |
487 | 497 | ||
@@ -505,19 +515,19 @@ static void panic_halt_ipmi_heartbeat(void) | |||
505 | atomic_add(2, &panic_done_count); | 515 | atomic_add(2, &panic_done_count); |
506 | } | 516 | } |
507 | 517 | ||
508 | static struct ipmi_smi_msg panic_halt_smi_msg = | 518 | static struct ipmi_smi_msg panic_halt_smi_msg = { |
509 | { | ||
510 | .done = panic_smi_free | 519 | .done = panic_smi_free |
511 | }; | 520 | }; |
512 | static struct ipmi_recv_msg panic_halt_recv_msg = | 521 | static struct ipmi_recv_msg panic_halt_recv_msg = { |
513 | { | ||
514 | .done = panic_recv_free | 522 | .done = panic_recv_free |
515 | }; | 523 | }; |
516 | 524 | ||
517 | /* Special call, doesn't claim any locks. This is only to be called | 525 | /* |
518 | at panic or halt time, in run-to-completion mode, when the caller | 526 | * Special call, doesn't claim any locks. This is only to be called |
519 | is the only CPU and the only thing that will be going is these IPMI | 527 | * at panic or halt time, in run-to-completion mode, when the caller |
520 | calls. */ | 528 | * is the only CPU and the only thing that will be going is these IPMI |
529 | * calls. | ||
530 | */ | ||
521 | static void panic_halt_ipmi_set_timeout(void) | 531 | static void panic_halt_ipmi_set_timeout(void) |
522 | { | 532 | { |
523 | int send_heartbeat_now; | 533 | int send_heartbeat_now; |
@@ -540,10 +550,12 @@ static void panic_halt_ipmi_set_timeout(void) | |||
540 | ipmi_poll_interface(watchdog_user); | 550 | ipmi_poll_interface(watchdog_user); |
541 | } | 551 | } |
542 | 552 | ||
543 | /* We use a semaphore to make sure that only one thing can send a | 553 | /* |
544 | heartbeat at one time, because we only have one copy of the data. | 554 | * We use a mutex to make sure that only one thing can send a |
545 | The semaphore is claimed when the set_timeout is sent and freed | 555 | * heartbeat at one time, because we only have one copy of the data. |
546 | when both messages are free. */ | 556 | * The semaphore is claimed when the set_timeout is sent and freed |
557 | * when both messages are free. | ||
558 | */ | ||
547 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); | 559 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); |
548 | static DEFINE_MUTEX(heartbeat_lock); | 560 | static DEFINE_MUTEX(heartbeat_lock); |
549 | static DECLARE_COMPLETION(heartbeat_wait); | 561 | static DECLARE_COMPLETION(heartbeat_wait); |
@@ -557,15 +569,13 @@ static void heartbeat_free_recv(struct ipmi_recv_msg *msg) | |||
557 | if (atomic_dec_and_test(&heartbeat_tofree)) | 569 | if (atomic_dec_and_test(&heartbeat_tofree)) |
558 | complete(&heartbeat_wait); | 570 | complete(&heartbeat_wait); |
559 | } | 571 | } |
560 | static struct ipmi_smi_msg heartbeat_smi_msg = | 572 | static struct ipmi_smi_msg heartbeat_smi_msg = { |
561 | { | ||
562 | .done = heartbeat_free_smi | 573 | .done = heartbeat_free_smi |
563 | }; | 574 | }; |
564 | static struct ipmi_recv_msg heartbeat_recv_msg = | 575 | static struct ipmi_recv_msg heartbeat_recv_msg = { |
565 | { | ||
566 | .done = heartbeat_free_recv | 576 | .done = heartbeat_free_recv |
567 | }; | 577 | }; |
568 | 578 | ||
569 | static int ipmi_heartbeat(void) | 579 | static int ipmi_heartbeat(void) |
570 | { | 580 | { |
571 | struct kernel_ipmi_msg msg; | 581 | struct kernel_ipmi_msg msg; |
@@ -580,10 +590,12 @@ static int ipmi_heartbeat(void) | |||
580 | ipmi_watchdog_state = action_val; | 590 | ipmi_watchdog_state = action_val; |
581 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 591 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
582 | } else if (pretimeout_since_last_heartbeat) { | 592 | } else if (pretimeout_since_last_heartbeat) { |
583 | /* A pretimeout occurred, make sure we set the timeout. | 593 | /* |
584 | We don't want to set the action, though, we want to | 594 | * A pretimeout occurred, make sure we set the timeout. |
585 | leave that alone (thus it can't be combined with the | 595 | * We don't want to set the action, though, we want to |
586 | above operation. */ | 596 | * leave that alone (thus it can't be combined with the |
597 | * above operation. | ||
598 | */ | ||
587 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 599 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
588 | } | 600 | } |
589 | 601 | ||
@@ -591,8 +603,10 @@ static int ipmi_heartbeat(void) | |||
591 | 603 | ||
592 | atomic_set(&heartbeat_tofree, 2); | 604 | atomic_set(&heartbeat_tofree, 2); |
593 | 605 | ||
594 | /* Don't reset the timer if we have the timer turned off, that | 606 | /* |
595 | re-enables the watchdog. */ | 607 | * Don't reset the timer if we have the timer turned off, that |
608 | * re-enables the watchdog. | ||
609 | */ | ||
596 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { | 610 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { |
597 | mutex_unlock(&heartbeat_lock); | 611 | mutex_unlock(&heartbeat_lock); |
598 | return 0; | 612 | return 0; |
@@ -625,10 +639,12 @@ static int ipmi_heartbeat(void) | |||
625 | wait_for_completion(&heartbeat_wait); | 639 | wait_for_completion(&heartbeat_wait); |
626 | 640 | ||
627 | if (heartbeat_recv_msg.msg.data[0] != 0) { | 641 | if (heartbeat_recv_msg.msg.data[0] != 0) { |
628 | /* Got an error in the heartbeat response. It was already | 642 | /* |
629 | reported in ipmi_wdog_msg_handler, but we should return | 643 | * Got an error in the heartbeat response. It was already |
630 | an error here. */ | 644 | * reported in ipmi_wdog_msg_handler, but we should return |
631 | rv = -EINVAL; | 645 | * an error here. |
646 | */ | ||
647 | rv = -EINVAL; | ||
632 | } | 648 | } |
633 | 649 | ||
634 | mutex_unlock(&heartbeat_lock); | 650 | mutex_unlock(&heartbeat_lock); |
@@ -636,8 +652,7 @@ static int ipmi_heartbeat(void) | |||
636 | return rv; | 652 | return rv; |
637 | } | 653 | } |
638 | 654 | ||
639 | static struct watchdog_info ident = | 655 | static struct watchdog_info ident = { |
640 | { | ||
641 | .options = 0, /* WDIOF_SETTIMEOUT, */ | 656 | .options = 0, /* WDIOF_SETTIMEOUT, */ |
642 | .firmware_version = 1, | 657 | .firmware_version = 1, |
643 | .identity = "IPMI" | 658 | .identity = "IPMI" |
@@ -650,7 +665,7 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, | |||
650 | int i; | 665 | int i; |
651 | int val; | 666 | int val; |
652 | 667 | ||
653 | switch(cmd) { | 668 | switch (cmd) { |
654 | case WDIOC_GETSUPPORT: | 669 | case WDIOC_GETSUPPORT: |
655 | i = copy_to_user(argp, &ident, sizeof(ident)); | 670 | i = copy_to_user(argp, &ident, sizeof(ident)); |
656 | return i ? -EFAULT : 0; | 671 | return i ? -EFAULT : 0; |
@@ -690,15 +705,13 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, | |||
690 | i = copy_from_user(&val, argp, sizeof(int)); | 705 | i = copy_from_user(&val, argp, sizeof(int)); |
691 | if (i) | 706 | if (i) |
692 | return -EFAULT; | 707 | return -EFAULT; |
693 | if (val & WDIOS_DISABLECARD) | 708 | if (val & WDIOS_DISABLECARD) { |
694 | { | ||
695 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 709 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
696 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | 710 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); |
697 | ipmi_start_timer_on_heartbeat = 0; | 711 | ipmi_start_timer_on_heartbeat = 0; |
698 | } | 712 | } |
699 | 713 | ||
700 | if (val & WDIOS_ENABLECARD) | 714 | if (val & WDIOS_ENABLECARD) { |
701 | { | ||
702 | ipmi_watchdog_state = action_val; | 715 | ipmi_watchdog_state = action_val; |
703 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 716 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
704 | } | 717 | } |
@@ -724,13 +737,13 @@ static ssize_t ipmi_write(struct file *file, | |||
724 | int rv; | 737 | int rv; |
725 | 738 | ||
726 | if (len) { | 739 | if (len) { |
727 | if (!nowayout) { | 740 | if (!nowayout) { |
728 | size_t i; | 741 | size_t i; |
729 | 742 | ||
730 | /* In case it was set long ago */ | 743 | /* In case it was set long ago */ |
731 | expect_close = 0; | 744 | expect_close = 0; |
732 | 745 | ||
733 | for (i = 0; i != len; i++) { | 746 | for (i = 0; i != len; i++) { |
734 | char c; | 747 | char c; |
735 | 748 | ||
736 | if (get_user(c, buf + i)) | 749 | if (get_user(c, buf + i)) |
@@ -758,15 +771,17 @@ static ssize_t ipmi_read(struct file *file, | |||
758 | if (count <= 0) | 771 | if (count <= 0) |
759 | return 0; | 772 | return 0; |
760 | 773 | ||
761 | /* Reading returns if the pretimeout has gone off, and it only does | 774 | /* |
762 | it once per pretimeout. */ | 775 | * Reading returns if the pretimeout has gone off, and it only does |
776 | * it once per pretimeout. | ||
777 | */ | ||
763 | spin_lock(&ipmi_read_lock); | 778 | spin_lock(&ipmi_read_lock); |
764 | if (!data_to_read) { | 779 | if (!data_to_read) { |
765 | if (file->f_flags & O_NONBLOCK) { | 780 | if (file->f_flags & O_NONBLOCK) { |
766 | rv = -EAGAIN; | 781 | rv = -EAGAIN; |
767 | goto out; | 782 | goto out; |
768 | } | 783 | } |
769 | 784 | ||
770 | init_waitqueue_entry(&wait, current); | 785 | init_waitqueue_entry(&wait, current); |
771 | add_wait_queue(&read_q, &wait); | 786 | add_wait_queue(&read_q, &wait); |
772 | while (!data_to_read) { | 787 | while (!data_to_read) { |
@@ -776,7 +791,7 @@ static ssize_t ipmi_read(struct file *file, | |||
776 | spin_lock(&ipmi_read_lock); | 791 | spin_lock(&ipmi_read_lock); |
777 | } | 792 | } |
778 | remove_wait_queue(&read_q, &wait); | 793 | remove_wait_queue(&read_q, &wait); |
779 | 794 | ||
780 | if (signal_pending(current)) { | 795 | if (signal_pending(current)) { |
781 | rv = -ERESTARTSYS; | 796 | rv = -ERESTARTSYS; |
782 | goto out; | 797 | goto out; |
@@ -799,25 +814,27 @@ static ssize_t ipmi_read(struct file *file, | |||
799 | 814 | ||
800 | static int ipmi_open(struct inode *ino, struct file *filep) | 815 | static int ipmi_open(struct inode *ino, struct file *filep) |
801 | { | 816 | { |
802 | switch (iminor(ino)) { | 817 | switch (iminor(ino)) { |
803 | case WATCHDOG_MINOR: | 818 | case WATCHDOG_MINOR: |
804 | if (test_and_set_bit(0, &ipmi_wdog_open)) | 819 | if (test_and_set_bit(0, &ipmi_wdog_open)) |
805 | return -EBUSY; | 820 | return -EBUSY; |
806 | 821 | ||
807 | /* Don't start the timer now, let it start on the | 822 | /* |
808 | first heartbeat. */ | 823 | * Don't start the timer now, let it start on the |
824 | * first heartbeat. | ||
825 | */ | ||
809 | ipmi_start_timer_on_heartbeat = 1; | 826 | ipmi_start_timer_on_heartbeat = 1; |
810 | return nonseekable_open(ino, filep); | 827 | return nonseekable_open(ino, filep); |
811 | 828 | ||
812 | default: | 829 | default: |
813 | return (-ENODEV); | 830 | return (-ENODEV); |
814 | } | 831 | } |
815 | } | 832 | } |
816 | 833 | ||
817 | static unsigned int ipmi_poll(struct file *file, poll_table *wait) | 834 | static unsigned int ipmi_poll(struct file *file, poll_table *wait) |
818 | { | 835 | { |
819 | unsigned int mask = 0; | 836 | unsigned int mask = 0; |
820 | 837 | ||
821 | poll_wait(file, &read_q, wait); | 838 | poll_wait(file, &read_q, wait); |
822 | 839 | ||
823 | spin_lock(&ipmi_read_lock); | 840 | spin_lock(&ipmi_read_lock); |
@@ -851,7 +868,7 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
851 | clear_bit(0, &ipmi_wdog_open); | 868 | clear_bit(0, &ipmi_wdog_open); |
852 | } | 869 | } |
853 | 870 | ||
854 | ipmi_fasync (-1, filep, 0); | 871 | ipmi_fasync(-1, filep, 0); |
855 | expect_close = 0; | 872 | expect_close = 0; |
856 | 873 | ||
857 | return 0; | 874 | return 0; |
@@ -882,7 +899,7 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, | |||
882 | msg->msg.data[0], | 899 | msg->msg.data[0], |
883 | msg->msg.cmd); | 900 | msg->msg.cmd); |
884 | } | 901 | } |
885 | 902 | ||
886 | ipmi_free_recv_msg(msg); | 903 | ipmi_free_recv_msg(msg); |
887 | } | 904 | } |
888 | 905 | ||
@@ -902,14 +919,14 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data) | |||
902 | } | 919 | } |
903 | } | 920 | } |
904 | 921 | ||
905 | /* On some machines, the heartbeat will give | 922 | /* |
906 | an error and not work unless we re-enable | 923 | * On some machines, the heartbeat will give an error and not |
907 | the timer. So do so. */ | 924 | * work unless we re-enable the timer. So do so. |
925 | */ | ||
908 | pretimeout_since_last_heartbeat = 1; | 926 | pretimeout_since_last_heartbeat = 1; |
909 | } | 927 | } |
910 | 928 | ||
911 | static struct ipmi_user_hndl ipmi_hndlrs = | 929 | static struct ipmi_user_hndl ipmi_hndlrs = { |
912 | { | ||
913 | .ipmi_recv_hndl = ipmi_wdog_msg_handler, | 930 | .ipmi_recv_hndl = ipmi_wdog_msg_handler, |
914 | .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler | 931 | .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler |
915 | }; | 932 | }; |
@@ -949,8 +966,10 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
949 | int old_timeout = timeout; | 966 | int old_timeout = timeout; |
950 | int old_preop_val = preop_val; | 967 | int old_preop_val = preop_val; |
951 | 968 | ||
952 | /* Set the pretimeout to go off in a second and give | 969 | /* |
953 | ourselves plenty of time to stop the timer. */ | 970 | * Set the pretimeout to go off in a second and give |
971 | * ourselves plenty of time to stop the timer. | ||
972 | */ | ||
954 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | 973 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; |
955 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | 974 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ |
956 | pretimeout = 99; | 975 | pretimeout = 99; |
@@ -974,7 +993,7 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
974 | " occur. The NMI pretimeout will" | 993 | " occur. The NMI pretimeout will" |
975 | " likely not work\n"); | 994 | " likely not work\n"); |
976 | } | 995 | } |
977 | out_restore: | 996 | out_restore: |
978 | testing_nmi = 0; | 997 | testing_nmi = 0; |
979 | preop_val = old_preop_val; | 998 | preop_val = old_preop_val; |
980 | pretimeout = old_pretimeout; | 999 | pretimeout = old_pretimeout; |
@@ -1009,9 +1028,11 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
1009 | /* Make sure no one can call us any more. */ | 1028 | /* Make sure no one can call us any more. */ |
1010 | misc_deregister(&ipmi_wdog_miscdev); | 1029 | misc_deregister(&ipmi_wdog_miscdev); |
1011 | 1030 | ||
1012 | /* Wait to make sure the message makes it out. The lower layer has | 1031 | /* |
1013 | pointers to our buffers, we want to make sure they are done before | 1032 | * Wait to make sure the message makes it out. The lower layer has |
1014 | we release our memory. */ | 1033 | * pointers to our buffers, we want to make sure they are done before |
1034 | * we release our memory. | ||
1035 | */ | ||
1015 | while (atomic_read(&set_timeout_tofree)) | 1036 | while (atomic_read(&set_timeout_tofree)) |
1016 | schedule_timeout_uninterruptible(1); | 1037 | schedule_timeout_uninterruptible(1); |
1017 | 1038 | ||
@@ -1052,15 +1073,17 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) | |||
1052 | return NOTIFY_STOP; | 1073 | return NOTIFY_STOP; |
1053 | } | 1074 | } |
1054 | 1075 | ||
1055 | /* If we are not expecting a timeout, ignore it. */ | 1076 | /* If we are not expecting a timeout, ignore it. */ |
1056 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1077 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
1057 | return NOTIFY_OK; | 1078 | return NOTIFY_OK; |
1058 | 1079 | ||
1059 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | 1080 | if (preaction_val != WDOG_PRETIMEOUT_NMI) |
1060 | return NOTIFY_OK; | 1081 | return NOTIFY_OK; |
1061 | 1082 | ||
1062 | /* If no one else handled the NMI, we assume it was the IPMI | 1083 | /* |
1063 | watchdog. */ | 1084 | * If no one else handled the NMI, we assume it was the IPMI |
1085 | * watchdog. | ||
1086 | */ | ||
1064 | if (preop_val == WDOG_PREOP_PANIC) { | 1087 | if (preop_val == WDOG_PREOP_PANIC) { |
1065 | /* On some machines, the heartbeat will give | 1088 | /* On some machines, the heartbeat will give |
1066 | an error and not work unless we re-enable | 1089 | an error and not work unless we re-enable |
@@ -1082,7 +1105,7 @@ static int wdog_reboot_handler(struct notifier_block *this, | |||
1082 | unsigned long code, | 1105 | unsigned long code, |
1083 | void *unused) | 1106 | void *unused) |
1084 | { | 1107 | { |
1085 | static int reboot_event_handled = 0; | 1108 | static int reboot_event_handled; |
1086 | 1109 | ||
1087 | if ((watchdog_user) && (!reboot_event_handled)) { | 1110 | if ((watchdog_user) && (!reboot_event_handled)) { |
1088 | /* Make sure we only do this once. */ | 1111 | /* Make sure we only do this once. */ |
@@ -1115,7 +1138,7 @@ static int wdog_panic_handler(struct notifier_block *this, | |||
1115 | unsigned long event, | 1138 | unsigned long event, |
1116 | void *unused) | 1139 | void *unused) |
1117 | { | 1140 | { |
1118 | static int panic_event_handled = 0; | 1141 | static int panic_event_handled; |
1119 | 1142 | ||
1120 | /* On a panic, if we have a panic timeout, make sure to extend | 1143 | /* On a panic, if we have a panic timeout, make sure to extend |
1121 | the watchdog timer to a reasonable value to complete the | 1144 | the watchdog timer to a reasonable value to complete the |
@@ -1125,7 +1148,7 @@ static int wdog_panic_handler(struct notifier_block *this, | |||
1125 | ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { | 1148 | ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { |
1126 | /* Make sure we do this only once. */ | 1149 | /* Make sure we do this only once. */ |
1127 | panic_event_handled = 1; | 1150 | panic_event_handled = 1; |
1128 | 1151 | ||
1129 | timeout = 255; | 1152 | timeout = 255; |
1130 | pretimeout = 0; | 1153 | pretimeout = 0; |
1131 | panic_halt_ipmi_set_timeout(); | 1154 | panic_halt_ipmi_set_timeout(); |
@@ -1151,8 +1174,7 @@ static void ipmi_smi_gone(int if_num) | |||
1151 | ipmi_unregister_watchdog(if_num); | 1174 | ipmi_unregister_watchdog(if_num); |
1152 | } | 1175 | } |
1153 | 1176 | ||
1154 | static struct ipmi_smi_watcher smi_watcher = | 1177 | static struct ipmi_smi_watcher smi_watcher = { |
1155 | { | ||
1156 | .owner = THIS_MODULE, | 1178 | .owner = THIS_MODULE, |
1157 | .new_smi = ipmi_new_smi, | 1179 | .new_smi = ipmi_new_smi, |
1158 | .smi_gone = ipmi_smi_gone | 1180 | .smi_gone = ipmi_smi_gone |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index eba2883b630e..4f3cefa8eb0e 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -126,8 +126,8 @@ | |||
126 | #include <linux/delay.h> | 126 | #include <linux/delay.h> |
127 | #include <linux/ioport.h> | 127 | #include <linux/ioport.h> |
128 | 128 | ||
129 | #include <asm/uaccess.h> | 129 | #include <linux/uaccess.h> |
130 | #include <asm/io.h> | 130 | #include <linux/io.h> |
131 | #include <asm/system.h> | 131 | #include <asm/system.h> |
132 | 132 | ||
133 | #include <linux/pci.h> | 133 | #include <linux/pci.h> |
@@ -189,7 +189,7 @@ struct isi_board { | |||
189 | unsigned short status; | 189 | unsigned short status; |
190 | unsigned short port_status; /* each bit for each port */ | 190 | unsigned short port_status; /* each bit for each port */ |
191 | unsigned short shift_count; | 191 | unsigned short shift_count; |
192 | struct isi_port * ports; | 192 | struct isi_port *ports; |
193 | signed char count; | 193 | signed char count; |
194 | spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ | 194 | spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ |
195 | unsigned long flags; | 195 | unsigned long flags; |
@@ -205,11 +205,11 @@ struct isi_port { | |||
205 | u16 channel; | 205 | u16 channel; |
206 | u16 status; | 206 | u16 status; |
207 | u16 closing_wait; | 207 | u16 closing_wait; |
208 | struct isi_board * card; | 208 | struct isi_board *card; |
209 | struct tty_struct * tty; | 209 | struct tty_struct *tty; |
210 | wait_queue_head_t close_wait; | 210 | wait_queue_head_t close_wait; |
211 | wait_queue_head_t open_wait; | 211 | wait_queue_head_t open_wait; |
212 | unsigned char * xmit_buf; | 212 | unsigned char *xmit_buf; |
213 | int xmit_head; | 213 | int xmit_head; |
214 | int xmit_tail; | 214 | int xmit_tail; |
215 | int xmit_cnt; | 215 | int xmit_cnt; |
@@ -405,7 +405,7 @@ static void isicom_tx(unsigned long _data) | |||
405 | 405 | ||
406 | /* find next active board */ | 406 | /* find next active board */ |
407 | card = (prev_card + 1) & 0x0003; | 407 | card = (prev_card + 1) & 0x0003; |
408 | while(count-- > 0) { | 408 | while (count-- > 0) { |
409 | if (isi_card[card].status & BOARD_ACTIVE) | 409 | if (isi_card[card].status & BOARD_ACTIVE) |
410 | break; | 410 | break; |
411 | card = (card + 1) & 0x0003; | 411 | card = (card + 1) & 0x0003; |
@@ -428,7 +428,7 @@ static void isicom_tx(unsigned long _data) | |||
428 | if (retries >= 100) | 428 | if (retries >= 100) |
429 | goto unlock; | 429 | goto unlock; |
430 | 430 | ||
431 | for (;count > 0;count--, port++) { | 431 | for (; count > 0; count--, port++) { |
432 | /* port not active or tx disabled to force flow control */ | 432 | /* port not active or tx disabled to force flow control */ |
433 | if (!(port->flags & ASYNC_INITIALIZED) || | 433 | if (!(port->flags & ASYNC_INITIALIZED) || |
434 | !(port->status & ISI_TXOK)) | 434 | !(port->status & ISI_TXOK)) |
@@ -471,9 +471,10 @@ static void isicom_tx(unsigned long _data) | |||
471 | break; | 471 | break; |
472 | } | 472 | } |
473 | } | 473 | } |
474 | if (cnt <= 0) break; | 474 | if (cnt <= 0) |
475 | break; | ||
475 | word_count = cnt >> 1; | 476 | word_count = cnt >> 1; |
476 | outsw(base, port->xmit_buf+port->xmit_tail,word_count); | 477 | outsw(base, port->xmit_buf+port->xmit_tail, word_count); |
477 | port->xmit_tail = (port->xmit_tail | 478 | port->xmit_tail = (port->xmit_tail |
478 | + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); | 479 | + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); |
479 | txcount -= (word_count << 1); | 480 | txcount -= (word_count << 1); |
@@ -556,7 +557,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
556 | tty = port->tty; | 557 | tty = port->tty; |
557 | if (tty == NULL) { | 558 | if (tty == NULL) { |
558 | word_count = byte_count >> 1; | 559 | word_count = byte_count >> 1; |
559 | while(byte_count > 1) { | 560 | while (byte_count > 1) { |
560 | inw(base); | 561 | inw(base); |
561 | byte_count -= 2; | 562 | byte_count -= 2; |
562 | } | 563 | } |
@@ -569,7 +570,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
569 | 570 | ||
570 | if (header & 0x8000) { /* Status Packet */ | 571 | if (header & 0x8000) { /* Status Packet */ |
571 | header = inw(base); | 572 | header = inw(base); |
572 | switch(header & 0xff) { | 573 | switch (header & 0xff) { |
573 | case 0: /* Change in EIA signals */ | 574 | case 0: /* Change in EIA signals */ |
574 | if (port->flags & ASYNC_CHECK_CD) { | 575 | if (port->flags & ASYNC_CHECK_CD) { |
575 | if (port->status & ISI_DCD) { | 576 | if (port->status & ISI_DCD) { |
@@ -656,7 +657,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
656 | if (byte_count > 0) { | 657 | if (byte_count > 0) { |
657 | pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping " | 658 | pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping " |
658 | "bytes...\n", base, channel + 1); | 659 | "bytes...\n", base, channel + 1); |
659 | while(byte_count > 0) { /* drain out unread xtra data */ | 660 | /* drain out unread xtra data */ |
661 | while (byte_count > 0) { | ||
660 | inw(base); | 662 | inw(base); |
661 | byte_count -= 2; | 663 | byte_count -= 2; |
662 | } | 664 | } |
@@ -679,8 +681,11 @@ static void isicom_config_port(struct isi_port *port) | |||
679 | shift_count = card->shift_count; | 681 | shift_count = card->shift_count; |
680 | unsigned char flow_ctrl; | 682 | unsigned char flow_ctrl; |
681 | 683 | ||
682 | if (!(tty = port->tty) || !tty->termios) | 684 | tty = port->tty; |
685 | |||
686 | if (tty == NULL) | ||
683 | return; | 687 | return; |
688 | /* FIXME: Switch to new tty baud API */ | ||
684 | baud = C_BAUD(tty); | 689 | baud = C_BAUD(tty); |
685 | if (baud & CBAUDEX) { | 690 | if (baud & CBAUDEX) { |
686 | baud &= ~CBAUDEX; | 691 | baud &= ~CBAUDEX; |
@@ -706,7 +711,7 @@ static void isicom_config_port(struct isi_port *port) | |||
706 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 711 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
707 | baud++; /* 57.6 Kbps */ | 712 | baud++; /* 57.6 Kbps */ |
708 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 713 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
709 | baud +=2; /* 115 Kbps */ | 714 | baud += 2; /* 115 Kbps */ |
710 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 715 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
711 | baud += 3; /* 230 kbps*/ | 716 | baud += 3; /* 230 kbps*/ |
712 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 717 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
@@ -716,15 +721,14 @@ static void isicom_config_port(struct isi_port *port) | |||
716 | /* hang up */ | 721 | /* hang up */ |
717 | drop_dtr(port); | 722 | drop_dtr(port); |
718 | return; | 723 | return; |
719 | } | 724 | } else |
720 | else | ||
721 | raise_dtr(port); | 725 | raise_dtr(port); |
722 | 726 | ||
723 | if (WaitTillCardIsFree(base) == 0) { | 727 | if (WaitTillCardIsFree(base) == 0) { |
724 | outw(0x8000 | (channel << shift_count) |0x03, base); | 728 | outw(0x8000 | (channel << shift_count) | 0x03, base); |
725 | outw(linuxb_to_isib[baud] << 8 | 0x03, base); | 729 | outw(linuxb_to_isib[baud] << 8 | 0x03, base); |
726 | channel_setup = 0; | 730 | channel_setup = 0; |
727 | switch(C_CSIZE(tty)) { | 731 | switch (C_CSIZE(tty)) { |
728 | case CS5: | 732 | case CS5: |
729 | channel_setup |= ISICOM_CS5; | 733 | channel_setup |= ISICOM_CS5; |
730 | break; | 734 | break; |
@@ -767,7 +771,7 @@ static void isicom_config_port(struct isi_port *port) | |||
767 | flow_ctrl |= ISICOM_INITIATE_XONXOFF; | 771 | flow_ctrl |= ISICOM_INITIATE_XONXOFF; |
768 | 772 | ||
769 | if (WaitTillCardIsFree(base) == 0) { | 773 | if (WaitTillCardIsFree(base) == 0) { |
770 | outw(0x8000 | (channel << shift_count) |0x04, base); | 774 | outw(0x8000 | (channel << shift_count) | 0x04, base); |
771 | outw(flow_ctrl << 8 | 0x05, base); | 775 | outw(flow_ctrl << 8 | 0x05, base); |
772 | outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); | 776 | outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); |
773 | InterruptTheCard(base); | 777 | InterruptTheCard(base); |
@@ -805,20 +809,17 @@ static int isicom_setup_port(struct isi_port *port) | |||
805 | struct isi_board *card = port->card; | 809 | struct isi_board *card = port->card; |
806 | unsigned long flags; | 810 | unsigned long flags; |
807 | 811 | ||
808 | if (port->flags & ASYNC_INITIALIZED) { | 812 | if (port->flags & ASYNC_INITIALIZED) |
809 | return 0; | 813 | return 0; |
810 | } | ||
811 | if (!port->xmit_buf) { | 814 | if (!port->xmit_buf) { |
812 | unsigned long page; | 815 | /* Relies on BKL */ |
813 | 816 | unsigned long page = get_zeroed_page(GFP_KERNEL); | |
814 | if (!(page = get_zeroed_page(GFP_KERNEL))) | 817 | if (page == 0) |
815 | return -ENOMEM; | 818 | return -ENOMEM; |
816 | 819 | if (port->xmit_buf) | |
817 | if (port->xmit_buf) { | ||
818 | free_page(page); | 820 | free_page(page); |
819 | return -ERESTARTSYS; | 821 | else |
820 | } | 822 | port->xmit_buf = (unsigned char *) page; |
821 | port->xmit_buf = (unsigned char *) page; | ||
822 | } | 823 | } |
823 | 824 | ||
824 | spin_lock_irqsave(&card->card_lock, flags); | 825 | spin_lock_irqsave(&card->card_lock, flags); |
@@ -949,21 +950,18 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
949 | port->count++; | 950 | port->count++; |
950 | tty->driver_data = port; | 951 | tty->driver_data = port; |
951 | port->tty = tty; | 952 | port->tty = tty; |
952 | if ((error = isicom_setup_port(port))!=0) | 953 | error = isicom_setup_port(port); |
953 | return error; | 954 | if (error == 0) |
954 | if ((error = block_til_ready(tty, filp, port))!=0) | 955 | error = block_til_ready(tty, filp, port); |
955 | return error; | 956 | return error; |
956 | |||
957 | return 0; | ||
958 | } | 957 | } |
959 | 958 | ||
960 | /* close et all */ | 959 | /* close et all */ |
961 | 960 | ||
962 | static inline void isicom_shutdown_board(struct isi_board *bp) | 961 | static inline void isicom_shutdown_board(struct isi_board *bp) |
963 | { | 962 | { |
964 | if (bp->status & BOARD_ACTIVE) { | 963 | if (bp->status & BOARD_ACTIVE) |
965 | bp->status &= ~BOARD_ACTIVE; | 964 | bp->status &= ~BOARD_ACTIVE; |
966 | } | ||
967 | } | 965 | } |
968 | 966 | ||
969 | /* card->lock HAS to be held */ | 967 | /* card->lock HAS to be held */ |
@@ -1012,6 +1010,22 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
1012 | } | 1010 | } |
1013 | } | 1011 | } |
1014 | 1012 | ||
1013 | static void isicom_flush_buffer(struct tty_struct *tty) | ||
1014 | { | ||
1015 | struct isi_port *port = tty->driver_data; | ||
1016 | struct isi_board *card = port->card; | ||
1017 | unsigned long flags; | ||
1018 | |||
1019 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) | ||
1020 | return; | ||
1021 | |||
1022 | spin_lock_irqsave(&card->card_lock, flags); | ||
1023 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1024 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1025 | |||
1026 | tty_wakeup(tty); | ||
1027 | } | ||
1028 | |||
1015 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 1029 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
1016 | { | 1030 | { |
1017 | struct isi_port *port = tty->driver_data; | 1031 | struct isi_port *port = tty->driver_data; |
@@ -1065,8 +1079,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1065 | isicom_shutdown_port(port); | 1079 | isicom_shutdown_port(port); |
1066 | spin_unlock_irqrestore(&card->card_lock, flags); | 1080 | spin_unlock_irqrestore(&card->card_lock, flags); |
1067 | 1081 | ||
1068 | if (tty->driver->flush_buffer) | 1082 | isicom_flush_buffer(tty); |
1069 | tty->driver->flush_buffer(tty); | ||
1070 | tty_ldisc_flush(tty); | 1083 | tty_ldisc_flush(tty); |
1071 | 1084 | ||
1072 | spin_lock_irqsave(&card->card_lock, flags); | 1085 | spin_lock_irqsave(&card->card_lock, flags); |
@@ -1104,7 +1117,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf, | |||
1104 | 1117 | ||
1105 | spin_lock_irqsave(&card->card_lock, flags); | 1118 | spin_lock_irqsave(&card->card_lock, flags); |
1106 | 1119 | ||
1107 | while(1) { | 1120 | while (1) { |
1108 | cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt | 1121 | cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt |
1109 | - 1, SERIAL_XMIT_SIZE - port->xmit_head)); | 1122 | - 1, SERIAL_XMIT_SIZE - port->xmit_head)); |
1110 | if (cnt <= 0) | 1123 | if (cnt <= 0) |
@@ -1125,28 +1138,29 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf, | |||
1125 | } | 1138 | } |
1126 | 1139 | ||
1127 | /* put_char et all */ | 1140 | /* put_char et all */ |
1128 | static void isicom_put_char(struct tty_struct *tty, unsigned char ch) | 1141 | static int isicom_put_char(struct tty_struct *tty, unsigned char ch) |
1129 | { | 1142 | { |
1130 | struct isi_port *port = tty->driver_data; | 1143 | struct isi_port *port = tty->driver_data; |
1131 | struct isi_board *card = port->card; | 1144 | struct isi_board *card = port->card; |
1132 | unsigned long flags; | 1145 | unsigned long flags; |
1133 | 1146 | ||
1134 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) | 1147 | if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) |
1135 | return; | 1148 | return 0; |
1136 | 1149 | ||
1137 | if (!port->xmit_buf) | 1150 | if (!port->xmit_buf) |
1138 | return; | 1151 | return 0; |
1139 | 1152 | ||
1140 | spin_lock_irqsave(&card->card_lock, flags); | 1153 | spin_lock_irqsave(&card->card_lock, flags); |
1141 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { | 1154 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { |
1142 | spin_unlock_irqrestore(&card->card_lock, flags); | 1155 | spin_unlock_irqrestore(&card->card_lock, flags); |
1143 | return; | 1156 | return 0; |
1144 | } | 1157 | } |
1145 | 1158 | ||
1146 | port->xmit_buf[port->xmit_head++] = ch; | 1159 | port->xmit_buf[port->xmit_head++] = ch; |
1147 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); | 1160 | port->xmit_head &= (SERIAL_XMIT_SIZE - 1); |
1148 | port->xmit_cnt++; | 1161 | port->xmit_cnt++; |
1149 | spin_unlock_irqrestore(&card->card_lock, flags); | 1162 | spin_unlock_irqrestore(&card->card_lock, flags); |
1163 | return 1; | ||
1150 | } | 1164 | } |
1151 | 1165 | ||
1152 | /* flush_chars et all */ | 1166 | /* flush_chars et all */ |
@@ -1258,6 +1272,8 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1258 | if (copy_from_user(&newinfo, info, sizeof(newinfo))) | 1272 | if (copy_from_user(&newinfo, info, sizeof(newinfo))) |
1259 | return -EFAULT; | 1273 | return -EFAULT; |
1260 | 1274 | ||
1275 | lock_kernel(); | ||
1276 | |||
1261 | reconfig_port = ((port->flags & ASYNC_SPD_MASK) != | 1277 | reconfig_port = ((port->flags & ASYNC_SPD_MASK) != |
1262 | (newinfo.flags & ASYNC_SPD_MASK)); | 1278 | (newinfo.flags & ASYNC_SPD_MASK)); |
1263 | 1279 | ||
@@ -1265,12 +1281,13 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1265 | if ((newinfo.close_delay != port->close_delay) || | 1281 | if ((newinfo.close_delay != port->close_delay) || |
1266 | (newinfo.closing_wait != port->closing_wait) || | 1282 | (newinfo.closing_wait != port->closing_wait) || |
1267 | ((newinfo.flags & ~ASYNC_USR_MASK) != | 1283 | ((newinfo.flags & ~ASYNC_USR_MASK) != |
1268 | (port->flags & ~ASYNC_USR_MASK))) | 1284 | (port->flags & ~ASYNC_USR_MASK))) { |
1285 | unlock_kernel(); | ||
1269 | return -EPERM; | 1286 | return -EPERM; |
1270 | port->flags = ((port->flags & ~ ASYNC_USR_MASK) | | 1287 | } |
1288 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | ||
1271 | (newinfo.flags & ASYNC_USR_MASK)); | 1289 | (newinfo.flags & ASYNC_USR_MASK)); |
1272 | } | 1290 | } else { |
1273 | else { | ||
1274 | port->close_delay = newinfo.close_delay; | 1291 | port->close_delay = newinfo.close_delay; |
1275 | port->closing_wait = newinfo.closing_wait; | 1292 | port->closing_wait = newinfo.closing_wait; |
1276 | port->flags = ((port->flags & ~ASYNC_FLAGS) | | 1293 | port->flags = ((port->flags & ~ASYNC_FLAGS) | |
@@ -1282,6 +1299,7 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1282 | isicom_config_port(port); | 1299 | isicom_config_port(port); |
1283 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1300 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1284 | } | 1301 | } |
1302 | unlock_kernel(); | ||
1285 | return 0; | 1303 | return 0; |
1286 | } | 1304 | } |
1287 | 1305 | ||
@@ -1290,6 +1308,7 @@ static int isicom_get_serial_info(struct isi_port *port, | |||
1290 | { | 1308 | { |
1291 | struct serial_struct out_info; | 1309 | struct serial_struct out_info; |
1292 | 1310 | ||
1311 | lock_kernel(); | ||
1293 | memset(&out_info, 0, sizeof(out_info)); | 1312 | memset(&out_info, 0, sizeof(out_info)); |
1294 | /* out_info.type = ? */ | 1313 | /* out_info.type = ? */ |
1295 | out_info.line = port - isi_ports; | 1314 | out_info.line = port - isi_ports; |
@@ -1299,6 +1318,7 @@ static int isicom_get_serial_info(struct isi_port *port, | |||
1299 | /* out_info.baud_base = ? */ | 1318 | /* out_info.baud_base = ? */ |
1300 | out_info.close_delay = port->close_delay; | 1319 | out_info.close_delay = port->close_delay; |
1301 | out_info.closing_wait = port->closing_wait; | 1320 | out_info.closing_wait = port->closing_wait; |
1321 | unlock_kernel(); | ||
1302 | if (copy_to_user(info, &out_info, sizeof(out_info))) | 1322 | if (copy_to_user(info, &out_info, sizeof(out_info))) |
1303 | return -EFAULT; | 1323 | return -EFAULT; |
1304 | return 0; | 1324 | return 0; |
@@ -1314,7 +1334,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, | |||
1314 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) | 1334 | if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) |
1315 | return -ENODEV; | 1335 | return -ENODEV; |
1316 | 1336 | ||
1317 | switch(cmd) { | 1337 | switch (cmd) { |
1318 | case TCSBRK: | 1338 | case TCSBRK: |
1319 | retval = tty_check_change(tty); | 1339 | retval = tty_check_change(tty); |
1320 | if (retval) | 1340 | if (retval) |
@@ -1331,19 +1351,6 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, | |||
1331 | tty_wait_until_sent(tty, 0); | 1351 | tty_wait_until_sent(tty, 0); |
1332 | isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4); | 1352 | isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4); |
1333 | return 0; | 1353 | return 0; |
1334 | |||
1335 | case TIOCGSOFTCAR: | ||
1336 | return put_user(C_CLOCAL(tty) ? 1 : 0, | ||
1337 | (unsigned long __user *)argp); | ||
1338 | |||
1339 | case TIOCSSOFTCAR: | ||
1340 | if (get_user(arg, (unsigned long __user *) argp)) | ||
1341 | return -EFAULT; | ||
1342 | tty->termios->c_cflag = | ||
1343 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
1344 | (arg ? CLOCAL : 0)); | ||
1345 | return 0; | ||
1346 | |||
1347 | case TIOCGSERIAL: | 1354 | case TIOCGSERIAL: |
1348 | return isicom_get_serial_info(port, argp); | 1355 | return isicom_get_serial_info(port, argp); |
1349 | 1356 | ||
@@ -1453,22 +1460,6 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1453 | wake_up_interruptible(&port->open_wait); | 1460 | wake_up_interruptible(&port->open_wait); |
1454 | } | 1461 | } |
1455 | 1462 | ||
1456 | /* flush_buffer et all */ | ||
1457 | static void isicom_flush_buffer(struct tty_struct *tty) | ||
1458 | { | ||
1459 | struct isi_port *port = tty->driver_data; | ||
1460 | struct isi_board *card = port->card; | ||
1461 | unsigned long flags; | ||
1462 | |||
1463 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) | ||
1464 | return; | ||
1465 | |||
1466 | spin_lock_irqsave(&card->card_lock, flags); | ||
1467 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1468 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1469 | |||
1470 | tty_wakeup(tty); | ||
1471 | } | ||
1472 | 1463 | ||
1473 | /* | 1464 | /* |
1474 | * Driver init and deinit functions | 1465 | * Driver init and deinit functions |
@@ -1592,7 +1583,7 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1592 | default: | 1583 | default: |
1593 | dev_err(&pdev->dev, "Unknown signature.\n"); | 1584 | dev_err(&pdev->dev, "Unknown signature.\n"); |
1594 | goto end; | 1585 | goto end; |
1595 | } | 1586 | } |
1596 | 1587 | ||
1597 | retval = request_firmware(&fw, name, &pdev->dev); | 1588 | retval = request_firmware(&fw, name, &pdev->dev); |
1598 | if (retval) | 1589 | if (retval) |
@@ -1620,7 +1611,8 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1620 | if (WaitTillCardIsFree(base)) | 1611 | if (WaitTillCardIsFree(base)) |
1621 | goto errrelfw; | 1612 | goto errrelfw; |
1622 | 1613 | ||
1623 | if ((status = inw(base + 0x4)) != 0) { | 1614 | status = inw(base + 0x4); |
1615 | if (status != 0) { | ||
1624 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" | 1616 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" |
1625 | KERN_WARNING "Address:0x%x\n" | 1617 | KERN_WARNING "Address:0x%x\n" |
1626 | KERN_WARNING "Count:0x%x\n" | 1618 | KERN_WARNING "Count:0x%x\n" |
@@ -1637,12 +1629,13 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1637 | if (WaitTillCardIsFree(base)) | 1629 | if (WaitTillCardIsFree(base)) |
1638 | goto errrelfw; | 1630 | goto errrelfw; |
1639 | 1631 | ||
1640 | if ((status = inw(base + 0x4)) != 0) { | 1632 | status = inw(base + 0x4); |
1633 | if (status != 0) { | ||
1641 | dev_err(&pdev->dev, "Card%d got out of sync.Card " | 1634 | dev_err(&pdev->dev, "Card%d got out of sync.Card " |
1642 | "Status:0x%x\n", index + 1, status); | 1635 | "Status:0x%x\n", index + 1, status); |
1643 | goto errrelfw; | 1636 | goto errrelfw; |
1644 | } | 1637 | } |
1645 | } | 1638 | } |
1646 | 1639 | ||
1647 | /* XXX: should we test it by reading it back and comparing with original like | 1640 | /* XXX: should we test it by reading it back and comparing with original like |
1648 | * in load firmware package? */ | 1641 | * in load firmware package? */ |
@@ -1666,7 +1659,8 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1666 | if (WaitTillCardIsFree(base)) | 1659 | if (WaitTillCardIsFree(base)) |
1667 | goto errrelfw; | 1660 | goto errrelfw; |
1668 | 1661 | ||
1669 | if ((status = inw(base + 0x4)) != 0) { | 1662 | status = inw(base + 0x4); |
1663 | if (status != 0) { | ||
1670 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" | 1664 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" |
1671 | KERN_WARNING "Address:0x%x\n" | 1665 | KERN_WARNING "Address:0x%x\n" |
1672 | KERN_WARNING "Count:0x%x\n" | 1666 | KERN_WARNING "Count:0x%x\n" |
@@ -1699,7 +1693,8 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1699 | if (WaitTillCardIsFree(base)) | 1693 | if (WaitTillCardIsFree(base)) |
1700 | goto errrelfw; | 1694 | goto errrelfw; |
1701 | 1695 | ||
1702 | if ((status = inw(base + 0x4)) != 0) { | 1696 | status = inw(base + 0x4); |
1697 | if (status != 0) { | ||
1703 | dev_err(&pdev->dev, "Card%d verify got out of sync. " | 1698 | dev_err(&pdev->dev, "Card%d verify got out of sync. " |
1704 | "Card Status:0x%x\n", index + 1, status); | 1699 | "Card Status:0x%x\n", index + 1, status); |
1705 | goto errrelfw; | 1700 | goto errrelfw; |
@@ -1764,7 +1759,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1764 | index + 1); | 1759 | index + 1); |
1765 | retval = -EBUSY; | 1760 | retval = -EBUSY; |
1766 | goto errdec; | 1761 | goto errdec; |
1767 | } | 1762 | } |
1768 | 1763 | ||
1769 | retval = request_irq(board->irq, isicom_interrupt, | 1764 | retval = request_irq(board->irq, isicom_interrupt, |
1770 | IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); | 1765 | IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); |
@@ -1818,7 +1813,7 @@ static int __init isicom_init(void) | |||
1818 | int retval, idx, channel; | 1813 | int retval, idx, channel; |
1819 | struct isi_port *port; | 1814 | struct isi_port *port; |
1820 | 1815 | ||
1821 | for(idx = 0; idx < BOARD_COUNT; idx++) { | 1816 | for (idx = 0; idx < BOARD_COUNT; idx++) { |
1822 | port = &isi_ports[idx * 16]; | 1817 | port = &isi_ports[idx * 16]; |
1823 | isi_card[idx].ports = port; | 1818 | isi_card[idx].ports = port; |
1824 | spin_lock_init(&isi_card[idx].card_lock); | 1819 | spin_lock_init(&isi_card[idx].card_lock); |
@@ -1832,7 +1827,7 @@ static int __init isicom_init(void) | |||
1832 | init_waitqueue_head(&port->open_wait); | 1827 | init_waitqueue_head(&port->open_wait); |
1833 | init_waitqueue_head(&port->close_wait); | 1828 | init_waitqueue_head(&port->close_wait); |
1834 | /* . . . */ | 1829 | /* . . . */ |
1835 | } | 1830 | } |
1836 | isi_card[idx].base = 0; | 1831 | isi_card[idx].base = 0; |
1837 | isi_card[idx].irq = 0; | 1832 | isi_card[idx].irq = 0; |
1838 | } | 1833 | } |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index c645455c3fd1..7c8b62f162bf 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -1682,16 +1682,6 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1682 | rc = 0; | 1682 | rc = 0; |
1683 | 1683 | ||
1684 | switch (cmd) { | 1684 | switch (cmd) { |
1685 | case TIOCGSOFTCAR: | ||
1686 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), | ||
1687 | (unsigned __user *) arg); | ||
1688 | break; | ||
1689 | case TIOCSSOFTCAR: | ||
1690 | if ((rc = get_user(ival, (unsigned __user *) arg)) == 0) | ||
1691 | tty->termios->c_cflag = | ||
1692 | (tty->termios->c_cflag & ~CLOCAL) | | ||
1693 | (ival ? CLOCAL : 0); | ||
1694 | break; | ||
1695 | case TIOCGSERIAL: | 1685 | case TIOCGSERIAL: |
1696 | rc = stli_getserial(portp, argp); | 1686 | rc = stli_getserial(portp, argp); |
1697 | break; | 1687 | break; |
@@ -3267,7 +3257,7 @@ static int stli_initecp(struct stlibrd *brdp) | |||
3267 | */ | 3257 | */ |
3268 | EBRDINIT(brdp); | 3258 | EBRDINIT(brdp); |
3269 | 3259 | ||
3270 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3260 | brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); |
3271 | if (brdp->membase == NULL) { | 3261 | if (brdp->membase == NULL) { |
3272 | retval = -ENOMEM; | 3262 | retval = -ENOMEM; |
3273 | goto err_reg; | 3263 | goto err_reg; |
@@ -3424,7 +3414,7 @@ static int stli_initonb(struct stlibrd *brdp) | |||
3424 | */ | 3414 | */ |
3425 | EBRDINIT(brdp); | 3415 | EBRDINIT(brdp); |
3426 | 3416 | ||
3427 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3417 | brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); |
3428 | if (brdp->membase == NULL) { | 3418 | if (brdp->membase == NULL) { |
3429 | retval = -ENOMEM; | 3419 | retval = -ENOMEM; |
3430 | goto err_reg; | 3420 | goto err_reg; |
@@ -3675,7 +3665,7 @@ static int stli_eisamemprobe(struct stlibrd *brdp) | |||
3675 | */ | 3665 | */ |
3676 | for (i = 0; (i < stli_eisamempsize); i++) { | 3666 | for (i = 0; (i < stli_eisamempsize); i++) { |
3677 | brdp->memaddr = stli_eisamemprobeaddrs[i]; | 3667 | brdp->memaddr = stli_eisamemprobeaddrs[i]; |
3678 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3668 | brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); |
3679 | if (brdp->membase == NULL) | 3669 | if (brdp->membase == NULL) |
3680 | continue; | 3670 | continue; |
3681 | 3671 | ||
@@ -4433,6 +4423,8 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4433 | done = 0; | 4423 | done = 0; |
4434 | rc = 0; | 4424 | rc = 0; |
4435 | 4425 | ||
4426 | lock_kernel(); | ||
4427 | |||
4436 | switch (cmd) { | 4428 | switch (cmd) { |
4437 | case COM_GETPORTSTATS: | 4429 | case COM_GETPORTSTATS: |
4438 | rc = stli_getportstats(NULL, argp); | 4430 | rc = stli_getportstats(NULL, argp); |
@@ -4455,6 +4447,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4455 | done++; | 4447 | done++; |
4456 | break; | 4448 | break; |
4457 | } | 4449 | } |
4450 | unlock_kernel(); | ||
4458 | 4451 | ||
4459 | if (done) | 4452 | if (done) |
4460 | return rc; | 4453 | return rc; |
@@ -4472,6 +4465,8 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4472 | if (brdp->state == 0) | 4465 | if (brdp->state == 0) |
4473 | return -ENODEV; | 4466 | return -ENODEV; |
4474 | 4467 | ||
4468 | lock_kernel(); | ||
4469 | |||
4475 | switch (cmd) { | 4470 | switch (cmd) { |
4476 | case STL_BINTR: | 4471 | case STL_BINTR: |
4477 | EBRDINTR(brdp); | 4472 | EBRDINTR(brdp); |
@@ -4494,6 +4489,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4494 | rc = -ENOIOCTLCMD; | 4489 | rc = -ENOIOCTLCMD; |
4495 | break; | 4490 | break; |
4496 | } | 4491 | } |
4492 | unlock_kernel(); | ||
4497 | return rc; | 4493 | return rc; |
4498 | } | 4494 | } |
4499 | 4495 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 60b934adea65..7f7e798c1384 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -110,6 +110,7 @@ const int max_vals[] = { | |||
110 | const int NR_TYPES = ARRAY_SIZE(max_vals); | 110 | const int NR_TYPES = ARRAY_SIZE(max_vals); |
111 | 111 | ||
112 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | 112 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; |
113 | EXPORT_SYMBOL_GPL(kbd_table); | ||
113 | static struct kbd_struct *kbd = kbd_table; | 114 | static struct kbd_struct *kbd = kbd_table; |
114 | 115 | ||
115 | struct vt_spawn_console vt_spawn_con = { | 116 | struct vt_spawn_console vt_spawn_con = { |
@@ -260,6 +261,7 @@ void kd_mksound(unsigned int hz, unsigned int ticks) | |||
260 | } else | 261 | } else |
261 | kd_nosound(0); | 262 | kd_nosound(0); |
262 | } | 263 | } |
264 | EXPORT_SYMBOL(kd_mksound); | ||
263 | 265 | ||
264 | /* | 266 | /* |
265 | * Setting the keyboard rate. | 267 | * Setting the keyboard rate. |
@@ -1230,7 +1232,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1230 | 1232 | ||
1231 | if (rep && | 1233 | if (rep && |
1232 | (!vc_kbd_mode(kbd, VC_REPEAT) || | 1234 | (!vc_kbd_mode(kbd, VC_REPEAT) || |
1233 | (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) { | 1235 | (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) { |
1234 | /* | 1236 | /* |
1235 | * Don't repeat a key if the input buffers are not empty and the | 1237 | * Don't repeat a key if the input buffers are not empty and the |
1236 | * characters get aren't echoed locally. This makes key repeat | 1238 | * characters get aren't echoed locally. This makes key repeat |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index e83623ead441..934ffafedaea 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -364,6 +364,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
364 | return 0; | 364 | return 0; |
365 | } | 365 | } |
366 | 366 | ||
367 | #ifdef CONFIG_DEVKMEM | ||
367 | static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | 368 | static int mmap_kmem(struct file * file, struct vm_area_struct * vma) |
368 | { | 369 | { |
369 | unsigned long pfn; | 370 | unsigned long pfn; |
@@ -384,6 +385,7 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | |||
384 | vma->vm_pgoff = pfn; | 385 | vma->vm_pgoff = pfn; |
385 | return mmap_mem(file, vma); | 386 | return mmap_mem(file, vma); |
386 | } | 387 | } |
388 | #endif | ||
387 | 389 | ||
388 | #ifdef CONFIG_CRASH_DUMP | 390 | #ifdef CONFIG_CRASH_DUMP |
389 | /* | 391 | /* |
@@ -422,6 +424,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf, | |||
422 | extern long vread(char *buf, char *addr, unsigned long count); | 424 | extern long vread(char *buf, char *addr, unsigned long count); |
423 | extern long vwrite(char *buf, char *addr, unsigned long count); | 425 | extern long vwrite(char *buf, char *addr, unsigned long count); |
424 | 426 | ||
427 | #ifdef CONFIG_DEVKMEM | ||
425 | /* | 428 | /* |
426 | * This function reads the *virtual* memory as seen by the kernel. | 429 | * This function reads the *virtual* memory as seen by the kernel. |
427 | */ | 430 | */ |
@@ -626,6 +629,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
626 | *ppos = p; | 629 | *ppos = p; |
627 | return virtr + wrote; | 630 | return virtr + wrote; |
628 | } | 631 | } |
632 | #endif | ||
629 | 633 | ||
630 | #ifdef CONFIG_DEVPORT | 634 | #ifdef CONFIG_DEVPORT |
631 | static ssize_t read_port(struct file * file, char __user * buf, | 635 | static ssize_t read_port(struct file * file, char __user * buf, |
@@ -803,6 +807,7 @@ static const struct file_operations mem_fops = { | |||
803 | .get_unmapped_area = get_unmapped_area_mem, | 807 | .get_unmapped_area = get_unmapped_area_mem, |
804 | }; | 808 | }; |
805 | 809 | ||
810 | #ifdef CONFIG_DEVKMEM | ||
806 | static const struct file_operations kmem_fops = { | 811 | static const struct file_operations kmem_fops = { |
807 | .llseek = memory_lseek, | 812 | .llseek = memory_lseek, |
808 | .read = read_kmem, | 813 | .read = read_kmem, |
@@ -811,6 +816,7 @@ static const struct file_operations kmem_fops = { | |||
811 | .open = open_kmem, | 816 | .open = open_kmem, |
812 | .get_unmapped_area = get_unmapped_area_mem, | 817 | .get_unmapped_area = get_unmapped_area_mem, |
813 | }; | 818 | }; |
819 | #endif | ||
814 | 820 | ||
815 | static const struct file_operations null_fops = { | 821 | static const struct file_operations null_fops = { |
816 | .llseek = null_lseek, | 822 | .llseek = null_lseek, |
@@ -889,11 +895,13 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
889 | filp->f_mapping->backing_dev_info = | 895 | filp->f_mapping->backing_dev_info = |
890 | &directly_mappable_cdev_bdi; | 896 | &directly_mappable_cdev_bdi; |
891 | break; | 897 | break; |
898 | #ifdef CONFIG_DEVKMEM | ||
892 | case 2: | 899 | case 2: |
893 | filp->f_op = &kmem_fops; | 900 | filp->f_op = &kmem_fops; |
894 | filp->f_mapping->backing_dev_info = | 901 | filp->f_mapping->backing_dev_info = |
895 | &directly_mappable_cdev_bdi; | 902 | &directly_mappable_cdev_bdi; |
896 | break; | 903 | break; |
904 | #endif | ||
897 | case 3: | 905 | case 3: |
898 | filp->f_op = &null_fops; | 906 | filp->f_op = &null_fops; |
899 | break; | 907 | break; |
@@ -942,7 +950,9 @@ static const struct { | |||
942 | const struct file_operations *fops; | 950 | const struct file_operations *fops; |
943 | } devlist[] = { /* list of minor devices */ | 951 | } devlist[] = { /* list of minor devices */ |
944 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, | 952 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, |
953 | #ifdef CONFIG_DEVKMEM | ||
945 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, | 954 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, |
955 | #endif | ||
946 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, | 956 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, |
947 | #ifdef CONFIG_DEVPORT | 957 | #ifdef CONFIG_DEVPORT |
948 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, | 958 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 4d058dadbfcc..eaace0db0ff4 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -263,23 +263,26 @@ EXPORT_SYMBOL(misc_deregister); | |||
263 | 263 | ||
264 | static int __init misc_init(void) | 264 | static int __init misc_init(void) |
265 | { | 265 | { |
266 | #ifdef CONFIG_PROC_FS | 266 | int err; |
267 | struct proc_dir_entry *ent; | ||
268 | 267 | ||
269 | ent = create_proc_entry("misc", 0, NULL); | 268 | #ifdef CONFIG_PROC_FS |
270 | if (ent) | 269 | proc_create("misc", 0, NULL, &misc_proc_fops); |
271 | ent->proc_fops = &misc_proc_fops; | ||
272 | #endif | 270 | #endif |
273 | misc_class = class_create(THIS_MODULE, "misc"); | 271 | misc_class = class_create(THIS_MODULE, "misc"); |
272 | err = PTR_ERR(misc_class); | ||
274 | if (IS_ERR(misc_class)) | 273 | if (IS_ERR(misc_class)) |
275 | return PTR_ERR(misc_class); | 274 | goto fail_remove; |
276 | 275 | ||
277 | if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { | 276 | err = -EIO; |
278 | printk("unable to get major %d for misc devices\n", | 277 | if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) |
279 | MISC_MAJOR); | 278 | goto fail_printk; |
280 | class_destroy(misc_class); | ||
281 | return -EIO; | ||
282 | } | ||
283 | return 0; | 279 | return 0; |
280 | |||
281 | fail_printk: | ||
282 | printk("unable to get major %d for misc devices\n", MISC_MAJOR); | ||
283 | class_destroy(misc_class); | ||
284 | fail_remove: | ||
285 | remove_proc_entry("misc", NULL); | ||
286 | return err; | ||
284 | } | 287 | } |
285 | subsys_initcall(misc_init); | 288 | subsys_initcall(misc_init); |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index e60a74c66e3d..192961fd7173 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/miscdevice.h> | 30 | #include <linux/miscdevice.h> |
31 | #include <linux/posix-timers.h> | 31 | #include <linux/posix-timers.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/time.h> | ||
34 | #include <linux/math64.h> | ||
33 | 35 | ||
34 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
35 | #include <asm/sn/addrs.h> | 37 | #include <asm/sn/addrs.h> |
@@ -74,9 +76,8 @@ static const struct file_operations mmtimer_fops = { | |||
74 | * We only have comparison registers RTC1-4 currently available per | 76 | * We only have comparison registers RTC1-4 currently available per |
75 | * node. RTC0 is used by SAL. | 77 | * node. RTC0 is used by SAL. |
76 | */ | 78 | */ |
77 | #define NUM_COMPARATORS 3 | ||
78 | /* Check for an RTC interrupt pending */ | 79 | /* Check for an RTC interrupt pending */ |
79 | static int inline mmtimer_int_pending(int comparator) | 80 | static int mmtimer_int_pending(int comparator) |
80 | { | 81 | { |
81 | if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & | 82 | if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & |
82 | SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator) | 83 | SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator) |
@@ -84,15 +85,16 @@ static int inline mmtimer_int_pending(int comparator) | |||
84 | else | 85 | else |
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
88 | |||
87 | /* Clear the RTC interrupt pending bit */ | 89 | /* Clear the RTC interrupt pending bit */ |
88 | static void inline mmtimer_clr_int_pending(int comparator) | 90 | static void mmtimer_clr_int_pending(int comparator) |
89 | { | 91 | { |
90 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), | 92 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), |
91 | SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator); | 93 | SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator); |
92 | } | 94 | } |
93 | 95 | ||
94 | /* Setup timer on comparator RTC1 */ | 96 | /* Setup timer on comparator RTC1 */ |
95 | static void inline mmtimer_setup_int_0(u64 expires) | 97 | static void mmtimer_setup_int_0(int cpu, u64 expires) |
96 | { | 98 | { |
97 | u64 val; | 99 | u64 val; |
98 | 100 | ||
@@ -106,7 +108,7 @@ static void inline mmtimer_setup_int_0(u64 expires) | |||
106 | mmtimer_clr_int_pending(0); | 108 | mmtimer_clr_int_pending(0); |
107 | 109 | ||
108 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC1_INT_CONFIG_IDX_SHFT) | | 110 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC1_INT_CONFIG_IDX_SHFT) | |
109 | ((u64)cpu_physical_id(smp_processor_id()) << | 111 | ((u64)cpu_physical_id(cpu) << |
110 | SH_RTC1_INT_CONFIG_PID_SHFT); | 112 | SH_RTC1_INT_CONFIG_PID_SHFT); |
111 | 113 | ||
112 | /* Set configuration */ | 114 | /* Set configuration */ |
@@ -122,7 +124,7 @@ static void inline mmtimer_setup_int_0(u64 expires) | |||
122 | } | 124 | } |
123 | 125 | ||
124 | /* Setup timer on comparator RTC2 */ | 126 | /* Setup timer on comparator RTC2 */ |
125 | static void inline mmtimer_setup_int_1(u64 expires) | 127 | static void mmtimer_setup_int_1(int cpu, u64 expires) |
126 | { | 128 | { |
127 | u64 val; | 129 | u64 val; |
128 | 130 | ||
@@ -133,7 +135,7 @@ static void inline mmtimer_setup_int_1(u64 expires) | |||
133 | mmtimer_clr_int_pending(1); | 135 | mmtimer_clr_int_pending(1); |
134 | 136 | ||
135 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC2_INT_CONFIG_IDX_SHFT) | | 137 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC2_INT_CONFIG_IDX_SHFT) | |
136 | ((u64)cpu_physical_id(smp_processor_id()) << | 138 | ((u64)cpu_physical_id(cpu) << |
137 | SH_RTC2_INT_CONFIG_PID_SHFT); | 139 | SH_RTC2_INT_CONFIG_PID_SHFT); |
138 | 140 | ||
139 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_CONFIG), val); | 141 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_CONFIG), val); |
@@ -144,7 +146,7 @@ static void inline mmtimer_setup_int_1(u64 expires) | |||
144 | } | 146 | } |
145 | 147 | ||
146 | /* Setup timer on comparator RTC3 */ | 148 | /* Setup timer on comparator RTC3 */ |
147 | static void inline mmtimer_setup_int_2(u64 expires) | 149 | static void mmtimer_setup_int_2(int cpu, u64 expires) |
148 | { | 150 | { |
149 | u64 val; | 151 | u64 val; |
150 | 152 | ||
@@ -155,7 +157,7 @@ static void inline mmtimer_setup_int_2(u64 expires) | |||
155 | mmtimer_clr_int_pending(2); | 157 | mmtimer_clr_int_pending(2); |
156 | 158 | ||
157 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC3_INT_CONFIG_IDX_SHFT) | | 159 | val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC3_INT_CONFIG_IDX_SHFT) | |
158 | ((u64)cpu_physical_id(smp_processor_id()) << | 160 | ((u64)cpu_physical_id(cpu) << |
159 | SH_RTC3_INT_CONFIG_PID_SHFT); | 161 | SH_RTC3_INT_CONFIG_PID_SHFT); |
160 | 162 | ||
161 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_CONFIG), val); | 163 | HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_CONFIG), val); |
@@ -170,22 +172,22 @@ static void inline mmtimer_setup_int_2(u64 expires) | |||
170 | * in order to insure that the setup succeeds in a deterministic time frame. | 172 | * in order to insure that the setup succeeds in a deterministic time frame. |
171 | * It will check if the interrupt setup succeeded. | 173 | * It will check if the interrupt setup succeeded. |
172 | */ | 174 | */ |
173 | static int inline mmtimer_setup(int comparator, unsigned long expires) | 175 | static int mmtimer_setup(int cpu, int comparator, unsigned long expires) |
174 | { | 176 | { |
175 | 177 | ||
176 | switch (comparator) { | 178 | switch (comparator) { |
177 | case 0: | 179 | case 0: |
178 | mmtimer_setup_int_0(expires); | 180 | mmtimer_setup_int_0(cpu, expires); |
179 | break; | 181 | break; |
180 | case 1: | 182 | case 1: |
181 | mmtimer_setup_int_1(expires); | 183 | mmtimer_setup_int_1(cpu, expires); |
182 | break; | 184 | break; |
183 | case 2: | 185 | case 2: |
184 | mmtimer_setup_int_2(expires); | 186 | mmtimer_setup_int_2(cpu, expires); |
185 | break; | 187 | break; |
186 | } | 188 | } |
187 | /* We might've missed our expiration time */ | 189 | /* We might've missed our expiration time */ |
188 | if (rtc_time() < expires) | 190 | if (rtc_time() <= expires) |
189 | return 1; | 191 | return 1; |
190 | 192 | ||
191 | /* | 193 | /* |
@@ -195,7 +197,7 @@ static int inline mmtimer_setup(int comparator, unsigned long expires) | |||
195 | return mmtimer_int_pending(comparator); | 197 | return mmtimer_int_pending(comparator); |
196 | } | 198 | } |
197 | 199 | ||
198 | static int inline mmtimer_disable_int(long nasid, int comparator) | 200 | static int mmtimer_disable_int(long nasid, int comparator) |
199 | { | 201 | { |
200 | switch (comparator) { | 202 | switch (comparator) { |
201 | case 0: | 203 | case 0: |
@@ -216,18 +218,124 @@ static int inline mmtimer_disable_int(long nasid, int comparator) | |||
216 | return 0; | 218 | return 0; |
217 | } | 219 | } |
218 | 220 | ||
219 | #define TIMER_OFF 0xbadcabLL | 221 | #define COMPARATOR 1 /* The comparator to use */ |
220 | 222 | ||
221 | /* There is one of these for each comparator */ | 223 | #define TIMER_OFF 0xbadcabLL /* Timer is not setup */ |
222 | typedef struct mmtimer { | 224 | #define TIMER_SET 0 /* Comparator is set for this timer */ |
223 | spinlock_t lock ____cacheline_aligned; | 225 | |
226 | /* There is one of these for each timer */ | ||
227 | struct mmtimer { | ||
228 | struct rb_node list; | ||
224 | struct k_itimer *timer; | 229 | struct k_itimer *timer; |
225 | int i; | ||
226 | int cpu; | 230 | int cpu; |
231 | }; | ||
232 | |||
233 | struct mmtimer_node { | ||
234 | spinlock_t lock ____cacheline_aligned; | ||
235 | struct rb_root timer_head; | ||
236 | struct rb_node *next; | ||
227 | struct tasklet_struct tasklet; | 237 | struct tasklet_struct tasklet; |
228 | } mmtimer_t; | 238 | }; |
239 | static struct mmtimer_node *timers; | ||
240 | |||
241 | |||
242 | /* | ||
243 | * Add a new mmtimer struct to the node's mmtimer list. | ||
244 | * This function assumes the struct mmtimer_node is locked. | ||
245 | */ | ||
246 | static void mmtimer_add_list(struct mmtimer *n) | ||
247 | { | ||
248 | int nodeid = n->timer->it.mmtimer.node; | ||
249 | unsigned long expires = n->timer->it.mmtimer.expires; | ||
250 | struct rb_node **link = &timers[nodeid].timer_head.rb_node; | ||
251 | struct rb_node *parent = NULL; | ||
252 | struct mmtimer *x; | ||
253 | |||
254 | /* | ||
255 | * Find the right place in the rbtree: | ||
256 | */ | ||
257 | while (*link) { | ||
258 | parent = *link; | ||
259 | x = rb_entry(parent, struct mmtimer, list); | ||
260 | |||
261 | if (expires < x->timer->it.mmtimer.expires) | ||
262 | link = &(*link)->rb_left; | ||
263 | else | ||
264 | link = &(*link)->rb_right; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Insert the timer to the rbtree and check whether it | ||
269 | * replaces the first pending timer | ||
270 | */ | ||
271 | rb_link_node(&n->list, parent, link); | ||
272 | rb_insert_color(&n->list, &timers[nodeid].timer_head); | ||
273 | |||
274 | if (!timers[nodeid].next || expires < rb_entry(timers[nodeid].next, | ||
275 | struct mmtimer, list)->timer->it.mmtimer.expires) | ||
276 | timers[nodeid].next = &n->list; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Set the comparator for the next timer. | ||
281 | * This function assumes the struct mmtimer_node is locked. | ||
282 | */ | ||
283 | static void mmtimer_set_next_timer(int nodeid) | ||
284 | { | ||
285 | struct mmtimer_node *n = &timers[nodeid]; | ||
286 | struct mmtimer *x; | ||
287 | struct k_itimer *t; | ||
288 | int o; | ||
289 | |||
290 | restart: | ||
291 | if (n->next == NULL) | ||
292 | return; | ||
229 | 293 | ||
230 | static mmtimer_t ** timers; | 294 | x = rb_entry(n->next, struct mmtimer, list); |
295 | t = x->timer; | ||
296 | if (!t->it.mmtimer.incr) { | ||
297 | /* Not an interval timer */ | ||
298 | if (!mmtimer_setup(x->cpu, COMPARATOR, | ||
299 | t->it.mmtimer.expires)) { | ||
300 | /* Late setup, fire now */ | ||
301 | tasklet_schedule(&n->tasklet); | ||
302 | } | ||
303 | return; | ||
304 | } | ||
305 | |||
306 | /* Interval timer */ | ||
307 | o = 0; | ||
308 | while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) { | ||
309 | unsigned long e, e1; | ||
310 | struct rb_node *next; | ||
311 | t->it.mmtimer.expires += t->it.mmtimer.incr << o; | ||
312 | t->it_overrun += 1 << o; | ||
313 | o++; | ||
314 | if (o > 20) { | ||
315 | printk(KERN_ALERT "mmtimer: cannot reschedule timer\n"); | ||
316 | t->it.mmtimer.clock = TIMER_OFF; | ||
317 | n->next = rb_next(&x->list); | ||
318 | rb_erase(&x->list, &n->timer_head); | ||
319 | kfree(x); | ||
320 | goto restart; | ||
321 | } | ||
322 | |||
323 | e = t->it.mmtimer.expires; | ||
324 | next = rb_next(&x->list); | ||
325 | |||
326 | if (next == NULL) | ||
327 | continue; | ||
328 | |||
329 | e1 = rb_entry(next, struct mmtimer, list)-> | ||
330 | timer->it.mmtimer.expires; | ||
331 | if (e > e1) { | ||
332 | n->next = next; | ||
333 | rb_erase(&x->list, &n->timer_head); | ||
334 | mmtimer_add_list(x); | ||
335 | goto restart; | ||
336 | } | ||
337 | } | ||
338 | } | ||
231 | 339 | ||
232 | /** | 340 | /** |
233 | * mmtimer_ioctl - ioctl interface for /dev/mmtimer | 341 | * mmtimer_ioctl - ioctl interface for /dev/mmtimer |
@@ -366,8 +474,8 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp) | |||
366 | 474 | ||
367 | nsec = rtc_time() * sgi_clock_period | 475 | nsec = rtc_time() * sgi_clock_period |
368 | + sgi_clock_offset.tv_nsec; | 476 | + sgi_clock_offset.tv_nsec; |
369 | tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec) | 477 | *tp = ns_to_timespec(nsec); |
370 | + sgi_clock_offset.tv_sec; | 478 | tp->tv_sec += sgi_clock_offset.tv_sec; |
371 | return 0; | 479 | return 0; |
372 | }; | 480 | }; |
373 | 481 | ||
@@ -375,11 +483,11 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp) | |||
375 | { | 483 | { |
376 | 484 | ||
377 | u64 nsec; | 485 | u64 nsec; |
378 | u64 rem; | 486 | u32 rem; |
379 | 487 | ||
380 | nsec = rtc_time() * sgi_clock_period; | 488 | nsec = rtc_time() * sgi_clock_period; |
381 | 489 | ||
382 | sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem); | 490 | sgi_clock_offset.tv_sec = tp->tv_sec - div_u64_rem(nsec, NSEC_PER_SEC, &rem); |
383 | 491 | ||
384 | if (rem <= tp->tv_nsec) | 492 | if (rem <= tp->tv_nsec) |
385 | sgi_clock_offset.tv_nsec = tp->tv_sec - rem; | 493 | sgi_clock_offset.tv_nsec = tp->tv_sec - rem; |
@@ -390,35 +498,6 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp) | |||
390 | return 0; | 498 | return 0; |
391 | } | 499 | } |
392 | 500 | ||
393 | /* | ||
394 | * Schedule the next periodic interrupt. This function will attempt | ||
395 | * to schedule a periodic interrupt later if necessary. If the scheduling | ||
396 | * of an interrupt fails then the time to skip is lengthened | ||
397 | * exponentially in order to ensure that the next interrupt | ||
398 | * can be properly scheduled.. | ||
399 | */ | ||
400 | static int inline reschedule_periodic_timer(mmtimer_t *x) | ||
401 | { | ||
402 | int n; | ||
403 | struct k_itimer *t = x->timer; | ||
404 | |||
405 | t->it.mmtimer.clock = x->i; | ||
406 | t->it_overrun--; | ||
407 | |||
408 | n = 0; | ||
409 | do { | ||
410 | |||
411 | t->it.mmtimer.expires += t->it.mmtimer.incr << n; | ||
412 | t->it_overrun += 1 << n; | ||
413 | n++; | ||
414 | if (n > 20) | ||
415 | return 1; | ||
416 | |||
417 | } while (!mmtimer_setup(x->i, t->it.mmtimer.expires)); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | /** | 501 | /** |
423 | * mmtimer_interrupt - timer interrupt handler | 502 | * mmtimer_interrupt - timer interrupt handler |
424 | * @irq: irq received | 503 | * @irq: irq received |
@@ -435,71 +514,75 @@ static int inline reschedule_periodic_timer(mmtimer_t *x) | |||
435 | static irqreturn_t | 514 | static irqreturn_t |
436 | mmtimer_interrupt(int irq, void *dev_id) | 515 | mmtimer_interrupt(int irq, void *dev_id) |
437 | { | 516 | { |
438 | int i; | ||
439 | unsigned long expires = 0; | 517 | unsigned long expires = 0; |
440 | int result = IRQ_NONE; | 518 | int result = IRQ_NONE; |
441 | unsigned indx = cpu_to_node(smp_processor_id()); | 519 | unsigned indx = cpu_to_node(smp_processor_id()); |
520 | struct mmtimer *base; | ||
442 | 521 | ||
443 | /* | 522 | spin_lock(&timers[indx].lock); |
444 | * Do this once for each comparison register | 523 | base = rb_entry(timers[indx].next, struct mmtimer, list); |
445 | */ | 524 | if (base == NULL) { |
446 | for (i = 0; i < NUM_COMPARATORS; i++) { | 525 | spin_unlock(&timers[indx].lock); |
447 | mmtimer_t *base = timers[indx] + i; | 526 | return result; |
448 | /* Make sure this doesn't get reused before tasklet_sched */ | 527 | } |
449 | spin_lock(&base->lock); | 528 | |
450 | if (base->cpu == smp_processor_id()) { | 529 | if (base->cpu == smp_processor_id()) { |
451 | if (base->timer) | 530 | if (base->timer) |
452 | expires = base->timer->it.mmtimer.expires; | 531 | expires = base->timer->it.mmtimer.expires; |
453 | /* expires test won't work with shared irqs */ | 532 | /* expires test won't work with shared irqs */ |
454 | if ((mmtimer_int_pending(i) > 0) || | 533 | if ((mmtimer_int_pending(COMPARATOR) > 0) || |
455 | (expires && (expires < rtc_time()))) { | 534 | (expires && (expires <= rtc_time()))) { |
456 | mmtimer_clr_int_pending(i); | 535 | mmtimer_clr_int_pending(COMPARATOR); |
457 | tasklet_schedule(&base->tasklet); | 536 | tasklet_schedule(&timers[indx].tasklet); |
458 | result = IRQ_HANDLED; | 537 | result = IRQ_HANDLED; |
459 | } | ||
460 | } | 538 | } |
461 | spin_unlock(&base->lock); | ||
462 | expires = 0; | ||
463 | } | 539 | } |
540 | spin_unlock(&timers[indx].lock); | ||
464 | return result; | 541 | return result; |
465 | } | 542 | } |
466 | 543 | ||
467 | void mmtimer_tasklet(unsigned long data) { | 544 | static void mmtimer_tasklet(unsigned long data) |
468 | mmtimer_t *x = (mmtimer_t *)data; | 545 | { |
469 | struct k_itimer *t = x->timer; | 546 | int nodeid = data; |
547 | struct mmtimer_node *mn = &timers[nodeid]; | ||
548 | struct mmtimer *x = rb_entry(mn->next, struct mmtimer, list); | ||
549 | struct k_itimer *t; | ||
470 | unsigned long flags; | 550 | unsigned long flags; |
471 | 551 | ||
472 | if (t == NULL) | ||
473 | return; | ||
474 | |||
475 | /* Send signal and deal with periodic signals */ | 552 | /* Send signal and deal with periodic signals */ |
476 | spin_lock_irqsave(&t->it_lock, flags); | 553 | spin_lock_irqsave(&mn->lock, flags); |
477 | spin_lock(&x->lock); | 554 | if (!mn->next) |
478 | /* If timer was deleted between interrupt and here, leave */ | ||
479 | if (t != x->timer) | ||
480 | goto out; | 555 | goto out; |
481 | t->it_overrun = 0; | ||
482 | 556 | ||
483 | if (posix_timer_event(t, 0) != 0) { | 557 | x = rb_entry(mn->next, struct mmtimer, list); |
558 | t = x->timer; | ||
559 | |||
560 | if (t->it.mmtimer.clock == TIMER_OFF) | ||
561 | goto out; | ||
562 | |||
563 | t->it_overrun = 0; | ||
484 | 564 | ||
485 | // printk(KERN_WARNING "mmtimer: cannot deliver signal.\n"); | 565 | mn->next = rb_next(&x->list); |
566 | rb_erase(&x->list, &mn->timer_head); | ||
486 | 567 | ||
568 | if (posix_timer_event(t, 0) != 0) | ||
487 | t->it_overrun++; | 569 | t->it_overrun++; |
488 | } | 570 | |
489 | if(t->it.mmtimer.incr) { | 571 | if(t->it.mmtimer.incr) { |
490 | /* Periodic timer */ | 572 | t->it.mmtimer.expires += t->it.mmtimer.incr; |
491 | if (reschedule_periodic_timer(x)) { | 573 | mmtimer_add_list(x); |
492 | printk(KERN_WARNING "mmtimer: unable to reschedule\n"); | ||
493 | x->timer = NULL; | ||
494 | } | ||
495 | } else { | 574 | } else { |
496 | /* Ensure we don't false trigger in mmtimer_interrupt */ | 575 | /* Ensure we don't false trigger in mmtimer_interrupt */ |
576 | t->it.mmtimer.clock = TIMER_OFF; | ||
497 | t->it.mmtimer.expires = 0; | 577 | t->it.mmtimer.expires = 0; |
578 | kfree(x); | ||
498 | } | 579 | } |
580 | /* Set comparator for next timer, if there is one */ | ||
581 | mmtimer_set_next_timer(nodeid); | ||
582 | |||
499 | t->it_overrun_last = t->it_overrun; | 583 | t->it_overrun_last = t->it_overrun; |
500 | out: | 584 | out: |
501 | spin_unlock(&x->lock); | 585 | spin_unlock_irqrestore(&mn->lock, flags); |
502 | spin_unlock_irqrestore(&t->it_lock, flags); | ||
503 | } | 586 | } |
504 | 587 | ||
505 | static int sgi_timer_create(struct k_itimer *timer) | 588 | static int sgi_timer_create(struct k_itimer *timer) |
@@ -516,25 +599,53 @@ static int sgi_timer_create(struct k_itimer *timer) | |||
516 | */ | 599 | */ |
517 | static int sgi_timer_del(struct k_itimer *timr) | 600 | static int sgi_timer_del(struct k_itimer *timr) |
518 | { | 601 | { |
519 | int i = timr->it.mmtimer.clock; | ||
520 | cnodeid_t nodeid = timr->it.mmtimer.node; | 602 | cnodeid_t nodeid = timr->it.mmtimer.node; |
521 | mmtimer_t *t = timers[nodeid] + i; | ||
522 | unsigned long irqflags; | 603 | unsigned long irqflags; |
523 | 604 | ||
524 | if (i != TIMER_OFF) { | 605 | spin_lock_irqsave(&timers[nodeid].lock, irqflags); |
525 | spin_lock_irqsave(&t->lock, irqflags); | 606 | if (timr->it.mmtimer.clock != TIMER_OFF) { |
526 | mmtimer_disable_int(cnodeid_to_nasid(nodeid),i); | 607 | unsigned long expires = timr->it.mmtimer.expires; |
527 | t->timer = NULL; | 608 | struct rb_node *n = timers[nodeid].timer_head.rb_node; |
609 | struct mmtimer *uninitialized_var(t); | ||
610 | int r = 0; | ||
611 | |||
528 | timr->it.mmtimer.clock = TIMER_OFF; | 612 | timr->it.mmtimer.clock = TIMER_OFF; |
529 | timr->it.mmtimer.expires = 0; | 613 | timr->it.mmtimer.expires = 0; |
530 | spin_unlock_irqrestore(&t->lock, irqflags); | 614 | |
615 | while (n) { | ||
616 | t = rb_entry(n, struct mmtimer, list); | ||
617 | if (t->timer == timr) | ||
618 | break; | ||
619 | |||
620 | if (expires < t->timer->it.mmtimer.expires) | ||
621 | n = n->rb_left; | ||
622 | else | ||
623 | n = n->rb_right; | ||
624 | } | ||
625 | |||
626 | if (!n) { | ||
627 | spin_unlock_irqrestore(&timers[nodeid].lock, irqflags); | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | if (timers[nodeid].next == n) { | ||
632 | timers[nodeid].next = rb_next(n); | ||
633 | r = 1; | ||
634 | } | ||
635 | |||
636 | rb_erase(n, &timers[nodeid].timer_head); | ||
637 | kfree(t); | ||
638 | |||
639 | if (r) { | ||
640 | mmtimer_disable_int(cnodeid_to_nasid(nodeid), | ||
641 | COMPARATOR); | ||
642 | mmtimer_set_next_timer(nodeid); | ||
643 | } | ||
531 | } | 644 | } |
645 | spin_unlock_irqrestore(&timers[nodeid].lock, irqflags); | ||
532 | return 0; | 646 | return 0; |
533 | } | 647 | } |
534 | 648 | ||
535 | #define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC) | ||
536 | #define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec) | ||
537 | |||
538 | /* Assumption: it_lock is already held with irq's disabled */ | 649 | /* Assumption: it_lock is already held with irq's disabled */ |
539 | static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) | 650 | static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) |
540 | { | 651 | { |
@@ -547,9 +658,8 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) | |||
547 | return; | 658 | return; |
548 | } | 659 | } |
549 | 660 | ||
550 | ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period); | 661 | cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period); |
551 | ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period); | 662 | cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); |
552 | return; | ||
553 | } | 663 | } |
554 | 664 | ||
555 | 665 | ||
@@ -557,30 +667,33 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, | |||
557 | struct itimerspec * new_setting, | 667 | struct itimerspec * new_setting, |
558 | struct itimerspec * old_setting) | 668 | struct itimerspec * old_setting) |
559 | { | 669 | { |
560 | |||
561 | int i; | ||
562 | unsigned long when, period, irqflags; | 670 | unsigned long when, period, irqflags; |
563 | int err = 0; | 671 | int err = 0; |
564 | cnodeid_t nodeid; | 672 | cnodeid_t nodeid; |
565 | mmtimer_t *base; | 673 | struct mmtimer *base; |
674 | struct rb_node *n; | ||
566 | 675 | ||
567 | if (old_setting) | 676 | if (old_setting) |
568 | sgi_timer_get(timr, old_setting); | 677 | sgi_timer_get(timr, old_setting); |
569 | 678 | ||
570 | sgi_timer_del(timr); | 679 | sgi_timer_del(timr); |
571 | when = timespec_to_ns(new_setting->it_value); | 680 | when = timespec_to_ns(&new_setting->it_value); |
572 | period = timespec_to_ns(new_setting->it_interval); | 681 | period = timespec_to_ns(&new_setting->it_interval); |
573 | 682 | ||
574 | if (when == 0) | 683 | if (when == 0) |
575 | /* Clear timer */ | 684 | /* Clear timer */ |
576 | return 0; | 685 | return 0; |
577 | 686 | ||
687 | base = kmalloc(sizeof(struct mmtimer), GFP_KERNEL); | ||
688 | if (base == NULL) | ||
689 | return -ENOMEM; | ||
690 | |||
578 | if (flags & TIMER_ABSTIME) { | 691 | if (flags & TIMER_ABSTIME) { |
579 | struct timespec n; | 692 | struct timespec n; |
580 | unsigned long now; | 693 | unsigned long now; |
581 | 694 | ||
582 | getnstimeofday(&n); | 695 | getnstimeofday(&n); |
583 | now = timespec_to_ns(n); | 696 | now = timespec_to_ns(&n); |
584 | if (when > now) | 697 | if (when > now) |
585 | when -= now; | 698 | when -= now; |
586 | else | 699 | else |
@@ -604,47 +717,38 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, | |||
604 | preempt_disable(); | 717 | preempt_disable(); |
605 | 718 | ||
606 | nodeid = cpu_to_node(smp_processor_id()); | 719 | nodeid = cpu_to_node(smp_processor_id()); |
607 | retry: | ||
608 | /* Don't use an allocated timer, or a deleted one that's pending */ | ||
609 | for(i = 0; i< NUM_COMPARATORS; i++) { | ||
610 | base = timers[nodeid] + i; | ||
611 | if (!base->timer && !base->tasklet.state) { | ||
612 | break; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | if (i == NUM_COMPARATORS) { | ||
617 | preempt_enable(); | ||
618 | return -EBUSY; | ||
619 | } | ||
620 | 720 | ||
621 | spin_lock_irqsave(&base->lock, irqflags); | 721 | /* Lock the node timer structure */ |
722 | spin_lock_irqsave(&timers[nodeid].lock, irqflags); | ||
622 | 723 | ||
623 | if (base->timer || base->tasklet.state != 0) { | ||
624 | spin_unlock_irqrestore(&base->lock, irqflags); | ||
625 | goto retry; | ||
626 | } | ||
627 | base->timer = timr; | 724 | base->timer = timr; |
628 | base->cpu = smp_processor_id(); | 725 | base->cpu = smp_processor_id(); |
629 | 726 | ||
630 | timr->it.mmtimer.clock = i; | 727 | timr->it.mmtimer.clock = TIMER_SET; |
631 | timr->it.mmtimer.node = nodeid; | 728 | timr->it.mmtimer.node = nodeid; |
632 | timr->it.mmtimer.incr = period; | 729 | timr->it.mmtimer.incr = period; |
633 | timr->it.mmtimer.expires = when; | 730 | timr->it.mmtimer.expires = when; |
634 | 731 | ||
635 | if (period == 0) { | 732 | n = timers[nodeid].next; |
636 | if (!mmtimer_setup(i, when)) { | 733 | |
637 | mmtimer_disable_int(-1, i); | 734 | /* Add the new struct mmtimer to node's timer list */ |
638 | posix_timer_event(timr, 0); | 735 | mmtimer_add_list(base); |
639 | timr->it.mmtimer.expires = 0; | 736 | |
640 | } | 737 | if (timers[nodeid].next == n) { |
641 | } else { | 738 | /* No need to reprogram comparator for now */ |
642 | timr->it.mmtimer.expires -= period; | 739 | spin_unlock_irqrestore(&timers[nodeid].lock, irqflags); |
643 | if (reschedule_periodic_timer(base)) | 740 | preempt_enable(); |
644 | err = -EINVAL; | 741 | return err; |
645 | } | 742 | } |
646 | 743 | ||
647 | spin_unlock_irqrestore(&base->lock, irqflags); | 744 | /* We need to reprogram the comparator */ |
745 | if (n) | ||
746 | mmtimer_disable_int(cnodeid_to_nasid(nodeid), COMPARATOR); | ||
747 | |||
748 | mmtimer_set_next_timer(nodeid); | ||
749 | |||
750 | /* Unlock the node timer structure */ | ||
751 | spin_unlock_irqrestore(&timers[nodeid].lock, irqflags); | ||
648 | 752 | ||
649 | preempt_enable(); | 753 | preempt_enable(); |
650 | 754 | ||
@@ -669,7 +773,6 @@ static struct k_clock sgi_clock = { | |||
669 | */ | 773 | */ |
670 | static int __init mmtimer_init(void) | 774 | static int __init mmtimer_init(void) |
671 | { | 775 | { |
672 | unsigned i; | ||
673 | cnodeid_t node, maxn = -1; | 776 | cnodeid_t node, maxn = -1; |
674 | 777 | ||
675 | if (!ia64_platform_is("sn2")) | 778 | if (!ia64_platform_is("sn2")) |
@@ -706,31 +809,18 @@ static int __init mmtimer_init(void) | |||
706 | maxn++; | 809 | maxn++; |
707 | 810 | ||
708 | /* Allocate list of node ptrs to mmtimer_t's */ | 811 | /* Allocate list of node ptrs to mmtimer_t's */ |
709 | timers = kzalloc(sizeof(mmtimer_t *)*maxn, GFP_KERNEL); | 812 | timers = kzalloc(sizeof(struct mmtimer_node)*maxn, GFP_KERNEL); |
710 | if (timers == NULL) { | 813 | if (timers == NULL) { |
711 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | 814 | printk(KERN_ERR "%s: failed to allocate memory for device\n", |
712 | MMTIMER_NAME); | 815 | MMTIMER_NAME); |
713 | goto out3; | 816 | goto out3; |
714 | } | 817 | } |
715 | 818 | ||
716 | /* Allocate mmtimer_t's for each online node */ | 819 | /* Initialize struct mmtimer's for each online node */ |
717 | for_each_online_node(node) { | 820 | for_each_online_node(node) { |
718 | timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node); | 821 | spin_lock_init(&timers[node].lock); |
719 | if (timers[node] == NULL) { | 822 | tasklet_init(&timers[node].tasklet, mmtimer_tasklet, |
720 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | 823 | (unsigned long) node); |
721 | MMTIMER_NAME); | ||
722 | goto out4; | ||
723 | } | ||
724 | for (i=0; i< NUM_COMPARATORS; i++) { | ||
725 | mmtimer_t * base = timers[node] + i; | ||
726 | |||
727 | spin_lock_init(&base->lock); | ||
728 | base->timer = NULL; | ||
729 | base->cpu = 0; | ||
730 | base->i = i; | ||
731 | tasklet_init(&base->tasklet, mmtimer_tasklet, | ||
732 | (unsigned long) (base)); | ||
733 | } | ||
734 | } | 824 | } |
735 | 825 | ||
736 | sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; | 826 | sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; |
@@ -741,11 +831,8 @@ static int __init mmtimer_init(void) | |||
741 | 831 | ||
742 | return 0; | 832 | return 0; |
743 | 833 | ||
744 | out4: | ||
745 | for_each_online_node(node) { | ||
746 | kfree(timers[node]); | ||
747 | } | ||
748 | out3: | 834 | out3: |
835 | kfree(timers); | ||
749 | misc_deregister(&mmtimer_miscdev); | 836 | misc_deregister(&mmtimer_miscdev); |
750 | out2: | 837 | out2: |
751 | free_irq(SGI_MMTIMER_VECTOR, NULL); | 838 | free_irq(SGI_MMTIMER_VECTOR, NULL); |
@@ -754,4 +841,3 @@ out1: | |||
754 | } | 841 | } |
755 | 842 | ||
756 | module_init(mmtimer_init); | 843 | module_init(mmtimer_init); |
757 | |||
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 64b7b2b18352..d57d3a61919b 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -2,7 +2,8 @@ | |||
2 | /* | 2 | /* |
3 | * moxa.c -- MOXA Intellio family multiport serial driver. | 3 | * moxa.c -- MOXA Intellio family multiport serial driver. |
4 | * | 4 | * |
5 | * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com.tw). | 5 | * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com). |
6 | * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> | ||
6 | * | 7 | * |
7 | * This code is loosely based on the Linux serial driver, written by | 8 | * This code is loosely based on the Linux serial driver, written by |
8 | * Linus Torvalds, Theodore T'so and others. | 9 | * Linus Torvalds, Theodore T'so and others. |
@@ -25,6 +26,7 @@ | |||
25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
26 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/firmware.h> | ||
28 | #include <linux/signal.h> | 30 | #include <linux/signal.h> |
29 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
30 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
@@ -41,21 +43,26 @@ | |||
41 | #include <linux/pci.h> | 43 | #include <linux/pci.h> |
42 | #include <linux/init.h> | 44 | #include <linux/init.h> |
43 | #include <linux/bitops.h> | 45 | #include <linux/bitops.h> |
44 | #include <linux/completion.h> | ||
45 | 46 | ||
46 | #include <asm/system.h> | 47 | #include <asm/system.h> |
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
49 | 50 | ||
50 | #define MOXA_VERSION "5.1k" | 51 | #include "moxa.h" |
52 | |||
53 | #define MOXA_VERSION "6.0k" | ||
54 | |||
55 | #define MOXA_FW_HDRLEN 32 | ||
51 | 56 | ||
52 | #define MOXAMAJOR 172 | 57 | #define MOXAMAJOR 172 |
53 | #define MOXACUMAJOR 173 | ||
54 | 58 | ||
55 | #define MAX_BOARDS 4 /* Don't change this value */ | 59 | #define MAX_BOARDS 4 /* Don't change this value */ |
56 | #define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ | 60 | #define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ |
57 | #define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD) | 61 | #define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD) |
58 | 62 | ||
63 | #define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \ | ||
64 | (brd)->boardType == MOXA_BOARD_C320_PCI) | ||
65 | |||
59 | /* | 66 | /* |
60 | * Define the Moxa PCI vendor and device IDs. | 67 | * Define the Moxa PCI vendor and device IDs. |
61 | */ | 68 | */ |
@@ -92,24 +99,16 @@ static struct pci_device_id moxa_pcibrds[] = { | |||
92 | MODULE_DEVICE_TABLE(pci, moxa_pcibrds); | 99 | MODULE_DEVICE_TABLE(pci, moxa_pcibrds); |
93 | #endif /* CONFIG_PCI */ | 100 | #endif /* CONFIG_PCI */ |
94 | 101 | ||
95 | struct moxa_isa_board_conf { | 102 | struct moxa_port; |
96 | int boardType; | ||
97 | int numPorts; | ||
98 | unsigned long baseAddr; | ||
99 | }; | ||
100 | |||
101 | static struct moxa_isa_board_conf moxa_isa_boards[] = | ||
102 | { | ||
103 | /* {MOXA_BOARD_C218_ISA,8,0xDC000}, */ | ||
104 | }; | ||
105 | 103 | ||
106 | static struct moxa_board_conf { | 104 | static struct moxa_board_conf { |
107 | int boardType; | 105 | int boardType; |
108 | int numPorts; | 106 | int numPorts; |
109 | unsigned long baseAddr; | ||
110 | int busType; | 107 | int busType; |
111 | 108 | ||
112 | int loadstat; | 109 | unsigned int ready; |
110 | |||
111 | struct moxa_port *ports; | ||
113 | 112 | ||
114 | void __iomem *basemem; | 113 | void __iomem *basemem; |
115 | void __iomem *intNdx; | 114 | void __iomem *intNdx; |
@@ -131,30 +130,27 @@ struct moxaq_str { | |||
131 | }; | 130 | }; |
132 | 131 | ||
133 | struct moxa_port { | 132 | struct moxa_port { |
133 | struct moxa_board_conf *board; | ||
134 | struct tty_struct *tty; | ||
135 | void __iomem *tableAddr; | ||
136 | |||
134 | int type; | 137 | int type; |
135 | int port; | ||
136 | int close_delay; | 138 | int close_delay; |
137 | unsigned short closing_wait; | 139 | unsigned int count; |
138 | int count; | ||
139 | int blocked_open; | ||
140 | long event; /* long req'd for set_bit --RR */ | ||
141 | int asyncflags; | 140 | int asyncflags; |
142 | unsigned long statusflags; | ||
143 | struct tty_struct *tty; | ||
144 | int cflag; | 141 | int cflag; |
142 | unsigned long statusflags; | ||
145 | wait_queue_head_t open_wait; | 143 | wait_queue_head_t open_wait; |
146 | struct completion close_wait; | ||
147 | |||
148 | struct timer_list emptyTimer; | ||
149 | 144 | ||
150 | char chkPort; | 145 | u8 DCDState; |
151 | char lineCtrl; | 146 | u8 lineCtrl; |
152 | void __iomem *tableAddr; | 147 | u8 lowChkFlag; |
153 | long curBaud; | 148 | }; |
154 | char DCDState; | ||
155 | char lowChkFlag; | ||
156 | 149 | ||
157 | ushort breakCnt; | 150 | struct mon_str { |
151 | int tick; | ||
152 | int rxcnt[MAX_PORTS]; | ||
153 | int txcnt[MAX_PORTS]; | ||
158 | }; | 154 | }; |
159 | 155 | ||
160 | /* statusflags */ | 156 | /* statusflags */ |
@@ -168,20 +164,27 @@ struct moxa_port { | |||
168 | #define WAKEUP_CHARS 256 | 164 | #define WAKEUP_CHARS 256 |
169 | 165 | ||
170 | static int ttymajor = MOXAMAJOR; | 166 | static int ttymajor = MOXAMAJOR; |
167 | static struct mon_str moxaLog; | ||
168 | static unsigned int moxaFuncTout = HZ / 2; | ||
169 | static unsigned int moxaLowWaterChk; | ||
170 | static DEFINE_MUTEX(moxa_openlock); | ||
171 | /* Variables for insmod */ | 171 | /* Variables for insmod */ |
172 | #ifdef MODULE | 172 | #ifdef MODULE |
173 | static int baseaddr[4]; | 173 | static unsigned long baseaddr[MAX_BOARDS]; |
174 | static int type[4]; | 174 | static unsigned int type[MAX_BOARDS]; |
175 | static int numports[4]; | 175 | static unsigned int numports[MAX_BOARDS]; |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | MODULE_AUTHOR("William Chen"); | 178 | MODULE_AUTHOR("William Chen"); |
179 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); | 179 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); |
180 | MODULE_LICENSE("GPL"); | 180 | MODULE_LICENSE("GPL"); |
181 | #ifdef MODULE | 181 | #ifdef MODULE |
182 | module_param_array(type, int, NULL, 0); | 182 | module_param_array(type, uint, NULL, 0); |
183 | module_param_array(baseaddr, int, NULL, 0); | 183 | MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); |
184 | module_param_array(numports, int, NULL, 0); | 184 | module_param_array(baseaddr, ulong, NULL, 0); |
185 | MODULE_PARM_DESC(baseaddr, "base address"); | ||
186 | module_param_array(numports, uint, NULL, 0); | ||
187 | MODULE_PARM_DESC(numports, "numports (ignored for C218)"); | ||
185 | #endif | 188 | #endif |
186 | module_param(ttymajor, int, 0); | 189 | module_param(ttymajor, int, 0); |
187 | 190 | ||
@@ -194,9 +197,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int); | |||
194 | static int moxa_write_room(struct tty_struct *); | 197 | static int moxa_write_room(struct tty_struct *); |
195 | static void moxa_flush_buffer(struct tty_struct *); | 198 | static void moxa_flush_buffer(struct tty_struct *); |
196 | static int moxa_chars_in_buffer(struct tty_struct *); | 199 | static int moxa_chars_in_buffer(struct tty_struct *); |
197 | static void moxa_flush_chars(struct tty_struct *); | ||
198 | static void moxa_put_char(struct tty_struct *, unsigned char); | ||
199 | static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); | ||
200 | static void moxa_throttle(struct tty_struct *); | 200 | static void moxa_throttle(struct tty_struct *); |
201 | static void moxa_unthrottle(struct tty_struct *); | 201 | static void moxa_unthrottle(struct tty_struct *); |
202 | static void moxa_set_termios(struct tty_struct *, struct ktermios *); | 202 | static void moxa_set_termios(struct tty_struct *, struct ktermios *); |
@@ -208,44 +208,183 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
208 | unsigned int set, unsigned int clear); | 208 | unsigned int set, unsigned int clear); |
209 | static void moxa_poll(unsigned long); | 209 | static void moxa_poll(unsigned long); |
210 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | 210 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); |
211 | static int moxa_block_till_ready(struct tty_struct *, struct file *, | ||
212 | struct moxa_port *); | ||
213 | static void moxa_setup_empty_event(struct tty_struct *); | 211 | static void moxa_setup_empty_event(struct tty_struct *); |
214 | static void moxa_check_xmit_empty(unsigned long); | ||
215 | static void moxa_shut_down(struct moxa_port *); | 212 | static void moxa_shut_down(struct moxa_port *); |
216 | static void moxa_receive_data(struct moxa_port *); | ||
217 | /* | 213 | /* |
218 | * moxa board interface functions: | 214 | * moxa board interface functions: |
219 | */ | 215 | */ |
220 | static void MoxaDriverInit(void); | 216 | static void MoxaPortEnable(struct moxa_port *); |
221 | static int MoxaDriverIoctl(unsigned int, unsigned long, int); | 217 | static void MoxaPortDisable(struct moxa_port *); |
222 | static int MoxaDriverPoll(void); | 218 | static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); |
223 | static int MoxaPortsOfCard(int); | 219 | static int MoxaPortGetLineOut(struct moxa_port *, int *, int *); |
224 | static int MoxaPortIsValid(int); | 220 | static void MoxaPortLineCtrl(struct moxa_port *, int, int); |
225 | static void MoxaPortEnable(int); | 221 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); |
226 | static void MoxaPortDisable(int); | 222 | static int MoxaPortLineStatus(struct moxa_port *); |
227 | static long MoxaPortGetMaxBaud(int); | 223 | static void MoxaPortFlushData(struct moxa_port *, int); |
228 | static long MoxaPortSetBaud(int, long); | 224 | static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); |
229 | static int MoxaPortSetTermio(int, struct ktermios *, speed_t); | 225 | static int MoxaPortReadData(struct moxa_port *); |
230 | static int MoxaPortGetLineOut(int, int *, int *); | 226 | static int MoxaPortTxQueue(struct moxa_port *); |
231 | static void MoxaPortLineCtrl(int, int, int); | 227 | static int MoxaPortRxQueue(struct moxa_port *); |
232 | static void MoxaPortFlowCtrl(int, int, int, int, int, int); | 228 | static int MoxaPortTxFree(struct moxa_port *); |
233 | static int MoxaPortLineStatus(int); | 229 | static void MoxaPortTxDisable(struct moxa_port *); |
234 | static int MoxaPortDCDChange(int); | 230 | static void MoxaPortTxEnable(struct moxa_port *); |
235 | static int MoxaPortDCDON(int); | ||
236 | static void MoxaPortFlushData(int, int); | ||
237 | static int MoxaPortWriteData(int, unsigned char *, int); | ||
238 | static int MoxaPortReadData(int, struct tty_struct *tty); | ||
239 | static int MoxaPortTxQueue(int); | ||
240 | static int MoxaPortRxQueue(int); | ||
241 | static int MoxaPortTxFree(int); | ||
242 | static void MoxaPortTxDisable(int); | ||
243 | static void MoxaPortTxEnable(int); | ||
244 | static int MoxaPortResetBrkCnt(int); | ||
245 | static void MoxaPortSendBreak(int, int); | ||
246 | static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); | 231 | static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); |
247 | static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); | 232 | static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); |
248 | static void MoxaSetFifo(int port, int enable); | 233 | static void MoxaSetFifo(struct moxa_port *port, int enable); |
234 | |||
235 | /* | ||
236 | * I/O functions | ||
237 | */ | ||
238 | |||
239 | static void moxa_wait_finish(void __iomem *ofsAddr) | ||
240 | { | ||
241 | unsigned long end = jiffies + moxaFuncTout; | ||
242 | |||
243 | while (readw(ofsAddr + FuncCode) != 0) | ||
244 | if (time_after(jiffies, end)) | ||
245 | return; | ||
246 | if (readw(ofsAddr + FuncCode) != 0 && printk_ratelimit()) | ||
247 | printk(KERN_WARNING "moxa function expired\n"); | ||
248 | } | ||
249 | |||
250 | static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) | ||
251 | { | ||
252 | writew(arg, ofsAddr + FuncArg); | ||
253 | writew(cmd, ofsAddr + FuncCode); | ||
254 | moxa_wait_finish(ofsAddr); | ||
255 | } | ||
256 | |||
257 | static void moxa_low_water_check(void __iomem *ofsAddr) | ||
258 | { | ||
259 | u16 rptr, wptr, mask, len; | ||
260 | |||
261 | if (readb(ofsAddr + FlagStat) & Xoff_state) { | ||
262 | rptr = readw(ofsAddr + RXrptr); | ||
263 | wptr = readw(ofsAddr + RXwptr); | ||
264 | mask = readw(ofsAddr + RX_mask); | ||
265 | len = (wptr - rptr) & mask; | ||
266 | if (len <= Low_water) | ||
267 | moxafunc(ofsAddr, FC_SendXon, 0); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * TTY operations | ||
273 | */ | ||
274 | |||
275 | static int moxa_ioctl(struct tty_struct *tty, struct file *file, | ||
276 | unsigned int cmd, unsigned long arg) | ||
277 | { | ||
278 | struct moxa_port *ch = tty->driver_data; | ||
279 | void __user *argp = (void __user *)arg; | ||
280 | int status, ret = 0; | ||
281 | |||
282 | if (tty->index == MAX_PORTS) { | ||
283 | if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE && | ||
284 | cmd != MOXA_GETMSTATUS) | ||
285 | return -EINVAL; | ||
286 | } else if (!ch) | ||
287 | return -ENODEV; | ||
288 | |||
289 | switch (cmd) { | ||
290 | case MOXA_GETDATACOUNT: | ||
291 | moxaLog.tick = jiffies; | ||
292 | if (copy_to_user(argp, &moxaLog, sizeof(moxaLog))) | ||
293 | ret = -EFAULT; | ||
294 | break; | ||
295 | case MOXA_FLUSH_QUEUE: | ||
296 | MoxaPortFlushData(ch, arg); | ||
297 | break; | ||
298 | case MOXA_GET_IOQUEUE: { | ||
299 | struct moxaq_str __user *argm = argp; | ||
300 | struct moxaq_str tmp; | ||
301 | struct moxa_port *p; | ||
302 | unsigned int i, j; | ||
303 | |||
304 | mutex_lock(&moxa_openlock); | ||
305 | for (i = 0; i < MAX_BOARDS; i++) { | ||
306 | p = moxa_boards[i].ports; | ||
307 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | ||
308 | memset(&tmp, 0, sizeof(tmp)); | ||
309 | if (moxa_boards[i].ready) { | ||
310 | tmp.inq = MoxaPortRxQueue(p); | ||
311 | tmp.outq = MoxaPortTxQueue(p); | ||
312 | } | ||
313 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | ||
314 | mutex_unlock(&moxa_openlock); | ||
315 | return -EFAULT; | ||
316 | } | ||
317 | } | ||
318 | } | ||
319 | mutex_unlock(&moxa_openlock); | ||
320 | break; | ||
321 | } case MOXA_GET_OQUEUE: | ||
322 | status = MoxaPortTxQueue(ch); | ||
323 | ret = put_user(status, (unsigned long __user *)argp); | ||
324 | break; | ||
325 | case MOXA_GET_IQUEUE: | ||
326 | status = MoxaPortRxQueue(ch); | ||
327 | ret = put_user(status, (unsigned long __user *)argp); | ||
328 | break; | ||
329 | case MOXA_GETMSTATUS: { | ||
330 | struct mxser_mstatus __user *argm = argp; | ||
331 | struct mxser_mstatus tmp; | ||
332 | struct moxa_port *p; | ||
333 | unsigned int i, j; | ||
334 | |||
335 | mutex_lock(&moxa_openlock); | ||
336 | for (i = 0; i < MAX_BOARDS; i++) { | ||
337 | p = moxa_boards[i].ports; | ||
338 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | ||
339 | memset(&tmp, 0, sizeof(tmp)); | ||
340 | if (!moxa_boards[i].ready) | ||
341 | goto copy; | ||
342 | |||
343 | status = MoxaPortLineStatus(p); | ||
344 | if (status & 1) | ||
345 | tmp.cts = 1; | ||
346 | if (status & 2) | ||
347 | tmp.dsr = 1; | ||
348 | if (status & 4) | ||
349 | tmp.dcd = 1; | ||
350 | |||
351 | if (!p->tty || !p->tty->termios) | ||
352 | tmp.cflag = p->cflag; | ||
353 | else | ||
354 | tmp.cflag = p->tty->termios->c_cflag; | ||
355 | copy: | ||
356 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | ||
357 | mutex_unlock(&moxa_openlock); | ||
358 | return -EFAULT; | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | mutex_unlock(&moxa_openlock); | ||
363 | break; | ||
364 | } | ||
365 | case TIOCGSERIAL: | ||
366 | mutex_lock(&moxa_openlock); | ||
367 | ret = moxa_get_serial_info(ch, argp); | ||
368 | mutex_unlock(&moxa_openlock); | ||
369 | break; | ||
370 | case TIOCSSERIAL: | ||
371 | mutex_lock(&moxa_openlock); | ||
372 | ret = moxa_set_serial_info(ch, argp); | ||
373 | mutex_unlock(&moxa_openlock); | ||
374 | break; | ||
375 | default: | ||
376 | ret = -ENOIOCTLCMD; | ||
377 | } | ||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | static void moxa_break_ctl(struct tty_struct *tty, int state) | ||
382 | { | ||
383 | struct moxa_port *port = tty->driver_data; | ||
384 | |||
385 | moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak, | ||
386 | Magic_code); | ||
387 | } | ||
249 | 388 | ||
250 | static const struct tty_operations moxa_ops = { | 389 | static const struct tty_operations moxa_ops = { |
251 | .open = moxa_open, | 390 | .open = moxa_open, |
@@ -254,8 +393,6 @@ static const struct tty_operations moxa_ops = { | |||
254 | .write_room = moxa_write_room, | 393 | .write_room = moxa_write_room, |
255 | .flush_buffer = moxa_flush_buffer, | 394 | .flush_buffer = moxa_flush_buffer, |
256 | .chars_in_buffer = moxa_chars_in_buffer, | 395 | .chars_in_buffer = moxa_chars_in_buffer, |
257 | .flush_chars = moxa_flush_chars, | ||
258 | .put_char = moxa_put_char, | ||
259 | .ioctl = moxa_ioctl, | 396 | .ioctl = moxa_ioctl, |
260 | .throttle = moxa_throttle, | 397 | .throttle = moxa_throttle, |
261 | .unthrottle = moxa_unthrottle, | 398 | .unthrottle = moxa_unthrottle, |
@@ -263,15 +400,509 @@ static const struct tty_operations moxa_ops = { | |||
263 | .stop = moxa_stop, | 400 | .stop = moxa_stop, |
264 | .start = moxa_start, | 401 | .start = moxa_start, |
265 | .hangup = moxa_hangup, | 402 | .hangup = moxa_hangup, |
403 | .break_ctl = moxa_break_ctl, | ||
266 | .tiocmget = moxa_tiocmget, | 404 | .tiocmget = moxa_tiocmget, |
267 | .tiocmset = moxa_tiocmset, | 405 | .tiocmset = moxa_tiocmset, |
268 | }; | 406 | }; |
269 | 407 | ||
270 | static struct tty_driver *moxaDriver; | 408 | static struct tty_driver *moxaDriver; |
271 | static struct moxa_port moxa_ports[MAX_PORTS]; | ||
272 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); | 409 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); |
273 | static DEFINE_SPINLOCK(moxa_lock); | 410 | static DEFINE_SPINLOCK(moxa_lock); |
274 | 411 | ||
412 | /* | ||
413 | * HW init | ||
414 | */ | ||
415 | |||
416 | static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model) | ||
417 | { | ||
418 | switch (brd->boardType) { | ||
419 | case MOXA_BOARD_C218_ISA: | ||
420 | case MOXA_BOARD_C218_PCI: | ||
421 | if (model != 1) | ||
422 | goto err; | ||
423 | break; | ||
424 | case MOXA_BOARD_CP204J: | ||
425 | if (model != 3) | ||
426 | goto err; | ||
427 | break; | ||
428 | default: | ||
429 | if (model != 2) | ||
430 | goto err; | ||
431 | break; | ||
432 | } | ||
433 | return 0; | ||
434 | err: | ||
435 | return -EINVAL; | ||
436 | } | ||
437 | |||
438 | static int moxa_check_fw(const void *ptr) | ||
439 | { | ||
440 | const __le16 *lptr = ptr; | ||
441 | |||
442 | if (*lptr != cpu_to_le16(0x7980)) | ||
443 | return -EINVAL; | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf, | ||
449 | size_t len) | ||
450 | { | ||
451 | void __iomem *baseAddr = brd->basemem; | ||
452 | u16 tmp; | ||
453 | |||
454 | writeb(HW_reset, baseAddr + Control_reg); /* reset */ | ||
455 | msleep(10); | ||
456 | memset_io(baseAddr, 0, 4096); | ||
457 | memcpy_toio(baseAddr, buf, len); /* download BIOS */ | ||
458 | writeb(0, baseAddr + Control_reg); /* restart */ | ||
459 | |||
460 | msleep(2000); | ||
461 | |||
462 | switch (brd->boardType) { | ||
463 | case MOXA_BOARD_C218_ISA: | ||
464 | case MOXA_BOARD_C218_PCI: | ||
465 | tmp = readw(baseAddr + C218_key); | ||
466 | if (tmp != C218_KeyCode) | ||
467 | goto err; | ||
468 | break; | ||
469 | case MOXA_BOARD_CP204J: | ||
470 | tmp = readw(baseAddr + C218_key); | ||
471 | if (tmp != CP204J_KeyCode) | ||
472 | goto err; | ||
473 | break; | ||
474 | default: | ||
475 | tmp = readw(baseAddr + C320_key); | ||
476 | if (tmp != C320_KeyCode) | ||
477 | goto err; | ||
478 | tmp = readw(baseAddr + C320_status); | ||
479 | if (tmp != STS_init) { | ||
480 | printk(KERN_ERR "MOXA: bios upload failed -- CPU/Basic " | ||
481 | "module not found\n"); | ||
482 | return -EIO; | ||
483 | } | ||
484 | break; | ||
485 | } | ||
486 | |||
487 | return 0; | ||
488 | err: | ||
489 | printk(KERN_ERR "MOXA: bios upload failed -- board not found\n"); | ||
490 | return -EIO; | ||
491 | } | ||
492 | |||
493 | static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr, | ||
494 | size_t len) | ||
495 | { | ||
496 | void __iomem *baseAddr = brd->basemem; | ||
497 | |||
498 | if (len < 7168) { | ||
499 | printk(KERN_ERR "MOXA: invalid 320 bios -- too short\n"); | ||
500 | return -EINVAL; | ||
501 | } | ||
502 | |||
503 | writew(len - 7168 - 2, baseAddr + C320bapi_len); | ||
504 | writeb(1, baseAddr + Control_reg); /* Select Page 1 */ | ||
505 | memcpy_toio(baseAddr + DynPage_addr, ptr, 7168); | ||
506 | writeb(2, baseAddr + Control_reg); /* Select Page 2 */ | ||
507 | memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168); | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, | ||
513 | size_t len) | ||
514 | { | ||
515 | void __iomem *baseAddr = brd->basemem; | ||
516 | const u16 *uptr = ptr; | ||
517 | size_t wlen, len2, j; | ||
518 | unsigned long key, loadbuf, loadlen, checksum, checksum_ok; | ||
519 | unsigned int i, retry; | ||
520 | u16 usum, keycode; | ||
521 | |||
522 | keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode : | ||
523 | C218_KeyCode; | ||
524 | |||
525 | switch (brd->boardType) { | ||
526 | case MOXA_BOARD_CP204J: | ||
527 | case MOXA_BOARD_C218_ISA: | ||
528 | case MOXA_BOARD_C218_PCI: | ||
529 | key = C218_key; | ||
530 | loadbuf = C218_LoadBuf; | ||
531 | loadlen = C218DLoad_len; | ||
532 | checksum = C218check_sum; | ||
533 | checksum_ok = C218chksum_ok; | ||
534 | break; | ||
535 | default: | ||
536 | key = C320_key; | ||
537 | keycode = C320_KeyCode; | ||
538 | loadbuf = C320_LoadBuf; | ||
539 | loadlen = C320DLoad_len; | ||
540 | checksum = C320check_sum; | ||
541 | checksum_ok = C320chksum_ok; | ||
542 | break; | ||
543 | } | ||
544 | |||
545 | usum = 0; | ||
546 | wlen = len >> 1; | ||
547 | for (i = 0; i < wlen; i++) | ||
548 | usum += le16_to_cpu(uptr[i]); | ||
549 | retry = 0; | ||
550 | do { | ||
551 | wlen = len >> 1; | ||
552 | j = 0; | ||
553 | while (wlen) { | ||
554 | len2 = (wlen > 2048) ? 2048 : wlen; | ||
555 | wlen -= len2; | ||
556 | memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1); | ||
557 | j += len2 << 1; | ||
558 | |||
559 | writew(len2, baseAddr + loadlen); | ||
560 | writew(0, baseAddr + key); | ||
561 | for (i = 0; i < 100; i++) { | ||
562 | if (readw(baseAddr + key) == keycode) | ||
563 | break; | ||
564 | msleep(10); | ||
565 | } | ||
566 | if (readw(baseAddr + key) != keycode) | ||
567 | return -EIO; | ||
568 | } | ||
569 | writew(0, baseAddr + loadlen); | ||
570 | writew(usum, baseAddr + checksum); | ||
571 | writew(0, baseAddr + key); | ||
572 | for (i = 0; i < 100; i++) { | ||
573 | if (readw(baseAddr + key) == keycode) | ||
574 | break; | ||
575 | msleep(10); | ||
576 | } | ||
577 | retry++; | ||
578 | } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3)); | ||
579 | if (readb(baseAddr + checksum_ok) != 1) | ||
580 | return -EIO; | ||
581 | |||
582 | writew(0, baseAddr + key); | ||
583 | for (i = 0; i < 600; i++) { | ||
584 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
585 | break; | ||
586 | msleep(10); | ||
587 | } | ||
588 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
589 | return -EIO; | ||
590 | |||
591 | if (MOXA_IS_320(brd)) { | ||
592 | if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ | ||
593 | writew(0x3800, baseAddr + TMS320_PORT1); | ||
594 | writew(0x3900, baseAddr + TMS320_PORT2); | ||
595 | writew(28499, baseAddr + TMS320_CLOCK); | ||
596 | } else { | ||
597 | writew(0x3200, baseAddr + TMS320_PORT1); | ||
598 | writew(0x3400, baseAddr + TMS320_PORT2); | ||
599 | writew(19999, baseAddr + TMS320_CLOCK); | ||
600 | } | ||
601 | } | ||
602 | writew(1, baseAddr + Disable_IRQ); | ||
603 | writew(0, baseAddr + Magic_no); | ||
604 | for (i = 0; i < 500; i++) { | ||
605 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
606 | break; | ||
607 | msleep(10); | ||
608 | } | ||
609 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
610 | return -EIO; | ||
611 | |||
612 | if (MOXA_IS_320(brd)) { | ||
613 | j = readw(baseAddr + Module_cnt); | ||
614 | if (j <= 0) | ||
615 | return -EIO; | ||
616 | brd->numPorts = j * 8; | ||
617 | writew(j, baseAddr + Module_no); | ||
618 | writew(0, baseAddr + Magic_no); | ||
619 | for (i = 0; i < 600; i++) { | ||
620 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
621 | break; | ||
622 | msleep(10); | ||
623 | } | ||
624 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
625 | return -EIO; | ||
626 | } | ||
627 | brd->intNdx = baseAddr + IRQindex; | ||
628 | brd->intPend = baseAddr + IRQpending; | ||
629 | brd->intTable = baseAddr + IRQtable; | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, | ||
635 | size_t len) | ||
636 | { | ||
637 | void __iomem *ofsAddr, *baseAddr = brd->basemem; | ||
638 | struct moxa_port *port; | ||
639 | int retval, i; | ||
640 | |||
641 | if (len % 2) { | ||
642 | printk(KERN_ERR "MOXA: bios length is not even\n"); | ||
643 | return -EINVAL; | ||
644 | } | ||
645 | |||
646 | retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */ | ||
647 | if (retval) | ||
648 | return retval; | ||
649 | |||
650 | switch (brd->boardType) { | ||
651 | case MOXA_BOARD_C218_ISA: | ||
652 | case MOXA_BOARD_C218_PCI: | ||
653 | case MOXA_BOARD_CP204J: | ||
654 | port = brd->ports; | ||
655 | for (i = 0; i < brd->numPorts; i++, port++) { | ||
656 | port->board = brd; | ||
657 | port->DCDState = 0; | ||
658 | port->tableAddr = baseAddr + Extern_table + | ||
659 | Extern_size * i; | ||
660 | ofsAddr = port->tableAddr; | ||
661 | writew(C218rx_mask, ofsAddr + RX_mask); | ||
662 | writew(C218tx_mask, ofsAddr + TX_mask); | ||
663 | writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); | ||
664 | writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); | ||
665 | |||
666 | writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); | ||
667 | writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); | ||
668 | |||
669 | } | ||
670 | break; | ||
671 | default: | ||
672 | port = brd->ports; | ||
673 | for (i = 0; i < brd->numPorts; i++, port++) { | ||
674 | port->board = brd; | ||
675 | port->DCDState = 0; | ||
676 | port->tableAddr = baseAddr + Extern_table + | ||
677 | Extern_size * i; | ||
678 | ofsAddr = port->tableAddr; | ||
679 | switch (brd->numPorts) { | ||
680 | case 8: | ||
681 | writew(C320p8rx_mask, ofsAddr + RX_mask); | ||
682 | writew(C320p8tx_mask, ofsAddr + TX_mask); | ||
683 | writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); | ||
684 | writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); | ||
685 | writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); | ||
686 | writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); | ||
687 | |||
688 | break; | ||
689 | case 16: | ||
690 | writew(C320p16rx_mask, ofsAddr + RX_mask); | ||
691 | writew(C320p16tx_mask, ofsAddr + TX_mask); | ||
692 | writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); | ||
693 | writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); | ||
694 | writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); | ||
695 | writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); | ||
696 | break; | ||
697 | |||
698 | case 24: | ||
699 | writew(C320p24rx_mask, ofsAddr + RX_mask); | ||
700 | writew(C320p24tx_mask, ofsAddr + TX_mask); | ||
701 | writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); | ||
702 | writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); | ||
703 | writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); | ||
704 | writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); | ||
705 | break; | ||
706 | case 32: | ||
707 | writew(C320p32rx_mask, ofsAddr + RX_mask); | ||
708 | writew(C320p32tx_mask, ofsAddr + TX_mask); | ||
709 | writew(C320p32tx_ofs, ofsAddr + Ofs_txb); | ||
710 | writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); | ||
711 | writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); | ||
712 | writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); | ||
713 | writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | break; | ||
718 | } | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) | ||
723 | { | ||
724 | void *ptr = fw->data; | ||
725 | char rsn[64]; | ||
726 | u16 lens[5]; | ||
727 | size_t len; | ||
728 | unsigned int a, lenp, lencnt; | ||
729 | int ret = -EINVAL; | ||
730 | struct { | ||
731 | __le32 magic; /* 0x34303430 */ | ||
732 | u8 reserved1[2]; | ||
733 | u8 type; /* UNIX = 3 */ | ||
734 | u8 model; /* C218T=1, C320T=2, CP204=3 */ | ||
735 | u8 reserved2[8]; | ||
736 | __le16 len[5]; | ||
737 | } *hdr = ptr; | ||
738 | |||
739 | BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens)); | ||
740 | |||
741 | if (fw->size < MOXA_FW_HDRLEN) { | ||
742 | strcpy(rsn, "too short (even header won't fit)"); | ||
743 | goto err; | ||
744 | } | ||
745 | if (hdr->magic != cpu_to_le32(0x30343034)) { | ||
746 | sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic)); | ||
747 | goto err; | ||
748 | } | ||
749 | if (hdr->type != 3) { | ||
750 | sprintf(rsn, "not for linux, type is %u", hdr->type); | ||
751 | goto err; | ||
752 | } | ||
753 | if (moxa_check_fw_model(brd, hdr->model)) { | ||
754 | sprintf(rsn, "not for this card, model is %u", hdr->model); | ||
755 | goto err; | ||
756 | } | ||
757 | |||
758 | len = MOXA_FW_HDRLEN; | ||
759 | lencnt = hdr->model == 2 ? 5 : 3; | ||
760 | for (a = 0; a < ARRAY_SIZE(lens); a++) { | ||
761 | lens[a] = le16_to_cpu(hdr->len[a]); | ||
762 | if (lens[a] && len + lens[a] <= fw->size && | ||
763 | moxa_check_fw(&fw->data[len])) | ||
764 | printk(KERN_WARNING "MOXA firmware: unexpected input " | ||
765 | "at offset %u, but going on\n", (u32)len); | ||
766 | if (!lens[a] && a < lencnt) { | ||
767 | sprintf(rsn, "too few entries in fw file"); | ||
768 | goto err; | ||
769 | } | ||
770 | len += lens[a]; | ||
771 | } | ||
772 | |||
773 | if (len != fw->size) { | ||
774 | sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size, | ||
775 | (u32)len); | ||
776 | goto err; | ||
777 | } | ||
778 | |||
779 | ptr += MOXA_FW_HDRLEN; | ||
780 | lenp = 0; /* bios */ | ||
781 | |||
782 | strcpy(rsn, "read above"); | ||
783 | |||
784 | ret = moxa_load_bios(brd, ptr, lens[lenp]); | ||
785 | if (ret) | ||
786 | goto err; | ||
787 | |||
788 | /* we skip the tty section (lens[1]), since we don't need it */ | ||
789 | ptr += lens[lenp] + lens[lenp + 1]; | ||
790 | lenp += 2; /* comm */ | ||
791 | |||
792 | if (hdr->model == 2) { | ||
793 | ret = moxa_load_320b(brd, ptr, lens[lenp]); | ||
794 | if (ret) | ||
795 | goto err; | ||
796 | /* skip another tty */ | ||
797 | ptr += lens[lenp] + lens[lenp + 1]; | ||
798 | lenp += 2; | ||
799 | } | ||
800 | |||
801 | ret = moxa_load_code(brd, ptr, lens[lenp]); | ||
802 | if (ret) | ||
803 | goto err; | ||
804 | |||
805 | return 0; | ||
806 | err: | ||
807 | printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn); | ||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | ||
812 | { | ||
813 | const struct firmware *fw; | ||
814 | const char *file; | ||
815 | struct moxa_port *p; | ||
816 | unsigned int i; | ||
817 | int ret; | ||
818 | |||
819 | brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), | ||
820 | GFP_KERNEL); | ||
821 | if (brd->ports == NULL) { | ||
822 | printk(KERN_ERR "cannot allocate memory for ports\n"); | ||
823 | ret = -ENOMEM; | ||
824 | goto err; | ||
825 | } | ||
826 | |||
827 | for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { | ||
828 | p->type = PORT_16550A; | ||
829 | p->close_delay = 5 * HZ / 10; | ||
830 | p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | ||
831 | init_waitqueue_head(&p->open_wait); | ||
832 | } | ||
833 | |||
834 | switch (brd->boardType) { | ||
835 | case MOXA_BOARD_C218_ISA: | ||
836 | case MOXA_BOARD_C218_PCI: | ||
837 | file = "c218tunx.cod"; | ||
838 | break; | ||
839 | case MOXA_BOARD_CP204J: | ||
840 | file = "cp204unx.cod"; | ||
841 | break; | ||
842 | default: | ||
843 | file = "c320tunx.cod"; | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | ret = request_firmware(&fw, file, dev); | ||
848 | if (ret) { | ||
849 | printk(KERN_ERR "MOXA: request_firmware failed. Make sure " | ||
850 | "you've placed '%s' file into your firmware " | ||
851 | "loader directory (e.g. /lib/firmware)\n", | ||
852 | file); | ||
853 | goto err_free; | ||
854 | } | ||
855 | |||
856 | ret = moxa_load_fw(brd, fw); | ||
857 | |||
858 | release_firmware(fw); | ||
859 | |||
860 | if (ret) | ||
861 | goto err_free; | ||
862 | |||
863 | spin_lock_bh(&moxa_lock); | ||
864 | brd->ready = 1; | ||
865 | if (!timer_pending(&moxaTimer)) | ||
866 | mod_timer(&moxaTimer, jiffies + HZ / 50); | ||
867 | spin_unlock_bh(&moxa_lock); | ||
868 | |||
869 | return 0; | ||
870 | err_free: | ||
871 | kfree(brd->ports); | ||
872 | err: | ||
873 | return ret; | ||
874 | } | ||
875 | |||
876 | static void moxa_board_deinit(struct moxa_board_conf *brd) | ||
877 | { | ||
878 | unsigned int a, opened; | ||
879 | |||
880 | mutex_lock(&moxa_openlock); | ||
881 | spin_lock_bh(&moxa_lock); | ||
882 | brd->ready = 0; | ||
883 | spin_unlock_bh(&moxa_lock); | ||
884 | |||
885 | /* pci hot-un-plug support */ | ||
886 | for (a = 0; a < brd->numPorts; a++) | ||
887 | if (brd->ports[a].asyncflags & ASYNC_INITIALIZED) | ||
888 | tty_hangup(brd->ports[a].tty); | ||
889 | while (1) { | ||
890 | opened = 0; | ||
891 | for (a = 0; a < brd->numPorts; a++) | ||
892 | if (brd->ports[a].asyncflags & ASYNC_INITIALIZED) | ||
893 | opened++; | ||
894 | mutex_unlock(&moxa_openlock); | ||
895 | if (!opened) | ||
896 | break; | ||
897 | msleep(50); | ||
898 | mutex_lock(&moxa_openlock); | ||
899 | } | ||
900 | |||
901 | iounmap(brd->basemem); | ||
902 | brd->basemem = NULL; | ||
903 | kfree(brd->ports); | ||
904 | } | ||
905 | |||
275 | #ifdef CONFIG_PCI | 906 | #ifdef CONFIG_PCI |
276 | static int __devinit moxa_pci_probe(struct pci_dev *pdev, | 907 | static int __devinit moxa_pci_probe(struct pci_dev *pdev, |
277 | const struct pci_device_id *ent) | 908 | const struct pci_device_id *ent) |
@@ -299,10 +930,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
299 | } | 930 | } |
300 | 931 | ||
301 | board = &moxa_boards[i]; | 932 | board = &moxa_boards[i]; |
302 | board->basemem = pci_iomap(pdev, 2, 0x4000); | 933 | |
934 | retval = pci_request_region(pdev, 2, "moxa-base"); | ||
935 | if (retval) { | ||
936 | dev_err(&pdev->dev, "can't request pci region 2\n"); | ||
937 | goto err; | ||
938 | } | ||
939 | |||
940 | board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); | ||
303 | if (board->basemem == NULL) { | 941 | if (board->basemem == NULL) { |
304 | dev_err(&pdev->dev, "can't remap io space 2\n"); | 942 | dev_err(&pdev->dev, "can't remap io space 2\n"); |
305 | goto err; | 943 | goto err_reg; |
306 | } | 944 | } |
307 | 945 | ||
308 | board->boardType = board_type; | 946 | board->boardType = board_type; |
@@ -321,9 +959,21 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
321 | } | 959 | } |
322 | board->busType = MOXA_BUS_TYPE_PCI; | 960 | board->busType = MOXA_BUS_TYPE_PCI; |
323 | 961 | ||
962 | retval = moxa_init_board(board, &pdev->dev); | ||
963 | if (retval) | ||
964 | goto err_base; | ||
965 | |||
324 | pci_set_drvdata(pdev, board); | 966 | pci_set_drvdata(pdev, board); |
325 | 967 | ||
326 | return (0); | 968 | dev_info(&pdev->dev, "board '%s' ready (%u ports, firmware loaded)\n", |
969 | moxa_brdname[board_type - 1], board->numPorts); | ||
970 | |||
971 | return 0; | ||
972 | err_base: | ||
973 | iounmap(board->basemem); | ||
974 | board->basemem = NULL; | ||
975 | err_reg: | ||
976 | pci_release_region(pdev, 2); | ||
327 | err: | 977 | err: |
328 | return retval; | 978 | return retval; |
329 | } | 979 | } |
@@ -332,8 +982,9 @@ static void __devexit moxa_pci_remove(struct pci_dev *pdev) | |||
332 | { | 982 | { |
333 | struct moxa_board_conf *brd = pci_get_drvdata(pdev); | 983 | struct moxa_board_conf *brd = pci_get_drvdata(pdev); |
334 | 984 | ||
335 | pci_iounmap(pdev, brd->basemem); | 985 | moxa_board_deinit(brd); |
336 | brd->basemem = NULL; | 986 | |
987 | pci_release_region(pdev, 2); | ||
337 | } | 988 | } |
338 | 989 | ||
339 | static struct pci_driver moxa_pci_driver = { | 990 | static struct pci_driver moxa_pci_driver = { |
@@ -346,8 +997,8 @@ static struct pci_driver moxa_pci_driver = { | |||
346 | 997 | ||
347 | static int __init moxa_init(void) | 998 | static int __init moxa_init(void) |
348 | { | 999 | { |
349 | int i, numBoards, retval = 0; | 1000 | unsigned int isabrds = 0; |
350 | struct moxa_port *ch; | 1001 | int retval = 0; |
351 | 1002 | ||
352 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", | 1003 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
353 | MOXA_VERSION); | 1004 | MOXA_VERSION); |
@@ -368,154 +1019,176 @@ static int __init moxa_init(void) | |||
368 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; | 1019 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; |
369 | tty_set_operations(moxaDriver, &moxa_ops); | 1020 | tty_set_operations(moxaDriver, &moxa_ops); |
370 | 1021 | ||
371 | for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) { | ||
372 | ch->type = PORT_16550A; | ||
373 | ch->port = i; | ||
374 | ch->close_delay = 5 * HZ / 10; | ||
375 | ch->closing_wait = 30 * HZ; | ||
376 | ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | ||
377 | init_waitqueue_head(&ch->open_wait); | ||
378 | init_completion(&ch->close_wait); | ||
379 | |||
380 | setup_timer(&ch->emptyTimer, moxa_check_xmit_empty, | ||
381 | (unsigned long)ch); | ||
382 | } | ||
383 | |||
384 | pr_debug("Moxa tty devices major number = %d\n", ttymajor); | ||
385 | |||
386 | if (tty_register_driver(moxaDriver)) { | 1022 | if (tty_register_driver(moxaDriver)) { |
387 | printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); | 1023 | printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); |
388 | put_tty_driver(moxaDriver); | 1024 | put_tty_driver(moxaDriver); |
389 | return -1; | 1025 | return -1; |
390 | } | 1026 | } |
391 | 1027 | ||
392 | mod_timer(&moxaTimer, jiffies + HZ / 50); | 1028 | /* Find the boards defined from module args. */ |
393 | |||
394 | /* Find the boards defined in source code */ | ||
395 | numBoards = 0; | ||
396 | for (i = 0; i < MAX_BOARDS; i++) { | ||
397 | if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) || | ||
398 | (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) { | ||
399 | moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType; | ||
400 | if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) | ||
401 | moxa_boards[numBoards].numPorts = 8; | ||
402 | else | ||
403 | moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; | ||
404 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; | ||
405 | moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; | ||
406 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", | ||
407 | numBoards + 1, | ||
408 | moxa_brdname[moxa_boards[numBoards].boardType-1], | ||
409 | moxa_boards[numBoards].baseAddr); | ||
410 | numBoards++; | ||
411 | } | ||
412 | } | ||
413 | /* Find the boards defined form module args. */ | ||
414 | #ifdef MODULE | 1029 | #ifdef MODULE |
1030 | { | ||
1031 | struct moxa_board_conf *brd = moxa_boards; | ||
1032 | unsigned int i; | ||
415 | for (i = 0; i < MAX_BOARDS; i++) { | 1033 | for (i = 0; i < MAX_BOARDS; i++) { |
416 | if ((type[i] == MOXA_BOARD_C218_ISA) || | 1034 | if (!baseaddr[i]) |
417 | (type[i] == MOXA_BOARD_C320_ISA)) { | 1035 | break; |
1036 | if (type[i] == MOXA_BOARD_C218_ISA || | ||
1037 | type[i] == MOXA_BOARD_C320_ISA) { | ||
418 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", | 1038 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", |
419 | numBoards + 1, moxa_brdname[type[i] - 1], | 1039 | isabrds + 1, moxa_brdname[type[i] - 1], |
420 | (unsigned long)baseaddr[i]); | 1040 | baseaddr[i]); |
421 | if (numBoards >= MAX_BOARDS) { | 1041 | brd->boardType = type[i]; |
422 | printk(KERN_WARNING "More than %d MOXA " | 1042 | brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 : |
423 | "Intellio family boards found. Board " | 1043 | numports[i]; |
424 | "is ignored.\n", MAX_BOARDS); | 1044 | brd->busType = MOXA_BUS_TYPE_ISA; |
1045 | brd->basemem = ioremap_nocache(baseaddr[i], 0x4000); | ||
1046 | if (!brd->basemem) { | ||
1047 | printk(KERN_ERR "MOXA: can't remap %lx\n", | ||
1048 | baseaddr[i]); | ||
425 | continue; | 1049 | continue; |
426 | } | 1050 | } |
427 | moxa_boards[numBoards].boardType = type[i]; | 1051 | if (moxa_init_board(brd, NULL)) { |
428 | if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) | 1052 | iounmap(brd->basemem); |
429 | moxa_boards[numBoards].numPorts = 8; | 1053 | brd->basemem = NULL; |
430 | else | 1054 | continue; |
431 | moxa_boards[numBoards].numPorts = numports[i]; | 1055 | } |
432 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; | 1056 | |
433 | moxa_boards[numBoards].baseAddr = baseaddr[i]; | 1057 | printk(KERN_INFO "MOXA isa board found at 0x%.8lu and " |
434 | numBoards++; | 1058 | "ready (%u ports, firmware loaded)\n", |
1059 | baseaddr[i], brd->numPorts); | ||
1060 | |||
1061 | brd++; | ||
1062 | isabrds++; | ||
435 | } | 1063 | } |
436 | } | 1064 | } |
1065 | } | ||
437 | #endif | 1066 | #endif |
438 | 1067 | ||
439 | #ifdef CONFIG_PCI | 1068 | #ifdef CONFIG_PCI |
440 | retval = pci_register_driver(&moxa_pci_driver); | 1069 | retval = pci_register_driver(&moxa_pci_driver); |
441 | if (retval) { | 1070 | if (retval) { |
442 | printk(KERN_ERR "Can't register moxa pci driver!\n"); | 1071 | printk(KERN_ERR "Can't register MOXA pci driver!\n"); |
443 | if (numBoards) | 1072 | if (isabrds) |
444 | retval = 0; | 1073 | retval = 0; |
445 | } | 1074 | } |
446 | #endif | 1075 | #endif |
447 | 1076 | ||
448 | for (i = 0; i < numBoards; i++) { | ||
449 | moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr, | ||
450 | 0x4000); | ||
451 | } | ||
452 | |||
453 | return retval; | 1077 | return retval; |
454 | } | 1078 | } |
455 | 1079 | ||
456 | static void __exit moxa_exit(void) | 1080 | static void __exit moxa_exit(void) |
457 | { | 1081 | { |
458 | int i; | 1082 | unsigned int i; |
459 | 1083 | ||
460 | del_timer_sync(&moxaTimer); | 1084 | #ifdef CONFIG_PCI |
1085 | pci_unregister_driver(&moxa_pci_driver); | ||
1086 | #endif | ||
1087 | |||
1088 | for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */ | ||
1089 | if (moxa_boards[i].ready) | ||
1090 | moxa_board_deinit(&moxa_boards[i]); | ||
461 | 1091 | ||
462 | for (i = 0; i < MAX_PORTS; i++) | 1092 | del_timer_sync(&moxaTimer); |
463 | del_timer_sync(&moxa_ports[i].emptyTimer); | ||
464 | 1093 | ||
465 | if (tty_unregister_driver(moxaDriver)) | 1094 | if (tty_unregister_driver(moxaDriver)) |
466 | printk(KERN_ERR "Couldn't unregister MOXA Intellio family " | 1095 | printk(KERN_ERR "Couldn't unregister MOXA Intellio family " |
467 | "serial driver\n"); | 1096 | "serial driver\n"); |
468 | put_tty_driver(moxaDriver); | 1097 | put_tty_driver(moxaDriver); |
469 | |||
470 | #ifdef CONFIG_PCI | ||
471 | pci_unregister_driver(&moxa_pci_driver); | ||
472 | #endif | ||
473 | |||
474 | for (i = 0; i < MAX_BOARDS; i++) | ||
475 | if (moxa_boards[i].basemem) | ||
476 | iounmap(moxa_boards[i].basemem); | ||
477 | } | 1098 | } |
478 | 1099 | ||
479 | module_init(moxa_init); | 1100 | module_init(moxa_init); |
480 | module_exit(moxa_exit); | 1101 | module_exit(moxa_exit); |
481 | 1102 | ||
1103 | static void moxa_close_port(struct moxa_port *ch) | ||
1104 | { | ||
1105 | moxa_shut_down(ch); | ||
1106 | MoxaPortFlushData(ch, 2); | ||
1107 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | ||
1108 | ch->tty->driver_data = NULL; | ||
1109 | ch->tty = NULL; | ||
1110 | } | ||
1111 | |||
1112 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | ||
1113 | struct moxa_port *ch) | ||
1114 | { | ||
1115 | DEFINE_WAIT(wait); | ||
1116 | int retval = 0; | ||
1117 | u8 dcd; | ||
1118 | |||
1119 | while (1) { | ||
1120 | prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE); | ||
1121 | if (tty_hung_up_p(filp)) { | ||
1122 | #ifdef SERIAL_DO_RESTART | ||
1123 | retval = -ERESTARTSYS; | ||
1124 | #else | ||
1125 | retval = -EAGAIN; | ||
1126 | #endif | ||
1127 | break; | ||
1128 | } | ||
1129 | spin_lock_bh(&moxa_lock); | ||
1130 | dcd = ch->DCDState; | ||
1131 | spin_unlock_bh(&moxa_lock); | ||
1132 | if (dcd) | ||
1133 | break; | ||
1134 | |||
1135 | if (signal_pending(current)) { | ||
1136 | retval = -ERESTARTSYS; | ||
1137 | break; | ||
1138 | } | ||
1139 | schedule(); | ||
1140 | } | ||
1141 | finish_wait(&ch->open_wait, &wait); | ||
1142 | |||
1143 | return retval; | ||
1144 | } | ||
1145 | |||
482 | static int moxa_open(struct tty_struct *tty, struct file *filp) | 1146 | static int moxa_open(struct tty_struct *tty, struct file *filp) |
483 | { | 1147 | { |
1148 | struct moxa_board_conf *brd; | ||
484 | struct moxa_port *ch; | 1149 | struct moxa_port *ch; |
485 | int port; | 1150 | int port; |
486 | int retval; | 1151 | int retval; |
487 | 1152 | ||
488 | port = tty->index; | 1153 | port = tty->index; |
489 | if (port == MAX_PORTS) { | 1154 | if (port == MAX_PORTS) { |
490 | return (0); | 1155 | return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; |
491 | } | 1156 | } |
492 | if (!MoxaPortIsValid(port)) { | 1157 | if (mutex_lock_interruptible(&moxa_openlock)) |
493 | tty->driver_data = NULL; | 1158 | return -ERESTARTSYS; |
494 | return (-ENODEV); | 1159 | brd = &moxa_boards[port / MAX_PORTS_PER_BOARD]; |
1160 | if (!brd->ready) { | ||
1161 | mutex_unlock(&moxa_openlock); | ||
1162 | return -ENODEV; | ||
495 | } | 1163 | } |
496 | 1164 | ||
497 | ch = &moxa_ports[port]; | 1165 | ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; |
498 | ch->count++; | 1166 | ch->count++; |
499 | tty->driver_data = ch; | 1167 | tty->driver_data = ch; |
500 | ch->tty = tty; | 1168 | ch->tty = tty; |
501 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { | 1169 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { |
502 | ch->statusflags = 0; | 1170 | ch->statusflags = 0; |
503 | moxa_set_tty_param(tty, tty->termios); | 1171 | moxa_set_tty_param(tty, tty->termios); |
504 | MoxaPortLineCtrl(ch->port, 1, 1); | 1172 | MoxaPortLineCtrl(ch, 1, 1); |
505 | MoxaPortEnable(ch->port); | 1173 | MoxaPortEnable(ch); |
1174 | MoxaSetFifo(ch, ch->type == PORT_16550A); | ||
506 | ch->asyncflags |= ASYNC_INITIALIZED; | 1175 | ch->asyncflags |= ASYNC_INITIALIZED; |
507 | } | 1176 | } |
508 | retval = moxa_block_till_ready(tty, filp, ch); | 1177 | mutex_unlock(&moxa_openlock); |
509 | 1178 | ||
510 | moxa_unthrottle(tty); | 1179 | retval = 0; |
511 | 1180 | if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty)) | |
512 | if (ch->type == PORT_16550A) { | 1181 | retval = moxa_block_till_ready(tty, filp, ch); |
513 | MoxaSetFifo(ch->port, 1); | 1182 | mutex_lock(&moxa_openlock); |
514 | } else { | 1183 | if (retval) { |
515 | MoxaSetFifo(ch->port, 0); | 1184 | if (ch->count) /* 0 means already hung up... */ |
516 | } | 1185 | if (--ch->count == 0) |
1186 | moxa_close_port(ch); | ||
1187 | } else | ||
1188 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | ||
1189 | mutex_unlock(&moxa_openlock); | ||
517 | 1190 | ||
518 | return (retval); | 1191 | return retval; |
519 | } | 1192 | } |
520 | 1193 | ||
521 | static void moxa_close(struct tty_struct *tty, struct file *filp) | 1194 | static void moxa_close(struct tty_struct *tty, struct file *filp) |
@@ -524,23 +1197,14 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
524 | int port; | 1197 | int port; |
525 | 1198 | ||
526 | port = tty->index; | 1199 | port = tty->index; |
527 | if (port == MAX_PORTS) { | 1200 | if (port == MAX_PORTS || tty_hung_up_p(filp)) |
528 | return; | ||
529 | } | ||
530 | if (!MoxaPortIsValid(port)) { | ||
531 | pr_debug("Invalid portno in moxa_close\n"); | ||
532 | tty->driver_data = NULL; | ||
533 | return; | ||
534 | } | ||
535 | if (tty->driver_data == NULL) { | ||
536 | return; | 1201 | return; |
537 | } | ||
538 | if (tty_hung_up_p(filp)) { | ||
539 | return; | ||
540 | } | ||
541 | ch = (struct moxa_port *) tty->driver_data; | ||
542 | 1202 | ||
543 | if ((tty->count == 1) && (ch->count != 1)) { | 1203 | mutex_lock(&moxa_openlock); |
1204 | ch = tty->driver_data; | ||
1205 | if (ch == NULL) | ||
1206 | goto unlock; | ||
1207 | if (tty->count == 1 && ch->count != 1) { | ||
544 | printk(KERN_WARNING "moxa_close: bad serial port count; " | 1208 | printk(KERN_WARNING "moxa_close: bad serial port count; " |
545 | "tty->count is 1, ch->count is %d\n", ch->count); | 1209 | "tty->count is 1, ch->count is %d\n", ch->count); |
546 | ch->count = 1; | 1210 | ch->count = 1; |
@@ -550,59 +1214,35 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
550 | "device=%s\n", tty->name); | 1214 | "device=%s\n", tty->name); |
551 | ch->count = 0; | 1215 | ch->count = 0; |
552 | } | 1216 | } |
553 | if (ch->count) { | 1217 | if (ch->count) |
554 | return; | 1218 | goto unlock; |
555 | } | ||
556 | ch->asyncflags |= ASYNC_CLOSING; | ||
557 | 1219 | ||
558 | ch->cflag = tty->termios->c_cflag; | 1220 | ch->cflag = tty->termios->c_cflag; |
559 | if (ch->asyncflags & ASYNC_INITIALIZED) { | 1221 | if (ch->asyncflags & ASYNC_INITIALIZED) { |
560 | moxa_setup_empty_event(tty); | 1222 | moxa_setup_empty_event(tty); |
561 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | 1223 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ |
562 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); | ||
563 | } | ||
564 | moxa_shut_down(ch); | ||
565 | MoxaPortFlushData(port, 2); | ||
566 | |||
567 | if (tty->driver->flush_buffer) | ||
568 | tty->driver->flush_buffer(tty); | ||
569 | tty_ldisc_flush(tty); | ||
570 | |||
571 | tty->closing = 0; | ||
572 | ch->event = 0; | ||
573 | ch->tty = NULL; | ||
574 | if (ch->blocked_open) { | ||
575 | if (ch->close_delay) { | ||
576 | msleep_interruptible(jiffies_to_msecs(ch->close_delay)); | ||
577 | } | ||
578 | wake_up_interruptible(&ch->open_wait); | ||
579 | } | 1224 | } |
580 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 1225 | |
581 | complete_all(&ch->close_wait); | 1226 | moxa_close_port(ch); |
1227 | unlock: | ||
1228 | mutex_unlock(&moxa_openlock); | ||
582 | } | 1229 | } |
583 | 1230 | ||
584 | static int moxa_write(struct tty_struct *tty, | 1231 | static int moxa_write(struct tty_struct *tty, |
585 | const unsigned char *buf, int count) | 1232 | const unsigned char *buf, int count) |
586 | { | 1233 | { |
587 | struct moxa_port *ch; | 1234 | struct moxa_port *ch = tty->driver_data; |
588 | int len, port; | 1235 | int len; |
589 | unsigned long flags; | ||
590 | 1236 | ||
591 | ch = (struct moxa_port *) tty->driver_data; | ||
592 | if (ch == NULL) | 1237 | if (ch == NULL) |
593 | return (0); | 1238 | return 0; |
594 | port = ch->port; | ||
595 | 1239 | ||
596 | spin_lock_irqsave(&moxa_lock, flags); | 1240 | spin_lock_bh(&moxa_lock); |
597 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); | 1241 | len = MoxaPortWriteData(ch, buf, count); |
598 | spin_unlock_irqrestore(&moxa_lock, flags); | 1242 | spin_unlock_bh(&moxa_lock); |
599 | 1243 | ||
600 | /********************************************* | ||
601 | if ( !(ch->statusflags & LOWWAIT) && | ||
602 | ((len != count) || (MoxaPortTxFree(port) <= 100)) ) | ||
603 | ************************************************/ | ||
604 | ch->statusflags |= LOWWAIT; | 1244 | ch->statusflags |= LOWWAIT; |
605 | return (len); | 1245 | return len; |
606 | } | 1246 | } |
607 | 1247 | ||
608 | static int moxa_write_room(struct tty_struct *tty) | 1248 | static int moxa_write_room(struct tty_struct *tty) |
@@ -610,27 +1250,27 @@ static int moxa_write_room(struct tty_struct *tty) | |||
610 | struct moxa_port *ch; | 1250 | struct moxa_port *ch; |
611 | 1251 | ||
612 | if (tty->stopped) | 1252 | if (tty->stopped) |
613 | return (0); | 1253 | return 0; |
614 | ch = (struct moxa_port *) tty->driver_data; | 1254 | ch = tty->driver_data; |
615 | if (ch == NULL) | 1255 | if (ch == NULL) |
616 | return (0); | 1256 | return 0; |
617 | return (MoxaPortTxFree(ch->port)); | 1257 | return MoxaPortTxFree(ch); |
618 | } | 1258 | } |
619 | 1259 | ||
620 | static void moxa_flush_buffer(struct tty_struct *tty) | 1260 | static void moxa_flush_buffer(struct tty_struct *tty) |
621 | { | 1261 | { |
622 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1262 | struct moxa_port *ch = tty->driver_data; |
623 | 1263 | ||
624 | if (ch == NULL) | 1264 | if (ch == NULL) |
625 | return; | 1265 | return; |
626 | MoxaPortFlushData(ch->port, 1); | 1266 | MoxaPortFlushData(ch, 1); |
627 | tty_wakeup(tty); | 1267 | tty_wakeup(tty); |
628 | } | 1268 | } |
629 | 1269 | ||
630 | static int moxa_chars_in_buffer(struct tty_struct *tty) | 1270 | static int moxa_chars_in_buffer(struct tty_struct *tty) |
631 | { | 1271 | { |
1272 | struct moxa_port *ch = tty->driver_data; | ||
632 | int chars; | 1273 | int chars; |
633 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | ||
634 | 1274 | ||
635 | /* | 1275 | /* |
636 | * Sigh...I have to check if driver_data is NULL here, because | 1276 | * Sigh...I have to check if driver_data is NULL here, because |
@@ -639,8 +1279,9 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
639 | * routine. And since the open() failed, we return 0 here. TDJ | 1279 | * routine. And since the open() failed, we return 0 here. TDJ |
640 | */ | 1280 | */ |
641 | if (ch == NULL) | 1281 | if (ch == NULL) |
642 | return (0); | 1282 | return 0; |
643 | chars = MoxaPortTxQueue(ch->port); | 1283 | lock_kernel(); |
1284 | chars = MoxaPortTxQueue(ch); | ||
644 | if (chars) { | 1285 | if (chars) { |
645 | /* | 1286 | /* |
646 | * Make it possible to wakeup anything waiting for output | 1287 | * Make it possible to wakeup anything waiting for output |
@@ -649,73 +1290,54 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
649 | if (!(ch->statusflags & EMPTYWAIT)) | 1290 | if (!(ch->statusflags & EMPTYWAIT)) |
650 | moxa_setup_empty_event(tty); | 1291 | moxa_setup_empty_event(tty); |
651 | } | 1292 | } |
652 | return (chars); | 1293 | unlock_kernel(); |
653 | } | 1294 | return chars; |
654 | |||
655 | static void moxa_flush_chars(struct tty_struct *tty) | ||
656 | { | ||
657 | /* | ||
658 | * Don't think I need this, because this is called to empty the TX | ||
659 | * buffer for the 16450, 16550, etc. | ||
660 | */ | ||
661 | } | ||
662 | |||
663 | static void moxa_put_char(struct tty_struct *tty, unsigned char c) | ||
664 | { | ||
665 | struct moxa_port *ch; | ||
666 | int port; | ||
667 | unsigned long flags; | ||
668 | |||
669 | ch = (struct moxa_port *) tty->driver_data; | ||
670 | if (ch == NULL) | ||
671 | return; | ||
672 | port = ch->port; | ||
673 | spin_lock_irqsave(&moxa_lock, flags); | ||
674 | MoxaPortWriteData(port, &c, 1); | ||
675 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
676 | /************************************************ | ||
677 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) | ||
678 | *************************************************/ | ||
679 | ch->statusflags |= LOWWAIT; | ||
680 | } | 1295 | } |
681 | 1296 | ||
682 | static int moxa_tiocmget(struct tty_struct *tty, struct file *file) | 1297 | static int moxa_tiocmget(struct tty_struct *tty, struct file *file) |
683 | { | 1298 | { |
684 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1299 | struct moxa_port *ch; |
685 | int port; | ||
686 | int flag = 0, dtr, rts; | 1300 | int flag = 0, dtr, rts; |
687 | 1301 | ||
688 | port = tty->index; | 1302 | mutex_lock(&moxa_openlock); |
689 | if ((port != MAX_PORTS) && (!ch)) | 1303 | ch = tty->driver_data; |
690 | return (-EINVAL); | 1304 | if (!ch) { |
1305 | mutex_unlock(&moxa_openlock); | ||
1306 | return -EINVAL; | ||
1307 | } | ||
691 | 1308 | ||
692 | MoxaPortGetLineOut(ch->port, &dtr, &rts); | 1309 | MoxaPortGetLineOut(ch, &dtr, &rts); |
693 | if (dtr) | 1310 | if (dtr) |
694 | flag |= TIOCM_DTR; | 1311 | flag |= TIOCM_DTR; |
695 | if (rts) | 1312 | if (rts) |
696 | flag |= TIOCM_RTS; | 1313 | flag |= TIOCM_RTS; |
697 | dtr = MoxaPortLineStatus(ch->port); | 1314 | dtr = MoxaPortLineStatus(ch); |
698 | if (dtr & 1) | 1315 | if (dtr & 1) |
699 | flag |= TIOCM_CTS; | 1316 | flag |= TIOCM_CTS; |
700 | if (dtr & 2) | 1317 | if (dtr & 2) |
701 | flag |= TIOCM_DSR; | 1318 | flag |= TIOCM_DSR; |
702 | if (dtr & 4) | 1319 | if (dtr & 4) |
703 | flag |= TIOCM_CD; | 1320 | flag |= TIOCM_CD; |
1321 | mutex_unlock(&moxa_openlock); | ||
704 | return flag; | 1322 | return flag; |
705 | } | 1323 | } |
706 | 1324 | ||
707 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | 1325 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, |
708 | unsigned int set, unsigned int clear) | 1326 | unsigned int set, unsigned int clear) |
709 | { | 1327 | { |
710 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1328 | struct moxa_port *ch; |
711 | int port; | 1329 | int port; |
712 | int dtr, rts; | 1330 | int dtr, rts; |
713 | 1331 | ||
714 | port = tty->index; | 1332 | port = tty->index; |
715 | if ((port != MAX_PORTS) && (!ch)) | 1333 | mutex_lock(&moxa_openlock); |
716 | return (-EINVAL); | 1334 | ch = tty->driver_data; |
1335 | if (!ch) { | ||
1336 | mutex_unlock(&moxa_openlock); | ||
1337 | return -EINVAL; | ||
1338 | } | ||
717 | 1339 | ||
718 | MoxaPortGetLineOut(ch->port, &dtr, &rts); | 1340 | MoxaPortGetLineOut(ch, &dtr, &rts); |
719 | if (set & TIOCM_RTS) | 1341 | if (set & TIOCM_RTS) |
720 | rts = 1; | 1342 | rts = 1; |
721 | if (set & TIOCM_DTR) | 1343 | if (set & TIOCM_DTR) |
@@ -724,105 +1346,51 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
724 | rts = 0; | 1346 | rts = 0; |
725 | if (clear & TIOCM_DTR) | 1347 | if (clear & TIOCM_DTR) |
726 | dtr = 0; | 1348 | dtr = 0; |
727 | MoxaPortLineCtrl(ch->port, dtr, rts); | 1349 | MoxaPortLineCtrl(ch, dtr, rts); |
1350 | mutex_unlock(&moxa_openlock); | ||
728 | return 0; | 1351 | return 0; |
729 | } | 1352 | } |
730 | 1353 | ||
731 | static int moxa_ioctl(struct tty_struct *tty, struct file *file, | ||
732 | unsigned int cmd, unsigned long arg) | ||
733 | { | ||
734 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | ||
735 | register int port; | ||
736 | void __user *argp = (void __user *)arg; | ||
737 | int retval; | ||
738 | |||
739 | port = tty->index; | ||
740 | if ((port != MAX_PORTS) && (!ch)) | ||
741 | return (-EINVAL); | ||
742 | |||
743 | switch (cmd) { | ||
744 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | ||
745 | retval = tty_check_change(tty); | ||
746 | if (retval) | ||
747 | return (retval); | ||
748 | moxa_setup_empty_event(tty); | ||
749 | tty_wait_until_sent(tty, 0); | ||
750 | if (!arg) | ||
751 | MoxaPortSendBreak(ch->port, 0); | ||
752 | return (0); | ||
753 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | ||
754 | retval = tty_check_change(tty); | ||
755 | if (retval) | ||
756 | return (retval); | ||
757 | moxa_setup_empty_event(tty); | ||
758 | tty_wait_until_sent(tty, 0); | ||
759 | MoxaPortSendBreak(ch->port, arg); | ||
760 | return (0); | ||
761 | case TIOCGSOFTCAR: | ||
762 | return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); | ||
763 | case TIOCSSOFTCAR: | ||
764 | if(get_user(retval, (unsigned long __user *) argp)) | ||
765 | return -EFAULT; | ||
766 | arg = retval; | ||
767 | tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | | ||
768 | (arg ? CLOCAL : 0)); | ||
769 | if (C_CLOCAL(tty)) | ||
770 | ch->asyncflags &= ~ASYNC_CHECK_CD; | ||
771 | else | ||
772 | ch->asyncflags |= ASYNC_CHECK_CD; | ||
773 | return (0); | ||
774 | case TIOCGSERIAL: | ||
775 | return moxa_get_serial_info(ch, argp); | ||
776 | |||
777 | case TIOCSSERIAL: | ||
778 | return moxa_set_serial_info(ch, argp); | ||
779 | default: | ||
780 | retval = MoxaDriverIoctl(cmd, arg, port); | ||
781 | } | ||
782 | return (retval); | ||
783 | } | ||
784 | |||
785 | static void moxa_throttle(struct tty_struct *tty) | 1354 | static void moxa_throttle(struct tty_struct *tty) |
786 | { | 1355 | { |
787 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1356 | struct moxa_port *ch = tty->driver_data; |
788 | 1357 | ||
789 | ch->statusflags |= THROTTLE; | 1358 | ch->statusflags |= THROTTLE; |
790 | } | 1359 | } |
791 | 1360 | ||
792 | static void moxa_unthrottle(struct tty_struct *tty) | 1361 | static void moxa_unthrottle(struct tty_struct *tty) |
793 | { | 1362 | { |
794 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1363 | struct moxa_port *ch = tty->driver_data; |
795 | 1364 | ||
796 | ch->statusflags &= ~THROTTLE; | 1365 | ch->statusflags &= ~THROTTLE; |
797 | } | 1366 | } |
798 | 1367 | ||
799 | static void moxa_set_termios(struct tty_struct *tty, | 1368 | static void moxa_set_termios(struct tty_struct *tty, |
800 | struct ktermios *old_termios) | 1369 | struct ktermios *old_termios) |
801 | { | 1370 | { |
802 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1371 | struct moxa_port *ch = tty->driver_data; |
803 | 1372 | ||
804 | if (ch == NULL) | 1373 | if (ch == NULL) |
805 | return; | 1374 | return; |
806 | moxa_set_tty_param(tty, old_termios); | 1375 | moxa_set_tty_param(tty, old_termios); |
807 | if (!(old_termios->c_cflag & CLOCAL) && | 1376 | if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) |
808 | (tty->termios->c_cflag & CLOCAL)) | ||
809 | wake_up_interruptible(&ch->open_wait); | 1377 | wake_up_interruptible(&ch->open_wait); |
810 | } | 1378 | } |
811 | 1379 | ||
812 | static void moxa_stop(struct tty_struct *tty) | 1380 | static void moxa_stop(struct tty_struct *tty) |
813 | { | 1381 | { |
814 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1382 | struct moxa_port *ch = tty->driver_data; |
815 | 1383 | ||
816 | if (ch == NULL) | 1384 | if (ch == NULL) |
817 | return; | 1385 | return; |
818 | MoxaPortTxDisable(ch->port); | 1386 | MoxaPortTxDisable(ch); |
819 | ch->statusflags |= TXSTOPPED; | 1387 | ch->statusflags |= TXSTOPPED; |
820 | } | 1388 | } |
821 | 1389 | ||
822 | 1390 | ||
823 | static void moxa_start(struct tty_struct *tty) | 1391 | static void moxa_start(struct tty_struct *tty) |
824 | { | 1392 | { |
825 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1393 | struct moxa_port *ch = tty->driver_data; |
826 | 1394 | ||
827 | if (ch == NULL) | 1395 | if (ch == NULL) |
828 | return; | 1396 | return; |
@@ -830,91 +1398,143 @@ static void moxa_start(struct tty_struct *tty) | |||
830 | if (!(ch->statusflags & TXSTOPPED)) | 1398 | if (!(ch->statusflags & TXSTOPPED)) |
831 | return; | 1399 | return; |
832 | 1400 | ||
833 | MoxaPortTxEnable(ch->port); | 1401 | MoxaPortTxEnable(ch); |
834 | ch->statusflags &= ~TXSTOPPED; | 1402 | ch->statusflags &= ~TXSTOPPED; |
835 | } | 1403 | } |
836 | 1404 | ||
837 | static void moxa_hangup(struct tty_struct *tty) | 1405 | static void moxa_hangup(struct tty_struct *tty) |
838 | { | 1406 | { |
839 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 1407 | struct moxa_port *ch; |
840 | 1408 | ||
841 | moxa_flush_buffer(tty); | 1409 | mutex_lock(&moxa_openlock); |
842 | moxa_shut_down(ch); | 1410 | ch = tty->driver_data; |
843 | ch->event = 0; | 1411 | if (ch == NULL) { |
1412 | mutex_unlock(&moxa_openlock); | ||
1413 | return; | ||
1414 | } | ||
844 | ch->count = 0; | 1415 | ch->count = 0; |
845 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | 1416 | moxa_close_port(ch); |
846 | ch->tty = NULL; | 1417 | mutex_unlock(&moxa_openlock); |
1418 | |||
847 | wake_up_interruptible(&ch->open_wait); | 1419 | wake_up_interruptible(&ch->open_wait); |
848 | } | 1420 | } |
849 | 1421 | ||
850 | static void moxa_poll(unsigned long ignored) | 1422 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) |
851 | { | 1423 | { |
852 | register int card; | 1424 | dcd = !!dcd; |
853 | struct moxa_port *ch; | ||
854 | struct tty_struct *tp; | ||
855 | int i, ports; | ||
856 | 1425 | ||
857 | del_timer(&moxaTimer); | 1426 | if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) { |
1427 | if (!dcd) | ||
1428 | tty_hangup(p->tty); | ||
1429 | } | ||
1430 | p->DCDState = dcd; | ||
1431 | } | ||
858 | 1432 | ||
859 | if (MoxaDriverPoll() < 0) { | 1433 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, |
860 | mod_timer(&moxaTimer, jiffies + HZ / 50); | 1434 | u16 __iomem *ip) |
861 | return; | 1435 | { |
1436 | struct tty_struct *tty = p->tty; | ||
1437 | void __iomem *ofsAddr; | ||
1438 | unsigned int inited = p->asyncflags & ASYNC_INITIALIZED; | ||
1439 | u16 intr; | ||
1440 | |||
1441 | if (tty) { | ||
1442 | if ((p->statusflags & EMPTYWAIT) && | ||
1443 | MoxaPortTxQueue(p) == 0) { | ||
1444 | p->statusflags &= ~EMPTYWAIT; | ||
1445 | tty_wakeup(tty); | ||
1446 | } | ||
1447 | if ((p->statusflags & LOWWAIT) && !tty->stopped && | ||
1448 | MoxaPortTxQueue(p) <= WAKEUP_CHARS) { | ||
1449 | p->statusflags &= ~LOWWAIT; | ||
1450 | tty_wakeup(tty); | ||
1451 | } | ||
1452 | |||
1453 | if (inited && !(p->statusflags & THROTTLE) && | ||
1454 | MoxaPortRxQueue(p) > 0) { /* RX */ | ||
1455 | MoxaPortReadData(p); | ||
1456 | tty_schedule_flip(tty); | ||
1457 | } | ||
1458 | } else { | ||
1459 | p->statusflags &= ~EMPTYWAIT; | ||
1460 | MoxaPortFlushData(p, 0); /* flush RX */ | ||
862 | } | 1461 | } |
1462 | |||
1463 | if (!handle) /* nothing else to do */ | ||
1464 | return 0; | ||
1465 | |||
1466 | intr = readw(ip); /* port irq status */ | ||
1467 | if (intr == 0) | ||
1468 | return 0; | ||
1469 | |||
1470 | writew(0, ip); /* ACK port */ | ||
1471 | ofsAddr = p->tableAddr; | ||
1472 | if (intr & IntrTx) /* disable tx intr */ | ||
1473 | writew(readw(ofsAddr + HostStat) & ~WakeupTx, | ||
1474 | ofsAddr + HostStat); | ||
1475 | |||
1476 | if (!inited) | ||
1477 | return 0; | ||
1478 | |||
1479 | if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ | ||
1480 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
1481 | tty_schedule_flip(tty); | ||
1482 | } | ||
1483 | |||
1484 | if (intr & IntrLine) | ||
1485 | moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); | ||
1486 | |||
1487 | return 0; | ||
1488 | } | ||
1489 | |||
1490 | static void moxa_poll(unsigned long ignored) | ||
1491 | { | ||
1492 | struct moxa_board_conf *brd; | ||
1493 | u16 __iomem *ip; | ||
1494 | unsigned int card, port, served = 0; | ||
1495 | |||
1496 | spin_lock(&moxa_lock); | ||
863 | for (card = 0; card < MAX_BOARDS; card++) { | 1497 | for (card = 0; card < MAX_BOARDS; card++) { |
864 | if ((ports = MoxaPortsOfCard(card)) <= 0) | 1498 | brd = &moxa_boards[card]; |
1499 | if (!brd->ready) | ||
865 | continue; | 1500 | continue; |
866 | ch = &moxa_ports[card * MAX_PORTS_PER_BOARD]; | 1501 | |
867 | for (i = 0; i < ports; i++, ch++) { | 1502 | served++; |
868 | if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) | 1503 | |
869 | continue; | 1504 | ip = NULL; |
870 | if (!(ch->statusflags & THROTTLE) && | 1505 | if (readb(brd->intPend) == 0xff) |
871 | (MoxaPortRxQueue(ch->port) > 0)) | 1506 | ip = brd->intTable + readb(brd->intNdx); |
872 | moxa_receive_data(ch); | 1507 | |
873 | if ((tp = ch->tty) == 0) | 1508 | for (port = 0; port < brd->numPorts; port++) |
874 | continue; | 1509 | moxa_poll_port(&brd->ports[port], !!ip, ip + port); |
875 | if (ch->statusflags & LOWWAIT) { | 1510 | |
876 | if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { | 1511 | if (ip) |
877 | if (!tp->stopped) { | 1512 | writeb(0, brd->intPend); /* ACK */ |
878 | ch->statusflags &= ~LOWWAIT; | 1513 | |
879 | tty_wakeup(tp); | 1514 | if (moxaLowWaterChk) { |
880 | } | 1515 | struct moxa_port *p = brd->ports; |
881 | } | 1516 | for (port = 0; port < brd->numPorts; port++, p++) |
882 | } | 1517 | if (p->lowChkFlag) { |
883 | if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) { | 1518 | p->lowChkFlag = 0; |
884 | tty_insert_flip_char(tp, 0, TTY_BREAK); | 1519 | moxa_low_water_check(p->tableAddr); |
885 | tty_schedule_flip(tp); | ||
886 | } | ||
887 | if (MoxaPortDCDChange(ch->port)) { | ||
888 | if (ch->asyncflags & ASYNC_CHECK_CD) { | ||
889 | if (MoxaPortDCDON(ch->port)) | ||
890 | wake_up_interruptible(&ch->open_wait); | ||
891 | else { | ||
892 | tty_hangup(tp); | ||
893 | wake_up_interruptible(&ch->open_wait); | ||
894 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | ||
895 | } | ||
896 | } | 1520 | } |
897 | } | ||
898 | } | 1521 | } |
899 | } | 1522 | } |
1523 | moxaLowWaterChk = 0; | ||
900 | 1524 | ||
901 | mod_timer(&moxaTimer, jiffies + HZ / 50); | 1525 | if (served) |
1526 | mod_timer(&moxaTimer, jiffies + HZ / 50); | ||
1527 | spin_unlock(&moxa_lock); | ||
902 | } | 1528 | } |
903 | 1529 | ||
904 | /******************************************************************************/ | 1530 | /******************************************************************************/ |
905 | 1531 | ||
906 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) | 1532 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) |
907 | { | 1533 | { |
908 | register struct ktermios *ts; | 1534 | register struct ktermios *ts = tty->termios; |
909 | struct moxa_port *ch; | 1535 | struct moxa_port *ch = tty->driver_data; |
910 | int rts, cts, txflow, rxflow, xany, baud; | 1536 | int rts, cts, txflow, rxflow, xany, baud; |
911 | 1537 | ||
912 | ch = (struct moxa_port *) tty->driver_data; | ||
913 | ts = tty->termios; | ||
914 | if (ts->c_cflag & CLOCAL) | ||
915 | ch->asyncflags &= ~ASYNC_CHECK_CD; | ||
916 | else | ||
917 | ch->asyncflags |= ASYNC_CHECK_CD; | ||
918 | rts = cts = txflow = rxflow = xany = 0; | 1538 | rts = cts = txflow = rxflow = xany = 0; |
919 | if (ts->c_cflag & CRTSCTS) | 1539 | if (ts->c_cflag & CRTSCTS) |
920 | rts = cts = 1; | 1540 | rts = cts = 1; |
@@ -927,776 +1547,60 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term | |||
927 | 1547 | ||
928 | /* Clear the features we don't support */ | 1548 | /* Clear the features we don't support */ |
929 | ts->c_cflag &= ~CMSPAR; | 1549 | ts->c_cflag &= ~CMSPAR; |
930 | MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany); | 1550 | MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany); |
931 | baud = MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); | 1551 | baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty)); |
932 | if (baud == -1) | 1552 | if (baud == -1) |
933 | baud = tty_termios_baud_rate(old_termios); | 1553 | baud = tty_termios_baud_rate(old_termios); |
934 | /* Not put the baud rate into the termios data */ | 1554 | /* Not put the baud rate into the termios data */ |
935 | tty_encode_baud_rate(tty, baud, baud); | 1555 | tty_encode_baud_rate(tty, baud, baud); |
936 | } | 1556 | } |
937 | 1557 | ||
938 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | ||
939 | struct moxa_port *ch) | ||
940 | { | ||
941 | DECLARE_WAITQUEUE(wait,current); | ||
942 | unsigned long flags; | ||
943 | int retval; | ||
944 | int do_clocal = C_CLOCAL(tty); | ||
945 | |||
946 | /* | ||
947 | * If the device is in the middle of being closed, then block | ||
948 | * until it's done, and then try again. | ||
949 | */ | ||
950 | if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { | ||
951 | if (ch->asyncflags & ASYNC_CLOSING) | ||
952 | wait_for_completion_interruptible(&ch->close_wait); | ||
953 | #ifdef SERIAL_DO_RESTART | ||
954 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) | ||
955 | return (-EAGAIN); | ||
956 | else | ||
957 | return (-ERESTARTSYS); | ||
958 | #else | ||
959 | return (-EAGAIN); | ||
960 | #endif | ||
961 | } | ||
962 | /* | ||
963 | * If non-blocking mode is set, then make the check up front | ||
964 | * and then exit. | ||
965 | */ | ||
966 | if (filp->f_flags & O_NONBLOCK) { | ||
967 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | ||
968 | return (0); | ||
969 | } | ||
970 | /* | ||
971 | * Block waiting for the carrier detect and the line to become free | ||
972 | */ | ||
973 | retval = 0; | ||
974 | add_wait_queue(&ch->open_wait, &wait); | ||
975 | pr_debug("block_til_ready before block: ttys%d, count = %d\n", | ||
976 | ch->port, ch->count); | ||
977 | spin_lock_irqsave(&moxa_lock, flags); | ||
978 | if (!tty_hung_up_p(filp)) | ||
979 | ch->count--; | ||
980 | ch->blocked_open++; | ||
981 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
982 | |||
983 | while (1) { | ||
984 | set_current_state(TASK_INTERRUPTIBLE); | ||
985 | if (tty_hung_up_p(filp) || | ||
986 | !(ch->asyncflags & ASYNC_INITIALIZED)) { | ||
987 | #ifdef SERIAL_DO_RESTART | ||
988 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) | ||
989 | retval = -EAGAIN; | ||
990 | else | ||
991 | retval = -ERESTARTSYS; | ||
992 | #else | ||
993 | retval = -EAGAIN; | ||
994 | #endif | ||
995 | break; | ||
996 | } | ||
997 | if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal || | ||
998 | MoxaPortDCDON(ch->port))) | ||
999 | break; | ||
1000 | |||
1001 | if (signal_pending(current)) { | ||
1002 | retval = -ERESTARTSYS; | ||
1003 | break; | ||
1004 | } | ||
1005 | schedule(); | ||
1006 | } | ||
1007 | set_current_state(TASK_RUNNING); | ||
1008 | remove_wait_queue(&ch->open_wait, &wait); | ||
1009 | |||
1010 | spin_lock_irqsave(&moxa_lock, flags); | ||
1011 | if (!tty_hung_up_p(filp)) | ||
1012 | ch->count++; | ||
1013 | ch->blocked_open--; | ||
1014 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1015 | pr_debug("block_til_ready after blocking: ttys%d, count = %d\n", | ||
1016 | ch->port, ch->count); | ||
1017 | if (retval) | ||
1018 | return (retval); | ||
1019 | /* FIXME: review to see if we need to use set_bit on these */ | ||
1020 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | ||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static void moxa_setup_empty_event(struct tty_struct *tty) | 1558 | static void moxa_setup_empty_event(struct tty_struct *tty) |
1025 | { | 1559 | { |
1026 | struct moxa_port *ch = tty->driver_data; | 1560 | struct moxa_port *ch = tty->driver_data; |
1027 | unsigned long flags; | ||
1028 | 1561 | ||
1029 | spin_lock_irqsave(&moxa_lock, flags); | 1562 | spin_lock_bh(&moxa_lock); |
1030 | ch->statusflags |= EMPTYWAIT; | 1563 | ch->statusflags |= EMPTYWAIT; |
1031 | mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); | 1564 | spin_unlock_bh(&moxa_lock); |
1032 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1033 | } | ||
1034 | |||
1035 | static void moxa_check_xmit_empty(unsigned long data) | ||
1036 | { | ||
1037 | struct moxa_port *ch; | ||
1038 | |||
1039 | ch = (struct moxa_port *) data; | ||
1040 | if (ch->tty && (ch->statusflags & EMPTYWAIT)) { | ||
1041 | if (MoxaPortTxQueue(ch->port) == 0) { | ||
1042 | ch->statusflags &= ~EMPTYWAIT; | ||
1043 | tty_wakeup(ch->tty); | ||
1044 | return; | ||
1045 | } | ||
1046 | mod_timer(&moxa_ports[ch->port].emptyTimer, | ||
1047 | round_jiffies(jiffies + HZ)); | ||
1048 | } else | ||
1049 | ch->statusflags &= ~EMPTYWAIT; | ||
1050 | } | 1565 | } |
1051 | 1566 | ||
1052 | static void moxa_shut_down(struct moxa_port *ch) | 1567 | static void moxa_shut_down(struct moxa_port *ch) |
1053 | { | 1568 | { |
1054 | struct tty_struct *tp; | 1569 | struct tty_struct *tp = ch->tty; |
1055 | 1570 | ||
1056 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) | 1571 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) |
1057 | return; | 1572 | return; |
1058 | 1573 | ||
1059 | tp = ch->tty; | 1574 | MoxaPortDisable(ch); |
1060 | |||
1061 | MoxaPortDisable(ch->port); | ||
1062 | 1575 | ||
1063 | /* | 1576 | /* |
1064 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. | 1577 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. |
1065 | */ | 1578 | */ |
1066 | if (tp->termios->c_cflag & HUPCL) | 1579 | if (C_HUPCL(tp)) |
1067 | MoxaPortLineCtrl(ch->port, 0, 0); | 1580 | MoxaPortLineCtrl(ch, 0, 0); |
1068 | 1581 | ||
1582 | spin_lock_bh(&moxa_lock); | ||
1069 | ch->asyncflags &= ~ASYNC_INITIALIZED; | 1583 | ch->asyncflags &= ~ASYNC_INITIALIZED; |
1584 | spin_unlock_bh(&moxa_lock); | ||
1070 | } | 1585 | } |
1071 | 1586 | ||
1072 | static void moxa_receive_data(struct moxa_port *ch) | ||
1073 | { | ||
1074 | struct tty_struct *tp; | ||
1075 | struct ktermios *ts; | ||
1076 | unsigned long flags; | ||
1077 | |||
1078 | ts = NULL; | ||
1079 | tp = ch->tty; | ||
1080 | if (tp) | ||
1081 | ts = tp->termios; | ||
1082 | /************************************************** | ||
1083 | if ( !tp || !ts || !(ts->c_cflag & CREAD) ) { | ||
1084 | *****************************************************/ | ||
1085 | if (!tp || !ts) { | ||
1086 | MoxaPortFlushData(ch->port, 0); | ||
1087 | return; | ||
1088 | } | ||
1089 | spin_lock_irqsave(&moxa_lock, flags); | ||
1090 | MoxaPortReadData(ch->port, tp); | ||
1091 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1092 | tty_schedule_flip(tp); | ||
1093 | } | ||
1094 | |||
1095 | #define Magic_code 0x404 | ||
1096 | |||
1097 | /* | ||
1098 | * System Configuration | ||
1099 | */ | ||
1100 | /* | ||
1101 | * for C218 BIOS initialization | ||
1102 | */ | ||
1103 | #define C218_ConfBase 0x800 | ||
1104 | #define C218_status (C218_ConfBase + 0) /* BIOS running status */ | ||
1105 | #define C218_diag (C218_ConfBase + 2) /* diagnostic status */ | ||
1106 | #define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ | ||
1107 | #define C218DLoad_len (C218_ConfBase + 6) /* WORD */ | ||
1108 | #define C218check_sum (C218_ConfBase + 8) /* BYTE */ | ||
1109 | #define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ | ||
1110 | #define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ | ||
1111 | #define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ | ||
1112 | #define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ | ||
1113 | #define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ | ||
1114 | |||
1115 | #define C218_LoadBuf 0x0F00 | ||
1116 | #define C218_KeyCode 0x218 | ||
1117 | #define CP204J_KeyCode 0x204 | ||
1118 | |||
1119 | /* | ||
1120 | * for C320 BIOS initialization | ||
1121 | */ | ||
1122 | #define C320_ConfBase 0x800 | ||
1123 | #define C320_LoadBuf 0x0f00 | ||
1124 | #define STS_init 0x05 /* for C320_status */ | ||
1125 | |||
1126 | #define C320_status C320_ConfBase + 0 /* BIOS running status */ | ||
1127 | #define C320_diag C320_ConfBase + 2 /* diagnostic status */ | ||
1128 | #define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ | ||
1129 | #define C320DLoad_len C320_ConfBase + 6 /* WORD */ | ||
1130 | #define C320check_sum C320_ConfBase + 8 /* WORD */ | ||
1131 | #define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ | ||
1132 | #define C320bapi_len C320_ConfBase + 0x0c /* WORD */ | ||
1133 | #define C320UART_no C320_ConfBase + 0x0e /* WORD */ | ||
1134 | |||
1135 | #define C320_KeyCode 0x320 | ||
1136 | |||
1137 | #define FixPage_addr 0x0000 /* starting addr of static page */ | ||
1138 | #define DynPage_addr 0x2000 /* starting addr of dynamic page */ | ||
1139 | #define C218_start 0x3000 /* starting addr of C218 BIOS prg */ | ||
1140 | #define Control_reg 0x1ff0 /* select page and reset control */ | ||
1141 | #define HW_reset 0x80 | ||
1142 | |||
1143 | /* | ||
1144 | * Function Codes | ||
1145 | */ | ||
1146 | #define FC_CardReset 0x80 | ||
1147 | #define FC_ChannelReset 1 /* C320 firmware not supported */ | ||
1148 | #define FC_EnableCH 2 | ||
1149 | #define FC_DisableCH 3 | ||
1150 | #define FC_SetParam 4 | ||
1151 | #define FC_SetMode 5 | ||
1152 | #define FC_SetRate 6 | ||
1153 | #define FC_LineControl 7 | ||
1154 | #define FC_LineStatus 8 | ||
1155 | #define FC_XmitControl 9 | ||
1156 | #define FC_FlushQueue 10 | ||
1157 | #define FC_SendBreak 11 | ||
1158 | #define FC_StopBreak 12 | ||
1159 | #define FC_LoopbackON 13 | ||
1160 | #define FC_LoopbackOFF 14 | ||
1161 | #define FC_ClrIrqTable 15 | ||
1162 | #define FC_SendXon 16 | ||
1163 | #define FC_SetTermIrq 17 /* C320 firmware not supported */ | ||
1164 | #define FC_SetCntIrq 18 /* C320 firmware not supported */ | ||
1165 | #define FC_SetBreakIrq 19 | ||
1166 | #define FC_SetLineIrq 20 | ||
1167 | #define FC_SetFlowCtl 21 | ||
1168 | #define FC_GenIrq 22 | ||
1169 | #define FC_InCD180 23 | ||
1170 | #define FC_OutCD180 24 | ||
1171 | #define FC_InUARTreg 23 | ||
1172 | #define FC_OutUARTreg 24 | ||
1173 | #define FC_SetXonXoff 25 | ||
1174 | #define FC_OutCD180CCR 26 | ||
1175 | #define FC_ExtIQueue 27 | ||
1176 | #define FC_ExtOQueue 28 | ||
1177 | #define FC_ClrLineIrq 29 | ||
1178 | #define FC_HWFlowCtl 30 | ||
1179 | #define FC_GetClockRate 35 | ||
1180 | #define FC_SetBaud 36 | ||
1181 | #define FC_SetDataMode 41 | ||
1182 | #define FC_GetCCSR 43 | ||
1183 | #define FC_GetDataError 45 | ||
1184 | #define FC_RxControl 50 | ||
1185 | #define FC_ImmSend 51 | ||
1186 | #define FC_SetXonState 52 | ||
1187 | #define FC_SetXoffState 53 | ||
1188 | #define FC_SetRxFIFOTrig 54 | ||
1189 | #define FC_SetTxFIFOCnt 55 | ||
1190 | #define FC_UnixRate 56 | ||
1191 | #define FC_UnixResetTimer 57 | ||
1192 | |||
1193 | #define RxFIFOTrig1 0 | ||
1194 | #define RxFIFOTrig4 1 | ||
1195 | #define RxFIFOTrig8 2 | ||
1196 | #define RxFIFOTrig14 3 | ||
1197 | |||
1198 | /* | ||
1199 | * Dual-Ported RAM | ||
1200 | */ | ||
1201 | #define DRAM_global 0 | ||
1202 | #define INT_data (DRAM_global + 0) | ||
1203 | #define Config_base (DRAM_global + 0x108) | ||
1204 | |||
1205 | #define IRQindex (INT_data + 0) | ||
1206 | #define IRQpending (INT_data + 4) | ||
1207 | #define IRQtable (INT_data + 8) | ||
1208 | |||
1209 | /* | ||
1210 | * Interrupt Status | ||
1211 | */ | ||
1212 | #define IntrRx 0x01 /* receiver data O.K. */ | ||
1213 | #define IntrTx 0x02 /* transmit buffer empty */ | ||
1214 | #define IntrFunc 0x04 /* function complete */ | ||
1215 | #define IntrBreak 0x08 /* received break */ | ||
1216 | #define IntrLine 0x10 /* line status change | ||
1217 | for transmitter */ | ||
1218 | #define IntrIntr 0x20 /* received INTR code */ | ||
1219 | #define IntrQuit 0x40 /* received QUIT code */ | ||
1220 | #define IntrEOF 0x80 /* received EOF code */ | ||
1221 | |||
1222 | #define IntrRxTrigger 0x100 /* rx data count reach tigger value */ | ||
1223 | #define IntrTxTrigger 0x200 /* tx data count below trigger value */ | ||
1224 | |||
1225 | #define Magic_no (Config_base + 0) | ||
1226 | #define Card_model_no (Config_base + 2) | ||
1227 | #define Total_ports (Config_base + 4) | ||
1228 | #define Module_cnt (Config_base + 8) | ||
1229 | #define Module_no (Config_base + 10) | ||
1230 | #define Timer_10ms (Config_base + 14) | ||
1231 | #define Disable_IRQ (Config_base + 20) | ||
1232 | #define TMS320_PORT1 (Config_base + 22) | ||
1233 | #define TMS320_PORT2 (Config_base + 24) | ||
1234 | #define TMS320_CLOCK (Config_base + 26) | ||
1235 | |||
1236 | /* | ||
1237 | * DATA BUFFER in DRAM | ||
1238 | */ | ||
1239 | #define Extern_table 0x400 /* Base address of the external table | ||
1240 | (24 words * 64) total 3K bytes | ||
1241 | (24 words * 128) total 6K bytes */ | ||
1242 | #define Extern_size 0x60 /* 96 bytes */ | ||
1243 | #define RXrptr 0x00 /* read pointer for RX buffer */ | ||
1244 | #define RXwptr 0x02 /* write pointer for RX buffer */ | ||
1245 | #define TXrptr 0x04 /* read pointer for TX buffer */ | ||
1246 | #define TXwptr 0x06 /* write pointer for TX buffer */ | ||
1247 | #define HostStat 0x08 /* IRQ flag and general flag */ | ||
1248 | #define FlagStat 0x0A | ||
1249 | #define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ | ||
1250 | /* x x x x | | | | */ | ||
1251 | /* | | | + CTS flow */ | ||
1252 | /* | | +--- RTS flow */ | ||
1253 | /* | +------ TX Xon/Xoff */ | ||
1254 | /* +--------- RX Xon/Xoff */ | ||
1255 | #define Break_cnt 0x0E /* received break count */ | ||
1256 | #define CD180TXirq 0x10 /* if non-0: enable TX irq */ | ||
1257 | #define RX_mask 0x12 | ||
1258 | #define TX_mask 0x14 | ||
1259 | #define Ofs_rxb 0x16 | ||
1260 | #define Ofs_txb 0x18 | ||
1261 | #define Page_rxb 0x1A | ||
1262 | #define Page_txb 0x1C | ||
1263 | #define EndPage_rxb 0x1E | ||
1264 | #define EndPage_txb 0x20 | ||
1265 | #define Data_error 0x22 | ||
1266 | #define RxTrigger 0x28 | ||
1267 | #define TxTrigger 0x2a | ||
1268 | |||
1269 | #define rRXwptr 0x34 | ||
1270 | #define Low_water 0x36 | ||
1271 | |||
1272 | #define FuncCode 0x40 | ||
1273 | #define FuncArg 0x42 | ||
1274 | #define FuncArg1 0x44 | ||
1275 | |||
1276 | #define C218rx_size 0x2000 /* 8K bytes */ | ||
1277 | #define C218tx_size 0x8000 /* 32K bytes */ | ||
1278 | |||
1279 | #define C218rx_mask (C218rx_size - 1) | ||
1280 | #define C218tx_mask (C218tx_size - 1) | ||
1281 | |||
1282 | #define C320p8rx_size 0x2000 | ||
1283 | #define C320p8tx_size 0x8000 | ||
1284 | #define C320p8rx_mask (C320p8rx_size - 1) | ||
1285 | #define C320p8tx_mask (C320p8tx_size - 1) | ||
1286 | |||
1287 | #define C320p16rx_size 0x2000 | ||
1288 | #define C320p16tx_size 0x4000 | ||
1289 | #define C320p16rx_mask (C320p16rx_size - 1) | ||
1290 | #define C320p16tx_mask (C320p16tx_size - 1) | ||
1291 | |||
1292 | #define C320p24rx_size 0x2000 | ||
1293 | #define C320p24tx_size 0x2000 | ||
1294 | #define C320p24rx_mask (C320p24rx_size - 1) | ||
1295 | #define C320p24tx_mask (C320p24tx_size - 1) | ||
1296 | |||
1297 | #define C320p32rx_size 0x1000 | ||
1298 | #define C320p32tx_size 0x1000 | ||
1299 | #define C320p32rx_mask (C320p32rx_size - 1) | ||
1300 | #define C320p32tx_mask (C320p32tx_size - 1) | ||
1301 | |||
1302 | #define Page_size 0x2000 | ||
1303 | #define Page_mask (Page_size - 1) | ||
1304 | #define C218rx_spage 3 | ||
1305 | #define C218tx_spage 4 | ||
1306 | #define C218rx_pageno 1 | ||
1307 | #define C218tx_pageno 4 | ||
1308 | #define C218buf_pageno 5 | ||
1309 | |||
1310 | #define C320p8rx_spage 3 | ||
1311 | #define C320p8tx_spage 4 | ||
1312 | #define C320p8rx_pgno 1 | ||
1313 | #define C320p8tx_pgno 4 | ||
1314 | #define C320p8buf_pgno 5 | ||
1315 | |||
1316 | #define C320p16rx_spage 3 | ||
1317 | #define C320p16tx_spage 4 | ||
1318 | #define C320p16rx_pgno 1 | ||
1319 | #define C320p16tx_pgno 2 | ||
1320 | #define C320p16buf_pgno 3 | ||
1321 | |||
1322 | #define C320p24rx_spage 3 | ||
1323 | #define C320p24tx_spage 4 | ||
1324 | #define C320p24rx_pgno 1 | ||
1325 | #define C320p24tx_pgno 1 | ||
1326 | #define C320p24buf_pgno 2 | ||
1327 | |||
1328 | #define C320p32rx_spage 3 | ||
1329 | #define C320p32tx_ofs C320p32rx_size | ||
1330 | #define C320p32tx_spage 3 | ||
1331 | #define C320p32buf_pgno 1 | ||
1332 | |||
1333 | /* | ||
1334 | * Host Status | ||
1335 | */ | ||
1336 | #define WakeupRx 0x01 | ||
1337 | #define WakeupTx 0x02 | ||
1338 | #define WakeupBreak 0x08 | ||
1339 | #define WakeupLine 0x10 | ||
1340 | #define WakeupIntr 0x20 | ||
1341 | #define WakeupQuit 0x40 | ||
1342 | #define WakeupEOF 0x80 /* used in VTIME control */ | ||
1343 | #define WakeupRxTrigger 0x100 | ||
1344 | #define WakeupTxTrigger 0x200 | ||
1345 | /* | ||
1346 | * Flag status | ||
1347 | */ | ||
1348 | #define Rx_over 0x01 | ||
1349 | #define Xoff_state 0x02 | ||
1350 | #define Tx_flowOff 0x04 | ||
1351 | #define Tx_enable 0x08 | ||
1352 | #define CTS_state 0x10 | ||
1353 | #define DSR_state 0x20 | ||
1354 | #define DCD_state 0x80 | ||
1355 | /* | ||
1356 | * FlowControl | ||
1357 | */ | ||
1358 | #define CTS_FlowCtl 1 | ||
1359 | #define RTS_FlowCtl 2 | ||
1360 | #define Tx_FlowCtl 4 | ||
1361 | #define Rx_FlowCtl 8 | ||
1362 | #define IXM_IXANY 0x10 | ||
1363 | |||
1364 | #define LowWater 128 | ||
1365 | |||
1366 | #define DTR_ON 1 | ||
1367 | #define RTS_ON 2 | ||
1368 | #define CTS_ON 1 | ||
1369 | #define DSR_ON 2 | ||
1370 | #define DCD_ON 8 | ||
1371 | |||
1372 | /* mode definition */ | ||
1373 | #define MX_CS8 0x03 | ||
1374 | #define MX_CS7 0x02 | ||
1375 | #define MX_CS6 0x01 | ||
1376 | #define MX_CS5 0x00 | ||
1377 | |||
1378 | #define MX_STOP1 0x00 | ||
1379 | #define MX_STOP15 0x04 | ||
1380 | #define MX_STOP2 0x08 | ||
1381 | |||
1382 | #define MX_PARNONE 0x00 | ||
1383 | #define MX_PAREVEN 0x40 | ||
1384 | #define MX_PARODD 0xC0 | ||
1385 | |||
1386 | /* | ||
1387 | * Query | ||
1388 | */ | ||
1389 | |||
1390 | struct mon_str { | ||
1391 | int tick; | ||
1392 | int rxcnt[MAX_PORTS]; | ||
1393 | int txcnt[MAX_PORTS]; | ||
1394 | }; | ||
1395 | |||
1396 | #define DCD_changed 0x01 | ||
1397 | #define DCD_oldstate 0x80 | ||
1398 | |||
1399 | static unsigned char moxaBuff[10240]; | ||
1400 | static int moxaLowWaterChk; | ||
1401 | static int moxaCard; | ||
1402 | static struct mon_str moxaLog; | ||
1403 | static int moxaFuncTout = HZ / 2; | ||
1404 | |||
1405 | static void moxafunc(void __iomem *, int, ushort); | ||
1406 | static void moxa_wait_finish(void __iomem *); | ||
1407 | static void moxa_low_water_check(void __iomem *); | ||
1408 | static int moxaloadbios(int, unsigned char __user *, int); | ||
1409 | static int moxafindcard(int); | ||
1410 | static int moxaload320b(int, unsigned char __user *, int); | ||
1411 | static int moxaloadcode(int, unsigned char __user *, int); | ||
1412 | static int moxaloadc218(int, void __iomem *, int); | ||
1413 | static int moxaloadc320(int, void __iomem *, int, int *); | ||
1414 | |||
1415 | /***************************************************************************** | 1587 | /***************************************************************************** |
1416 | * Driver level functions: * | 1588 | * Driver level functions: * |
1417 | * 1. MoxaDriverInit(void); * | ||
1418 | * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); * | ||
1419 | * 3. MoxaDriverPoll(void); * | ||
1420 | *****************************************************************************/ | 1589 | *****************************************************************************/ |
1421 | void MoxaDriverInit(void) | ||
1422 | { | ||
1423 | struct moxa_port *p; | ||
1424 | unsigned int i; | ||
1425 | 1590 | ||
1426 | moxaFuncTout = HZ / 2; /* 500 mini-seconds */ | 1591 | static void MoxaPortFlushData(struct moxa_port *port, int mode) |
1427 | moxaCard = 0; | ||
1428 | moxaLog.tick = 0; | ||
1429 | moxaLowWaterChk = 0; | ||
1430 | for (i = 0; i < MAX_PORTS; i++) { | ||
1431 | p = &moxa_ports[i]; | ||
1432 | p->chkPort = 0; | ||
1433 | p->lowChkFlag = 0; | ||
1434 | p->lineCtrl = 0; | ||
1435 | moxaLog.rxcnt[i] = 0; | ||
1436 | moxaLog.txcnt[i] = 0; | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | #define MOXA 0x400 | ||
1441 | #define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ | ||
1442 | #define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ | ||
1443 | #define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */ | ||
1444 | #define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */ | ||
1445 | #define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */ | ||
1446 | #define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */ | ||
1447 | #define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */ | ||
1448 | #define MOXA_GETDATACOUNT (MOXA + 23) | ||
1449 | #define MOXA_GET_IOQUEUE (MOXA + 27) | ||
1450 | #define MOXA_FLUSH_QUEUE (MOXA + 28) | ||
1451 | #define MOXA_GET_CONF (MOXA + 35) /* configuration */ | ||
1452 | #define MOXA_GET_MAJOR (MOXA + 63) | ||
1453 | #define MOXA_GET_CUMAJOR (MOXA + 64) | ||
1454 | #define MOXA_GETMSTATUS (MOXA + 65) | ||
1455 | |||
1456 | struct dl_str { | ||
1457 | char __user *buf; | ||
1458 | int len; | ||
1459 | int cardno; | ||
1460 | }; | ||
1461 | |||
1462 | static struct dl_str dltmp; | ||
1463 | |||
1464 | void MoxaPortFlushData(int port, int mode) | ||
1465 | { | 1592 | { |
1466 | void __iomem *ofsAddr; | 1593 | void __iomem *ofsAddr; |
1467 | if ((mode < 0) || (mode > 2)) | 1594 | if (mode < 0 || mode > 2) |
1468 | return; | 1595 | return; |
1469 | ofsAddr = moxa_ports[port].tableAddr; | 1596 | ofsAddr = port->tableAddr; |
1470 | moxafunc(ofsAddr, FC_FlushQueue, mode); | 1597 | moxafunc(ofsAddr, FC_FlushQueue, mode); |
1471 | if (mode != 1) { | 1598 | if (mode != 1) { |
1472 | moxa_ports[port].lowChkFlag = 0; | 1599 | port->lowChkFlag = 0; |
1473 | moxa_low_water_check(ofsAddr); | 1600 | moxa_low_water_check(ofsAddr); |
1474 | } | 1601 | } |
1475 | } | 1602 | } |
1476 | 1603 | ||
1477 | int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) | ||
1478 | { | ||
1479 | int i; | ||
1480 | int status; | ||
1481 | int MoxaPortTxQueue(int), MoxaPortRxQueue(int); | ||
1482 | void __user *argp = (void __user *)arg; | ||
1483 | |||
1484 | if (port == MAX_PORTS) { | ||
1485 | if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) && | ||
1486 | (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) && | ||
1487 | (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) && | ||
1488 | (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) && | ||
1489 | (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS)) | ||
1490 | return (-EINVAL); | ||
1491 | } | ||
1492 | switch (cmd) { | ||
1493 | case MOXA_GET_CONF: | ||
1494 | if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * | ||
1495 | sizeof(struct moxa_board_conf))) | ||
1496 | return -EFAULT; | ||
1497 | return (0); | ||
1498 | case MOXA_INIT_DRIVER: | ||
1499 | if ((int) arg == 0x404) | ||
1500 | MoxaDriverInit(); | ||
1501 | return (0); | ||
1502 | case MOXA_GETDATACOUNT: | ||
1503 | moxaLog.tick = jiffies; | ||
1504 | if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str))) | ||
1505 | return -EFAULT; | ||
1506 | return (0); | ||
1507 | case MOXA_FLUSH_QUEUE: | ||
1508 | MoxaPortFlushData(port, arg); | ||
1509 | return (0); | ||
1510 | case MOXA_GET_IOQUEUE: { | ||
1511 | struct moxaq_str __user *argm = argp; | ||
1512 | struct moxaq_str tmp; | ||
1513 | |||
1514 | for (i = 0; i < MAX_PORTS; i++, argm++) { | ||
1515 | memset(&tmp, 0, sizeof(tmp)); | ||
1516 | if (moxa_ports[i].chkPort) { | ||
1517 | tmp.inq = MoxaPortRxQueue(i); | ||
1518 | tmp.outq = MoxaPortTxQueue(i); | ||
1519 | } | ||
1520 | if (copy_to_user(argm, &tmp, sizeof(tmp))) | ||
1521 | return -EFAULT; | ||
1522 | } | ||
1523 | return (0); | ||
1524 | } case MOXA_GET_OQUEUE: | ||
1525 | i = MoxaPortTxQueue(port); | ||
1526 | return put_user(i, (unsigned long __user *)argp); | ||
1527 | case MOXA_GET_IQUEUE: | ||
1528 | i = MoxaPortRxQueue(port); | ||
1529 | return put_user(i, (unsigned long __user *)argp); | ||
1530 | case MOXA_GET_MAJOR: | ||
1531 | if(copy_to_user(argp, &ttymajor, sizeof(int))) | ||
1532 | return -EFAULT; | ||
1533 | return 0; | ||
1534 | case MOXA_GET_CUMAJOR: | ||
1535 | i = 0; | ||
1536 | if(copy_to_user(argp, &i, sizeof(int))) | ||
1537 | return -EFAULT; | ||
1538 | return 0; | ||
1539 | case MOXA_GETMSTATUS: { | ||
1540 | struct mxser_mstatus __user *argm = argp; | ||
1541 | struct mxser_mstatus tmp; | ||
1542 | struct moxa_port *p; | ||
1543 | |||
1544 | for (i = 0; i < MAX_PORTS; i++, argm++) { | ||
1545 | p = &moxa_ports[i]; | ||
1546 | memset(&tmp, 0, sizeof(tmp)); | ||
1547 | if (!p->chkPort) { | ||
1548 | goto copy; | ||
1549 | } else { | ||
1550 | status = MoxaPortLineStatus(p->port); | ||
1551 | if (status & 1) | ||
1552 | tmp.cts = 1; | ||
1553 | if (status & 2) | ||
1554 | tmp.dsr = 1; | ||
1555 | if (status & 4) | ||
1556 | tmp.dcd = 1; | ||
1557 | } | ||
1558 | |||
1559 | if (!p->tty || !p->tty->termios) | ||
1560 | tmp.cflag = p->cflag; | ||
1561 | else | ||
1562 | tmp.cflag = p->tty->termios->c_cflag; | ||
1563 | copy: | ||
1564 | if (copy_to_user(argm, &tmp, sizeof(tmp))) | ||
1565 | return -EFAULT; | ||
1566 | } | ||
1567 | return 0; | ||
1568 | } default: | ||
1569 | return (-ENOIOCTLCMD); | ||
1570 | case MOXA_LOAD_BIOS: | ||
1571 | case MOXA_FIND_BOARD: | ||
1572 | case MOXA_LOAD_C320B: | ||
1573 | case MOXA_LOAD_CODE: | ||
1574 | if (!capable(CAP_SYS_RAWIO)) | ||
1575 | return -EPERM; | ||
1576 | break; | ||
1577 | } | ||
1578 | |||
1579 | if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) | ||
1580 | return -EFAULT; | ||
1581 | if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0) | ||
1582 | return -EINVAL; | ||
1583 | |||
1584 | switch(cmd) | ||
1585 | { | ||
1586 | case MOXA_LOAD_BIOS: | ||
1587 | i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len); | ||
1588 | return (i); | ||
1589 | case MOXA_FIND_BOARD: | ||
1590 | return moxafindcard(dltmp.cardno); | ||
1591 | case MOXA_LOAD_C320B: | ||
1592 | moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len); | ||
1593 | default: /* to keep gcc happy */ | ||
1594 | return (0); | ||
1595 | case MOXA_LOAD_CODE: | ||
1596 | i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len); | ||
1597 | if (i == -1) | ||
1598 | return (-EFAULT); | ||
1599 | return (i); | ||
1600 | |||
1601 | } | ||
1602 | } | ||
1603 | |||
1604 | int MoxaDriverPoll(void) | ||
1605 | { | ||
1606 | struct moxa_board_conf *brd; | ||
1607 | register ushort temp; | ||
1608 | register int card; | ||
1609 | void __iomem *ofsAddr; | ||
1610 | void __iomem *ip; | ||
1611 | int port, p, ports; | ||
1612 | |||
1613 | if (moxaCard == 0) | ||
1614 | return (-1); | ||
1615 | for (card = 0; card < MAX_BOARDS; card++) { | ||
1616 | brd = &moxa_boards[card]; | ||
1617 | if (brd->loadstat == 0) | ||
1618 | continue; | ||
1619 | if ((ports = brd->numPorts) == 0) | ||
1620 | continue; | ||
1621 | if (readb(brd->intPend) == 0xff) { | ||
1622 | ip = brd->intTable + readb(brd->intNdx); | ||
1623 | p = card * MAX_PORTS_PER_BOARD; | ||
1624 | ports <<= 1; | ||
1625 | for (port = 0; port < ports; port += 2, p++) { | ||
1626 | if ((temp = readw(ip + port)) != 0) { | ||
1627 | writew(0, ip + port); | ||
1628 | ofsAddr = moxa_ports[p].tableAddr; | ||
1629 | if (temp & IntrTx) | ||
1630 | writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat); | ||
1631 | if (temp & IntrBreak) { | ||
1632 | moxa_ports[p].breakCnt++; | ||
1633 | } | ||
1634 | if (temp & IntrLine) { | ||
1635 | if (readb(ofsAddr + FlagStat) & DCD_state) { | ||
1636 | if ((moxa_ports[p].DCDState & DCD_oldstate) == 0) | ||
1637 | moxa_ports[p].DCDState = (DCD_oldstate | | ||
1638 | DCD_changed); | ||
1639 | } else { | ||
1640 | if (moxa_ports[p].DCDState & DCD_oldstate) | ||
1641 | moxa_ports[p].DCDState = DCD_changed; | ||
1642 | } | ||
1643 | } | ||
1644 | } | ||
1645 | } | ||
1646 | writeb(0, brd->intPend); | ||
1647 | } | ||
1648 | if (moxaLowWaterChk) { | ||
1649 | p = card * MAX_PORTS_PER_BOARD; | ||
1650 | for (port = 0; port < ports; port++, p++) { | ||
1651 | if (moxa_ports[p].lowChkFlag) { | ||
1652 | moxa_ports[p].lowChkFlag = 0; | ||
1653 | ofsAddr = moxa_ports[p].tableAddr; | ||
1654 | moxa_low_water_check(ofsAddr); | ||
1655 | } | ||
1656 | } | ||
1657 | } | ||
1658 | } | ||
1659 | moxaLowWaterChk = 0; | ||
1660 | return (0); | ||
1661 | } | ||
1662 | |||
1663 | /***************************************************************************** | ||
1664 | * Card level function: * | ||
1665 | * 1. MoxaPortsOfCard(int cardno); * | ||
1666 | *****************************************************************************/ | ||
1667 | int MoxaPortsOfCard(int cardno) | ||
1668 | { | ||
1669 | |||
1670 | if (moxa_boards[cardno].boardType == 0) | ||
1671 | return (0); | ||
1672 | return (moxa_boards[cardno].numPorts); | ||
1673 | } | ||
1674 | |||
1675 | /***************************************************************************** | ||
1676 | * Port level functions: * | ||
1677 | * 1. MoxaPortIsValid(int port); * | ||
1678 | * 2. MoxaPortEnable(int port); * | ||
1679 | * 3. MoxaPortDisable(int port); * | ||
1680 | * 4. MoxaPortGetMaxBaud(int port); * | ||
1681 | * 6. MoxaPortSetBaud(int port, long baud); * | ||
1682 | * 8. MoxaPortSetTermio(int port, unsigned char *termio); * | ||
1683 | * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); * | ||
1684 | * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * | ||
1685 | * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); * | ||
1686 | * 12. MoxaPortLineStatus(int port); * | ||
1687 | * 13. MoxaPortDCDChange(int port); * | ||
1688 | * 14. MoxaPortDCDON(int port); * | ||
1689 | * 15. MoxaPortFlushData(int port, int mode); * | ||
1690 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * | ||
1691 | * 17. MoxaPortReadData(int port, struct tty_struct *tty); * | ||
1692 | * 20. MoxaPortTxQueue(int port); * | ||
1693 | * 21. MoxaPortTxFree(int port); * | ||
1694 | * 22. MoxaPortRxQueue(int port); * | ||
1695 | * 24. MoxaPortTxDisable(int port); * | ||
1696 | * 25. MoxaPortTxEnable(int port); * | ||
1697 | * 27. MoxaPortResetBrkCnt(int port); * | ||
1698 | * 30. MoxaPortSendBreak(int port, int ticks); * | ||
1699 | *****************************************************************************/ | ||
1700 | /* | 1604 | /* |
1701 | * Moxa Port Number Description: | 1605 | * Moxa Port Number Description: |
1702 | * | 1606 | * |
@@ -1733,33 +1637,6 @@ int MoxaPortsOfCard(int cardno) | |||
1733 | * -ENOIOCTLCMD | 1637 | * -ENOIOCTLCMD |
1734 | * | 1638 | * |
1735 | * | 1639 | * |
1736 | * Function 3: Moxa driver polling process routine. | ||
1737 | * Syntax: | ||
1738 | * int MoxaDriverPoll(void); | ||
1739 | * | ||
1740 | * return: 0 ; polling O.K. | ||
1741 | * -1 : no any Moxa card. | ||
1742 | * | ||
1743 | * | ||
1744 | * Function 4: Get the ports of this card. | ||
1745 | * Syntax: | ||
1746 | * int MoxaPortsOfCard(int cardno); | ||
1747 | * | ||
1748 | * int cardno : card number (0 - 3) | ||
1749 | * | ||
1750 | * return: 0 : this card is invalid | ||
1751 | * 8/16/24/32 | ||
1752 | * | ||
1753 | * | ||
1754 | * Function 5: Check this port is valid or invalid | ||
1755 | * Syntax: | ||
1756 | * int MoxaPortIsValid(int port); | ||
1757 | * int port : port number (0 - 127, ref port description) | ||
1758 | * | ||
1759 | * return: 0 : this port is invalid | ||
1760 | * 1 : this port is valid | ||
1761 | * | ||
1762 | * | ||
1763 | * Function 6: Enable this port to start Tx/Rx data. | 1640 | * Function 6: Enable this port to start Tx/Rx data. |
1764 | * Syntax: | 1641 | * Syntax: |
1765 | * void MoxaPortEnable(int port); | 1642 | * void MoxaPortEnable(int port); |
@@ -1772,18 +1649,9 @@ int MoxaPortsOfCard(int cardno) | |||
1772 | * int port : port number (0 - 127) | 1649 | * int port : port number (0 - 127) |
1773 | * | 1650 | * |
1774 | * | 1651 | * |
1775 | * Function 8: Get the maximun available baud rate of this port. | ||
1776 | * Syntax: | ||
1777 | * long MoxaPortGetMaxBaud(int port); | ||
1778 | * int port : port number (0 - 127) | ||
1779 | * | ||
1780 | * return: 0 : this port is invalid | ||
1781 | * 38400/57600/115200 bps | ||
1782 | * | ||
1783 | * | ||
1784 | * Function 10: Setting baud rate of this port. | 1652 | * Function 10: Setting baud rate of this port. |
1785 | * Syntax: | 1653 | * Syntax: |
1786 | * long MoxaPortSetBaud(int port, long baud); | 1654 | * speed_t MoxaPortSetBaud(int port, speed_t baud); |
1787 | * int port : port number (0 - 127) | 1655 | * int port : port number (0 - 127) |
1788 | * long baud : baud rate (50 - 115200) | 1656 | * long baud : baud rate (50 - 115200) |
1789 | * | 1657 | * |
@@ -1850,25 +1718,6 @@ int MoxaPortsOfCard(int cardno) | |||
1850 | * Bit 2 - DCD state (0: off, 1: on) | 1718 | * Bit 2 - DCD state (0: off, 1: on) |
1851 | * | 1719 | * |
1852 | * | 1720 | * |
1853 | * Function 17: Check the DCD state has changed since the last read | ||
1854 | * of this function. | ||
1855 | * Syntax: | ||
1856 | * int MoxaPortDCDChange(int port); | ||
1857 | * int port : port number (0 - 127) | ||
1858 | * | ||
1859 | * return: 0 : no changed | ||
1860 | * 1 : DCD has changed | ||
1861 | * | ||
1862 | * | ||
1863 | * Function 18: Check ths current DCD state is ON or not. | ||
1864 | * Syntax: | ||
1865 | * int MoxaPortDCDON(int port); | ||
1866 | * int port : port number (0 - 127) | ||
1867 | * | ||
1868 | * return: 0 : DCD off | ||
1869 | * 1 : DCD on | ||
1870 | * | ||
1871 | * | ||
1872 | * Function 19: Flush the Rx/Tx buffer data of this port. | 1721 | * Function 19: Flush the Rx/Tx buffer data of this port. |
1873 | * Syntax: | 1722 | * Syntax: |
1874 | * void MoxaPortFlushData(int port, int mode); | 1723 | * void MoxaPortFlushData(int port, int mode); |
@@ -1942,40 +1791,20 @@ int MoxaPortsOfCard(int cardno) | |||
1942 | * return: 0 - .. : BREAK signal count | 1791 | * return: 0 - .. : BREAK signal count |
1943 | * | 1792 | * |
1944 | * | 1793 | * |
1945 | * Function 34: Send out a BREAK signal. | ||
1946 | * Syntax: | ||
1947 | * void MoxaPortSendBreak(int port, int ms100); | ||
1948 | * int port : port number (0 - 127) | ||
1949 | * int ms100 : break signal time interval. | ||
1950 | * unit: 100 mini-second. if ms100 == 0, it will | ||
1951 | * send out a about 250 ms BREAK signal. | ||
1952 | * | ||
1953 | */ | 1794 | */ |
1954 | int MoxaPortIsValid(int port) | ||
1955 | { | ||
1956 | |||
1957 | if (moxaCard == 0) | ||
1958 | return (0); | ||
1959 | if (moxa_ports[port].chkPort == 0) | ||
1960 | return (0); | ||
1961 | return (1); | ||
1962 | } | ||
1963 | 1795 | ||
1964 | void MoxaPortEnable(int port) | 1796 | static void MoxaPortEnable(struct moxa_port *port) |
1965 | { | 1797 | { |
1966 | void __iomem *ofsAddr; | 1798 | void __iomem *ofsAddr; |
1967 | int MoxaPortLineStatus(int); | 1799 | u16 lowwater = 512; |
1968 | short lowwater = 512; | ||
1969 | 1800 | ||
1970 | ofsAddr = moxa_ports[port].tableAddr; | 1801 | ofsAddr = port->tableAddr; |
1971 | writew(lowwater, ofsAddr + Low_water); | 1802 | writew(lowwater, ofsAddr + Low_water); |
1972 | moxa_ports[port].breakCnt = 0; | 1803 | if (MOXA_IS_320(port->board)) |
1973 | if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || | ||
1974 | (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { | ||
1975 | moxafunc(ofsAddr, FC_SetBreakIrq, 0); | 1804 | moxafunc(ofsAddr, FC_SetBreakIrq, 0); |
1976 | } else { | 1805 | else |
1977 | writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat); | 1806 | writew(readw(ofsAddr + HostStat) | WakeupBreak, |
1978 | } | 1807 | ofsAddr + HostStat); |
1979 | 1808 | ||
1980 | moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); | 1809 | moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); |
1981 | moxafunc(ofsAddr, FC_FlushQueue, 2); | 1810 | moxafunc(ofsAddr, FC_FlushQueue, 2); |
@@ -1984,9 +1813,9 @@ void MoxaPortEnable(int port) | |||
1984 | MoxaPortLineStatus(port); | 1813 | MoxaPortLineStatus(port); |
1985 | } | 1814 | } |
1986 | 1815 | ||
1987 | void MoxaPortDisable(int port) | 1816 | static void MoxaPortDisable(struct moxa_port *port) |
1988 | { | 1817 | { |
1989 | void __iomem *ofsAddr = moxa_ports[port].tableAddr; | 1818 | void __iomem *ofsAddr = port->tableAddr; |
1990 | 1819 | ||
1991 | moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ | 1820 | moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ |
1992 | moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); | 1821 | moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); |
@@ -1994,49 +1823,32 @@ void MoxaPortDisable(int port) | |||
1994 | moxafunc(ofsAddr, FC_DisableCH, Magic_code); | 1823 | moxafunc(ofsAddr, FC_DisableCH, Magic_code); |
1995 | } | 1824 | } |
1996 | 1825 | ||
1997 | long MoxaPortGetMaxBaud(int port) | 1826 | static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud) |
1998 | { | ||
1999 | if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || | ||
2000 | (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) | ||
2001 | return (460800L); | ||
2002 | else | ||
2003 | return (921600L); | ||
2004 | } | ||
2005 | |||
2006 | |||
2007 | long MoxaPortSetBaud(int port, long baud) | ||
2008 | { | 1827 | { |
2009 | void __iomem *ofsAddr; | 1828 | void __iomem *ofsAddr = port->tableAddr; |
2010 | long max, clock; | 1829 | unsigned int clock, val; |
2011 | unsigned int val; | 1830 | speed_t max; |
2012 | 1831 | ||
2013 | if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0)) | 1832 | max = MOXA_IS_320(port->board) ? 460800 : 921600; |
2014 | return (0); | 1833 | if (baud < 50) |
2015 | ofsAddr = moxa_ports[port].tableAddr; | 1834 | return 0; |
2016 | if (baud > max) | 1835 | if (baud > max) |
2017 | baud = max; | 1836 | baud = max; |
2018 | if (max == 38400L) | 1837 | clock = 921600; |
2019 | clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */ | ||
2020 | else if (max == 57600L) | ||
2021 | clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */ | ||
2022 | else | ||
2023 | clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */ | ||
2024 | val = clock / baud; | 1838 | val = clock / baud; |
2025 | moxafunc(ofsAddr, FC_SetBaud, val); | 1839 | moxafunc(ofsAddr, FC_SetBaud, val); |
2026 | baud = clock / val; | 1840 | baud = clock / val; |
2027 | moxa_ports[port].curBaud = baud; | 1841 | return baud; |
2028 | return (baud); | ||
2029 | } | 1842 | } |
2030 | 1843 | ||
2031 | int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) | 1844 | static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio, |
1845 | speed_t baud) | ||
2032 | { | 1846 | { |
2033 | void __iomem *ofsAddr; | 1847 | void __iomem *ofsAddr; |
2034 | tcflag_t cflag; | 1848 | tcflag_t cflag; |
2035 | tcflag_t mode = 0; | 1849 | tcflag_t mode = 0; |
2036 | 1850 | ||
2037 | if (moxa_ports[port].chkPort == 0 || termio == 0) | 1851 | ofsAddr = port->tableAddr; |
2038 | return (-1); | ||
2039 | ofsAddr = moxa_ports[port].tableAddr; | ||
2040 | cflag = termio->c_cflag; /* termio->c_cflag */ | 1852 | cflag = termio->c_cflag; /* termio->c_cflag */ |
2041 | 1853 | ||
2042 | mode = termio->c_cflag & CSIZE; | 1854 | mode = termio->c_cflag & CSIZE; |
@@ -2065,13 +1877,11 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) | |||
2065 | } else | 1877 | } else |
2066 | mode |= MX_PARNONE; | 1878 | mode |= MX_PARNONE; |
2067 | 1879 | ||
2068 | moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode); | 1880 | moxafunc(ofsAddr, FC_SetDataMode, (u16)mode); |
1881 | |||
1882 | if (MOXA_IS_320(port->board) && baud >= 921600) | ||
1883 | return -1; | ||
2069 | 1884 | ||
2070 | if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || | ||
2071 | (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { | ||
2072 | if (baud >= 921600L) | ||
2073 | return (-1); | ||
2074 | } | ||
2075 | baud = MoxaPortSetBaud(port, baud); | 1885 | baud = MoxaPortSetBaud(port, baud); |
2076 | 1886 | ||
2077 | if (termio->c_iflag & (IXON | IXOFF | IXANY)) { | 1887 | if (termio->c_iflag & (IXON | IXOFF | IXANY)) { |
@@ -2081,51 +1891,37 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) | |||
2081 | moxa_wait_finish(ofsAddr); | 1891 | moxa_wait_finish(ofsAddr); |
2082 | 1892 | ||
2083 | } | 1893 | } |
2084 | return (baud); | 1894 | return baud; |
2085 | } | 1895 | } |
2086 | 1896 | ||
2087 | int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState) | 1897 | static int MoxaPortGetLineOut(struct moxa_port *port, int *dtrState, |
1898 | int *rtsState) | ||
2088 | { | 1899 | { |
1900 | if (dtrState) | ||
1901 | *dtrState = !!(port->lineCtrl & DTR_ON); | ||
1902 | if (rtsState) | ||
1903 | *rtsState = !!(port->lineCtrl & RTS_ON); | ||
2089 | 1904 | ||
2090 | if (!MoxaPortIsValid(port)) | 1905 | return 0; |
2091 | return (-1); | ||
2092 | if (dtrState) { | ||
2093 | if (moxa_ports[port].lineCtrl & DTR_ON) | ||
2094 | *dtrState = 1; | ||
2095 | else | ||
2096 | *dtrState = 0; | ||
2097 | } | ||
2098 | if (rtsState) { | ||
2099 | if (moxa_ports[port].lineCtrl & RTS_ON) | ||
2100 | *rtsState = 1; | ||
2101 | else | ||
2102 | *rtsState = 0; | ||
2103 | } | ||
2104 | return (0); | ||
2105 | } | 1906 | } |
2106 | 1907 | ||
2107 | void MoxaPortLineCtrl(int port, int dtr, int rts) | 1908 | static void MoxaPortLineCtrl(struct moxa_port *port, int dtr, int rts) |
2108 | { | 1909 | { |
2109 | void __iomem *ofsAddr; | 1910 | u8 mode = 0; |
2110 | int mode; | ||
2111 | 1911 | ||
2112 | ofsAddr = moxa_ports[port].tableAddr; | ||
2113 | mode = 0; | ||
2114 | if (dtr) | 1912 | if (dtr) |
2115 | mode |= DTR_ON; | 1913 | mode |= DTR_ON; |
2116 | if (rts) | 1914 | if (rts) |
2117 | mode |= RTS_ON; | 1915 | mode |= RTS_ON; |
2118 | moxa_ports[port].lineCtrl = mode; | 1916 | port->lineCtrl = mode; |
2119 | moxafunc(ofsAddr, FC_LineControl, mode); | 1917 | moxafunc(port->tableAddr, FC_LineControl, mode); |
2120 | } | 1918 | } |
2121 | 1919 | ||
2122 | void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany) | 1920 | static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts, |
1921 | int txflow, int rxflow, int txany) | ||
2123 | { | 1922 | { |
2124 | void __iomem *ofsAddr; | 1923 | int mode = 0; |
2125 | int mode; | ||
2126 | 1924 | ||
2127 | ofsAddr = moxa_ports[port].tableAddr; | ||
2128 | mode = 0; | ||
2129 | if (rts) | 1925 | if (rts) |
2130 | mode |= RTS_FlowCtl; | 1926 | mode |= RTS_FlowCtl; |
2131 | if (cts) | 1927 | if (cts) |
@@ -2136,81 +1932,50 @@ void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int tx | |||
2136 | mode |= Rx_FlowCtl; | 1932 | mode |= Rx_FlowCtl; |
2137 | if (txany) | 1933 | if (txany) |
2138 | mode |= IXM_IXANY; | 1934 | mode |= IXM_IXANY; |
2139 | moxafunc(ofsAddr, FC_SetFlowCtl, mode); | 1935 | moxafunc(port->tableAddr, FC_SetFlowCtl, mode); |
2140 | } | 1936 | } |
2141 | 1937 | ||
2142 | int MoxaPortLineStatus(int port) | 1938 | static int MoxaPortLineStatus(struct moxa_port *port) |
2143 | { | 1939 | { |
2144 | void __iomem *ofsAddr; | 1940 | void __iomem *ofsAddr; |
2145 | int val; | 1941 | int val; |
2146 | 1942 | ||
2147 | ofsAddr = moxa_ports[port].tableAddr; | 1943 | ofsAddr = port->tableAddr; |
2148 | if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || | 1944 | if (MOXA_IS_320(port->board)) { |
2149 | (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { | ||
2150 | moxafunc(ofsAddr, FC_LineStatus, 0); | 1945 | moxafunc(ofsAddr, FC_LineStatus, 0); |
2151 | val = readw(ofsAddr + FuncArg); | 1946 | val = readw(ofsAddr + FuncArg); |
2152 | } else { | 1947 | } else { |
2153 | val = readw(ofsAddr + FlagStat) >> 4; | 1948 | val = readw(ofsAddr + FlagStat) >> 4; |
2154 | } | 1949 | } |
2155 | val &= 0x0B; | 1950 | val &= 0x0B; |
2156 | if (val & 8) { | 1951 | if (val & 8) |
2157 | val |= 4; | 1952 | val |= 4; |
2158 | if ((moxa_ports[port].DCDState & DCD_oldstate) == 0) | 1953 | spin_lock_bh(&moxa_lock); |
2159 | moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed); | 1954 | moxa_new_dcdstate(port, val & 8); |
2160 | } else { | 1955 | spin_unlock_bh(&moxa_lock); |
2161 | if (moxa_ports[port].DCDState & DCD_oldstate) | ||
2162 | moxa_ports[port].DCDState = DCD_changed; | ||
2163 | } | ||
2164 | val &= 7; | 1956 | val &= 7; |
2165 | return (val); | 1957 | return val; |
2166 | } | ||
2167 | |||
2168 | int MoxaPortDCDChange(int port) | ||
2169 | { | ||
2170 | int n; | ||
2171 | |||
2172 | if (moxa_ports[port].chkPort == 0) | ||
2173 | return (0); | ||
2174 | n = moxa_ports[port].DCDState; | ||
2175 | moxa_ports[port].DCDState &= ~DCD_changed; | ||
2176 | n &= DCD_changed; | ||
2177 | return (n); | ||
2178 | } | ||
2179 | |||
2180 | int MoxaPortDCDON(int port) | ||
2181 | { | ||
2182 | int n; | ||
2183 | |||
2184 | if (moxa_ports[port].chkPort == 0) | ||
2185 | return (0); | ||
2186 | if (moxa_ports[port].DCDState & DCD_oldstate) | ||
2187 | n = 1; | ||
2188 | else | ||
2189 | n = 0; | ||
2190 | return (n); | ||
2191 | } | 1958 | } |
2192 | 1959 | ||
2193 | int MoxaPortWriteData(int port, unsigned char * buffer, int len) | 1960 | static int MoxaPortWriteData(struct moxa_port *port, |
1961 | const unsigned char *buffer, int len) | ||
2194 | { | 1962 | { |
2195 | int c, total, i; | ||
2196 | ushort tail; | ||
2197 | int cnt; | ||
2198 | ushort head, tx_mask, spage, epage; | ||
2199 | ushort pageno, pageofs, bufhead; | ||
2200 | void __iomem *baseAddr, *ofsAddr, *ofs; | 1963 | void __iomem *baseAddr, *ofsAddr, *ofs; |
1964 | unsigned int c, total; | ||
1965 | u16 head, tail, tx_mask, spage, epage; | ||
1966 | u16 pageno, pageofs, bufhead; | ||
2201 | 1967 | ||
2202 | ofsAddr = moxa_ports[port].tableAddr; | 1968 | ofsAddr = port->tableAddr; |
2203 | baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem; | 1969 | baseAddr = port->board->basemem; |
2204 | tx_mask = readw(ofsAddr + TX_mask); | 1970 | tx_mask = readw(ofsAddr + TX_mask); |
2205 | spage = readw(ofsAddr + Page_txb); | 1971 | spage = readw(ofsAddr + Page_txb); |
2206 | epage = readw(ofsAddr + EndPage_txb); | 1972 | epage = readw(ofsAddr + EndPage_txb); |
2207 | tail = readw(ofsAddr + TXwptr); | 1973 | tail = readw(ofsAddr + TXwptr); |
2208 | head = readw(ofsAddr + TXrptr); | 1974 | head = readw(ofsAddr + TXrptr); |
2209 | c = (head > tail) ? (head - tail - 1) | 1975 | c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask); |
2210 | : (head - tail + tx_mask); | ||
2211 | if (c > len) | 1976 | if (c > len) |
2212 | c = len; | 1977 | c = len; |
2213 | moxaLog.txcnt[port] += c; | 1978 | moxaLog.txcnt[port->tty->index] += c; |
2214 | total = c; | 1979 | total = c; |
2215 | if (spage == epage) { | 1980 | if (spage == epage) { |
2216 | bufhead = readw(ofsAddr + Ofs_txb); | 1981 | bufhead = readw(ofsAddr + Ofs_txb); |
@@ -2222,249 +1987,179 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len) | |||
2222 | len = tx_mask + 1 - tail; | 1987 | len = tx_mask + 1 - tail; |
2223 | len = (c > len) ? len : c; | 1988 | len = (c > len) ? len : c; |
2224 | ofs = baseAddr + DynPage_addr + bufhead + tail; | 1989 | ofs = baseAddr + DynPage_addr + bufhead + tail; |
2225 | for (i = 0; i < len; i++) | 1990 | memcpy_toio(ofs, buffer, len); |
2226 | writeb(*buffer++, ofs + i); | 1991 | buffer += len; |
2227 | tail = (tail + len) & tx_mask; | 1992 | tail = (tail + len) & tx_mask; |
2228 | c -= len; | 1993 | c -= len; |
2229 | } | 1994 | } |
2230 | writew(tail, ofsAddr + TXwptr); | ||
2231 | } else { | 1995 | } else { |
2232 | len = c; | ||
2233 | pageno = spage + (tail >> 13); | 1996 | pageno = spage + (tail >> 13); |
2234 | pageofs = tail & Page_mask; | 1997 | pageofs = tail & Page_mask; |
2235 | do { | 1998 | while (c > 0) { |
2236 | cnt = Page_size - pageofs; | 1999 | len = Page_size - pageofs; |
2237 | if (cnt > c) | 2000 | if (len > c) |
2238 | cnt = c; | 2001 | len = c; |
2239 | c -= cnt; | ||
2240 | writeb(pageno, baseAddr + Control_reg); | 2002 | writeb(pageno, baseAddr + Control_reg); |
2241 | ofs = baseAddr + DynPage_addr + pageofs; | 2003 | ofs = baseAddr + DynPage_addr + pageofs; |
2242 | for (i = 0; i < cnt; i++) | 2004 | memcpy_toio(ofs, buffer, len); |
2243 | writeb(*buffer++, ofs + i); | 2005 | buffer += len; |
2244 | if (c == 0) { | ||
2245 | writew((tail + len) & tx_mask, ofsAddr + TXwptr); | ||
2246 | break; | ||
2247 | } | ||
2248 | if (++pageno == epage) | 2006 | if (++pageno == epage) |
2249 | pageno = spage; | 2007 | pageno = spage; |
2250 | pageofs = 0; | 2008 | pageofs = 0; |
2251 | } while (1); | 2009 | c -= len; |
2010 | } | ||
2011 | tail = (tail + total) & tx_mask; | ||
2252 | } | 2012 | } |
2013 | writew(tail, ofsAddr + TXwptr); | ||
2253 | writeb(1, ofsAddr + CD180TXirq); /* start to send */ | 2014 | writeb(1, ofsAddr + CD180TXirq); /* start to send */ |
2254 | return (total); | 2015 | return total; |
2255 | } | 2016 | } |
2256 | 2017 | ||
2257 | int MoxaPortReadData(int port, struct tty_struct *tty) | 2018 | static int MoxaPortReadData(struct moxa_port *port) |
2258 | { | 2019 | { |
2259 | register ushort head, pageofs; | 2020 | struct tty_struct *tty = port->tty; |
2260 | int i, count, cnt, len, total, remain; | 2021 | unsigned char *dst; |
2261 | ushort tail, rx_mask, spage, epage; | ||
2262 | ushort pageno, bufhead; | ||
2263 | void __iomem *baseAddr, *ofsAddr, *ofs; | 2022 | void __iomem *baseAddr, *ofsAddr, *ofs; |
2023 | unsigned int count, len, total; | ||
2024 | u16 tail, rx_mask, spage, epage; | ||
2025 | u16 pageno, pageofs, bufhead, head; | ||
2264 | 2026 | ||
2265 | ofsAddr = moxa_ports[port].tableAddr; | 2027 | ofsAddr = port->tableAddr; |
2266 | baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem; | 2028 | baseAddr = port->board->basemem; |
2267 | head = readw(ofsAddr + RXrptr); | 2029 | head = readw(ofsAddr + RXrptr); |
2268 | tail = readw(ofsAddr + RXwptr); | 2030 | tail = readw(ofsAddr + RXwptr); |
2269 | rx_mask = readw(ofsAddr + RX_mask); | 2031 | rx_mask = readw(ofsAddr + RX_mask); |
2270 | spage = readw(ofsAddr + Page_rxb); | 2032 | spage = readw(ofsAddr + Page_rxb); |
2271 | epage = readw(ofsAddr + EndPage_rxb); | 2033 | epage = readw(ofsAddr + EndPage_rxb); |
2272 | count = (tail >= head) ? (tail - head) | 2034 | count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1); |
2273 | : (tail - head + rx_mask + 1); | ||
2274 | if (count == 0) | 2035 | if (count == 0) |
2275 | return 0; | 2036 | return 0; |
2276 | 2037 | ||
2277 | total = count; | 2038 | total = count; |
2278 | remain = count - total; | 2039 | moxaLog.rxcnt[tty->index] += total; |
2279 | moxaLog.rxcnt[port] += total; | ||
2280 | count = total; | ||
2281 | if (spage == epage) { | 2040 | if (spage == epage) { |
2282 | bufhead = readw(ofsAddr + Ofs_rxb); | 2041 | bufhead = readw(ofsAddr + Ofs_rxb); |
2283 | writew(spage, baseAddr + Control_reg); | 2042 | writew(spage, baseAddr + Control_reg); |
2284 | while (count > 0) { | 2043 | while (count > 0) { |
2285 | if (tail >= head) | ||
2286 | len = tail - head; | ||
2287 | else | ||
2288 | len = rx_mask + 1 - head; | ||
2289 | len = (count > len) ? len : count; | ||
2290 | ofs = baseAddr + DynPage_addr + bufhead + head; | 2044 | ofs = baseAddr + DynPage_addr + bufhead + head; |
2291 | for (i = 0; i < len; i++) | 2045 | len = (tail >= head) ? (tail - head) : |
2292 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); | 2046 | (rx_mask + 1 - head); |
2047 | len = tty_prepare_flip_string(tty, &dst, | ||
2048 | min(len, count)); | ||
2049 | memcpy_fromio(dst, ofs, len); | ||
2293 | head = (head + len) & rx_mask; | 2050 | head = (head + len) & rx_mask; |
2294 | count -= len; | 2051 | count -= len; |
2295 | } | 2052 | } |
2296 | writew(head, ofsAddr + RXrptr); | ||
2297 | } else { | 2053 | } else { |
2298 | len = count; | ||
2299 | pageno = spage + (head >> 13); | 2054 | pageno = spage + (head >> 13); |
2300 | pageofs = head & Page_mask; | 2055 | pageofs = head & Page_mask; |
2301 | do { | 2056 | while (count > 0) { |
2302 | cnt = Page_size - pageofs; | ||
2303 | if (cnt > count) | ||
2304 | cnt = count; | ||
2305 | count -= cnt; | ||
2306 | writew(pageno, baseAddr + Control_reg); | 2057 | writew(pageno, baseAddr + Control_reg); |
2307 | ofs = baseAddr + DynPage_addr + pageofs; | 2058 | ofs = baseAddr + DynPage_addr + pageofs; |
2308 | for (i = 0; i < cnt; i++) | 2059 | len = tty_prepare_flip_string(tty, &dst, |
2309 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); | 2060 | min(Page_size - pageofs, count)); |
2310 | if (count == 0) { | 2061 | memcpy_fromio(dst, ofs, len); |
2311 | writew((head + len) & rx_mask, ofsAddr + RXrptr); | 2062 | |
2312 | break; | 2063 | count -= len; |
2313 | } | 2064 | pageofs = (pageofs + len) & Page_mask; |
2314 | if (++pageno == epage) | 2065 | if (pageofs == 0 && ++pageno == epage) |
2315 | pageno = spage; | 2066 | pageno = spage; |
2316 | pageofs = 0; | 2067 | } |
2317 | } while (1); | 2068 | head = (head + total) & rx_mask; |
2318 | } | 2069 | } |
2319 | if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) { | 2070 | writew(head, ofsAddr + RXrptr); |
2071 | if (readb(ofsAddr + FlagStat) & Xoff_state) { | ||
2320 | moxaLowWaterChk = 1; | 2072 | moxaLowWaterChk = 1; |
2321 | moxa_ports[port].lowChkFlag = 1; | 2073 | port->lowChkFlag = 1; |
2322 | } | 2074 | } |
2323 | return (total); | 2075 | return total; |
2324 | } | 2076 | } |
2325 | 2077 | ||
2326 | 2078 | ||
2327 | int MoxaPortTxQueue(int port) | 2079 | static int MoxaPortTxQueue(struct moxa_port *port) |
2328 | { | 2080 | { |
2329 | void __iomem *ofsAddr; | 2081 | void __iomem *ofsAddr = port->tableAddr; |
2330 | ushort rptr, wptr, mask; | 2082 | u16 rptr, wptr, mask; |
2331 | int len; | ||
2332 | 2083 | ||
2333 | ofsAddr = moxa_ports[port].tableAddr; | ||
2334 | rptr = readw(ofsAddr + TXrptr); | 2084 | rptr = readw(ofsAddr + TXrptr); |
2335 | wptr = readw(ofsAddr + TXwptr); | 2085 | wptr = readw(ofsAddr + TXwptr); |
2336 | mask = readw(ofsAddr + TX_mask); | 2086 | mask = readw(ofsAddr + TX_mask); |
2337 | len = (wptr - rptr) & mask; | 2087 | return (wptr - rptr) & mask; |
2338 | return (len); | ||
2339 | } | 2088 | } |
2340 | 2089 | ||
2341 | int MoxaPortTxFree(int port) | 2090 | static int MoxaPortTxFree(struct moxa_port *port) |
2342 | { | 2091 | { |
2343 | void __iomem *ofsAddr; | 2092 | void __iomem *ofsAddr = port->tableAddr; |
2344 | ushort rptr, wptr, mask; | 2093 | u16 rptr, wptr, mask; |
2345 | int len; | ||
2346 | 2094 | ||
2347 | ofsAddr = moxa_ports[port].tableAddr; | ||
2348 | rptr = readw(ofsAddr + TXrptr); | 2095 | rptr = readw(ofsAddr + TXrptr); |
2349 | wptr = readw(ofsAddr + TXwptr); | 2096 | wptr = readw(ofsAddr + TXwptr); |
2350 | mask = readw(ofsAddr + TX_mask); | 2097 | mask = readw(ofsAddr + TX_mask); |
2351 | len = mask - ((wptr - rptr) & mask); | 2098 | return mask - ((wptr - rptr) & mask); |
2352 | return (len); | ||
2353 | } | 2099 | } |
2354 | 2100 | ||
2355 | int MoxaPortRxQueue(int port) | 2101 | static int MoxaPortRxQueue(struct moxa_port *port) |
2356 | { | 2102 | { |
2357 | void __iomem *ofsAddr; | 2103 | void __iomem *ofsAddr = port->tableAddr; |
2358 | ushort rptr, wptr, mask; | 2104 | u16 rptr, wptr, mask; |
2359 | int len; | ||
2360 | 2105 | ||
2361 | ofsAddr = moxa_ports[port].tableAddr; | ||
2362 | rptr = readw(ofsAddr + RXrptr); | 2106 | rptr = readw(ofsAddr + RXrptr); |
2363 | wptr = readw(ofsAddr + RXwptr); | 2107 | wptr = readw(ofsAddr + RXwptr); |
2364 | mask = readw(ofsAddr + RX_mask); | 2108 | mask = readw(ofsAddr + RX_mask); |
2365 | len = (wptr - rptr) & mask; | 2109 | return (wptr - rptr) & mask; |
2366 | return (len); | ||
2367 | } | 2110 | } |
2368 | 2111 | ||
2369 | 2112 | static void MoxaPortTxDisable(struct moxa_port *port) | |
2370 | void MoxaPortTxDisable(int port) | ||
2371 | { | 2113 | { |
2372 | void __iomem *ofsAddr; | 2114 | moxafunc(port->tableAddr, FC_SetXoffState, Magic_code); |
2373 | |||
2374 | ofsAddr = moxa_ports[port].tableAddr; | ||
2375 | moxafunc(ofsAddr, FC_SetXoffState, Magic_code); | ||
2376 | } | 2115 | } |
2377 | 2116 | ||
2378 | void MoxaPortTxEnable(int port) | 2117 | static void MoxaPortTxEnable(struct moxa_port *port) |
2379 | { | 2118 | { |
2380 | void __iomem *ofsAddr; | 2119 | moxafunc(port->tableAddr, FC_SetXonState, Magic_code); |
2381 | |||
2382 | ofsAddr = moxa_ports[port].tableAddr; | ||
2383 | moxafunc(ofsAddr, FC_SetXonState, Magic_code); | ||
2384 | } | ||
2385 | |||
2386 | |||
2387 | int MoxaPortResetBrkCnt(int port) | ||
2388 | { | ||
2389 | ushort cnt; | ||
2390 | cnt = moxa_ports[port].breakCnt; | ||
2391 | moxa_ports[port].breakCnt = 0; | ||
2392 | return (cnt); | ||
2393 | } | ||
2394 | |||
2395 | |||
2396 | void MoxaPortSendBreak(int port, int ms100) | ||
2397 | { | ||
2398 | void __iomem *ofsAddr; | ||
2399 | |||
2400 | ofsAddr = moxa_ports[port].tableAddr; | ||
2401 | if (ms100) { | ||
2402 | moxafunc(ofsAddr, FC_SendBreak, Magic_code); | ||
2403 | msleep(ms100 * 10); | ||
2404 | } else { | ||
2405 | moxafunc(ofsAddr, FC_SendBreak, Magic_code); | ||
2406 | msleep(250); | ||
2407 | } | ||
2408 | moxafunc(ofsAddr, FC_StopBreak, Magic_code); | ||
2409 | } | 2120 | } |
2410 | 2121 | ||
2411 | static int moxa_get_serial_info(struct moxa_port *info, | 2122 | static int moxa_get_serial_info(struct moxa_port *info, |
2412 | struct serial_struct __user *retinfo) | 2123 | struct serial_struct __user *retinfo) |
2413 | { | 2124 | { |
2414 | struct serial_struct tmp; | 2125 | struct serial_struct tmp = { |
2415 | 2126 | .type = info->type, | |
2416 | memset(&tmp, 0, sizeof(tmp)); | 2127 | .line = info->tty->index, |
2417 | tmp.type = info->type; | 2128 | .flags = info->asyncflags, |
2418 | tmp.line = info->port; | 2129 | .baud_base = 921600, |
2419 | tmp.port = 0; | 2130 | .close_delay = info->close_delay |
2420 | tmp.irq = 0; | 2131 | }; |
2421 | tmp.flags = info->asyncflags; | 2132 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; |
2422 | tmp.baud_base = 921600; | ||
2423 | tmp.close_delay = info->close_delay; | ||
2424 | tmp.closing_wait = info->closing_wait; | ||
2425 | tmp.custom_divisor = 0; | ||
2426 | tmp.hub6 = 0; | ||
2427 | if(copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
2428 | return -EFAULT; | ||
2429 | return (0); | ||
2430 | } | 2133 | } |
2431 | 2134 | ||
2432 | 2135 | ||
2433 | static int moxa_set_serial_info(struct moxa_port *info, | 2136 | static int moxa_set_serial_info(struct moxa_port *info, |
2434 | struct serial_struct __user *new_info) | 2137 | struct serial_struct __user *new_info) |
2435 | { | 2138 | { |
2436 | struct serial_struct new_serial; | 2139 | struct serial_struct new_serial; |
2437 | 2140 | ||
2438 | if(copy_from_user(&new_serial, new_info, sizeof(new_serial))) | 2141 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
2439 | return -EFAULT; | 2142 | return -EFAULT; |
2440 | 2143 | ||
2441 | if ((new_serial.irq != 0) || | 2144 | if (new_serial.irq != 0 || new_serial.port != 0 || |
2442 | (new_serial.port != 0) || | 2145 | new_serial.custom_divisor != 0 || |
2443 | // (new_serial.type != info->type) || | 2146 | new_serial.baud_base != 921600) |
2444 | (new_serial.custom_divisor != 0) || | 2147 | return -EPERM; |
2445 | (new_serial.baud_base != 921600)) | ||
2446 | return (-EPERM); | ||
2447 | 2148 | ||
2448 | if (!capable(CAP_SYS_ADMIN)) { | 2149 | if (!capable(CAP_SYS_ADMIN)) { |
2449 | if (((new_serial.flags & ~ASYNC_USR_MASK) != | 2150 | if (((new_serial.flags & ~ASYNC_USR_MASK) != |
2450 | (info->asyncflags & ~ASYNC_USR_MASK))) | 2151 | (info->asyncflags & ~ASYNC_USR_MASK))) |
2451 | return (-EPERM); | 2152 | return -EPERM; |
2452 | } else { | 2153 | } else |
2453 | info->close_delay = new_serial.close_delay * HZ / 100; | 2154 | info->close_delay = new_serial.close_delay * HZ / 100; |
2454 | info->closing_wait = new_serial.closing_wait * HZ / 100; | ||
2455 | } | ||
2456 | 2155 | ||
2457 | new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); | 2156 | new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); |
2458 | new_serial.flags |= (info->asyncflags & ASYNC_FLAGS); | 2157 | new_serial.flags |= (info->asyncflags & ASYNC_FLAGS); |
2459 | 2158 | ||
2460 | if (new_serial.type == PORT_16550A) { | 2159 | MoxaSetFifo(info, new_serial.type == PORT_16550A); |
2461 | MoxaSetFifo(info->port, 1); | ||
2462 | } else { | ||
2463 | MoxaSetFifo(info->port, 0); | ||
2464 | } | ||
2465 | 2160 | ||
2466 | info->type = new_serial.type; | 2161 | info->type = new_serial.type; |
2467 | return (0); | 2162 | return 0; |
2468 | } | 2163 | } |
2469 | 2164 | ||
2470 | 2165 | ||
@@ -2472,374 +2167,10 @@ static int moxa_set_serial_info(struct moxa_port *info, | |||
2472 | /***************************************************************************** | 2167 | /***************************************************************************** |
2473 | * Static local functions: * | 2168 | * Static local functions: * |
2474 | *****************************************************************************/ | 2169 | *****************************************************************************/ |
2475 | static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) | ||
2476 | { | ||
2477 | |||
2478 | writew(arg, ofsAddr + FuncArg); | ||
2479 | writew(cmd, ofsAddr + FuncCode); | ||
2480 | moxa_wait_finish(ofsAddr); | ||
2481 | } | ||
2482 | |||
2483 | static void moxa_wait_finish(void __iomem *ofsAddr) | ||
2484 | { | ||
2485 | unsigned long i, j; | ||
2486 | |||
2487 | i = jiffies; | ||
2488 | while (readw(ofsAddr + FuncCode) != 0) { | ||
2489 | j = jiffies; | ||
2490 | if ((j - i) > moxaFuncTout) { | ||
2491 | return; | ||
2492 | } | ||
2493 | } | ||
2494 | } | ||
2495 | |||
2496 | static void moxa_low_water_check(void __iomem *ofsAddr) | ||
2497 | { | ||
2498 | int len; | ||
2499 | ushort rptr, wptr, mask; | ||
2500 | |||
2501 | if (readb(ofsAddr + FlagStat) & Xoff_state) { | ||
2502 | rptr = readw(ofsAddr + RXrptr); | ||
2503 | wptr = readw(ofsAddr + RXwptr); | ||
2504 | mask = readw(ofsAddr + RX_mask); | ||
2505 | len = (wptr - rptr) & mask; | ||
2506 | if (len <= Low_water) | ||
2507 | moxafunc(ofsAddr, FC_SendXon, 0); | ||
2508 | } | ||
2509 | } | ||
2510 | |||
2511 | static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) | ||
2512 | { | ||
2513 | void __iomem *baseAddr; | ||
2514 | int i; | ||
2515 | |||
2516 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2517 | return -EINVAL; | ||
2518 | if(copy_from_user(moxaBuff, tmp, len)) | ||
2519 | return -EFAULT; | ||
2520 | baseAddr = moxa_boards[cardno].basemem; | ||
2521 | writeb(HW_reset, baseAddr + Control_reg); /* reset */ | ||
2522 | msleep(10); | ||
2523 | for (i = 0; i < 4096; i++) | ||
2524 | writeb(0, baseAddr + i); /* clear fix page */ | ||
2525 | for (i = 0; i < len; i++) | ||
2526 | writeb(moxaBuff[i], baseAddr + i); /* download BIOS */ | ||
2527 | writeb(0, baseAddr + Control_reg); /* restart */ | ||
2528 | return (0); | ||
2529 | } | ||
2530 | |||
2531 | static int moxafindcard(int cardno) | ||
2532 | { | ||
2533 | void __iomem *baseAddr; | ||
2534 | ushort tmp; | ||
2535 | |||
2536 | baseAddr = moxa_boards[cardno].basemem; | ||
2537 | switch (moxa_boards[cardno].boardType) { | ||
2538 | case MOXA_BOARD_C218_ISA: | ||
2539 | case MOXA_BOARD_C218_PCI: | ||
2540 | if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) { | ||
2541 | return (-1); | ||
2542 | } | ||
2543 | break; | ||
2544 | case MOXA_BOARD_CP204J: | ||
2545 | if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) { | ||
2546 | return (-1); | ||
2547 | } | ||
2548 | break; | ||
2549 | default: | ||
2550 | if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) { | ||
2551 | return (-1); | ||
2552 | } | ||
2553 | if ((tmp = readw(baseAddr + C320_status)) != STS_init) { | ||
2554 | return (-2); | ||
2555 | } | ||
2556 | } | ||
2557 | return (0); | ||
2558 | } | ||
2559 | |||
2560 | static int moxaload320b(int cardno, unsigned char __user *tmp, int len) | ||
2561 | { | ||
2562 | void __iomem *baseAddr; | ||
2563 | int i; | ||
2564 | |||
2565 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2566 | return -EINVAL; | ||
2567 | if(copy_from_user(moxaBuff, tmp, len)) | ||
2568 | return -EFAULT; | ||
2569 | baseAddr = moxa_boards[cardno].basemem; | ||
2570 | writew(len - 7168 - 2, baseAddr + C320bapi_len); | ||
2571 | writeb(1, baseAddr + Control_reg); /* Select Page 1 */ | ||
2572 | for (i = 0; i < 7168; i++) | ||
2573 | writeb(moxaBuff[i], baseAddr + DynPage_addr + i); | ||
2574 | writeb(2, baseAddr + Control_reg); /* Select Page 2 */ | ||
2575 | for (i = 0; i < (len - 7168); i++) | ||
2576 | writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i); | ||
2577 | return (0); | ||
2578 | } | ||
2579 | |||
2580 | static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) | ||
2581 | { | ||
2582 | void __iomem *baseAddr, *ofsAddr; | ||
2583 | int retval, port, i; | ||
2584 | |||
2585 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2586 | return -EINVAL; | ||
2587 | if(copy_from_user(moxaBuff, tmp, len)) | ||
2588 | return -EFAULT; | ||
2589 | baseAddr = moxa_boards[cardno].basemem; | ||
2590 | switch (moxa_boards[cardno].boardType) { | ||
2591 | case MOXA_BOARD_C218_ISA: | ||
2592 | case MOXA_BOARD_C218_PCI: | ||
2593 | case MOXA_BOARD_CP204J: | ||
2594 | retval = moxaloadc218(cardno, baseAddr, len); | ||
2595 | if (retval) | ||
2596 | return (retval); | ||
2597 | port = cardno * MAX_PORTS_PER_BOARD; | ||
2598 | for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { | ||
2599 | struct moxa_port *p = &moxa_ports[port]; | ||
2600 | |||
2601 | p->chkPort = 1; | ||
2602 | p->curBaud = 9600L; | ||
2603 | p->DCDState = 0; | ||
2604 | p->tableAddr = baseAddr + Extern_table + Extern_size * i; | ||
2605 | ofsAddr = p->tableAddr; | ||
2606 | writew(C218rx_mask, ofsAddr + RX_mask); | ||
2607 | writew(C218tx_mask, ofsAddr + TX_mask); | ||
2608 | writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); | ||
2609 | writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); | ||
2610 | |||
2611 | writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); | ||
2612 | writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); | ||
2613 | |||
2614 | } | ||
2615 | break; | ||
2616 | default: | ||
2617 | retval = moxaloadc320(cardno, baseAddr, len, | ||
2618 | &moxa_boards[cardno].numPorts); | ||
2619 | if (retval) | ||
2620 | return (retval); | ||
2621 | port = cardno * MAX_PORTS_PER_BOARD; | ||
2622 | for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { | ||
2623 | struct moxa_port *p = &moxa_ports[port]; | ||
2624 | |||
2625 | p->chkPort = 1; | ||
2626 | p->curBaud = 9600L; | ||
2627 | p->DCDState = 0; | ||
2628 | p->tableAddr = baseAddr + Extern_table + Extern_size * i; | ||
2629 | ofsAddr = p->tableAddr; | ||
2630 | if (moxa_boards[cardno].numPorts == 8) { | ||
2631 | writew(C320p8rx_mask, ofsAddr + RX_mask); | ||
2632 | writew(C320p8tx_mask, ofsAddr + TX_mask); | ||
2633 | writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); | ||
2634 | writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); | ||
2635 | writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); | ||
2636 | writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); | ||
2637 | |||
2638 | } else if (moxa_boards[cardno].numPorts == 16) { | ||
2639 | writew(C320p16rx_mask, ofsAddr + RX_mask); | ||
2640 | writew(C320p16tx_mask, ofsAddr + TX_mask); | ||
2641 | writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); | ||
2642 | writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); | ||
2643 | writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); | ||
2644 | writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); | ||
2645 | |||
2646 | } else if (moxa_boards[cardno].numPorts == 24) { | ||
2647 | writew(C320p24rx_mask, ofsAddr + RX_mask); | ||
2648 | writew(C320p24tx_mask, ofsAddr + TX_mask); | ||
2649 | writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); | ||
2650 | writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); | ||
2651 | writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); | ||
2652 | writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); | ||
2653 | } else if (moxa_boards[cardno].numPorts == 32) { | ||
2654 | writew(C320p32rx_mask, ofsAddr + RX_mask); | ||
2655 | writew(C320p32tx_mask, ofsAddr + TX_mask); | ||
2656 | writew(C320p32tx_ofs, ofsAddr + Ofs_txb); | ||
2657 | writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); | ||
2658 | writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); | ||
2659 | writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); | ||
2660 | writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); | ||
2661 | } | ||
2662 | } | ||
2663 | break; | ||
2664 | } | ||
2665 | moxa_boards[cardno].loadstat = 1; | ||
2666 | return (0); | ||
2667 | } | ||
2668 | |||
2669 | static int moxaloadc218(int cardno, void __iomem *baseAddr, int len) | ||
2670 | { | ||
2671 | char retry; | ||
2672 | int i, j, len1, len2; | ||
2673 | ushort usum, *ptr, keycode; | ||
2674 | |||
2675 | if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J) | ||
2676 | keycode = CP204J_KeyCode; | ||
2677 | else | ||
2678 | keycode = C218_KeyCode; | ||
2679 | usum = 0; | ||
2680 | len1 = len >> 1; | ||
2681 | ptr = (ushort *) moxaBuff; | ||
2682 | for (i = 0; i < len1; i++) | ||
2683 | usum += le16_to_cpu(*(ptr + i)); | ||
2684 | retry = 0; | ||
2685 | do { | ||
2686 | len1 = len >> 1; | ||
2687 | j = 0; | ||
2688 | while (len1) { | ||
2689 | len2 = (len1 > 2048) ? 2048 : len1; | ||
2690 | len1 -= len2; | ||
2691 | for (i = 0; i < len2 << 1; i++) | ||
2692 | writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i); | ||
2693 | j += i; | ||
2694 | |||
2695 | writew(len2, baseAddr + C218DLoad_len); | ||
2696 | writew(0, baseAddr + C218_key); | ||
2697 | for (i = 0; i < 100; i++) { | ||
2698 | if (readw(baseAddr + C218_key) == keycode) | ||
2699 | break; | ||
2700 | msleep(10); | ||
2701 | } | ||
2702 | if (readw(baseAddr + C218_key) != keycode) { | ||
2703 | return (-1); | ||
2704 | } | ||
2705 | } | ||
2706 | writew(0, baseAddr + C218DLoad_len); | ||
2707 | writew(usum, baseAddr + C218check_sum); | ||
2708 | writew(0, baseAddr + C218_key); | ||
2709 | for (i = 0; i < 100; i++) { | ||
2710 | if (readw(baseAddr + C218_key) == keycode) | ||
2711 | break; | ||
2712 | msleep(10); | ||
2713 | } | ||
2714 | retry++; | ||
2715 | } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3)); | ||
2716 | if (readb(baseAddr + C218chksum_ok) != 1) { | ||
2717 | return (-1); | ||
2718 | } | ||
2719 | writew(0, baseAddr + C218_key); | ||
2720 | for (i = 0; i < 100; i++) { | ||
2721 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
2722 | break; | ||
2723 | msleep(10); | ||
2724 | } | ||
2725 | if (readw(baseAddr + Magic_no) != Magic_code) { | ||
2726 | return (-1); | ||
2727 | } | ||
2728 | writew(1, baseAddr + Disable_IRQ); | ||
2729 | writew(0, baseAddr + Magic_no); | ||
2730 | for (i = 0; i < 100; i++) { | ||
2731 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
2732 | break; | ||
2733 | msleep(10); | ||
2734 | } | ||
2735 | if (readw(baseAddr + Magic_no) != Magic_code) { | ||
2736 | return (-1); | ||
2737 | } | ||
2738 | moxaCard = 1; | ||
2739 | moxa_boards[cardno].intNdx = baseAddr + IRQindex; | ||
2740 | moxa_boards[cardno].intPend = baseAddr + IRQpending; | ||
2741 | moxa_boards[cardno].intTable = baseAddr + IRQtable; | ||
2742 | return (0); | ||
2743 | } | ||
2744 | |||
2745 | static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts) | ||
2746 | { | ||
2747 | ushort usum; | ||
2748 | int i, j, wlen, len2, retry; | ||
2749 | ushort *uptr; | ||
2750 | |||
2751 | usum = 0; | ||
2752 | wlen = len >> 1; | ||
2753 | uptr = (ushort *) moxaBuff; | ||
2754 | for (i = 0; i < wlen; i++) | ||
2755 | usum += le16_to_cpu(uptr[i]); | ||
2756 | retry = 0; | ||
2757 | j = 0; | ||
2758 | do { | ||
2759 | while (wlen) { | ||
2760 | if (wlen > 2048) | ||
2761 | len2 = 2048; | ||
2762 | else | ||
2763 | len2 = wlen; | ||
2764 | wlen -= len2; | ||
2765 | len2 <<= 1; | ||
2766 | for (i = 0; i < len2; i++) | ||
2767 | writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i); | ||
2768 | len2 >>= 1; | ||
2769 | j += i; | ||
2770 | writew(len2, baseAddr + C320DLoad_len); | ||
2771 | writew(0, baseAddr + C320_key); | ||
2772 | for (i = 0; i < 10; i++) { | ||
2773 | if (readw(baseAddr + C320_key) == C320_KeyCode) | ||
2774 | break; | ||
2775 | msleep(10); | ||
2776 | } | ||
2777 | if (readw(baseAddr + C320_key) != C320_KeyCode) | ||
2778 | return (-1); | ||
2779 | } | ||
2780 | writew(0, baseAddr + C320DLoad_len); | ||
2781 | writew(usum, baseAddr + C320check_sum); | ||
2782 | writew(0, baseAddr + C320_key); | ||
2783 | for (i = 0; i < 10; i++) { | ||
2784 | if (readw(baseAddr + C320_key) == C320_KeyCode) | ||
2785 | break; | ||
2786 | msleep(10); | ||
2787 | } | ||
2788 | retry++; | ||
2789 | } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3)); | ||
2790 | if (readb(baseAddr + C320chksum_ok) != 1) | ||
2791 | return (-1); | ||
2792 | writew(0, baseAddr + C320_key); | ||
2793 | for (i = 0; i < 600; i++) { | ||
2794 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
2795 | break; | ||
2796 | msleep(10); | ||
2797 | } | ||
2798 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
2799 | return (-100); | ||
2800 | |||
2801 | if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ | ||
2802 | writew(0x3800, baseAddr + TMS320_PORT1); | ||
2803 | writew(0x3900, baseAddr + TMS320_PORT2); | ||
2804 | writew(28499, baseAddr + TMS320_CLOCK); | ||
2805 | } else { | ||
2806 | writew(0x3200, baseAddr + TMS320_PORT1); | ||
2807 | writew(0x3400, baseAddr + TMS320_PORT2); | ||
2808 | writew(19999, baseAddr + TMS320_CLOCK); | ||
2809 | } | ||
2810 | writew(1, baseAddr + Disable_IRQ); | ||
2811 | writew(0, baseAddr + Magic_no); | ||
2812 | for (i = 0; i < 500; i++) { | ||
2813 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
2814 | break; | ||
2815 | msleep(10); | ||
2816 | } | ||
2817 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
2818 | return (-102); | ||
2819 | |||
2820 | j = readw(baseAddr + Module_cnt); | ||
2821 | if (j <= 0) | ||
2822 | return (-101); | ||
2823 | *numPorts = j * 8; | ||
2824 | writew(j, baseAddr + Module_no); | ||
2825 | writew(0, baseAddr + Magic_no); | ||
2826 | for (i = 0; i < 600; i++) { | ||
2827 | if (readw(baseAddr + Magic_no) == Magic_code) | ||
2828 | break; | ||
2829 | msleep(10); | ||
2830 | } | ||
2831 | if (readw(baseAddr + Magic_no) != Magic_code) | ||
2832 | return (-102); | ||
2833 | moxaCard = 1; | ||
2834 | moxa_boards[cardno].intNdx = baseAddr + IRQindex; | ||
2835 | moxa_boards[cardno].intPend = baseAddr + IRQpending; | ||
2836 | moxa_boards[cardno].intTable = baseAddr + IRQtable; | ||
2837 | return (0); | ||
2838 | } | ||
2839 | 2170 | ||
2840 | static void MoxaSetFifo(int port, int enable) | 2171 | static void MoxaSetFifo(struct moxa_port *port, int enable) |
2841 | { | 2172 | { |
2842 | void __iomem *ofsAddr = moxa_ports[port].tableAddr; | 2173 | void __iomem *ofsAddr = port->tableAddr; |
2843 | 2174 | ||
2844 | if (!enable) { | 2175 | if (!enable) { |
2845 | moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); | 2176 | moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); |
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h new file mode 100644 index 000000000000..87d16ce57be7 --- /dev/null +++ b/drivers/char/moxa.h | |||
@@ -0,0 +1,304 @@ | |||
1 | #ifndef MOXA_H_FILE | ||
2 | #define MOXA_H_FILE | ||
3 | |||
4 | #define MOXA 0x400 | ||
5 | #define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ | ||
6 | #define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ | ||
7 | #define MOXA_GETDATACOUNT (MOXA + 23) | ||
8 | #define MOXA_GET_IOQUEUE (MOXA + 27) | ||
9 | #define MOXA_FLUSH_QUEUE (MOXA + 28) | ||
10 | #define MOXA_GETMSTATUS (MOXA + 65) | ||
11 | |||
12 | /* | ||
13 | * System Configuration | ||
14 | */ | ||
15 | |||
16 | #define Magic_code 0x404 | ||
17 | |||
18 | /* | ||
19 | * for C218 BIOS initialization | ||
20 | */ | ||
21 | #define C218_ConfBase 0x800 | ||
22 | #define C218_status (C218_ConfBase + 0) /* BIOS running status */ | ||
23 | #define C218_diag (C218_ConfBase + 2) /* diagnostic status */ | ||
24 | #define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ | ||
25 | #define C218DLoad_len (C218_ConfBase + 6) /* WORD */ | ||
26 | #define C218check_sum (C218_ConfBase + 8) /* BYTE */ | ||
27 | #define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ | ||
28 | #define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ | ||
29 | #define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ | ||
30 | #define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ | ||
31 | #define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ | ||
32 | |||
33 | #define C218_LoadBuf 0x0F00 | ||
34 | #define C218_KeyCode 0x218 | ||
35 | #define CP204J_KeyCode 0x204 | ||
36 | |||
37 | /* | ||
38 | * for C320 BIOS initialization | ||
39 | */ | ||
40 | #define C320_ConfBase 0x800 | ||
41 | #define C320_LoadBuf 0x0f00 | ||
42 | #define STS_init 0x05 /* for C320_status */ | ||
43 | |||
44 | #define C320_status C320_ConfBase + 0 /* BIOS running status */ | ||
45 | #define C320_diag C320_ConfBase + 2 /* diagnostic status */ | ||
46 | #define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ | ||
47 | #define C320DLoad_len C320_ConfBase + 6 /* WORD */ | ||
48 | #define C320check_sum C320_ConfBase + 8 /* WORD */ | ||
49 | #define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ | ||
50 | #define C320bapi_len C320_ConfBase + 0x0c /* WORD */ | ||
51 | #define C320UART_no C320_ConfBase + 0x0e /* WORD */ | ||
52 | |||
53 | #define C320_KeyCode 0x320 | ||
54 | |||
55 | #define FixPage_addr 0x0000 /* starting addr of static page */ | ||
56 | #define DynPage_addr 0x2000 /* starting addr of dynamic page */ | ||
57 | #define C218_start 0x3000 /* starting addr of C218 BIOS prg */ | ||
58 | #define Control_reg 0x1ff0 /* select page and reset control */ | ||
59 | #define HW_reset 0x80 | ||
60 | |||
61 | /* | ||
62 | * Function Codes | ||
63 | */ | ||
64 | #define FC_CardReset 0x80 | ||
65 | #define FC_ChannelReset 1 /* C320 firmware not supported */ | ||
66 | #define FC_EnableCH 2 | ||
67 | #define FC_DisableCH 3 | ||
68 | #define FC_SetParam 4 | ||
69 | #define FC_SetMode 5 | ||
70 | #define FC_SetRate 6 | ||
71 | #define FC_LineControl 7 | ||
72 | #define FC_LineStatus 8 | ||
73 | #define FC_XmitControl 9 | ||
74 | #define FC_FlushQueue 10 | ||
75 | #define FC_SendBreak 11 | ||
76 | #define FC_StopBreak 12 | ||
77 | #define FC_LoopbackON 13 | ||
78 | #define FC_LoopbackOFF 14 | ||
79 | #define FC_ClrIrqTable 15 | ||
80 | #define FC_SendXon 16 | ||
81 | #define FC_SetTermIrq 17 /* C320 firmware not supported */ | ||
82 | #define FC_SetCntIrq 18 /* C320 firmware not supported */ | ||
83 | #define FC_SetBreakIrq 19 | ||
84 | #define FC_SetLineIrq 20 | ||
85 | #define FC_SetFlowCtl 21 | ||
86 | #define FC_GenIrq 22 | ||
87 | #define FC_InCD180 23 | ||
88 | #define FC_OutCD180 24 | ||
89 | #define FC_InUARTreg 23 | ||
90 | #define FC_OutUARTreg 24 | ||
91 | #define FC_SetXonXoff 25 | ||
92 | #define FC_OutCD180CCR 26 | ||
93 | #define FC_ExtIQueue 27 | ||
94 | #define FC_ExtOQueue 28 | ||
95 | #define FC_ClrLineIrq 29 | ||
96 | #define FC_HWFlowCtl 30 | ||
97 | #define FC_GetClockRate 35 | ||
98 | #define FC_SetBaud 36 | ||
99 | #define FC_SetDataMode 41 | ||
100 | #define FC_GetCCSR 43 | ||
101 | #define FC_GetDataError 45 | ||
102 | #define FC_RxControl 50 | ||
103 | #define FC_ImmSend 51 | ||
104 | #define FC_SetXonState 52 | ||
105 | #define FC_SetXoffState 53 | ||
106 | #define FC_SetRxFIFOTrig 54 | ||
107 | #define FC_SetTxFIFOCnt 55 | ||
108 | #define FC_UnixRate 56 | ||
109 | #define FC_UnixResetTimer 57 | ||
110 | |||
111 | #define RxFIFOTrig1 0 | ||
112 | #define RxFIFOTrig4 1 | ||
113 | #define RxFIFOTrig8 2 | ||
114 | #define RxFIFOTrig14 3 | ||
115 | |||
116 | /* | ||
117 | * Dual-Ported RAM | ||
118 | */ | ||
119 | #define DRAM_global 0 | ||
120 | #define INT_data (DRAM_global + 0) | ||
121 | #define Config_base (DRAM_global + 0x108) | ||
122 | |||
123 | #define IRQindex (INT_data + 0) | ||
124 | #define IRQpending (INT_data + 4) | ||
125 | #define IRQtable (INT_data + 8) | ||
126 | |||
127 | /* | ||
128 | * Interrupt Status | ||
129 | */ | ||
130 | #define IntrRx 0x01 /* receiver data O.K. */ | ||
131 | #define IntrTx 0x02 /* transmit buffer empty */ | ||
132 | #define IntrFunc 0x04 /* function complete */ | ||
133 | #define IntrBreak 0x08 /* received break */ | ||
134 | #define IntrLine 0x10 /* line status change | ||
135 | for transmitter */ | ||
136 | #define IntrIntr 0x20 /* received INTR code */ | ||
137 | #define IntrQuit 0x40 /* received QUIT code */ | ||
138 | #define IntrEOF 0x80 /* received EOF code */ | ||
139 | |||
140 | #define IntrRxTrigger 0x100 /* rx data count reach tigger value */ | ||
141 | #define IntrTxTrigger 0x200 /* tx data count below trigger value */ | ||
142 | |||
143 | #define Magic_no (Config_base + 0) | ||
144 | #define Card_model_no (Config_base + 2) | ||
145 | #define Total_ports (Config_base + 4) | ||
146 | #define Module_cnt (Config_base + 8) | ||
147 | #define Module_no (Config_base + 10) | ||
148 | #define Timer_10ms (Config_base + 14) | ||
149 | #define Disable_IRQ (Config_base + 20) | ||
150 | #define TMS320_PORT1 (Config_base + 22) | ||
151 | #define TMS320_PORT2 (Config_base + 24) | ||
152 | #define TMS320_CLOCK (Config_base + 26) | ||
153 | |||
154 | /* | ||
155 | * DATA BUFFER in DRAM | ||
156 | */ | ||
157 | #define Extern_table 0x400 /* Base address of the external table | ||
158 | (24 words * 64) total 3K bytes | ||
159 | (24 words * 128) total 6K bytes */ | ||
160 | #define Extern_size 0x60 /* 96 bytes */ | ||
161 | #define RXrptr 0x00 /* read pointer for RX buffer */ | ||
162 | #define RXwptr 0x02 /* write pointer for RX buffer */ | ||
163 | #define TXrptr 0x04 /* read pointer for TX buffer */ | ||
164 | #define TXwptr 0x06 /* write pointer for TX buffer */ | ||
165 | #define HostStat 0x08 /* IRQ flag and general flag */ | ||
166 | #define FlagStat 0x0A | ||
167 | #define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ | ||
168 | /* x x x x | | | | */ | ||
169 | /* | | | + CTS flow */ | ||
170 | /* | | +--- RTS flow */ | ||
171 | /* | +------ TX Xon/Xoff */ | ||
172 | /* +--------- RX Xon/Xoff */ | ||
173 | #define Break_cnt 0x0E /* received break count */ | ||
174 | #define CD180TXirq 0x10 /* if non-0: enable TX irq */ | ||
175 | #define RX_mask 0x12 | ||
176 | #define TX_mask 0x14 | ||
177 | #define Ofs_rxb 0x16 | ||
178 | #define Ofs_txb 0x18 | ||
179 | #define Page_rxb 0x1A | ||
180 | #define Page_txb 0x1C | ||
181 | #define EndPage_rxb 0x1E | ||
182 | #define EndPage_txb 0x20 | ||
183 | #define Data_error 0x22 | ||
184 | #define RxTrigger 0x28 | ||
185 | #define TxTrigger 0x2a | ||
186 | |||
187 | #define rRXwptr 0x34 | ||
188 | #define Low_water 0x36 | ||
189 | |||
190 | #define FuncCode 0x40 | ||
191 | #define FuncArg 0x42 | ||
192 | #define FuncArg1 0x44 | ||
193 | |||
194 | #define C218rx_size 0x2000 /* 8K bytes */ | ||
195 | #define C218tx_size 0x8000 /* 32K bytes */ | ||
196 | |||
197 | #define C218rx_mask (C218rx_size - 1) | ||
198 | #define C218tx_mask (C218tx_size - 1) | ||
199 | |||
200 | #define C320p8rx_size 0x2000 | ||
201 | #define C320p8tx_size 0x8000 | ||
202 | #define C320p8rx_mask (C320p8rx_size - 1) | ||
203 | #define C320p8tx_mask (C320p8tx_size - 1) | ||
204 | |||
205 | #define C320p16rx_size 0x2000 | ||
206 | #define C320p16tx_size 0x4000 | ||
207 | #define C320p16rx_mask (C320p16rx_size - 1) | ||
208 | #define C320p16tx_mask (C320p16tx_size - 1) | ||
209 | |||
210 | #define C320p24rx_size 0x2000 | ||
211 | #define C320p24tx_size 0x2000 | ||
212 | #define C320p24rx_mask (C320p24rx_size - 1) | ||
213 | #define C320p24tx_mask (C320p24tx_size - 1) | ||
214 | |||
215 | #define C320p32rx_size 0x1000 | ||
216 | #define C320p32tx_size 0x1000 | ||
217 | #define C320p32rx_mask (C320p32rx_size - 1) | ||
218 | #define C320p32tx_mask (C320p32tx_size - 1) | ||
219 | |||
220 | #define Page_size 0x2000U | ||
221 | #define Page_mask (Page_size - 1) | ||
222 | #define C218rx_spage 3 | ||
223 | #define C218tx_spage 4 | ||
224 | #define C218rx_pageno 1 | ||
225 | #define C218tx_pageno 4 | ||
226 | #define C218buf_pageno 5 | ||
227 | |||
228 | #define C320p8rx_spage 3 | ||
229 | #define C320p8tx_spage 4 | ||
230 | #define C320p8rx_pgno 1 | ||
231 | #define C320p8tx_pgno 4 | ||
232 | #define C320p8buf_pgno 5 | ||
233 | |||
234 | #define C320p16rx_spage 3 | ||
235 | #define C320p16tx_spage 4 | ||
236 | #define C320p16rx_pgno 1 | ||
237 | #define C320p16tx_pgno 2 | ||
238 | #define C320p16buf_pgno 3 | ||
239 | |||
240 | #define C320p24rx_spage 3 | ||
241 | #define C320p24tx_spage 4 | ||
242 | #define C320p24rx_pgno 1 | ||
243 | #define C320p24tx_pgno 1 | ||
244 | #define C320p24buf_pgno 2 | ||
245 | |||
246 | #define C320p32rx_spage 3 | ||
247 | #define C320p32tx_ofs C320p32rx_size | ||
248 | #define C320p32tx_spage 3 | ||
249 | #define C320p32buf_pgno 1 | ||
250 | |||
251 | /* | ||
252 | * Host Status | ||
253 | */ | ||
254 | #define WakeupRx 0x01 | ||
255 | #define WakeupTx 0x02 | ||
256 | #define WakeupBreak 0x08 | ||
257 | #define WakeupLine 0x10 | ||
258 | #define WakeupIntr 0x20 | ||
259 | #define WakeupQuit 0x40 | ||
260 | #define WakeupEOF 0x80 /* used in VTIME control */ | ||
261 | #define WakeupRxTrigger 0x100 | ||
262 | #define WakeupTxTrigger 0x200 | ||
263 | /* | ||
264 | * Flag status | ||
265 | */ | ||
266 | #define Rx_over 0x01 | ||
267 | #define Xoff_state 0x02 | ||
268 | #define Tx_flowOff 0x04 | ||
269 | #define Tx_enable 0x08 | ||
270 | #define CTS_state 0x10 | ||
271 | #define DSR_state 0x20 | ||
272 | #define DCD_state 0x80 | ||
273 | /* | ||
274 | * FlowControl | ||
275 | */ | ||
276 | #define CTS_FlowCtl 1 | ||
277 | #define RTS_FlowCtl 2 | ||
278 | #define Tx_FlowCtl 4 | ||
279 | #define Rx_FlowCtl 8 | ||
280 | #define IXM_IXANY 0x10 | ||
281 | |||
282 | #define LowWater 128 | ||
283 | |||
284 | #define DTR_ON 1 | ||
285 | #define RTS_ON 2 | ||
286 | #define CTS_ON 1 | ||
287 | #define DSR_ON 2 | ||
288 | #define DCD_ON 8 | ||
289 | |||
290 | /* mode definition */ | ||
291 | #define MX_CS8 0x03 | ||
292 | #define MX_CS7 0x02 | ||
293 | #define MX_CS6 0x01 | ||
294 | #define MX_CS5 0x00 | ||
295 | |||
296 | #define MX_STOP1 0x00 | ||
297 | #define MX_STOP15 0x04 | ||
298 | #define MX_STOP2 0x08 | ||
299 | |||
300 | #define MX_PARNONE 0x00 | ||
301 | #define MX_PAREVEN 0x40 | ||
302 | #define MX_PARODD 0xC0 | ||
303 | |||
304 | #endif | ||
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index ff146c2b08fd..fe2a95b5d3c0 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -180,7 +180,7 @@ mspec_close(struct vm_area_struct *vma) | |||
180 | my_page = vdata->maddr[index]; | 180 | my_page = vdata->maddr[index]; |
181 | vdata->maddr[index] = 0; | 181 | vdata->maddr[index] = 0; |
182 | if (!mspec_zero_block(my_page, PAGE_SIZE)) | 182 | if (!mspec_zero_block(my_page, PAGE_SIZE)) |
183 | uncached_free_page(my_page); | 183 | uncached_free_page(my_page, 1); |
184 | else | 184 | else |
185 | printk(KERN_WARNING "mspec_close(): " | 185 | printk(KERN_WARNING "mspec_close(): " |
186 | "failed to zero page %ld\n", my_page); | 186 | "failed to zero page %ld\n", my_page); |
@@ -209,7 +209,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) | |||
209 | index = (address - vdata->vm_start) >> PAGE_SHIFT; | 209 | index = (address - vdata->vm_start) >> PAGE_SHIFT; |
210 | maddr = (volatile unsigned long) vdata->maddr[index]; | 210 | maddr = (volatile unsigned long) vdata->maddr[index]; |
211 | if (maddr == 0) { | 211 | if (maddr == 0) { |
212 | maddr = uncached_alloc_page(numa_node_id()); | 212 | maddr = uncached_alloc_page(numa_node_id(), 1); |
213 | if (maddr == 0) | 213 | if (maddr == 0) |
214 | return NOPFN_OOM; | 214 | return NOPFN_OOM; |
215 | 215 | ||
@@ -218,7 +218,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) | |||
218 | vdata->count++; | 218 | vdata->count++; |
219 | vdata->maddr[index] = maddr; | 219 | vdata->maddr[index] = maddr; |
220 | } else { | 220 | } else { |
221 | uncached_free_page(maddr); | 221 | uncached_free_page(maddr, 1); |
222 | maddr = vdata->maddr[index]; | 222 | maddr = vdata->maddr[index]; |
223 | } | 223 | } |
224 | spin_unlock(&vdata->lock); | 224 | spin_unlock(&vdata->lock); |
@@ -367,7 +367,7 @@ mspec_init(void) | |||
367 | int nasid; | 367 | int nasid; |
368 | unsigned long phys; | 368 | unsigned long phys; |
369 | 369 | ||
370 | scratch_page[nid] = uncached_alloc_page(nid); | 370 | scratch_page[nid] = uncached_alloc_page(nid, 1); |
371 | if (scratch_page[nid] == 0) | 371 | if (scratch_page[nid] == 0) |
372 | goto free_scratch_pages; | 372 | goto free_scratch_pages; |
373 | phys = __pa(scratch_page[nid]); | 373 | phys = __pa(scratch_page[nid]); |
@@ -414,7 +414,7 @@ mspec_init(void) | |||
414 | free_scratch_pages: | 414 | free_scratch_pages: |
415 | for_each_node(nid) { | 415 | for_each_node(nid) { |
416 | if (scratch_page[nid] != 0) | 416 | if (scratch_page[nid] != 0) |
417 | uncached_free_page(scratch_page[nid]); | 417 | uncached_free_page(scratch_page[nid], 1); |
418 | } | 418 | } |
419 | return ret; | 419 | return ret; |
420 | } | 420 | } |
@@ -431,7 +431,7 @@ mspec_exit(void) | |||
431 | 431 | ||
432 | for_each_node(nid) { | 432 | for_each_node(nid) { |
433 | if (scratch_page[nid] != 0) | 433 | if (scratch_page[nid] != 0) |
434 | uncached_free_page(scratch_page[nid]); | 434 | uncached_free_page(scratch_page[nid], 1); |
435 | } | 435 | } |
436 | } | 436 | } |
437 | } | 437 | } |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 68c2e9234691..4b81a85c5b53 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -307,6 +307,200 @@ static unsigned char mxser_msr[MXSER_PORTS + 1]; | |||
307 | static struct mxser_mon_ext mon_data_ext; | 307 | static struct mxser_mon_ext mon_data_ext; |
308 | static int mxser_set_baud_method[MXSER_PORTS + 1]; | 308 | static int mxser_set_baud_method[MXSER_PORTS + 1]; |
309 | 309 | ||
310 | static void mxser_enable_must_enchance_mode(unsigned long baseio) | ||
311 | { | ||
312 | u8 oldlcr; | ||
313 | u8 efr; | ||
314 | |||
315 | oldlcr = inb(baseio + UART_LCR); | ||
316 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
317 | |||
318 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
319 | efr |= MOXA_MUST_EFR_EFRB_ENABLE; | ||
320 | |||
321 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
322 | outb(oldlcr, baseio + UART_LCR); | ||
323 | } | ||
324 | |||
325 | static void mxser_disable_must_enchance_mode(unsigned long baseio) | ||
326 | { | ||
327 | u8 oldlcr; | ||
328 | u8 efr; | ||
329 | |||
330 | oldlcr = inb(baseio + UART_LCR); | ||
331 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
332 | |||
333 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
334 | efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; | ||
335 | |||
336 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
337 | outb(oldlcr, baseio + UART_LCR); | ||
338 | } | ||
339 | |||
340 | static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) | ||
341 | { | ||
342 | u8 oldlcr; | ||
343 | u8 efr; | ||
344 | |||
345 | oldlcr = inb(baseio + UART_LCR); | ||
346 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
347 | |||
348 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
349 | efr &= ~MOXA_MUST_EFR_BANK_MASK; | ||
350 | efr |= MOXA_MUST_EFR_BANK0; | ||
351 | |||
352 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
353 | outb(value, baseio + MOXA_MUST_XON1_REGISTER); | ||
354 | outb(oldlcr, baseio + UART_LCR); | ||
355 | } | ||
356 | |||
357 | static void mxser_set_must_xoff1_value(unsigned long baseio, u8 value) | ||
358 | { | ||
359 | u8 oldlcr; | ||
360 | u8 efr; | ||
361 | |||
362 | oldlcr = inb(baseio + UART_LCR); | ||
363 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
364 | |||
365 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
366 | efr &= ~MOXA_MUST_EFR_BANK_MASK; | ||
367 | efr |= MOXA_MUST_EFR_BANK0; | ||
368 | |||
369 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
370 | outb(value, baseio + MOXA_MUST_XOFF1_REGISTER); | ||
371 | outb(oldlcr, baseio + UART_LCR); | ||
372 | } | ||
373 | |||
374 | static void mxser_set_must_fifo_value(struct mxser_port *info) | ||
375 | { | ||
376 | u8 oldlcr; | ||
377 | u8 efr; | ||
378 | |||
379 | oldlcr = inb(info->ioaddr + UART_LCR); | ||
380 | outb(MOXA_MUST_ENTER_ENCHANCE, info->ioaddr + UART_LCR); | ||
381 | |||
382 | efr = inb(info->ioaddr + MOXA_MUST_EFR_REGISTER); | ||
383 | efr &= ~MOXA_MUST_EFR_BANK_MASK; | ||
384 | efr |= MOXA_MUST_EFR_BANK1; | ||
385 | |||
386 | outb(efr, info->ioaddr + MOXA_MUST_EFR_REGISTER); | ||
387 | outb((u8)info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); | ||
388 | outb((u8)info->rx_trigger, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); | ||
389 | outb((u8)info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); | ||
390 | outb(oldlcr, info->ioaddr + UART_LCR); | ||
391 | } | ||
392 | |||
393 | static void mxser_set_must_enum_value(unsigned long baseio, u8 value) | ||
394 | { | ||
395 | u8 oldlcr; | ||
396 | u8 efr; | ||
397 | |||
398 | oldlcr = inb(baseio + UART_LCR); | ||
399 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
400 | |||
401 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
402 | efr &= ~MOXA_MUST_EFR_BANK_MASK; | ||
403 | efr |= MOXA_MUST_EFR_BANK2; | ||
404 | |||
405 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
406 | outb(value, baseio + MOXA_MUST_ENUM_REGISTER); | ||
407 | outb(oldlcr, baseio + UART_LCR); | ||
408 | } | ||
409 | |||
410 | static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) | ||
411 | { | ||
412 | u8 oldlcr; | ||
413 | u8 efr; | ||
414 | |||
415 | oldlcr = inb(baseio + UART_LCR); | ||
416 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
417 | |||
418 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
419 | efr &= ~MOXA_MUST_EFR_BANK_MASK; | ||
420 | efr |= MOXA_MUST_EFR_BANK2; | ||
421 | |||
422 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
423 | *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); | ||
424 | outb(oldlcr, baseio + UART_LCR); | ||
425 | } | ||
426 | |||
427 | static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) | ||
428 | { | ||
429 | u8 oldlcr; | ||
430 | u8 efr; | ||
431 | |||
432 | oldlcr = inb(baseio + UART_LCR); | ||
433 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
434 | |||
435 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
436 | efr &= ~MOXA_MUST_EFR_SF_MASK; | ||
437 | |||
438 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
439 | outb(oldlcr, baseio + UART_LCR); | ||
440 | } | ||
441 | |||
442 | static void mxser_enable_must_tx_software_flow_control(unsigned long baseio) | ||
443 | { | ||
444 | u8 oldlcr; | ||
445 | u8 efr; | ||
446 | |||
447 | oldlcr = inb(baseio + UART_LCR); | ||
448 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
449 | |||
450 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
451 | efr &= ~MOXA_MUST_EFR_SF_TX_MASK; | ||
452 | efr |= MOXA_MUST_EFR_SF_TX1; | ||
453 | |||
454 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
455 | outb(oldlcr, baseio + UART_LCR); | ||
456 | } | ||
457 | |||
458 | static void mxser_disable_must_tx_software_flow_control(unsigned long baseio) | ||
459 | { | ||
460 | u8 oldlcr; | ||
461 | u8 efr; | ||
462 | |||
463 | oldlcr = inb(baseio + UART_LCR); | ||
464 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
465 | |||
466 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
467 | efr &= ~MOXA_MUST_EFR_SF_TX_MASK; | ||
468 | |||
469 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
470 | outb(oldlcr, baseio + UART_LCR); | ||
471 | } | ||
472 | |||
473 | static void mxser_enable_must_rx_software_flow_control(unsigned long baseio) | ||
474 | { | ||
475 | u8 oldlcr; | ||
476 | u8 efr; | ||
477 | |||
478 | oldlcr = inb(baseio + UART_LCR); | ||
479 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
480 | |||
481 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
482 | efr &= ~MOXA_MUST_EFR_SF_RX_MASK; | ||
483 | efr |= MOXA_MUST_EFR_SF_RX1; | ||
484 | |||
485 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
486 | outb(oldlcr, baseio + UART_LCR); | ||
487 | } | ||
488 | |||
489 | static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) | ||
490 | { | ||
491 | u8 oldlcr; | ||
492 | u8 efr; | ||
493 | |||
494 | oldlcr = inb(baseio + UART_LCR); | ||
495 | outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); | ||
496 | |||
497 | efr = inb(baseio + MOXA_MUST_EFR_REGISTER); | ||
498 | efr &= ~MOXA_MUST_EFR_SF_RX_MASK; | ||
499 | |||
500 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | ||
501 | outb(oldlcr, baseio + UART_LCR); | ||
502 | } | ||
503 | |||
310 | #ifdef CONFIG_PCI | 504 | #ifdef CONFIG_PCI |
311 | static int __devinit CheckIsMoxaMust(unsigned long io) | 505 | static int __devinit CheckIsMoxaMust(unsigned long io) |
312 | { | 506 | { |
@@ -314,16 +508,16 @@ static int __devinit CheckIsMoxaMust(unsigned long io) | |||
314 | int i; | 508 | int i; |
315 | 509 | ||
316 | outb(0, io + UART_LCR); | 510 | outb(0, io + UART_LCR); |
317 | DISABLE_MOXA_MUST_ENCHANCE_MODE(io); | 511 | mxser_disable_must_enchance_mode(io); |
318 | oldmcr = inb(io + UART_MCR); | 512 | oldmcr = inb(io + UART_MCR); |
319 | outb(0, io + UART_MCR); | 513 | outb(0, io + UART_MCR); |
320 | SET_MOXA_MUST_XON1_VALUE(io, 0x11); | 514 | mxser_set_must_xon1_value(io, 0x11); |
321 | if ((hwid = inb(io + UART_MCR)) != 0) { | 515 | if ((hwid = inb(io + UART_MCR)) != 0) { |
322 | outb(oldmcr, io + UART_MCR); | 516 | outb(oldmcr, io + UART_MCR); |
323 | return MOXA_OTHER_UART; | 517 | return MOXA_OTHER_UART; |
324 | } | 518 | } |
325 | 519 | ||
326 | GET_MOXA_MUST_HARDWARE_ID(io, &hwid); | 520 | mxser_get_must_hardware_id(io, &hwid); |
327 | for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ | 521 | for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ |
328 | if (hwid == Gpci_uart_info[i].type) | 522 | if (hwid == Gpci_uart_info[i].type) |
329 | return (int)hwid; | 523 | return (int)hwid; |
@@ -494,10 +688,10 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
494 | } else | 688 | } else |
495 | quot /= newspd; | 689 | quot /= newspd; |
496 | 690 | ||
497 | SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot); | 691 | mxser_set_must_enum_value(info->ioaddr, quot); |
498 | } else | 692 | } else |
499 | #endif | 693 | #endif |
500 | SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0); | 694 | mxser_set_must_enum_value(info->ioaddr, 0); |
501 | 695 | ||
502 | return 0; | 696 | return 0; |
503 | } | 697 | } |
@@ -553,14 +747,14 @@ static int mxser_change_speed(struct mxser_port *info, | |||
553 | if (info->board->chip_flag) { | 747 | if (info->board->chip_flag) { |
554 | fcr = UART_FCR_ENABLE_FIFO; | 748 | fcr = UART_FCR_ENABLE_FIFO; |
555 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; | 749 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; |
556 | SET_MOXA_MUST_FIFO_VALUE(info); | 750 | mxser_set_must_fifo_value(info); |
557 | } else | 751 | } else |
558 | fcr = 0; | 752 | fcr = 0; |
559 | } else { | 753 | } else { |
560 | fcr = UART_FCR_ENABLE_FIFO; | 754 | fcr = UART_FCR_ENABLE_FIFO; |
561 | if (info->board->chip_flag) { | 755 | if (info->board->chip_flag) { |
562 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; | 756 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; |
563 | SET_MOXA_MUST_FIFO_VALUE(info); | 757 | mxser_set_must_fifo_value(info); |
564 | } else { | 758 | } else { |
565 | switch (info->rx_trigger) { | 759 | switch (info->rx_trigger) { |
566 | case 1: | 760 | case 1: |
@@ -657,17 +851,21 @@ static int mxser_change_speed(struct mxser_port *info, | |||
657 | } | 851 | } |
658 | } | 852 | } |
659 | if (info->board->chip_flag) { | 853 | if (info->board->chip_flag) { |
660 | SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty)); | 854 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->tty)); |
661 | SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty)); | 855 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->tty)); |
662 | if (I_IXON(info->tty)) { | 856 | if (I_IXON(info->tty)) { |
663 | ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 857 | mxser_enable_must_rx_software_flow_control( |
858 | info->ioaddr); | ||
664 | } else { | 859 | } else { |
665 | DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 860 | mxser_disable_must_rx_software_flow_control( |
861 | info->ioaddr); | ||
666 | } | 862 | } |
667 | if (I_IXOFF(info->tty)) { | 863 | if (I_IXOFF(info->tty)) { |
668 | ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 864 | mxser_enable_must_tx_software_flow_control( |
865 | info->ioaddr); | ||
669 | } else { | 866 | } else { |
670 | DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 867 | mxser_disable_must_tx_software_flow_control( |
868 | info->ioaddr); | ||
671 | } | 869 | } |
672 | } | 870 | } |
673 | 871 | ||
@@ -927,6 +1125,27 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
927 | return 0; | 1125 | return 0; |
928 | } | 1126 | } |
929 | 1127 | ||
1128 | static void mxser_flush_buffer(struct tty_struct *tty) | ||
1129 | { | ||
1130 | struct mxser_port *info = tty->driver_data; | ||
1131 | char fcr; | ||
1132 | unsigned long flags; | ||
1133 | |||
1134 | |||
1135 | spin_lock_irqsave(&info->slock, flags); | ||
1136 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
1137 | |||
1138 | fcr = inb(info->ioaddr + UART_FCR); | ||
1139 | outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
1140 | info->ioaddr + UART_FCR); | ||
1141 | outb(fcr, info->ioaddr + UART_FCR); | ||
1142 | |||
1143 | spin_unlock_irqrestore(&info->slock, flags); | ||
1144 | |||
1145 | tty_wakeup(tty); | ||
1146 | } | ||
1147 | |||
1148 | |||
930 | /* | 1149 | /* |
931 | * This routine is called when the serial port gets closed. First, we | 1150 | * This routine is called when the serial port gets closed. First, we |
932 | * wait for the last remaining data to be sent. Then, we unlink its | 1151 | * wait for the last remaining data to be sent. Then, we unlink its |
@@ -1013,9 +1232,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1013 | } | 1232 | } |
1014 | mxser_shutdown(info); | 1233 | mxser_shutdown(info); |
1015 | 1234 | ||
1016 | if (tty->driver->flush_buffer) | 1235 | mxser_flush_buffer(tty); |
1017 | tty->driver->flush_buffer(tty); | ||
1018 | |||
1019 | tty_ldisc_flush(tty); | 1236 | tty_ldisc_flush(tty); |
1020 | 1237 | ||
1021 | tty->closing = 0; | 1238 | tty->closing = 0; |
@@ -1072,16 +1289,16 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou | |||
1072 | return total; | 1289 | return total; |
1073 | } | 1290 | } |
1074 | 1291 | ||
1075 | static void mxser_put_char(struct tty_struct *tty, unsigned char ch) | 1292 | static int mxser_put_char(struct tty_struct *tty, unsigned char ch) |
1076 | { | 1293 | { |
1077 | struct mxser_port *info = tty->driver_data; | 1294 | struct mxser_port *info = tty->driver_data; |
1078 | unsigned long flags; | 1295 | unsigned long flags; |
1079 | 1296 | ||
1080 | if (!info->xmit_buf) | 1297 | if (!info->xmit_buf) |
1081 | return; | 1298 | return 0; |
1082 | 1299 | ||
1083 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | 1300 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) |
1084 | return; | 1301 | return 0; |
1085 | 1302 | ||
1086 | spin_lock_irqsave(&info->slock, flags); | 1303 | spin_lock_irqsave(&info->slock, flags); |
1087 | info->xmit_buf[info->xmit_head++] = ch; | 1304 | info->xmit_buf[info->xmit_head++] = ch; |
@@ -1099,6 +1316,7 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch) | |||
1099 | spin_unlock_irqrestore(&info->slock, flags); | 1316 | spin_unlock_irqrestore(&info->slock, flags); |
1100 | } | 1317 | } |
1101 | } | 1318 | } |
1319 | return 1; | ||
1102 | } | 1320 | } |
1103 | 1321 | ||
1104 | 1322 | ||
@@ -1142,26 +1360,6 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) | |||
1142 | return info->xmit_cnt; | 1360 | return info->xmit_cnt; |
1143 | } | 1361 | } |
1144 | 1362 | ||
1145 | static void mxser_flush_buffer(struct tty_struct *tty) | ||
1146 | { | ||
1147 | struct mxser_port *info = tty->driver_data; | ||
1148 | char fcr; | ||
1149 | unsigned long flags; | ||
1150 | |||
1151 | |||
1152 | spin_lock_irqsave(&info->slock, flags); | ||
1153 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
1154 | |||
1155 | fcr = inb(info->ioaddr + UART_FCR); | ||
1156 | outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
1157 | info->ioaddr + UART_FCR); | ||
1158 | outb(fcr, info->ioaddr + UART_FCR); | ||
1159 | |||
1160 | spin_unlock_irqrestore(&info->slock, flags); | ||
1161 | |||
1162 | tty_wakeup(tty); | ||
1163 | } | ||
1164 | |||
1165 | /* | 1363 | /* |
1166 | * ------------------------------------------------------------ | 1364 | * ------------------------------------------------------------ |
1167 | * friends of mxser_ioctl() | 1365 | * friends of mxser_ioctl() |
@@ -1460,6 +1658,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1460 | struct mxser_port *port; | 1658 | struct mxser_port *port; |
1461 | int result, status; | 1659 | int result, status; |
1462 | unsigned int i, j; | 1660 | unsigned int i, j; |
1661 | int ret = 0; | ||
1463 | 1662 | ||
1464 | switch (cmd) { | 1663 | switch (cmd) { |
1465 | case MOXA_GET_MAJOR: | 1664 | case MOXA_GET_MAJOR: |
@@ -1467,18 +1666,21 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1467 | 1666 | ||
1468 | case MOXA_CHKPORTENABLE: | 1667 | case MOXA_CHKPORTENABLE: |
1469 | result = 0; | 1668 | result = 0; |
1470 | 1669 | lock_kernel(); | |
1471 | for (i = 0; i < MXSER_BOARDS; i++) | 1670 | for (i = 0; i < MXSER_BOARDS; i++) |
1472 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) | 1671 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) |
1473 | if (mxser_boards[i].ports[j].ioaddr) | 1672 | if (mxser_boards[i].ports[j].ioaddr) |
1474 | result |= (1 << i); | 1673 | result |= (1 << i); |
1475 | 1674 | unlock_kernel(); | |
1476 | return put_user(result, (unsigned long __user *)argp); | 1675 | return put_user(result, (unsigned long __user *)argp); |
1477 | case MOXA_GETDATACOUNT: | 1676 | case MOXA_GETDATACOUNT: |
1677 | lock_kernel(); | ||
1478 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) | 1678 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) |
1479 | return -EFAULT; | 1679 | ret = -EFAULT; |
1480 | return 0; | 1680 | unlock_kernel(); |
1681 | return ret; | ||
1481 | case MOXA_GETMSTATUS: | 1682 | case MOXA_GETMSTATUS: |
1683 | lock_kernel(); | ||
1482 | for (i = 0; i < MXSER_BOARDS; i++) | 1684 | for (i = 0; i < MXSER_BOARDS; i++) |
1483 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1685 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1484 | port = &mxser_boards[i].ports[j]; | 1686 | port = &mxser_boards[i].ports[j]; |
@@ -1515,6 +1717,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1515 | else | 1717 | else |
1516 | GMStatus[i].cts = 0; | 1718 | GMStatus[i].cts = 0; |
1517 | } | 1719 | } |
1720 | unlock_kernel(); | ||
1518 | if (copy_to_user(argp, GMStatus, | 1721 | if (copy_to_user(argp, GMStatus, |
1519 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) | 1722 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) |
1520 | return -EFAULT; | 1723 | return -EFAULT; |
@@ -1524,7 +1727,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1524 | unsigned long opmode; | 1727 | unsigned long opmode; |
1525 | unsigned cflag, iflag; | 1728 | unsigned cflag, iflag; |
1526 | 1729 | ||
1527 | for (i = 0; i < MXSER_BOARDS; i++) | 1730 | lock_kernel(); |
1731 | for (i = 0; i < MXSER_BOARDS; i++) { | ||
1528 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1732 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1529 | port = &mxser_boards[i].ports[j]; | 1733 | port = &mxser_boards[i].ports[j]; |
1530 | if (!port->ioaddr) | 1734 | if (!port->ioaddr) |
@@ -1589,13 +1793,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1589 | mon_data_ext.iftype[i] = opmode; | 1793 | mon_data_ext.iftype[i] = opmode; |
1590 | 1794 | ||
1591 | } | 1795 | } |
1592 | if (copy_to_user(argp, &mon_data_ext, | 1796 | } |
1593 | sizeof(mon_data_ext))) | 1797 | unlock_kernel(); |
1594 | return -EFAULT; | 1798 | if (copy_to_user(argp, &mon_data_ext, |
1595 | 1799 | sizeof(mon_data_ext))) | |
1596 | return 0; | 1800 | return -EFAULT; |
1597 | 1801 | return 0; | |
1598 | } default: | 1802 | } |
1803 | default: | ||
1599 | return -ENOIOCTLCMD; | 1804 | return -ENOIOCTLCMD; |
1600 | } | 1805 | } |
1601 | return 0; | 1806 | return 0; |
@@ -1651,16 +1856,20 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1651 | opmode != RS422_MODE && | 1856 | opmode != RS422_MODE && |
1652 | opmode != RS485_4WIRE_MODE) | 1857 | opmode != RS485_4WIRE_MODE) |
1653 | return -EFAULT; | 1858 | return -EFAULT; |
1859 | lock_kernel(); | ||
1654 | mask = ModeMask[p]; | 1860 | mask = ModeMask[p]; |
1655 | shiftbit = p * 2; | 1861 | shiftbit = p * 2; |
1656 | val = inb(info->opmode_ioaddr); | 1862 | val = inb(info->opmode_ioaddr); |
1657 | val &= mask; | 1863 | val &= mask; |
1658 | val |= (opmode << shiftbit); | 1864 | val |= (opmode << shiftbit); |
1659 | outb(val, info->opmode_ioaddr); | 1865 | outb(val, info->opmode_ioaddr); |
1866 | unlock_kernel(); | ||
1660 | } else { | 1867 | } else { |
1868 | lock_kernel(); | ||
1661 | shiftbit = p * 2; | 1869 | shiftbit = p * 2; |
1662 | opmode = inb(info->opmode_ioaddr) >> shiftbit; | 1870 | opmode = inb(info->opmode_ioaddr) >> shiftbit; |
1663 | opmode &= OP_MODE_MASK; | 1871 | opmode &= OP_MODE_MASK; |
1872 | unlock_kernel(); | ||
1664 | if (put_user(opmode, (int __user *)argp)) | 1873 | if (put_user(opmode, (int __user *)argp)) |
1665 | return -EFAULT; | 1874 | return -EFAULT; |
1666 | } | 1875 | } |
@@ -1687,19 +1896,18 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1687 | tty_wait_until_sent(tty, 0); | 1896 | tty_wait_until_sent(tty, 0); |
1688 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); | 1897 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); |
1689 | return 0; | 1898 | return 0; |
1690 | case TIOCGSOFTCAR: | ||
1691 | return put_user(!!C_CLOCAL(tty), (unsigned long __user *)argp); | ||
1692 | case TIOCSSOFTCAR: | ||
1693 | if (get_user(arg, (unsigned long __user *)argp)) | ||
1694 | return -EFAULT; | ||
1695 | tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); | ||
1696 | return 0; | ||
1697 | case TIOCGSERIAL: | 1899 | case TIOCGSERIAL: |
1698 | return mxser_get_serial_info(info, argp); | 1900 | lock_kernel(); |
1901 | retval = mxser_get_serial_info(info, argp); | ||
1902 | unlock_kernel(); | ||
1903 | return retval; | ||
1699 | case TIOCSSERIAL: | 1904 | case TIOCSSERIAL: |
1700 | return mxser_set_serial_info(info, argp); | 1905 | lock_kernel(); |
1906 | retval = mxser_set_serial_info(info, argp); | ||
1907 | unlock_kernel(); | ||
1908 | return retval; | ||
1701 | case TIOCSERGETLSR: /* Get line status register */ | 1909 | case TIOCSERGETLSR: /* Get line status register */ |
1702 | return mxser_get_lsr_info(info, argp); | 1910 | return mxser_get_lsr_info(info, argp); |
1703 | /* | 1911 | /* |
1704 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | 1912 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change |
1705 | * - mask passed in arg for lines of interest | 1913 | * - mask passed in arg for lines of interest |
@@ -1746,24 +1954,27 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1746 | case MOXA_HighSpeedOn: | 1954 | case MOXA_HighSpeedOn: |
1747 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1955 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1748 | case MOXA_SDS_RSTICOUNTER: | 1956 | case MOXA_SDS_RSTICOUNTER: |
1957 | lock_kernel(); | ||
1749 | info->mon_data.rxcnt = 0; | 1958 | info->mon_data.rxcnt = 0; |
1750 | info->mon_data.txcnt = 0; | 1959 | info->mon_data.txcnt = 0; |
1960 | unlock_kernel(); | ||
1751 | return 0; | 1961 | return 0; |
1752 | 1962 | ||
1753 | case MOXA_ASPP_OQUEUE:{ | 1963 | case MOXA_ASPP_OQUEUE:{ |
1754 | int len, lsr; | 1964 | int len, lsr; |
1755 | 1965 | ||
1966 | lock_kernel(); | ||
1756 | len = mxser_chars_in_buffer(tty); | 1967 | len = mxser_chars_in_buffer(tty); |
1757 | |||
1758 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; | 1968 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; |
1759 | |||
1760 | len += (lsr ? 0 : 1); | 1969 | len += (lsr ? 0 : 1); |
1970 | unlock_kernel(); | ||
1761 | 1971 | ||
1762 | return put_user(len, (int __user *)argp); | 1972 | return put_user(len, (int __user *)argp); |
1763 | } | 1973 | } |
1764 | case MOXA_ASPP_MON: { | 1974 | case MOXA_ASPP_MON: { |
1765 | int mcr, status; | 1975 | int mcr, status; |
1766 | 1976 | ||
1977 | lock_kernel(); | ||
1767 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1978 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1768 | mxser_check_modem_status(info, status); | 1979 | mxser_check_modem_status(info, status); |
1769 | 1980 | ||
@@ -1782,7 +1993,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1782 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1993 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1783 | else | 1994 | else |
1784 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1995 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
1785 | 1996 | unlock_kernel(); | |
1786 | if (copy_to_user(argp, &info->mon_data, | 1997 | if (copy_to_user(argp, &info->mon_data, |
1787 | sizeof(struct mxser_mon))) | 1998 | sizeof(struct mxser_mon))) |
1788 | return -EFAULT; | 1999 | return -EFAULT; |
@@ -1925,7 +2136,8 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
1925 | 2136 | ||
1926 | if (info->board->chip_flag) { | 2137 | if (info->board->chip_flag) { |
1927 | spin_lock_irqsave(&info->slock, flags); | 2138 | spin_lock_irqsave(&info->slock, flags); |
1928 | DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 2139 | mxser_disable_must_rx_software_flow_control( |
2140 | info->ioaddr); | ||
1929 | spin_unlock_irqrestore(&info->slock, flags); | 2141 | spin_unlock_irqrestore(&info->slock, flags); |
1930 | } | 2142 | } |
1931 | 2143 | ||
@@ -1979,6 +2191,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1979 | timeout, char_time); | 2191 | timeout, char_time); |
1980 | printk("jiff=%lu...", jiffies); | 2192 | printk("jiff=%lu...", jiffies); |
1981 | #endif | 2193 | #endif |
2194 | lock_kernel(); | ||
1982 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { | 2195 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { |
1983 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2196 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1984 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); | 2197 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); |
@@ -1990,6 +2203,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1990 | break; | 2203 | break; |
1991 | } | 2204 | } |
1992 | set_current_state(TASK_RUNNING); | 2205 | set_current_state(TASK_RUNNING); |
2206 | unlock_kernel(); | ||
1993 | 2207 | ||
1994 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2208 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1995 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 2209 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
@@ -2342,7 +2556,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2342 | 2556 | ||
2343 | /* Enhance mode enabled here */ | 2557 | /* Enhance mode enabled here */ |
2344 | if (brd->chip_flag != MOXA_OTHER_UART) | 2558 | if (brd->chip_flag != MOXA_OTHER_UART) |
2345 | ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr); | 2559 | mxser_enable_must_enchance_mode(info->ioaddr); |
2346 | 2560 | ||
2347 | info->flags = ASYNC_SHARE_IRQ; | 2561 | info->flags = ASYNC_SHARE_IRQ; |
2348 | info->type = brd->uart_type; | 2562 | info->type = brd->uart_type; |
diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h index 844171115954..41878a69203d 100644 --- a/drivers/char/mxser.h +++ b/drivers/char/mxser.h | |||
@@ -147,141 +147,4 @@ | |||
147 | /* Rx software flow control mask */ | 147 | /* Rx software flow control mask */ |
148 | #define MOXA_MUST_EFR_SF_RX_MASK 0x03 | 148 | #define MOXA_MUST_EFR_SF_RX_MASK 0x03 |
149 | 149 | ||
150 | #define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \ | ||
151 | u8 __oldlcr, __efr; \ | ||
152 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
153 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
154 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
155 | __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \ | ||
156 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
157 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
158 | } while (0) | ||
159 | |||
160 | #define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \ | ||
161 | u8 __oldlcr, __efr; \ | ||
162 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
163 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
164 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
165 | __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \ | ||
166 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
167 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
168 | } while (0) | ||
169 | |||
170 | #define SET_MOXA_MUST_XON1_VALUE(baseio, Value) do { \ | ||
171 | u8 __oldlcr, __efr; \ | ||
172 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
173 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
174 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
175 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
176 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
177 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
178 | outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER); \ | ||
179 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
180 | } while (0) | ||
181 | |||
182 | #define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) do { \ | ||
183 | u8 __oldlcr, __efr; \ | ||
184 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
185 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
186 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
187 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
188 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
189 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
190 | outb((u8)(Value), (baseio)+MOXA_MUST_XOFF1_REGISTER); \ | ||
191 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
192 | } while (0) | ||
193 | |||
194 | #define SET_MOXA_MUST_FIFO_VALUE(info) do { \ | ||
195 | u8 __oldlcr, __efr; \ | ||
196 | __oldlcr = inb((info)->ioaddr+UART_LCR); \ | ||
197 | outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR);\ | ||
198 | __efr = inb((info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ | ||
199 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
200 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
201 | outb(__efr, (info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ | ||
202 | outb((u8)((info)->rx_high_water), (info)->ioaddr+ \ | ||
203 | MOXA_MUST_RBRTH_REGISTER); \ | ||
204 | outb((u8)((info)->rx_trigger), (info)->ioaddr+ \ | ||
205 | MOXA_MUST_RBRTI_REGISTER); \ | ||
206 | outb((u8)((info)->rx_low_water), (info)->ioaddr+ \ | ||
207 | MOXA_MUST_RBRTL_REGISTER); \ | ||
208 | outb(__oldlcr, (info)->ioaddr+UART_LCR); \ | ||
209 | } while (0) | ||
210 | |||
211 | #define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) do { \ | ||
212 | u8 __oldlcr, __efr; \ | ||
213 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
214 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
215 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
216 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
217 | __efr |= MOXA_MUST_EFR_BANK2; \ | ||
218 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
219 | outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER); \ | ||
220 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
221 | } while (0) | ||
222 | |||
223 | #define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) do { \ | ||
224 | u8 __oldlcr, __efr; \ | ||
225 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
226 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
227 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
228 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
229 | __efr |= MOXA_MUST_EFR_BANK2; \ | ||
230 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
231 | *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \ | ||
232 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
233 | } while (0) | ||
234 | |||
235 | #define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) do { \ | ||
236 | u8 __oldlcr, __efr; \ | ||
237 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
238 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
239 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
240 | __efr &= ~MOXA_MUST_EFR_SF_MASK; \ | ||
241 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
242 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
243 | } while (0) | ||
244 | |||
245 | #define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \ | ||
246 | u8 __oldlcr, __efr; \ | ||
247 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
248 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
249 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
250 | __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ | ||
251 | __efr |= MOXA_MUST_EFR_SF_TX1; \ | ||
252 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
253 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
254 | } while (0) | ||
255 | |||
256 | #define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \ | ||
257 | u8 __oldlcr, __efr; \ | ||
258 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
259 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
260 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
261 | __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ | ||
262 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
263 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
264 | } while (0) | ||
265 | |||
266 | #define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \ | ||
267 | u8 __oldlcr, __efr; \ | ||
268 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
269 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
270 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
271 | __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ | ||
272 | __efr |= MOXA_MUST_EFR_SF_RX1; \ | ||
273 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
274 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
275 | } while (0) | ||
276 | |||
277 | #define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \ | ||
278 | u8 __oldlcr, __efr; \ | ||
279 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
280 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
281 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
282 | __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ | ||
283 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
284 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
285 | } while (0) | ||
286 | |||
287 | #endif | 150 | #endif |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 06803ed5568c..a35bfd7ee80e 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -342,12 +342,10 @@ static int n_hdlc_tty_open (struct tty_struct *tty) | |||
342 | #endif | 342 | #endif |
343 | 343 | ||
344 | /* Flush any pending characters in the driver and discipline. */ | 344 | /* Flush any pending characters in the driver and discipline. */ |
345 | |||
346 | if (tty->ldisc.flush_buffer) | 345 | if (tty->ldisc.flush_buffer) |
347 | tty->ldisc.flush_buffer (tty); | 346 | tty->ldisc.flush_buffer(tty); |
348 | 347 | ||
349 | if (tty->driver->flush_buffer) | 348 | tty_driver_flush_buffer(tty); |
350 | tty->driver->flush_buffer (tty); | ||
351 | 349 | ||
352 | if (debuglevel >= DEBUG_LEVEL_INFO) | 350 | if (debuglevel >= DEBUG_LEVEL_INFO) |
353 | printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__); | 351 | printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__); |
@@ -399,7 +397,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) | |||
399 | 397 | ||
400 | /* Send the next block of data to device */ | 398 | /* Send the next block of data to device */ |
401 | tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | 399 | tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); |
402 | actual = tty->driver->write(tty, tbuf->buf, tbuf->count); | 400 | actual = tty->ops->write(tty, tbuf->buf, tbuf->count); |
403 | 401 | ||
404 | /* rollback was possible and has been done */ | 402 | /* rollback was possible and has been done */ |
405 | if (actual == -ERESTARTSYS) { | 403 | if (actual == -ERESTARTSYS) { |
@@ -578,26 +576,36 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
578 | return -EFAULT; | 576 | return -EFAULT; |
579 | } | 577 | } |
580 | 578 | ||
579 | lock_kernel(); | ||
580 | |||
581 | for (;;) { | 581 | for (;;) { |
582 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 582 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
583 | unlock_kernel(); | ||
583 | return -EIO; | 584 | return -EIO; |
585 | } | ||
584 | 586 | ||
585 | n_hdlc = tty2n_hdlc (tty); | 587 | n_hdlc = tty2n_hdlc (tty); |
586 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || | 588 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || |
587 | tty != n_hdlc->tty) | 589 | tty != n_hdlc->tty) { |
590 | unlock_kernel(); | ||
588 | return 0; | 591 | return 0; |
592 | } | ||
589 | 593 | ||
590 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); | 594 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); |
591 | if (rbuf) | 595 | if (rbuf) |
592 | break; | 596 | break; |
593 | 597 | ||
594 | /* no data */ | 598 | /* no data */ |
595 | if (file->f_flags & O_NONBLOCK) | 599 | if (file->f_flags & O_NONBLOCK) { |
600 | unlock_kernel(); | ||
596 | return -EAGAIN; | 601 | return -EAGAIN; |
602 | } | ||
597 | 603 | ||
598 | interruptible_sleep_on (&tty->read_wait); | 604 | interruptible_sleep_on (&tty->read_wait); |
599 | if (signal_pending(current)) | 605 | if (signal_pending(current)) { |
606 | unlock_kernel(); | ||
600 | return -EINTR; | 607 | return -EINTR; |
608 | } | ||
601 | } | 609 | } |
602 | 610 | ||
603 | if (rbuf->count > nr) | 611 | if (rbuf->count > nr) |
@@ -618,7 +626,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
618 | kfree(rbuf); | 626 | kfree(rbuf); |
619 | else | 627 | else |
620 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); | 628 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); |
621 | 629 | unlock_kernel(); | |
622 | return ret; | 630 | return ret; |
623 | 631 | ||
624 | } /* end of n_hdlc_tty_read() */ | 632 | } /* end of n_hdlc_tty_read() */ |
@@ -661,6 +669,8 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
661 | count = maxframe; | 669 | count = maxframe; |
662 | } | 670 | } |
663 | 671 | ||
672 | lock_kernel(); | ||
673 | |||
664 | add_wait_queue(&tty->write_wait, &wait); | 674 | add_wait_queue(&tty->write_wait, &wait); |
665 | set_current_state(TASK_INTERRUPTIBLE); | 675 | set_current_state(TASK_INTERRUPTIBLE); |
666 | 676 | ||
@@ -695,7 +705,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
695 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); | 705 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); |
696 | n_hdlc_send_frames(n_hdlc,tty); | 706 | n_hdlc_send_frames(n_hdlc,tty); |
697 | } | 707 | } |
698 | 708 | unlock_kernel(); | |
699 | return error; | 709 | return error; |
700 | 710 | ||
701 | } /* end of n_hdlc_tty_write() */ | 711 | } /* end of n_hdlc_tty_write() */ |
@@ -740,8 +750,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
740 | 750 | ||
741 | case TIOCOUTQ: | 751 | case TIOCOUTQ: |
742 | /* get the pending tx byte count in the driver */ | 752 | /* get the pending tx byte count in the driver */ |
743 | count = tty->driver->chars_in_buffer ? | 753 | count = tty_chars_in_buffer(tty); |
744 | tty->driver->chars_in_buffer(tty) : 0; | ||
745 | /* add size of next output frame in queue */ | 754 | /* add size of next output frame in queue */ |
746 | spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); | 755 | spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); |
747 | if (n_hdlc->tx_buf_list.head) | 756 | if (n_hdlc->tx_buf_list.head) |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 6b918b80f73e..902169062332 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -376,8 +376,9 @@ static void put_char(struct r3964_info *pInfo, unsigned char ch) | |||
376 | if (tty == NULL) | 376 | if (tty == NULL) |
377 | return; | 377 | return; |
378 | 378 | ||
379 | if (tty->driver->put_char) { | 379 | /* FIXME: put_char should not be called from an IRQ */ |
380 | tty->driver->put_char(tty, ch); | 380 | if (tty->ops->put_char) { |
381 | tty->ops->put_char(tty, ch); | ||
381 | } | 382 | } |
382 | pInfo->bcc ^= ch; | 383 | pInfo->bcc ^= ch; |
383 | } | 384 | } |
@@ -386,12 +387,9 @@ static void flush(struct r3964_info *pInfo) | |||
386 | { | 387 | { |
387 | struct tty_struct *tty = pInfo->tty; | 388 | struct tty_struct *tty = pInfo->tty; |
388 | 389 | ||
389 | if (tty == NULL) | 390 | if (tty == NULL || tty->ops->flush_chars == NULL) |
390 | return; | 391 | return; |
391 | 392 | tty->ops->flush_chars(tty); | |
392 | if (tty->driver->flush_chars) { | ||
393 | tty->driver->flush_chars(tty); | ||
394 | } | ||
395 | } | 393 | } |
396 | 394 | ||
397 | static void trigger_transmit(struct r3964_info *pInfo) | 395 | static void trigger_transmit(struct r3964_info *pInfo) |
@@ -449,12 +447,11 @@ static void transmit_block(struct r3964_info *pInfo) | |||
449 | struct r3964_block_header *pBlock = pInfo->tx_first; | 447 | struct r3964_block_header *pBlock = pInfo->tx_first; |
450 | int room = 0; | 448 | int room = 0; |
451 | 449 | ||
452 | if ((tty == NULL) || (pBlock == NULL)) { | 450 | if (tty == NULL || pBlock == NULL) { |
453 | return; | 451 | return; |
454 | } | 452 | } |
455 | 453 | ||
456 | if (tty->driver->write_room) | 454 | room = tty_write_room(tty); |
457 | room = tty->driver->write_room(tty); | ||
458 | 455 | ||
459 | TRACE_PS("transmit_block %p, room %d, length %d", | 456 | TRACE_PS("transmit_block %p, room %d, length %d", |
460 | pBlock, room, pBlock->length); | 457 | pBlock, room, pBlock->length); |
@@ -1075,12 +1072,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1075 | 1072 | ||
1076 | TRACE_L("read()"); | 1073 | TRACE_L("read()"); |
1077 | 1074 | ||
1075 | lock_kernel(); | ||
1076 | |||
1078 | pClient = findClient(pInfo, task_pid(current)); | 1077 | pClient = findClient(pInfo, task_pid(current)); |
1079 | if (pClient) { | 1078 | if (pClient) { |
1080 | pMsg = remove_msg(pInfo, pClient); | 1079 | pMsg = remove_msg(pInfo, pClient); |
1081 | if (pMsg == NULL) { | 1080 | if (pMsg == NULL) { |
1082 | /* no messages available. */ | 1081 | /* no messages available. */ |
1083 | if (file->f_flags & O_NONBLOCK) { | 1082 | if (file->f_flags & O_NONBLOCK) { |
1083 | unlock_kernel(); | ||
1084 | return -EAGAIN; | 1084 | return -EAGAIN; |
1085 | } | 1085 | } |
1086 | /* block until there is a message: */ | 1086 | /* block until there is a message: */ |
@@ -1090,8 +1090,10 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1090 | 1090 | ||
1091 | /* If we still haven't got a message, we must have been signalled */ | 1091 | /* If we still haven't got a message, we must have been signalled */ |
1092 | 1092 | ||
1093 | if (!pMsg) | 1093 | if (!pMsg) { |
1094 | unlock_kernel(); | ||
1094 | return -EINTR; | 1095 | return -EINTR; |
1096 | } | ||
1095 | 1097 | ||
1096 | /* deliver msg to client process: */ | 1098 | /* deliver msg to client process: */ |
1097 | theMsg.msg_id = pMsg->msg_id; | 1099 | theMsg.msg_id = pMsg->msg_id; |
@@ -1102,12 +1104,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1102 | kfree(pMsg); | 1104 | kfree(pMsg); |
1103 | TRACE_M("r3964_read - msg kfree %p", pMsg); | 1105 | TRACE_M("r3964_read - msg kfree %p", pMsg); |
1104 | 1106 | ||
1105 | if (copy_to_user(buf, &theMsg, count)) | 1107 | if (copy_to_user(buf, &theMsg, count)) { |
1108 | unlock_kernel(); | ||
1106 | return -EFAULT; | 1109 | return -EFAULT; |
1110 | } | ||
1107 | 1111 | ||
1108 | TRACE_PS("read - return %d", count); | 1112 | TRACE_PS("read - return %d", count); |
1109 | return count; | 1113 | return count; |
1110 | } | 1114 | } |
1115 | unlock_kernel(); | ||
1111 | return -EPERM; | 1116 | return -EPERM; |
1112 | } | 1117 | } |
1113 | 1118 | ||
@@ -1156,6 +1161,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1156 | pHeader->locks = 0; | 1161 | pHeader->locks = 0; |
1157 | pHeader->owner = NULL; | 1162 | pHeader->owner = NULL; |
1158 | 1163 | ||
1164 | lock_kernel(); | ||
1165 | |||
1159 | pClient = findClient(pInfo, task_pid(current)); | 1166 | pClient = findClient(pInfo, task_pid(current)); |
1160 | if (pClient) { | 1167 | if (pClient) { |
1161 | pHeader->owner = pClient; | 1168 | pHeader->owner = pClient; |
@@ -1173,6 +1180,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1173 | add_tx_queue(pInfo, pHeader); | 1180 | add_tx_queue(pInfo, pHeader); |
1174 | trigger_transmit(pInfo); | 1181 | trigger_transmit(pInfo); |
1175 | 1182 | ||
1183 | unlock_kernel(); | ||
1184 | |||
1176 | return 0; | 1185 | return 0; |
1177 | } | 1186 | } |
1178 | 1187 | ||
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 0c09409fa45d..19105ec203f7 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -147,10 +147,8 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty) | |||
147 | 147 | ||
148 | static void check_unthrottle(struct tty_struct *tty) | 148 | static void check_unthrottle(struct tty_struct *tty) |
149 | { | 149 | { |
150 | if (tty->count && | 150 | if (tty->count) |
151 | test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 151 | tty_unthrottle(tty); |
152 | tty->driver->unthrottle) | ||
153 | tty->driver->unthrottle(tty); | ||
154 | } | 152 | } |
155 | 153 | ||
156 | /** | 154 | /** |
@@ -183,22 +181,24 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
183 | * at hangup) or when the N_TTY line discipline internally has to | 181 | * at hangup) or when the N_TTY line discipline internally has to |
184 | * clean the pending queue (for example some signals). | 182 | * clean the pending queue (for example some signals). |
185 | * | 183 | * |
186 | * FIXME: tty->ctrl_status is not spinlocked and relies on | 184 | * Locking: ctrl_lock |
187 | * lock_kernel() still. | ||
188 | */ | 185 | */ |
189 | 186 | ||
190 | static void n_tty_flush_buffer(struct tty_struct *tty) | 187 | static void n_tty_flush_buffer(struct tty_struct *tty) |
191 | { | 188 | { |
189 | unsigned long flags; | ||
192 | /* clear everything and unthrottle the driver */ | 190 | /* clear everything and unthrottle the driver */ |
193 | reset_buffer_flags(tty); | 191 | reset_buffer_flags(tty); |
194 | 192 | ||
195 | if (!tty->link) | 193 | if (!tty->link) |
196 | return; | 194 | return; |
197 | 195 | ||
196 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
198 | if (tty->link->packet) { | 197 | if (tty->link->packet) { |
199 | tty->ctrl_status |= TIOCPKT_FLUSHREAD; | 198 | tty->ctrl_status |= TIOCPKT_FLUSHREAD; |
200 | wake_up_interruptible(&tty->link->read_wait); | 199 | wake_up_interruptible(&tty->link->read_wait); |
201 | } | 200 | } |
201 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
202 | } | 202 | } |
203 | 203 | ||
204 | /** | 204 | /** |
@@ -264,17 +264,18 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty) | |||
264 | * relevant in the world today. If you ever need them, add them here. | 264 | * relevant in the world today. If you ever need them, add them here. |
265 | * | 265 | * |
266 | * Called from both the receive and transmit sides and can be called | 266 | * Called from both the receive and transmit sides and can be called |
267 | * re-entrantly. Relies on lock_kernel() still. | 267 | * re-entrantly. Relies on lock_kernel() for tty->column state. |
268 | */ | 268 | */ |
269 | 269 | ||
270 | static int opost(unsigned char c, struct tty_struct *tty) | 270 | static int opost(unsigned char c, struct tty_struct *tty) |
271 | { | 271 | { |
272 | int space, spaces; | 272 | int space, spaces; |
273 | 273 | ||
274 | space = tty->driver->write_room(tty); | 274 | space = tty_write_room(tty); |
275 | if (!space) | 275 | if (!space) |
276 | return -1; | 276 | return -1; |
277 | 277 | ||
278 | lock_kernel(); | ||
278 | if (O_OPOST(tty)) { | 279 | if (O_OPOST(tty)) { |
279 | switch (c) { | 280 | switch (c) { |
280 | case '\n': | 281 | case '\n': |
@@ -283,7 +284,7 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
283 | if (O_ONLCR(tty)) { | 284 | if (O_ONLCR(tty)) { |
284 | if (space < 2) | 285 | if (space < 2) |
285 | return -1; | 286 | return -1; |
286 | tty->driver->put_char(tty, '\r'); | 287 | tty_put_char(tty, '\r'); |
287 | tty->column = 0; | 288 | tty->column = 0; |
288 | } | 289 | } |
289 | tty->canon_column = tty->column; | 290 | tty->canon_column = tty->column; |
@@ -305,7 +306,7 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
305 | if (space < spaces) | 306 | if (space < spaces) |
306 | return -1; | 307 | return -1; |
307 | tty->column += spaces; | 308 | tty->column += spaces; |
308 | tty->driver->write(tty, " ", spaces); | 309 | tty->ops->write(tty, " ", spaces); |
309 | return 0; | 310 | return 0; |
310 | } | 311 | } |
311 | tty->column += spaces; | 312 | tty->column += spaces; |
@@ -322,7 +323,8 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
322 | break; | 323 | break; |
323 | } | 324 | } |
324 | } | 325 | } |
325 | tty->driver->put_char(tty, c); | 326 | tty_put_char(tty, c); |
327 | unlock_kernel(); | ||
326 | return 0; | 328 | return 0; |
327 | } | 329 | } |
328 | 330 | ||
@@ -337,7 +339,8 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
337 | * the simple cases normally found and helps to generate blocks of | 339 | * the simple cases normally found and helps to generate blocks of |
338 | * symbols for the console driver and thus improve performance. | 340 | * symbols for the console driver and thus improve performance. |
339 | * | 341 | * |
340 | * Called from write_chan under the tty layer write lock. | 342 | * Called from write_chan under the tty layer write lock. Relies |
343 | * on lock_kernel for the tty->column state. | ||
341 | */ | 344 | */ |
342 | 345 | ||
343 | static ssize_t opost_block(struct tty_struct *tty, | 346 | static ssize_t opost_block(struct tty_struct *tty, |
@@ -347,12 +350,13 @@ static ssize_t opost_block(struct tty_struct *tty, | |||
347 | int i; | 350 | int i; |
348 | const unsigned char *cp; | 351 | const unsigned char *cp; |
349 | 352 | ||
350 | space = tty->driver->write_room(tty); | 353 | space = tty_write_room(tty); |
351 | if (!space) | 354 | if (!space) |
352 | return 0; | 355 | return 0; |
353 | if (nr > space) | 356 | if (nr > space) |
354 | nr = space; | 357 | nr = space; |
355 | 358 | ||
359 | lock_kernel(); | ||
356 | for (i = 0, cp = buf; i < nr; i++, cp++) { | 360 | for (i = 0, cp = buf; i < nr; i++, cp++) { |
357 | switch (*cp) { | 361 | switch (*cp) { |
358 | case '\n': | 362 | case '\n': |
@@ -384,27 +388,15 @@ static ssize_t opost_block(struct tty_struct *tty, | |||
384 | } | 388 | } |
385 | } | 389 | } |
386 | break_out: | 390 | break_out: |
387 | if (tty->driver->flush_chars) | 391 | if (tty->ops->flush_chars) |
388 | tty->driver->flush_chars(tty); | 392 | tty->ops->flush_chars(tty); |
389 | i = tty->driver->write(tty, buf, i); | 393 | i = tty->ops->write(tty, buf, i); |
394 | unlock_kernel(); | ||
390 | return i; | 395 | return i; |
391 | } | 396 | } |
392 | 397 | ||
393 | 398 | ||
394 | /** | 399 | /** |
395 | * put_char - write character to driver | ||
396 | * @c: character (or part of unicode symbol) | ||
397 | * @tty: terminal device | ||
398 | * | ||
399 | * Queue a byte to the driver layer for output | ||
400 | */ | ||
401 | |||
402 | static inline void put_char(unsigned char c, struct tty_struct *tty) | ||
403 | { | ||
404 | tty->driver->put_char(tty, c); | ||
405 | } | ||
406 | |||
407 | /** | ||
408 | * echo_char - echo characters | 400 | * echo_char - echo characters |
409 | * @c: unicode byte to echo | 401 | * @c: unicode byte to echo |
410 | * @tty: terminal device | 402 | * @tty: terminal device |
@@ -416,8 +408,8 @@ static inline void put_char(unsigned char c, struct tty_struct *tty) | |||
416 | static void echo_char(unsigned char c, struct tty_struct *tty) | 408 | static void echo_char(unsigned char c, struct tty_struct *tty) |
417 | { | 409 | { |
418 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') { | 410 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') { |
419 | put_char('^', tty); | 411 | tty_put_char(tty, '^'); |
420 | put_char(c ^ 0100, tty); | 412 | tty_put_char(tty, c ^ 0100); |
421 | tty->column += 2; | 413 | tty->column += 2; |
422 | } else | 414 | } else |
423 | opost(c, tty); | 415 | opost(c, tty); |
@@ -426,7 +418,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty) | |||
426 | static inline void finish_erasing(struct tty_struct *tty) | 418 | static inline void finish_erasing(struct tty_struct *tty) |
427 | { | 419 | { |
428 | if (tty->erasing) { | 420 | if (tty->erasing) { |
429 | put_char('/', tty); | 421 | tty_put_char(tty, '/'); |
430 | tty->column++; | 422 | tty->column++; |
431 | tty->erasing = 0; | 423 | tty->erasing = 0; |
432 | } | 424 | } |
@@ -510,7 +502,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
510 | if (L_ECHO(tty)) { | 502 | if (L_ECHO(tty)) { |
511 | if (L_ECHOPRT(tty)) { | 503 | if (L_ECHOPRT(tty)) { |
512 | if (!tty->erasing) { | 504 | if (!tty->erasing) { |
513 | put_char('\\', tty); | 505 | tty_put_char(tty, '\\'); |
514 | tty->column++; | 506 | tty->column++; |
515 | tty->erasing = 1; | 507 | tty->erasing = 1; |
516 | } | 508 | } |
@@ -518,7 +510,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
518 | echo_char(c, tty); | 510 | echo_char(c, tty); |
519 | while (--cnt > 0) { | 511 | while (--cnt > 0) { |
520 | head = (head+1) & (N_TTY_BUF_SIZE-1); | 512 | head = (head+1) & (N_TTY_BUF_SIZE-1); |
521 | put_char(tty->read_buf[head], tty); | 513 | tty_put_char(tty, tty->read_buf[head]); |
522 | } | 514 | } |
523 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { | 515 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { |
524 | echo_char(ERASE_CHAR(tty), tty); | 516 | echo_char(ERASE_CHAR(tty), tty); |
@@ -546,22 +538,22 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
546 | /* Now backup to that column. */ | 538 | /* Now backup to that column. */ |
547 | while (tty->column > col) { | 539 | while (tty->column > col) { |
548 | /* Can't use opost here. */ | 540 | /* Can't use opost here. */ |
549 | put_char('\b', tty); | 541 | tty_put_char(tty, '\b'); |
550 | if (tty->column > 0) | 542 | if (tty->column > 0) |
551 | tty->column--; | 543 | tty->column--; |
552 | } | 544 | } |
553 | } else { | 545 | } else { |
554 | if (iscntrl(c) && L_ECHOCTL(tty)) { | 546 | if (iscntrl(c) && L_ECHOCTL(tty)) { |
555 | put_char('\b', tty); | 547 | tty_put_char(tty, '\b'); |
556 | put_char(' ', tty); | 548 | tty_put_char(tty, ' '); |
557 | put_char('\b', tty); | 549 | tty_put_char(tty, '\b'); |
558 | if (tty->column > 0) | 550 | if (tty->column > 0) |
559 | tty->column--; | 551 | tty->column--; |
560 | } | 552 | } |
561 | if (!iscntrl(c) || L_ECHOCTL(tty)) { | 553 | if (!iscntrl(c) || L_ECHOCTL(tty)) { |
562 | put_char('\b', tty); | 554 | tty_put_char(tty, '\b'); |
563 | put_char(' ', tty); | 555 | tty_put_char(tty, ' '); |
564 | put_char('\b', tty); | 556 | tty_put_char(tty, '\b'); |
565 | if (tty->column > 0) | 557 | if (tty->column > 0) |
566 | tty->column--; | 558 | tty->column--; |
567 | } | 559 | } |
@@ -592,8 +584,7 @@ static inline void isig(int sig, struct tty_struct *tty, int flush) | |||
592 | kill_pgrp(tty->pgrp, sig, 1); | 584 | kill_pgrp(tty->pgrp, sig, 1); |
593 | if (flush || !L_NOFLSH(tty)) { | 585 | if (flush || !L_NOFLSH(tty)) { |
594 | n_tty_flush_buffer(tty); | 586 | n_tty_flush_buffer(tty); |
595 | if (tty->driver->flush_buffer) | 587 | tty_driver_flush_buffer(tty); |
596 | tty->driver->flush_buffer(tty); | ||
597 | } | 588 | } |
598 | } | 589 | } |
599 | 590 | ||
@@ -701,7 +692,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
701 | 692 | ||
702 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | 693 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && |
703 | ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || | 694 | ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || |
704 | c == INTR_CHAR(tty) || c == QUIT_CHAR(tty))) | 695 | c == INTR_CHAR(tty) || c == QUIT_CHAR(tty) || c == SUSP_CHAR(tty))) |
705 | start_tty(tty); | 696 | start_tty(tty); |
706 | 697 | ||
707 | if (tty->closing) { | 698 | if (tty->closing) { |
@@ -725,7 +716,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
725 | tty->lnext = 0; | 716 | tty->lnext = 0; |
726 | if (L_ECHO(tty)) { | 717 | if (L_ECHO(tty)) { |
727 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 718 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { |
728 | put_char('\a', tty); /* beep if no space */ | 719 | tty_put_char(tty, '\a'); /* beep if no space */ |
729 | return; | 720 | return; |
730 | } | 721 | } |
731 | /* Record the column of first canon char. */ | 722 | /* Record the column of first canon char. */ |
@@ -739,13 +730,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
739 | return; | 730 | return; |
740 | } | 731 | } |
741 | 732 | ||
742 | if (c == '\r') { | ||
743 | if (I_IGNCR(tty)) | ||
744 | return; | ||
745 | if (I_ICRNL(tty)) | ||
746 | c = '\n'; | ||
747 | } else if (c == '\n' && I_INLCR(tty)) | ||
748 | c = '\r'; | ||
749 | if (I_IXON(tty)) { | 733 | if (I_IXON(tty)) { |
750 | if (c == START_CHAR(tty)) { | 734 | if (c == START_CHAR(tty)) { |
751 | start_tty(tty); | 735 | start_tty(tty); |
@@ -756,6 +740,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
756 | return; | 740 | return; |
757 | } | 741 | } |
758 | } | 742 | } |
743 | |||
759 | if (L_ISIG(tty)) { | 744 | if (L_ISIG(tty)) { |
760 | int signal; | 745 | int signal; |
761 | signal = SIGINT; | 746 | signal = SIGINT; |
@@ -775,8 +760,7 @@ send_signal: | |||
775 | */ | 760 | */ |
776 | if (!L_NOFLSH(tty)) { | 761 | if (!L_NOFLSH(tty)) { |
777 | n_tty_flush_buffer(tty); | 762 | n_tty_flush_buffer(tty); |
778 | if (tty->driver->flush_buffer) | 763 | tty_driver_flush_buffer(tty); |
779 | tty->driver->flush_buffer(tty); | ||
780 | } | 764 | } |
781 | if (L_ECHO(tty)) | 765 | if (L_ECHO(tty)) |
782 | echo_char(c, tty); | 766 | echo_char(c, tty); |
@@ -785,6 +769,15 @@ send_signal: | |||
785 | return; | 769 | return; |
786 | } | 770 | } |
787 | } | 771 | } |
772 | |||
773 | if (c == '\r') { | ||
774 | if (I_IGNCR(tty)) | ||
775 | return; | ||
776 | if (I_ICRNL(tty)) | ||
777 | c = '\n'; | ||
778 | } else if (c == '\n' && I_INLCR(tty)) | ||
779 | c = '\r'; | ||
780 | |||
788 | if (tty->icanon) { | 781 | if (tty->icanon) { |
789 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || | 782 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || |
790 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { | 783 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { |
@@ -796,8 +789,8 @@ send_signal: | |||
796 | if (L_ECHO(tty)) { | 789 | if (L_ECHO(tty)) { |
797 | finish_erasing(tty); | 790 | finish_erasing(tty); |
798 | if (L_ECHOCTL(tty)) { | 791 | if (L_ECHOCTL(tty)) { |
799 | put_char('^', tty); | 792 | tty_put_char(tty, '^'); |
800 | put_char('\b', tty); | 793 | tty_put_char(tty, '\b'); |
801 | } | 794 | } |
802 | } | 795 | } |
803 | return; | 796 | return; |
@@ -818,7 +811,7 @@ send_signal: | |||
818 | if (c == '\n') { | 811 | if (c == '\n') { |
819 | if (L_ECHO(tty) || L_ECHONL(tty)) { | 812 | if (L_ECHO(tty) || L_ECHONL(tty)) { |
820 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | 813 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) |
821 | put_char('\a', tty); | 814 | tty_put_char(tty, '\a'); |
822 | opost('\n', tty); | 815 | opost('\n', tty); |
823 | } | 816 | } |
824 | goto handle_newline; | 817 | goto handle_newline; |
@@ -836,7 +829,7 @@ send_signal: | |||
836 | */ | 829 | */ |
837 | if (L_ECHO(tty)) { | 830 | if (L_ECHO(tty)) { |
838 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | 831 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) |
839 | put_char('\a', tty); | 832 | tty_put_char(tty, '\a'); |
840 | /* Record the column of first canon char. */ | 833 | /* Record the column of first canon char. */ |
841 | if (tty->canon_head == tty->read_head) | 834 | if (tty->canon_head == tty->read_head) |
842 | tty->canon_column = tty->column; | 835 | tty->canon_column = tty->column; |
@@ -866,7 +859,7 @@ handle_newline: | |||
866 | finish_erasing(tty); | 859 | finish_erasing(tty); |
867 | if (L_ECHO(tty)) { | 860 | if (L_ECHO(tty)) { |
868 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 861 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { |
869 | put_char('\a', tty); /* beep if no space */ | 862 | tty_put_char(tty, '\a'); /* beep if no space */ |
870 | return; | 863 | return; |
871 | } | 864 | } |
872 | if (c == '\n') | 865 | if (c == '\n') |
@@ -970,8 +963,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
970 | break; | 963 | break; |
971 | } | 964 | } |
972 | } | 965 | } |
973 | if (tty->driver->flush_chars) | 966 | if (tty->ops->flush_chars) |
974 | tty->driver->flush_chars(tty); | 967 | tty->ops->flush_chars(tty); |
975 | } | 968 | } |
976 | 969 | ||
977 | n_tty_set_room(tty); | 970 | n_tty_set_room(tty); |
@@ -987,12 +980,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
987 | * mode. We don't want to throttle the driver if we're in | 980 | * mode. We don't want to throttle the driver if we're in |
988 | * canonical mode and don't have a newline yet! | 981 | * canonical mode and don't have a newline yet! |
989 | */ | 982 | */ |
990 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { | 983 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) |
991 | /* check TTY_THROTTLED first so it indicates our state */ | 984 | tty_throttle(tty); |
992 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | ||
993 | tty->driver->throttle) | ||
994 | tty->driver->throttle(tty); | ||
995 | } | ||
996 | } | 985 | } |
997 | 986 | ||
998 | int is_ignored(int sig) | 987 | int is_ignored(int sig) |
@@ -1076,6 +1065,9 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1076 | tty->real_raw = 0; | 1065 | tty->real_raw = 0; |
1077 | } | 1066 | } |
1078 | n_tty_set_room(tty); | 1067 | n_tty_set_room(tty); |
1068 | /* The termios change make the tty ready for I/O */ | ||
1069 | wake_up_interruptible(&tty->write_wait); | ||
1070 | wake_up_interruptible(&tty->read_wait); | ||
1079 | } | 1071 | } |
1080 | 1072 | ||
1081 | /** | 1073 | /** |
@@ -1194,6 +1186,11 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *, | |||
1194 | * Perform job control management checks on this file/tty descriptor | 1186 | * Perform job control management checks on this file/tty descriptor |
1195 | * and if appropriate send any needed signals and return a negative | 1187 | * and if appropriate send any needed signals and return a negative |
1196 | * error code if action should be taken. | 1188 | * error code if action should be taken. |
1189 | * | ||
1190 | * FIXME: | ||
1191 | * Locking: None - redirected write test is safe, testing | ||
1192 | * current->signal should possibly lock current->sighand | ||
1193 | * pgrp locking ? | ||
1197 | */ | 1194 | */ |
1198 | 1195 | ||
1199 | static int job_control(struct tty_struct *tty, struct file *file) | 1196 | static int job_control(struct tty_struct *tty, struct file *file) |
@@ -1246,6 +1243,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, | |||
1246 | ssize_t size; | 1243 | ssize_t size; |
1247 | long timeout; | 1244 | long timeout; |
1248 | unsigned long flags; | 1245 | unsigned long flags; |
1246 | int packet; | ||
1249 | 1247 | ||
1250 | do_it_again: | 1248 | do_it_again: |
1251 | 1249 | ||
@@ -1289,16 +1287,19 @@ do_it_again: | |||
1289 | if (mutex_lock_interruptible(&tty->atomic_read_lock)) | 1287 | if (mutex_lock_interruptible(&tty->atomic_read_lock)) |
1290 | return -ERESTARTSYS; | 1288 | return -ERESTARTSYS; |
1291 | } | 1289 | } |
1290 | packet = tty->packet; | ||
1292 | 1291 | ||
1293 | add_wait_queue(&tty->read_wait, &wait); | 1292 | add_wait_queue(&tty->read_wait, &wait); |
1294 | while (nr) { | 1293 | while (nr) { |
1295 | /* First test for status change. */ | 1294 | /* First test for status change. */ |
1296 | if (tty->packet && tty->link->ctrl_status) { | 1295 | if (packet && tty->link->ctrl_status) { |
1297 | unsigned char cs; | 1296 | unsigned char cs; |
1298 | if (b != buf) | 1297 | if (b != buf) |
1299 | break; | 1298 | break; |
1299 | spin_lock_irqsave(&tty->link->ctrl_lock, flags); | ||
1300 | cs = tty->link->ctrl_status; | 1300 | cs = tty->link->ctrl_status; |
1301 | tty->link->ctrl_status = 0; | 1301 | tty->link->ctrl_status = 0; |
1302 | spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); | ||
1302 | if (tty_put_user(tty, cs, b++)) { | 1303 | if (tty_put_user(tty, cs, b++)) { |
1303 | retval = -EFAULT; | 1304 | retval = -EFAULT; |
1304 | b--; | 1305 | b--; |
@@ -1333,6 +1334,7 @@ do_it_again: | |||
1333 | retval = -ERESTARTSYS; | 1334 | retval = -ERESTARTSYS; |
1334 | break; | 1335 | break; |
1335 | } | 1336 | } |
1337 | /* FIXME: does n_tty_set_room need locking ? */ | ||
1336 | n_tty_set_room(tty); | 1338 | n_tty_set_room(tty); |
1337 | timeout = schedule_timeout(timeout); | 1339 | timeout = schedule_timeout(timeout); |
1338 | continue; | 1340 | continue; |
@@ -1340,7 +1342,7 @@ do_it_again: | |||
1340 | __set_current_state(TASK_RUNNING); | 1342 | __set_current_state(TASK_RUNNING); |
1341 | 1343 | ||
1342 | /* Deal with packet mode. */ | 1344 | /* Deal with packet mode. */ |
1343 | if (tty->packet && b == buf) { | 1345 | if (packet && b == buf) { |
1344 | if (tty_put_user(tty, TIOCPKT_DATA, b++)) { | 1346 | if (tty_put_user(tty, TIOCPKT_DATA, b++)) { |
1345 | retval = -EFAULT; | 1347 | retval = -EFAULT; |
1346 | b--; | 1348 | b--; |
@@ -1388,6 +1390,8 @@ do_it_again: | |||
1388 | break; | 1390 | break; |
1389 | } else { | 1391 | } else { |
1390 | int uncopied; | 1392 | int uncopied; |
1393 | /* The copy function takes the read lock and handles | ||
1394 | locking internally for this case */ | ||
1391 | uncopied = copy_from_read_buf(tty, &b, &nr); | 1395 | uncopied = copy_from_read_buf(tty, &b, &nr); |
1392 | uncopied += copy_from_read_buf(tty, &b, &nr); | 1396 | uncopied += copy_from_read_buf(tty, &b, &nr); |
1393 | if (uncopied) { | 1397 | if (uncopied) { |
@@ -1429,7 +1433,6 @@ do_it_again: | |||
1429 | goto do_it_again; | 1433 | goto do_it_again; |
1430 | 1434 | ||
1431 | n_tty_set_room(tty); | 1435 | n_tty_set_room(tty); |
1432 | |||
1433 | return retval; | 1436 | return retval; |
1434 | } | 1437 | } |
1435 | 1438 | ||
@@ -1492,11 +1495,11 @@ static ssize_t write_chan(struct tty_struct *tty, struct file *file, | |||
1492 | break; | 1495 | break; |
1493 | b++; nr--; | 1496 | b++; nr--; |
1494 | } | 1497 | } |
1495 | if (tty->driver->flush_chars) | 1498 | if (tty->ops->flush_chars) |
1496 | tty->driver->flush_chars(tty); | 1499 | tty->ops->flush_chars(tty); |
1497 | } else { | 1500 | } else { |
1498 | while (nr > 0) { | 1501 | while (nr > 0) { |
1499 | c = tty->driver->write(tty, b, nr); | 1502 | c = tty->ops->write(tty, b, nr); |
1500 | if (c < 0) { | 1503 | if (c < 0) { |
1501 | retval = c; | 1504 | retval = c; |
1502 | goto break_out; | 1505 | goto break_out; |
@@ -1533,11 +1536,6 @@ break_out: | |||
1533 | * | 1536 | * |
1534 | * This code must be sure never to sleep through a hangup. | 1537 | * This code must be sure never to sleep through a hangup. |
1535 | * Called without the kernel lock held - fine | 1538 | * Called without the kernel lock held - fine |
1536 | * | ||
1537 | * FIXME: if someone changes the VMIN or discipline settings for the | ||
1538 | * terminal while another process is in poll() the poll does not | ||
1539 | * recompute the new limits. Possibly set_termios should issue | ||
1540 | * a read wakeup to fix this bug. | ||
1541 | */ | 1539 | */ |
1542 | 1540 | ||
1543 | static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | 1541 | static unsigned int normal_poll(struct tty_struct *tty, struct file *file, |
@@ -1561,9 +1559,9 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | |||
1561 | else | 1559 | else |
1562 | tty->minimum_to_wake = 1; | 1560 | tty->minimum_to_wake = 1; |
1563 | } | 1561 | } |
1564 | if (!tty_is_writelocked(tty) && | 1562 | if (tty->ops->write && !tty_is_writelocked(tty) && |
1565 | tty->driver->chars_in_buffer(tty) < WAKEUP_CHARS && | 1563 | tty_chars_in_buffer(tty) < WAKEUP_CHARS && |
1566 | tty->driver->write_room(tty) > 0) | 1564 | tty_write_room(tty) > 0) |
1567 | mask |= POLLOUT | POLLWRNORM; | 1565 | mask |= POLLOUT | POLLWRNORM; |
1568 | return mask; | 1566 | return mask; |
1569 | } | 1567 | } |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 6a6843a0a674..66a0f931c66c 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -73,7 +73,7 @@ do { \ | |||
73 | char tmp[P_BUF_SIZE]; \ | 73 | char tmp[P_BUF_SIZE]; \ |
74 | snprintf(tmp, sizeof(tmp), ##args); \ | 74 | snprintf(tmp, sizeof(tmp), ##args); \ |
75 | printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \ | 75 | printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \ |
76 | __FUNCTION__, tmp); \ | 76 | __func__, tmp); \ |
77 | } while (0) | 77 | } while (0) |
78 | 78 | ||
79 | #define DBG1(args...) D_(0x01, ##args) | 79 | #define DBG1(args...) D_(0x01, ##args) |
@@ -1407,7 +1407,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1407 | /* Find out what card type it is */ | 1407 | /* Find out what card type it is */ |
1408 | nozomi_get_card_type(dc); | 1408 | nozomi_get_card_type(dc); |
1409 | 1409 | ||
1410 | dc->base_addr = ioremap(start, dc->card_type); | 1410 | dc->base_addr = ioremap_nocache(start, dc->card_type); |
1411 | if (!dc->base_addr) { | 1411 | if (!dc->base_addr) { |
1412 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); | 1412 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); |
1413 | ret = -ENODEV; | 1413 | ret = -ENODEV; |
@@ -1724,6 +1724,8 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file) | |||
1724 | const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; | 1724 | const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; |
1725 | const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; | 1725 | const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; |
1726 | 1726 | ||
1727 | /* Note: these could change under us but it is not clear this | ||
1728 | matters if so */ | ||
1727 | return (ctrl_ul->RTS ? TIOCM_RTS : 0) | | 1729 | return (ctrl_ul->RTS ? TIOCM_RTS : 0) | |
1728 | (ctrl_ul->DTR ? TIOCM_DTR : 0) | | 1730 | (ctrl_ul->DTR ? TIOCM_DTR : 0) | |
1729 | (ctrl_dl->DCD ? TIOCM_CAR : 0) | | 1731 | (ctrl_dl->DCD ? TIOCM_CAR : 0) | |
@@ -1849,16 +1851,6 @@ static void ntty_throttle(struct tty_struct *tty) | |||
1849 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1851 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1850 | } | 1852 | } |
1851 | 1853 | ||
1852 | /* just to discard single character writes */ | ||
1853 | static void ntty_put_char(struct tty_struct *tty, unsigned char c) | ||
1854 | { | ||
1855 | /* | ||
1856 | * card does not react correct when we write single chars | ||
1857 | * to the card, so we discard them | ||
1858 | */ | ||
1859 | DBG2("PUT CHAR Function: %c", c); | ||
1860 | } | ||
1861 | |||
1862 | /* Returns number of chars in buffer, called by tty layer */ | 1854 | /* Returns number of chars in buffer, called by tty layer */ |
1863 | static s32 ntty_chars_in_buffer(struct tty_struct *tty) | 1855 | static s32 ntty_chars_in_buffer(struct tty_struct *tty) |
1864 | { | 1856 | { |
@@ -1892,7 +1884,6 @@ static const struct tty_operations tty_ops = { | |||
1892 | .unthrottle = ntty_unthrottle, | 1884 | .unthrottle = ntty_unthrottle, |
1893 | .throttle = ntty_throttle, | 1885 | .throttle = ntty_throttle, |
1894 | .chars_in_buffer = ntty_chars_in_buffer, | 1886 | .chars_in_buffer = ntty_chars_in_buffer, |
1895 | .put_char = ntty_put_char, | ||
1896 | .tiocmget = ntty_tiocmget, | 1887 | .tiocmget = ntty_tiocmget, |
1897 | .tiocmset = ntty_tiocmset, | 1888 | .tiocmset = ntty_tiocmset, |
1898 | }; | 1889 | }; |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 454d7324ba40..4a933d413423 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -53,7 +53,7 @@ module_param(pc_debug, int, 0600); | |||
53 | #define DEBUGP(n, rdr, x, args...) do { \ | 53 | #define DEBUGP(n, rdr, x, args...) do { \ |
54 | if (pc_debug >= (n)) \ | 54 | if (pc_debug >= (n)) \ |
55 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | 55 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ |
56 | __FUNCTION__ , ## args); \ | 56 | __func__ , ## args); \ |
57 | } while (0) | 57 | } while (0) |
58 | #else | 58 | #else |
59 | #define DEBUGP(n, rdr, x, args...) | 59 | #define DEBUGP(n, rdr, x, args...) |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 5f291bf739a6..035084c07329 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -47,7 +47,7 @@ module_param(pc_debug, int, 0600); | |||
47 | #define DEBUGP(n, rdr, x, args...) do { \ | 47 | #define DEBUGP(n, rdr, x, args...) do { \ |
48 | if (pc_debug >= (n)) \ | 48 | if (pc_debug >= (n)) \ |
49 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | 49 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ |
50 | __FUNCTION__ , ##args); \ | 50 | __func__ , ##args); \ |
51 | } while (0) | 51 | } while (0) |
52 | #else | 52 | #else |
53 | #define DEBUGP(n, rdr, x, args...) | 53 | #define DEBUGP(n, rdr, x, args...) |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index 1f978ff87fa8..fa9d3c945f31 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c | |||
@@ -354,32 +354,6 @@ struct ipw_rx_packet { | |||
354 | unsigned int channel_idx; | 354 | unsigned int channel_idx; |
355 | }; | 355 | }; |
356 | 356 | ||
357 | #ifdef IPWIRELESS_STATE_DEBUG | ||
358 | int ipwireless_dump_hardware_state(char *p, size_t limit, | ||
359 | struct ipw_hardware *hw) | ||
360 | { | ||
361 | return snprintf(p, limit, | ||
362 | "debug: initializing=%d\n" | ||
363 | "debug: tx_ready=%d\n" | ||
364 | "debug: tx_queued=%d\n" | ||
365 | "debug: rx_ready=%d\n" | ||
366 | "debug: rx_bytes_queued=%d\n" | ||
367 | "debug: blocking_rx=%d\n" | ||
368 | "debug: removed=%d\n" | ||
369 | "debug: hardware.shutting_down=%d\n" | ||
370 | "debug: to_setup=%d\n", | ||
371 | hw->initializing, | ||
372 | hw->tx_ready, | ||
373 | hw->tx_queued, | ||
374 | hw->rx_ready, | ||
375 | hw->rx_bytes_queued, | ||
376 | hw->blocking_rx, | ||
377 | hw->removed, | ||
378 | hw->shutting_down, | ||
379 | hw->to_setup); | ||
380 | } | ||
381 | #endif | ||
382 | |||
383 | static char *data_type(const unsigned char *buf, unsigned length) | 357 | static char *data_type(const unsigned char *buf, unsigned length) |
384 | { | 358 | { |
385 | struct nl_packet_header *hdr = (struct nl_packet_header *) buf; | 359 | struct nl_packet_header *hdr = (struct nl_packet_header *) buf; |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.h b/drivers/char/pcmcia/ipwireless/hardware.h index c83190ffb0e7..19ce5eb266b1 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.h +++ b/drivers/char/pcmcia/ipwireless/hardware.h | |||
@@ -58,7 +58,5 @@ void ipwireless_init_hardware_v1(struct ipw_hardware *hw, | |||
58 | void *reboot_cb_data); | 58 | void *reboot_cb_data); |
59 | void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw); | 59 | void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw); |
60 | void ipwireless_sleep(unsigned int tenths); | 60 | void ipwireless_sleep(unsigned int tenths); |
61 | int ipwireless_dump_hardware_state(char *p, size_t limit, | ||
62 | struct ipw_hardware *hw); | ||
63 | 61 | ||
64 | #endif | 62 | #endif |
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index d793e68b3e0d..fe914d34f7f6 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c | |||
@@ -63,21 +63,6 @@ struct ipw_network { | |||
63 | struct work_struct work_go_offline; | 63 | struct work_struct work_go_offline; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | |||
67 | #ifdef IPWIRELESS_STATE_DEBUG | ||
68 | int ipwireless_dump_network_state(char *p, size_t limit, | ||
69 | struct ipw_network *network) | ||
70 | { | ||
71 | return snprintf(p, limit, | ||
72 | "debug: ppp_blocked=%d\n" | ||
73 | "debug: outgoing_packets_queued=%d\n" | ||
74 | "debug: network.shutting_down=%d\n", | ||
75 | network->ppp_blocked, | ||
76 | network->outgoing_packets_queued, | ||
77 | network->shutting_down); | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | static void notify_packet_sent(void *callback_data, unsigned int packet_length) | 66 | static void notify_packet_sent(void *callback_data, unsigned int packet_length) |
82 | { | 67 | { |
83 | struct ipw_network *network = callback_data; | 68 | struct ipw_network *network = callback_data; |
diff --git a/drivers/char/pcmcia/ipwireless/network.h b/drivers/char/pcmcia/ipwireless/network.h index b0e1e952fd14..ccacd26fc7ef 100644 --- a/drivers/char/pcmcia/ipwireless/network.h +++ b/drivers/char/pcmcia/ipwireless/network.h | |||
@@ -49,7 +49,4 @@ void ipwireless_ppp_close(struct ipw_network *net); | |||
49 | int ipwireless_ppp_channel_index(struct ipw_network *net); | 49 | int ipwireless_ppp_channel_index(struct ipw_network *net); |
50 | int ipwireless_ppp_unit_number(struct ipw_network *net); | 50 | int ipwireless_ppp_unit_number(struct ipw_network *net); |
51 | 51 | ||
52 | int ipwireless_dump_network_state(char *p, size_t limit, | ||
53 | struct ipw_network *net); | ||
54 | |||
55 | #endif | 52 | #endif |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 583356426dfb..1dd0e992c83d 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -503,20 +503,9 @@ static void* mgslpc_get_text_ptr(void) | |||
503 | * The wrappers maintain line discipline references | 503 | * The wrappers maintain line discipline references |
504 | * while calling into the line discipline. | 504 | * while calling into the line discipline. |
505 | * | 505 | * |
506 | * ldisc_flush_buffer - flush line discipline receive buffers | ||
507 | * ldisc_receive_buf - pass receive data to line discipline | 506 | * ldisc_receive_buf - pass receive data to line discipline |
508 | */ | 507 | */ |
509 | 508 | ||
510 | static void ldisc_flush_buffer(struct tty_struct *tty) | ||
511 | { | ||
512 | struct tty_ldisc *ld = tty_ldisc_ref(tty); | ||
513 | if (ld) { | ||
514 | if (ld->flush_buffer) | ||
515 | ld->flush_buffer(tty); | ||
516 | tty_ldisc_deref(ld); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | static void ldisc_receive_buf(struct tty_struct *tty, | 509 | static void ldisc_receive_buf(struct tty_struct *tty, |
521 | const __u8 *data, char *flags, int count) | 510 | const __u8 *data, char *flags, int count) |
522 | { | 511 | { |
@@ -1556,7 +1545,7 @@ static void mgslpc_change_params(MGSLPC_INFO *info) | |||
1556 | 1545 | ||
1557 | /* Add a character to the transmit buffer | 1546 | /* Add a character to the transmit buffer |
1558 | */ | 1547 | */ |
1559 | static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch) | 1548 | static int mgslpc_put_char(struct tty_struct *tty, unsigned char ch) |
1560 | { | 1549 | { |
1561 | MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; | 1550 | MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; |
1562 | unsigned long flags; | 1551 | unsigned long flags; |
@@ -1567,10 +1556,10 @@ static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch) | |||
1567 | } | 1556 | } |
1568 | 1557 | ||
1569 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char")) | 1558 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char")) |
1570 | return; | 1559 | return 0; |
1571 | 1560 | ||
1572 | if (!info->tx_buf) | 1561 | if (!info->tx_buf) |
1573 | return; | 1562 | return 0; |
1574 | 1563 | ||
1575 | spin_lock_irqsave(&info->lock,flags); | 1564 | spin_lock_irqsave(&info->lock,flags); |
1576 | 1565 | ||
@@ -1583,6 +1572,7 @@ static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch) | |||
1583 | } | 1572 | } |
1584 | 1573 | ||
1585 | spin_unlock_irqrestore(&info->lock,flags); | 1574 | spin_unlock_irqrestore(&info->lock,flags); |
1575 | return 1; | ||
1586 | } | 1576 | } |
1587 | 1577 | ||
1588 | /* Enable transmitter so remaining characters in the | 1578 | /* Enable transmitter so remaining characters in the |
@@ -2467,10 +2457,9 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp) | |||
2467 | if (info->flags & ASYNC_INITIALIZED) | 2457 | if (info->flags & ASYNC_INITIALIZED) |
2468 | mgslpc_wait_until_sent(tty, info->timeout); | 2458 | mgslpc_wait_until_sent(tty, info->timeout); |
2469 | 2459 | ||
2470 | if (tty->driver->flush_buffer) | 2460 | mgslpc_flush_buffer(tty); |
2471 | tty->driver->flush_buffer(tty); | ||
2472 | 2461 | ||
2473 | ldisc_flush_buffer(tty); | 2462 | tty_ldisc_flush(tty); |
2474 | 2463 | ||
2475 | shutdown(info); | 2464 | shutdown(info); |
2476 | 2465 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 706ff34728f1..0a05c038ae6f 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -181,6 +181,7 @@ static int pty_set_lock(struct tty_struct *tty, int __user * arg) | |||
181 | static void pty_flush_buffer(struct tty_struct *tty) | 181 | static void pty_flush_buffer(struct tty_struct *tty) |
182 | { | 182 | { |
183 | struct tty_struct *to = tty->link; | 183 | struct tty_struct *to = tty->link; |
184 | unsigned long flags; | ||
184 | 185 | ||
185 | if (!to) | 186 | if (!to) |
186 | return; | 187 | return; |
@@ -189,8 +190,10 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
189 | to->ldisc.flush_buffer(to); | 190 | to->ldisc.flush_buffer(to); |
190 | 191 | ||
191 | if (to->packet) { | 192 | if (to->packet) { |
193 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
192 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 194 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
193 | wake_up_interruptible(&to->read_wait); | 195 | wake_up_interruptible(&to->read_wait); |
196 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
194 | } | 197 | } |
195 | } | 198 | } |
196 | 199 | ||
@@ -251,6 +254,18 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, | |||
251 | static int legacy_count = CONFIG_LEGACY_PTY_COUNT; | 254 | static int legacy_count = CONFIG_LEGACY_PTY_COUNT; |
252 | module_param(legacy_count, int, 0); | 255 | module_param(legacy_count, int, 0); |
253 | 256 | ||
257 | static const struct tty_operations pty_ops_bsd = { | ||
258 | .open = pty_open, | ||
259 | .close = pty_close, | ||
260 | .write = pty_write, | ||
261 | .write_room = pty_write_room, | ||
262 | .flush_buffer = pty_flush_buffer, | ||
263 | .chars_in_buffer = pty_chars_in_buffer, | ||
264 | .unthrottle = pty_unthrottle, | ||
265 | .set_termios = pty_set_termios, | ||
266 | .ioctl = pty_bsd_ioctl, | ||
267 | }; | ||
268 | |||
254 | static void __init legacy_pty_init(void) | 269 | static void __init legacy_pty_init(void) |
255 | { | 270 | { |
256 | if (legacy_count <= 0) | 271 | if (legacy_count <= 0) |
@@ -281,7 +296,6 @@ static void __init legacy_pty_init(void) | |||
281 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; | 296 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; |
282 | pty_driver->other = pty_slave_driver; | 297 | pty_driver->other = pty_slave_driver; |
283 | tty_set_operations(pty_driver, &pty_ops); | 298 | tty_set_operations(pty_driver, &pty_ops); |
284 | pty_driver->ioctl = pty_bsd_ioctl; | ||
285 | 299 | ||
286 | pty_slave_driver->owner = THIS_MODULE; | 300 | pty_slave_driver->owner = THIS_MODULE; |
287 | pty_slave_driver->driver_name = "pty_slave"; | 301 | pty_slave_driver->driver_name = "pty_slave"; |
@@ -374,6 +388,19 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
374 | return -ENOIOCTLCMD; | 388 | return -ENOIOCTLCMD; |
375 | } | 389 | } |
376 | 390 | ||
391 | static const struct tty_operations pty_unix98_ops = { | ||
392 | .open = pty_open, | ||
393 | .close = pty_close, | ||
394 | .write = pty_write, | ||
395 | .write_room = pty_write_room, | ||
396 | .flush_buffer = pty_flush_buffer, | ||
397 | .chars_in_buffer = pty_chars_in_buffer, | ||
398 | .unthrottle = pty_unthrottle, | ||
399 | .set_termios = pty_set_termios, | ||
400 | .ioctl = pty_unix98_ioctl | ||
401 | }; | ||
402 | |||
403 | |||
377 | static void __init unix98_pty_init(void) | 404 | static void __init unix98_pty_init(void) |
378 | { | 405 | { |
379 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 406 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); |
@@ -400,8 +427,7 @@ static void __init unix98_pty_init(void) | |||
400 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 427 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
401 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 428 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
402 | ptm_driver->other = pts_driver; | 429 | ptm_driver->other = pts_driver; |
403 | tty_set_operations(ptm_driver, &pty_ops); | 430 | tty_set_operations(ptm_driver, &pty_unix98_ops); |
404 | ptm_driver->ioctl = pty_unix98_ioctl; | ||
405 | 431 | ||
406 | pts_driver->owner = THIS_MODULE; | 432 | pts_driver->owner = THIS_MODULE; |
407 | pts_driver->driver_name = "pty_slave"; | 433 | pts_driver->driver_name = "pty_slave"; |
diff --git a/drivers/char/random.c b/drivers/char/random.c index f43c89f7c449..0cf98bd4f2d2 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -272,7 +272,7 @@ static int random_write_wakeup_thresh = 128; | |||
272 | 272 | ||
273 | static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28; | 273 | static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28; |
274 | 274 | ||
275 | static DEFINE_PER_CPU(int, trickle_count) = 0; | 275 | static DEFINE_PER_CPU(int, trickle_count); |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * A pool of size .poolwords is stirred with a primitive polynomial | 278 | * A pool of size .poolwords is stirred with a primitive polynomial |
@@ -370,17 +370,19 @@ static struct poolinfo { | |||
370 | */ | 370 | */ |
371 | static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | 371 | static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); |
372 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 372 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
373 | static struct fasync_struct *fasync; | ||
373 | 374 | ||
374 | #if 0 | 375 | #if 0 |
375 | static int debug = 0; | 376 | static int debug; |
376 | module_param(debug, bool, 0644); | 377 | module_param(debug, bool, 0644); |
377 | #define DEBUG_ENT(fmt, arg...) do { if (debug) \ | 378 | #define DEBUG_ENT(fmt, arg...) do { \ |
378 | printk(KERN_DEBUG "random %04d %04d %04d: " \ | 379 | if (debug) \ |
379 | fmt,\ | 380 | printk(KERN_DEBUG "random %04d %04d %04d: " \ |
380 | input_pool.entropy_count,\ | 381 | fmt,\ |
381 | blocking_pool.entropy_count,\ | 382 | input_pool.entropy_count,\ |
382 | nonblocking_pool.entropy_count,\ | 383 | blocking_pool.entropy_count,\ |
383 | ## arg); } while (0) | 384 | nonblocking_pool.entropy_count,\ |
385 | ## arg); } while (0) | ||
384 | #else | 386 | #else |
385 | #define DEBUG_ENT(fmt, arg...) do {} while (0) | 387 | #define DEBUG_ENT(fmt, arg...) do {} while (0) |
386 | #endif | 388 | #endif |
@@ -394,7 +396,7 @@ module_param(debug, bool, 0644); | |||
394 | 396 | ||
395 | struct entropy_store; | 397 | struct entropy_store; |
396 | struct entropy_store { | 398 | struct entropy_store { |
397 | /* mostly-read data: */ | 399 | /* read-only data: */ |
398 | struct poolinfo *poolinfo; | 400 | struct poolinfo *poolinfo; |
399 | __u32 *pool; | 401 | __u32 *pool; |
400 | const char *name; | 402 | const char *name; |
@@ -402,7 +404,7 @@ struct entropy_store { | |||
402 | struct entropy_store *pull; | 404 | struct entropy_store *pull; |
403 | 405 | ||
404 | /* read-write data: */ | 406 | /* read-write data: */ |
405 | spinlock_t lock ____cacheline_aligned_in_smp; | 407 | spinlock_t lock; |
406 | unsigned add_ptr; | 408 | unsigned add_ptr; |
407 | int entropy_count; | 409 | int entropy_count; |
408 | int input_rotate; | 410 | int input_rotate; |
@@ -438,25 +440,26 @@ static struct entropy_store nonblocking_pool = { | |||
438 | }; | 440 | }; |
439 | 441 | ||
440 | /* | 442 | /* |
441 | * This function adds a byte into the entropy "pool". It does not | 443 | * This function adds bytes into the entropy "pool". It does not |
442 | * update the entropy estimate. The caller should call | 444 | * update the entropy estimate. The caller should call |
443 | * credit_entropy_store if this is appropriate. | 445 | * credit_entropy_bits if this is appropriate. |
444 | * | 446 | * |
445 | * The pool is stirred with a primitive polynomial of the appropriate | 447 | * The pool is stirred with a primitive polynomial of the appropriate |
446 | * degree, and then twisted. We twist by three bits at a time because | 448 | * degree, and then twisted. We twist by three bits at a time because |
447 | * it's cheap to do so and helps slightly in the expected case where | 449 | * it's cheap to do so and helps slightly in the expected case where |
448 | * the entropy is concentrated in the low-order bits. | 450 | * the entropy is concentrated in the low-order bits. |
449 | */ | 451 | */ |
450 | static void __add_entropy_words(struct entropy_store *r, const __u32 *in, | 452 | static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, |
451 | int nwords, __u32 out[16]) | 453 | int nbytes, __u8 out[64]) |
452 | { | 454 | { |
453 | static __u32 const twist_table[8] = { | 455 | static __u32 const twist_table[8] = { |
454 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, | 456 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, |
455 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; | 457 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; |
456 | unsigned long i, add_ptr, tap1, tap2, tap3, tap4, tap5; | 458 | unsigned long i, j, tap1, tap2, tap3, tap4, tap5; |
457 | int new_rotate, input_rotate; | 459 | int input_rotate; |
458 | int wordmask = r->poolinfo->poolwords - 1; | 460 | int wordmask = r->poolinfo->poolwords - 1; |
459 | __u32 w, next_w; | 461 | const char *bytes = in; |
462 | __u32 w; | ||
460 | unsigned long flags; | 463 | unsigned long flags; |
461 | 464 | ||
462 | /* Taps are constant, so we can load them without holding r->lock. */ | 465 | /* Taps are constant, so we can load them without holding r->lock. */ |
@@ -465,78 +468,76 @@ static void __add_entropy_words(struct entropy_store *r, const __u32 *in, | |||
465 | tap3 = r->poolinfo->tap3; | 468 | tap3 = r->poolinfo->tap3; |
466 | tap4 = r->poolinfo->tap4; | 469 | tap4 = r->poolinfo->tap4; |
467 | tap5 = r->poolinfo->tap5; | 470 | tap5 = r->poolinfo->tap5; |
468 | next_w = *in++; | ||
469 | 471 | ||
470 | spin_lock_irqsave(&r->lock, flags); | 472 | spin_lock_irqsave(&r->lock, flags); |
471 | prefetch_range(r->pool, wordmask); | ||
472 | input_rotate = r->input_rotate; | 473 | input_rotate = r->input_rotate; |
473 | add_ptr = r->add_ptr; | 474 | i = r->add_ptr; |
474 | 475 | ||
475 | while (nwords--) { | 476 | /* mix one byte at a time to simplify size handling and churn faster */ |
476 | w = rol32(next_w, input_rotate); | 477 | while (nbytes--) { |
477 | if (nwords > 0) | 478 | w = rol32(*bytes++, input_rotate & 31); |
478 | next_w = *in++; | 479 | i = (i - 1) & wordmask; |
479 | i = add_ptr = (add_ptr - 1) & wordmask; | ||
480 | /* | ||
481 | * Normally, we add 7 bits of rotation to the pool. | ||
482 | * At the beginning of the pool, add an extra 7 bits | ||
483 | * rotation, so that successive passes spread the | ||
484 | * input bits across the pool evenly. | ||
485 | */ | ||
486 | new_rotate = input_rotate + 14; | ||
487 | if (i) | ||
488 | new_rotate = input_rotate + 7; | ||
489 | input_rotate = new_rotate & 31; | ||
490 | 480 | ||
491 | /* XOR in the various taps */ | 481 | /* XOR in the various taps */ |
482 | w ^= r->pool[i]; | ||
492 | w ^= r->pool[(i + tap1) & wordmask]; | 483 | w ^= r->pool[(i + tap1) & wordmask]; |
493 | w ^= r->pool[(i + tap2) & wordmask]; | 484 | w ^= r->pool[(i + tap2) & wordmask]; |
494 | w ^= r->pool[(i + tap3) & wordmask]; | 485 | w ^= r->pool[(i + tap3) & wordmask]; |
495 | w ^= r->pool[(i + tap4) & wordmask]; | 486 | w ^= r->pool[(i + tap4) & wordmask]; |
496 | w ^= r->pool[(i + tap5) & wordmask]; | 487 | w ^= r->pool[(i + tap5) & wordmask]; |
497 | w ^= r->pool[i]; | 488 | |
489 | /* Mix the result back in with a twist */ | ||
498 | r->pool[i] = (w >> 3) ^ twist_table[w & 7]; | 490 | r->pool[i] = (w >> 3) ^ twist_table[w & 7]; |
491 | |||
492 | /* | ||
493 | * Normally, we add 7 bits of rotation to the pool. | ||
494 | * At the beginning of the pool, add an extra 7 bits | ||
495 | * rotation, so that successive passes spread the | ||
496 | * input bits across the pool evenly. | ||
497 | */ | ||
498 | input_rotate += i ? 7 : 14; | ||
499 | } | 499 | } |
500 | 500 | ||
501 | r->input_rotate = input_rotate; | 501 | r->input_rotate = input_rotate; |
502 | r->add_ptr = add_ptr; | 502 | r->add_ptr = i; |
503 | 503 | ||
504 | if (out) { | 504 | if (out) |
505 | for (i = 0; i < 16; i++) { | 505 | for (j = 0; j < 16; j++) |
506 | out[i] = r->pool[add_ptr]; | 506 | ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; |
507 | add_ptr = (add_ptr - 1) & wordmask; | ||
508 | } | ||
509 | } | ||
510 | 507 | ||
511 | spin_unlock_irqrestore(&r->lock, flags); | 508 | spin_unlock_irqrestore(&r->lock, flags); |
512 | } | 509 | } |
513 | 510 | ||
514 | static inline void add_entropy_words(struct entropy_store *r, const __u32 *in, | 511 | static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) |
515 | int nwords) | ||
516 | { | 512 | { |
517 | __add_entropy_words(r, in, nwords, NULL); | 513 | mix_pool_bytes_extract(r, in, bytes, NULL); |
518 | } | 514 | } |
519 | 515 | ||
520 | /* | 516 | /* |
521 | * Credit (or debit) the entropy store with n bits of entropy | 517 | * Credit (or debit) the entropy store with n bits of entropy |
522 | */ | 518 | */ |
523 | static void credit_entropy_store(struct entropy_store *r, int nbits) | 519 | static void credit_entropy_bits(struct entropy_store *r, int nbits) |
524 | { | 520 | { |
525 | unsigned long flags; | 521 | unsigned long flags; |
526 | 522 | ||
523 | if (!nbits) | ||
524 | return; | ||
525 | |||
527 | spin_lock_irqsave(&r->lock, flags); | 526 | spin_lock_irqsave(&r->lock, flags); |
528 | 527 | ||
529 | if (r->entropy_count + nbits < 0) { | 528 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); |
530 | DEBUG_ENT("negative entropy/overflow (%d+%d)\n", | 529 | r->entropy_count += nbits; |
531 | r->entropy_count, nbits); | 530 | if (r->entropy_count < 0) { |
531 | DEBUG_ENT("negative entropy/overflow\n"); | ||
532 | r->entropy_count = 0; | 532 | r->entropy_count = 0; |
533 | } else if (r->entropy_count + nbits > r->poolinfo->POOLBITS) { | 533 | } else if (r->entropy_count > r->poolinfo->POOLBITS) |
534 | r->entropy_count = r->poolinfo->POOLBITS; | 534 | r->entropy_count = r->poolinfo->POOLBITS; |
535 | } else { | 535 | |
536 | r->entropy_count += nbits; | 536 | /* should we wake readers? */ |
537 | if (nbits) | 537 | if (r == &input_pool && |
538 | DEBUG_ENT("added %d entropy credits to %s\n", | 538 | r->entropy_count >= random_read_wakeup_thresh) { |
539 | nbits, r->name); | 539 | wake_up_interruptible(&random_read_wait); |
540 | kill_fasync(&fasync, SIGIO, POLL_IN); | ||
540 | } | 541 | } |
541 | 542 | ||
542 | spin_unlock_irqrestore(&r->lock, flags); | 543 | spin_unlock_irqrestore(&r->lock, flags); |
@@ -551,7 +552,7 @@ static void credit_entropy_store(struct entropy_store *r, int nbits) | |||
551 | /* There is one of these per entropy source */ | 552 | /* There is one of these per entropy source */ |
552 | struct timer_rand_state { | 553 | struct timer_rand_state { |
553 | cycles_t last_time; | 554 | cycles_t last_time; |
554 | long last_delta,last_delta2; | 555 | long last_delta, last_delta2; |
555 | unsigned dont_count_entropy:1; | 556 | unsigned dont_count_entropy:1; |
556 | }; | 557 | }; |
557 | 558 | ||
@@ -586,7 +587,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
586 | sample.jiffies = jiffies; | 587 | sample.jiffies = jiffies; |
587 | sample.cycles = get_cycles(); | 588 | sample.cycles = get_cycles(); |
588 | sample.num = num; | 589 | sample.num = num; |
589 | add_entropy_words(&input_pool, (u32 *)&sample, sizeof(sample)/4); | 590 | mix_pool_bytes(&input_pool, &sample, sizeof(sample)); |
590 | 591 | ||
591 | /* | 592 | /* |
592 | * Calculate number of bits of randomness we probably added. | 593 | * Calculate number of bits of randomness we probably added. |
@@ -620,13 +621,9 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
620 | * Round down by 1 bit on general principles, | 621 | * Round down by 1 bit on general principles, |
621 | * and limit entropy entimate to 12 bits. | 622 | * and limit entropy entimate to 12 bits. |
622 | */ | 623 | */ |
623 | credit_entropy_store(&input_pool, | 624 | credit_entropy_bits(&input_pool, |
624 | min_t(int, fls(delta>>1), 11)); | 625 | min_t(int, fls(delta>>1), 11)); |
625 | } | 626 | } |
626 | |||
627 | if(input_pool.entropy_count >= random_read_wakeup_thresh) | ||
628 | wake_up_interruptible(&random_read_wait); | ||
629 | |||
630 | out: | 627 | out: |
631 | preempt_enable(); | 628 | preempt_enable(); |
632 | } | 629 | } |
@@ -677,7 +674,7 @@ void add_disk_randomness(struct gendisk *disk) | |||
677 | * | 674 | * |
678 | *********************************************************************/ | 675 | *********************************************************************/ |
679 | 676 | ||
680 | static ssize_t extract_entropy(struct entropy_store *r, void * buf, | 677 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, |
681 | size_t nbytes, int min, int rsvd); | 678 | size_t nbytes, int min, int rsvd); |
682 | 679 | ||
683 | /* | 680 | /* |
@@ -704,10 +701,10 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
704 | "(%d of %d requested)\n", | 701 | "(%d of %d requested)\n", |
705 | r->name, bytes * 8, nbytes * 8, r->entropy_count); | 702 | r->name, bytes * 8, nbytes * 8, r->entropy_count); |
706 | 703 | ||
707 | bytes=extract_entropy(r->pull, tmp, bytes, | 704 | bytes = extract_entropy(r->pull, tmp, bytes, |
708 | random_read_wakeup_thresh / 8, rsvd); | 705 | random_read_wakeup_thresh / 8, rsvd); |
709 | add_entropy_words(r, tmp, (bytes + 3) / 4); | 706 | mix_pool_bytes(r, tmp, bytes); |
710 | credit_entropy_store(r, bytes*8); | 707 | credit_entropy_bits(r, bytes*8); |
711 | } | 708 | } |
712 | } | 709 | } |
713 | 710 | ||
@@ -744,13 +741,15 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
744 | if (r->limit && nbytes + reserved >= r->entropy_count / 8) | 741 | if (r->limit && nbytes + reserved >= r->entropy_count / 8) |
745 | nbytes = r->entropy_count/8 - reserved; | 742 | nbytes = r->entropy_count/8 - reserved; |
746 | 743 | ||
747 | if(r->entropy_count / 8 >= nbytes + reserved) | 744 | if (r->entropy_count / 8 >= nbytes + reserved) |
748 | r->entropy_count -= nbytes*8; | 745 | r->entropy_count -= nbytes*8; |
749 | else | 746 | else |
750 | r->entropy_count = reserved; | 747 | r->entropy_count = reserved; |
751 | 748 | ||
752 | if (r->entropy_count < random_write_wakeup_thresh) | 749 | if (r->entropy_count < random_write_wakeup_thresh) { |
753 | wake_up_interruptible(&random_write_wait); | 750 | wake_up_interruptible(&random_write_wait); |
751 | kill_fasync(&fasync, SIGIO, POLL_OUT); | ||
752 | } | ||
754 | } | 753 | } |
755 | 754 | ||
756 | DEBUG_ENT("debiting %d entropy credits from %s%s\n", | 755 | DEBUG_ENT("debiting %d entropy credits from %s%s\n", |
@@ -764,45 +763,46 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
764 | static void extract_buf(struct entropy_store *r, __u8 *out) | 763 | static void extract_buf(struct entropy_store *r, __u8 *out) |
765 | { | 764 | { |
766 | int i; | 765 | int i; |
767 | __u32 data[16], buf[5 + SHA_WORKSPACE_WORDS]; | 766 | __u32 hash[5], workspace[SHA_WORKSPACE_WORDS]; |
767 | __u8 extract[64]; | ||
768 | |||
769 | /* Generate a hash across the pool, 16 words (512 bits) at a time */ | ||
770 | sha_init(hash); | ||
771 | for (i = 0; i < r->poolinfo->poolwords; i += 16) | ||
772 | sha_transform(hash, (__u8 *)(r->pool + i), workspace); | ||
768 | 773 | ||
769 | sha_init(buf); | ||
770 | /* | 774 | /* |
771 | * As we hash the pool, we mix intermediate values of | 775 | * We mix the hash back into the pool to prevent backtracking |
772 | * the hash back into the pool. This eliminates | 776 | * attacks (where the attacker knows the state of the pool |
773 | * backtracking attacks (where the attacker knows | 777 | * plus the current outputs, and attempts to find previous |
774 | * the state of the pool plus the current outputs, and | 778 | * ouputs), unless the hash function can be inverted. By |
775 | * attempts to find previous ouputs), unless the hash | 779 | * mixing at least a SHA1 worth of hash data back, we make |
776 | * function can be inverted. | 780 | * brute-forcing the feedback as hard as brute-forcing the |
781 | * hash. | ||
777 | */ | 782 | */ |
778 | for (i = 0; i < r->poolinfo->poolwords; i += 16) { | 783 | mix_pool_bytes_extract(r, hash, sizeof(hash), extract); |
779 | /* hash blocks of 16 words = 512 bits */ | ||
780 | sha_transform(buf, (__u8 *)(r->pool + i), buf + 5); | ||
781 | /* feed back portion of the resulting hash */ | ||
782 | add_entropy_words(r, &buf[i % 5], 1); | ||
783 | } | ||
784 | 784 | ||
785 | /* | 785 | /* |
786 | * To avoid duplicates, we atomically extract a | 786 | * To avoid duplicates, we atomically extract a portion of the |
787 | * portion of the pool while mixing, and hash one | 787 | * pool while mixing, and hash one final time. |
788 | * final time. | ||
789 | */ | 788 | */ |
790 | __add_entropy_words(r, &buf[i % 5], 1, data); | 789 | sha_transform(hash, extract, workspace); |
791 | sha_transform(buf, (__u8 *)data, buf + 5); | 790 | memset(extract, 0, sizeof(extract)); |
791 | memset(workspace, 0, sizeof(workspace)); | ||
792 | 792 | ||
793 | /* | 793 | /* |
794 | * In case the hash function has some recognizable | 794 | * In case the hash function has some recognizable output |
795 | * output pattern, we fold it in half. | 795 | * pattern, we fold it in half. Thus, we always feed back |
796 | * twice as much data as we output. | ||
796 | */ | 797 | */ |
797 | 798 | hash[0] ^= hash[3]; | |
798 | buf[0] ^= buf[3]; | 799 | hash[1] ^= hash[4]; |
799 | buf[1] ^= buf[4]; | 800 | hash[2] ^= rol32(hash[2], 16); |
800 | buf[2] ^= rol32(buf[2], 16); | 801 | memcpy(out, hash, EXTRACT_SIZE); |
801 | memcpy(out, buf, EXTRACT_SIZE); | 802 | memset(hash, 0, sizeof(hash)); |
802 | memset(buf, 0, sizeof(buf)); | ||
803 | } | 803 | } |
804 | 804 | ||
805 | static ssize_t extract_entropy(struct entropy_store *r, void * buf, | 805 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, |
806 | size_t nbytes, int min, int reserved) | 806 | size_t nbytes, int min, int reserved) |
807 | { | 807 | { |
808 | ssize_t ret = 0, i; | 808 | ssize_t ret = 0, i; |
@@ -872,7 +872,6 @@ void get_random_bytes(void *buf, int nbytes) | |||
872 | { | 872 | { |
873 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); | 873 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); |
874 | } | 874 | } |
875 | |||
876 | EXPORT_SYMBOL(get_random_bytes); | 875 | EXPORT_SYMBOL(get_random_bytes); |
877 | 876 | ||
878 | /* | 877 | /* |
@@ -894,12 +893,11 @@ static void init_std_data(struct entropy_store *r) | |||
894 | spin_unlock_irqrestore(&r->lock, flags); | 893 | spin_unlock_irqrestore(&r->lock, flags); |
895 | 894 | ||
896 | now = ktime_get_real(); | 895 | now = ktime_get_real(); |
897 | add_entropy_words(r, (__u32 *)&now, sizeof(now)/4); | 896 | mix_pool_bytes(r, &now, sizeof(now)); |
898 | add_entropy_words(r, (__u32 *)utsname(), | 897 | mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); |
899 | sizeof(*(utsname()))/4); | ||
900 | } | 898 | } |
901 | 899 | ||
902 | static int __init rand_initialize(void) | 900 | static int rand_initialize(void) |
903 | { | 901 | { |
904 | init_std_data(&input_pool); | 902 | init_std_data(&input_pool); |
905 | init_std_data(&blocking_pool); | 903 | init_std_data(&blocking_pool); |
@@ -940,7 +938,7 @@ void rand_initialize_disk(struct gendisk *disk) | |||
940 | #endif | 938 | #endif |
941 | 939 | ||
942 | static ssize_t | 940 | static ssize_t |
943 | random_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) | 941 | random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
944 | { | 942 | { |
945 | ssize_t n, retval = 0, count = 0; | 943 | ssize_t n, retval = 0, count = 0; |
946 | 944 | ||
@@ -1002,8 +1000,7 @@ random_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) | |||
1002 | } | 1000 | } |
1003 | 1001 | ||
1004 | static ssize_t | 1002 | static ssize_t |
1005 | urandom_read(struct file * file, char __user * buf, | 1003 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
1006 | size_t nbytes, loff_t *ppos) | ||
1007 | { | 1004 | { |
1008 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1005 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); |
1009 | } | 1006 | } |
@@ -1038,16 +1035,15 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) | |||
1038 | count -= bytes; | 1035 | count -= bytes; |
1039 | p += bytes; | 1036 | p += bytes; |
1040 | 1037 | ||
1041 | add_entropy_words(r, buf, (bytes + 3) / 4); | 1038 | mix_pool_bytes(r, buf, bytes); |
1042 | cond_resched(); | 1039 | cond_resched(); |
1043 | } | 1040 | } |
1044 | 1041 | ||
1045 | return 0; | 1042 | return 0; |
1046 | } | 1043 | } |
1047 | 1044 | ||
1048 | static ssize_t | 1045 | static ssize_t random_write(struct file *file, const char __user *buffer, |
1049 | random_write(struct file * file, const char __user * buffer, | 1046 | size_t count, loff_t *ppos) |
1050 | size_t count, loff_t *ppos) | ||
1051 | { | 1047 | { |
1052 | size_t ret; | 1048 | size_t ret; |
1053 | struct inode *inode = file->f_path.dentry->d_inode; | 1049 | struct inode *inode = file->f_path.dentry->d_inode; |
@@ -1064,9 +1060,7 @@ random_write(struct file * file, const char __user * buffer, | |||
1064 | return (ssize_t)count; | 1060 | return (ssize_t)count; |
1065 | } | 1061 | } |
1066 | 1062 | ||
1067 | static int | 1063 | static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
1068 | random_ioctl(struct inode * inode, struct file * file, | ||
1069 | unsigned int cmd, unsigned long arg) | ||
1070 | { | 1064 | { |
1071 | int size, ent_count; | 1065 | int size, ent_count; |
1072 | int __user *p = (int __user *)arg; | 1066 | int __user *p = (int __user *)arg; |
@@ -1074,8 +1068,8 @@ random_ioctl(struct inode * inode, struct file * file, | |||
1074 | 1068 | ||
1075 | switch (cmd) { | 1069 | switch (cmd) { |
1076 | case RNDGETENTCNT: | 1070 | case RNDGETENTCNT: |
1077 | ent_count = input_pool.entropy_count; | 1071 | /* inherently racy, no point locking */ |
1078 | if (put_user(ent_count, p)) | 1072 | if (put_user(input_pool.entropy_count, p)) |
1079 | return -EFAULT; | 1073 | return -EFAULT; |
1080 | return 0; | 1074 | return 0; |
1081 | case RNDADDTOENTCNT: | 1075 | case RNDADDTOENTCNT: |
@@ -1083,13 +1077,7 @@ random_ioctl(struct inode * inode, struct file * file, | |||
1083 | return -EPERM; | 1077 | return -EPERM; |
1084 | if (get_user(ent_count, p)) | 1078 | if (get_user(ent_count, p)) |
1085 | return -EFAULT; | 1079 | return -EFAULT; |
1086 | credit_entropy_store(&input_pool, ent_count); | 1080 | credit_entropy_bits(&input_pool, ent_count); |
1087 | /* | ||
1088 | * Wake up waiting processes if we have enough | ||
1089 | * entropy. | ||
1090 | */ | ||
1091 | if (input_pool.entropy_count >= random_read_wakeup_thresh) | ||
1092 | wake_up_interruptible(&random_read_wait); | ||
1093 | return 0; | 1081 | return 0; |
1094 | case RNDADDENTROPY: | 1082 | case RNDADDENTROPY: |
1095 | if (!capable(CAP_SYS_ADMIN)) | 1083 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1104,39 +1092,45 @@ random_ioctl(struct inode * inode, struct file * file, | |||
1104 | size); | 1092 | size); |
1105 | if (retval < 0) | 1093 | if (retval < 0) |
1106 | return retval; | 1094 | return retval; |
1107 | credit_entropy_store(&input_pool, ent_count); | 1095 | credit_entropy_bits(&input_pool, ent_count); |
1108 | /* | ||
1109 | * Wake up waiting processes if we have enough | ||
1110 | * entropy. | ||
1111 | */ | ||
1112 | if (input_pool.entropy_count >= random_read_wakeup_thresh) | ||
1113 | wake_up_interruptible(&random_read_wait); | ||
1114 | return 0; | 1096 | return 0; |
1115 | case RNDZAPENTCNT: | 1097 | case RNDZAPENTCNT: |
1116 | case RNDCLEARPOOL: | 1098 | case RNDCLEARPOOL: |
1117 | /* Clear the entropy pool counters. */ | 1099 | /* Clear the entropy pool counters. */ |
1118 | if (!capable(CAP_SYS_ADMIN)) | 1100 | if (!capable(CAP_SYS_ADMIN)) |
1119 | return -EPERM; | 1101 | return -EPERM; |
1120 | init_std_data(&input_pool); | 1102 | rand_initialize(); |
1121 | init_std_data(&blocking_pool); | ||
1122 | init_std_data(&nonblocking_pool); | ||
1123 | return 0; | 1103 | return 0; |
1124 | default: | 1104 | default: |
1125 | return -EINVAL; | 1105 | return -EINVAL; |
1126 | } | 1106 | } |
1127 | } | 1107 | } |
1128 | 1108 | ||
1109 | static int random_fasync(int fd, struct file *filp, int on) | ||
1110 | { | ||
1111 | return fasync_helper(fd, filp, on, &fasync); | ||
1112 | } | ||
1113 | |||
1114 | static int random_release(struct inode *inode, struct file *filp) | ||
1115 | { | ||
1116 | return fasync_helper(-1, filp, 0, &fasync); | ||
1117 | } | ||
1118 | |||
1129 | const struct file_operations random_fops = { | 1119 | const struct file_operations random_fops = { |
1130 | .read = random_read, | 1120 | .read = random_read, |
1131 | .write = random_write, | 1121 | .write = random_write, |
1132 | .poll = random_poll, | 1122 | .poll = random_poll, |
1133 | .ioctl = random_ioctl, | 1123 | .unlocked_ioctl = random_ioctl, |
1124 | .fasync = random_fasync, | ||
1125 | .release = random_release, | ||
1134 | }; | 1126 | }; |
1135 | 1127 | ||
1136 | const struct file_operations urandom_fops = { | 1128 | const struct file_operations urandom_fops = { |
1137 | .read = urandom_read, | 1129 | .read = urandom_read, |
1138 | .write = random_write, | 1130 | .write = random_write, |
1139 | .ioctl = random_ioctl, | 1131 | .unlocked_ioctl = random_ioctl, |
1132 | .fasync = random_fasync, | ||
1133 | .release = random_release, | ||
1140 | }; | 1134 | }; |
1141 | 1135 | ||
1142 | /*************************************************************** | 1136 | /*************************************************************** |
@@ -1157,7 +1151,6 @@ void generate_random_uuid(unsigned char uuid_out[16]) | |||
1157 | /* Set the UUID variant to DCE */ | 1151 | /* Set the UUID variant to DCE */ |
1158 | uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80; | 1152 | uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80; |
1159 | } | 1153 | } |
1160 | |||
1161 | EXPORT_SYMBOL(generate_random_uuid); | 1154 | EXPORT_SYMBOL(generate_random_uuid); |
1162 | 1155 | ||
1163 | /******************************************************************** | 1156 | /******************************************************************** |
@@ -1339,7 +1332,7 @@ ctl_table random_table[] = { | |||
1339 | 1332 | ||
1340 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1333 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1341 | 1334 | ||
1342 | static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12]) | 1335 | static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) |
1343 | { | 1336 | { |
1344 | __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; | 1337 | __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; |
1345 | 1338 | ||
@@ -1487,8 +1480,8 @@ __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, | |||
1487 | */ | 1480 | */ |
1488 | 1481 | ||
1489 | memcpy(hash, saddr, 16); | 1482 | memcpy(hash, saddr, 16); |
1490 | hash[4]=((__force u16)sport << 16) + (__force u16)dport; | 1483 | hash[4] = ((__force u16)sport << 16) + (__force u16)dport; |
1491 | memcpy(&hash[5],keyptr->secret,sizeof(__u32) * 7); | 1484 | memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
1492 | 1485 | ||
1493 | seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; | 1486 | seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; |
1494 | seq += keyptr->count; | 1487 | seq += keyptr->count; |
@@ -1538,10 +1531,10 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | |||
1538 | * Note that the words are placed into the starting vector, which is | 1531 | * Note that the words are placed into the starting vector, which is |
1539 | * then mixed with a partial MD4 over random data. | 1532 | * then mixed with a partial MD4 over random data. |
1540 | */ | 1533 | */ |
1541 | hash[0]=(__force u32)saddr; | 1534 | hash[0] = (__force u32)saddr; |
1542 | hash[1]=(__force u32)daddr; | 1535 | hash[1] = (__force u32)daddr; |
1543 | hash[2]=((__force u16)sport << 16) + (__force u16)dport; | 1536 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
1544 | hash[3]=keyptr->secret[11]; | 1537 | hash[3] = keyptr->secret[11]; |
1545 | 1538 | ||
1546 | seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; | 1539 | seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; |
1547 | seq += keyptr->count; | 1540 | seq += keyptr->count; |
@@ -1556,10 +1549,7 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | |||
1556 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | 1549 | * Choosing a clock of 64 ns period is OK. (period of 274 s) |
1557 | */ | 1550 | */ |
1558 | seq += ktime_to_ns(ktime_get_real()) >> 6; | 1551 | seq += ktime_to_ns(ktime_get_real()) >> 6; |
1559 | #if 0 | 1552 | |
1560 | printk("init_seq(%lx, %lx, %d, %d) = %d\n", | ||
1561 | saddr, daddr, sport, dport, seq); | ||
1562 | #endif | ||
1563 | return seq; | 1553 | return seq; |
1564 | } | 1554 | } |
1565 | 1555 | ||
@@ -1582,14 +1572,15 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | |||
1582 | } | 1572 | } |
1583 | 1573 | ||
1584 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1574 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1585 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport) | 1575 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
1576 | __be16 dport) | ||
1586 | { | 1577 | { |
1587 | struct keydata *keyptr = get_keyptr(); | 1578 | struct keydata *keyptr = get_keyptr(); |
1588 | u32 hash[12]; | 1579 | u32 hash[12]; |
1589 | 1580 | ||
1590 | memcpy(hash, saddr, 16); | 1581 | memcpy(hash, saddr, 16); |
1591 | hash[4] = (__force u32)dport; | 1582 | hash[4] = (__force u32)dport; |
1592 | memcpy(&hash[5],keyptr->secret,sizeof(__u32) * 7); | 1583 | memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
1593 | 1584 | ||
1594 | return twothirdsMD4Transform((const __u32 *)daddr, hash); | 1585 | return twothirdsMD4Transform((const __u32 *)daddr, hash); |
1595 | } | 1586 | } |
@@ -1617,13 +1608,9 @@ u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, | |||
1617 | 1608 | ||
1618 | seq += ktime_to_ns(ktime_get_real()); | 1609 | seq += ktime_to_ns(ktime_get_real()); |
1619 | seq &= (1ull << 48) - 1; | 1610 | seq &= (1ull << 48) - 1; |
1620 | #if 0 | 1611 | |
1621 | printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n", | ||
1622 | saddr, daddr, sport, dport, seq); | ||
1623 | #endif | ||
1624 | return seq; | 1612 | return seq; |
1625 | } | 1613 | } |
1626 | |||
1627 | EXPORT_SYMBOL(secure_dccp_sequence_number); | 1614 | EXPORT_SYMBOL(secure_dccp_sequence_number); |
1628 | #endif | 1615 | #endif |
1629 | 1616 | ||
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h index f4f837f86829..a03a538a3efb 100644 --- a/drivers/char/rio/cirrus.h +++ b/drivers/char/rio/cirrus.h | |||
@@ -43,83 +43,83 @@ | |||
43 | /* Bit fields for particular registers shared with driver */ | 43 | /* Bit fields for particular registers shared with driver */ |
44 | 44 | ||
45 | /* COR1 - driver and RTA */ | 45 | /* COR1 - driver and RTA */ |
46 | #define COR1_ODD 0x80 /* Odd parity */ | 46 | #define RIOC_COR1_ODD 0x80 /* Odd parity */ |
47 | #define COR1_EVEN 0x00 /* Even parity */ | 47 | #define RIOC_COR1_EVEN 0x00 /* Even parity */ |
48 | #define COR1_NOP 0x00 /* No parity */ | 48 | #define RIOC_COR1_NOP 0x00 /* No parity */ |
49 | #define COR1_FORCE 0x20 /* Force parity */ | 49 | #define RIOC_COR1_FORCE 0x20 /* Force parity */ |
50 | #define COR1_NORMAL 0x40 /* With parity */ | 50 | #define RIOC_COR1_NORMAL 0x40 /* With parity */ |
51 | #define COR1_1STOP 0x00 /* 1 stop bit */ | 51 | #define RIOC_COR1_1STOP 0x00 /* 1 stop bit */ |
52 | #define COR1_15STOP 0x04 /* 1.5 stop bits */ | 52 | #define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */ |
53 | #define COR1_2STOP 0x08 /* 2 stop bits */ | 53 | #define RIOC_COR1_2STOP 0x08 /* 2 stop bits */ |
54 | #define COR1_5BITS 0x00 /* 5 data bits */ | 54 | #define RIOC_COR1_5BITS 0x00 /* 5 data bits */ |
55 | #define COR1_6BITS 0x01 /* 6 data bits */ | 55 | #define RIOC_COR1_6BITS 0x01 /* 6 data bits */ |
56 | #define COR1_7BITS 0x02 /* 7 data bits */ | 56 | #define RIOC_COR1_7BITS 0x02 /* 7 data bits */ |
57 | #define COR1_8BITS 0x03 /* 8 data bits */ | 57 | #define RIOC_COR1_8BITS 0x03 /* 8 data bits */ |
58 | 58 | ||
59 | #define COR1_HOST 0xef /* Safe host bits */ | 59 | #define RIOC_COR1_HOST 0xef /* Safe host bits */ |
60 | 60 | ||
61 | /* RTA only */ | 61 | /* RTA only */ |
62 | #define COR1_CINPCK 0x00 /* Check parity of received characters */ | 62 | #define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */ |
63 | #define COR1_CNINPCK 0x10 /* Don't check parity */ | 63 | #define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */ |
64 | 64 | ||
65 | /* COR2 bits for both RTA and driver use */ | 65 | /* COR2 bits for both RTA and driver use */ |
66 | #define COR2_IXANY 0x80 /* IXANY - any character is XON */ | 66 | #define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */ |
67 | #define COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ | 67 | #define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ |
68 | #define COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ | 68 | #define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ |
69 | 69 | ||
70 | /* Additional driver bits */ | 70 | /* Additional driver bits */ |
71 | #define COR2_HUPCL 0x20 /* Hang up on close */ | 71 | #define RIOC_COR2_HUPCL 0x20 /* Hang up on close */ |
72 | #define COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ | 72 | #define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ |
73 | #define COR2_IXOFF 0x01 /* Enable rx software flow control */ | 73 | #define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */ |
74 | #define COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ | 74 | #define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ |
75 | 75 | ||
76 | /* RTA use only */ | 76 | /* RTA use only */ |
77 | #define COR2_ETC 0x20 /* Embedded transmit options */ | 77 | #define RIOC_COR2_ETC 0x20 /* Embedded transmit options */ |
78 | #define COR2_LOCAL 0x10 /* Local loopback mode */ | 78 | #define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */ |
79 | #define COR2_REMOTE 0x08 /* Remote loopback mode */ | 79 | #define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */ |
80 | #define COR2_HOST 0xc2 /* Safe host bits */ | 80 | #define RIOC_COR2_HOST 0xc2 /* Safe host bits */ |
81 | 81 | ||
82 | /* COR3 - RTA use only */ | 82 | /* COR3 - RTA use only */ |
83 | #define COR3_SCDRNG 0x80 /* Enable special char detect for range */ | 83 | #define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */ |
84 | #define COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ | 84 | #define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ |
85 | #define COR3_FCT 0x20 /* Flow control transparency */ | 85 | #define RIOC_COR3_FCT 0x20 /* Flow control transparency */ |
86 | #define COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ | 86 | #define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ |
87 | #define COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ | 87 | #define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ |
88 | #define COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ | 88 | #define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ |
89 | #define COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ | 89 | #define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ |
90 | #define COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ | 90 | #define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ |
91 | 91 | ||
92 | #define COR3_THRESHOLD COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ | 92 | #define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ |
93 | 93 | ||
94 | #define COR3_DEFAULT (COR3_FCT | COR3_THRESHOLD) | 94 | #define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD) |
95 | /* Default bits for COR3 */ | 95 | /* Default bits for COR3 */ |
96 | 96 | ||
97 | /* COR4 driver and RTA use */ | 97 | /* COR4 driver and RTA use */ |
98 | #define COR4_IGNCR 0x80 /* Throw away CR's on input */ | 98 | #define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */ |
99 | #define COR4_ICRNL 0x40 /* Map CR -> NL on input */ | 99 | #define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */ |
100 | #define COR4_INLCR 0x20 /* Map NL -> CR on input */ | 100 | #define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */ |
101 | #define COR4_IGNBRK 0x10 /* Ignore Break */ | 101 | #define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */ |
102 | #define COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ | 102 | #define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ |
103 | #define COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ | 103 | #define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ |
104 | 104 | ||
105 | 105 | ||
106 | /* COR4 driver only */ | 106 | /* COR4 driver only */ |
107 | #define COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ | 107 | #define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ |
108 | #define COR4_PARMRK 0x02 /* PARMRK */ | 108 | #define RIOC_COR4_PARMRK 0x02 /* PARMRK */ |
109 | 109 | ||
110 | #define COR4_HOST 0xf8 /* Safe host bits */ | 110 | #define RIOC_COR4_HOST 0xf8 /* Safe host bits */ |
111 | 111 | ||
112 | /* COR4 RTA only */ | 112 | /* COR4 RTA only */ |
113 | #define COR4_CIGNPAR 0x02 /* Thrown away bad characters */ | 113 | #define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */ |
114 | #define COR4_CPARMRK 0x04 /* PARMRK characters */ | 114 | #define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */ |
115 | #define COR4_CNPARMRK 0x03 /* Don't PARMRK */ | 115 | #define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */ |
116 | 116 | ||
117 | /* COR5 driver and RTA use */ | 117 | /* COR5 driver and RTA use */ |
118 | #define COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ | 118 | #define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ |
119 | #define COR5_LNE 0x40 /* Enable LNEXT processing */ | 119 | #define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */ |
120 | #define COR5_CMOE 0x20 /* Match good and errored characters */ | 120 | #define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */ |
121 | #define COR5_ONLCR 0x02 /* NL -> CR NL on output */ | 121 | #define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */ |
122 | #define COR5_OCRNL 0x01 /* CR -> NL on output */ | 122 | #define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */ |
123 | 123 | ||
124 | /* | 124 | /* |
125 | ** Spare bits - these are not used in the CIRRUS registers, so we use | 125 | ** Spare bits - these are not used in the CIRRUS registers, so we use |
@@ -128,86 +128,86 @@ | |||
128 | /* | 128 | /* |
129 | ** tstop and tbusy indication | 129 | ** tstop and tbusy indication |
130 | */ | 130 | */ |
131 | #define COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ | 131 | #define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ |
132 | #define COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ | 132 | #define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ |
133 | /* | 133 | /* |
134 | ** TAB3 | 134 | ** TAB3 |
135 | */ | 135 | */ |
136 | #define COR5_TAB3 0x10 /* TAB3 mode */ | 136 | #define RIOC_COR5_TAB3 0x10 /* TAB3 mode */ |
137 | 137 | ||
138 | #define COR5_HOST 0xc3 /* Safe host bits */ | 138 | #define RIOC_COR5_HOST 0xc3 /* Safe host bits */ |
139 | 139 | ||
140 | /* CCSR */ | 140 | /* CCSR */ |
141 | #define CCSR_TXFLOFF 0x04 /* Tx is xoffed */ | 141 | #define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */ |
142 | 142 | ||
143 | /* MSVR1 */ | 143 | /* MSVR1 */ |
144 | /* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the | 144 | /* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the |
145 | RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 | 145 | RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 |
146 | serial option. | 146 | serial option. |
147 | */ | 147 | */ |
148 | #define MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ | 148 | #define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ |
149 | #define MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ | 149 | #define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ |
150 | #define MSVR1_RI 0x20 /* RI */ | 150 | #define RIOC_MSVR1_RI 0x20 /* RI */ |
151 | #define MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ | 151 | #define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ |
152 | #define MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ | 152 | #define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ |
153 | /* Next two used to indicate state of tbusy and tstop to driver */ | 153 | /* Next two used to indicate state of tbusy and tstop to driver */ |
154 | #define MSVR1_TSTOP 0x08 /* Set if port flow controlled */ | 154 | #define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */ |
155 | #define MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ | 155 | #define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ |
156 | 156 | ||
157 | #define MSVR1_HOST 0xf3 /* The bits the host wants */ | 157 | #define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */ |
158 | 158 | ||
159 | /* Defines for the subscripts of a CONFIG packet */ | 159 | /* Defines for the subscripts of a CONFIG packet */ |
160 | #define CONFIG_COR1 1 /* Option register 1 */ | 160 | #define RIOC_CONFIG_COR1 1 /* Option register 1 */ |
161 | #define CONFIG_COR2 2 /* Option register 2 */ | 161 | #define RIOC_CONFIG_COR2 2 /* Option register 2 */ |
162 | #define CONFIG_COR4 3 /* Option register 4 */ | 162 | #define RIOC_CONFIG_COR4 3 /* Option register 4 */ |
163 | #define CONFIG_COR5 4 /* Option register 5 */ | 163 | #define RIOC_CONFIG_COR5 4 /* Option register 5 */ |
164 | #define CONFIG_TXXON 5 /* Tx XON character */ | 164 | #define RIOC_CONFIG_TXXON 5 /* Tx XON character */ |
165 | #define CONFIG_TXXOFF 6 /* Tx XOFF character */ | 165 | #define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */ |
166 | #define CONFIG_RXXON 7 /* Rx XON character */ | 166 | #define RIOC_CONFIG_RXXON 7 /* Rx XON character */ |
167 | #define CONFIG_RXXOFF 8 /* Rx XOFF character */ | 167 | #define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */ |
168 | #define CONFIG_LNEXT 9 /* LNEXT character */ | 168 | #define RIOC_CONFIG_LNEXT 9 /* LNEXT character */ |
169 | #define CONFIG_TXBAUD 10 /* Tx baud rate */ | 169 | #define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */ |
170 | #define CONFIG_RXBAUD 11 /* Rx baud rate */ | 170 | #define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */ |
171 | 171 | ||
172 | #define PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ | 172 | #define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ |
173 | 173 | ||
174 | /* Packet types going from Host to remote - with the exception of OPEN, MOPEN, | 174 | /* Packet types going from Host to remote - with the exception of OPEN, MOPEN, |
175 | CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not | 175 | CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not |
176 | be used | 176 | be used |
177 | */ | 177 | */ |
178 | #define OPEN 0x00 /* Open a port */ | 178 | #define RIOC_OPEN 0x00 /* Open a port */ |
179 | #define CONFIG 0x01 /* Configure a port */ | 179 | #define RIOC_CONFIG 0x01 /* Configure a port */ |
180 | #define MOPEN 0x02 /* Modem open (block for DCD) */ | 180 | #define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */ |
181 | #define CLOSE 0x03 /* Close a port */ | 181 | #define RIOC_CLOSE 0x03 /* Close a port */ |
182 | #define WFLUSH (0x04 | PRE_EMPTIVE) /* Write flush */ | 182 | #define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */ |
183 | #define RFLUSH (0x05 | PRE_EMPTIVE) /* Read flush */ | 183 | #define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */ |
184 | #define RESUME (0x06 | PRE_EMPTIVE) /* Resume if xoffed */ | 184 | #define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */ |
185 | #define SBREAK 0x07 /* Start break */ | 185 | #define RIOC_SBREAK 0x07 /* Start break */ |
186 | #define EBREAK 0x08 /* End break */ | 186 | #define RIOC_EBREAK 0x08 /* End break */ |
187 | #define SUSPEND (0x09 | PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ | 187 | #define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ |
188 | #define FCLOSE (0x0a | PRE_EMPTIVE) /* Force close */ | 188 | #define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */ |
189 | #define XPRINT 0x0b /* Xprint packet */ | 189 | #define RIOC_XPRINT 0x0b /* Xprint packet */ |
190 | #define MBIS (0x0c | PRE_EMPTIVE) /* Set modem lines */ | 190 | #define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */ |
191 | #define MBIC (0x0d | PRE_EMPTIVE) /* Clear modem lines */ | 191 | #define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */ |
192 | #define MSET (0x0e | PRE_EMPTIVE) /* Set modem lines */ | 192 | #define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */ |
193 | #define PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ | 193 | #define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ |
194 | #define MGET (0x10 | PRE_EMPTIVE) /* Force update of modem status */ | 194 | #define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */ |
195 | #define MEMDUMP (0x11 | PRE_EMPTIVE) /* Send back mem from addr supplied */ | 195 | #define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */ |
196 | #define READ_REGISTER (0x12 | PRE_EMPTIVE) /* Read CD1400 register (debug) */ | 196 | #define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */ |
197 | 197 | ||
198 | /* "Command" packets going from remote to host COMPLETE and MODEM_STATUS | 198 | /* "Command" packets going from remote to host COMPLETE and MODEM_STATUS |
199 | use data[4] / data[3] to indicate current state and modem status respectively | 199 | use data[4] / data[3] to indicate current state and modem status respectively |
200 | */ | 200 | */ |
201 | 201 | ||
202 | #define COMPLETE (0x20 | PRE_EMPTIVE) | 202 | #define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE) |
203 | /* Command complete */ | 203 | /* Command complete */ |
204 | #define BREAK_RECEIVED (0x21 | PRE_EMPTIVE) | 204 | #define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE) |
205 | /* Break received */ | 205 | /* Break received */ |
206 | #define MODEM_STATUS (0x22 | PRE_EMPTIVE) | 206 | #define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE) |
207 | /* Change in modem status */ | 207 | /* Change in modem status */ |
208 | 208 | ||
209 | /* "Command" packet that could go either way - handshake wake-up */ | 209 | /* "Command" packet that could go either way - handshake wake-up */ |
210 | #define HANDSHAKE (0x23 | PRE_EMPTIVE) | 210 | #define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE) |
211 | /* Wake-up to HOST / RTA */ | 211 | /* Wake-up to HOST / RTA */ |
212 | 212 | ||
213 | #endif | 213 | #endif |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 0ce96670f979..412777cd1e68 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -344,7 +344,7 @@ int rio_minor(struct tty_struct *tty) | |||
344 | 344 | ||
345 | static int rio_set_real_termios(void *ptr) | 345 | static int rio_set_real_termios(void *ptr) |
346 | { | 346 | { |
347 | return RIOParam((struct Port *) ptr, CONFIG, 1, 1); | 347 | return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1); |
348 | } | 348 | } |
349 | 349 | ||
350 | 350 | ||
@@ -487,7 +487,7 @@ static int rio_get_CD(void *ptr) | |||
487 | int rv; | 487 | int rv; |
488 | 488 | ||
489 | func_enter(); | 489 | func_enter(); |
490 | rv = (PortP->ModemState & MSVR1_CD) != 0; | 490 | rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0; |
491 | 491 | ||
492 | rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); | 492 | rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); |
493 | 493 | ||
@@ -607,7 +607,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd | |||
607 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); | 607 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); |
608 | rc = -EIO; | 608 | rc = -EIO; |
609 | } else { | 609 | } else { |
610 | if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) { | 610 | if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) == |
611 | RIO_FAIL) { | ||
611 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | 612 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); |
612 | rc = -EIO; | 613 | rc = -EIO; |
613 | } | 614 | } |
@@ -622,7 +623,8 @@ static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd | |||
622 | l = arg ? arg * 100 : 250; | 623 | l = arg ? arg * 100 : 250; |
623 | if (l > 255) | 624 | if (l > 255) |
624 | l = 255; | 625 | l = 255; |
625 | if (RIOShortCommand(p, PortP, SBREAK, 2, arg ? arg * 100 : 250) == RIO_FAIL) { | 626 | if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, |
627 | arg ? arg * 100 : 250) == RIO_FAIL) { | ||
626 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | 628 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); |
627 | rc = -EIO; | 629 | rc = -EIO; |
628 | } | 630 | } |
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h index dc3f005614a3..7f26cd7c815e 100644 --- a/drivers/char/rio/rio_linux.h +++ b/drivers/char/rio/rio_linux.h | |||
@@ -186,9 +186,9 @@ static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n) | |||
186 | 186 | ||
187 | #ifdef DEBUG | 187 | #ifdef DEBUG |
188 | #define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) | 188 | #define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) |
189 | #define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __FUNCTION__) | 189 | #define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__) |
190 | #define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __FUNCTION__) | 190 | #define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__) |
191 | #define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__FUNCTION__, port->line) | 191 | #define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line) |
192 | #else | 192 | #else |
193 | #define rio_dprintk(f, str...) /* nothing */ | 193 | #define rio_dprintk(f, str...) /* nothing */ |
194 | #define func_enter() | 194 | #define func_enter() |
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c index bf36959fc121..7b96e0814887 100644 --- a/drivers/char/rio/riocmd.c +++ b/drivers/char/rio/riocmd.c | |||
@@ -417,7 +417,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc | |||
417 | PortP = p->RIOPortp[SysPort]; | 417 | PortP = p->RIOPortp[SysPort]; |
418 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 418 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
419 | switch (readb(&PktCmdP->Command)) { | 419 | switch (readb(&PktCmdP->Command)) { |
420 | case BREAK_RECEIVED: | 420 | case RIOC_BREAK_RECEIVED: |
421 | rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); | 421 | rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); |
422 | /* If the current line disc. is not multi-threading and | 422 | /* If the current line disc. is not multi-threading and |
423 | the current processor is not the default, reset rup_intr | 423 | the current processor is not the default, reset rup_intr |
@@ -428,16 +428,16 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc | |||
428 | gs_got_break(&PortP->gs); | 428 | gs_got_break(&PortP->gs); |
429 | break; | 429 | break; |
430 | 430 | ||
431 | case COMPLETE: | 431 | case RIOC_COMPLETE: |
432 | rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); | 432 | rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); |
433 | subCommand = 1; | 433 | subCommand = 1; |
434 | switch (readb(&PktCmdP->SubCommand)) { | 434 | switch (readb(&PktCmdP->SubCommand)) { |
435 | case MEMDUMP: | 435 | case RIOC_MEMDUMP: |
436 | rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); | 436 | rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); |
437 | break; | 437 | break; |
438 | case READ_REGISTER: | 438 | case RIOC_READ_REGISTER: |
439 | rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); | 439 | rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); |
440 | p->CdRegister = (readb(&PktCmdP->ModemStatus) & MSVR1_HOST); | 440 | p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST); |
441 | break; | 441 | break; |
442 | default: | 442 | default: |
443 | subCommand = 0; | 443 | subCommand = 0; |
@@ -456,14 +456,15 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc | |||
456 | rio_dprintk(RIO_DEBUG_CMD, "No change\n"); | 456 | rio_dprintk(RIO_DEBUG_CMD, "No change\n"); |
457 | 457 | ||
458 | /* FALLTHROUGH */ | 458 | /* FALLTHROUGH */ |
459 | case MODEM_STATUS: | 459 | case RIOC_MODEM_STATUS: |
460 | /* | 460 | /* |
461 | ** Knock out the tbusy and tstop bits, as these are not relevant | 461 | ** Knock out the tbusy and tstop bits, as these are not relevant |
462 | ** to the check for modem status change (they're just there because | 462 | ** to the check for modem status change (they're just there because |
463 | ** it's a convenient place to put them!). | 463 | ** it's a convenient place to put them!). |
464 | */ | 464 | */ |
465 | ReportedModemStatus = readb(&PktCmdP->ModemStatus); | 465 | ReportedModemStatus = readb(&PktCmdP->ModemStatus); |
466 | if ((PortP->ModemState & MSVR1_HOST) == (ReportedModemStatus & MSVR1_HOST)) { | 466 | if ((PortP->ModemState & RIOC_MSVR1_HOST) == |
467 | (ReportedModemStatus & RIOC_MSVR1_HOST)) { | ||
467 | rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); | 468 | rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); |
468 | /* | 469 | /* |
469 | ** Update ModemState just in case tbusy or tstop states have | 470 | ** Update ModemState just in case tbusy or tstop states have |
@@ -497,7 +498,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc | |||
497 | /* | 498 | /* |
498 | ** Is there a carrier? | 499 | ** Is there a carrier? |
499 | */ | 500 | */ |
500 | if (PortP->ModemState & MSVR1_CD) { | 501 | if (PortP->ModemState & RIOC_MSVR1_CD) { |
501 | /* | 502 | /* |
502 | ** Has carrier just appeared? | 503 | ** Has carrier just appeared? |
503 | */ | 504 | */ |
@@ -691,7 +692,7 @@ void RIOPollHostCommands(struct rio_info *p, struct Host *HostP) | |||
691 | */ | 692 | */ |
692 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | 693 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); |
693 | FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); | 694 | FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); |
694 | if (readb(&PacketP->data[5]) == MEMDUMP) { | 695 | if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) { |
695 | rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); | 696 | rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); |
696 | rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); | 697 | rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); |
697 | } | 698 | } |
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c index d8eb2bcbe015..d65ceb9a434a 100644 --- a/drivers/char/rio/rioctrl.c +++ b/drivers/char/rio/rioctrl.c | |||
@@ -422,7 +422,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
422 | } | 422 | } |
423 | 423 | ||
424 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 424 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
425 | if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == RIO_FAIL) { | 425 | if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) == |
426 | RIO_FAIL) { | ||
426 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); | 427 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); |
427 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 428 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
428 | return -EBUSY; | 429 | return -EBUSY; |
@@ -636,7 +637,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
636 | return -ENXIO; | 637 | return -ENXIO; |
637 | } | 638 | } |
638 | PortP = (p->RIOPortp[PortTty.port]); | 639 | PortP = (p->RIOPortp[PortTty.port]); |
639 | RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP); | 640 | RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM, |
641 | OK_TO_SLEEP); | ||
640 | return retval; | 642 | return retval; |
641 | 643 | ||
642 | case RIO_SET_PORT_PARAMS: | 644 | case RIO_SET_PORT_PARAMS: |
@@ -1247,7 +1249,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
1247 | 1249 | ||
1248 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 1250 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
1249 | 1251 | ||
1250 | if (RIOPreemptiveCmd(p, PortP, MEMDUMP) == RIO_FAIL) { | 1252 | if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) { |
1251 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); | 1253 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); |
1252 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 1254 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
1253 | return -EBUSY; | 1255 | return -EBUSY; |
@@ -1313,7 +1315,8 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
1313 | 1315 | ||
1314 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 1316 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
1315 | 1317 | ||
1316 | if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) { | 1318 | if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) == |
1319 | RIO_FAIL) { | ||
1317 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); | 1320 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); |
1318 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 1321 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
1319 | return -EBUSY; | 1322 | return -EBUSY; |
@@ -1434,50 +1437,50 @@ int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) | |||
1434 | PktCmdP->PhbNum = port; | 1437 | PktCmdP->PhbNum = port; |
1435 | 1438 | ||
1436 | switch (Cmd) { | 1439 | switch (Cmd) { |
1437 | case MEMDUMP: | 1440 | case RIOC_MEMDUMP: |
1438 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " | 1441 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " |
1439 | "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); | 1442 | "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); |
1440 | PktCmdP->SubCommand = MEMDUMP; | 1443 | PktCmdP->SubCommand = RIOC_MEMDUMP; |
1441 | PktCmdP->SubAddr = SubCmd.Addr; | 1444 | PktCmdP->SubAddr = SubCmd.Addr; |
1442 | break; | 1445 | break; |
1443 | case FCLOSE: | 1446 | case RIOC_FCLOSE: |
1444 | rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", | 1447 | rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", |
1445 | CmdBlkP); | 1448 | CmdBlkP); |
1446 | break; | 1449 | break; |
1447 | case READ_REGISTER: | 1450 | case RIOC_READ_REGISTER: |
1448 | rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " | 1451 | rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " |
1449 | "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); | 1452 | "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); |
1450 | PktCmdP->SubCommand = READ_REGISTER; | 1453 | PktCmdP->SubCommand = RIOC_READ_REGISTER; |
1451 | PktCmdP->SubAddr = SubCmd.Addr; | 1454 | PktCmdP->SubAddr = SubCmd.Addr; |
1452 | break; | 1455 | break; |
1453 | case RESUME: | 1456 | case RIOC_RESUME: |
1454 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", | 1457 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", |
1455 | CmdBlkP); | 1458 | CmdBlkP); |
1456 | break; | 1459 | break; |
1457 | case RFLUSH: | 1460 | case RIOC_RFLUSH: |
1458 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", | 1461 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", |
1459 | CmdBlkP); | 1462 | CmdBlkP); |
1460 | CmdBlkP->PostFuncP = RIORFlushEnable; | 1463 | CmdBlkP->PostFuncP = RIORFlushEnable; |
1461 | break; | 1464 | break; |
1462 | case SUSPEND: | 1465 | case RIOC_SUSPEND: |
1463 | rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", | 1466 | rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", |
1464 | CmdBlkP); | 1467 | CmdBlkP); |
1465 | break; | 1468 | break; |
1466 | 1469 | ||
1467 | case MGET: | 1470 | case RIOC_MGET: |
1468 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", | 1471 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", |
1469 | CmdBlkP); | 1472 | CmdBlkP); |
1470 | break; | 1473 | break; |
1471 | 1474 | ||
1472 | case MSET: | 1475 | case RIOC_MSET: |
1473 | case MBIC: | 1476 | case RIOC_MBIC: |
1474 | case MBIS: | 1477 | case RIOC_MBIS: |
1475 | CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; | 1478 | CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; |
1476 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " | 1479 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " |
1477 | "blk %p\n", CmdBlkP); | 1480 | "blk %p\n", CmdBlkP); |
1478 | break; | 1481 | break; |
1479 | 1482 | ||
1480 | case WFLUSH: | 1483 | case RIOC_WFLUSH: |
1481 | /* | 1484 | /* |
1482 | ** If we have queued up the maximum number of Write flushes | 1485 | ** If we have queued up the maximum number of Write flushes |
1483 | ** allowed then we should not bother sending any more to the | 1486 | ** allowed then we should not bother sending any more to the |
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index 4734e26e1ccd..ea21686c69a4 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c | |||
@@ -401,9 +401,8 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP) | |||
401 | PortP->InUse = NOT_INUSE; | 401 | PortP->InUse = NOT_INUSE; |
402 | 402 | ||
403 | rio_spin_unlock(&PortP->portSem); | 403 | rio_spin_unlock(&PortP->portSem); |
404 | if (RIOParam(PortP, OPEN, ((PortP->Cor2Copy & (COR2_RTSFLOW | COR2_CTSFLOW)) == (COR2_RTSFLOW | COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) { | 404 | if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) |
405 | continue; /* with next port */ | 405 | continue; /* with next port */ |
406 | } | ||
407 | rio_spin_lock(&PortP->portSem); | 406 | rio_spin_lock(&PortP->portSem); |
408 | PortP->MagicFlags &= ~MAGIC_REBOOT; | 407 | PortP->MagicFlags &= ~MAGIC_REBOOT; |
409 | } | 408 | } |
@@ -429,7 +428,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP) | |||
429 | */ | 428 | */ |
430 | PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; | 429 | PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; |
431 | 430 | ||
432 | writeb(WFLUSH, &PktCmdP->Command); | 431 | writeb(RIOC_WFLUSH, &PktCmdP->Command); |
433 | 432 | ||
434 | p = PortP->HostPort % (u16) PORTS_PER_RTA; | 433 | p = PortP->HostPort % (u16) PORTS_PER_RTA; |
435 | 434 | ||
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c index da276ed57b3f..4810b845cc21 100644 --- a/drivers/char/rio/rioparam.c +++ b/drivers/char/rio/rioparam.c | |||
@@ -177,7 +177,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
177 | } | 177 | } |
178 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 178 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
179 | 179 | ||
180 | if (cmd == OPEN) { | 180 | if (cmd == RIOC_OPEN) { |
181 | /* | 181 | /* |
182 | ** If the port is set to store or lock the parameters, and it is | 182 | ** If the port is set to store or lock the parameters, and it is |
183 | ** paramed with OPEN, we want to restore the saved port termio, but | 183 | ** paramed with OPEN, we want to restore the saved port termio, but |
@@ -241,50 +241,50 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
241 | case CS5: | 241 | case CS5: |
242 | { | 242 | { |
243 | rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); | 243 | rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); |
244 | Cor1 |= COR1_5BITS; | 244 | Cor1 |= RIOC_COR1_5BITS; |
245 | break; | 245 | break; |
246 | } | 246 | } |
247 | case CS6: | 247 | case CS6: |
248 | { | 248 | { |
249 | rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); | 249 | rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); |
250 | Cor1 |= COR1_6BITS; | 250 | Cor1 |= RIOC_COR1_6BITS; |
251 | break; | 251 | break; |
252 | } | 252 | } |
253 | case CS7: | 253 | case CS7: |
254 | { | 254 | { |
255 | rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); | 255 | rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); |
256 | Cor1 |= COR1_7BITS; | 256 | Cor1 |= RIOC_COR1_7BITS; |
257 | break; | 257 | break; |
258 | } | 258 | } |
259 | case CS8: | 259 | case CS8: |
260 | { | 260 | { |
261 | rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); | 261 | rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); |
262 | Cor1 |= COR1_8BITS; | 262 | Cor1 |= RIOC_COR1_8BITS; |
263 | break; | 263 | break; |
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
267 | if (TtyP->termios->c_cflag & CSTOPB) { | 267 | if (TtyP->termios->c_cflag & CSTOPB) { |
268 | rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); | 268 | rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); |
269 | Cor1 |= COR1_2STOP; | 269 | Cor1 |= RIOC_COR1_2STOP; |
270 | } else { | 270 | } else { |
271 | rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); | 271 | rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); |
272 | Cor1 |= COR1_1STOP; | 272 | Cor1 |= RIOC_COR1_1STOP; |
273 | } | 273 | } |
274 | 274 | ||
275 | if (TtyP->termios->c_cflag & PARENB) { | 275 | if (TtyP->termios->c_cflag & PARENB) { |
276 | rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); | 276 | rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); |
277 | Cor1 |= COR1_NORMAL; | 277 | Cor1 |= RIOC_COR1_NORMAL; |
278 | } else { | 278 | } else { |
279 | rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); | 279 | rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); |
280 | Cor1 |= COR1_NOP; | 280 | Cor1 |= RIOC_COR1_NOP; |
281 | } | 281 | } |
282 | if (TtyP->termios->c_cflag & PARODD) { | 282 | if (TtyP->termios->c_cflag & PARODD) { |
283 | rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); | 283 | rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); |
284 | Cor1 |= COR1_ODD; | 284 | Cor1 |= RIOC_COR1_ODD; |
285 | } else { | 285 | } else { |
286 | rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); | 286 | rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); |
287 | Cor1 |= COR1_EVEN; | 287 | Cor1 |= RIOC_COR1_EVEN; |
288 | } | 288 | } |
289 | 289 | ||
290 | /* | 290 | /* |
@@ -292,11 +292,11 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
292 | */ | 292 | */ |
293 | if (TtyP->termios->c_iflag & IXON) { | 293 | if (TtyP->termios->c_iflag & IXON) { |
294 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); | 294 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); |
295 | Cor2 |= COR2_IXON; | 295 | Cor2 |= RIOC_COR2_IXON; |
296 | } else { | 296 | } else { |
297 | if (PortP->Config & RIO_IXON) { | 297 | if (PortP->Config & RIO_IXON) { |
298 | rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); | 298 | rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); |
299 | Cor2 |= COR2_IXON; | 299 | Cor2 |= RIOC_COR2_IXON; |
300 | } else | 300 | } else |
301 | rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); | 301 | rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); |
302 | } | 302 | } |
@@ -304,29 +304,29 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
304 | if (TtyP->termios->c_iflag & IXANY) { | 304 | if (TtyP->termios->c_iflag & IXANY) { |
305 | if (PortP->Config & RIO_IXANY) { | 305 | if (PortP->Config & RIO_IXANY) { |
306 | rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); | 306 | rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); |
307 | Cor2 |= COR2_IXANY; | 307 | Cor2 |= RIOC_COR2_IXANY; |
308 | } else | 308 | } else |
309 | rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); | 309 | rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); |
310 | } | 310 | } |
311 | 311 | ||
312 | if (TtyP->termios->c_iflag & IXOFF) { | 312 | if (TtyP->termios->c_iflag & IXOFF) { |
313 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); | 313 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); |
314 | Cor2 |= COR2_IXOFF; | 314 | Cor2 |= RIOC_COR2_IXOFF; |
315 | } | 315 | } |
316 | 316 | ||
317 | if (TtyP->termios->c_cflag & HUPCL) { | 317 | if (TtyP->termios->c_cflag & HUPCL) { |
318 | rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); | 318 | rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); |
319 | Cor2 |= COR2_HUPCL; | 319 | Cor2 |= RIOC_COR2_HUPCL; |
320 | } | 320 | } |
321 | 321 | ||
322 | if (C_CRTSCTS(TtyP)) { | 322 | if (C_CRTSCTS(TtyP)) { |
323 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); | 323 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); |
324 | Cor2 |= COR2_CTSFLOW; | 324 | Cor2 |= RIOC_COR2_CTSFLOW; |
325 | Cor2 |= COR2_RTSFLOW; | 325 | Cor2 |= RIOC_COR2_RTSFLOW; |
326 | } else { | 326 | } else { |
327 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); | 327 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); |
328 | Cor2 &= ~COR2_CTSFLOW; | 328 | Cor2 &= ~RIOC_COR2_CTSFLOW; |
329 | Cor2 &= ~COR2_RTSFLOW; | 329 | Cor2 &= ~RIOC_COR2_RTSFLOW; |
330 | } | 330 | } |
331 | 331 | ||
332 | 332 | ||
@@ -341,36 +341,36 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
341 | */ | 341 | */ |
342 | if (TtyP->termios->c_iflag & IGNBRK) { | 342 | if (TtyP->termios->c_iflag & IGNBRK) { |
343 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); | 343 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); |
344 | Cor4 |= COR4_IGNBRK; | 344 | Cor4 |= RIOC_COR4_IGNBRK; |
345 | } | 345 | } |
346 | if (!(TtyP->termios->c_iflag & BRKINT)) { | 346 | if (!(TtyP->termios->c_iflag & BRKINT)) { |
347 | rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); | 347 | rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); |
348 | Cor4 |= COR4_NBRKINT; | 348 | Cor4 |= RIOC_COR4_NBRKINT; |
349 | } else { | 349 | } else { |
350 | rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); | 350 | rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); |
351 | } | 351 | } |
352 | 352 | ||
353 | if (TtyP->termios->c_iflag & INLCR) { | 353 | if (TtyP->termios->c_iflag & INLCR) { |
354 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); | 354 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); |
355 | Cor4 |= COR4_INLCR; | 355 | Cor4 |= RIOC_COR4_INLCR; |
356 | } | 356 | } |
357 | 357 | ||
358 | if (TtyP->termios->c_iflag & IGNCR) { | 358 | if (TtyP->termios->c_iflag & IGNCR) { |
359 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); | 359 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); |
360 | Cor4 |= COR4_IGNCR; | 360 | Cor4 |= RIOC_COR4_IGNCR; |
361 | } | 361 | } |
362 | 362 | ||
363 | if (TtyP->termios->c_iflag & ICRNL) { | 363 | if (TtyP->termios->c_iflag & ICRNL) { |
364 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); | 364 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); |
365 | Cor4 |= COR4_ICRNL; | 365 | Cor4 |= RIOC_COR4_ICRNL; |
366 | } | 366 | } |
367 | if (TtyP->termios->c_iflag & IGNPAR) { | 367 | if (TtyP->termios->c_iflag & IGNPAR) { |
368 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); | 368 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); |
369 | Cor4 |= COR4_IGNPAR; | 369 | Cor4 |= RIOC_COR4_IGNPAR; |
370 | } | 370 | } |
371 | if (TtyP->termios->c_iflag & PARMRK) { | 371 | if (TtyP->termios->c_iflag & PARMRK) { |
372 | rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); | 372 | rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); |
373 | Cor4 |= COR4_PARMRK; | 373 | Cor4 |= RIOC_COR4_PARMRK; |
374 | } | 374 | } |
375 | 375 | ||
376 | /* | 376 | /* |
@@ -378,22 +378,22 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
378 | ** on reception of a config packet. | 378 | ** on reception of a config packet. |
379 | ** The download code handles the zero baud condition. | 379 | ** The download code handles the zero baud condition. |
380 | */ | 380 | */ |
381 | Cor4 |= COR4_RAISEMOD; | 381 | Cor4 |= RIOC_COR4_RAISEMOD; |
382 | 382 | ||
383 | /* | 383 | /* |
384 | ** COR 5 | 384 | ** COR 5 |
385 | */ | 385 | */ |
386 | 386 | ||
387 | Cor5 = COR5_CMOE; | 387 | Cor5 = RIOC_COR5_CMOE; |
388 | 388 | ||
389 | /* | 389 | /* |
390 | ** Set to monitor tbusy/tstop (or not). | 390 | ** Set to monitor tbusy/tstop (or not). |
391 | */ | 391 | */ |
392 | 392 | ||
393 | if (PortP->MonitorTstate) | 393 | if (PortP->MonitorTstate) |
394 | Cor5 |= COR5_TSTATE_ON; | 394 | Cor5 |= RIOC_COR5_TSTATE_ON; |
395 | else | 395 | else |
396 | Cor5 |= COR5_TSTATE_OFF; | 396 | Cor5 |= RIOC_COR5_TSTATE_OFF; |
397 | 397 | ||
398 | /* | 398 | /* |
399 | ** Could set LNE here if you wanted LNext processing. SVR4 will use it. | 399 | ** Could set LNE here if you wanted LNext processing. SVR4 will use it. |
@@ -401,24 +401,24 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | |||
401 | if (TtyP->termios->c_iflag & ISTRIP) { | 401 | if (TtyP->termios->c_iflag & ISTRIP) { |
402 | rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); | 402 | rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); |
403 | if (!(PortP->State & RIO_TRIAD_MODE)) { | 403 | if (!(PortP->State & RIO_TRIAD_MODE)) { |
404 | Cor5 |= COR5_ISTRIP; | 404 | Cor5 |= RIOC_COR5_ISTRIP; |
405 | } | 405 | } |
406 | } | 406 | } |
407 | 407 | ||
408 | if (TtyP->termios->c_oflag & ONLCR) { | 408 | if (TtyP->termios->c_oflag & ONLCR) { |
409 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); | 409 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); |
410 | if (PortP->CookMode == COOK_MEDIUM) | 410 | if (PortP->CookMode == COOK_MEDIUM) |
411 | Cor5 |= COR5_ONLCR; | 411 | Cor5 |= RIOC_COR5_ONLCR; |
412 | } | 412 | } |
413 | if (TtyP->termios->c_oflag & OCRNL) { | 413 | if (TtyP->termios->c_oflag & OCRNL) { |
414 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); | 414 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); |
415 | if (PortP->CookMode == COOK_MEDIUM) | 415 | if (PortP->CookMode == COOK_MEDIUM) |
416 | Cor5 |= COR5_OCRNL; | 416 | Cor5 |= RIOC_COR5_OCRNL; |
417 | } | 417 | } |
418 | if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { | 418 | if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { |
419 | rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); | 419 | rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); |
420 | if (PortP->CookMode == COOK_MEDIUM) | 420 | if (PortP->CookMode == COOK_MEDIUM) |
421 | Cor5 |= COR5_TAB3; | 421 | Cor5 |= RIOC_COR5_TAB3; |
422 | } | 422 | } |
423 | 423 | ||
424 | /* | 424 | /* |
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c index 1cb8580a161d..c99354843be1 100644 --- a/drivers/char/rio/riotty.c +++ b/drivers/char/rio/riotty.c | |||
@@ -211,7 +211,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) | |||
211 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); | 211 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); |
212 | if (repeat_this-- <= 0) { | 212 | if (repeat_this-- <= 0) { |
213 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); | 213 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); |
214 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 214 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
215 | retval = -EINTR; | 215 | retval = -EINTR; |
216 | goto bombout; | 216 | goto bombout; |
217 | } | 217 | } |
@@ -264,7 +264,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) | |||
264 | here. If I read the docs correctly the "open" | 264 | here. If I read the docs correctly the "open" |
265 | command piggybacks the parameters immediately. | 265 | command piggybacks the parameters immediately. |
266 | -- REW */ | 266 | -- REW */ |
267 | RIOParam(PortP, OPEN, 1, OK_TO_SLEEP); /* Open the port */ | 267 | RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */ |
268 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 268 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
269 | 269 | ||
270 | /* | 270 | /* |
@@ -275,7 +275,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) | |||
275 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 275 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
276 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | 276 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { |
277 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); | 277 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); |
278 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 278 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
279 | func_exit(); | 279 | func_exit(); |
280 | return -EINTR; | 280 | return -EINTR; |
281 | } | 281 | } |
@@ -297,7 +297,8 @@ int riotopen(struct tty_struct *tty, struct file *filp) | |||
297 | ** insert test for carrier here. -- ??? | 297 | ** insert test for carrier here. -- ??? |
298 | ** I already see that test here. What's the deal? -- REW | 298 | ** I already see that test here. What's the deal? -- REW |
299 | */ | 299 | */ |
300 | if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD)) { | 300 | if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || |
301 | (PortP->ModemState & RIOC_MSVR1_CD)) { | ||
301 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); | 302 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); |
302 | /* | 303 | /* |
303 | tp->tm.c_state |= CARR_ON; | 304 | tp->tm.c_state |= CARR_ON; |
@@ -325,7 +326,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) | |||
325 | ** I think it's OK. -- REW | 326 | ** I think it's OK. -- REW |
326 | */ | 327 | */ |
327 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); | 328 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); |
328 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 329 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
329 | /* | 330 | /* |
330 | tp->tm.c_state &= ~WOPEN; | 331 | tp->tm.c_state &= ~WOPEN; |
331 | */ | 332 | */ |
@@ -416,7 +417,7 @@ int riotclose(void *ptr) | |||
416 | */ | 417 | */ |
417 | PortP->State &= ~RIO_MOPEN; | 418 | PortP->State &= ~RIO_MOPEN; |
418 | PortP->State &= ~RIO_CARR_ON; | 419 | PortP->State &= ~RIO_CARR_ON; |
419 | PortP->ModemState &= ~MSVR1_CD; | 420 | PortP->ModemState &= ~RIOC_MSVR1_CD; |
420 | /* | 421 | /* |
421 | ** If the device was open as both a Modem and a tty line | 422 | ** If the device was open as both a Modem and a tty line |
422 | ** then we need to wimp out here, as the port has not really | 423 | ** then we need to wimp out here, as the port has not really |
@@ -453,7 +454,7 @@ int riotclose(void *ptr) | |||
453 | if (repeat_this-- <= 0) { | 454 | if (repeat_this-- <= 0) { |
454 | rv = -EINTR; | 455 | rv = -EINTR; |
455 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); | 456 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); |
456 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 457 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
457 | goto close_end; | 458 | goto close_end; |
458 | } | 459 | } |
459 | rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); | 460 | rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); |
@@ -492,8 +493,8 @@ int riotclose(void *ptr) | |||
492 | /* Can't call RIOShortCommand with the port locked. */ | 493 | /* Can't call RIOShortCommand with the port locked. */ |
493 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 494 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
494 | 495 | ||
495 | if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { | 496 | if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) { |
496 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 497 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
497 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 498 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
498 | goto close_end; | 499 | goto close_end; |
499 | } | 500 | } |
@@ -503,7 +504,7 @@ int riotclose(void *ptr) | |||
503 | try--; | 504 | try--; |
504 | if (time_after(jiffies, end_time)) { | 505 | if (time_after(jiffies, end_time)) { |
505 | rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); | 506 | rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); |
506 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 507 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
507 | break; | 508 | break; |
508 | } | 509 | } |
509 | rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); | 510 | rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); |
@@ -515,14 +516,14 @@ int riotclose(void *ptr) | |||
515 | } | 516 | } |
516 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | 517 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { |
517 | rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); | 518 | rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); |
518 | RIOPreemptiveCmd(p, PortP, FCLOSE); | 519 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); |
519 | break; | 520 | break; |
520 | } | 521 | } |
521 | } | 522 | } |
522 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 523 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
523 | rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); | 524 | rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); |
524 | 525 | ||
525 | /* RIOPreemptiveCmd(p, PortP, FCLOSE); */ | 526 | /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */ |
526 | 527 | ||
527 | /* | 528 | /* |
528 | ** 15.10.1998 ARG - ESIL 0761 part fix | 529 | ** 15.10.1998 ARG - ESIL 0761 part fix |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 3f9d0a9ac36d..f073c710ab8d 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) | 4 | * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) |
5 | * | 5 | * |
6 | * This code is loosely based on the Linux serial driver, written by | 6 | * This code is loosely based on the Linux serial driver, written by |
7 | * Linus Torvalds, Theodore T'so and others. The RISCom/8 card | 7 | * Linus Torvalds, Theodore T'so and others. The RISCom/8 card |
8 | * programming info was obtained from various drivers for other OSes | 8 | * programming info was obtained from various drivers for other OSes |
9 | * (FreeBSD, ISC, etc), but no source code from those drivers were | 9 | * (FreeBSD, ISC, etc), but no source code from those drivers were |
10 | * directly included in this driver. | 10 | * directly included in this driver. |
11 | * | 11 | * |
12 | * | 12 | * |
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | 35 | ||
36 | #include <asm/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
@@ -49,7 +49,7 @@ | |||
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
51 | 51 | ||
52 | #include <asm/uaccess.h> | 52 | #include <linux/uaccess.h> |
53 | 53 | ||
54 | #include "riscom8.h" | 54 | #include "riscom8.h" |
55 | #include "riscom8_reg.h" | 55 | #include "riscom8_reg.h" |
@@ -57,15 +57,15 @@ | |||
57 | /* Am I paranoid or not ? ;-) */ | 57 | /* Am I paranoid or not ? ;-) */ |
58 | #define RISCOM_PARANOIA_CHECK | 58 | #define RISCOM_PARANOIA_CHECK |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals. | 61 | * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals. |
62 | * You can slightly speed up things by #undefing the following option, | 62 | * You can slightly speed up things by #undefing the following option, |
63 | * if you are REALLY sure that your board is correct one. | 63 | * if you are REALLY sure that your board is correct one. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | #define RISCOM_BRAIN_DAMAGED_CTS | 66 | #define RISCOM_BRAIN_DAMAGED_CTS |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * The following defines are mostly for testing purposes. But if you need | 69 | * The following defines are mostly for testing purposes. But if you need |
70 | * some nice reporting in your syslog, you can define them also. | 70 | * some nice reporting in your syslog, you can define them also. |
71 | */ | 71 | */ |
@@ -112,7 +112,7 @@ static unsigned short rc_ioport[] = { | |||
112 | #define RC_NIOPORT ARRAY_SIZE(rc_ioport) | 112 | #define RC_NIOPORT ARRAY_SIZE(rc_ioport) |
113 | 113 | ||
114 | 114 | ||
115 | static inline int rc_paranoia_check(struct riscom_port const * port, | 115 | static int rc_paranoia_check(struct riscom_port const *port, |
116 | char *name, const char *routine) | 116 | char *name, const char *routine) |
117 | { | 117 | { |
118 | #ifdef RISCOM_PARANOIA_CHECK | 118 | #ifdef RISCOM_PARANOIA_CHECK |
@@ -134,52 +134,53 @@ static inline int rc_paranoia_check(struct riscom_port const * port, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /* | 136 | /* |
137 | * | 137 | * |
138 | * Service functions for RISCom/8 driver. | 138 | * Service functions for RISCom/8 driver. |
139 | * | 139 | * |
140 | */ | 140 | */ |
141 | 141 | ||
142 | /* Get board number from pointer */ | 142 | /* Get board number from pointer */ |
143 | static inline int board_No (struct riscom_board const * bp) | 143 | static inline int board_No(struct riscom_board const *bp) |
144 | { | 144 | { |
145 | return bp - rc_board; | 145 | return bp - rc_board; |
146 | } | 146 | } |
147 | 147 | ||
148 | /* Get port number from pointer */ | 148 | /* Get port number from pointer */ |
149 | static inline int port_No (struct riscom_port const * port) | 149 | static inline int port_No(struct riscom_port const *port) |
150 | { | 150 | { |
151 | return RC_PORT(port - rc_port); | 151 | return RC_PORT(port - rc_port); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* Get pointer to board from pointer to port */ | 154 | /* Get pointer to board from pointer to port */ |
155 | static inline struct riscom_board * port_Board(struct riscom_port const * port) | 155 | static inline struct riscom_board *port_Board(struct riscom_port const *port) |
156 | { | 156 | { |
157 | return &rc_board[RC_BOARD(port - rc_port)]; | 157 | return &rc_board[RC_BOARD(port - rc_port)]; |
158 | } | 158 | } |
159 | 159 | ||
160 | /* Input Byte from CL CD180 register */ | 160 | /* Input Byte from CL CD180 register */ |
161 | static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg) | 161 | static inline unsigned char rc_in(struct riscom_board const *bp, |
162 | unsigned short reg) | ||
162 | { | 163 | { |
163 | return inb(bp->base + RC_TO_ISA(reg)); | 164 | return inb(bp->base + RC_TO_ISA(reg)); |
164 | } | 165 | } |
165 | 166 | ||
166 | /* Output Byte to CL CD180 register */ | 167 | /* Output Byte to CL CD180 register */ |
167 | static inline void rc_out(struct riscom_board const * bp, unsigned short reg, | 168 | static inline void rc_out(struct riscom_board const *bp, unsigned short reg, |
168 | unsigned char val) | 169 | unsigned char val) |
169 | { | 170 | { |
170 | outb(val, bp->base + RC_TO_ISA(reg)); | 171 | outb(val, bp->base + RC_TO_ISA(reg)); |
171 | } | 172 | } |
172 | 173 | ||
173 | /* Wait for Channel Command Register ready */ | 174 | /* Wait for Channel Command Register ready */ |
174 | static inline void rc_wait_CCR(struct riscom_board const * bp) | 175 | static void rc_wait_CCR(struct riscom_board const *bp) |
175 | { | 176 | { |
176 | unsigned long delay; | 177 | unsigned long delay; |
177 | 178 | ||
178 | /* FIXME: need something more descriptive then 100000 :) */ | 179 | /* FIXME: need something more descriptive then 100000 :) */ |
179 | for (delay = 100000; delay; delay--) | 180 | for (delay = 100000; delay; delay--) |
180 | if (!rc_in(bp, CD180_CCR)) | 181 | if (!rc_in(bp, CD180_CCR)) |
181 | return; | 182 | return; |
182 | 183 | ||
183 | printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); | 184 | printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); |
184 | } | 185 | } |
185 | 186 | ||
@@ -187,11 +188,11 @@ static inline void rc_wait_CCR(struct riscom_board const * bp) | |||
187 | * RISCom/8 probe functions. | 188 | * RISCom/8 probe functions. |
188 | */ | 189 | */ |
189 | 190 | ||
190 | static inline int rc_request_io_range(struct riscom_board * const bp) | 191 | static int rc_request_io_range(struct riscom_board * const bp) |
191 | { | 192 | { |
192 | int i; | 193 | int i; |
193 | 194 | ||
194 | for (i = 0; i < RC_NIOPORT; i++) | 195 | for (i = 0; i < RC_NIOPORT; i++) |
195 | if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, | 196 | if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, |
196 | "RISCom/8")) { | 197 | "RISCom/8")) { |
197 | goto out_release; | 198 | goto out_release; |
@@ -200,42 +201,42 @@ static inline int rc_request_io_range(struct riscom_board * const bp) | |||
200 | out_release: | 201 | out_release: |
201 | printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", | 202 | printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", |
202 | board_No(bp), bp->base); | 203 | board_No(bp), bp->base); |
203 | while(--i >= 0) | 204 | while (--i >= 0) |
204 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); | 205 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); |
205 | return 1; | 206 | return 1; |
206 | } | 207 | } |
207 | 208 | ||
208 | static inline void rc_release_io_range(struct riscom_board * const bp) | 209 | static void rc_release_io_range(struct riscom_board * const bp) |
209 | { | 210 | { |
210 | int i; | 211 | int i; |
211 | 212 | ||
212 | for (i = 0; i < RC_NIOPORT; i++) | 213 | for (i = 0; i < RC_NIOPORT; i++) |
213 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); | 214 | release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); |
214 | } | 215 | } |
215 | 216 | ||
216 | /* Reset and setup CD180 chip */ | 217 | /* Reset and setup CD180 chip */ |
217 | static void __init rc_init_CD180(struct riscom_board const * bp) | 218 | static void __init rc_init_CD180(struct riscom_board const *bp) |
218 | { | 219 | { |
219 | unsigned long flags; | 220 | unsigned long flags; |
220 | 221 | ||
221 | spin_lock_irqsave(&riscom_lock, flags); | 222 | spin_lock_irqsave(&riscom_lock, flags); |
222 | 223 | ||
223 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ | 224 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ |
224 | rc_wait_CCR(bp); /* Wait for CCR ready */ | 225 | rc_wait_CCR(bp); /* Wait for CCR ready */ |
225 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ | 226 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ |
226 | spin_unlock_irqrestore(&riscom_lock, flags); | 227 | spin_unlock_irqrestore(&riscom_lock, flags); |
227 | msleep(50); /* Delay 0.05 sec */ | 228 | msleep(50); /* Delay 0.05 sec */ |
228 | spin_lock_irqsave(&riscom_lock, flags); | 229 | spin_lock_irqsave(&riscom_lock, flags); |
229 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ | 230 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ |
230 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ | 231 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ |
231 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ | 232 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ |
232 | rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for transmitter intr */ | 233 | rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */ |
233 | rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for receiver intr */ | 234 | rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */ |
234 | 235 | ||
235 | /* Setting up prescaler. We need 4 ticks per 1 ms */ | 236 | /* Setting up prescaler. We need 4 ticks per 1 ms */ |
236 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); | 237 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); |
237 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); | 238 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); |
238 | 239 | ||
239 | spin_unlock_irqrestore(&riscom_lock, flags); | 240 | spin_unlock_irqrestore(&riscom_lock, flags); |
240 | } | 241 | } |
241 | 242 | ||
@@ -245,12 +246,12 @@ static int __init rc_probe(struct riscom_board *bp) | |||
245 | unsigned char val1, val2; | 246 | unsigned char val1, val2; |
246 | int irqs = 0; | 247 | int irqs = 0; |
247 | int retries; | 248 | int retries; |
248 | 249 | ||
249 | bp->irq = 0; | 250 | bp->irq = 0; |
250 | 251 | ||
251 | if (rc_request_io_range(bp)) | 252 | if (rc_request_io_range(bp)) |
252 | return 1; | 253 | return 1; |
253 | 254 | ||
254 | /* Are the I/O ports here ? */ | 255 | /* Are the I/O ports here ? */ |
255 | rc_out(bp, CD180_PPRL, 0x5a); | 256 | rc_out(bp, CD180_PPRL, 0x5a); |
256 | outb(0xff, 0x80); | 257 | outb(0xff, 0x80); |
@@ -258,34 +259,34 @@ static int __init rc_probe(struct riscom_board *bp) | |||
258 | rc_out(bp, CD180_PPRL, 0xa5); | 259 | rc_out(bp, CD180_PPRL, 0xa5); |
259 | outb(0x00, 0x80); | 260 | outb(0x00, 0x80); |
260 | val2 = rc_in(bp, CD180_PPRL); | 261 | val2 = rc_in(bp, CD180_PPRL); |
261 | 262 | ||
262 | if ((val1 != 0x5a) || (val2 != 0xa5)) { | 263 | if ((val1 != 0x5a) || (val2 != 0xa5)) { |
263 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", | 264 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", |
264 | board_No(bp), bp->base); | 265 | board_No(bp), bp->base); |
265 | goto out_release; | 266 | goto out_release; |
266 | } | 267 | } |
267 | 268 | ||
268 | /* It's time to find IRQ for this board */ | 269 | /* It's time to find IRQ for this board */ |
269 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { | 270 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { |
270 | irqs = probe_irq_on(); | 271 | irqs = probe_irq_on(); |
271 | rc_init_CD180(bp); /* Reset CD180 chip */ | 272 | rc_init_CD180(bp); /* Reset CD180 chip */ |
272 | rc_out(bp, CD180_CAR, 2); /* Select port 2 */ | 273 | rc_out(bp, CD180_CAR, 2); /* Select port 2 */ |
273 | rc_wait_CCR(bp); | 274 | rc_wait_CCR(bp); |
274 | rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ | 275 | rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ |
275 | rc_out(bp, CD180_IER, IER_TXRDY); /* Enable tx empty intr */ | 276 | rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */ |
276 | msleep(50); | 277 | msleep(50); |
277 | irqs = probe_irq_off(irqs); | 278 | irqs = probe_irq_off(irqs); |
278 | val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ | 279 | val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ |
279 | val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ | 280 | val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ |
280 | rc_init_CD180(bp); /* Reset CD180 again */ | 281 | rc_init_CD180(bp); /* Reset CD180 again */ |
281 | 282 | ||
282 | if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { | 283 | if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { |
283 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " | 284 | printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " |
284 | "found.\n", board_No(bp), bp->base); | 285 | "found.\n", board_No(bp), bp->base); |
285 | goto out_release; | 286 | goto out_release; |
286 | } | 287 | } |
287 | } | 288 | } |
288 | 289 | ||
289 | if (irqs <= 0) { | 290 | if (irqs <= 0) { |
290 | printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " | 291 | printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " |
291 | "at 0x%03x.\n", board_No(bp), bp->base); | 292 | "at 0x%03x.\n", board_No(bp), bp->base); |
@@ -293,113 +294,112 @@ static int __init rc_probe(struct riscom_board *bp) | |||
293 | } | 294 | } |
294 | bp->irq = irqs; | 295 | bp->irq = irqs; |
295 | bp->flags |= RC_BOARD_PRESENT; | 296 | bp->flags |= RC_BOARD_PRESENT; |
296 | 297 | ||
297 | printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " | 298 | printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " |
298 | "0x%03x, IRQ %d.\n", | 299 | "0x%03x, IRQ %d.\n", |
299 | board_No(bp), | 300 | board_No(bp), |
300 | (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ | 301 | (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ |
301 | bp->base, bp->irq); | 302 | bp->base, bp->irq); |
302 | 303 | ||
303 | return 0; | 304 | return 0; |
304 | out_release: | 305 | out_release: |
305 | rc_release_io_range(bp); | 306 | rc_release_io_range(bp); |
306 | return 1; | 307 | return 1; |
307 | } | 308 | } |
308 | 309 | ||
309 | /* | 310 | /* |
310 | * | 311 | * |
311 | * Interrupt processing routines. | 312 | * Interrupt processing routines. |
312 | * | 313 | * |
313 | */ | 314 | */ |
314 | 315 | ||
315 | static inline struct riscom_port * rc_get_port(struct riscom_board const * bp, | 316 | static struct riscom_port *rc_get_port(struct riscom_board const *bp, |
316 | unsigned char const * what) | 317 | unsigned char const *what) |
317 | { | 318 | { |
318 | unsigned char channel; | 319 | unsigned char channel; |
319 | struct riscom_port * port; | 320 | struct riscom_port *port; |
320 | 321 | ||
321 | channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; | 322 | channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; |
322 | if (channel < CD180_NCH) { | 323 | if (channel < CD180_NCH) { |
323 | port = &rc_port[board_No(bp) * RC_NPORT + channel]; | 324 | port = &rc_port[board_No(bp) * RC_NPORT + channel]; |
324 | if (port->flags & ASYNC_INITIALIZED) { | 325 | if (port->flags & ASYNC_INITIALIZED) |
325 | return port; | 326 | return port; |
326 | } | ||
327 | } | 327 | } |
328 | printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", | 328 | printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", |
329 | board_No(bp), what, channel); | 329 | board_No(bp), what, channel); |
330 | return NULL; | 330 | return NULL; |
331 | } | 331 | } |
332 | 332 | ||
333 | static inline void rc_receive_exc(struct riscom_board const * bp) | 333 | static void rc_receive_exc(struct riscom_board const *bp) |
334 | { | 334 | { |
335 | struct riscom_port *port; | 335 | struct riscom_port *port; |
336 | struct tty_struct *tty; | 336 | struct tty_struct *tty; |
337 | unsigned char status; | 337 | unsigned char status; |
338 | unsigned char ch, flag; | 338 | unsigned char ch, flag; |
339 | 339 | ||
340 | if (!(port = rc_get_port(bp, "Receive"))) | 340 | port = rc_get_port(bp, "Receive"); |
341 | if (port == NULL) | ||
341 | return; | 342 | return; |
342 | 343 | ||
343 | tty = port->tty; | 344 | tty = port->tty; |
344 | 345 | ||
345 | #ifdef RC_REPORT_OVERRUN | 346 | #ifdef RC_REPORT_OVERRUN |
346 | status = rc_in(bp, CD180_RCSR); | 347 | status = rc_in(bp, CD180_RCSR); |
347 | if (status & RCSR_OE) | 348 | if (status & RCSR_OE) |
348 | port->overrun++; | 349 | port->overrun++; |
349 | status &= port->mark_mask; | 350 | status &= port->mark_mask; |
350 | #else | 351 | #else |
351 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; | 352 | status = rc_in(bp, CD180_RCSR) & port->mark_mask; |
352 | #endif | 353 | #endif |
353 | ch = rc_in(bp, CD180_RDR); | 354 | ch = rc_in(bp, CD180_RDR); |
354 | if (!status) { | 355 | if (!status) |
355 | return; | 356 | return; |
356 | } | ||
357 | if (status & RCSR_TOUT) { | 357 | if (status & RCSR_TOUT) { |
358 | printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " | 358 | printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " |
359 | "Hardware problems ?\n", | 359 | "Hardware problems ?\n", |
360 | board_No(bp), port_No(port)); | 360 | board_No(bp), port_No(port)); |
361 | return; | 361 | return; |
362 | 362 | ||
363 | } else if (status & RCSR_BREAK) { | 363 | } else if (status & RCSR_BREAK) { |
364 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", | 364 | printk(KERN_INFO "rc%d: port %d: Handling break...\n", |
365 | board_No(bp), port_No(port)); | 365 | board_No(bp), port_No(port)); |
366 | flag = TTY_BREAK; | 366 | flag = TTY_BREAK; |
367 | if (port->flags & ASYNC_SAK) | 367 | if (port->flags & ASYNC_SAK) |
368 | do_SAK(tty); | 368 | do_SAK(tty); |
369 | 369 | ||
370 | } else if (status & RCSR_PE) | 370 | } else if (status & RCSR_PE) |
371 | flag = TTY_PARITY; | 371 | flag = TTY_PARITY; |
372 | 372 | ||
373 | else if (status & RCSR_FE) | 373 | else if (status & RCSR_FE) |
374 | flag = TTY_FRAME; | 374 | flag = TTY_FRAME; |
375 | 375 | ||
376 | else if (status & RCSR_OE) | 376 | else if (status & RCSR_OE) |
377 | flag = TTY_OVERRUN; | 377 | flag = TTY_OVERRUN; |
378 | |||
379 | else | 378 | else |
380 | flag = TTY_NORMAL; | 379 | flag = TTY_NORMAL; |
381 | 380 | ||
382 | tty_insert_flip_char(tty, ch, flag); | 381 | tty_insert_flip_char(tty, ch, flag); |
383 | tty_flip_buffer_push(tty); | 382 | tty_flip_buffer_push(tty); |
384 | } | 383 | } |
385 | 384 | ||
386 | static inline void rc_receive(struct riscom_board const * bp) | 385 | static void rc_receive(struct riscom_board const *bp) |
387 | { | 386 | { |
388 | struct riscom_port *port; | 387 | struct riscom_port *port; |
389 | struct tty_struct *tty; | 388 | struct tty_struct *tty; |
390 | unsigned char count; | 389 | unsigned char count; |
391 | 390 | ||
392 | if (!(port = rc_get_port(bp, "Receive"))) | 391 | port = rc_get_port(bp, "Receive"); |
392 | if (port == NULL) | ||
393 | return; | 393 | return; |
394 | 394 | ||
395 | tty = port->tty; | 395 | tty = port->tty; |
396 | 396 | ||
397 | count = rc_in(bp, CD180_RDCR); | 397 | count = rc_in(bp, CD180_RDCR); |
398 | 398 | ||
399 | #ifdef RC_REPORT_FIFO | 399 | #ifdef RC_REPORT_FIFO |
400 | port->hits[count > 8 ? 9 : count]++; | 400 | port->hits[count > 8 ? 9 : count]++; |
401 | #endif | 401 | #endif |
402 | 402 | ||
403 | while (count--) { | 403 | while (count--) { |
404 | if (tty_buffer_request_room(tty, 1) == 0) { | 404 | if (tty_buffer_request_room(tty, 1) == 0) { |
405 | printk(KERN_WARNING "rc%d: port %d: Working around " | 405 | printk(KERN_WARNING "rc%d: port %d: Working around " |
@@ -412,26 +412,26 @@ static inline void rc_receive(struct riscom_board const * bp) | |||
412 | tty_flip_buffer_push(tty); | 412 | tty_flip_buffer_push(tty); |
413 | } | 413 | } |
414 | 414 | ||
415 | static inline void rc_transmit(struct riscom_board const * bp) | 415 | static void rc_transmit(struct riscom_board const *bp) |
416 | { | 416 | { |
417 | struct riscom_port *port; | 417 | struct riscom_port *port; |
418 | struct tty_struct *tty; | 418 | struct tty_struct *tty; |
419 | unsigned char count; | 419 | unsigned char count; |
420 | 420 | ||
421 | 421 | port = rc_get_port(bp, "Transmit"); | |
422 | if (!(port = rc_get_port(bp, "Transmit"))) | 422 | if (port == NULL) |
423 | return; | 423 | return; |
424 | 424 | ||
425 | tty = port->tty; | 425 | tty = port->tty; |
426 | 426 | ||
427 | if (port->IER & IER_TXEMPTY) { | 427 | if (port->IER & IER_TXEMPTY) { |
428 | /* FIFO drained */ | 428 | /* FIFO drained */ |
429 | rc_out(bp, CD180_CAR, port_No(port)); | 429 | rc_out(bp, CD180_CAR, port_No(port)); |
430 | port->IER &= ~IER_TXEMPTY; | 430 | port->IER &= ~IER_TXEMPTY; |
431 | rc_out(bp, CD180_IER, port->IER); | 431 | rc_out(bp, CD180_IER, port->IER); |
432 | return; | 432 | return; |
433 | } | 433 | } |
434 | 434 | ||
435 | if ((port->xmit_cnt <= 0 && !port->break_length) | 435 | if ((port->xmit_cnt <= 0 && !port->break_length) |
436 | || tty->stopped || tty->hw_stopped) { | 436 | || tty->stopped || tty->hw_stopped) { |
437 | rc_out(bp, CD180_CAR, port_No(port)); | 437 | rc_out(bp, CD180_CAR, port_No(port)); |
@@ -439,7 +439,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
439 | rc_out(bp, CD180_IER, port->IER); | 439 | rc_out(bp, CD180_IER, port->IER); |
440 | return; | 440 | return; |
441 | } | 441 | } |
442 | 442 | ||
443 | if (port->break_length) { | 443 | if (port->break_length) { |
444 | if (port->break_length > 0) { | 444 | if (port->break_length > 0) { |
445 | if (port->COR2 & COR2_ETC) { | 445 | if (port->COR2 & COR2_ETC) { |
@@ -451,7 +451,8 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
451 | rc_out(bp, CD180_TDR, CD180_C_ESC); | 451 | rc_out(bp, CD180_TDR, CD180_C_ESC); |
452 | rc_out(bp, CD180_TDR, CD180_C_DELAY); | 452 | rc_out(bp, CD180_TDR, CD180_C_DELAY); |
453 | rc_out(bp, CD180_TDR, count); | 453 | rc_out(bp, CD180_TDR, count); |
454 | if (!(port->break_length -= count)) | 454 | port->break_length -= count; |
455 | if (port->break_length == 0) | ||
455 | port->break_length--; | 456 | port->break_length--; |
456 | } else { | 457 | } else { |
457 | rc_out(bp, CD180_TDR, CD180_C_ESC); | 458 | rc_out(bp, CD180_TDR, CD180_C_ESC); |
@@ -463,7 +464,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
463 | } | 464 | } |
464 | return; | 465 | return; |
465 | } | 466 | } |
466 | 467 | ||
467 | count = CD180_NFIFO; | 468 | count = CD180_NFIFO; |
468 | do { | 469 | do { |
469 | rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]); | 470 | rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]); |
@@ -471,7 +472,7 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
471 | if (--port->xmit_cnt <= 0) | 472 | if (--port->xmit_cnt <= 0) |
472 | break; | 473 | break; |
473 | } while (--count > 0); | 474 | } while (--count > 0); |
474 | 475 | ||
475 | if (port->xmit_cnt <= 0) { | 476 | if (port->xmit_cnt <= 0) { |
476 | rc_out(bp, CD180_CAR, port_No(port)); | 477 | rc_out(bp, CD180_CAR, port_No(port)); |
477 | port->IER &= ~IER_TXRDY; | 478 | port->IER &= ~IER_TXRDY; |
@@ -481,25 +482,26 @@ static inline void rc_transmit(struct riscom_board const * bp) | |||
481 | tty_wakeup(tty); | 482 | tty_wakeup(tty); |
482 | } | 483 | } |
483 | 484 | ||
484 | static inline void rc_check_modem(struct riscom_board const * bp) | 485 | static void rc_check_modem(struct riscom_board const *bp) |
485 | { | 486 | { |
486 | struct riscom_port *port; | 487 | struct riscom_port *port; |
487 | struct tty_struct *tty; | 488 | struct tty_struct *tty; |
488 | unsigned char mcr; | 489 | unsigned char mcr; |
489 | 490 | ||
490 | if (!(port = rc_get_port(bp, "Modem"))) | 491 | port = rc_get_port(bp, "Modem"); |
492 | if (port == NULL) | ||
491 | return; | 493 | return; |
492 | 494 | ||
493 | tty = port->tty; | 495 | tty = port->tty; |
494 | 496 | ||
495 | mcr = rc_in(bp, CD180_MCR); | 497 | mcr = rc_in(bp, CD180_MCR); |
496 | if (mcr & MCR_CDCHG) { | 498 | if (mcr & MCR_CDCHG) { |
497 | if (rc_in(bp, CD180_MSVR) & MSVR_CD) | 499 | if (rc_in(bp, CD180_MSVR) & MSVR_CD) |
498 | wake_up_interruptible(&port->open_wait); | 500 | wake_up_interruptible(&port->open_wait); |
499 | else | 501 | else |
500 | tty_hangup(tty); | 502 | tty_hangup(tty); |
501 | } | 503 | } |
502 | 504 | ||
503 | #ifdef RISCOM_BRAIN_DAMAGED_CTS | 505 | #ifdef RISCOM_BRAIN_DAMAGED_CTS |
504 | if (mcr & MCR_CTSCHG) { | 506 | if (mcr & MCR_CTSCHG) { |
505 | if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { | 507 | if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { |
@@ -526,13 +528,13 @@ static inline void rc_check_modem(struct riscom_board const * bp) | |||
526 | rc_out(bp, CD180_IER, port->IER); | 528 | rc_out(bp, CD180_IER, port->IER); |
527 | } | 529 | } |
528 | #endif /* RISCOM_BRAIN_DAMAGED_CTS */ | 530 | #endif /* RISCOM_BRAIN_DAMAGED_CTS */ |
529 | 531 | ||
530 | /* Clear change bits */ | 532 | /* Clear change bits */ |
531 | rc_out(bp, CD180_MCR, 0); | 533 | rc_out(bp, CD180_MCR, 0); |
532 | } | 534 | } |
533 | 535 | ||
534 | /* The main interrupt processing routine */ | 536 | /* The main interrupt processing routine */ |
535 | static irqreturn_t rc_interrupt(int dummy, void * dev_id) | 537 | static irqreturn_t rc_interrupt(int dummy, void *dev_id) |
536 | { | 538 | { |
537 | unsigned char status; | 539 | unsigned char status; |
538 | unsigned char ack; | 540 | unsigned char ack; |
@@ -547,13 +549,11 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
547 | (RC_BSR_TOUT | RC_BSR_TINT | | 549 | (RC_BSR_TOUT | RC_BSR_TINT | |
548 | RC_BSR_MINT | RC_BSR_RINT))) { | 550 | RC_BSR_MINT | RC_BSR_RINT))) { |
549 | handled = 1; | 551 | handled = 1; |
550 | if (status & RC_BSR_TOUT) | 552 | if (status & RC_BSR_TOUT) |
551 | printk(KERN_WARNING "rc%d: Got timeout. Hardware " | 553 | printk(KERN_WARNING "rc%d: Got timeout. Hardware " |
552 | "error?\n", board_No(bp)); | 554 | "error?\n", board_No(bp)); |
553 | |||
554 | else if (status & RC_BSR_RINT) { | 555 | else if (status & RC_BSR_RINT) { |
555 | ack = rc_in(bp, RC_ACK_RINT); | 556 | ack = rc_in(bp, RC_ACK_RINT); |
556 | |||
557 | if (ack == (RC_ID | GIVR_IT_RCV)) | 557 | if (ack == (RC_ID | GIVR_IT_RCV)) |
558 | rc_receive(bp); | 558 | rc_receive(bp); |
559 | else if (ack == (RC_ID | GIVR_IT_REXC)) | 559 | else if (ack == (RC_ID | GIVR_IT_REXC)) |
@@ -562,29 +562,23 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
562 | printk(KERN_WARNING "rc%d: Bad receive ack " | 562 | printk(KERN_WARNING "rc%d: Bad receive ack " |
563 | "0x%02x.\n", | 563 | "0x%02x.\n", |
564 | board_No(bp), ack); | 564 | board_No(bp), ack); |
565 | |||
566 | } else if (status & RC_BSR_TINT) { | 565 | } else if (status & RC_BSR_TINT) { |
567 | ack = rc_in(bp, RC_ACK_TINT); | 566 | ack = rc_in(bp, RC_ACK_TINT); |
568 | |||
569 | if (ack == (RC_ID | GIVR_IT_TX)) | 567 | if (ack == (RC_ID | GIVR_IT_TX)) |
570 | rc_transmit(bp); | 568 | rc_transmit(bp); |
571 | else | 569 | else |
572 | printk(KERN_WARNING "rc%d: Bad transmit ack " | 570 | printk(KERN_WARNING "rc%d: Bad transmit ack " |
573 | "0x%02x.\n", | 571 | "0x%02x.\n", |
574 | board_No(bp), ack); | 572 | board_No(bp), ack); |
575 | |||
576 | } else /* if (status & RC_BSR_MINT) */ { | 573 | } else /* if (status & RC_BSR_MINT) */ { |
577 | ack = rc_in(bp, RC_ACK_MINT); | 574 | ack = rc_in(bp, RC_ACK_MINT); |
578 | 575 | if (ack == (RC_ID | GIVR_IT_MODEM)) | |
579 | if (ack == (RC_ID | GIVR_IT_MODEM)) | ||
580 | rc_check_modem(bp); | 576 | rc_check_modem(bp); |
581 | else | 577 | else |
582 | printk(KERN_WARNING "rc%d: Bad modem ack " | 578 | printk(KERN_WARNING "rc%d: Bad modem ack " |
583 | "0x%02x.\n", | 579 | "0x%02x.\n", |
584 | board_No(bp), ack); | 580 | board_No(bp), ack); |
585 | 581 | } | |
586 | } | ||
587 | |||
588 | rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ | 582 | rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ |
589 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ | 583 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ |
590 | } | 584 | } |
@@ -596,24 +590,24 @@ static irqreturn_t rc_interrupt(int dummy, void * dev_id) | |||
596 | */ | 590 | */ |
597 | 591 | ||
598 | /* Called with disabled interrupts */ | 592 | /* Called with disabled interrupts */ |
599 | static int rc_setup_board(struct riscom_board * bp) | 593 | static int rc_setup_board(struct riscom_board *bp) |
600 | { | 594 | { |
601 | int error; | 595 | int error; |
602 | 596 | ||
603 | if (bp->flags & RC_BOARD_ACTIVE) | 597 | if (bp->flags & RC_BOARD_ACTIVE) |
604 | return 0; | 598 | return 0; |
605 | 599 | ||
606 | error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, | 600 | error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, |
607 | "RISCom/8", bp); | 601 | "RISCom/8", bp); |
608 | if (error) | 602 | if (error) |
609 | return error; | 603 | return error; |
610 | 604 | ||
611 | rc_out(bp, RC_CTOUT, 0); /* Just in case */ | 605 | rc_out(bp, RC_CTOUT, 0); /* Just in case */ |
612 | bp->DTR = ~0; | 606 | bp->DTR = ~0; |
613 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ | 607 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ |
614 | 608 | ||
615 | bp->flags |= RC_BOARD_ACTIVE; | 609 | bp->flags |= RC_BOARD_ACTIVE; |
616 | 610 | ||
617 | return 0; | 611 | return 0; |
618 | } | 612 | } |
619 | 613 | ||
@@ -622,40 +616,40 @@ static void rc_shutdown_board(struct riscom_board *bp) | |||
622 | { | 616 | { |
623 | if (!(bp->flags & RC_BOARD_ACTIVE)) | 617 | if (!(bp->flags & RC_BOARD_ACTIVE)) |
624 | return; | 618 | return; |
625 | 619 | ||
626 | bp->flags &= ~RC_BOARD_ACTIVE; | 620 | bp->flags &= ~RC_BOARD_ACTIVE; |
627 | 621 | ||
628 | free_irq(bp->irq, NULL); | 622 | free_irq(bp->irq, NULL); |
629 | 623 | ||
630 | bp->DTR = ~0; | 624 | bp->DTR = ~0; |
631 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ | 625 | rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ |
632 | 626 | ||
633 | } | 627 | } |
634 | 628 | ||
635 | /* | 629 | /* |
636 | * Setting up port characteristics. | 630 | * Setting up port characteristics. |
637 | * Must be called with disabled interrupts | 631 | * Must be called with disabled interrupts |
638 | */ | 632 | */ |
639 | static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | 633 | static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) |
640 | { | 634 | { |
641 | struct tty_struct *tty; | 635 | struct tty_struct *tty = port->tty; |
642 | unsigned long baud; | 636 | unsigned long baud; |
643 | long tmp; | 637 | long tmp; |
644 | unsigned char cor1 = 0, cor3 = 0; | 638 | unsigned char cor1 = 0, cor3 = 0; |
645 | unsigned char mcor1 = 0, mcor2 = 0; | 639 | unsigned char mcor1 = 0, mcor2 = 0; |
646 | 640 | ||
647 | if (!(tty = port->tty) || !tty->termios) | 641 | if (tty == NULL || tty->termios == NULL) |
648 | return; | 642 | return; |
649 | 643 | ||
650 | port->IER = 0; | 644 | port->IER = 0; |
651 | port->COR2 = 0; | 645 | port->COR2 = 0; |
652 | port->MSVR = MSVR_RTS; | 646 | port->MSVR = MSVR_RTS; |
653 | 647 | ||
654 | baud = tty_get_baud_rate(tty); | 648 | baud = tty_get_baud_rate(tty); |
655 | 649 | ||
656 | /* Select port on the board */ | 650 | /* Select port on the board */ |
657 | rc_out(bp, CD180_CAR, port_No(port)); | 651 | rc_out(bp, CD180_CAR, port_No(port)); |
658 | 652 | ||
659 | if (!baud) { | 653 | if (!baud) { |
660 | /* Drop DTR & exit */ | 654 | /* Drop DTR & exit */ |
661 | bp->DTR |= (1u << port_No(port)); | 655 | bp->DTR |= (1u << port_No(port)); |
@@ -666,69 +660,68 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
666 | bp->DTR &= ~(1u << port_No(port)); | 660 | bp->DTR &= ~(1u << port_No(port)); |
667 | rc_out(bp, RC_DTR, bp->DTR); | 661 | rc_out(bp, RC_DTR, bp->DTR); |
668 | } | 662 | } |
669 | 663 | ||
670 | /* | 664 | /* |
671 | * Now we must calculate some speed depended things | 665 | * Now we must calculate some speed depended things |
672 | */ | 666 | */ |
673 | 667 | ||
674 | /* Set baud rate for port */ | 668 | /* Set baud rate for port */ |
675 | tmp = (((RC_OSCFREQ + baud/2) / baud + | 669 | tmp = (((RC_OSCFREQ + baud/2) / baud + |
676 | CD180_TPC/2) / CD180_TPC); | 670 | CD180_TPC/2) / CD180_TPC); |
677 | 671 | ||
678 | rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); | 672 | rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); |
679 | rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); | 673 | rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); |
680 | rc_out(bp, CD180_RBPRL, tmp & 0xff); | 674 | rc_out(bp, CD180_RBPRL, tmp & 0xff); |
681 | rc_out(bp, CD180_TBPRL, tmp & 0xff); | 675 | rc_out(bp, CD180_TBPRL, tmp & 0xff); |
682 | 676 | ||
683 | baud = (baud + 5) / 10; /* Estimated CPS */ | 677 | baud = (baud + 5) / 10; /* Estimated CPS */ |
684 | 678 | ||
685 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | 679 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ |
686 | tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; | 680 | tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; |
687 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? | 681 | port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? |
688 | SERIAL_XMIT_SIZE - 1 : tmp); | 682 | SERIAL_XMIT_SIZE - 1 : tmp); |
689 | 683 | ||
690 | /* Receiver timeout will be transmission time for 1.5 chars */ | 684 | /* Receiver timeout will be transmission time for 1.5 chars */ |
691 | tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; | 685 | tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; |
692 | tmp = (tmp > 0xff) ? 0xff : tmp; | 686 | tmp = (tmp > 0xff) ? 0xff : tmp; |
693 | rc_out(bp, CD180_RTPR, tmp); | 687 | rc_out(bp, CD180_RTPR, tmp); |
694 | 688 | ||
695 | switch (C_CSIZE(tty)) { | 689 | switch (C_CSIZE(tty)) { |
696 | case CS5: | 690 | case CS5: |
697 | cor1 |= COR1_5BITS; | 691 | cor1 |= COR1_5BITS; |
698 | break; | 692 | break; |
699 | case CS6: | 693 | case CS6: |
700 | cor1 |= COR1_6BITS; | 694 | cor1 |= COR1_6BITS; |
701 | break; | 695 | break; |
702 | case CS7: | 696 | case CS7: |
703 | cor1 |= COR1_7BITS; | 697 | cor1 |= COR1_7BITS; |
704 | break; | 698 | break; |
705 | case CS8: | 699 | case CS8: |
706 | cor1 |= COR1_8BITS; | 700 | cor1 |= COR1_8BITS; |
707 | break; | 701 | break; |
708 | } | 702 | } |
709 | 703 | if (C_CSTOPB(tty)) | |
710 | if (C_CSTOPB(tty)) | ||
711 | cor1 |= COR1_2SB; | 704 | cor1 |= COR1_2SB; |
712 | 705 | ||
713 | cor1 |= COR1_IGNORE; | 706 | cor1 |= COR1_IGNORE; |
714 | if (C_PARENB(tty)) { | 707 | if (C_PARENB(tty)) { |
715 | cor1 |= COR1_NORMPAR; | 708 | cor1 |= COR1_NORMPAR; |
716 | if (C_PARODD(tty)) | 709 | if (C_PARODD(tty)) |
717 | cor1 |= COR1_ODDP; | 710 | cor1 |= COR1_ODDP; |
718 | if (I_INPCK(tty)) | 711 | if (I_INPCK(tty)) |
719 | cor1 &= ~COR1_IGNORE; | 712 | cor1 &= ~COR1_IGNORE; |
720 | } | 713 | } |
721 | /* Set marking of some errors */ | 714 | /* Set marking of some errors */ |
722 | port->mark_mask = RCSR_OE | RCSR_TOUT; | 715 | port->mark_mask = RCSR_OE | RCSR_TOUT; |
723 | if (I_INPCK(tty)) | 716 | if (I_INPCK(tty)) |
724 | port->mark_mask |= RCSR_FE | RCSR_PE; | 717 | port->mark_mask |= RCSR_FE | RCSR_PE; |
725 | if (I_BRKINT(tty) || I_PARMRK(tty)) | 718 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
726 | port->mark_mask |= RCSR_BREAK; | 719 | port->mark_mask |= RCSR_BREAK; |
727 | if (I_IGNPAR(tty)) | 720 | if (I_IGNPAR(tty)) |
728 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); | 721 | port->mark_mask &= ~(RCSR_FE | RCSR_PE); |
729 | if (I_IGNBRK(tty)) { | 722 | if (I_IGNBRK(tty)) { |
730 | port->mark_mask &= ~RCSR_BREAK; | 723 | port->mark_mask &= ~RCSR_BREAK; |
731 | if (I_IGNPAR(tty)) | 724 | if (I_IGNPAR(tty)) |
732 | /* Real raw mode. Ignore all */ | 725 | /* Real raw mode. Ignore all */ |
733 | port->mark_mask &= ~RCSR_OE; | 726 | port->mark_mask &= ~RCSR_OE; |
734 | } | 727 | } |
@@ -738,7 +731,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
738 | port->IER |= IER_DSR | IER_CTS; | 731 | port->IER |= IER_DSR | IER_CTS; |
739 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; | 732 | mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; |
740 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; | 733 | mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; |
741 | tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR)); | 734 | tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & |
735 | (MSVR_CTS|MSVR_DSR)); | ||
742 | #else | 736 | #else |
743 | port->COR2 |= COR2_CTSAE; | 737 | port->COR2 |= COR2_CTSAE; |
744 | #endif | 738 | #endif |
@@ -761,13 +755,13 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
761 | mcor1 |= MCOR1_CDZD; | 755 | mcor1 |= MCOR1_CDZD; |
762 | mcor2 |= MCOR2_CDOD; | 756 | mcor2 |= MCOR2_CDOD; |
763 | } | 757 | } |
764 | 758 | ||
765 | if (C_CREAD(tty)) | 759 | if (C_CREAD(tty)) |
766 | /* Enable receiver */ | 760 | /* Enable receiver */ |
767 | port->IER |= IER_RXD; | 761 | port->IER |= IER_RXD; |
768 | 762 | ||
769 | /* Set input FIFO size (1-8 bytes) */ | 763 | /* Set input FIFO size (1-8 bytes) */ |
770 | cor3 |= RISCOM_RXFIFO; | 764 | cor3 |= RISCOM_RXFIFO; |
771 | /* Setting up CD180 channel registers */ | 765 | /* Setting up CD180 channel registers */ |
772 | rc_out(bp, CD180_COR1, cor1); | 766 | rc_out(bp, CD180_COR1, cor1); |
773 | rc_out(bp, CD180_COR2, port->COR2); | 767 | rc_out(bp, CD180_COR2, port->COR2); |
@@ -791,36 +785,30 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) | |||
791 | static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | 785 | static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) |
792 | { | 786 | { |
793 | unsigned long flags; | 787 | unsigned long flags; |
794 | 788 | ||
795 | if (port->flags & ASYNC_INITIALIZED) | 789 | if (port->flags & ASYNC_INITIALIZED) |
796 | return 0; | 790 | return 0; |
797 | 791 | ||
798 | if (!port->xmit_buf) { | 792 | if (!port->xmit_buf) { |
799 | /* We may sleep in get_zeroed_page() */ | 793 | /* We may sleep in get_zeroed_page() */ |
800 | unsigned long tmp; | 794 | unsigned long tmp = get_zeroed_page(GFP_KERNEL); |
801 | 795 | if (tmp == 0) | |
802 | if (!(tmp = get_zeroed_page(GFP_KERNEL))) | ||
803 | return -ENOMEM; | 796 | return -ENOMEM; |
804 | 797 | if (port->xmit_buf) | |
805 | if (port->xmit_buf) { | ||
806 | free_page(tmp); | 798 | free_page(tmp); |
807 | return -ERESTARTSYS; | 799 | else |
808 | } | 800 | port->xmit_buf = (unsigned char *) tmp; |
809 | port->xmit_buf = (unsigned char *) tmp; | ||
810 | } | 801 | } |
811 | |||
812 | spin_lock_irqsave(&riscom_lock, flags); | 802 | spin_lock_irqsave(&riscom_lock, flags); |
813 | 803 | ||
814 | if (port->tty) | 804 | if (port->tty) |
815 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 805 | clear_bit(TTY_IO_ERROR, &port->tty->flags); |
816 | 806 | if (port->count == 1) | |
817 | if (port->count == 1) | ||
818 | bp->count++; | 807 | bp->count++; |
819 | |||
820 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 808 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
821 | rc_change_speed(bp, port); | 809 | rc_change_speed(bp, port); |
822 | port->flags |= ASYNC_INITIALIZED; | 810 | port->flags |= ASYNC_INITIALIZED; |
823 | 811 | ||
824 | spin_unlock_irqrestore(&riscom_lock, flags); | 812 | spin_unlock_irqrestore(&riscom_lock, flags); |
825 | return 0; | 813 | return 0; |
826 | } | 814 | } |
@@ -829,38 +817,39 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | |||
829 | static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) | 817 | static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) |
830 | { | 818 | { |
831 | struct tty_struct *tty; | 819 | struct tty_struct *tty; |
832 | 820 | ||
833 | if (!(port->flags & ASYNC_INITIALIZED)) | 821 | if (!(port->flags & ASYNC_INITIALIZED)) |
834 | return; | 822 | return; |
835 | 823 | ||
836 | #ifdef RC_REPORT_OVERRUN | 824 | #ifdef RC_REPORT_OVERRUN |
837 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", | 825 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", |
838 | board_No(bp), port_No(port), port->overrun); | 826 | board_No(bp), port_No(port), port->overrun); |
839 | #endif | 827 | #endif |
840 | #ifdef RC_REPORT_FIFO | 828 | #ifdef RC_REPORT_FIFO |
841 | { | 829 | { |
842 | int i; | 830 | int i; |
843 | 831 | ||
844 | printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", | 832 | printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", |
845 | board_No(bp), port_No(port)); | 833 | board_No(bp), port_No(port)); |
846 | for (i = 0; i < 10; i++) { | 834 | for (i = 0; i < 10; i++) |
847 | printk("%ld ", port->hits[i]); | 835 | printk("%ld ", port->hits[i]); |
848 | } | ||
849 | printk("].\n"); | 836 | printk("].\n"); |
850 | } | 837 | } |
851 | #endif | 838 | #endif |
852 | if (port->xmit_buf) { | 839 | if (port->xmit_buf) { |
853 | free_page((unsigned long) port->xmit_buf); | 840 | free_page((unsigned long) port->xmit_buf); |
854 | port->xmit_buf = NULL; | 841 | port->xmit_buf = NULL; |
855 | } | 842 | } |
856 | 843 | ||
857 | if (!(tty = port->tty) || C_HUPCL(tty)) { | 844 | tty = port->tty; |
845 | |||
846 | if (tty == NULL || C_HUPCL(tty)) { | ||
858 | /* Drop DTR */ | 847 | /* Drop DTR */ |
859 | bp->DTR |= (1u << port_No(port)); | 848 | bp->DTR |= (1u << port_No(port)); |
860 | rc_out(bp, RC_DTR, bp->DTR); | 849 | rc_out(bp, RC_DTR, bp->DTR); |
861 | } | 850 | } |
862 | 851 | ||
863 | /* Select port */ | 852 | /* Select port */ |
864 | rc_out(bp, CD180_CAR, port_No(port)); | 853 | rc_out(bp, CD180_CAR, port_No(port)); |
865 | /* Reset port */ | 854 | /* Reset port */ |
866 | rc_wait_CCR(bp); | 855 | rc_wait_CCR(bp); |
@@ -868,28 +857,26 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) | |||
868 | /* Disable all interrupts from this port */ | 857 | /* Disable all interrupts from this port */ |
869 | port->IER = 0; | 858 | port->IER = 0; |
870 | rc_out(bp, CD180_IER, port->IER); | 859 | rc_out(bp, CD180_IER, port->IER); |
871 | 860 | ||
872 | if (tty) | 861 | if (tty) |
873 | set_bit(TTY_IO_ERROR, &tty->flags); | 862 | set_bit(TTY_IO_ERROR, &tty->flags); |
874 | port->flags &= ~ASYNC_INITIALIZED; | 863 | port->flags &= ~ASYNC_INITIALIZED; |
875 | 864 | ||
876 | if (--bp->count < 0) { | 865 | if (--bp->count < 0) { |
877 | printk(KERN_INFO "rc%d: rc_shutdown_port: " | 866 | printk(KERN_INFO "rc%d: rc_shutdown_port: " |
878 | "bad board count: %d\n", | 867 | "bad board count: %d\n", |
879 | board_No(bp), bp->count); | 868 | board_No(bp), bp->count); |
880 | bp->count = 0; | 869 | bp->count = 0; |
881 | } | 870 | } |
882 | |||
883 | /* | 871 | /* |
884 | * If this is the last opened port on the board | 872 | * If this is the last opened port on the board |
885 | * shutdown whole board | 873 | * shutdown whole board |
886 | */ | 874 | */ |
887 | if (!bp->count) | 875 | if (!bp->count) |
888 | rc_shutdown_board(bp); | 876 | rc_shutdown_board(bp); |
889 | } | 877 | } |
890 | 878 | ||
891 | 879 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | |
892 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | ||
893 | struct riscom_port *port) | 880 | struct riscom_port *port) |
894 | { | 881 | { |
895 | DECLARE_WAITQUEUE(wait, current); | 882 | DECLARE_WAITQUEUE(wait, current); |
@@ -921,7 +908,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
921 | return 0; | 908 | return 0; |
922 | } | 909 | } |
923 | 910 | ||
924 | if (C_CLOCAL(tty)) | 911 | if (C_CLOCAL(tty)) |
925 | do_clocal = 1; | 912 | do_clocal = 1; |
926 | 913 | ||
927 | /* | 914 | /* |
@@ -959,7 +946,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
959 | if (port->flags & ASYNC_HUP_NOTIFY) | 946 | if (port->flags & ASYNC_HUP_NOTIFY) |
960 | retval = -EAGAIN; | 947 | retval = -EAGAIN; |
961 | else | 948 | else |
962 | retval = -ERESTARTSYS; | 949 | retval = -ERESTARTSYS; |
963 | break; | 950 | break; |
964 | } | 951 | } |
965 | if (!(port->flags & ASYNC_CLOSING) && | 952 | if (!(port->flags & ASYNC_CLOSING) && |
@@ -978,50 +965,63 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
978 | port->blocked_open--; | 965 | port->blocked_open--; |
979 | if (retval) | 966 | if (retval) |
980 | return retval; | 967 | return retval; |
981 | 968 | ||
982 | port->flags |= ASYNC_NORMAL_ACTIVE; | 969 | port->flags |= ASYNC_NORMAL_ACTIVE; |
983 | return 0; | 970 | return 0; |
984 | } | 971 | } |
985 | 972 | ||
986 | static int rc_open(struct tty_struct * tty, struct file * filp) | 973 | static int rc_open(struct tty_struct *tty, struct file *filp) |
987 | { | 974 | { |
988 | int board; | 975 | int board; |
989 | int error; | 976 | int error; |
990 | struct riscom_port * port; | 977 | struct riscom_port *port; |
991 | struct riscom_board * bp; | 978 | struct riscom_board *bp; |
992 | 979 | ||
993 | board = RC_BOARD(tty->index); | 980 | board = RC_BOARD(tty->index); |
994 | if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) | 981 | if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) |
995 | return -ENODEV; | 982 | return -ENODEV; |
996 | 983 | ||
997 | bp = &rc_board[board]; | 984 | bp = &rc_board[board]; |
998 | port = rc_port + board * RC_NPORT + RC_PORT(tty->index); | 985 | port = rc_port + board * RC_NPORT + RC_PORT(tty->index); |
999 | if (rc_paranoia_check(port, tty->name, "rc_open")) | 986 | if (rc_paranoia_check(port, tty->name, "rc_open")) |
1000 | return -ENODEV; | 987 | return -ENODEV; |
1001 | 988 | ||
1002 | if ((error = rc_setup_board(bp))) | 989 | error = rc_setup_board(bp); |
990 | if (error) | ||
1003 | return error; | 991 | return error; |
1004 | 992 | ||
1005 | port->count++; | 993 | port->count++; |
1006 | tty->driver_data = port; | 994 | tty->driver_data = port; |
1007 | port->tty = tty; | 995 | port->tty = tty; |
1008 | 996 | ||
1009 | if ((error = rc_setup_port(bp, port))) | 997 | error = rc_setup_port(bp, port); |
1010 | return error; | 998 | if (error == 0) |
1011 | 999 | error = block_til_ready(tty, filp, port); | |
1012 | if ((error = block_til_ready(tty, filp, port))) | 1000 | return error; |
1013 | return error; | ||
1014 | |||
1015 | return 0; | ||
1016 | } | 1001 | } |
1017 | 1002 | ||
1018 | static void rc_close(struct tty_struct * tty, struct file * filp) | 1003 | static void rc_flush_buffer(struct tty_struct *tty) |
1004 | { | ||
1005 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | ||
1006 | unsigned long flags; | ||
1007 | |||
1008 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | ||
1009 | return; | ||
1010 | |||
1011 | spin_lock_irqsave(&riscom_lock, flags); | ||
1012 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1013 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1014 | |||
1015 | tty_wakeup(tty); | ||
1016 | } | ||
1017 | |||
1018 | static void rc_close(struct tty_struct *tty, struct file *filp) | ||
1019 | { | 1019 | { |
1020 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; | 1020 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; |
1021 | struct riscom_board *bp; | 1021 | struct riscom_board *bp; |
1022 | unsigned long flags; | 1022 | unsigned long flags; |
1023 | unsigned long timeout; | 1023 | unsigned long timeout; |
1024 | 1024 | ||
1025 | if (!port || rc_paranoia_check(port, tty->name, "close")) | 1025 | if (!port || rc_paranoia_check(port, tty->name, "close")) |
1026 | return; | 1026 | return; |
1027 | 1027 | ||
@@ -1029,7 +1029,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1029 | 1029 | ||
1030 | if (tty_hung_up_p(filp)) | 1030 | if (tty_hung_up_p(filp)) |
1031 | goto out; | 1031 | goto out; |
1032 | 1032 | ||
1033 | bp = port_Board(port); | 1033 | bp = port_Board(port); |
1034 | if ((tty->count == 1) && (port->count != 1)) { | 1034 | if ((tty->count == 1) && (port->count != 1)) { |
1035 | printk(KERN_INFO "rc%d: rc_close: bad port count;" | 1035 | printk(KERN_INFO "rc%d: rc_close: bad port count;" |
@@ -1047,7 +1047,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1047 | goto out; | 1047 | goto out; |
1048 | port->flags |= ASYNC_CLOSING; | 1048 | port->flags |= ASYNC_CLOSING; |
1049 | /* | 1049 | /* |
1050 | * Now we wait for the transmit buffer to clear; and we notify | 1050 | * Now we wait for the transmit buffer to clear; and we notify |
1051 | * the line discipline to only process XON/XOFF characters. | 1051 | * the line discipline to only process XON/XOFF characters. |
1052 | */ | 1052 | */ |
1053 | tty->closing = 1; | 1053 | tty->closing = 1; |
@@ -1070,24 +1070,22 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1070 | * has completely drained; this is especially | 1070 | * has completely drained; this is especially |
1071 | * important if there is a transmit FIFO! | 1071 | * important if there is a transmit FIFO! |
1072 | */ | 1072 | */ |
1073 | timeout = jiffies+HZ; | 1073 | timeout = jiffies + HZ; |
1074 | while(port->IER & IER_TXEMPTY) { | 1074 | while (port->IER & IER_TXEMPTY) { |
1075 | msleep_interruptible(jiffies_to_msecs(port->timeout)); | 1075 | msleep_interruptible(jiffies_to_msecs(port->timeout)); |
1076 | if (time_after(jiffies, timeout)) | 1076 | if (time_after(jiffies, timeout)) |
1077 | break; | 1077 | break; |
1078 | } | 1078 | } |
1079 | } | 1079 | } |
1080 | rc_shutdown_port(bp, port); | 1080 | rc_shutdown_port(bp, port); |
1081 | if (tty->driver->flush_buffer) | 1081 | rc_flush_buffer(tty); |
1082 | tty->driver->flush_buffer(tty); | ||
1083 | tty_ldisc_flush(tty); | 1082 | tty_ldisc_flush(tty); |
1084 | 1083 | ||
1085 | tty->closing = 0; | 1084 | tty->closing = 0; |
1086 | port->tty = NULL; | 1085 | port->tty = NULL; |
1087 | if (port->blocked_open) { | 1086 | if (port->blocked_open) { |
1088 | if (port->close_delay) { | 1087 | if (port->close_delay) |
1089 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | 1088 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); |
1090 | } | ||
1091 | wake_up_interruptible(&port->open_wait); | 1089 | wake_up_interruptible(&port->open_wait); |
1092 | } | 1090 | } |
1093 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1091 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
@@ -1097,17 +1095,17 @@ out: | |||
1097 | spin_unlock_irqrestore(&riscom_lock, flags); | 1095 | spin_unlock_irqrestore(&riscom_lock, flags); |
1098 | } | 1096 | } |
1099 | 1097 | ||
1100 | static int rc_write(struct tty_struct * tty, | 1098 | static int rc_write(struct tty_struct *tty, |
1101 | const unsigned char *buf, int count) | 1099 | const unsigned char *buf, int count) |
1102 | { | 1100 | { |
1103 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1101 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1104 | struct riscom_board *bp; | 1102 | struct riscom_board *bp; |
1105 | int c, total = 0; | 1103 | int c, total = 0; |
1106 | unsigned long flags; | 1104 | unsigned long flags; |
1107 | 1105 | ||
1108 | if (rc_paranoia_check(port, tty->name, "rc_write")) | 1106 | if (rc_paranoia_check(port, tty->name, "rc_write")) |
1109 | return 0; | 1107 | return 0; |
1110 | 1108 | ||
1111 | bp = port_Board(port); | 1109 | bp = port_Board(port); |
1112 | 1110 | ||
1113 | if (!tty || !port->xmit_buf) | 1111 | if (!tty || !port->xmit_buf) |
@@ -1144,38 +1142,41 @@ static int rc_write(struct tty_struct * tty, | |||
1144 | return total; | 1142 | return total; |
1145 | } | 1143 | } |
1146 | 1144 | ||
1147 | static void rc_put_char(struct tty_struct * tty, unsigned char ch) | 1145 | static int rc_put_char(struct tty_struct *tty, unsigned char ch) |
1148 | { | 1146 | { |
1149 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1147 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1150 | unsigned long flags; | 1148 | unsigned long flags; |
1149 | int ret = 0; | ||
1151 | 1150 | ||
1152 | if (rc_paranoia_check(port, tty->name, "rc_put_char")) | 1151 | if (rc_paranoia_check(port, tty->name, "rc_put_char")) |
1153 | return; | 1152 | return 0; |
1154 | 1153 | ||
1155 | if (!tty || !port->xmit_buf) | 1154 | if (!tty || !port->xmit_buf) |
1156 | return; | 1155 | return 0; |
1157 | 1156 | ||
1158 | spin_lock_irqsave(&riscom_lock, flags); | 1157 | spin_lock_irqsave(&riscom_lock, flags); |
1159 | 1158 | ||
1160 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | 1159 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) |
1161 | goto out; | 1160 | goto out; |
1162 | 1161 | ||
1163 | port->xmit_buf[port->xmit_head++] = ch; | 1162 | port->xmit_buf[port->xmit_head++] = ch; |
1164 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; | 1163 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; |
1165 | port->xmit_cnt++; | 1164 | port->xmit_cnt++; |
1165 | ret = 1; | ||
1166 | 1166 | ||
1167 | out: | 1167 | out: |
1168 | spin_unlock_irqrestore(&riscom_lock, flags); | 1168 | spin_unlock_irqrestore(&riscom_lock, flags); |
1169 | return ret; | ||
1169 | } | 1170 | } |
1170 | 1171 | ||
1171 | static void rc_flush_chars(struct tty_struct * tty) | 1172 | static void rc_flush_chars(struct tty_struct *tty) |
1172 | { | 1173 | { |
1173 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1174 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1174 | unsigned long flags; | 1175 | unsigned long flags; |
1175 | 1176 | ||
1176 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) | 1177 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) |
1177 | return; | 1178 | return; |
1178 | 1179 | ||
1179 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | 1180 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
1180 | !port->xmit_buf) | 1181 | !port->xmit_buf) |
1181 | return; | 1182 | return; |
@@ -1189,11 +1190,11 @@ static void rc_flush_chars(struct tty_struct * tty) | |||
1189 | spin_unlock_irqrestore(&riscom_lock, flags); | 1190 | spin_unlock_irqrestore(&riscom_lock, flags); |
1190 | } | 1191 | } |
1191 | 1192 | ||
1192 | static int rc_write_room(struct tty_struct * tty) | 1193 | static int rc_write_room(struct tty_struct *tty) |
1193 | { | 1194 | { |
1194 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1195 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1195 | int ret; | 1196 | int ret; |
1196 | 1197 | ||
1197 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) | 1198 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) |
1198 | return 0; | 1199 | return 0; |
1199 | 1200 | ||
@@ -1206,39 +1207,22 @@ static int rc_write_room(struct tty_struct * tty) | |||
1206 | static int rc_chars_in_buffer(struct tty_struct *tty) | 1207 | static int rc_chars_in_buffer(struct tty_struct *tty) |
1207 | { | 1208 | { |
1208 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1209 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1209 | 1210 | ||
1210 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) | 1211 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) |
1211 | return 0; | 1212 | return 0; |
1212 | |||
1213 | return port->xmit_cnt; | ||
1214 | } | ||
1215 | |||
1216 | static void rc_flush_buffer(struct tty_struct *tty) | ||
1217 | { | ||
1218 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | ||
1219 | unsigned long flags; | ||
1220 | |||
1221 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | ||
1222 | return; | ||
1223 | |||
1224 | spin_lock_irqsave(&riscom_lock, flags); | ||
1225 | |||
1226 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1227 | 1213 | ||
1228 | spin_unlock_irqrestore(&riscom_lock, flags); | 1214 | return port->xmit_cnt; |
1229 | |||
1230 | tty_wakeup(tty); | ||
1231 | } | 1215 | } |
1232 | 1216 | ||
1233 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) | 1217 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) |
1234 | { | 1218 | { |
1235 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1219 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1236 | struct riscom_board * bp; | 1220 | struct riscom_board *bp; |
1237 | unsigned char status; | 1221 | unsigned char status; |
1238 | unsigned int result; | 1222 | unsigned int result; |
1239 | unsigned long flags; | 1223 | unsigned long flags; |
1240 | 1224 | ||
1241 | if (rc_paranoia_check(port, tty->name, __FUNCTION__)) | 1225 | if (rc_paranoia_check(port, tty->name, __func__)) |
1242 | return -ENODEV; | 1226 | return -ENODEV; |
1243 | 1227 | ||
1244 | bp = port_Board(port); | 1228 | bp = port_Board(port); |
@@ -1266,7 +1250,7 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1266 | unsigned long flags; | 1250 | unsigned long flags; |
1267 | struct riscom_board *bp; | 1251 | struct riscom_board *bp; |
1268 | 1252 | ||
1269 | if (rc_paranoia_check(port, tty->name, __FUNCTION__)) | 1253 | if (rc_paranoia_check(port, tty->name, __func__)) |
1270 | return -ENODEV; | 1254 | return -ENODEV; |
1271 | 1255 | ||
1272 | bp = port_Board(port); | 1256 | bp = port_Board(port); |
@@ -1292,11 +1276,11 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1292 | return 0; | 1276 | return 0; |
1293 | } | 1277 | } |
1294 | 1278 | ||
1295 | static inline void rc_send_break(struct riscom_port * port, unsigned long length) | 1279 | static void rc_send_break(struct riscom_port *port, unsigned long length) |
1296 | { | 1280 | { |
1297 | struct riscom_board *bp = port_Board(port); | 1281 | struct riscom_board *bp = port_Board(port); |
1298 | unsigned long flags; | 1282 | unsigned long flags; |
1299 | 1283 | ||
1300 | spin_lock_irqsave(&riscom_lock, flags); | 1284 | spin_lock_irqsave(&riscom_lock, flags); |
1301 | 1285 | ||
1302 | port->break_length = RISCOM_TPS / HZ * length; | 1286 | port->break_length = RISCOM_TPS / HZ * length; |
@@ -1312,17 +1296,17 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length | |||
1312 | spin_unlock_irqrestore(&riscom_lock, flags); | 1296 | spin_unlock_irqrestore(&riscom_lock, flags); |
1313 | } | 1297 | } |
1314 | 1298 | ||
1315 | static inline int rc_set_serial_info(struct riscom_port * port, | 1299 | static int rc_set_serial_info(struct riscom_port *port, |
1316 | struct serial_struct __user * newinfo) | 1300 | struct serial_struct __user *newinfo) |
1317 | { | 1301 | { |
1318 | struct serial_struct tmp; | 1302 | struct serial_struct tmp; |
1319 | struct riscom_board *bp = port_Board(port); | 1303 | struct riscom_board *bp = port_Board(port); |
1320 | int change_speed; | 1304 | int change_speed; |
1321 | 1305 | ||
1322 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) | 1306 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) |
1323 | return -EFAULT; | 1307 | return -EFAULT; |
1324 | 1308 | ||
1325 | #if 0 | 1309 | #if 0 |
1326 | if ((tmp.irq != bp->irq) || | 1310 | if ((tmp.irq != bp->irq) || |
1327 | (tmp.port != bp->base) || | 1311 | (tmp.port != bp->base) || |
1328 | (tmp.type != PORT_CIRRUS) || | 1312 | (tmp.type != PORT_CIRRUS) || |
@@ -1331,16 +1315,16 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1331 | (tmp.xmit_fifo_size != CD180_NFIFO) || | 1315 | (tmp.xmit_fifo_size != CD180_NFIFO) || |
1332 | (tmp.flags & ~RISCOM_LEGAL_FLAGS)) | 1316 | (tmp.flags & ~RISCOM_LEGAL_FLAGS)) |
1333 | return -EINVAL; | 1317 | return -EINVAL; |
1334 | #endif | 1318 | #endif |
1335 | 1319 | ||
1336 | change_speed = ((port->flags & ASYNC_SPD_MASK) != | 1320 | change_speed = ((port->flags & ASYNC_SPD_MASK) != |
1337 | (tmp.flags & ASYNC_SPD_MASK)); | 1321 | (tmp.flags & ASYNC_SPD_MASK)); |
1338 | 1322 | ||
1339 | if (!capable(CAP_SYS_ADMIN)) { | 1323 | if (!capable(CAP_SYS_ADMIN)) { |
1340 | if ((tmp.close_delay != port->close_delay) || | 1324 | if ((tmp.close_delay != port->close_delay) || |
1341 | (tmp.closing_wait != port->closing_wait) || | 1325 | (tmp.closing_wait != port->closing_wait) || |
1342 | ((tmp.flags & ~ASYNC_USR_MASK) != | 1326 | ((tmp.flags & ~ASYNC_USR_MASK) != |
1343 | (port->flags & ~ASYNC_USR_MASK))) | 1327 | (port->flags & ~ASYNC_USR_MASK))) |
1344 | return -EPERM; | 1328 | return -EPERM; |
1345 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1329 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
1346 | (tmp.flags & ASYNC_USR_MASK)); | 1330 | (tmp.flags & ASYNC_USR_MASK)); |
@@ -1360,12 +1344,12 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1360 | return 0; | 1344 | return 0; |
1361 | } | 1345 | } |
1362 | 1346 | ||
1363 | static inline int rc_get_serial_info(struct riscom_port * port, | 1347 | static int rc_get_serial_info(struct riscom_port *port, |
1364 | struct serial_struct __user *retinfo) | 1348 | struct serial_struct __user *retinfo) |
1365 | { | 1349 | { |
1366 | struct serial_struct tmp; | 1350 | struct serial_struct tmp; |
1367 | struct riscom_board *bp = port_Board(port); | 1351 | struct riscom_board *bp = port_Board(port); |
1368 | 1352 | ||
1369 | memset(&tmp, 0, sizeof(tmp)); | 1353 | memset(&tmp, 0, sizeof(tmp)); |
1370 | tmp.type = PORT_CIRRUS; | 1354 | tmp.type = PORT_CIRRUS; |
1371 | tmp.line = port - rc_port; | 1355 | tmp.line = port - rc_port; |
@@ -1379,19 +1363,18 @@ static inline int rc_get_serial_info(struct riscom_port * port, | |||
1379 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 1363 | return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
1380 | } | 1364 | } |
1381 | 1365 | ||
1382 | static int rc_ioctl(struct tty_struct * tty, struct file * filp, | 1366 | static int rc_ioctl(struct tty_struct *tty, struct file *filp, |
1383 | unsigned int cmd, unsigned long arg) | 1367 | unsigned int cmd, unsigned long arg) |
1384 | |||
1385 | { | 1368 | { |
1386 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1369 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1387 | void __user *argp = (void __user *)arg; | 1370 | void __user *argp = (void __user *)arg; |
1388 | int retval; | 1371 | int retval = 0; |
1389 | 1372 | ||
1390 | if (rc_paranoia_check(port, tty->name, "rc_ioctl")) | 1373 | if (rc_paranoia_check(port, tty->name, "rc_ioctl")) |
1391 | return -ENODEV; | 1374 | return -ENODEV; |
1392 | 1375 | ||
1393 | switch (cmd) { | 1376 | switch (cmd) { |
1394 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 1377 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
1395 | retval = tty_check_change(tty); | 1378 | retval = tty_check_change(tty); |
1396 | if (retval) | 1379 | if (retval) |
1397 | return retval; | 1380 | return retval; |
@@ -1399,45 +1382,40 @@ static int rc_ioctl(struct tty_struct * tty, struct file * filp, | |||
1399 | if (!arg) | 1382 | if (!arg) |
1400 | rc_send_break(port, HZ/4); /* 1/4 second */ | 1383 | rc_send_break(port, HZ/4); /* 1/4 second */ |
1401 | break; | 1384 | break; |
1402 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 1385 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
1403 | retval = tty_check_change(tty); | 1386 | retval = tty_check_change(tty); |
1404 | if (retval) | 1387 | if (retval) |
1405 | return retval; | 1388 | return retval; |
1406 | tty_wait_until_sent(tty, 0); | 1389 | tty_wait_until_sent(tty, 0); |
1407 | rc_send_break(port, arg ? arg*(HZ/10) : HZ/4); | 1390 | rc_send_break(port, arg ? arg*(HZ/10) : HZ/4); |
1408 | break; | 1391 | break; |
1409 | case TIOCGSOFTCAR: | 1392 | case TIOCGSERIAL: |
1410 | return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp); | 1393 | lock_kernel(); |
1411 | case TIOCSSOFTCAR: | 1394 | retval = rc_get_serial_info(port, argp); |
1412 | if (get_user(arg,(unsigned __user *) argp)) | 1395 | unlock_kernel(); |
1413 | return -EFAULT; | ||
1414 | tty->termios->c_cflag = | ||
1415 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
1416 | (arg ? CLOCAL : 0)); | ||
1417 | break; | 1396 | break; |
1418 | case TIOCGSERIAL: | 1397 | case TIOCSSERIAL: |
1419 | return rc_get_serial_info(port, argp); | 1398 | lock_kernel(); |
1420 | case TIOCSSERIAL: | 1399 | retval = rc_set_serial_info(port, argp); |
1421 | return rc_set_serial_info(port, argp); | 1400 | unlock_kernel(); |
1422 | default: | 1401 | break; |
1423 | return -ENOIOCTLCMD; | 1402 | default: |
1403 | retval = -ENOIOCTLCMD; | ||
1424 | } | 1404 | } |
1425 | return 0; | 1405 | return retval; |
1426 | } | 1406 | } |
1427 | 1407 | ||
1428 | static void rc_throttle(struct tty_struct * tty) | 1408 | static void rc_throttle(struct tty_struct *tty) |
1429 | { | 1409 | { |
1430 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1410 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1431 | struct riscom_board *bp; | 1411 | struct riscom_board *bp; |
1432 | unsigned long flags; | 1412 | unsigned long flags; |
1433 | 1413 | ||
1434 | if (rc_paranoia_check(port, tty->name, "rc_throttle")) | 1414 | if (rc_paranoia_check(port, tty->name, "rc_throttle")) |
1435 | return; | 1415 | return; |
1436 | |||
1437 | bp = port_Board(port); | 1416 | bp = port_Board(port); |
1438 | 1417 | ||
1439 | spin_lock_irqsave(&riscom_lock, flags); | 1418 | spin_lock_irqsave(&riscom_lock, flags); |
1440 | |||
1441 | port->MSVR &= ~MSVR_RTS; | 1419 | port->MSVR &= ~MSVR_RTS; |
1442 | rc_out(bp, CD180_CAR, port_No(port)); | 1420 | rc_out(bp, CD180_CAR, port_No(port)); |
1443 | if (I_IXOFF(tty)) { | 1421 | if (I_IXOFF(tty)) { |
@@ -1446,23 +1424,20 @@ static void rc_throttle(struct tty_struct * tty) | |||
1446 | rc_wait_CCR(bp); | 1424 | rc_wait_CCR(bp); |
1447 | } | 1425 | } |
1448 | rc_out(bp, CD180_MSVR, port->MSVR); | 1426 | rc_out(bp, CD180_MSVR, port->MSVR); |
1449 | |||
1450 | spin_unlock_irqrestore(&riscom_lock, flags); | 1427 | spin_unlock_irqrestore(&riscom_lock, flags); |
1451 | } | 1428 | } |
1452 | 1429 | ||
1453 | static void rc_unthrottle(struct tty_struct * tty) | 1430 | static void rc_unthrottle(struct tty_struct *tty) |
1454 | { | 1431 | { |
1455 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1432 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1456 | struct riscom_board *bp; | 1433 | struct riscom_board *bp; |
1457 | unsigned long flags; | 1434 | unsigned long flags; |
1458 | 1435 | ||
1459 | if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) | 1436 | if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) |
1460 | return; | 1437 | return; |
1461 | |||
1462 | bp = port_Board(port); | 1438 | bp = port_Board(port); |
1463 | |||
1464 | spin_lock_irqsave(&riscom_lock, flags); | ||
1465 | 1439 | ||
1440 | spin_lock_irqsave(&riscom_lock, flags); | ||
1466 | port->MSVR |= MSVR_RTS; | 1441 | port->MSVR |= MSVR_RTS; |
1467 | rc_out(bp, CD180_CAR, port_No(port)); | 1442 | rc_out(bp, CD180_CAR, port_No(port)); |
1468 | if (I_IXOFF(tty)) { | 1443 | if (I_IXOFF(tty)) { |
@@ -1471,62 +1446,58 @@ static void rc_unthrottle(struct tty_struct * tty) | |||
1471 | rc_wait_CCR(bp); | 1446 | rc_wait_CCR(bp); |
1472 | } | 1447 | } |
1473 | rc_out(bp, CD180_MSVR, port->MSVR); | 1448 | rc_out(bp, CD180_MSVR, port->MSVR); |
1474 | |||
1475 | spin_unlock_irqrestore(&riscom_lock, flags); | 1449 | spin_unlock_irqrestore(&riscom_lock, flags); |
1476 | } | 1450 | } |
1477 | 1451 | ||
1478 | static void rc_stop(struct tty_struct * tty) | 1452 | static void rc_stop(struct tty_struct *tty) |
1479 | { | 1453 | { |
1480 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1454 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1481 | struct riscom_board *bp; | 1455 | struct riscom_board *bp; |
1482 | unsigned long flags; | 1456 | unsigned long flags; |
1483 | 1457 | ||
1484 | if (rc_paranoia_check(port, tty->name, "rc_stop")) | 1458 | if (rc_paranoia_check(port, tty->name, "rc_stop")) |
1485 | return; | 1459 | return; |
1486 | 1460 | ||
1487 | bp = port_Board(port); | 1461 | bp = port_Board(port); |
1488 | |||
1489 | spin_lock_irqsave(&riscom_lock, flags); | ||
1490 | 1462 | ||
1463 | spin_lock_irqsave(&riscom_lock, flags); | ||
1491 | port->IER &= ~IER_TXRDY; | 1464 | port->IER &= ~IER_TXRDY; |
1492 | rc_out(bp, CD180_CAR, port_No(port)); | 1465 | rc_out(bp, CD180_CAR, port_No(port)); |
1493 | rc_out(bp, CD180_IER, port->IER); | 1466 | rc_out(bp, CD180_IER, port->IER); |
1494 | |||
1495 | spin_unlock_irqrestore(&riscom_lock, flags); | 1467 | spin_unlock_irqrestore(&riscom_lock, flags); |
1496 | } | 1468 | } |
1497 | 1469 | ||
1498 | static void rc_start(struct tty_struct * tty) | 1470 | static void rc_start(struct tty_struct *tty) |
1499 | { | 1471 | { |
1500 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1472 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1501 | struct riscom_board *bp; | 1473 | struct riscom_board *bp; |
1502 | unsigned long flags; | 1474 | unsigned long flags; |
1503 | 1475 | ||
1504 | if (rc_paranoia_check(port, tty->name, "rc_start")) | 1476 | if (rc_paranoia_check(port, tty->name, "rc_start")) |
1505 | return; | 1477 | return; |
1506 | 1478 | ||
1507 | bp = port_Board(port); | 1479 | bp = port_Board(port); |
1508 | 1480 | ||
1509 | spin_lock_irqsave(&riscom_lock, flags); | 1481 | spin_lock_irqsave(&riscom_lock, flags); |
1510 | 1482 | ||
1511 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 1483 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
1512 | port->IER |= IER_TXRDY; | 1484 | port->IER |= IER_TXRDY; |
1513 | rc_out(bp, CD180_CAR, port_No(port)); | 1485 | rc_out(bp, CD180_CAR, port_No(port)); |
1514 | rc_out(bp, CD180_IER, port->IER); | 1486 | rc_out(bp, CD180_IER, port->IER); |
1515 | } | 1487 | } |
1516 | |||
1517 | spin_unlock_irqrestore(&riscom_lock, flags); | 1488 | spin_unlock_irqrestore(&riscom_lock, flags); |
1518 | } | 1489 | } |
1519 | 1490 | ||
1520 | static void rc_hangup(struct tty_struct * tty) | 1491 | static void rc_hangup(struct tty_struct *tty) |
1521 | { | 1492 | { |
1522 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1493 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1523 | struct riscom_board *bp; | 1494 | struct riscom_board *bp; |
1524 | 1495 | ||
1525 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1496 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1526 | return; | 1497 | return; |
1527 | 1498 | ||
1528 | bp = port_Board(port); | 1499 | bp = port_Board(port); |
1529 | 1500 | ||
1530 | rc_shutdown_port(bp, port); | 1501 | rc_shutdown_port(bp, port); |
1531 | port->count = 0; | 1502 | port->count = 0; |
1532 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 1503 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -1534,17 +1505,14 @@ static void rc_hangup(struct tty_struct * tty) | |||
1534 | wake_up_interruptible(&port->open_wait); | 1505 | wake_up_interruptible(&port->open_wait); |
1535 | } | 1506 | } |
1536 | 1507 | ||
1537 | static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios) | 1508 | static void rc_set_termios(struct tty_struct *tty, |
1509 | struct ktermios *old_termios) | ||
1538 | { | 1510 | { |
1539 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1511 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1540 | unsigned long flags; | 1512 | unsigned long flags; |
1541 | 1513 | ||
1542 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) | 1514 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) |
1543 | return; | 1515 | return; |
1544 | |||
1545 | if (tty->termios->c_cflag == old_termios->c_cflag && | ||
1546 | tty->termios->c_iflag == old_termios->c_iflag) | ||
1547 | return; | ||
1548 | 1516 | ||
1549 | spin_lock_irqsave(&riscom_lock, flags); | 1517 | spin_lock_irqsave(&riscom_lock, flags); |
1550 | rc_change_speed(port_Board(port), port); | 1518 | rc_change_speed(port_Board(port), port); |
@@ -1583,9 +1551,9 @@ static int __init rc_init_drivers(void) | |||
1583 | int i; | 1551 | int i; |
1584 | 1552 | ||
1585 | riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); | 1553 | riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); |
1586 | if (!riscom_driver) | 1554 | if (!riscom_driver) |
1587 | return -ENOMEM; | 1555 | return -ENOMEM; |
1588 | 1556 | ||
1589 | riscom_driver->owner = THIS_MODULE; | 1557 | riscom_driver->owner = THIS_MODULE; |
1590 | riscom_driver->name = "ttyL"; | 1558 | riscom_driver->name = "ttyL"; |
1591 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; | 1559 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; |
@@ -1598,23 +1566,21 @@ static int __init rc_init_drivers(void) | |||
1598 | riscom_driver->init_termios.c_ospeed = 9600; | 1566 | riscom_driver->init_termios.c_ospeed = 9600; |
1599 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; | 1567 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; |
1600 | tty_set_operations(riscom_driver, &riscom_ops); | 1568 | tty_set_operations(riscom_driver, &riscom_ops); |
1601 | if ((error = tty_register_driver(riscom_driver))) { | 1569 | error = tty_register_driver(riscom_driver); |
1570 | if (error != 0) { | ||
1602 | put_tty_driver(riscom_driver); | 1571 | put_tty_driver(riscom_driver); |
1603 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " | 1572 | printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " |
1604 | "error = %d\n", | 1573 | "error = %d\n", error); |
1605 | error); | ||
1606 | return 1; | 1574 | return 1; |
1607 | } | 1575 | } |
1608 | |||
1609 | memset(rc_port, 0, sizeof(rc_port)); | 1576 | memset(rc_port, 0, sizeof(rc_port)); |
1610 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { | 1577 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { |
1611 | rc_port[i].magic = RISCOM8_MAGIC; | 1578 | rc_port[i].magic = RISCOM8_MAGIC; |
1612 | rc_port[i].close_delay = 50 * HZ/100; | 1579 | rc_port[i].close_delay = 50 * HZ / 100; |
1613 | rc_port[i].closing_wait = 3000 * HZ/100; | 1580 | rc_port[i].closing_wait = 3000 * HZ / 100; |
1614 | init_waitqueue_head(&rc_port[i].open_wait); | 1581 | init_waitqueue_head(&rc_port[i].open_wait); |
1615 | init_waitqueue_head(&rc_port[i].close_wait); | 1582 | init_waitqueue_head(&rc_port[i].close_wait); |
1616 | } | 1583 | } |
1617 | |||
1618 | return 0; | 1584 | return 0; |
1619 | } | 1585 | } |
1620 | 1586 | ||
@@ -1627,13 +1593,13 @@ static void rc_release_drivers(void) | |||
1627 | #ifndef MODULE | 1593 | #ifndef MODULE |
1628 | /* | 1594 | /* |
1629 | * Called at boot time. | 1595 | * Called at boot time. |
1630 | * | 1596 | * |
1631 | * You can specify IO base for up to RC_NBOARD cards, | 1597 | * You can specify IO base for up to RC_NBOARD cards, |
1632 | * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. | 1598 | * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. |
1633 | * Note that there will be no probing at default | 1599 | * Note that there will be no probing at default |
1634 | * addresses in this case. | 1600 | * addresses in this case. |
1635 | * | 1601 | * |
1636 | */ | 1602 | */ |
1637 | static int __init riscom8_setup(char *str) | 1603 | static int __init riscom8_setup(char *str) |
1638 | { | 1604 | { |
1639 | int ints[RC_NBOARD]; | 1605 | int ints[RC_NBOARD]; |
@@ -1644,7 +1610,7 @@ static int __init riscom8_setup(char *str) | |||
1644 | for (i = 0; i < RC_NBOARD; i++) { | 1610 | for (i = 0; i < RC_NBOARD; i++) { |
1645 | if (i < ints[0]) | 1611 | if (i < ints[0]) |
1646 | rc_board[i].base = ints[i+1]; | 1612 | rc_board[i].base = ints[i+1]; |
1647 | else | 1613 | else |
1648 | rc_board[i].base = 0; | 1614 | rc_board[i].base = 0; |
1649 | } | 1615 | } |
1650 | return 1; | 1616 | return 1; |
@@ -1659,8 +1625,8 @@ static char banner[] __initdata = | |||
1659 | static char no_boards_msg[] __initdata = | 1625 | static char no_boards_msg[] __initdata = |
1660 | KERN_INFO "rc: No RISCom/8 boards detected.\n"; | 1626 | KERN_INFO "rc: No RISCom/8 boards detected.\n"; |
1661 | 1627 | ||
1662 | /* | 1628 | /* |
1663 | * This routine must be called by kernel at boot time | 1629 | * This routine must be called by kernel at boot time |
1664 | */ | 1630 | */ |
1665 | static int __init riscom8_init(void) | 1631 | static int __init riscom8_init(void) |
1666 | { | 1632 | { |
@@ -1669,13 +1635,12 @@ static int __init riscom8_init(void) | |||
1669 | 1635 | ||
1670 | printk(banner); | 1636 | printk(banner); |
1671 | 1637 | ||
1672 | if (rc_init_drivers()) | 1638 | if (rc_init_drivers()) |
1673 | return -EIO; | 1639 | return -EIO; |
1674 | 1640 | ||
1675 | for (i = 0; i < RC_NBOARD; i++) | 1641 | for (i = 0; i < RC_NBOARD; i++) |
1676 | if (rc_board[i].base && !rc_probe(&rc_board[i])) | 1642 | if (rc_board[i].base && !rc_probe(&rc_board[i])) |
1677 | found++; | 1643 | found++; |
1678 | |||
1679 | if (!found) { | 1644 | if (!found) { |
1680 | rc_release_drivers(); | 1645 | rc_release_drivers(); |
1681 | printk(no_boards_msg); | 1646 | printk(no_boards_msg); |
@@ -1702,13 +1667,13 @@ MODULE_LICENSE("GPL"); | |||
1702 | * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. | 1667 | * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. |
1703 | * | 1668 | * |
1704 | */ | 1669 | */ |
1705 | static int __init riscom8_init_module (void) | 1670 | static int __init riscom8_init_module(void) |
1706 | { | 1671 | { |
1707 | #ifdef MODULE | 1672 | #ifdef MODULE |
1708 | int i; | 1673 | int i; |
1709 | 1674 | ||
1710 | if (iobase || iobase1 || iobase2 || iobase3) { | 1675 | if (iobase || iobase1 || iobase2 || iobase3) { |
1711 | for(i = 0; i < RC_NBOARD; i++) | 1676 | for (i = 0; i < RC_NBOARD; i++) |
1712 | rc_board[i].base = 0; | 1677 | rc_board[i].base = 0; |
1713 | } | 1678 | } |
1714 | 1679 | ||
@@ -1724,18 +1689,17 @@ static int __init riscom8_init_module (void) | |||
1724 | 1689 | ||
1725 | return riscom8_init(); | 1690 | return riscom8_init(); |
1726 | } | 1691 | } |
1727 | 1692 | ||
1728 | static void __exit riscom8_exit_module (void) | 1693 | static void __exit riscom8_exit_module(void) |
1729 | { | 1694 | { |
1730 | int i; | 1695 | int i; |
1731 | 1696 | ||
1732 | rc_release_drivers(); | 1697 | rc_release_drivers(); |
1733 | for (i = 0; i < RC_NBOARD; i++) | 1698 | for (i = 0; i < RC_NBOARD; i++) |
1734 | if (rc_board[i].flags & RC_BOARD_PRESENT) | 1699 | if (rc_board[i].flags & RC_BOARD_PRESENT) |
1735 | rc_release_io_range(&rc_board[i]); | 1700 | rc_release_io_range(&rc_board[i]); |
1736 | 1701 | ||
1737 | } | 1702 | } |
1738 | 1703 | ||
1739 | module_init(riscom8_init_module); | 1704 | module_init(riscom8_init_module); |
1740 | module_exit(riscom8_exit_module); | 1705 | module_exit(riscom8_exit_module); |
1741 | |||
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index f585bc8579e9..743dc80a9325 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -449,7 +449,8 @@ static void rp_do_transmit(struct r_port *info) | |||
449 | while (1) { | 449 | while (1) { |
450 | if (tty->stopped || tty->hw_stopped) | 450 | if (tty->stopped || tty->hw_stopped) |
451 | break; | 451 | break; |
452 | c = min(info->xmit_fifo_room, min(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail)); | 452 | c = min(info->xmit_fifo_room, info->xmit_cnt); |
453 | c = min(c, XMIT_BUF_SIZE - info->xmit_tail); | ||
453 | if (c <= 0 || info->xmit_fifo_room <= 0) | 454 | if (c <= 0 || info->xmit_fifo_room <= 0) |
454 | break; | 455 | break; |
455 | sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2); | 456 | sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2); |
@@ -1433,29 +1434,38 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file, | |||
1433 | { | 1434 | { |
1434 | struct r_port *info = (struct r_port *) tty->driver_data; | 1435 | struct r_port *info = (struct r_port *) tty->driver_data; |
1435 | void __user *argp = (void __user *)arg; | 1436 | void __user *argp = (void __user *)arg; |
1437 | int ret = 0; | ||
1436 | 1438 | ||
1437 | if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) | 1439 | if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) |
1438 | return -ENXIO; | 1440 | return -ENXIO; |
1439 | 1441 | ||
1442 | lock_kernel(); | ||
1443 | |||
1440 | switch (cmd) { | 1444 | switch (cmd) { |
1441 | case RCKP_GET_STRUCT: | 1445 | case RCKP_GET_STRUCT: |
1442 | if (copy_to_user(argp, info, sizeof (struct r_port))) | 1446 | if (copy_to_user(argp, info, sizeof (struct r_port))) |
1443 | return -EFAULT; | 1447 | ret = -EFAULT; |
1444 | return 0; | 1448 | break; |
1445 | case RCKP_GET_CONFIG: | 1449 | case RCKP_GET_CONFIG: |
1446 | return get_config(info, argp); | 1450 | ret = get_config(info, argp); |
1451 | break; | ||
1447 | case RCKP_SET_CONFIG: | 1452 | case RCKP_SET_CONFIG: |
1448 | return set_config(info, argp); | 1453 | ret = set_config(info, argp); |
1454 | break; | ||
1449 | case RCKP_GET_PORTS: | 1455 | case RCKP_GET_PORTS: |
1450 | return get_ports(info, argp); | 1456 | ret = get_ports(info, argp); |
1457 | break; | ||
1451 | case RCKP_RESET_RM2: | 1458 | case RCKP_RESET_RM2: |
1452 | return reset_rm2(info, argp); | 1459 | ret = reset_rm2(info, argp); |
1460 | break; | ||
1453 | case RCKP_GET_VERSION: | 1461 | case RCKP_GET_VERSION: |
1454 | return get_version(info, argp); | 1462 | ret = get_version(info, argp); |
1463 | break; | ||
1455 | default: | 1464 | default: |
1456 | return -ENOIOCTLCMD; | 1465 | ret = -ENOIOCTLCMD; |
1457 | } | 1466 | } |
1458 | return 0; | 1467 | unlock_kernel(); |
1468 | return ret; | ||
1459 | } | 1469 | } |
1460 | 1470 | ||
1461 | static void rp_send_xchar(struct tty_struct *tty, char ch) | 1471 | static void rp_send_xchar(struct tty_struct *tty, char ch) |
@@ -1575,6 +1585,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1575 | jiffies); | 1585 | jiffies); |
1576 | printk(KERN_INFO "cps=%d...\n", info->cps); | 1586 | printk(KERN_INFO "cps=%d...\n", info->cps); |
1577 | #endif | 1587 | #endif |
1588 | lock_kernel(); | ||
1578 | while (1) { | 1589 | while (1) { |
1579 | txcnt = sGetTxCnt(cp); | 1590 | txcnt = sGetTxCnt(cp); |
1580 | if (!txcnt) { | 1591 | if (!txcnt) { |
@@ -1602,6 +1613,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1602 | break; | 1613 | break; |
1603 | } | 1614 | } |
1604 | __set_current_state(TASK_RUNNING); | 1615 | __set_current_state(TASK_RUNNING); |
1616 | unlock_kernel(); | ||
1605 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1617 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1606 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); | 1618 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); |
1607 | #endif | 1619 | #endif |
@@ -1651,14 +1663,14 @@ static void rp_hangup(struct tty_struct *tty) | |||
1651 | * writing routines will write directly to transmit FIFO. | 1663 | * writing routines will write directly to transmit FIFO. |
1652 | * Write buffer and counters protected by spinlocks | 1664 | * Write buffer and counters protected by spinlocks |
1653 | */ | 1665 | */ |
1654 | static void rp_put_char(struct tty_struct *tty, unsigned char ch) | 1666 | static int rp_put_char(struct tty_struct *tty, unsigned char ch) |
1655 | { | 1667 | { |
1656 | struct r_port *info = (struct r_port *) tty->driver_data; | 1668 | struct r_port *info = (struct r_port *) tty->driver_data; |
1657 | CHANNEL_t *cp; | 1669 | CHANNEL_t *cp; |
1658 | unsigned long flags; | 1670 | unsigned long flags; |
1659 | 1671 | ||
1660 | if (rocket_paranoia_check(info, "rp_put_char")) | 1672 | if (rocket_paranoia_check(info, "rp_put_char")) |
1661 | return; | 1673 | return 0; |
1662 | 1674 | ||
1663 | /* | 1675 | /* |
1664 | * Grab the port write mutex, locking out other processes that try to | 1676 | * Grab the port write mutex, locking out other processes that try to |
@@ -1687,6 +1699,7 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1687 | } | 1699 | } |
1688 | spin_unlock_irqrestore(&info->slock, flags); | 1700 | spin_unlock_irqrestore(&info->slock, flags); |
1689 | mutex_unlock(&info->write_mtx); | 1701 | mutex_unlock(&info->write_mtx); |
1702 | return 1; | ||
1690 | } | 1703 | } |
1691 | 1704 | ||
1692 | /* | 1705 | /* |
@@ -1749,10 +1762,10 @@ static int rp_write(struct tty_struct *tty, | |||
1749 | 1762 | ||
1750 | /* Write remaining data into the port's xmit_buf */ | 1763 | /* Write remaining data into the port's xmit_buf */ |
1751 | while (1) { | 1764 | while (1) { |
1752 | if (!info->tty) /* Seemingly obligatory check... */ | 1765 | if (!info->tty) /* Seemingly obligatory check... */ |
1753 | goto end; | 1766 | goto end; |
1754 | 1767 | c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); | |
1755 | c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head)); | 1768 | c = min(c, XMIT_BUF_SIZE - info->xmit_head); |
1756 | if (c <= 0) | 1769 | if (c <= 0) |
1757 | break; | 1770 | break; |
1758 | 1771 | ||
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index b01d38125a8f..143cc432fdb2 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -55,7 +55,7 @@ static inline void sOutW(unsigned short port, unsigned short value) | |||
55 | 55 | ||
56 | static inline void out32(unsigned short port, Byte_t *p) | 56 | static inline void out32(unsigned short port, Byte_t *p) |
57 | { | 57 | { |
58 | u32 value = le32_to_cpu(get_unaligned((__le32 *)p)); | 58 | u32 value = get_unaligned_le32(p); |
59 | #ifdef ROCKET_DEBUG_IO | 59 | #ifdef ROCKET_DEBUG_IO |
60 | printk(KERN_DEBUG "out32(%x, %lx)...\n", port, value); | 60 | printk(KERN_DEBUG "out32(%x, %lx)...\n", port, value); |
61 | #endif | 61 | #endif |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index e2ec2ee4cf79..5f80a9dff573 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -1069,10 +1069,8 @@ no_irq: | |||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | #ifdef CONFIG_PROC_FS | 1071 | #ifdef CONFIG_PROC_FS |
1072 | ent = create_proc_entry("driver/rtc", 0, NULL); | 1072 | ent = proc_create("driver/rtc", 0, NULL, &rtc_proc_fops); |
1073 | if (ent) | 1073 | if (!ent) |
1074 | ent->proc_fops = &rtc_proc_fops; | ||
1075 | else | ||
1076 | printk(KERN_WARNING "rtc: Failed to register with procfs.\n"); | 1074 | printk(KERN_WARNING "rtc: Failed to register with procfs.\n"); |
1077 | #endif | 1075 | #endif |
1078 | 1076 | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index df8cd0ca97eb..fd2db07a50fc 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1060,7 +1060,7 @@ static void config_setup(struct cyclades_port *info) | |||
1060 | 1060 | ||
1061 | } /* config_setup */ | 1061 | } /* config_setup */ |
1062 | 1062 | ||
1063 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) | 1063 | static int cy_put_char(struct tty_struct *tty, unsigned char ch) |
1064 | { | 1064 | { |
1065 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 1065 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
1066 | unsigned long flags; | 1066 | unsigned long flags; |
@@ -1070,7 +1070,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
1070 | #endif | 1070 | #endif |
1071 | 1071 | ||
1072 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 1072 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
1073 | return; | 1073 | return 0; |
1074 | 1074 | ||
1075 | if (!info->xmit_buf) | 1075 | if (!info->xmit_buf) |
1076 | return; | 1076 | return; |
@@ -1078,13 +1078,14 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
1078 | local_irq_save(flags); | 1078 | local_irq_save(flags); |
1079 | if (info->xmit_cnt >= PAGE_SIZE - 1) { | 1079 | if (info->xmit_cnt >= PAGE_SIZE - 1) { |
1080 | local_irq_restore(flags); | 1080 | local_irq_restore(flags); |
1081 | return; | 1081 | return 0; |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | info->xmit_buf[info->xmit_head++] = ch; | 1084 | info->xmit_buf[info->xmit_head++] = ch; |
1085 | info->xmit_head &= PAGE_SIZE - 1; | 1085 | info->xmit_head &= PAGE_SIZE - 1; |
1086 | info->xmit_cnt++; | 1086 | info->xmit_cnt++; |
1087 | local_irq_restore(flags); | 1087 | local_irq_restore(flags); |
1088 | return 1; | ||
1088 | } /* cy_put_char */ | 1089 | } /* cy_put_char */ |
1089 | 1090 | ||
1090 | static void cy_flush_chars(struct tty_struct *tty) | 1091 | static void cy_flush_chars(struct tty_struct *tty) |
@@ -1539,6 +1540,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1539 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ | 1540 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ |
1540 | #endif | 1541 | #endif |
1541 | 1542 | ||
1543 | lock_kernel(); | ||
1544 | |||
1542 | switch (cmd) { | 1545 | switch (cmd) { |
1543 | case CYGETMON: | 1546 | case CYGETMON: |
1544 | ret_val = get_mon_info(info, argp); | 1547 | ret_val = get_mon_info(info, argp); |
@@ -1584,18 +1587,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1584 | break; | 1587 | break; |
1585 | 1588 | ||
1586 | /* The following commands are incompletely implemented!!! */ | 1589 | /* The following commands are incompletely implemented!!! */ |
1587 | case TIOCGSOFTCAR: | ||
1588 | ret_val = | ||
1589 | put_user(C_CLOCAL(tty) ? 1 : 0, | ||
1590 | (unsigned long __user *)argp); | ||
1591 | break; | ||
1592 | case TIOCSSOFTCAR: | ||
1593 | ret_val = get_user(val, (unsigned long __user *)argp); | ||
1594 | if (ret_val) | ||
1595 | break; | ||
1596 | tty->termios->c_cflag = | ||
1597 | ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); | ||
1598 | break; | ||
1599 | case TIOCGSERIAL: | 1590 | case TIOCGSERIAL: |
1600 | ret_val = get_serial_info(info, argp); | 1591 | ret_val = get_serial_info(info, argp); |
1601 | break; | 1592 | break; |
@@ -1605,6 +1596,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
1605 | default: | 1596 | default: |
1606 | ret_val = -ENOIOCTLCMD; | 1597 | ret_val = -ENOIOCTLCMD; |
1607 | } | 1598 | } |
1599 | unlock_kernel(); | ||
1608 | 1600 | ||
1609 | #ifdef SERIAL_DEBUG_OTHER | 1601 | #ifdef SERIAL_DEBUG_OTHER |
1610 | printk("cy_ioctl done\n"); | 1602 | printk("cy_ioctl done\n"); |
@@ -1683,8 +1675,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
1683 | if (info->flags & ASYNC_INITIALIZED) | 1675 | if (info->flags & ASYNC_INITIALIZED) |
1684 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 1676 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ |
1685 | shutdown(info); | 1677 | shutdown(info); |
1686 | if (tty->driver->flush_buffer) | 1678 | cy_flush_buffer(tty); |
1687 | tty->driver->flush_buffer(tty); | ||
1688 | tty_ldisc_flush(tty); | 1679 | tty_ldisc_flush(tty); |
1689 | info->tty = NULL; | 1680 | info->tty = NULL; |
1690 | if (info->blocked_open) { | 1681 | if (info->blocked_open) { |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index b9c1dba6bd01..8fe099a41065 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -80,7 +80,7 @@ scdrv_open(struct inode *inode, struct file *file) | |||
80 | sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); | 80 | sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); |
81 | if (sd == NULL) { | 81 | if (sd == NULL) { |
82 | printk("%s: couldn't allocate subchannel data\n", | 82 | printk("%s: couldn't allocate subchannel data\n", |
83 | __FUNCTION__); | 83 | __func__); |
84 | return -ENOMEM; | 84 | return -ENOMEM; |
85 | } | 85 | } |
86 | 86 | ||
@@ -90,7 +90,7 @@ scdrv_open(struct inode *inode, struct file *file) | |||
90 | 90 | ||
91 | if (sd->sd_subch < 0) { | 91 | if (sd->sd_subch < 0) { |
92 | kfree(sd); | 92 | kfree(sd); |
93 | printk("%s: couldn't allocate subchannel\n", __FUNCTION__); | 93 | printk("%s: couldn't allocate subchannel\n", __func__); |
94 | return -EBUSY; | 94 | return -EBUSY; |
95 | } | 95 | } |
96 | 96 | ||
@@ -110,7 +110,7 @@ scdrv_open(struct inode *inode, struct file *file) | |||
110 | if (rv) { | 110 | if (rv) { |
111 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); | 111 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); |
112 | kfree(sd); | 112 | kfree(sd); |
113 | printk("%s: irq request failed (%d)\n", __FUNCTION__, rv); | 113 | printk("%s: irq request failed (%d)\n", __func__, rv); |
114 | return -EBUSY; | 114 | return -EBUSY; |
115 | } | 115 | } |
116 | 116 | ||
@@ -215,7 +215,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) | |||
215 | */ | 215 | */ |
216 | if (count < len) { | 216 | if (count < len) { |
217 | pr_debug("%s: only accepting %d of %d bytes\n", | 217 | pr_debug("%s: only accepting %d of %d bytes\n", |
218 | __FUNCTION__, (int) count, len); | 218 | __func__, (int) count, len); |
219 | } | 219 | } |
220 | len = min((int) count, len); | 220 | len = min((int) count, len); |
221 | if (copy_to_user(buf, sd->sd_rb, len)) | 221 | if (copy_to_user(buf, sd->sd_rb, len)) |
@@ -384,7 +384,7 @@ scdrv_init(void) | |||
384 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, | 384 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, |
385 | SYSCTL_BASENAME) < 0) { | 385 | SYSCTL_BASENAME) < 0) { |
386 | printk("%s: failed to register SN system controller device\n", | 386 | printk("%s: failed to register SN system controller device\n", |
387 | __FUNCTION__); | 387 | __func__); |
388 | return -ENODEV; | 388 | return -ENODEV; |
389 | } | 389 | } |
390 | snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); | 390 | snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); |
@@ -403,7 +403,7 @@ scdrv_init(void) | |||
403 | GFP_KERNEL); | 403 | GFP_KERNEL); |
404 | if (!scd) { | 404 | if (!scd) { |
405 | printk("%s: failed to allocate device info" | 405 | printk("%s: failed to allocate device info" |
406 | "for %s/%s\n", __FUNCTION__, | 406 | "for %s/%s\n", __func__, |
407 | SYSCTL_BASENAME, devname); | 407 | SYSCTL_BASENAME, devname); |
408 | continue; | 408 | continue; |
409 | } | 409 | } |
@@ -412,7 +412,7 @@ scdrv_init(void) | |||
412 | scd->scd_nasid = cnodeid_to_nasid(cnode); | 412 | scd->scd_nasid = cnodeid_to_nasid(cnode); |
413 | if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { | 413 | if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { |
414 | printk("%s: failed to allocate driver buffer" | 414 | printk("%s: failed to allocate driver buffer" |
415 | "(%s%s)\n", __FUNCTION__, | 415 | "(%s%s)\n", __func__, |
416 | SYSCTL_BASENAME, devname); | 416 | SYSCTL_BASENAME, devname); |
417 | kfree(scd); | 417 | kfree(scd); |
418 | continue; | 418 | continue; |
@@ -424,7 +424,7 @@ scdrv_init(void) | |||
424 | ("%s: failed to initialize SAL for" | 424 | ("%s: failed to initialize SAL for" |
425 | " system controller communication" | 425 | " system controller communication" |
426 | " (%s/%s): outdated PROM?\n", | 426 | " (%s/%s): outdated PROM?\n", |
427 | __FUNCTION__, SYSCTL_BASENAME, devname); | 427 | __func__, SYSCTL_BASENAME, devname); |
428 | kfree(scd); | 428 | kfree(scd); |
429 | kfree(salbuf); | 429 | kfree(salbuf); |
430 | continue; | 430 | continue; |
@@ -435,7 +435,7 @@ scdrv_init(void) | |||
435 | if (cdev_add(&scd->scd_cdev, dev, 1)) { | 435 | if (cdev_add(&scd->scd_cdev, dev, 1)) { |
436 | printk("%s: failed to register system" | 436 | printk("%s: failed to register system" |
437 | " controller device (%s%s)\n", | 437 | " controller device (%s%s)\n", |
438 | __FUNCTION__, SYSCTL_BASENAME, devname); | 438 | __func__, SYSCTL_BASENAME, devname); |
439 | kfree(scd); | 439 | kfree(scd); |
440 | kfree(salbuf); | 440 | kfree(salbuf); |
441 | continue; | 441 | continue; |
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index 1b75b0b7d542..53b3d44f8c06 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c | |||
@@ -63,16 +63,13 @@ static int | |||
63 | scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc) | 63 | scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc) |
64 | { | 64 | { |
65 | char *desc_end; | 65 | char *desc_end; |
66 | __be32 from_buf; | ||
67 | 66 | ||
68 | /* record event source address */ | 67 | /* record event source address */ |
69 | from_buf = get_unaligned((__be32 *)event); | 68 | *src = get_unaligned_be32(event); |
70 | *src = be32_to_cpup(&from_buf); | ||
71 | event += 4; /* move on to event code */ | 69 | event += 4; /* move on to event code */ |
72 | 70 | ||
73 | /* record the system controller's event code */ | 71 | /* record the system controller's event code */ |
74 | from_buf = get_unaligned((__be32 *)event); | 72 | *code = get_unaligned_be32(event); |
75 | *code = be32_to_cpup(&from_buf); | ||
76 | event += 4; /* move on to event arguments */ | 73 | event += 4; /* move on to event arguments */ |
77 | 74 | ||
78 | /* how many arguments are in the packet? */ | 75 | /* how many arguments are in the packet? */ |
@@ -86,8 +83,7 @@ scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc) | |||
86 | /* not an integer argument, so give up */ | 83 | /* not an integer argument, so give up */ |
87 | return -1; | 84 | return -1; |
88 | } | 85 | } |
89 | from_buf = get_unaligned((__be32 *)event); | 86 | *esp_code = get_unaligned_be32(event); |
90 | *esp_code = be32_to_cpup(&from_buf); | ||
91 | event += 4; | 87 | event += 4; |
92 | 88 | ||
93 | /* parse out the event description */ | 89 | /* parse out the event description */ |
@@ -275,7 +271,7 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
275 | event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); | 271 | event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); |
276 | if (event_sd == NULL) { | 272 | if (event_sd == NULL) { |
277 | printk(KERN_WARNING "%s: couldn't allocate subchannel info" | 273 | printk(KERN_WARNING "%s: couldn't allocate subchannel info" |
278 | " for event monitoring\n", __FUNCTION__); | 274 | " for event monitoring\n", __func__); |
279 | return; | 275 | return; |
280 | } | 276 | } |
281 | 277 | ||
@@ -289,7 +285,7 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
289 | if (event_sd->sd_subch < 0) { | 285 | if (event_sd->sd_subch < 0) { |
290 | kfree(event_sd); | 286 | kfree(event_sd); |
291 | printk(KERN_WARNING "%s: couldn't open event subchannel\n", | 287 | printk(KERN_WARNING "%s: couldn't open event subchannel\n", |
292 | __FUNCTION__); | 288 | __func__); |
293 | return; | 289 | return; |
294 | } | 290 | } |
295 | 291 | ||
@@ -299,7 +295,7 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
299 | "system controller events", event_sd); | 295 | "system controller events", event_sd); |
300 | if (rv) { | 296 | if (rv) { |
301 | printk(KERN_WARNING "%s: irq request failed (%d)\n", | 297 | printk(KERN_WARNING "%s: irq request failed (%d)\n", |
302 | __FUNCTION__, rv); | 298 | __func__, rv); |
303 | ia64_sn_irtr_close(event_sd->sd_nasid, event_sd->sd_subch); | 299 | ia64_sn_irtr_close(event_sd->sd_nasid, event_sd->sd_subch); |
304 | kfree(event_sd); | 300 | kfree(event_sd); |
305 | return; | 301 | return; |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index c03ad164c39a..58533de59027 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -506,7 +506,7 @@ static struct sonypi_device { | |||
506 | while (--n && (command)) \ | 506 | while (--n && (command)) \ |
507 | udelay(1); \ | 507 | udelay(1); \ |
508 | if (!n && (verbose || !quiet)) \ | 508 | if (!n && (verbose || !quiet)) \ |
509 | printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \ | 509 | printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \ |
510 | } | 510 | } |
511 | 511 | ||
512 | #ifdef CONFIG_ACPI | 512 | #ifdef CONFIG_ACPI |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 4b5b5b78acb4..2ee4d9893757 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO; | |||
131 | #define SX_DEBUG_FIFO 0x0800 | 131 | #define SX_DEBUG_FIFO 0x0800 |
132 | 132 | ||
133 | 133 | ||
134 | #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__) | 134 | #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__) |
135 | #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__) | 135 | #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__) |
136 | 136 | ||
137 | #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) | 137 | #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) |
138 | 138 | ||
@@ -874,7 +874,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id) | |||
874 | 874 | ||
875 | spin_lock_irqsave(&bp->lock, flags); | 875 | spin_lock_irqsave(&bp->lock, flags); |
876 | 876 | ||
877 | dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); | 877 | dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); |
878 | if (!(bp->flags & SX_BOARD_ACTIVE)) { | 878 | if (!(bp->flags & SX_BOARD_ACTIVE)) { |
879 | dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); | 879 | dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); |
880 | spin_unlock_irqrestore(&bp->lock, flags); | 880 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -1504,6 +1504,27 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1504 | return 0; | 1504 | return 0; |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | static void sx_flush_buffer(struct tty_struct *tty) | ||
1508 | { | ||
1509 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | ||
1510 | unsigned long flags; | ||
1511 | struct specialix_board * bp; | ||
1512 | |||
1513 | func_enter(); | ||
1514 | |||
1515 | if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { | ||
1516 | func_exit(); | ||
1517 | return; | ||
1518 | } | ||
1519 | |||
1520 | bp = port_Board(port); | ||
1521 | spin_lock_irqsave(&port->lock, flags); | ||
1522 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1523 | spin_unlock_irqrestore(&port->lock, flags); | ||
1524 | tty_wakeup(tty); | ||
1525 | |||
1526 | func_exit(); | ||
1527 | } | ||
1507 | 1528 | ||
1508 | static void sx_close(struct tty_struct * tty, struct file * filp) | 1529 | static void sx_close(struct tty_struct * tty, struct file * filp) |
1509 | { | 1530 | { |
@@ -1597,8 +1618,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1597 | } | 1618 | } |
1598 | 1619 | ||
1599 | sx_shutdown_port(bp, port); | 1620 | sx_shutdown_port(bp, port); |
1600 | if (tty->driver->flush_buffer) | 1621 | sx_flush_buffer(tty); |
1601 | tty->driver->flush_buffer(tty); | ||
1602 | tty_ldisc_flush(tty); | 1622 | tty_ldisc_flush(tty); |
1603 | spin_lock_irqsave(&port->lock, flags); | 1623 | spin_lock_irqsave(&port->lock, flags); |
1604 | tty->closing = 0; | 1624 | tty->closing = 0; |
@@ -1670,7 +1690,7 @@ static int sx_write(struct tty_struct * tty, | |||
1670 | } | 1690 | } |
1671 | 1691 | ||
1672 | 1692 | ||
1673 | static void sx_put_char(struct tty_struct * tty, unsigned char ch) | 1693 | static int sx_put_char(struct tty_struct * tty, unsigned char ch) |
1674 | { | 1694 | { |
1675 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 1695 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
1676 | unsigned long flags; | 1696 | unsigned long flags; |
@@ -1680,12 +1700,12 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1680 | 1700 | ||
1681 | if (sx_paranoia_check(port, tty->name, "sx_put_char")) { | 1701 | if (sx_paranoia_check(port, tty->name, "sx_put_char")) { |
1682 | func_exit(); | 1702 | func_exit(); |
1683 | return; | 1703 | return 0; |
1684 | } | 1704 | } |
1685 | dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); | 1705 | dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); |
1686 | if (!port->xmit_buf) { | 1706 | if (!port->xmit_buf) { |
1687 | func_exit(); | 1707 | func_exit(); |
1688 | return; | 1708 | return 0; |
1689 | } | 1709 | } |
1690 | bp = port_Board(port); | 1710 | bp = port_Board(port); |
1691 | spin_lock_irqsave(&port->lock, flags); | 1711 | spin_lock_irqsave(&port->lock, flags); |
@@ -1695,7 +1715,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1695 | spin_unlock_irqrestore(&port->lock, flags); | 1715 | spin_unlock_irqrestore(&port->lock, flags); |
1696 | dprintk (SX_DEBUG_TX, "Exit size\n"); | 1716 | dprintk (SX_DEBUG_TX, "Exit size\n"); |
1697 | func_exit(); | 1717 | func_exit(); |
1698 | return; | 1718 | return 0; |
1699 | } | 1719 | } |
1700 | dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); | 1720 | dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); |
1701 | port->xmit_buf[port->xmit_head++] = ch; | 1721 | port->xmit_buf[port->xmit_head++] = ch; |
@@ -1704,6 +1724,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) | |||
1704 | spin_unlock_irqrestore(&port->lock, flags); | 1724 | spin_unlock_irqrestore(&port->lock, flags); |
1705 | 1725 | ||
1706 | func_exit(); | 1726 | func_exit(); |
1727 | return 1; | ||
1707 | } | 1728 | } |
1708 | 1729 | ||
1709 | 1730 | ||
@@ -1770,28 +1791,6 @@ static int sx_chars_in_buffer(struct tty_struct *tty) | |||
1770 | } | 1791 | } |
1771 | 1792 | ||
1772 | 1793 | ||
1773 | static void sx_flush_buffer(struct tty_struct *tty) | ||
1774 | { | ||
1775 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | ||
1776 | unsigned long flags; | ||
1777 | struct specialix_board * bp; | ||
1778 | |||
1779 | func_enter(); | ||
1780 | |||
1781 | if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { | ||
1782 | func_exit(); | ||
1783 | return; | ||
1784 | } | ||
1785 | |||
1786 | bp = port_Board(port); | ||
1787 | spin_lock_irqsave(&port->lock, flags); | ||
1788 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1789 | spin_unlock_irqrestore(&port->lock, flags); | ||
1790 | tty_wakeup(tty); | ||
1791 | |||
1792 | func_exit(); | ||
1793 | } | ||
1794 | |||
1795 | 1794 | ||
1796 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) | 1795 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) |
1797 | { | 1796 | { |
@@ -1803,7 +1802,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) | |||
1803 | 1802 | ||
1804 | func_enter(); | 1803 | func_enter(); |
1805 | 1804 | ||
1806 | if (sx_paranoia_check(port, tty->name, __FUNCTION__)) { | 1805 | if (sx_paranoia_check(port, tty->name, __func__)) { |
1807 | func_exit(); | 1806 | func_exit(); |
1808 | return -ENODEV; | 1807 | return -ENODEV; |
1809 | } | 1808 | } |
@@ -1845,7 +1844,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1845 | 1844 | ||
1846 | func_enter(); | 1845 | func_enter(); |
1847 | 1846 | ||
1848 | if (sx_paranoia_check(port, tty->name, __FUNCTION__)) { | 1847 | if (sx_paranoia_check(port, tty->name, __func__)) { |
1849 | func_exit(); | 1848 | func_exit(); |
1850 | return -ENODEV; | 1849 | return -ENODEV; |
1851 | } | 1850 | } |
@@ -1922,29 +1921,13 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1922 | int change_speed; | 1921 | int change_speed; |
1923 | 1922 | ||
1924 | func_enter(); | 1923 | func_enter(); |
1925 | /* | 1924 | |
1926 | if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) { | ||
1927 | func_exit(); | ||
1928 | return -EFAULT; | ||
1929 | } | ||
1930 | */ | ||
1931 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { | 1925 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { |
1932 | func_enter(); | 1926 | func_enter(); |
1933 | return -EFAULT; | 1927 | return -EFAULT; |
1934 | } | 1928 | } |
1935 | 1929 | ||
1936 | #if 0 | 1930 | lock_kernel(); |
1937 | if ((tmp.irq != bp->irq) || | ||
1938 | (tmp.port != bp->base) || | ||
1939 | (tmp.type != PORT_CIRRUS) || | ||
1940 | (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) || | ||
1941 | (tmp.custom_divisor != 0) || | ||
1942 | (tmp.xmit_fifo_size != CD186x_NFIFO) || | ||
1943 | (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) { | ||
1944 | func_exit(); | ||
1945 | return -EINVAL; | ||
1946 | } | ||
1947 | #endif | ||
1948 | 1931 | ||
1949 | change_speed = ((port->flags & ASYNC_SPD_MASK) != | 1932 | change_speed = ((port->flags & ASYNC_SPD_MASK) != |
1950 | (tmp.flags & ASYNC_SPD_MASK)); | 1933 | (tmp.flags & ASYNC_SPD_MASK)); |
@@ -1956,6 +1939,7 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1956 | ((tmp.flags & ~ASYNC_USR_MASK) != | 1939 | ((tmp.flags & ~ASYNC_USR_MASK) != |
1957 | (port->flags & ~ASYNC_USR_MASK))) { | 1940 | (port->flags & ~ASYNC_USR_MASK))) { |
1958 | func_exit(); | 1941 | func_exit(); |
1942 | unlock_kernel(); | ||
1959 | return -EPERM; | 1943 | return -EPERM; |
1960 | } | 1944 | } |
1961 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1945 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
@@ -1972,6 +1956,7 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1972 | sx_change_speed(bp, port); | 1956 | sx_change_speed(bp, port); |
1973 | } | 1957 | } |
1974 | func_exit(); | 1958 | func_exit(); |
1959 | unlock_kernel(); | ||
1975 | return 0; | 1960 | return 0; |
1976 | } | 1961 | } |
1977 | 1962 | ||
@@ -1984,12 +1969,8 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
1984 | 1969 | ||
1985 | func_enter(); | 1970 | func_enter(); |
1986 | 1971 | ||
1987 | /* | ||
1988 | if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp))) | ||
1989 | return -EFAULT; | ||
1990 | */ | ||
1991 | |||
1992 | memset(&tmp, 0, sizeof(tmp)); | 1972 | memset(&tmp, 0, sizeof(tmp)); |
1973 | lock_kernel(); | ||
1993 | tmp.type = PORT_CIRRUS; | 1974 | tmp.type = PORT_CIRRUS; |
1994 | tmp.line = port - sx_port; | 1975 | tmp.line = port - sx_port; |
1995 | tmp.port = bp->base; | 1976 | tmp.port = bp->base; |
@@ -2000,6 +1981,7 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
2000 | tmp.closing_wait = port->closing_wait * HZ/100; | 1981 | tmp.closing_wait = port->closing_wait * HZ/100; |
2001 | tmp.custom_divisor = port->custom_divisor; | 1982 | tmp.custom_divisor = port->custom_divisor; |
2002 | tmp.xmit_fifo_size = CD186x_NFIFO; | 1983 | tmp.xmit_fifo_size = CD186x_NFIFO; |
1984 | unlock_kernel(); | ||
2003 | if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { | 1985 | if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { |
2004 | func_exit(); | 1986 | func_exit(); |
2005 | return -EFAULT; | 1987 | return -EFAULT; |
@@ -2045,23 +2027,6 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, | |||
2045 | sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); | 2027 | sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); |
2046 | func_exit(); | 2028 | func_exit(); |
2047 | return 0; | 2029 | return 0; |
2048 | case TIOCGSOFTCAR: | ||
2049 | if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) { | ||
2050 | func_exit(); | ||
2051 | return -EFAULT; | ||
2052 | } | ||
2053 | func_exit(); | ||
2054 | return 0; | ||
2055 | case TIOCSSOFTCAR: | ||
2056 | if (get_user(arg, (unsigned long __user *) argp)) { | ||
2057 | func_exit(); | ||
2058 | return -EFAULT; | ||
2059 | } | ||
2060 | tty->termios->c_cflag = | ||
2061 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
2062 | (arg ? CLOCAL : 0)); | ||
2063 | func_exit(); | ||
2064 | return 0; | ||
2065 | case TIOCGSERIAL: | 2030 | case TIOCGSERIAL: |
2066 | func_exit(); | 2031 | func_exit(); |
2067 | return sx_get_serial_info(port, argp); | 2032 | return sx_get_serial_info(port, argp); |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 874aaa08e956..d17be10c5d21 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -875,6 +875,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
875 | timeout = HZ; | 875 | timeout = HZ; |
876 | tend = jiffies + timeout; | 876 | tend = jiffies + timeout; |
877 | 877 | ||
878 | lock_kernel(); | ||
878 | while (stl_datastate(portp)) { | 879 | while (stl_datastate(portp)) { |
879 | if (signal_pending(current)) | 880 | if (signal_pending(current)) |
880 | break; | 881 | break; |
@@ -882,6 +883,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
882 | if (time_after_eq(jiffies, tend)) | 883 | if (time_after_eq(jiffies, tend)) |
883 | break; | 884 | break; |
884 | } | 885 | } |
886 | unlock_kernel(); | ||
885 | } | 887 | } |
886 | 888 | ||
887 | /*****************************************************************************/ | 889 | /*****************************************************************************/ |
@@ -1273,18 +1275,9 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1273 | 1275 | ||
1274 | rc = 0; | 1276 | rc = 0; |
1275 | 1277 | ||
1278 | lock_kernel(); | ||
1279 | |||
1276 | switch (cmd) { | 1280 | switch (cmd) { |
1277 | case TIOCGSOFTCAR: | ||
1278 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), | ||
1279 | (unsigned __user *) argp); | ||
1280 | break; | ||
1281 | case TIOCSSOFTCAR: | ||
1282 | if (get_user(ival, (unsigned int __user *) arg)) | ||
1283 | return -EFAULT; | ||
1284 | tty->termios->c_cflag = | ||
1285 | (tty->termios->c_cflag & ~CLOCAL) | | ||
1286 | (ival ? CLOCAL : 0); | ||
1287 | break; | ||
1288 | case TIOCGSERIAL: | 1281 | case TIOCGSERIAL: |
1289 | rc = stl_getserial(portp, argp); | 1282 | rc = stl_getserial(portp, argp); |
1290 | break; | 1283 | break; |
@@ -1308,7 +1301,7 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1308 | rc = -ENOIOCTLCMD; | 1301 | rc = -ENOIOCTLCMD; |
1309 | break; | 1302 | break; |
1310 | } | 1303 | } |
1311 | 1304 | unlock_kernel(); | |
1312 | return rc; | 1305 | return rc; |
1313 | } | 1306 | } |
1314 | 1307 | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index a6e1c9ba1217..f39f6fd89350 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -384,11 +384,11 @@ static struct real_driver sx_real_driver = { | |||
384 | #define sx_dprintk(f, str...) /* nothing */ | 384 | #define sx_dprintk(f, str...) /* nothing */ |
385 | #endif | 385 | #endif |
386 | 386 | ||
387 | #define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__) | 387 | #define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__) |
388 | #define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__FUNCTION__) | 388 | #define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__) |
389 | 389 | ||
390 | #define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ | 390 | #define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ |
391 | __FUNCTION__, port->line) | 391 | __func__, port->line) |
392 | 392 | ||
393 | /* | 393 | /* |
394 | * Firmware loader driver specific routines | 394 | * Firmware loader driver specific routines |
@@ -1574,7 +1574,7 @@ static void sx_close(void *ptr) | |||
1574 | sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", | 1574 | sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", |
1575 | port->gs.count); | 1575 | port->gs.count); |
1576 | /*printk("%s SETTING port count to zero: %p count: %d\n", | 1576 | /*printk("%s SETTING port count to zero: %p count: %d\n", |
1577 | __FUNCTION__, port, port->gs.count); | 1577 | __func__, port, port->gs.count); |
1578 | port->gs.count = 0;*/ | 1578 | port->gs.count = 0;*/ |
1579 | } | 1579 | } |
1580 | 1580 | ||
@@ -1844,6 +1844,7 @@ static void sx_break(struct tty_struct *tty, int flag) | |||
1844 | int rv; | 1844 | int rv; |
1845 | 1845 | ||
1846 | func_enter(); | 1846 | func_enter(); |
1847 | lock_kernel(); | ||
1847 | 1848 | ||
1848 | if (flag) | 1849 | if (flag) |
1849 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); | 1850 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); |
@@ -1852,7 +1853,7 @@ static void sx_break(struct tty_struct *tty, int flag) | |||
1852 | if (rv != 1) | 1853 | if (rv != 1) |
1853 | printk(KERN_ERR "sx: couldn't send break (%x).\n", | 1854 | printk(KERN_ERR "sx: couldn't send break (%x).\n", |
1854 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | 1855 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); |
1855 | 1856 | unlock_kernel(); | |
1856 | func_exit(); | 1857 | func_exit(); |
1857 | } | 1858 | } |
1858 | 1859 | ||
@@ -1888,23 +1889,12 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1888 | int rc; | 1889 | int rc; |
1889 | struct sx_port *port = tty->driver_data; | 1890 | struct sx_port *port = tty->driver_data; |
1890 | void __user *argp = (void __user *)arg; | 1891 | void __user *argp = (void __user *)arg; |
1891 | int ival; | ||
1892 | 1892 | ||
1893 | /* func_enter2(); */ | 1893 | /* func_enter2(); */ |
1894 | 1894 | ||
1895 | rc = 0; | 1895 | rc = 0; |
1896 | lock_kernel(); | ||
1896 | switch (cmd) { | 1897 | switch (cmd) { |
1897 | case TIOCGSOFTCAR: | ||
1898 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), | ||
1899 | (unsigned __user *)argp); | ||
1900 | break; | ||
1901 | case TIOCSSOFTCAR: | ||
1902 | if ((rc = get_user(ival, (unsigned __user *)argp)) == 0) { | ||
1903 | tty->termios->c_cflag = | ||
1904 | (tty->termios->c_cflag & ~CLOCAL) | | ||
1905 | (ival ? CLOCAL : 0); | ||
1906 | } | ||
1907 | break; | ||
1908 | case TIOCGSERIAL: | 1898 | case TIOCGSERIAL: |
1909 | rc = gs_getserial(&port->gs, argp); | 1899 | rc = gs_getserial(&port->gs, argp); |
1910 | break; | 1900 | break; |
@@ -1915,6 +1905,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, | |||
1915 | rc = -ENOIOCTLCMD; | 1905 | rc = -ENOIOCTLCMD; |
1916 | break; | 1906 | break; |
1917 | } | 1907 | } |
1908 | unlock_kernel(); | ||
1918 | 1909 | ||
1919 | /* func_exit(); */ | 1910 | /* func_exit(); */ |
1920 | return rc; | 1911 | return rc; |
@@ -2549,7 +2540,7 @@ static int __devinit sx_eisa_probe(struct device *dev) | |||
2549 | goto err_flag; | 2540 | goto err_flag; |
2550 | } | 2541 | } |
2551 | board->base2 = | 2542 | board->base2 = |
2552 | board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN); | 2543 | board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN); |
2553 | if (!board->base) { | 2544 | if (!board->base) { |
2554 | dev_err(dev, "can't remap memory\n"); | 2545 | dev_err(dev, "can't remap memory\n"); |
2555 | goto err_reg; | 2546 | goto err_reg; |
@@ -2626,7 +2617,7 @@ static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) | |||
2626 | 2617 | ||
2627 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); | 2618 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); |
2628 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; | 2619 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; |
2629 | rebase = ioremap(hwbase, 0x80); | 2620 | rebase = ioremap_nocache(hwbase, 0x80); |
2630 | t = readl(rebase + CNTRL_REG_OFFSET); | 2621 | t = readl(rebase + CNTRL_REG_OFFSET); |
2631 | if (t != CNTRL_REG_GOODVALUE) { | 2622 | if (t != CNTRL_REG_GOODVALUE) { |
2632 | printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " | 2623 | printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " |
@@ -2770,7 +2761,7 @@ static int __init sx_init(void) | |||
2770 | if (!request_region(board->hw_base, board->hw_len, "sx")) | 2761 | if (!request_region(board->hw_base, board->hw_len, "sx")) |
2771 | continue; | 2762 | continue; |
2772 | board->base2 = | 2763 | board->base2 = |
2773 | board->base = ioremap(board->hw_base, board->hw_len); | 2764 | board->base = ioremap_nocache(board->hw_base, board->hw_len); |
2774 | if (!board->base) | 2765 | if (!board->base) |
2775 | goto err_sx_reg; | 2766 | goto err_sx_reg; |
2776 | board->flags &= ~SX_BOARD_TYPE; | 2767 | board->flags &= ~SX_BOARD_TYPE; |
@@ -2794,7 +2785,7 @@ err_sx_reg: | |||
2794 | if (!request_region(board->hw_base, board->hw_len, "sx")) | 2785 | if (!request_region(board->hw_base, board->hw_len, "sx")) |
2795 | continue; | 2786 | continue; |
2796 | board->base2 = | 2787 | board->base2 = |
2797 | board->base = ioremap(board->hw_base, board->hw_len); | 2788 | board->base = ioremap_nocache(board->hw_base, board->hw_len); |
2798 | if (!board->base) | 2789 | if (!board->base) |
2799 | goto err_si_reg; | 2790 | goto err_si_reg; |
2800 | board->flags &= ~SX_BOARD_TYPE; | 2791 | board->flags &= ~SX_BOARD_TYPE; |
@@ -2817,7 +2808,7 @@ err_si_reg: | |||
2817 | if (!request_region(board->hw_base, board->hw_len, "sx")) | 2808 | if (!request_region(board->hw_base, board->hw_len, "sx")) |
2818 | continue; | 2809 | continue; |
2819 | board->base2 = | 2810 | board->base2 = |
2820 | board->base = ioremap(board->hw_base, board->hw_len); | 2811 | board->base = ioremap_nocache(board->hw_base, board->hw_len); |
2821 | if (!board->base) | 2812 | if (!board->base) |
2822 | goto err_si1_reg; | 2813 | goto err_si1_reg; |
2823 | board->flags &= ~SX_BOARD_TYPE; | 2814 | board->flags &= ~SX_BOARD_TYPE; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index fadab1d9510f..ac5080df2565 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -2026,34 +2026,35 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
2026 | * | 2026 | * |
2027 | * Return Value: None | 2027 | * Return Value: None |
2028 | */ | 2028 | */ |
2029 | static void mgsl_put_char(struct tty_struct *tty, unsigned char ch) | 2029 | static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) |
2030 | { | 2030 | { |
2031 | struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data; | 2031 | struct mgsl_struct *info = tty->driver_data; |
2032 | unsigned long flags; | 2032 | unsigned long flags; |
2033 | int ret = 0; | ||
2033 | 2034 | ||
2034 | if ( debug_level >= DEBUG_LEVEL_INFO ) { | 2035 | if (debug_level >= DEBUG_LEVEL_INFO) { |
2035 | printk( "%s(%d):mgsl_put_char(%d) on %s\n", | 2036 | printk(KERN_DEBUG "%s(%d):mgsl_put_char(%d) on %s\n", |
2036 | __FILE__,__LINE__,ch,info->device_name); | 2037 | __FILE__, __LINE__, ch, info->device_name); |
2037 | } | 2038 | } |
2038 | 2039 | ||
2039 | if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) | 2040 | if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) |
2040 | return; | 2041 | return 0; |
2041 | 2042 | ||
2042 | if (!tty || !info->xmit_buf) | 2043 | if (!tty || !info->xmit_buf) |
2043 | return; | 2044 | return 0; |
2044 | 2045 | ||
2045 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2046 | spin_lock_irqsave(&info->irq_spinlock, flags); |
2046 | |||
2047 | if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) { | ||
2048 | 2047 | ||
2048 | if ((info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active) { | ||
2049 | if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) { | 2049 | if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) { |
2050 | info->xmit_buf[info->xmit_head++] = ch; | 2050 | info->xmit_buf[info->xmit_head++] = ch; |
2051 | info->xmit_head &= SERIAL_XMIT_SIZE-1; | 2051 | info->xmit_head &= SERIAL_XMIT_SIZE-1; |
2052 | info->xmit_cnt++; | 2052 | info->xmit_cnt++; |
2053 | ret = 1; | ||
2053 | } | 2054 | } |
2054 | } | 2055 | } |
2055 | 2056 | spin_unlock_irqrestore(&info->irq_spinlock, flags); | |
2056 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 2057 | return ret; |
2057 | 2058 | ||
2058 | } /* end of mgsl_put_char() */ | 2059 | } /* end of mgsl_put_char() */ |
2059 | 2060 | ||
@@ -2942,6 +2943,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2942 | unsigned int cmd, unsigned long arg) | 2943 | unsigned int cmd, unsigned long arg) |
2943 | { | 2944 | { |
2944 | struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; | 2945 | struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; |
2946 | int ret; | ||
2945 | 2947 | ||
2946 | if (debug_level >= DEBUG_LEVEL_INFO) | 2948 | if (debug_level >= DEBUG_LEVEL_INFO) |
2947 | printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, | 2949 | printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, |
@@ -2956,7 +2958,10 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2956 | return -EIO; | 2958 | return -EIO; |
2957 | } | 2959 | } |
2958 | 2960 | ||
2959 | return mgsl_ioctl_common(info, cmd, arg); | 2961 | lock_kernel(); |
2962 | ret = mgsl_ioctl_common(info, cmd, arg); | ||
2963 | unlock_kernel(); | ||
2964 | return ret; | ||
2960 | } | 2965 | } |
2961 | 2966 | ||
2962 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) | 2967 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) |
@@ -3153,8 +3158,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) | |||
3153 | if (info->flags & ASYNC_INITIALIZED) | 3158 | if (info->flags & ASYNC_INITIALIZED) |
3154 | mgsl_wait_until_sent(tty, info->timeout); | 3159 | mgsl_wait_until_sent(tty, info->timeout); |
3155 | 3160 | ||
3156 | if (tty->driver->flush_buffer) | 3161 | mgsl_flush_buffer(tty); |
3157 | tty->driver->flush_buffer(tty); | ||
3158 | 3162 | ||
3159 | tty_ldisc_flush(tty); | 3163 | tty_ldisc_flush(tty); |
3160 | 3164 | ||
@@ -3217,7 +3221,8 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3217 | * interval should also be less than the timeout. | 3221 | * interval should also be less than the timeout. |
3218 | * Note: use tight timings here to satisfy the NIST-PCTS. | 3222 | * Note: use tight timings here to satisfy the NIST-PCTS. |
3219 | */ | 3223 | */ |
3220 | 3224 | ||
3225 | lock_kernel(); | ||
3221 | if ( info->params.data_rate ) { | 3226 | if ( info->params.data_rate ) { |
3222 | char_time = info->timeout/(32 * 5); | 3227 | char_time = info->timeout/(32 * 5); |
3223 | if (!char_time) | 3228 | if (!char_time) |
@@ -3247,6 +3252,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3247 | break; | 3252 | break; |
3248 | } | 3253 | } |
3249 | } | 3254 | } |
3255 | unlock_kernel(); | ||
3250 | 3256 | ||
3251 | exit: | 3257 | exit: |
3252 | if (debug_level >= DEBUG_LEVEL_INFO) | 3258 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -4144,7 +4150,8 @@ static int mgsl_claim_resources(struct mgsl_struct *info) | |||
4144 | } | 4150 | } |
4145 | info->lcr_mem_requested = true; | 4151 | info->lcr_mem_requested = true; |
4146 | 4152 | ||
4147 | info->memory_base = ioremap(info->phys_memory_base,0x40000); | 4153 | info->memory_base = ioremap_nocache(info->phys_memory_base, |
4154 | 0x40000); | ||
4148 | if (!info->memory_base) { | 4155 | if (!info->memory_base) { |
4149 | printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n", | 4156 | printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n", |
4150 | __FILE__,__LINE__,info->device_name, info->phys_memory_base ); | 4157 | __FILE__,__LINE__,info->device_name, info->phys_memory_base ); |
@@ -4157,12 +4164,14 @@ static int mgsl_claim_resources(struct mgsl_struct *info) | |||
4157 | goto errout; | 4164 | goto errout; |
4158 | } | 4165 | } |
4159 | 4166 | ||
4160 | info->lcr_base = ioremap(info->phys_lcr_base,PAGE_SIZE) + info->lcr_offset; | 4167 | info->lcr_base = ioremap_nocache(info->phys_lcr_base, |
4168 | PAGE_SIZE); | ||
4161 | if (!info->lcr_base) { | 4169 | if (!info->lcr_base) { |
4162 | printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n", | 4170 | printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n", |
4163 | __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); | 4171 | __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); |
4164 | goto errout; | 4172 | goto errout; |
4165 | } | 4173 | } |
4174 | info->lcr_base += info->lcr_offset; | ||
4166 | 4175 | ||
4167 | } else { | 4176 | } else { |
4168 | /* claim DMA channel */ | 4177 | /* claim DMA channel */ |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index f3d8d72e5ea4..2001b0e52dc6 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -151,7 +151,7 @@ static void hangup(struct tty_struct *tty); | |||
151 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); | 151 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); |
152 | 152 | ||
153 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); | 153 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); |
154 | static void put_char(struct tty_struct *tty, unsigned char ch); | 154 | static int put_char(struct tty_struct *tty, unsigned char ch); |
155 | static void send_xchar(struct tty_struct *tty, char ch); | 155 | static void send_xchar(struct tty_struct *tty, char ch); |
156 | static void wait_until_sent(struct tty_struct *tty, int timeout); | 156 | static void wait_until_sent(struct tty_struct *tty, int timeout); |
157 | static int write_room(struct tty_struct *tty); | 157 | static int write_room(struct tty_struct *tty); |
@@ -771,8 +771,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
771 | 771 | ||
772 | if (info->flags & ASYNC_INITIALIZED) | 772 | if (info->flags & ASYNC_INITIALIZED) |
773 | wait_until_sent(tty, info->timeout); | 773 | wait_until_sent(tty, info->timeout); |
774 | if (tty->driver->flush_buffer) | 774 | flush_buffer(tty); |
775 | tty->driver->flush_buffer(tty); | ||
776 | tty_ldisc_flush(tty); | 775 | tty_ldisc_flush(tty); |
777 | 776 | ||
778 | shutdown(info); | 777 | shutdown(info); |
@@ -913,20 +912,24 @@ cleanup: | |||
913 | return ret; | 912 | return ret; |
914 | } | 913 | } |
915 | 914 | ||
916 | static void put_char(struct tty_struct *tty, unsigned char ch) | 915 | static int put_char(struct tty_struct *tty, unsigned char ch) |
917 | { | 916 | { |
918 | struct slgt_info *info = tty->driver_data; | 917 | struct slgt_info *info = tty->driver_data; |
919 | unsigned long flags; | 918 | unsigned long flags; |
919 | int ret; | ||
920 | 920 | ||
921 | if (sanity_check(info, tty->name, "put_char")) | 921 | if (sanity_check(info, tty->name, "put_char")) |
922 | return; | 922 | return 0; |
923 | DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); | 923 | DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); |
924 | if (!info->tx_buf) | 924 | if (!info->tx_buf) |
925 | return; | 925 | return 0; |
926 | spin_lock_irqsave(&info->lock,flags); | 926 | spin_lock_irqsave(&info->lock,flags); |
927 | if (!info->tx_active && (info->tx_count < info->max_frame_size)) | 927 | if (!info->tx_active && (info->tx_count < info->max_frame_size)) { |
928 | info->tx_buf[info->tx_count++] = ch; | 928 | info->tx_buf[info->tx_count++] = ch; |
929 | ret = 1; | ||
930 | } | ||
929 | spin_unlock_irqrestore(&info->lock,flags); | 931 | spin_unlock_irqrestore(&info->lock,flags); |
932 | return ret; | ||
930 | } | 933 | } |
931 | 934 | ||
932 | static void send_xchar(struct tty_struct *tty, char ch) | 935 | static void send_xchar(struct tty_struct *tty, char ch) |
@@ -967,6 +970,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
967 | * Note: use tight timings here to satisfy the NIST-PCTS. | 970 | * Note: use tight timings here to satisfy the NIST-PCTS. |
968 | */ | 971 | */ |
969 | 972 | ||
973 | lock_kernel(); | ||
974 | |||
970 | if (info->params.data_rate) { | 975 | if (info->params.data_rate) { |
971 | char_time = info->timeout/(32 * 5); | 976 | char_time = info->timeout/(32 * 5); |
972 | if (!char_time) | 977 | if (!char_time) |
@@ -984,6 +989,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
984 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 989 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
985 | break; | 990 | break; |
986 | } | 991 | } |
992 | unlock_kernel(); | ||
987 | 993 | ||
988 | exit: | 994 | exit: |
989 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); | 995 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); |
@@ -1097,6 +1103,7 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1097 | struct serial_icounter_struct __user *p_cuser; /* user space */ | 1103 | struct serial_icounter_struct __user *p_cuser; /* user space */ |
1098 | unsigned long flags; | 1104 | unsigned long flags; |
1099 | void __user *argp = (void __user *)arg; | 1105 | void __user *argp = (void __user *)arg; |
1106 | int ret; | ||
1100 | 1107 | ||
1101 | if (sanity_check(info, tty->name, "ioctl")) | 1108 | if (sanity_check(info, tty->name, "ioctl")) |
1102 | return -ENODEV; | 1109 | return -ENODEV; |
@@ -1108,37 +1115,54 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1108 | return -EIO; | 1115 | return -EIO; |
1109 | } | 1116 | } |
1110 | 1117 | ||
1118 | lock_kernel(); | ||
1119 | |||
1111 | switch (cmd) { | 1120 | switch (cmd) { |
1112 | case MGSL_IOCGPARAMS: | 1121 | case MGSL_IOCGPARAMS: |
1113 | return get_params(info, argp); | 1122 | ret = get_params(info, argp); |
1123 | break; | ||
1114 | case MGSL_IOCSPARAMS: | 1124 | case MGSL_IOCSPARAMS: |
1115 | return set_params(info, argp); | 1125 | ret = set_params(info, argp); |
1126 | break; | ||
1116 | case MGSL_IOCGTXIDLE: | 1127 | case MGSL_IOCGTXIDLE: |
1117 | return get_txidle(info, argp); | 1128 | ret = get_txidle(info, argp); |
1129 | break; | ||
1118 | case MGSL_IOCSTXIDLE: | 1130 | case MGSL_IOCSTXIDLE: |
1119 | return set_txidle(info, (int)arg); | 1131 | ret = set_txidle(info, (int)arg); |
1132 | break; | ||
1120 | case MGSL_IOCTXENABLE: | 1133 | case MGSL_IOCTXENABLE: |
1121 | return tx_enable(info, (int)arg); | 1134 | ret = tx_enable(info, (int)arg); |
1135 | break; | ||
1122 | case MGSL_IOCRXENABLE: | 1136 | case MGSL_IOCRXENABLE: |
1123 | return rx_enable(info, (int)arg); | 1137 | ret = rx_enable(info, (int)arg); |
1138 | break; | ||
1124 | case MGSL_IOCTXABORT: | 1139 | case MGSL_IOCTXABORT: |
1125 | return tx_abort(info); | 1140 | ret = tx_abort(info); |
1141 | break; | ||
1126 | case MGSL_IOCGSTATS: | 1142 | case MGSL_IOCGSTATS: |
1127 | return get_stats(info, argp); | 1143 | ret = get_stats(info, argp); |
1144 | break; | ||
1128 | case MGSL_IOCWAITEVENT: | 1145 | case MGSL_IOCWAITEVENT: |
1129 | return wait_mgsl_event(info, argp); | 1146 | ret = wait_mgsl_event(info, argp); |
1147 | break; | ||
1130 | case TIOCMIWAIT: | 1148 | case TIOCMIWAIT: |
1131 | return modem_input_wait(info,(int)arg); | 1149 | ret = modem_input_wait(info,(int)arg); |
1150 | break; | ||
1132 | case MGSL_IOCGIF: | 1151 | case MGSL_IOCGIF: |
1133 | return get_interface(info, argp); | 1152 | ret = get_interface(info, argp); |
1153 | break; | ||
1134 | case MGSL_IOCSIF: | 1154 | case MGSL_IOCSIF: |
1135 | return set_interface(info,(int)arg); | 1155 | ret = set_interface(info,(int)arg); |
1156 | break; | ||
1136 | case MGSL_IOCSGPIO: | 1157 | case MGSL_IOCSGPIO: |
1137 | return set_gpio(info, argp); | 1158 | ret = set_gpio(info, argp); |
1159 | break; | ||
1138 | case MGSL_IOCGGPIO: | 1160 | case MGSL_IOCGGPIO: |
1139 | return get_gpio(info, argp); | 1161 | ret = get_gpio(info, argp); |
1162 | break; | ||
1140 | case MGSL_IOCWAITGPIO: | 1163 | case MGSL_IOCWAITGPIO: |
1141 | return wait_gpio(info, argp); | 1164 | ret = wait_gpio(info, argp); |
1165 | break; | ||
1142 | case TIOCGICOUNT: | 1166 | case TIOCGICOUNT: |
1143 | spin_lock_irqsave(&info->lock,flags); | 1167 | spin_lock_irqsave(&info->lock,flags); |
1144 | cnow = info->icount; | 1168 | cnow = info->icount; |
@@ -1155,12 +1179,14 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1155 | put_user(cnow.parity, &p_cuser->parity) || | 1179 | put_user(cnow.parity, &p_cuser->parity) || |
1156 | put_user(cnow.brk, &p_cuser->brk) || | 1180 | put_user(cnow.brk, &p_cuser->brk) || |
1157 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | 1181 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) |
1158 | return -EFAULT; | 1182 | ret = -EFAULT; |
1159 | return 0; | 1183 | ret = 0; |
1184 | break; | ||
1160 | default: | 1185 | default: |
1161 | return -ENOIOCTLCMD; | 1186 | ret = -ENOIOCTLCMD; |
1162 | } | 1187 | } |
1163 | return 0; | 1188 | unlock_kernel(); |
1189 | return ret; | ||
1164 | } | 1190 | } |
1165 | 1191 | ||
1166 | /* | 1192 | /* |
@@ -3324,7 +3350,7 @@ static int claim_resources(struct slgt_info *info) | |||
3324 | else | 3350 | else |
3325 | info->reg_addr_requested = true; | 3351 | info->reg_addr_requested = true; |
3326 | 3352 | ||
3327 | info->reg_addr = ioremap(info->phys_reg_addr, SLGT_REG_SIZE); | 3353 | info->reg_addr = ioremap_nocache(info->phys_reg_addr, SLGT_REG_SIZE); |
3328 | if (!info->reg_addr) { | 3354 | if (!info->reg_addr) { |
3329 | DBGERR(("%s cant map device registers, addr=%08X\n", | 3355 | DBGERR(("%s cant map device registers, addr=%08X\n", |
3330 | info->device_name, info->phys_reg_addr)); | 3356 | info->device_name, info->phys_reg_addr)); |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index e98c3e6f8216..bec54866e0bb 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -519,7 +519,7 @@ static void hangup(struct tty_struct *tty); | |||
519 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); | 519 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); |
520 | 520 | ||
521 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); | 521 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); |
522 | static void put_char(struct tty_struct *tty, unsigned char ch); | 522 | static int put_char(struct tty_struct *tty, unsigned char ch); |
523 | static void send_xchar(struct tty_struct *tty, char ch); | 523 | static void send_xchar(struct tty_struct *tty, char ch); |
524 | static void wait_until_sent(struct tty_struct *tty, int timeout); | 524 | static void wait_until_sent(struct tty_struct *tty, int timeout); |
525 | static int write_room(struct tty_struct *tty); | 525 | static int write_room(struct tty_struct *tty); |
@@ -862,8 +862,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
862 | if (info->flags & ASYNC_INITIALIZED) | 862 | if (info->flags & ASYNC_INITIALIZED) |
863 | wait_until_sent(tty, info->timeout); | 863 | wait_until_sent(tty, info->timeout); |
864 | 864 | ||
865 | if (tty->driver->flush_buffer) | 865 | flush_buffer(tty); |
866 | tty->driver->flush_buffer(tty); | ||
867 | 866 | ||
868 | tty_ldisc_flush(tty); | 867 | tty_ldisc_flush(tty); |
869 | 868 | ||
@@ -1046,10 +1045,11 @@ cleanup: | |||
1046 | 1045 | ||
1047 | /* Add a character to the transmit buffer. | 1046 | /* Add a character to the transmit buffer. |
1048 | */ | 1047 | */ |
1049 | static void put_char(struct tty_struct *tty, unsigned char ch) | 1048 | static int put_char(struct tty_struct *tty, unsigned char ch) |
1050 | { | 1049 | { |
1051 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; | 1050 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; |
1052 | unsigned long flags; | 1051 | unsigned long flags; |
1052 | int ret = 0; | ||
1053 | 1053 | ||
1054 | if ( debug_level >= DEBUG_LEVEL_INFO ) { | 1054 | if ( debug_level >= DEBUG_LEVEL_INFO ) { |
1055 | printk( "%s(%d):%s put_char(%d)\n", | 1055 | printk( "%s(%d):%s put_char(%d)\n", |
@@ -1057,10 +1057,10 @@ static void put_char(struct tty_struct *tty, unsigned char ch) | |||
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | if (sanity_check(info, tty->name, "put_char")) | 1059 | if (sanity_check(info, tty->name, "put_char")) |
1060 | return; | 1060 | return 0; |
1061 | 1061 | ||
1062 | if (!info->tx_buf) | 1062 | if (!info->tx_buf) |
1063 | return; | 1063 | return 0; |
1064 | 1064 | ||
1065 | spin_lock_irqsave(&info->lock,flags); | 1065 | spin_lock_irqsave(&info->lock,flags); |
1066 | 1066 | ||
@@ -1072,10 +1072,12 @@ static void put_char(struct tty_struct *tty, unsigned char ch) | |||
1072 | if (info->tx_put >= info->max_frame_size) | 1072 | if (info->tx_put >= info->max_frame_size) |
1073 | info->tx_put -= info->max_frame_size; | 1073 | info->tx_put -= info->max_frame_size; |
1074 | info->tx_count++; | 1074 | info->tx_count++; |
1075 | ret = 1; | ||
1075 | } | 1076 | } |
1076 | } | 1077 | } |
1077 | 1078 | ||
1078 | spin_unlock_irqrestore(&info->lock,flags); | 1079 | spin_unlock_irqrestore(&info->lock,flags); |
1080 | return ret; | ||
1079 | } | 1081 | } |
1080 | 1082 | ||
1081 | /* Send a high-priority XON/XOFF character | 1083 | /* Send a high-priority XON/XOFF character |
@@ -1119,6 +1121,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1119 | if (sanity_check(info, tty->name, "wait_until_sent")) | 1121 | if (sanity_check(info, tty->name, "wait_until_sent")) |
1120 | return; | 1122 | return; |
1121 | 1123 | ||
1124 | lock_kernel(); | ||
1125 | |||
1122 | if (!(info->flags & ASYNC_INITIALIZED)) | 1126 | if (!(info->flags & ASYNC_INITIALIZED)) |
1123 | goto exit; | 1127 | goto exit; |
1124 | 1128 | ||
@@ -1161,6 +1165,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1161 | } | 1165 | } |
1162 | 1166 | ||
1163 | exit: | 1167 | exit: |
1168 | unlock_kernel(); | ||
1164 | if (debug_level >= DEBUG_LEVEL_INFO) | 1169 | if (debug_level >= DEBUG_LEVEL_INFO) |
1165 | printk("%s(%d):%s wait_until_sent() exit\n", | 1170 | printk("%s(%d):%s wait_until_sent() exit\n", |
1166 | __FILE__,__LINE__, info->device_name ); | 1171 | __FILE__,__LINE__, info->device_name ); |
@@ -1176,6 +1181,7 @@ static int write_room(struct tty_struct *tty) | |||
1176 | if (sanity_check(info, tty->name, "write_room")) | 1181 | if (sanity_check(info, tty->name, "write_room")) |
1177 | return 0; | 1182 | return 0; |
1178 | 1183 | ||
1184 | lock_kernel(); | ||
1179 | if (info->params.mode == MGSL_MODE_HDLC) { | 1185 | if (info->params.mode == MGSL_MODE_HDLC) { |
1180 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; | 1186 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; |
1181 | } else { | 1187 | } else { |
@@ -1183,6 +1189,7 @@ static int write_room(struct tty_struct *tty) | |||
1183 | if (ret < 0) | 1189 | if (ret < 0) |
1184 | ret = 0; | 1190 | ret = 0; |
1185 | } | 1191 | } |
1192 | unlock_kernel(); | ||
1186 | 1193 | ||
1187 | if (debug_level >= DEBUG_LEVEL_INFO) | 1194 | if (debug_level >= DEBUG_LEVEL_INFO) |
1188 | printk("%s(%d):%s write_room()=%d\n", | 1195 | printk("%s(%d):%s write_room()=%d\n", |
@@ -1303,7 +1310,7 @@ static void tx_release(struct tty_struct *tty) | |||
1303 | * | 1310 | * |
1304 | * Return Value: 0 if success, otherwise error code | 1311 | * Return Value: 0 if success, otherwise error code |
1305 | */ | 1312 | */ |
1306 | static int ioctl(struct tty_struct *tty, struct file *file, | 1313 | static int do_ioctl(struct tty_struct *tty, struct file *file, |
1307 | unsigned int cmd, unsigned long arg) | 1314 | unsigned int cmd, unsigned long arg) |
1308 | { | 1315 | { |
1309 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; | 1316 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; |
@@ -1393,6 +1400,16 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1393 | return 0; | 1400 | return 0; |
1394 | } | 1401 | } |
1395 | 1402 | ||
1403 | static int ioctl(struct tty_struct *tty, struct file *file, | ||
1404 | unsigned int cmd, unsigned long arg) | ||
1405 | { | ||
1406 | int ret; | ||
1407 | lock_kernel(); | ||
1408 | ret = do_ioctl(tty, file, cmd, arg); | ||
1409 | unlock_kernel(); | ||
1410 | return ret; | ||
1411 | } | ||
1412 | |||
1396 | /* | 1413 | /* |
1397 | * /proc fs routines.... | 1414 | * /proc fs routines.... |
1398 | */ | 1415 | */ |
@@ -3626,7 +3643,8 @@ static int claim_resources(SLMP_INFO *info) | |||
3626 | else | 3643 | else |
3627 | info->sca_statctrl_requested = true; | 3644 | info->sca_statctrl_requested = true; |
3628 | 3645 | ||
3629 | info->memory_base = ioremap(info->phys_memory_base,SCA_MEM_SIZE); | 3646 | info->memory_base = ioremap_nocache(info->phys_memory_base, |
3647 | SCA_MEM_SIZE); | ||
3630 | if (!info->memory_base) { | 3648 | if (!info->memory_base) { |
3631 | printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n", | 3649 | printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n", |
3632 | __FILE__,__LINE__,info->device_name, info->phys_memory_base ); | 3650 | __FILE__,__LINE__,info->device_name, info->phys_memory_base ); |
@@ -3634,7 +3652,7 @@ static int claim_resources(SLMP_INFO *info) | |||
3634 | goto errout; | 3652 | goto errout; |
3635 | } | 3653 | } |
3636 | 3654 | ||
3637 | info->lcr_base = ioremap(info->phys_lcr_base,PAGE_SIZE); | 3655 | info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE); |
3638 | if (!info->lcr_base) { | 3656 | if (!info->lcr_base) { |
3639 | printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n", | 3657 | printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n", |
3640 | __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); | 3658 | __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); |
@@ -3643,7 +3661,7 @@ static int claim_resources(SLMP_INFO *info) | |||
3643 | } | 3661 | } |
3644 | info->lcr_base += info->lcr_offset; | 3662 | info->lcr_base += info->lcr_offset; |
3645 | 3663 | ||
3646 | info->sca_base = ioremap(info->phys_sca_base,PAGE_SIZE); | 3664 | info->sca_base = ioremap_nocache(info->phys_sca_base, PAGE_SIZE); |
3647 | if (!info->sca_base) { | 3665 | if (!info->sca_base) { |
3648 | printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n", | 3666 | printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n", |
3649 | __FILE__,__LINE__,info->device_name, info->phys_sca_base ); | 3667 | __FILE__,__LINE__,info->device_name, info->phys_sca_base ); |
@@ -3652,7 +3670,8 @@ static int claim_resources(SLMP_INFO *info) | |||
3652 | } | 3670 | } |
3653 | info->sca_base += info->sca_offset; | 3671 | info->sca_base += info->sca_offset; |
3654 | 3672 | ||
3655 | info->statctrl_base = ioremap(info->phys_statctrl_base,PAGE_SIZE); | 3673 | info->statctrl_base = ioremap_nocache(info->phys_statctrl_base, |
3674 | PAGE_SIZE); | ||
3656 | if (!info->statctrl_base) { | 3675 | if (!info->statctrl_base) { |
3657 | printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n", | 3676 | printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n", |
3658 | __FILE__,__LINE__,info->device_name, info->phys_statctrl_base ); | 3677 | __FILE__,__LINE__,info->device_name, info->phys_statctrl_base ); |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1ade193c9128..9e9bad8bdcf4 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -196,6 +196,48 @@ static struct sysrq_key_op sysrq_showlocks_op = { | |||
196 | #define sysrq_showlocks_op (*(struct sysrq_key_op *)0) | 196 | #define sysrq_showlocks_op (*(struct sysrq_key_op *)0) |
197 | #endif | 197 | #endif |
198 | 198 | ||
199 | #ifdef CONFIG_SMP | ||
200 | static DEFINE_SPINLOCK(show_lock); | ||
201 | |||
202 | static void showacpu(void *dummy) | ||
203 | { | ||
204 | unsigned long flags; | ||
205 | |||
206 | /* Idle CPUs have no interesting backtrace. */ | ||
207 | if (idle_cpu(smp_processor_id())) | ||
208 | return; | ||
209 | |||
210 | spin_lock_irqsave(&show_lock, flags); | ||
211 | printk(KERN_INFO "CPU%d:\n", smp_processor_id()); | ||
212 | show_stack(NULL, NULL); | ||
213 | spin_unlock_irqrestore(&show_lock, flags); | ||
214 | } | ||
215 | |||
216 | static void sysrq_showregs_othercpus(struct work_struct *dummy) | ||
217 | { | ||
218 | smp_call_function(showacpu, NULL, 0, 0); | ||
219 | } | ||
220 | |||
221 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | ||
222 | |||
223 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | ||
224 | { | ||
225 | struct pt_regs *regs = get_irq_regs(); | ||
226 | if (regs) { | ||
227 | printk(KERN_INFO "CPU%d:\n", smp_processor_id()); | ||
228 | show_regs(regs); | ||
229 | } | ||
230 | schedule_work(&sysrq_showallcpus); | ||
231 | } | ||
232 | |||
233 | static struct sysrq_key_op sysrq_showallcpus_op = { | ||
234 | .handler = sysrq_handle_showallcpus, | ||
235 | .help_msg = "aLlcpus", | ||
236 | .action_msg = "Show backtrace of all active CPUs", | ||
237 | .enable_mask = SYSRQ_ENABLE_DUMP, | ||
238 | }; | ||
239 | #endif | ||
240 | |||
199 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) | 241 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) |
200 | { | 242 | { |
201 | struct pt_regs *regs = get_irq_regs(); | 243 | struct pt_regs *regs = get_irq_regs(); |
@@ -340,7 +382,11 @@ static struct sysrq_key_op *sysrq_key_table[36] = { | |||
340 | &sysrq_kill_op, /* i */ | 382 | &sysrq_kill_op, /* i */ |
341 | NULL, /* j */ | 383 | NULL, /* j */ |
342 | &sysrq_SAK_op, /* k */ | 384 | &sysrq_SAK_op, /* k */ |
385 | #ifdef CONFIG_SMP | ||
386 | &sysrq_showallcpus_op, /* l */ | ||
387 | #else | ||
343 | NULL, /* l */ | 388 | NULL, /* l */ |
389 | #endif | ||
344 | &sysrq_showmem_op, /* m */ | 390 | &sysrq_showmem_op, /* m */ |
345 | &sysrq_unrt_op, /* n */ | 391 | &sysrq_unrt_op, /* n */ |
346 | /* o: This will often be registered as 'Off' at init time */ | 392 | /* o: This will often be registered as 'Off' at init time */ |
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index ce5ebe3b168f..663cd15d7c78 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -426,7 +426,7 @@ static int tosh_probe(void) | |||
426 | int i,major,minor,day,year,month,flag; | 426 | int i,major,minor,day,year,month,flag; |
427 | unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 }; | 427 | unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 }; |
428 | SMMRegisters regs; | 428 | SMMRegisters regs; |
429 | void __iomem *bios = ioremap(0xf0000, 0x10000); | 429 | void __iomem *bios = ioremap_cache(0xf0000, 0x10000); |
430 | 430 | ||
431 | if (!bios) | 431 | if (!bios) |
432 | return -ENOMEM; | 432 | return -ENOMEM; |
@@ -520,12 +520,11 @@ static int __init toshiba_init(void) | |||
520 | { | 520 | { |
521 | struct proc_dir_entry *pde; | 521 | struct proc_dir_entry *pde; |
522 | 522 | ||
523 | pde = create_proc_entry("toshiba", 0, NULL); | 523 | pde = proc_create("toshiba", 0, NULL, &proc_toshiba_fops); |
524 | if (!pde) { | 524 | if (!pde) { |
525 | misc_deregister(&tosh_device); | 525 | misc_deregister(&tosh_device); |
526 | return -ENOMEM; | 526 | return -ENOMEM; |
527 | } | 527 | } |
528 | pde->proc_fops = &proc_toshiba_fops; | ||
529 | } | 528 | } |
530 | #endif | 529 | #endif |
531 | 530 | ||
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 8f3f7620f95a..3738cfa209ff 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -23,7 +23,7 @@ if TCG_TPM | |||
23 | 23 | ||
24 | config TCG_TIS | 24 | config TCG_TIS |
25 | tristate "TPM Interface Specification 1.2 Interface" | 25 | tristate "TPM Interface Specification 1.2 Interface" |
26 | depends on PNPACPI | 26 | depends on PNP |
27 | ---help--- | 27 | ---help--- |
28 | If you have a TPM security chip that is compliant with the | 28 | If you have a TPM security chip that is compliant with the |
29 | TCG TIS 1.2 TPM specification say Yes and it will be accessible | 29 | TCG TIS 1.2 TPM specification say Yes and it will be accessible |
@@ -32,7 +32,6 @@ config TCG_TIS | |||
32 | 32 | ||
33 | config TCG_NSC | 33 | config TCG_NSC |
34 | tristate "National Semiconductor TPM Interface" | 34 | tristate "National Semiconductor TPM Interface" |
35 | depends on PNPACPI | ||
36 | ---help--- | 35 | ---help--- |
37 | If you have a TPM security chip from National Semiconductor | 36 | If you have a TPM security chip from National Semiconductor |
38 | say Yes and it will be accessible from within Linux. To | 37 | say Yes and it will be accessible from within Linux. To |
@@ -48,7 +47,7 @@ config TCG_ATMEL | |||
48 | 47 | ||
49 | config TCG_INFINEON | 48 | config TCG_INFINEON |
50 | tristate "Infineon Technologies TPM Interface" | 49 | tristate "Infineon Technologies TPM Interface" |
51 | depends on PNPACPI | 50 | depends on PNP |
52 | ---help--- | 51 | ---help--- |
53 | If you have a TPM security chip from Infineon Technologies | 52 | If you have a TPM security chip from Infineon Technologies |
54 | (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it | 53 | (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 6313326bc41f..ab18c1e7b115 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -264,7 +264,7 @@ static const struct tpm_vendor_specific tpm_nsc = { | |||
264 | 264 | ||
265 | static struct platform_device *pdev = NULL; | 265 | static struct platform_device *pdev = NULL; |
266 | 266 | ||
267 | static void __devexit tpm_nsc_remove(struct device *dev) | 267 | static void tpm_nsc_remove(struct device *dev) |
268 | { | 268 | { |
269 | struct tpm_chip *chip = dev_get_drvdata(dev); | 269 | struct tpm_chip *chip = dev_get_drvdata(dev); |
270 | if ( chip ) { | 270 | if ( chip ) { |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 7722466e052f..3582f43345a8 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/audit.h> | 12 | #include <linux/audit.h> |
13 | #include <linux/file.h> | 13 | #include <linux/file.h> |
14 | #include <linux/fdtable.h> | ||
14 | #include <linux/tty.h> | 15 | #include <linux/tty.h> |
15 | 16 | ||
16 | struct tty_audit_buf { | 17 | struct tty_audit_buf { |
@@ -92,7 +93,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
92 | get_task_comm(name, tsk); | 93 | get_task_comm(name, tsk); |
93 | audit_log_untrustedstring(ab, name); | 94 | audit_log_untrustedstring(ab, name); |
94 | audit_log_format(ab, " data="); | 95 | audit_log_format(ab, " data="); |
95 | audit_log_n_untrustedstring(ab, buf->valid, buf->data); | 96 | audit_log_n_untrustedstring(ab, buf->data, buf->valid); |
96 | audit_log_end(ab); | 97 | audit_log_end(ab); |
97 | } | 98 | } |
98 | buf->valid = 0; | 99 | buf->valid = 0; |
@@ -151,14 +152,9 @@ void tty_audit_fork(struct signal_struct *sig) | |||
151 | /** | 152 | /** |
152 | * tty_audit_push_task - Flush task's pending audit data | 153 | * tty_audit_push_task - Flush task's pending audit data |
153 | */ | 154 | */ |
154 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) | 155 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
155 | { | 156 | { |
156 | struct tty_audit_buf *buf; | 157 | struct tty_audit_buf *buf; |
157 | /* FIXME I think this is correct. Check against netlink once that is | ||
158 | * I really need to read this code more closely. But that's for | ||
159 | * another patch. | ||
160 | */ | ||
161 | unsigned int sessionid = audit_get_sessionid(tsk); | ||
162 | 158 | ||
163 | spin_lock_irq(&tsk->sighand->siglock); | 159 | spin_lock_irq(&tsk->sighand->siglock); |
164 | buf = tsk->signal->tty_audit_buf; | 160 | buf = tsk->signal->tty_audit_buf; |
@@ -238,6 +234,10 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
238 | if (unlikely(size == 0)) | 234 | if (unlikely(size == 0)) |
239 | return; | 235 | return; |
240 | 236 | ||
237 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY | ||
238 | && tty->driver->subtype == PTY_TYPE_MASTER) | ||
239 | return; | ||
240 | |||
241 | buf = tty_audit_buf_get(tty); | 241 | buf = tty_audit_buf_get(tty); |
242 | if (!buf) | 242 | if (!buf) |
243 | return; | 243 | return; |
@@ -300,53 +300,3 @@ void tty_audit_push(struct tty_struct *tty) | |||
300 | tty_audit_buf_put(buf); | 300 | tty_audit_buf_put(buf); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | |||
304 | /** | ||
305 | * tty_audit_opening - A TTY is being opened. | ||
306 | * | ||
307 | * As a special hack, tasks that close all their TTYs and open new ones | ||
308 | * are assumed to be system daemons (e.g. getty) and auditing is | ||
309 | * automatically disabled for them. | ||
310 | */ | ||
311 | void tty_audit_opening(void) | ||
312 | { | ||
313 | int disable; | ||
314 | |||
315 | disable = 1; | ||
316 | spin_lock_irq(¤t->sighand->siglock); | ||
317 | if (current->signal->audit_tty == 0) | ||
318 | disable = 0; | ||
319 | spin_unlock_irq(¤t->sighand->siglock); | ||
320 | if (!disable) | ||
321 | return; | ||
322 | |||
323 | task_lock(current); | ||
324 | if (current->files) { | ||
325 | struct fdtable *fdt; | ||
326 | unsigned i; | ||
327 | |||
328 | /* | ||
329 | * We don't take a ref to the file, so we must hold ->file_lock | ||
330 | * instead. | ||
331 | */ | ||
332 | spin_lock(¤t->files->file_lock); | ||
333 | fdt = files_fdtable(current->files); | ||
334 | for (i = 0; i < fdt->max_fds; i++) { | ||
335 | struct file *filp; | ||
336 | |||
337 | filp = fcheck_files(current->files, i); | ||
338 | if (filp && is_tty(filp)) { | ||
339 | disable = 0; | ||
340 | break; | ||
341 | } | ||
342 | } | ||
343 | spin_unlock(¤t->files->file_lock); | ||
344 | } | ||
345 | task_unlock(current); | ||
346 | if (!disable) | ||
347 | return; | ||
348 | |||
349 | spin_lock_irq(¤t->sighand->siglock); | ||
350 | current->signal->audit_tty = 0; | ||
351 | spin_unlock_irq(¤t->sighand->siglock); | ||
352 | } | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 98b65a230994..49c1a2267a55 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #include <linux/tty_flip.h> | 78 | #include <linux/tty_flip.h> |
79 | #include <linux/devpts_fs.h> | 79 | #include <linux/devpts_fs.h> |
80 | #include <linux/file.h> | 80 | #include <linux/file.h> |
81 | #include <linux/fdtable.h> | ||
81 | #include <linux/console.h> | 82 | #include <linux/console.h> |
82 | #include <linux/timer.h> | 83 | #include <linux/timer.h> |
83 | #include <linux/ctype.h> | 84 | #include <linux/ctype.h> |
@@ -91,7 +92,6 @@ | |||
91 | #include <linux/module.h> | 92 | #include <linux/module.h> |
92 | #include <linux/smp_lock.h> | 93 | #include <linux/smp_lock.h> |
93 | #include <linux/device.h> | 94 | #include <linux/device.h> |
94 | #include <linux/idr.h> | ||
95 | #include <linux/wait.h> | 95 | #include <linux/wait.h> |
96 | #include <linux/bitops.h> | 96 | #include <linux/bitops.h> |
97 | #include <linux/delay.h> | 97 | #include <linux/delay.h> |
@@ -137,9 +137,6 @@ EXPORT_SYMBOL(tty_mutex); | |||
137 | 137 | ||
138 | #ifdef CONFIG_UNIX98_PTYS | 138 | #ifdef CONFIG_UNIX98_PTYS |
139 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ | 139 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ |
140 | extern int pty_limit; /* Config limit on Unix98 ptys */ | ||
141 | static DEFINE_IDR(allocated_ptys); | ||
142 | static DEFINE_MUTEX(allocated_ptys_lock); | ||
143 | static int ptmx_open(struct inode *, struct file *); | 140 | static int ptmx_open(struct inode *, struct file *); |
144 | #endif | 141 | #endif |
145 | 142 | ||
@@ -152,8 +149,7 @@ ssize_t redirected_tty_write(struct file *, const char __user *, | |||
152 | static unsigned int tty_poll(struct file *, poll_table *); | 149 | static unsigned int tty_poll(struct file *, poll_table *); |
153 | static int tty_open(struct inode *, struct file *); | 150 | static int tty_open(struct inode *, struct file *); |
154 | static int tty_release(struct inode *, struct file *); | 151 | static int tty_release(struct inode *, struct file *); |
155 | int tty_ioctl(struct inode *inode, struct file *file, | 152 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
156 | unsigned int cmd, unsigned long arg); | ||
157 | #ifdef CONFIG_COMPAT | 153 | #ifdef CONFIG_COMPAT |
158 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, | 154 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
159 | unsigned long arg); | 155 | unsigned long arg); |
@@ -1109,8 +1105,8 @@ restart: | |||
1109 | a reference to the old ldisc. If we ended up flipping back | 1105 | a reference to the old ldisc. If we ended up flipping back |
1110 | to the existing ldisc we have two references to it */ | 1106 | to the existing ldisc we have two references to it */ |
1111 | 1107 | ||
1112 | if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc) | 1108 | if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc) |
1113 | tty->driver->set_ldisc(tty); | 1109 | tty->ops->set_ldisc(tty); |
1114 | 1110 | ||
1115 | tty_ldisc_put(o_ldisc.num); | 1111 | tty_ldisc_put(o_ldisc.num); |
1116 | 1112 | ||
@@ -1182,9 +1178,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
1182 | if (*str == '\0') | 1178 | if (*str == '\0') |
1183 | str = NULL; | 1179 | str = NULL; |
1184 | 1180 | ||
1185 | if (tty_line >= 0 && tty_line <= p->num && p->poll_init && | 1181 | if (tty_line >= 0 && tty_line <= p->num && p->ops && |
1186 | !p->poll_init(p, tty_line, str)) { | 1182 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { |
1187 | |||
1188 | res = p; | 1183 | res = p; |
1189 | *line = tty_line; | 1184 | *line = tty_line; |
1190 | break; | 1185 | break; |
@@ -1205,26 +1200,37 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver); | |||
1205 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | 1200 | * not in the foreground, send a SIGTTOU. If the signal is blocked or |
1206 | * ignored, go ahead and perform the operation. (POSIX 7.2) | 1201 | * ignored, go ahead and perform the operation. (POSIX 7.2) |
1207 | * | 1202 | * |
1208 | * Locking: none | 1203 | * Locking: ctrl_lock |
1209 | */ | 1204 | */ |
1210 | 1205 | ||
1211 | int tty_check_change(struct tty_struct *tty) | 1206 | int tty_check_change(struct tty_struct *tty) |
1212 | { | 1207 | { |
1208 | unsigned long flags; | ||
1209 | int ret = 0; | ||
1210 | |||
1213 | if (current->signal->tty != tty) | 1211 | if (current->signal->tty != tty) |
1214 | return 0; | 1212 | return 0; |
1213 | |||
1214 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1215 | |||
1215 | if (!tty->pgrp) { | 1216 | if (!tty->pgrp) { |
1216 | printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); | 1217 | printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); |
1217 | return 0; | 1218 | goto out; |
1218 | } | 1219 | } |
1219 | if (task_pgrp(current) == tty->pgrp) | 1220 | if (task_pgrp(current) == tty->pgrp) |
1220 | return 0; | 1221 | goto out; |
1221 | if (is_ignored(SIGTTOU)) | 1222 | if (is_ignored(SIGTTOU)) |
1222 | return 0; | 1223 | goto out; |
1223 | if (is_current_pgrp_orphaned()) | 1224 | if (is_current_pgrp_orphaned()) { |
1224 | return -EIO; | 1225 | ret = -EIO; |
1226 | goto out; | ||
1227 | } | ||
1225 | kill_pgrp(task_pgrp(current), SIGTTOU, 1); | 1228 | kill_pgrp(task_pgrp(current), SIGTTOU, 1); |
1226 | set_thread_flag(TIF_SIGPENDING); | 1229 | set_thread_flag(TIF_SIGPENDING); |
1227 | return -ERESTARTSYS; | 1230 | ret = -ERESTARTSYS; |
1231 | out: | ||
1232 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1233 | return ret; | ||
1228 | } | 1234 | } |
1229 | 1235 | ||
1230 | EXPORT_SYMBOL(tty_check_change); | 1236 | EXPORT_SYMBOL(tty_check_change); |
@@ -1247,8 +1253,8 @@ static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait) | |||
1247 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; | 1253 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; |
1248 | } | 1254 | } |
1249 | 1255 | ||
1250 | static int hung_up_tty_ioctl(struct inode *inode, struct file *file, | 1256 | static long hung_up_tty_ioctl(struct file *file, unsigned int cmd, |
1251 | unsigned int cmd, unsigned long arg) | 1257 | unsigned long arg) |
1252 | { | 1258 | { |
1253 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 1259 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
1254 | } | 1260 | } |
@@ -1264,7 +1270,7 @@ static const struct file_operations tty_fops = { | |||
1264 | .read = tty_read, | 1270 | .read = tty_read, |
1265 | .write = tty_write, | 1271 | .write = tty_write, |
1266 | .poll = tty_poll, | 1272 | .poll = tty_poll, |
1267 | .ioctl = tty_ioctl, | 1273 | .unlocked_ioctl = tty_ioctl, |
1268 | .compat_ioctl = tty_compat_ioctl, | 1274 | .compat_ioctl = tty_compat_ioctl, |
1269 | .open = tty_open, | 1275 | .open = tty_open, |
1270 | .release = tty_release, | 1276 | .release = tty_release, |
@@ -1277,7 +1283,7 @@ static const struct file_operations ptmx_fops = { | |||
1277 | .read = tty_read, | 1283 | .read = tty_read, |
1278 | .write = tty_write, | 1284 | .write = tty_write, |
1279 | .poll = tty_poll, | 1285 | .poll = tty_poll, |
1280 | .ioctl = tty_ioctl, | 1286 | .unlocked_ioctl = tty_ioctl, |
1281 | .compat_ioctl = tty_compat_ioctl, | 1287 | .compat_ioctl = tty_compat_ioctl, |
1282 | .open = ptmx_open, | 1288 | .open = ptmx_open, |
1283 | .release = tty_release, | 1289 | .release = tty_release, |
@@ -1290,7 +1296,7 @@ static const struct file_operations console_fops = { | |||
1290 | .read = tty_read, | 1296 | .read = tty_read, |
1291 | .write = redirected_tty_write, | 1297 | .write = redirected_tty_write, |
1292 | .poll = tty_poll, | 1298 | .poll = tty_poll, |
1293 | .ioctl = tty_ioctl, | 1299 | .unlocked_ioctl = tty_ioctl, |
1294 | .compat_ioctl = tty_compat_ioctl, | 1300 | .compat_ioctl = tty_compat_ioctl, |
1295 | .open = tty_open, | 1301 | .open = tty_open, |
1296 | .release = tty_release, | 1302 | .release = tty_release, |
@@ -1302,7 +1308,7 @@ static const struct file_operations hung_up_tty_fops = { | |||
1302 | .read = hung_up_tty_read, | 1308 | .read = hung_up_tty_read, |
1303 | .write = hung_up_tty_write, | 1309 | .write = hung_up_tty_write, |
1304 | .poll = hung_up_tty_poll, | 1310 | .poll = hung_up_tty_poll, |
1305 | .ioctl = hung_up_tty_ioctl, | 1311 | .unlocked_ioctl = hung_up_tty_ioctl, |
1306 | .compat_ioctl = hung_up_tty_compat_ioctl, | 1312 | .compat_ioctl = hung_up_tty_compat_ioctl, |
1307 | .release = tty_release, | 1313 | .release = tty_release, |
1308 | }; | 1314 | }; |
@@ -1404,6 +1410,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
1404 | struct task_struct *p; | 1410 | struct task_struct *p; |
1405 | struct tty_ldisc *ld; | 1411 | struct tty_ldisc *ld; |
1406 | int closecount = 0, n; | 1412 | int closecount = 0, n; |
1413 | unsigned long flags; | ||
1407 | 1414 | ||
1408 | if (!tty) | 1415 | if (!tty) |
1409 | return; | 1416 | return; |
@@ -1441,8 +1448,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
1441 | /* We may have no line discipline at this point */ | 1448 | /* We may have no line discipline at this point */ |
1442 | if (ld->flush_buffer) | 1449 | if (ld->flush_buffer) |
1443 | ld->flush_buffer(tty); | 1450 | ld->flush_buffer(tty); |
1444 | if (tty->driver->flush_buffer) | 1451 | tty_driver_flush_buffer(tty); |
1445 | tty->driver->flush_buffer(tty); | ||
1446 | if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && | 1452 | if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && |
1447 | ld->write_wakeup) | 1453 | ld->write_wakeup) |
1448 | ld->write_wakeup(tty); | 1454 | ld->write_wakeup(tty); |
@@ -1480,19 +1486,24 @@ static void do_tty_hangup(struct work_struct *work) | |||
1480 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | 1486 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); |
1481 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | 1487 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); |
1482 | put_pid(p->signal->tty_old_pgrp); /* A noop */ | 1488 | put_pid(p->signal->tty_old_pgrp); /* A noop */ |
1489 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1483 | if (tty->pgrp) | 1490 | if (tty->pgrp) |
1484 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); | 1491 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); |
1492 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1485 | spin_unlock_irq(&p->sighand->siglock); | 1493 | spin_unlock_irq(&p->sighand->siglock); |
1486 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); | 1494 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); |
1487 | } | 1495 | } |
1488 | read_unlock(&tasklist_lock); | 1496 | read_unlock(&tasklist_lock); |
1489 | 1497 | ||
1498 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1490 | tty->flags = 0; | 1499 | tty->flags = 0; |
1491 | put_pid(tty->session); | 1500 | put_pid(tty->session); |
1492 | put_pid(tty->pgrp); | 1501 | put_pid(tty->pgrp); |
1493 | tty->session = NULL; | 1502 | tty->session = NULL; |
1494 | tty->pgrp = NULL; | 1503 | tty->pgrp = NULL; |
1495 | tty->ctrl_status = 0; | 1504 | tty->ctrl_status = 0; |
1505 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1506 | |||
1496 | /* | 1507 | /* |
1497 | * If one of the devices matches a console pointer, we | 1508 | * If one of the devices matches a console pointer, we |
1498 | * cannot just call hangup() because that will cause | 1509 | * cannot just call hangup() because that will cause |
@@ -1500,11 +1511,11 @@ static void do_tty_hangup(struct work_struct *work) | |||
1500 | * So we just call close() the right number of times. | 1511 | * So we just call close() the right number of times. |
1501 | */ | 1512 | */ |
1502 | if (cons_filp) { | 1513 | if (cons_filp) { |
1503 | if (tty->driver->close) | 1514 | if (tty->ops->close) |
1504 | for (n = 0; n < closecount; n++) | 1515 | for (n = 0; n < closecount; n++) |
1505 | tty->driver->close(tty, cons_filp); | 1516 | tty->ops->close(tty, cons_filp); |
1506 | } else if (tty->driver->hangup) | 1517 | } else if (tty->ops->hangup) |
1507 | (tty->driver->hangup)(tty); | 1518 | (tty->ops->hangup)(tty); |
1508 | /* | 1519 | /* |
1509 | * We don't want to have driver/ldisc interactions beyond | 1520 | * We don't want to have driver/ldisc interactions beyond |
1510 | * the ones we did here. The driver layer expects no | 1521 | * the ones we did here. The driver layer expects no |
@@ -1626,16 +1637,17 @@ void disassociate_ctty(int on_exit) | |||
1626 | struct tty_struct *tty; | 1637 | struct tty_struct *tty; |
1627 | struct pid *tty_pgrp = NULL; | 1638 | struct pid *tty_pgrp = NULL; |
1628 | 1639 | ||
1629 | lock_kernel(); | ||
1630 | 1640 | ||
1631 | mutex_lock(&tty_mutex); | 1641 | mutex_lock(&tty_mutex); |
1632 | tty = get_current_tty(); | 1642 | tty = get_current_tty(); |
1633 | if (tty) { | 1643 | if (tty) { |
1634 | tty_pgrp = get_pid(tty->pgrp); | 1644 | tty_pgrp = get_pid(tty->pgrp); |
1635 | mutex_unlock(&tty_mutex); | 1645 | mutex_unlock(&tty_mutex); |
1646 | lock_kernel(); | ||
1636 | /* XXX: here we race, there is nothing protecting tty */ | 1647 | /* XXX: here we race, there is nothing protecting tty */ |
1637 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 1648 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1638 | tty_vhangup(tty); | 1649 | tty_vhangup(tty); |
1650 | unlock_kernel(); | ||
1639 | } else if (on_exit) { | 1651 | } else if (on_exit) { |
1640 | struct pid *old_pgrp; | 1652 | struct pid *old_pgrp; |
1641 | spin_lock_irq(¤t->sighand->siglock); | 1653 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1648,7 +1660,6 @@ void disassociate_ctty(int on_exit) | |||
1648 | put_pid(old_pgrp); | 1660 | put_pid(old_pgrp); |
1649 | } | 1661 | } |
1650 | mutex_unlock(&tty_mutex); | 1662 | mutex_unlock(&tty_mutex); |
1651 | unlock_kernel(); | ||
1652 | return; | 1663 | return; |
1653 | } | 1664 | } |
1654 | if (tty_pgrp) { | 1665 | if (tty_pgrp) { |
@@ -1667,10 +1678,13 @@ void disassociate_ctty(int on_exit) | |||
1667 | /* It is possible that do_tty_hangup has free'd this tty */ | 1678 | /* It is possible that do_tty_hangup has free'd this tty */ |
1668 | tty = get_current_tty(); | 1679 | tty = get_current_tty(); |
1669 | if (tty) { | 1680 | if (tty) { |
1681 | unsigned long flags; | ||
1682 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1670 | put_pid(tty->session); | 1683 | put_pid(tty->session); |
1671 | put_pid(tty->pgrp); | 1684 | put_pid(tty->pgrp); |
1672 | tty->session = NULL; | 1685 | tty->session = NULL; |
1673 | tty->pgrp = NULL; | 1686 | tty->pgrp = NULL; |
1687 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1674 | } else { | 1688 | } else { |
1675 | #ifdef TTY_DEBUG_HANGUP | 1689 | #ifdef TTY_DEBUG_HANGUP |
1676 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 1690 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
@@ -1683,7 +1697,6 @@ void disassociate_ctty(int on_exit) | |||
1683 | read_lock(&tasklist_lock); | 1697 | read_lock(&tasklist_lock); |
1684 | session_clear_tty(task_session(current)); | 1698 | session_clear_tty(task_session(current)); |
1685 | read_unlock(&tasklist_lock); | 1699 | read_unlock(&tasklist_lock); |
1686 | unlock_kernel(); | ||
1687 | } | 1700 | } |
1688 | 1701 | ||
1689 | /** | 1702 | /** |
@@ -1693,8 +1706,10 @@ void disassociate_ctty(int on_exit) | |||
1693 | void no_tty(void) | 1706 | void no_tty(void) |
1694 | { | 1707 | { |
1695 | struct task_struct *tsk = current; | 1708 | struct task_struct *tsk = current; |
1709 | lock_kernel(); | ||
1696 | if (tsk->signal->leader) | 1710 | if (tsk->signal->leader) |
1697 | disassociate_ctty(0); | 1711 | disassociate_ctty(0); |
1712 | unlock_kernel(); | ||
1698 | proc_clear_tty(tsk); | 1713 | proc_clear_tty(tsk); |
1699 | } | 1714 | } |
1700 | 1715 | ||
@@ -1714,21 +1729,26 @@ void no_tty(void) | |||
1714 | * but not always. | 1729 | * but not always. |
1715 | * | 1730 | * |
1716 | * Locking: | 1731 | * Locking: |
1717 | * Broken. Relies on BKL which is unsafe here. | 1732 | * Uses the tty control lock internally |
1718 | */ | 1733 | */ |
1719 | 1734 | ||
1720 | void stop_tty(struct tty_struct *tty) | 1735 | void stop_tty(struct tty_struct *tty) |
1721 | { | 1736 | { |
1722 | if (tty->stopped) | 1737 | unsigned long flags; |
1738 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1739 | if (tty->stopped) { | ||
1740 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1723 | return; | 1741 | return; |
1742 | } | ||
1724 | tty->stopped = 1; | 1743 | tty->stopped = 1; |
1725 | if (tty->link && tty->link->packet) { | 1744 | if (tty->link && tty->link->packet) { |
1726 | tty->ctrl_status &= ~TIOCPKT_START; | 1745 | tty->ctrl_status &= ~TIOCPKT_START; |
1727 | tty->ctrl_status |= TIOCPKT_STOP; | 1746 | tty->ctrl_status |= TIOCPKT_STOP; |
1728 | wake_up_interruptible(&tty->link->read_wait); | 1747 | wake_up_interruptible(&tty->link->read_wait); |
1729 | } | 1748 | } |
1730 | if (tty->driver->stop) | 1749 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1731 | (tty->driver->stop)(tty); | 1750 | if (tty->ops->stop) |
1751 | (tty->ops->stop)(tty); | ||
1732 | } | 1752 | } |
1733 | 1753 | ||
1734 | EXPORT_SYMBOL(stop_tty); | 1754 | EXPORT_SYMBOL(stop_tty); |
@@ -1743,21 +1763,26 @@ EXPORT_SYMBOL(stop_tty); | |||
1743 | * driver start method is invoked and the line discipline woken. | 1763 | * driver start method is invoked and the line discipline woken. |
1744 | * | 1764 | * |
1745 | * Locking: | 1765 | * Locking: |
1746 | * Broken. Relies on BKL which is unsafe here. | 1766 | * ctrl_lock |
1747 | */ | 1767 | */ |
1748 | 1768 | ||
1749 | void start_tty(struct tty_struct *tty) | 1769 | void start_tty(struct tty_struct *tty) |
1750 | { | 1770 | { |
1751 | if (!tty->stopped || tty->flow_stopped) | 1771 | unsigned long flags; |
1772 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
1773 | if (!tty->stopped || tty->flow_stopped) { | ||
1774 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
1752 | return; | 1775 | return; |
1776 | } | ||
1753 | tty->stopped = 0; | 1777 | tty->stopped = 0; |
1754 | if (tty->link && tty->link->packet) { | 1778 | if (tty->link && tty->link->packet) { |
1755 | tty->ctrl_status &= ~TIOCPKT_STOP; | 1779 | tty->ctrl_status &= ~TIOCPKT_STOP; |
1756 | tty->ctrl_status |= TIOCPKT_START; | 1780 | tty->ctrl_status |= TIOCPKT_START; |
1757 | wake_up_interruptible(&tty->link->read_wait); | 1781 | wake_up_interruptible(&tty->link->read_wait); |
1758 | } | 1782 | } |
1759 | if (tty->driver->start) | 1783 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1760 | (tty->driver->start)(tty); | 1784 | if (tty->ops->start) |
1785 | (tty->ops->start)(tty); | ||
1761 | /* If we have a running line discipline it may need kicking */ | 1786 | /* If we have a running line discipline it may need kicking */ |
1762 | tty_wakeup(tty); | 1787 | tty_wakeup(tty); |
1763 | } | 1788 | } |
@@ -1775,10 +1800,8 @@ EXPORT_SYMBOL(start_tty); | |||
1775 | * for hung up devices before calling the line discipline method. | 1800 | * for hung up devices before calling the line discipline method. |
1776 | * | 1801 | * |
1777 | * Locking: | 1802 | * Locking: |
1778 | * Locks the line discipline internally while needed | 1803 | * Locks the line discipline internally while needed. Multiple |
1779 | * For historical reasons the line discipline read method is | 1804 | * read calls may be outstanding in parallel. |
1780 | * invoked under the BKL. This will go away in time so do not rely on it | ||
1781 | * in new code. Multiple read calls may be outstanding in parallel. | ||
1782 | */ | 1805 | */ |
1783 | 1806 | ||
1784 | static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | 1807 | static ssize_t tty_read(struct file *file, char __user *buf, size_t count, |
@@ -1799,13 +1822,11 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
1799 | /* We want to wait for the line discipline to sort out in this | 1822 | /* We want to wait for the line discipline to sort out in this |
1800 | situation */ | 1823 | situation */ |
1801 | ld = tty_ldisc_ref_wait(tty); | 1824 | ld = tty_ldisc_ref_wait(tty); |
1802 | lock_kernel(); | ||
1803 | if (ld->read) | 1825 | if (ld->read) |
1804 | i = (ld->read)(tty, file, buf, count); | 1826 | i = (ld->read)(tty, file, buf, count); |
1805 | else | 1827 | else |
1806 | i = -EIO; | 1828 | i = -EIO; |
1807 | tty_ldisc_deref(ld); | 1829 | tty_ldisc_deref(ld); |
1808 | unlock_kernel(); | ||
1809 | if (i > 0) | 1830 | if (i > 0) |
1810 | inode->i_atime = current_fs_time(inode->i_sb); | 1831 | inode->i_atime = current_fs_time(inode->i_sb); |
1811 | return i; | 1832 | return i; |
@@ -1893,9 +1914,7 @@ static inline ssize_t do_tty_write( | |||
1893 | ret = -EFAULT; | 1914 | ret = -EFAULT; |
1894 | if (copy_from_user(tty->write_buf, buf, size)) | 1915 | if (copy_from_user(tty->write_buf, buf, size)) |
1895 | break; | 1916 | break; |
1896 | lock_kernel(); | ||
1897 | ret = write(tty, file, tty->write_buf, size); | 1917 | ret = write(tty, file, tty->write_buf, size); |
1898 | unlock_kernel(); | ||
1899 | if (ret <= 0) | 1918 | if (ret <= 0) |
1900 | break; | 1919 | break; |
1901 | written += ret; | 1920 | written += ret; |
@@ -1948,10 +1967,13 @@ static ssize_t tty_write(struct file *file, const char __user *buf, | |||
1948 | tty = (struct tty_struct *)file->private_data; | 1967 | tty = (struct tty_struct *)file->private_data; |
1949 | if (tty_paranoia_check(tty, inode, "tty_write")) | 1968 | if (tty_paranoia_check(tty, inode, "tty_write")) |
1950 | return -EIO; | 1969 | return -EIO; |
1951 | if (!tty || !tty->driver->write || | 1970 | if (!tty || !tty->ops->write || |
1952 | (test_bit(TTY_IO_ERROR, &tty->flags))) | 1971 | (test_bit(TTY_IO_ERROR, &tty->flags))) |
1953 | return -EIO; | 1972 | return -EIO; |
1954 | 1973 | /* Short term debug to catch buggy drivers */ | |
1974 | if (tty->ops->write_room == NULL) | ||
1975 | printk(KERN_ERR "tty driver %s lacks a write_room method.\n", | ||
1976 | tty->driver->name); | ||
1955 | ld = tty_ldisc_ref_wait(tty); | 1977 | ld = tty_ldisc_ref_wait(tty); |
1956 | if (!ld->write) | 1978 | if (!ld->write) |
1957 | ret = -EIO; | 1979 | ret = -EIO; |
@@ -2098,6 +2120,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2098 | goto fail_no_mem; | 2120 | goto fail_no_mem; |
2099 | initialize_tty_struct(tty); | 2121 | initialize_tty_struct(tty); |
2100 | tty->driver = driver; | 2122 | tty->driver = driver; |
2123 | tty->ops = driver->ops; | ||
2101 | tty->index = idx; | 2124 | tty->index = idx; |
2102 | tty_line_name(driver, idx, tty->name); | 2125 | tty_line_name(driver, idx, tty->name); |
2103 | 2126 | ||
@@ -2128,6 +2151,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2128 | goto free_mem_out; | 2151 | goto free_mem_out; |
2129 | initialize_tty_struct(o_tty); | 2152 | initialize_tty_struct(o_tty); |
2130 | o_tty->driver = driver->other; | 2153 | o_tty->driver = driver->other; |
2154 | o_tty->ops = driver->ops; | ||
2131 | o_tty->index = idx; | 2155 | o_tty->index = idx; |
2132 | tty_line_name(driver->other, idx, o_tty->name); | 2156 | tty_line_name(driver->other, idx, o_tty->name); |
2133 | 2157 | ||
@@ -2432,8 +2456,8 @@ static void release_dev(struct file *filp) | |||
2432 | } | 2456 | } |
2433 | } | 2457 | } |
2434 | #endif | 2458 | #endif |
2435 | if (tty->driver->close) | 2459 | if (tty->ops->close) |
2436 | tty->driver->close(tty, filp); | 2460 | tty->ops->close(tty, filp); |
2437 | 2461 | ||
2438 | /* | 2462 | /* |
2439 | * Sanity check: if tty->count is going to zero, there shouldn't be | 2463 | * Sanity check: if tty->count is going to zero, there shouldn't be |
@@ -2612,15 +2636,9 @@ static void release_dev(struct file *filp) | |||
2612 | */ | 2636 | */ |
2613 | release_tty(tty, idx); | 2637 | release_tty(tty, idx); |
2614 | 2638 | ||
2615 | #ifdef CONFIG_UNIX98_PTYS | ||
2616 | /* Make this pty number available for reallocation */ | 2639 | /* Make this pty number available for reallocation */ |
2617 | if (devpts) { | 2640 | if (devpts) |
2618 | mutex_lock(&allocated_ptys_lock); | 2641 | devpts_kill_index(idx); |
2619 | idr_remove(&allocated_ptys, idx); | ||
2620 | mutex_unlock(&allocated_ptys_lock); | ||
2621 | } | ||
2622 | #endif | ||
2623 | |||
2624 | } | 2642 | } |
2625 | 2643 | ||
2626 | /** | 2644 | /** |
@@ -2716,8 +2734,8 @@ got_driver: | |||
2716 | printk(KERN_DEBUG "opening %s...", tty->name); | 2734 | printk(KERN_DEBUG "opening %s...", tty->name); |
2717 | #endif | 2735 | #endif |
2718 | if (!retval) { | 2736 | if (!retval) { |
2719 | if (tty->driver->open) | 2737 | if (tty->ops->open) |
2720 | retval = tty->driver->open(tty, filp); | 2738 | retval = tty->ops->open(tty, filp); |
2721 | else | 2739 | else |
2722 | retval = -ENODEV; | 2740 | retval = -ENODEV; |
2723 | } | 2741 | } |
@@ -2755,7 +2773,6 @@ got_driver: | |||
2755 | __proc_set_tty(current, tty); | 2773 | __proc_set_tty(current, tty); |
2756 | spin_unlock_irq(¤t->sighand->siglock); | 2774 | spin_unlock_irq(¤t->sighand->siglock); |
2757 | mutex_unlock(&tty_mutex); | 2775 | mutex_unlock(&tty_mutex); |
2758 | tty_audit_opening(); | ||
2759 | return 0; | 2776 | return 0; |
2760 | } | 2777 | } |
2761 | 2778 | ||
@@ -2777,29 +2794,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2777 | struct tty_struct *tty; | 2794 | struct tty_struct *tty; |
2778 | int retval; | 2795 | int retval; |
2779 | int index; | 2796 | int index; |
2780 | int idr_ret; | ||
2781 | 2797 | ||
2782 | nonseekable_open(inode, filp); | 2798 | nonseekable_open(inode, filp); |
2783 | 2799 | ||
2784 | /* find a device that is not in use. */ | 2800 | /* find a device that is not in use. */ |
2785 | mutex_lock(&allocated_ptys_lock); | 2801 | index = devpts_new_index(); |
2786 | if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { | 2802 | if (index < 0) |
2787 | mutex_unlock(&allocated_ptys_lock); | 2803 | return index; |
2788 | return -ENOMEM; | ||
2789 | } | ||
2790 | idr_ret = idr_get_new(&allocated_ptys, NULL, &index); | ||
2791 | if (idr_ret < 0) { | ||
2792 | mutex_unlock(&allocated_ptys_lock); | ||
2793 | if (idr_ret == -EAGAIN) | ||
2794 | return -ENOMEM; | ||
2795 | return -EIO; | ||
2796 | } | ||
2797 | if (index >= pty_limit) { | ||
2798 | idr_remove(&allocated_ptys, index); | ||
2799 | mutex_unlock(&allocated_ptys_lock); | ||
2800 | return -EIO; | ||
2801 | } | ||
2802 | mutex_unlock(&allocated_ptys_lock); | ||
2803 | 2804 | ||
2804 | mutex_lock(&tty_mutex); | 2805 | mutex_lock(&tty_mutex); |
2805 | retval = init_dev(ptm_driver, index, &tty); | 2806 | retval = init_dev(ptm_driver, index, &tty); |
@@ -2812,23 +2813,19 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2812 | filp->private_data = tty; | 2813 | filp->private_data = tty; |
2813 | file_move(filp, &tty->tty_files); | 2814 | file_move(filp, &tty->tty_files); |
2814 | 2815 | ||
2815 | retval = -ENOMEM; | 2816 | retval = devpts_pty_new(tty->link); |
2816 | if (devpts_pty_new(tty->link)) | 2817 | if (retval) |
2817 | goto out1; | 2818 | goto out1; |
2818 | 2819 | ||
2819 | check_tty_count(tty, "tty_open"); | 2820 | check_tty_count(tty, "ptmx_open"); |
2820 | retval = ptm_driver->open(tty, filp); | 2821 | retval = ptm_driver->ops->open(tty, filp); |
2821 | if (!retval) { | 2822 | if (!retval) |
2822 | tty_audit_opening(); | ||
2823 | return 0; | 2823 | return 0; |
2824 | } | ||
2825 | out1: | 2824 | out1: |
2826 | release_dev(filp); | 2825 | release_dev(filp); |
2827 | return retval; | 2826 | return retval; |
2828 | out: | 2827 | out: |
2829 | mutex_lock(&allocated_ptys_lock); | 2828 | devpts_kill_index(index); |
2830 | idr_remove(&allocated_ptys, index); | ||
2831 | mutex_unlock(&allocated_ptys_lock); | ||
2832 | return retval; | 2829 | return retval; |
2833 | } | 2830 | } |
2834 | #endif | 2831 | #endif |
@@ -2885,6 +2882,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
2885 | static int tty_fasync(int fd, struct file *filp, int on) | 2882 | static int tty_fasync(int fd, struct file *filp, int on) |
2886 | { | 2883 | { |
2887 | struct tty_struct *tty; | 2884 | struct tty_struct *tty; |
2885 | unsigned long flags; | ||
2888 | int retval; | 2886 | int retval; |
2889 | 2887 | ||
2890 | tty = (struct tty_struct *)filp->private_data; | 2888 | tty = (struct tty_struct *)filp->private_data; |
@@ -2900,6 +2898,7 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
2900 | struct pid *pid; | 2898 | struct pid *pid; |
2901 | if (!waitqueue_active(&tty->read_wait)) | 2899 | if (!waitqueue_active(&tty->read_wait)) |
2902 | tty->minimum_to_wake = 1; | 2900 | tty->minimum_to_wake = 1; |
2901 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
2903 | if (tty->pgrp) { | 2902 | if (tty->pgrp) { |
2904 | pid = tty->pgrp; | 2903 | pid = tty->pgrp; |
2905 | type = PIDTYPE_PGID; | 2904 | type = PIDTYPE_PGID; |
@@ -2907,6 +2906,7 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
2907 | pid = task_pid(current); | 2906 | pid = task_pid(current); |
2908 | type = PIDTYPE_PID; | 2907 | type = PIDTYPE_PID; |
2909 | } | 2908 | } |
2909 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
2910 | retval = __f_setown(filp, pid, type, 0); | 2910 | retval = __f_setown(filp, pid, type, 0); |
2911 | if (retval) | 2911 | if (retval) |
2912 | return retval; | 2912 | return retval; |
@@ -2992,6 +2992,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2992 | struct winsize __user *arg) | 2992 | struct winsize __user *arg) |
2993 | { | 2993 | { |
2994 | struct winsize tmp_ws; | 2994 | struct winsize tmp_ws; |
2995 | struct pid *pgrp, *rpgrp; | ||
2996 | unsigned long flags; | ||
2995 | 2997 | ||
2996 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | 2998 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) |
2997 | return -EFAULT; | 2999 | return -EFAULT; |
@@ -3009,10 +3011,21 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
3009 | } | 3011 | } |
3010 | } | 3012 | } |
3011 | #endif | 3013 | #endif |
3012 | if (tty->pgrp) | 3014 | /* Get the PID values and reference them so we can |
3013 | kill_pgrp(tty->pgrp, SIGWINCH, 1); | 3015 | avoid holding the tty ctrl lock while sending signals */ |
3014 | if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp) | 3016 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
3015 | kill_pgrp(real_tty->pgrp, SIGWINCH, 1); | 3017 | pgrp = get_pid(tty->pgrp); |
3018 | rpgrp = get_pid(real_tty->pgrp); | ||
3019 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
3020 | |||
3021 | if (pgrp) | ||
3022 | kill_pgrp(pgrp, SIGWINCH, 1); | ||
3023 | if (rpgrp != pgrp && rpgrp) | ||
3024 | kill_pgrp(rpgrp, SIGWINCH, 1); | ||
3025 | |||
3026 | put_pid(pgrp); | ||
3027 | put_pid(rpgrp); | ||
3028 | |||
3016 | tty->winsize = tmp_ws; | 3029 | tty->winsize = tmp_ws; |
3017 | real_tty->winsize = tmp_ws; | 3030 | real_tty->winsize = tmp_ws; |
3018 | done: | 3031 | done: |
@@ -3073,10 +3086,13 @@ static int fionbio(struct file *file, int __user *p) | |||
3073 | if (get_user(nonblock, p)) | 3086 | if (get_user(nonblock, p)) |
3074 | return -EFAULT; | 3087 | return -EFAULT; |
3075 | 3088 | ||
3089 | /* file->f_flags is still BKL protected in the fs layer - vomit */ | ||
3090 | lock_kernel(); | ||
3076 | if (nonblock) | 3091 | if (nonblock) |
3077 | file->f_flags |= O_NONBLOCK; | 3092 | file->f_flags |= O_NONBLOCK; |
3078 | else | 3093 | else |
3079 | file->f_flags &= ~O_NONBLOCK; | 3094 | file->f_flags &= ~O_NONBLOCK; |
3095 | unlock_kernel(); | ||
3080 | return 0; | 3096 | return 0; |
3081 | } | 3097 | } |
3082 | 3098 | ||
@@ -3134,6 +3150,27 @@ unlock: | |||
3134 | } | 3150 | } |
3135 | 3151 | ||
3136 | /** | 3152 | /** |
3153 | * tty_get_pgrp - return a ref counted pgrp pid | ||
3154 | * @tty: tty to read | ||
3155 | * | ||
3156 | * Returns a refcounted instance of the pid struct for the process | ||
3157 | * group controlling the tty. | ||
3158 | */ | ||
3159 | |||
3160 | struct pid *tty_get_pgrp(struct tty_struct *tty) | ||
3161 | { | ||
3162 | unsigned long flags; | ||
3163 | struct pid *pgrp; | ||
3164 | |||
3165 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
3166 | pgrp = get_pid(tty->pgrp); | ||
3167 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
3168 | |||
3169 | return pgrp; | ||
3170 | } | ||
3171 | EXPORT_SYMBOL_GPL(tty_get_pgrp); | ||
3172 | |||
3173 | /** | ||
3137 | * tiocgpgrp - get process group | 3174 | * tiocgpgrp - get process group |
3138 | * @tty: tty passed by user | 3175 | * @tty: tty passed by user |
3139 | * @real_tty: tty side of the tty pased by the user if a pty else the tty | 3176 | * @real_tty: tty side of the tty pased by the user if a pty else the tty |
@@ -3147,13 +3184,18 @@ unlock: | |||
3147 | 3184 | ||
3148 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3185 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
3149 | { | 3186 | { |
3187 | struct pid *pid; | ||
3188 | int ret; | ||
3150 | /* | 3189 | /* |
3151 | * (tty == real_tty) is a cheap way of | 3190 | * (tty == real_tty) is a cheap way of |
3152 | * testing if the tty is NOT a master pty. | 3191 | * testing if the tty is NOT a master pty. |
3153 | */ | 3192 | */ |
3154 | if (tty == real_tty && current->signal->tty != real_tty) | 3193 | if (tty == real_tty && current->signal->tty != real_tty) |
3155 | return -ENOTTY; | 3194 | return -ENOTTY; |
3156 | return put_user(pid_vnr(real_tty->pgrp), p); | 3195 | pid = tty_get_pgrp(real_tty); |
3196 | ret = put_user(pid_vnr(pid), p); | ||
3197 | put_pid(pid); | ||
3198 | return ret; | ||
3157 | } | 3199 | } |
3158 | 3200 | ||
3159 | /** | 3201 | /** |
@@ -3165,7 +3207,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
3165 | * Set the process group of the tty to the session passed. Only | 3207 | * Set the process group of the tty to the session passed. Only |
3166 | * permitted where the tty session is our session. | 3208 | * permitted where the tty session is our session. |
3167 | * | 3209 | * |
3168 | * Locking: None | 3210 | * Locking: RCU, ctrl lock |
3169 | */ | 3211 | */ |
3170 | 3212 | ||
3171 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3213 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
@@ -3173,6 +3215,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
3173 | struct pid *pgrp; | 3215 | struct pid *pgrp; |
3174 | pid_t pgrp_nr; | 3216 | pid_t pgrp_nr; |
3175 | int retval = tty_check_change(real_tty); | 3217 | int retval = tty_check_change(real_tty); |
3218 | unsigned long flags; | ||
3176 | 3219 | ||
3177 | if (retval == -EIO) | 3220 | if (retval == -EIO) |
3178 | return -ENOTTY; | 3221 | return -ENOTTY; |
@@ -3195,8 +3238,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
3195 | if (session_of_pgrp(pgrp) != task_session(current)) | 3238 | if (session_of_pgrp(pgrp) != task_session(current)) |
3196 | goto out_unlock; | 3239 | goto out_unlock; |
3197 | retval = 0; | 3240 | retval = 0; |
3241 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
3198 | put_pid(real_tty->pgrp); | 3242 | put_pid(real_tty->pgrp); |
3199 | real_tty->pgrp = get_pid(pgrp); | 3243 | real_tty->pgrp = get_pid(pgrp); |
3244 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
3200 | out_unlock: | 3245 | out_unlock: |
3201 | rcu_read_unlock(); | 3246 | rcu_read_unlock(); |
3202 | return retval; | 3247 | return retval; |
@@ -3240,10 +3285,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ | |||
3240 | static int tiocsetd(struct tty_struct *tty, int __user *p) | 3285 | static int tiocsetd(struct tty_struct *tty, int __user *p) |
3241 | { | 3286 | { |
3242 | int ldisc; | 3287 | int ldisc; |
3288 | int ret; | ||
3243 | 3289 | ||
3244 | if (get_user(ldisc, p)) | 3290 | if (get_user(ldisc, p)) |
3245 | return -EFAULT; | 3291 | return -EFAULT; |
3246 | return tty_set_ldisc(tty, ldisc); | 3292 | |
3293 | lock_kernel(); | ||
3294 | ret = tty_set_ldisc(tty, ldisc); | ||
3295 | unlock_kernel(); | ||
3296 | |||
3297 | return ret; | ||
3247 | } | 3298 | } |
3248 | 3299 | ||
3249 | /** | 3300 | /** |
@@ -3263,18 +3314,18 @@ static int send_break(struct tty_struct *tty, unsigned int duration) | |||
3263 | { | 3314 | { |
3264 | if (tty_write_lock(tty, 0) < 0) | 3315 | if (tty_write_lock(tty, 0) < 0) |
3265 | return -EINTR; | 3316 | return -EINTR; |
3266 | tty->driver->break_ctl(tty, -1); | 3317 | tty->ops->break_ctl(tty, -1); |
3267 | if (!signal_pending(current)) | 3318 | if (!signal_pending(current)) |
3268 | msleep_interruptible(duration); | 3319 | msleep_interruptible(duration); |
3269 | tty->driver->break_ctl(tty, 0); | 3320 | tty->ops->break_ctl(tty, 0); |
3270 | tty_write_unlock(tty); | 3321 | tty_write_unlock(tty); |
3271 | if (signal_pending(current)) | 3322 | if (!signal_pending(current)) |
3272 | return -EINTR; | 3323 | return -EINTR; |
3273 | return 0; | 3324 | return 0; |
3274 | } | 3325 | } |
3275 | 3326 | ||
3276 | /** | 3327 | /** |
3277 | * tiocmget - get modem status | 3328 | * tty_tiocmget - get modem status |
3278 | * @tty: tty device | 3329 | * @tty: tty device |
3279 | * @file: user file pointer | 3330 | * @file: user file pointer |
3280 | * @p: pointer to result | 3331 | * @p: pointer to result |
@@ -3289,8 +3340,8 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p | |||
3289 | { | 3340 | { |
3290 | int retval = -EINVAL; | 3341 | int retval = -EINVAL; |
3291 | 3342 | ||
3292 | if (tty->driver->tiocmget) { | 3343 | if (tty->ops->tiocmget) { |
3293 | retval = tty->driver->tiocmget(tty, file); | 3344 | retval = tty->ops->tiocmget(tty, file); |
3294 | 3345 | ||
3295 | if (retval >= 0) | 3346 | if (retval >= 0) |
3296 | retval = put_user(retval, p); | 3347 | retval = put_user(retval, p); |
@@ -3299,7 +3350,7 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p | |||
3299 | } | 3350 | } |
3300 | 3351 | ||
3301 | /** | 3352 | /** |
3302 | * tiocmset - set modem status | 3353 | * tty_tiocmset - set modem status |
3303 | * @tty: tty device | 3354 | * @tty: tty device |
3304 | * @file: user file pointer | 3355 | * @file: user file pointer |
3305 | * @cmd: command - clear bits, set bits or set all | 3356 | * @cmd: command - clear bits, set bits or set all |
@@ -3316,7 +3367,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int | |||
3316 | { | 3367 | { |
3317 | int retval = -EINVAL; | 3368 | int retval = -EINVAL; |
3318 | 3369 | ||
3319 | if (tty->driver->tiocmset) { | 3370 | if (tty->ops->tiocmset) { |
3320 | unsigned int set, clear, val; | 3371 | unsigned int set, clear, val; |
3321 | 3372 | ||
3322 | retval = get_user(val, p); | 3373 | retval = get_user(val, p); |
@@ -3340,7 +3391,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int | |||
3340 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 3391 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
3341 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 3392 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
3342 | 3393 | ||
3343 | retval = tty->driver->tiocmset(tty, file, set, clear); | 3394 | retval = tty->ops->tiocmset(tty, file, set, clear); |
3344 | } | 3395 | } |
3345 | return retval; | 3396 | return retval; |
3346 | } | 3397 | } |
@@ -3348,20 +3399,18 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int | |||
3348 | /* | 3399 | /* |
3349 | * Split this up, as gcc can choke on it otherwise.. | 3400 | * Split this up, as gcc can choke on it otherwise.. |
3350 | */ | 3401 | */ |
3351 | int tty_ioctl(struct inode *inode, struct file *file, | 3402 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
3352 | unsigned int cmd, unsigned long arg) | ||
3353 | { | 3403 | { |
3354 | struct tty_struct *tty, *real_tty; | 3404 | struct tty_struct *tty, *real_tty; |
3355 | void __user *p = (void __user *)arg; | 3405 | void __user *p = (void __user *)arg; |
3356 | int retval; | 3406 | int retval; |
3357 | struct tty_ldisc *ld; | 3407 | struct tty_ldisc *ld; |
3408 | struct inode *inode = file->f_dentry->d_inode; | ||
3358 | 3409 | ||
3359 | tty = (struct tty_struct *)file->private_data; | 3410 | tty = (struct tty_struct *)file->private_data; |
3360 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 3411 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
3361 | return -EINVAL; | 3412 | return -EINVAL; |
3362 | 3413 | ||
3363 | /* CHECKME: is this safe as one end closes ? */ | ||
3364 | |||
3365 | real_tty = tty; | 3414 | real_tty = tty; |
3366 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 3415 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
3367 | tty->driver->subtype == PTY_TYPE_MASTER) | 3416 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -3370,21 +3419,28 @@ int tty_ioctl(struct inode *inode, struct file *file, | |||
3370 | /* | 3419 | /* |
3371 | * Break handling by driver | 3420 | * Break handling by driver |
3372 | */ | 3421 | */ |
3373 | if (!tty->driver->break_ctl) { | 3422 | |
3423 | retval = -EINVAL; | ||
3424 | |||
3425 | if (!tty->ops->break_ctl) { | ||
3374 | switch (cmd) { | 3426 | switch (cmd) { |
3375 | case TIOCSBRK: | 3427 | case TIOCSBRK: |
3376 | case TIOCCBRK: | 3428 | case TIOCCBRK: |
3377 | if (tty->driver->ioctl) | 3429 | if (tty->ops->ioctl) |
3378 | return tty->driver->ioctl(tty, file, cmd, arg); | 3430 | retval = tty->ops->ioctl(tty, file, cmd, arg); |
3379 | return -EINVAL; | 3431 | if (retval != -EINVAL && retval != -ENOIOCTLCMD) |
3432 | printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name); | ||
3433 | return retval; | ||
3380 | 3434 | ||
3381 | /* These two ioctl's always return success; even if */ | 3435 | /* These two ioctl's always return success; even if */ |
3382 | /* the driver doesn't support them. */ | 3436 | /* the driver doesn't support them. */ |
3383 | case TCSBRK: | 3437 | case TCSBRK: |
3384 | case TCSBRKP: | 3438 | case TCSBRKP: |
3385 | if (!tty->driver->ioctl) | 3439 | if (!tty->ops->ioctl) |
3386 | return 0; | 3440 | return 0; |
3387 | retval = tty->driver->ioctl(tty, file, cmd, arg); | 3441 | retval = tty->ops->ioctl(tty, file, cmd, arg); |
3442 | if (retval != -EINVAL && retval != -ENOIOCTLCMD) | ||
3443 | printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name); | ||
3388 | if (retval == -ENOIOCTLCMD) | 3444 | if (retval == -ENOIOCTLCMD) |
3389 | retval = 0; | 3445 | retval = 0; |
3390 | return retval; | 3446 | return retval; |
@@ -3442,7 +3498,6 @@ int tty_ioctl(struct inode *inode, struct file *file, | |||
3442 | case TIOCGSID: | 3498 | case TIOCGSID: |
3443 | return tiocgsid(tty, real_tty, p); | 3499 | return tiocgsid(tty, real_tty, p); |
3444 | case TIOCGETD: | 3500 | case TIOCGETD: |
3445 | /* FIXME: check this is ok */ | ||
3446 | return put_user(tty->ldisc.num, (int __user *)p); | 3501 | return put_user(tty->ldisc.num, (int __user *)p); |
3447 | case TIOCSETD: | 3502 | case TIOCSETD: |
3448 | return tiocsetd(tty, p); | 3503 | return tiocsetd(tty, p); |
@@ -3454,11 +3509,13 @@ int tty_ioctl(struct inode *inode, struct file *file, | |||
3454 | * Break handling | 3509 | * Break handling |
3455 | */ | 3510 | */ |
3456 | case TIOCSBRK: /* Turn break on, unconditionally */ | 3511 | case TIOCSBRK: /* Turn break on, unconditionally */ |
3457 | tty->driver->break_ctl(tty, -1); | 3512 | if (tty->ops->break_ctl) |
3513 | tty->ops->break_ctl(tty, -1); | ||
3458 | return 0; | 3514 | return 0; |
3459 | 3515 | ||
3460 | case TIOCCBRK: /* Turn break off, unconditionally */ | 3516 | case TIOCCBRK: /* Turn break off, unconditionally */ |
3461 | tty->driver->break_ctl(tty, 0); | 3517 | if (tty->ops->break_ctl) |
3518 | tty->ops->break_ctl(tty, 0); | ||
3462 | return 0; | 3519 | return 0; |
3463 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 3520 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
3464 | /* non-zero arg means wait for all output data | 3521 | /* non-zero arg means wait for all output data |
@@ -3487,8 +3544,8 @@ int tty_ioctl(struct inode *inode, struct file *file, | |||
3487 | } | 3544 | } |
3488 | break; | 3545 | break; |
3489 | } | 3546 | } |
3490 | if (tty->driver->ioctl) { | 3547 | if (tty->ops->ioctl) { |
3491 | retval = (tty->driver->ioctl)(tty, file, cmd, arg); | 3548 | retval = (tty->ops->ioctl)(tty, file, cmd, arg); |
3492 | if (retval != -ENOIOCTLCMD) | 3549 | if (retval != -ENOIOCTLCMD) |
3493 | return retval; | 3550 | return retval; |
3494 | } | 3551 | } |
@@ -3515,8 +3572,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
3515 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 3572 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
3516 | return -EINVAL; | 3573 | return -EINVAL; |
3517 | 3574 | ||
3518 | if (tty->driver->compat_ioctl) { | 3575 | if (tty->ops->compat_ioctl) { |
3519 | retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg); | 3576 | retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg); |
3520 | if (retval != -ENOIOCTLCMD) | 3577 | if (retval != -ENOIOCTLCMD) |
3521 | return retval; | 3578 | return retval; |
3522 | } | 3579 | } |
@@ -3566,8 +3623,7 @@ void __do_SAK(struct tty_struct *tty) | |||
3566 | 3623 | ||
3567 | tty_ldisc_flush(tty); | 3624 | tty_ldisc_flush(tty); |
3568 | 3625 | ||
3569 | if (tty->driver->flush_buffer) | 3626 | tty_driver_flush_buffer(tty); |
3570 | tty->driver->flush_buffer(tty); | ||
3571 | 3627 | ||
3572 | read_lock(&tasklist_lock); | 3628 | read_lock(&tasklist_lock); |
3573 | /* Kill the entire session */ | 3629 | /* Kill the entire session */ |
@@ -3773,19 +3829,32 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3773 | mutex_init(&tty->atomic_read_lock); | 3829 | mutex_init(&tty->atomic_read_lock); |
3774 | mutex_init(&tty->atomic_write_lock); | 3830 | mutex_init(&tty->atomic_write_lock); |
3775 | spin_lock_init(&tty->read_lock); | 3831 | spin_lock_init(&tty->read_lock); |
3832 | spin_lock_init(&tty->ctrl_lock); | ||
3776 | INIT_LIST_HEAD(&tty->tty_files); | 3833 | INIT_LIST_HEAD(&tty->tty_files); |
3777 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 3834 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
3778 | } | 3835 | } |
3779 | 3836 | ||
3780 | /* | 3837 | /** |
3781 | * The default put_char routine if the driver did not define one. | 3838 | * tty_put_char - write one character to a tty |
3839 | * @tty: tty | ||
3840 | * @ch: character | ||
3841 | * | ||
3842 | * Write one byte to the tty using the provided put_char method | ||
3843 | * if present. Returns the number of characters successfully output. | ||
3844 | * | ||
3845 | * Note: the specific put_char operation in the driver layer may go | ||
3846 | * away soon. Don't call it directly, use this method | ||
3782 | */ | 3847 | */ |
3783 | 3848 | ||
3784 | static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) | 3849 | int tty_put_char(struct tty_struct *tty, unsigned char ch) |
3785 | { | 3850 | { |
3786 | tty->driver->write(tty, &ch, 1); | 3851 | if (tty->ops->put_char) |
3852 | return tty->ops->put_char(tty, ch); | ||
3853 | return tty->ops->write(tty, &ch, 1); | ||
3787 | } | 3854 | } |
3788 | 3855 | ||
3856 | EXPORT_SYMBOL_GPL(tty_put_char); | ||
3857 | |||
3789 | static struct class *tty_class; | 3858 | static struct class *tty_class; |
3790 | 3859 | ||
3791 | /** | 3860 | /** |
@@ -3868,37 +3937,8 @@ void put_tty_driver(struct tty_driver *driver) | |||
3868 | void tty_set_operations(struct tty_driver *driver, | 3937 | void tty_set_operations(struct tty_driver *driver, |
3869 | const struct tty_operations *op) | 3938 | const struct tty_operations *op) |
3870 | { | 3939 | { |
3871 | driver->open = op->open; | 3940 | driver->ops = op; |
3872 | driver->close = op->close; | 3941 | }; |
3873 | driver->write = op->write; | ||
3874 | driver->put_char = op->put_char; | ||
3875 | driver->flush_chars = op->flush_chars; | ||
3876 | driver->write_room = op->write_room; | ||
3877 | driver->chars_in_buffer = op->chars_in_buffer; | ||
3878 | driver->ioctl = op->ioctl; | ||
3879 | driver->compat_ioctl = op->compat_ioctl; | ||
3880 | driver->set_termios = op->set_termios; | ||
3881 | driver->throttle = op->throttle; | ||
3882 | driver->unthrottle = op->unthrottle; | ||
3883 | driver->stop = op->stop; | ||
3884 | driver->start = op->start; | ||
3885 | driver->hangup = op->hangup; | ||
3886 | driver->break_ctl = op->break_ctl; | ||
3887 | driver->flush_buffer = op->flush_buffer; | ||
3888 | driver->set_ldisc = op->set_ldisc; | ||
3889 | driver->wait_until_sent = op->wait_until_sent; | ||
3890 | driver->send_xchar = op->send_xchar; | ||
3891 | driver->read_proc = op->read_proc; | ||
3892 | driver->write_proc = op->write_proc; | ||
3893 | driver->tiocmget = op->tiocmget; | ||
3894 | driver->tiocmset = op->tiocmset; | ||
3895 | #ifdef CONFIG_CONSOLE_POLL | ||
3896 | driver->poll_init = op->poll_init; | ||
3897 | driver->poll_get_char = op->poll_get_char; | ||
3898 | driver->poll_put_char = op->poll_put_char; | ||
3899 | #endif | ||
3900 | } | ||
3901 | |||
3902 | 3942 | ||
3903 | EXPORT_SYMBOL(alloc_tty_driver); | 3943 | EXPORT_SYMBOL(alloc_tty_driver); |
3904 | EXPORT_SYMBOL(put_tty_driver); | 3944 | EXPORT_SYMBOL(put_tty_driver); |
@@ -3961,9 +4001,6 @@ int tty_register_driver(struct tty_driver *driver) | |||
3961 | return error; | 4001 | return error; |
3962 | } | 4002 | } |
3963 | 4003 | ||
3964 | if (!driver->put_char) | ||
3965 | driver->put_char = tty_default_put_char; | ||
3966 | |||
3967 | mutex_lock(&tty_mutex); | 4004 | mutex_lock(&tty_mutex); |
3968 | list_add(&driver->tty_drivers, &tty_drivers); | 4005 | list_add(&driver->tty_drivers, &tty_drivers); |
3969 | mutex_unlock(&tty_mutex); | 4006 | mutex_unlock(&tty_mutex); |
@@ -4039,14 +4076,19 @@ void proc_clear_tty(struct task_struct *p) | |||
4039 | } | 4076 | } |
4040 | EXPORT_SYMBOL(proc_clear_tty); | 4077 | EXPORT_SYMBOL(proc_clear_tty); |
4041 | 4078 | ||
4079 | /* Called under the sighand lock */ | ||
4080 | |||
4042 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 4081 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
4043 | { | 4082 | { |
4044 | if (tty) { | 4083 | if (tty) { |
4045 | /* We should not have a session or pgrp to here but.... */ | 4084 | unsigned long flags; |
4085 | /* We should not have a session or pgrp to put here but.... */ | ||
4086 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
4046 | put_pid(tty->session); | 4087 | put_pid(tty->session); |
4047 | put_pid(tty->pgrp); | 4088 | put_pid(tty->pgrp); |
4048 | tty->session = get_pid(task_session(tsk)); | ||
4049 | tty->pgrp = get_pid(task_pgrp(tsk)); | 4089 | tty->pgrp = get_pid(task_pgrp(tsk)); |
4090 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
4091 | tty->session = get_pid(task_session(tsk)); | ||
4050 | } | 4092 | } |
4051 | put_pid(tsk->signal->tty_old_pgrp); | 4093 | put_pid(tsk->signal->tty_old_pgrp); |
4052 | tsk->signal->tty = tty; | 4094 | tsk->signal->tty = tty; |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index f95a80b2265f..b1a757a5ee27 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/smp_lock.h> | ||
24 | 25 | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
@@ -39,6 +40,50 @@ | |||
39 | #define TERMIOS_OLD 8 | 40 | #define TERMIOS_OLD 8 |
40 | 41 | ||
41 | 42 | ||
43 | int tty_chars_in_buffer(struct tty_struct *tty) | ||
44 | { | ||
45 | if (tty->ops->chars_in_buffer) | ||
46 | return tty->ops->chars_in_buffer(tty); | ||
47 | else | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | EXPORT_SYMBOL(tty_chars_in_buffer); | ||
52 | |||
53 | int tty_write_room(struct tty_struct *tty) | ||
54 | { | ||
55 | if (tty->ops->write_room) | ||
56 | return tty->ops->write_room(tty); | ||
57 | return 2048; | ||
58 | } | ||
59 | |||
60 | EXPORT_SYMBOL(tty_write_room); | ||
61 | |||
62 | void tty_driver_flush_buffer(struct tty_struct *tty) | ||
63 | { | ||
64 | if (tty->ops->flush_buffer) | ||
65 | tty->ops->flush_buffer(tty); | ||
66 | } | ||
67 | |||
68 | EXPORT_SYMBOL(tty_driver_flush_buffer); | ||
69 | |||
70 | void tty_throttle(struct tty_struct *tty) | ||
71 | { | ||
72 | /* check TTY_THROTTLED first so it indicates our state */ | ||
73 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | ||
74 | tty->ops->throttle) | ||
75 | tty->ops->throttle(tty); | ||
76 | } | ||
77 | EXPORT_SYMBOL(tty_throttle); | ||
78 | |||
79 | void tty_unthrottle(struct tty_struct *tty) | ||
80 | { | ||
81 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | ||
82 | tty->ops->unthrottle) | ||
83 | tty->ops->unthrottle(tty); | ||
84 | } | ||
85 | EXPORT_SYMBOL(tty_unthrottle); | ||
86 | |||
42 | /** | 87 | /** |
43 | * tty_wait_until_sent - wait for I/O to finish | 88 | * tty_wait_until_sent - wait for I/O to finish |
44 | * @tty: tty we are waiting for | 89 | * @tty: tty we are waiting for |
@@ -57,15 +102,13 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) | |||
57 | 102 | ||
58 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); | 103 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); |
59 | #endif | 104 | #endif |
60 | if (!tty->driver->chars_in_buffer) | ||
61 | return; | ||
62 | if (!timeout) | 105 | if (!timeout) |
63 | timeout = MAX_SCHEDULE_TIMEOUT; | 106 | timeout = MAX_SCHEDULE_TIMEOUT; |
64 | if (wait_event_interruptible_timeout(tty->write_wait, | 107 | if (wait_event_interruptible_timeout(tty->write_wait, |
65 | !tty->driver->chars_in_buffer(tty), timeout) < 0) | 108 | !tty_chars_in_buffer(tty), timeout) >= 0) { |
66 | return; | 109 | if (tty->ops->wait_until_sent) |
67 | if (tty->driver->wait_until_sent) | 110 | tty->ops->wait_until_sent(tty, timeout); |
68 | tty->driver->wait_until_sent(tty, timeout); | 111 | } |
69 | } | 112 | } |
70 | EXPORT_SYMBOL(tty_wait_until_sent); | 113 | EXPORT_SYMBOL(tty_wait_until_sent); |
71 | 114 | ||
@@ -393,8 +436,9 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
393 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 436 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) |
394 | { | 437 | { |
395 | int canon_change; | 438 | int canon_change; |
396 | struct ktermios old_termios = *tty->termios; | 439 | struct ktermios old_termios; |
397 | struct tty_ldisc *ld; | 440 | struct tty_ldisc *ld; |
441 | unsigned long flags; | ||
398 | 442 | ||
399 | /* | 443 | /* |
400 | * Perform the actual termios internal changes under lock. | 444 | * Perform the actual termios internal changes under lock. |
@@ -404,7 +448,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
404 | /* FIXME: we need to decide on some locking/ordering semantics | 448 | /* FIXME: we need to decide on some locking/ordering semantics |
405 | for the set_termios notification eventually */ | 449 | for the set_termios notification eventually */ |
406 | mutex_lock(&tty->termios_mutex); | 450 | mutex_lock(&tty->termios_mutex); |
407 | 451 | old_termios = *tty->termios; | |
408 | *tty->termios = *new_termios; | 452 | *tty->termios = *new_termios; |
409 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 453 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); |
410 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; | 454 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; |
@@ -429,17 +473,19 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
429 | STOP_CHAR(tty) == '\023' && | 473 | STOP_CHAR(tty) == '\023' && |
430 | START_CHAR(tty) == '\021'); | 474 | START_CHAR(tty) == '\021'); |
431 | if (old_flow != new_flow) { | 475 | if (old_flow != new_flow) { |
476 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
432 | tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); | 477 | tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); |
433 | if (new_flow) | 478 | if (new_flow) |
434 | tty->ctrl_status |= TIOCPKT_DOSTOP; | 479 | tty->ctrl_status |= TIOCPKT_DOSTOP; |
435 | else | 480 | else |
436 | tty->ctrl_status |= TIOCPKT_NOSTOP; | 481 | tty->ctrl_status |= TIOCPKT_NOSTOP; |
482 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
437 | wake_up_interruptible(&tty->link->read_wait); | 483 | wake_up_interruptible(&tty->link->read_wait); |
438 | } | 484 | } |
439 | } | 485 | } |
440 | 486 | ||
441 | if (tty->driver->set_termios) | 487 | if (tty->ops->set_termios) |
442 | (*tty->driver->set_termios)(tty, &old_termios); | 488 | (*tty->ops->set_termios)(tty, &old_termios); |
443 | else | 489 | else |
444 | tty_termios_copy_hw(tty->termios, &old_termios); | 490 | tty_termios_copy_hw(tty->termios, &old_termios); |
445 | 491 | ||
@@ -474,7 +520,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
474 | if (retval) | 520 | if (retval) |
475 | return retval; | 521 | return retval; |
476 | 522 | ||
523 | mutex_lock(&tty->termios_mutex); | ||
477 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); | 524 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); |
525 | mutex_unlock(&tty->termios_mutex); | ||
478 | 526 | ||
479 | if (opt & TERMIOS_TERMIO) { | 527 | if (opt & TERMIOS_TERMIO) { |
480 | if (user_termio_to_kernel_termios(&tmp_termios, | 528 | if (user_termio_to_kernel_termios(&tmp_termios, |
@@ -660,12 +708,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
660 | { | 708 | { |
661 | struct tchars tmp; | 709 | struct tchars tmp; |
662 | 710 | ||
711 | mutex_lock(&tty->termios_mutex); | ||
663 | tmp.t_intrc = tty->termios->c_cc[VINTR]; | 712 | tmp.t_intrc = tty->termios->c_cc[VINTR]; |
664 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; | 713 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; |
665 | tmp.t_startc = tty->termios->c_cc[VSTART]; | 714 | tmp.t_startc = tty->termios->c_cc[VSTART]; |
666 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; | 715 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; |
667 | tmp.t_eofc = tty->termios->c_cc[VEOF]; | 716 | tmp.t_eofc = tty->termios->c_cc[VEOF]; |
668 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ | 717 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ |
718 | mutex_unlock(&tty->termios_mutex); | ||
669 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 719 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
670 | } | 720 | } |
671 | 721 | ||
@@ -675,12 +725,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
675 | 725 | ||
676 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) | 726 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) |
677 | return -EFAULT; | 727 | return -EFAULT; |
728 | mutex_lock(&tty->termios_mutex); | ||
678 | tty->termios->c_cc[VINTR] = tmp.t_intrc; | 729 | tty->termios->c_cc[VINTR] = tmp.t_intrc; |
679 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; | 730 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; |
680 | tty->termios->c_cc[VSTART] = tmp.t_startc; | 731 | tty->termios->c_cc[VSTART] = tmp.t_startc; |
681 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; | 732 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; |
682 | tty->termios->c_cc[VEOF] = tmp.t_eofc; | 733 | tty->termios->c_cc[VEOF] = tmp.t_eofc; |
683 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ | 734 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
735 | mutex_unlock(&tty->termios_mutex); | ||
684 | return 0; | 736 | return 0; |
685 | } | 737 | } |
686 | #endif | 738 | #endif |
@@ -690,6 +742,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
690 | { | 742 | { |
691 | struct ltchars tmp; | 743 | struct ltchars tmp; |
692 | 744 | ||
745 | mutex_lock(&tty->termios_mutex); | ||
693 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; | 746 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; |
694 | /* what is dsuspc anyway? */ | 747 | /* what is dsuspc anyway? */ |
695 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; | 748 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; |
@@ -698,6 +751,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
698 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; | 751 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; |
699 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; | 752 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; |
700 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; | 753 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; |
754 | mutex_unlock(&tty->termios_mutex); | ||
701 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 755 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
702 | } | 756 | } |
703 | 757 | ||
@@ -708,6 +762,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
708 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) | 762 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) |
709 | return -EFAULT; | 763 | return -EFAULT; |
710 | 764 | ||
765 | mutex_lock(&tty->termios_mutex); | ||
711 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; | 766 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; |
712 | /* what is dsuspc anyway? */ | 767 | /* what is dsuspc anyway? */ |
713 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; | 768 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; |
@@ -716,6 +771,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
716 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; | 771 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; |
717 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; | 772 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; |
718 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; | 773 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; |
774 | mutex_unlock(&tty->termios_mutex); | ||
719 | return 0; | 775 | return 0; |
720 | } | 776 | } |
721 | #endif | 777 | #endif |
@@ -732,8 +788,8 @@ static int send_prio_char(struct tty_struct *tty, char ch) | |||
732 | { | 788 | { |
733 | int was_stopped = tty->stopped; | 789 | int was_stopped = tty->stopped; |
734 | 790 | ||
735 | if (tty->driver->send_xchar) { | 791 | if (tty->ops->send_xchar) { |
736 | tty->driver->send_xchar(tty, ch); | 792 | tty->ops->send_xchar(tty, ch); |
737 | return 0; | 793 | return 0; |
738 | } | 794 | } |
739 | 795 | ||
@@ -742,7 +798,7 @@ static int send_prio_char(struct tty_struct *tty, char ch) | |||
742 | 798 | ||
743 | if (was_stopped) | 799 | if (was_stopped) |
744 | start_tty(tty); | 800 | start_tty(tty); |
745 | tty->driver->write(tty, &ch, 1); | 801 | tty->ops->write(tty, &ch, 1); |
746 | if (was_stopped) | 802 | if (was_stopped) |
747 | stop_tty(tty); | 803 | stop_tty(tty); |
748 | tty_write_unlock(tty); | 804 | tty_write_unlock(tty); |
@@ -750,6 +806,33 @@ static int send_prio_char(struct tty_struct *tty, char ch) | |||
750 | } | 806 | } |
751 | 807 | ||
752 | /** | 808 | /** |
809 | * tty_change_softcar - carrier change ioctl helper | ||
810 | * @tty: tty to update | ||
811 | * @arg: enable/disable CLOCAL | ||
812 | * | ||
813 | * Perform a change to the CLOCAL state and call into the driver | ||
814 | * layer to make it visible. All done with the termios mutex | ||
815 | */ | ||
816 | |||
817 | static int tty_change_softcar(struct tty_struct *tty, int arg) | ||
818 | { | ||
819 | int ret = 0; | ||
820 | int bit = arg ? CLOCAL : 0; | ||
821 | struct ktermios old; | ||
822 | |||
823 | mutex_lock(&tty->termios_mutex); | ||
824 | old = *tty->termios; | ||
825 | tty->termios->c_cflag &= ~CLOCAL; | ||
826 | tty->termios->c_cflag |= bit; | ||
827 | if (tty->ops->set_termios) | ||
828 | tty->ops->set_termios(tty, &old); | ||
829 | if ((tty->termios->c_cflag & CLOCAL) != bit) | ||
830 | ret = -EINVAL; | ||
831 | mutex_unlock(&tty->termios_mutex); | ||
832 | return ret; | ||
833 | } | ||
834 | |||
835 | /** | ||
753 | * tty_mode_ioctl - mode related ioctls | 836 | * tty_mode_ioctl - mode related ioctls |
754 | * @tty: tty for the ioctl | 837 | * @tty: tty for the ioctl |
755 | * @file: file pointer for the tty | 838 | * @file: file pointer for the tty |
@@ -859,12 +942,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
859 | case TIOCSSOFTCAR: | 942 | case TIOCSSOFTCAR: |
860 | if (get_user(arg, (unsigned int __user *) arg)) | 943 | if (get_user(arg, (unsigned int __user *) arg)) |
861 | return -EFAULT; | 944 | return -EFAULT; |
862 | mutex_lock(&tty->termios_mutex); | 945 | return tty_change_softcar(tty, arg); |
863 | tty->termios->c_cflag = | ||
864 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
865 | (arg ? CLOCAL : 0)); | ||
866 | mutex_unlock(&tty->termios_mutex); | ||
867 | return 0; | ||
868 | default: | 946 | default: |
869 | return -ENOIOCTLCMD; | 947 | return -ENOIOCTLCMD; |
870 | } | 948 | } |
@@ -889,8 +967,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
889 | ld->flush_buffer(tty); | 967 | ld->flush_buffer(tty); |
890 | /* fall through */ | 968 | /* fall through */ |
891 | case TCOFLUSH: | 969 | case TCOFLUSH: |
892 | if (tty->driver->flush_buffer) | 970 | tty_driver_flush_buffer(tty); |
893 | tty->driver->flush_buffer(tty); | ||
894 | break; | 971 | break; |
895 | default: | 972 | default: |
896 | tty_ldisc_deref(ld); | 973 | tty_ldisc_deref(ld); |
@@ -905,6 +982,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
905 | unsigned int cmd, unsigned long arg) | 982 | unsigned int cmd, unsigned long arg) |
906 | { | 983 | { |
907 | struct tty_struct *real_tty; | 984 | struct tty_struct *real_tty; |
985 | unsigned long flags; | ||
908 | int retval; | 986 | int retval; |
909 | 987 | ||
910 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 988 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -946,9 +1024,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
946 | case TCFLSH: | 1024 | case TCFLSH: |
947 | return tty_perform_flush(tty, arg); | 1025 | return tty_perform_flush(tty, arg); |
948 | case TIOCOUTQ: | 1026 | case TIOCOUTQ: |
949 | return put_user(tty->driver->chars_in_buffer ? | 1027 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); |
950 | tty->driver->chars_in_buffer(tty) : 0, | ||
951 | (int __user *) arg); | ||
952 | case TIOCINQ: | 1028 | case TIOCINQ: |
953 | retval = tty->read_cnt; | 1029 | retval = tty->read_cnt; |
954 | if (L_ICANON(tty)) | 1030 | if (L_ICANON(tty)) |
@@ -963,6 +1039,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
963 | return -ENOTTY; | 1039 | return -ENOTTY; |
964 | if (get_user(pktmode, (int __user *) arg)) | 1040 | if (get_user(pktmode, (int __user *) arg)) |
965 | return -EFAULT; | 1041 | return -EFAULT; |
1042 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
966 | if (pktmode) { | 1043 | if (pktmode) { |
967 | if (!tty->packet) { | 1044 | if (!tty->packet) { |
968 | tty->packet = 1; | 1045 | tty->packet = 1; |
@@ -970,6 +1047,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
970 | } | 1047 | } |
971 | } else | 1048 | } else |
972 | tty->packet = 0; | 1049 | tty->packet = 0; |
1050 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
973 | return 0; | 1051 | return 0; |
974 | } | 1052 | } |
975 | default: | 1053 | default: |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 8de6b95aeb84..3d3e1c2b310f 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -628,13 +628,13 @@ static int viotty_write(struct tty_struct *tty, const unsigned char *buf, | |||
628 | /* | 628 | /* |
629 | * TTY put_char method | 629 | * TTY put_char method |
630 | */ | 630 | */ |
631 | static void viotty_put_char(struct tty_struct *tty, unsigned char ch) | 631 | static int viotty_put_char(struct tty_struct *tty, unsigned char ch) |
632 | { | 632 | { |
633 | struct port_info *pi; | 633 | struct port_info *pi; |
634 | 634 | ||
635 | pi = get_port_data(tty); | 635 | pi = get_port_data(tty); |
636 | if (pi == NULL) | 636 | if (pi == NULL) |
637 | return; | 637 | return 0; |
638 | 638 | ||
639 | /* This will append '\r' as well if the char is '\n' */ | 639 | /* This will append '\r' as well if the char is '\n' */ |
640 | if (viochar_is_console(pi)) | 640 | if (viochar_is_console(pi)) |
@@ -642,6 +642,7 @@ static void viotty_put_char(struct tty_struct *tty, unsigned char ch) | |||
642 | 642 | ||
643 | if (viopath_isactive(pi->lp)) | 643 | if (viopath_isactive(pi->lp)) |
644 | internal_write(pi, &ch, 1); | 644 | internal_write(pi, &ch, 1); |
645 | return 1; | ||
645 | } | 646 | } |
646 | 647 | ||
647 | /* | 648 | /* |
@@ -704,8 +705,11 @@ static int viotty_ioctl(struct tty_struct *tty, struct file *file, | |||
704 | case KDSKBLED: | 705 | case KDSKBLED: |
705 | return 0; | 706 | return 0; |
706 | } | 707 | } |
707 | 708 | /* FIXME: WTF is this being called for ??? */ | |
708 | return n_tty_ioctl(tty, file, cmd, arg); | 709 | lock_kernel(); |
710 | ret = n_tty_ioctl(tty, file, cmd, arg); | ||
711 | unlock_kernel(); | ||
712 | return ret; | ||
709 | } | 713 | } |
710 | 714 | ||
711 | /* | 715 | /* |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index db7a731e2362..58aad63831f4 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -249,6 +249,7 @@ static int proc_viotape_open(struct inode *inode, struct file *file) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | static const struct file_operations proc_viotape_operations = { | 251 | static const struct file_operations proc_viotape_operations = { |
252 | .owner = THIS_MODULE, | ||
252 | .open = proc_viotape_open, | 253 | .open = proc_viotape_open, |
253 | .read = seq_read, | 254 | .read = seq_read, |
254 | .llseek = seq_lseek, | 255 | .llseek = seq_lseek, |
@@ -915,7 +916,6 @@ static struct vio_driver viotape_driver = { | |||
915 | int __init viotap_init(void) | 916 | int __init viotap_init(void) |
916 | { | 917 | { |
917 | int ret; | 918 | int ret; |
918 | struct proc_dir_entry *e; | ||
919 | 919 | ||
920 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | 920 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) |
921 | return -ENODEV; | 921 | return -ENODEV; |
@@ -968,11 +968,8 @@ int __init viotap_init(void) | |||
968 | if (ret) | 968 | if (ret) |
969 | goto unreg_class; | 969 | goto unreg_class; |
970 | 970 | ||
971 | e = create_proc_entry("iSeries/viotape", S_IFREG|S_IRUGO, NULL); | 971 | proc_create("iSeries/viotape", S_IFREG|S_IRUGO, NULL, |
972 | if (e) { | 972 | &proc_viotape_operations); |
973 | e->owner = THIS_MODULE; | ||
974 | e->proc_fops = &proc_viotape_operations; | ||
975 | } | ||
976 | 973 | ||
977 | return 0; | 974 | return 0; |
978 | 975 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index df4c3ead9e2b..e458b08139af 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -301,7 +301,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
301 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 301 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
302 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); | 302 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); |
303 | scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); | 303 | scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); |
304 | scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, | 304 | scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_scrl_erase_char, |
305 | vc->vc_size_row * nr); | 305 | vc->vc_size_row * nr); |
306 | } | 306 | } |
307 | 307 | ||
@@ -319,7 +319,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
319 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 319 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
320 | step = vc->vc_cols * nr; | 320 | step = vc->vc_cols * nr; |
321 | scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); | 321 | scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); |
322 | scr_memsetw(s, vc->vc_video_erase_char, 2 * step); | 322 | scr_memsetw(s, vc->vc_scrl_erase_char, 2 * step); |
323 | } | 323 | } |
324 | 324 | ||
325 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) | 325 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) |
@@ -400,7 +400,7 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, | |||
400 | * Bit 7 : blink | 400 | * Bit 7 : blink |
401 | */ | 401 | */ |
402 | { | 402 | { |
403 | u8 a = vc->vc_color; | 403 | u8 a = _color; |
404 | if (!vc->vc_can_do_color) | 404 | if (!vc->vc_can_do_color) |
405 | return _intensity | | 405 | return _intensity | |
406 | (_italic ? 2 : 0) | | 406 | (_italic ? 2 : 0) | |
@@ -434,6 +434,7 @@ static void update_attr(struct vc_data *vc) | |||
434 | vc->vc_blink, vc->vc_underline, | 434 | vc->vc_blink, vc->vc_underline, |
435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); | 435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); |
436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; | 436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; |
437 | vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, false, false) << 8) | ' '; | ||
437 | } | 438 | } |
438 | 439 | ||
439 | /* Note: inverting the screen twice should revert to the original state */ | 440 | /* Note: inverting the screen twice should revert to the original state */ |
@@ -908,15 +909,21 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
908 | 909 | ||
909 | if (vc->vc_tty) { | 910 | if (vc->vc_tty) { |
910 | struct winsize ws, *cws = &vc->vc_tty->winsize; | 911 | struct winsize ws, *cws = &vc->vc_tty->winsize; |
912 | unsigned long flags; | ||
911 | 913 | ||
912 | memset(&ws, 0, sizeof(ws)); | 914 | memset(&ws, 0, sizeof(ws)); |
913 | ws.ws_row = vc->vc_rows; | 915 | ws.ws_row = vc->vc_rows; |
914 | ws.ws_col = vc->vc_cols; | 916 | ws.ws_col = vc->vc_cols; |
915 | ws.ws_ypixel = vc->vc_scan_lines; | 917 | ws.ws_ypixel = vc->vc_scan_lines; |
918 | |||
919 | mutex_lock(&vc->vc_tty->termios_mutex); | ||
920 | spin_lock_irqsave(&vc->vc_tty->ctrl_lock, flags); | ||
916 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && | 921 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && |
917 | vc->vc_tty->pgrp) | 922 | vc->vc_tty->pgrp) |
918 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); | 923 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); |
924 | spin_unlock_irqrestore(&vc->vc_tty->ctrl_lock, flags); | ||
919 | *cws = ws; | 925 | *cws = ws; |
926 | mutex_unlock(&vc->vc_tty->termios_mutex); | ||
920 | } | 927 | } |
921 | 928 | ||
922 | if (CON_IS_VISIBLE(vc)) | 929 | if (CON_IS_VISIBLE(vc)) |
@@ -2540,6 +2547,9 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2540 | if (get_user(type, p)) | 2547 | if (get_user(type, p)) |
2541 | return -EFAULT; | 2548 | return -EFAULT; |
2542 | ret = 0; | 2549 | ret = 0; |
2550 | |||
2551 | lock_kernel(); | ||
2552 | |||
2543 | switch (type) | 2553 | switch (type) |
2544 | { | 2554 | { |
2545 | case TIOCL_SETSEL: | 2555 | case TIOCL_SETSEL: |
@@ -2559,7 +2569,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2559 | ret = sel_loadlut(p); | 2569 | ret = sel_loadlut(p); |
2560 | break; | 2570 | break; |
2561 | case TIOCL_GETSHIFTSTATE: | 2571 | case TIOCL_GETSHIFTSTATE: |
2562 | 2572 | ||
2563 | /* | 2573 | /* |
2564 | * Make it possible to react to Shift+Mousebutton. | 2574 | * Make it possible to react to Shift+Mousebutton. |
2565 | * Note that 'shift_state' is an undocumented | 2575 | * Note that 'shift_state' is an undocumented |
@@ -2614,6 +2624,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2614 | ret = -EINVAL; | 2624 | ret = -EINVAL; |
2615 | break; | 2625 | break; |
2616 | } | 2626 | } |
2627 | unlock_kernel(); | ||
2617 | return ret; | 2628 | return ret; |
2618 | } | 2629 | } |
2619 | 2630 | ||
@@ -2631,11 +2642,11 @@ static int con_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
2631 | return retval; | 2642 | return retval; |
2632 | } | 2643 | } |
2633 | 2644 | ||
2634 | static void con_put_char(struct tty_struct *tty, unsigned char ch) | 2645 | static int con_put_char(struct tty_struct *tty, unsigned char ch) |
2635 | { | 2646 | { |
2636 | if (in_interrupt()) | 2647 | if (in_interrupt()) |
2637 | return; /* n_r3964 calls put_char() from interrupt context */ | 2648 | return 0; /* n_r3964 calls put_char() from interrupt context */ |
2638 | do_con_write(tty, &ch, 1); | 2649 | return do_con_write(tty, &ch, 1); |
2639 | } | 2650 | } |
2640 | 2651 | ||
2641 | static int con_write_room(struct tty_struct *tty) | 2652 | static int con_write_room(struct tty_struct *tty) |
@@ -3828,7 +3839,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) | |||
3828 | goto out; | 3839 | goto out; |
3829 | 3840 | ||
3830 | c = (font.width+7)/8 * 32 * font.charcount; | 3841 | c = (font.width+7)/8 * 32 * font.charcount; |
3831 | 3842 | ||
3832 | if (op->data && font.charcount > op->charcount) | 3843 | if (op->data && font.charcount > op->charcount) |
3833 | rc = -ENOSPC; | 3844 | rc = -ENOSPC; |
3834 | if (!(op->flags & KD_FONT_FLAG_OLD)) { | 3845 | if (!(op->flags & KD_FONT_FLAG_OLD)) { |
@@ -3993,6 +4004,7 @@ u16 screen_glyph(struct vc_data *vc, int offset) | |||
3993 | c |= 0x100; | 4004 | c |= 0x100; |
3994 | return c; | 4005 | return c; |
3995 | } | 4006 | } |
4007 | EXPORT_SYMBOL_GPL(screen_glyph); | ||
3996 | 4008 | ||
3997 | /* used by vcs - note the word offset */ | 4009 | /* used by vcs - note the word offset */ |
3998 | unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) | 4010 | unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index e6f89e8b9258..3211afd9d57e 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -373,11 +373,17 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
373 | unsigned char ucval; | 373 | unsigned char ucval; |
374 | void __user *up = (void __user *)arg; | 374 | void __user *up = (void __user *)arg; |
375 | int i, perm; | 375 | int i, perm; |
376 | 376 | int ret = 0; | |
377 | |||
377 | console = vc->vc_num; | 378 | console = vc->vc_num; |
378 | 379 | ||
379 | if (!vc_cons_allocated(console)) /* impossible? */ | 380 | lock_kernel(); |
380 | return -ENOIOCTLCMD; | 381 | |
382 | if (!vc_cons_allocated(console)) { /* impossible? */ | ||
383 | ret = -ENOIOCTLCMD; | ||
384 | goto out; | ||
385 | } | ||
386 | |||
381 | 387 | ||
382 | /* | 388 | /* |
383 | * To have permissions to do most of the vt ioctls, we either have | 389 | * To have permissions to do most of the vt ioctls, we either have |
@@ -391,15 +397,15 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
391 | switch (cmd) { | 397 | switch (cmd) { |
392 | case KIOCSOUND: | 398 | case KIOCSOUND: |
393 | if (!perm) | 399 | if (!perm) |
394 | return -EPERM; | 400 | goto eperm; |
395 | if (arg) | 401 | if (arg) |
396 | arg = CLOCK_TICK_RATE / arg; | 402 | arg = CLOCK_TICK_RATE / arg; |
397 | kd_mksound(arg, 0); | 403 | kd_mksound(arg, 0); |
398 | return 0; | 404 | break; |
399 | 405 | ||
400 | case KDMKTONE: | 406 | case KDMKTONE: |
401 | if (!perm) | 407 | if (!perm) |
402 | return -EPERM; | 408 | goto eperm; |
403 | { | 409 | { |
404 | unsigned int ticks, count; | 410 | unsigned int ticks, count; |
405 | 411 | ||
@@ -412,7 +418,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
412 | if (count) | 418 | if (count) |
413 | count = CLOCK_TICK_RATE / count; | 419 | count = CLOCK_TICK_RATE / count; |
414 | kd_mksound(count, ticks); | 420 | kd_mksound(count, ticks); |
415 | return 0; | 421 | break; |
416 | } | 422 | } |
417 | 423 | ||
418 | case KDGKBTYPE: | 424 | case KDGKBTYPE: |
@@ -435,14 +441,18 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
435 | * KDADDIO and KDDELIO may be able to add ports beyond what | 441 | * KDADDIO and KDDELIO may be able to add ports beyond what |
436 | * we reject here, but to be safe... | 442 | * we reject here, but to be safe... |
437 | */ | 443 | */ |
438 | if (arg < GPFIRST || arg > GPLAST) | 444 | if (arg < GPFIRST || arg > GPLAST) { |
439 | return -EINVAL; | 445 | ret = -EINVAL; |
440 | return sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; | 446 | break; |
447 | } | ||
448 | ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; | ||
449 | break; | ||
441 | 450 | ||
442 | case KDENABIO: | 451 | case KDENABIO: |
443 | case KDDISABIO: | 452 | case KDDISABIO: |
444 | return sys_ioperm(GPFIRST, GPNUM, | 453 | ret = sys_ioperm(GPFIRST, GPNUM, |
445 | (cmd == KDENABIO)) ? -ENXIO : 0; | 454 | (cmd == KDENABIO)) ? -ENXIO : 0; |
455 | break; | ||
446 | #endif | 456 | #endif |
447 | 457 | ||
448 | /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */ | 458 | /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */ |
@@ -450,19 +460,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
450 | case KDKBDREP: | 460 | case KDKBDREP: |
451 | { | 461 | { |
452 | struct kbd_repeat kbrep; | 462 | struct kbd_repeat kbrep; |
453 | int err; | ||
454 | 463 | ||
455 | if (!capable(CAP_SYS_TTY_CONFIG)) | 464 | if (!capable(CAP_SYS_TTY_CONFIG)) |
456 | return -EPERM; | 465 | goto eperm; |
457 | 466 | ||
458 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) | 467 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { |
459 | return -EFAULT; | 468 | ret = -EFAULT; |
460 | err = kbd_rate(&kbrep); | 469 | break; |
461 | if (err) | 470 | } |
462 | return err; | 471 | ret = kbd_rate(&kbrep); |
472 | if (ret) | ||
473 | break; | ||
463 | if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat))) | 474 | if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat))) |
464 | return -EFAULT; | 475 | ret = -EFAULT; |
465 | return 0; | 476 | break; |
466 | } | 477 | } |
467 | 478 | ||
468 | case KDSETMODE: | 479 | case KDSETMODE: |
@@ -475,7 +486,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
475 | * need to restore their engine state. --BenH | 486 | * need to restore their engine state. --BenH |
476 | */ | 487 | */ |
477 | if (!perm) | 488 | if (!perm) |
478 | return -EPERM; | 489 | goto eperm; |
479 | switch (arg) { | 490 | switch (arg) { |
480 | case KD_GRAPHICS: | 491 | case KD_GRAPHICS: |
481 | break; | 492 | break; |
@@ -485,13 +496,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
485 | case KD_TEXT: | 496 | case KD_TEXT: |
486 | break; | 497 | break; |
487 | default: | 498 | default: |
488 | return -EINVAL; | 499 | ret = -EINVAL; |
500 | goto out; | ||
489 | } | 501 | } |
490 | if (vc->vc_mode == (unsigned char) arg) | 502 | if (vc->vc_mode == (unsigned char) arg) |
491 | return 0; | 503 | break; |
492 | vc->vc_mode = (unsigned char) arg; | 504 | vc->vc_mode = (unsigned char) arg; |
493 | if (console != fg_console) | 505 | if (console != fg_console) |
494 | return 0; | 506 | break; |
495 | /* | 507 | /* |
496 | * explicitly blank/unblank the screen if switching modes | 508 | * explicitly blank/unblank the screen if switching modes |
497 | */ | 509 | */ |
@@ -501,7 +513,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
501 | else | 513 | else |
502 | do_blank_screen(1); | 514 | do_blank_screen(1); |
503 | release_console_sem(); | 515 | release_console_sem(); |
504 | return 0; | 516 | break; |
505 | 517 | ||
506 | case KDGETMODE: | 518 | case KDGETMODE: |
507 | ucval = vc->vc_mode; | 519 | ucval = vc->vc_mode; |
@@ -513,11 +525,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
513 | * these work like a combination of mmap and KDENABIO. | 525 | * these work like a combination of mmap and KDENABIO. |
514 | * this could be easily finished. | 526 | * this could be easily finished. |
515 | */ | 527 | */ |
516 | return -EINVAL; | 528 | ret = -EINVAL; |
529 | break; | ||
517 | 530 | ||
518 | case KDSKBMODE: | 531 | case KDSKBMODE: |
519 | if (!perm) | 532 | if (!perm) |
520 | return -EPERM; | 533 | goto eperm; |
521 | switch(arg) { | 534 | switch(arg) { |
522 | case K_RAW: | 535 | case K_RAW: |
523 | kbd->kbdmode = VC_RAW; | 536 | kbd->kbdmode = VC_RAW; |
@@ -534,10 +547,11 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
534 | compute_shiftstate(); | 547 | compute_shiftstate(); |
535 | break; | 548 | break; |
536 | default: | 549 | default: |
537 | return -EINVAL; | 550 | ret = -EINVAL; |
551 | goto out; | ||
538 | } | 552 | } |
539 | tty_ldisc_flush(tty); | 553 | tty_ldisc_flush(tty); |
540 | return 0; | 554 | break; |
541 | 555 | ||
542 | case KDGKBMODE: | 556 | case KDGKBMODE: |
543 | ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : | 557 | ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : |
@@ -557,28 +571,32 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
557 | set_vc_kbd_mode(kbd, VC_META); | 571 | set_vc_kbd_mode(kbd, VC_META); |
558 | break; | 572 | break; |
559 | default: | 573 | default: |
560 | return -EINVAL; | 574 | ret = -EINVAL; |
561 | } | 575 | } |
562 | return 0; | 576 | break; |
563 | 577 | ||
564 | case KDGKBMETA: | 578 | case KDGKBMETA: |
565 | ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); | 579 | ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); |
566 | setint: | 580 | setint: |
567 | return put_user(ucval, (int __user *)arg); | 581 | ret = put_user(ucval, (int __user *)arg); |
582 | break; | ||
568 | 583 | ||
569 | case KDGETKEYCODE: | 584 | case KDGETKEYCODE: |
570 | case KDSETKEYCODE: | 585 | case KDSETKEYCODE: |
571 | if(!capable(CAP_SYS_TTY_CONFIG)) | 586 | if(!capable(CAP_SYS_TTY_CONFIG)) |
572 | perm=0; | 587 | perm = 0; |
573 | return do_kbkeycode_ioctl(cmd, up, perm); | 588 | ret = do_kbkeycode_ioctl(cmd, up, perm); |
589 | break; | ||
574 | 590 | ||
575 | case KDGKBENT: | 591 | case KDGKBENT: |
576 | case KDSKBENT: | 592 | case KDSKBENT: |
577 | return do_kdsk_ioctl(cmd, up, perm, kbd); | 593 | ret = do_kdsk_ioctl(cmd, up, perm, kbd); |
594 | break; | ||
578 | 595 | ||
579 | case KDGKBSENT: | 596 | case KDGKBSENT: |
580 | case KDSKBSENT: | 597 | case KDSKBSENT: |
581 | return do_kdgkb_ioctl(cmd, up, perm); | 598 | ret = do_kdgkb_ioctl(cmd, up, perm); |
599 | break; | ||
582 | 600 | ||
583 | case KDGKBDIACR: | 601 | case KDGKBDIACR: |
584 | { | 602 | { |
@@ -586,26 +604,31 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
586 | struct kbdiacr diacr; | 604 | struct kbdiacr diacr; |
587 | int i; | 605 | int i; |
588 | 606 | ||
589 | if (put_user(accent_table_size, &a->kb_cnt)) | 607 | if (put_user(accent_table_size, &a->kb_cnt)) { |
590 | return -EFAULT; | 608 | ret = -EFAULT; |
609 | break; | ||
610 | } | ||
591 | for (i = 0; i < accent_table_size; i++) { | 611 | for (i = 0; i < accent_table_size; i++) { |
592 | diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); | 612 | diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); |
593 | diacr.base = conv_uni_to_8bit(accent_table[i].base); | 613 | diacr.base = conv_uni_to_8bit(accent_table[i].base); |
594 | diacr.result = conv_uni_to_8bit(accent_table[i].result); | 614 | diacr.result = conv_uni_to_8bit(accent_table[i].result); |
595 | if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) | 615 | if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) { |
596 | return -EFAULT; | 616 | ret = -EFAULT; |
617 | break; | ||
618 | } | ||
597 | } | 619 | } |
598 | return 0; | 620 | break; |
599 | } | 621 | } |
600 | case KDGKBDIACRUC: | 622 | case KDGKBDIACRUC: |
601 | { | 623 | { |
602 | struct kbdiacrsuc __user *a = up; | 624 | struct kbdiacrsuc __user *a = up; |
603 | 625 | ||
604 | if (put_user(accent_table_size, &a->kb_cnt)) | 626 | if (put_user(accent_table_size, &a->kb_cnt)) |
605 | return -EFAULT; | 627 | ret = -EFAULT; |
606 | if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc))) | 628 | else if (copy_to_user(a->kbdiacruc, accent_table, |
607 | return -EFAULT; | 629 | accent_table_size*sizeof(struct kbdiacruc))) |
608 | return 0; | 630 | ret = -EFAULT; |
631 | break; | ||
609 | } | 632 | } |
610 | 633 | ||
611 | case KDSKBDIACR: | 634 | case KDSKBDIACR: |
@@ -616,20 +639,26 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
616 | int i; | 639 | int i; |
617 | 640 | ||
618 | if (!perm) | 641 | if (!perm) |
619 | return -EPERM; | 642 | goto eperm; |
620 | if (get_user(ct,&a->kb_cnt)) | 643 | if (get_user(ct,&a->kb_cnt)) { |
621 | return -EFAULT; | 644 | ret = -EFAULT; |
622 | if (ct >= MAX_DIACR) | 645 | break; |
623 | return -EINVAL; | 646 | } |
647 | if (ct >= MAX_DIACR) { | ||
648 | ret = -EINVAL; | ||
649 | break; | ||
650 | } | ||
624 | accent_table_size = ct; | 651 | accent_table_size = ct; |
625 | for (i = 0; i < ct; i++) { | 652 | for (i = 0; i < ct; i++) { |
626 | if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) | 653 | if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) { |
627 | return -EFAULT; | 654 | ret = -EFAULT; |
655 | break; | ||
656 | } | ||
628 | accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); | 657 | accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); |
629 | accent_table[i].base = conv_8bit_to_uni(diacr.base); | 658 | accent_table[i].base = conv_8bit_to_uni(diacr.base); |
630 | accent_table[i].result = conv_8bit_to_uni(diacr.result); | 659 | accent_table[i].result = conv_8bit_to_uni(diacr.result); |
631 | } | 660 | } |
632 | return 0; | 661 | break; |
633 | } | 662 | } |
634 | 663 | ||
635 | case KDSKBDIACRUC: | 664 | case KDSKBDIACRUC: |
@@ -638,15 +667,19 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
638 | unsigned int ct; | 667 | unsigned int ct; |
639 | 668 | ||
640 | if (!perm) | 669 | if (!perm) |
641 | return -EPERM; | 670 | goto eperm; |
642 | if (get_user(ct,&a->kb_cnt)) | 671 | if (get_user(ct,&a->kb_cnt)) { |
643 | return -EFAULT; | 672 | ret = -EFAULT; |
644 | if (ct >= MAX_DIACR) | 673 | break; |
645 | return -EINVAL; | 674 | } |
675 | if (ct >= MAX_DIACR) { | ||
676 | ret = -EINVAL; | ||
677 | break; | ||
678 | } | ||
646 | accent_table_size = ct; | 679 | accent_table_size = ct; |
647 | if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) | 680 | if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) |
648 | return -EFAULT; | 681 | ret = -EFAULT; |
649 | return 0; | 682 | break; |
650 | } | 683 | } |
651 | 684 | ||
652 | /* the ioctls below read/set the flags usually shown in the leds */ | 685 | /* the ioctls below read/set the flags usually shown in the leds */ |
@@ -657,26 +690,29 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
657 | 690 | ||
658 | case KDSKBLED: | 691 | case KDSKBLED: |
659 | if (!perm) | 692 | if (!perm) |
660 | return -EPERM; | 693 | goto eperm; |
661 | if (arg & ~0x77) | 694 | if (arg & ~0x77) { |
662 | return -EINVAL; | 695 | ret = -EINVAL; |
696 | break; | ||
697 | } | ||
663 | kbd->ledflagstate = (arg & 7); | 698 | kbd->ledflagstate = (arg & 7); |
664 | kbd->default_ledflagstate = ((arg >> 4) & 7); | 699 | kbd->default_ledflagstate = ((arg >> 4) & 7); |
665 | set_leds(); | 700 | set_leds(); |
666 | return 0; | 701 | break; |
667 | 702 | ||
668 | /* the ioctls below only set the lights, not the functions */ | 703 | /* the ioctls below only set the lights, not the functions */ |
669 | /* for those, see KDGKBLED and KDSKBLED above */ | 704 | /* for those, see KDGKBLED and KDSKBLED above */ |
670 | case KDGETLED: | 705 | case KDGETLED: |
671 | ucval = getledstate(); | 706 | ucval = getledstate(); |
672 | setchar: | 707 | setchar: |
673 | return put_user(ucval, (char __user *)arg); | 708 | ret = put_user(ucval, (char __user *)arg); |
709 | break; | ||
674 | 710 | ||
675 | case KDSETLED: | 711 | case KDSETLED: |
676 | if (!perm) | 712 | if (!perm) |
677 | return -EPERM; | 713 | goto eperm; |
678 | setledstate(kbd, arg); | 714 | setledstate(kbd, arg); |
679 | return 0; | 715 | break; |
680 | 716 | ||
681 | /* | 717 | /* |
682 | * A process can indicate its willingness to accept signals | 718 | * A process can indicate its willingness to accept signals |
@@ -688,16 +724,17 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
688 | case KDSIGACCEPT: | 724 | case KDSIGACCEPT: |
689 | { | 725 | { |
690 | if (!perm || !capable(CAP_KILL)) | 726 | if (!perm || !capable(CAP_KILL)) |
691 | return -EPERM; | 727 | goto eperm; |
692 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) | 728 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) |
693 | return -EINVAL; | 729 | ret = -EINVAL; |
694 | 730 | else { | |
695 | spin_lock_irq(&vt_spawn_con.lock); | 731 | spin_lock_irq(&vt_spawn_con.lock); |
696 | put_pid(vt_spawn_con.pid); | 732 | put_pid(vt_spawn_con.pid); |
697 | vt_spawn_con.pid = get_pid(task_pid(current)); | 733 | vt_spawn_con.pid = get_pid(task_pid(current)); |
698 | vt_spawn_con.sig = arg; | 734 | vt_spawn_con.sig = arg; |
699 | spin_unlock_irq(&vt_spawn_con.lock); | 735 | spin_unlock_irq(&vt_spawn_con.lock); |
700 | return 0; | 736 | } |
737 | break; | ||
701 | } | 738 | } |
702 | 739 | ||
703 | case VT_SETMODE: | 740 | case VT_SETMODE: |
@@ -705,11 +742,15 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
705 | struct vt_mode tmp; | 742 | struct vt_mode tmp; |
706 | 743 | ||
707 | if (!perm) | 744 | if (!perm) |
708 | return -EPERM; | 745 | goto eperm; |
709 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) | 746 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { |
710 | return -EFAULT; | 747 | ret = -EFAULT; |
711 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) | 748 | goto out; |
712 | return -EINVAL; | 749 | } |
750 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { | ||
751 | ret = -EINVAL; | ||
752 | goto out; | ||
753 | } | ||
713 | acquire_console_sem(); | 754 | acquire_console_sem(); |
714 | vc->vt_mode = tmp; | 755 | vc->vt_mode = tmp; |
715 | /* the frsig is ignored, so we set it to 0 */ | 756 | /* the frsig is ignored, so we set it to 0 */ |
@@ -719,7 +760,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
719 | /* no switch is required -- saw@shade.msu.ru */ | 760 | /* no switch is required -- saw@shade.msu.ru */ |
720 | vc->vt_newvt = -1; | 761 | vc->vt_newvt = -1; |
721 | release_console_sem(); | 762 | release_console_sem(); |
722 | return 0; | 763 | break; |
723 | } | 764 | } |
724 | 765 | ||
725 | case VT_GETMODE: | 766 | case VT_GETMODE: |
@@ -732,7 +773,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
732 | release_console_sem(); | 773 | release_console_sem(); |
733 | 774 | ||
734 | rc = copy_to_user(up, &tmp, sizeof(struct vt_mode)); | 775 | rc = copy_to_user(up, &tmp, sizeof(struct vt_mode)); |
735 | return rc ? -EFAULT : 0; | 776 | if (rc) |
777 | ret = -EFAULT; | ||
778 | break; | ||
736 | } | 779 | } |
737 | 780 | ||
738 | /* | 781 | /* |
@@ -746,12 +789,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
746 | unsigned short state, mask; | 789 | unsigned short state, mask; |
747 | 790 | ||
748 | if (put_user(fg_console + 1, &vtstat->v_active)) | 791 | if (put_user(fg_console + 1, &vtstat->v_active)) |
749 | return -EFAULT; | 792 | ret = -EFAULT; |
750 | state = 1; /* /dev/tty0 is always open */ | 793 | else { |
751 | for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1) | 794 | state = 1; /* /dev/tty0 is always open */ |
752 | if (VT_IS_IN_USE(i)) | 795 | for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; |
753 | state |= mask; | 796 | ++i, mask <<= 1) |
754 | return put_user(state, &vtstat->v_state); | 797 | if (VT_IS_IN_USE(i)) |
798 | state |= mask; | ||
799 | ret = put_user(state, &vtstat->v_state); | ||
800 | } | ||
801 | break; | ||
755 | } | 802 | } |
756 | 803 | ||
757 | /* | 804 | /* |
@@ -771,27 +818,31 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
771 | */ | 818 | */ |
772 | case VT_ACTIVATE: | 819 | case VT_ACTIVATE: |
773 | if (!perm) | 820 | if (!perm) |
774 | return -EPERM; | 821 | goto eperm; |
775 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 822 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
776 | return -ENXIO; | 823 | ret = -ENXIO; |
777 | arg--; | 824 | else { |
778 | acquire_console_sem(); | 825 | arg--; |
779 | i = vc_allocate(arg); | 826 | acquire_console_sem(); |
780 | release_console_sem(); | 827 | ret = vc_allocate(arg); |
781 | if (i) | 828 | release_console_sem(); |
782 | return i; | 829 | if (ret) |
783 | set_console(arg); | 830 | break; |
784 | return 0; | 831 | set_console(arg); |
832 | } | ||
833 | break; | ||
785 | 834 | ||
786 | /* | 835 | /* |
787 | * wait until the specified VT has been activated | 836 | * wait until the specified VT has been activated |
788 | */ | 837 | */ |
789 | case VT_WAITACTIVE: | 838 | case VT_WAITACTIVE: |
790 | if (!perm) | 839 | if (!perm) |
791 | return -EPERM; | 840 | goto eperm; |
792 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 841 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
793 | return -ENXIO; | 842 | ret = -ENXIO; |
794 | return vt_waitactive(arg-1); | 843 | else |
844 | ret = vt_waitactive(arg - 1); | ||
845 | break; | ||
795 | 846 | ||
796 | /* | 847 | /* |
797 | * If a vt is under process control, the kernel will not switch to it | 848 | * If a vt is under process control, the kernel will not switch to it |
@@ -805,10 +856,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
805 | */ | 856 | */ |
806 | case VT_RELDISP: | 857 | case VT_RELDISP: |
807 | if (!perm) | 858 | if (!perm) |
808 | return -EPERM; | 859 | goto eperm; |
809 | if (vc->vt_mode.mode != VT_PROCESS) | ||
810 | return -EINVAL; | ||
811 | 860 | ||
861 | if (vc->vt_mode.mode != VT_PROCESS) { | ||
862 | ret = -EINVAL; | ||
863 | break; | ||
864 | } | ||
812 | /* | 865 | /* |
813 | * Switching-from response | 866 | * Switching-from response |
814 | */ | 867 | */ |
@@ -829,10 +882,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
829 | int newvt; | 882 | int newvt; |
830 | newvt = vc->vt_newvt; | 883 | newvt = vc->vt_newvt; |
831 | vc->vt_newvt = -1; | 884 | vc->vt_newvt = -1; |
832 | i = vc_allocate(newvt); | 885 | ret = vc_allocate(newvt); |
833 | if (i) { | 886 | if (ret) { |
834 | release_console_sem(); | 887 | release_console_sem(); |
835 | return i; | 888 | break; |
836 | } | 889 | } |
837 | /* | 890 | /* |
838 | * When we actually do the console switch, | 891 | * When we actually do the console switch, |
@@ -841,31 +894,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
841 | */ | 894 | */ |
842 | complete_change_console(vc_cons[newvt].d); | 895 | complete_change_console(vc_cons[newvt].d); |
843 | } | 896 | } |
844 | } | 897 | } else { |
845 | 898 | /* | |
846 | /* | 899 | * Switched-to response |
847 | * Switched-to response | 900 | */ |
848 | */ | ||
849 | else | ||
850 | { | ||
851 | /* | 901 | /* |
852 | * If it's just an ACK, ignore it | 902 | * If it's just an ACK, ignore it |
853 | */ | 903 | */ |
854 | if (arg != VT_ACKACQ) { | 904 | if (arg != VT_ACKACQ) |
855 | release_console_sem(); | 905 | ret = -EINVAL; |
856 | return -EINVAL; | ||
857 | } | ||
858 | } | 906 | } |
859 | release_console_sem(); | 907 | release_console_sem(); |
860 | 908 | break; | |
861 | return 0; | ||
862 | 909 | ||
863 | /* | 910 | /* |
864 | * Disallocate memory associated to VT (but leave VT1) | 911 | * Disallocate memory associated to VT (but leave VT1) |
865 | */ | 912 | */ |
866 | case VT_DISALLOCATE: | 913 | case VT_DISALLOCATE: |
867 | if (arg > MAX_NR_CONSOLES) | 914 | if (arg > MAX_NR_CONSOLES) { |
868 | return -ENXIO; | 915 | ret = -ENXIO; |
916 | break; | ||
917 | } | ||
869 | if (arg == 0) { | 918 | if (arg == 0) { |
870 | /* deallocate all unused consoles, but leave 0 */ | 919 | /* deallocate all unused consoles, but leave 0 */ |
871 | acquire_console_sem(); | 920 | acquire_console_sem(); |
@@ -877,14 +926,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
877 | /* deallocate a single console, if possible */ | 926 | /* deallocate a single console, if possible */ |
878 | arg--; | 927 | arg--; |
879 | if (VT_BUSY(arg)) | 928 | if (VT_BUSY(arg)) |
880 | return -EBUSY; | 929 | ret = -EBUSY; |
881 | if (arg) { /* leave 0 */ | 930 | else if (arg) { /* leave 0 */ |
882 | acquire_console_sem(); | 931 | acquire_console_sem(); |
883 | vc_deallocate(arg); | 932 | vc_deallocate(arg); |
884 | release_console_sem(); | 933 | release_console_sem(); |
885 | } | 934 | } |
886 | } | 935 | } |
887 | return 0; | 936 | break; |
888 | 937 | ||
889 | case VT_RESIZE: | 938 | case VT_RESIZE: |
890 | { | 939 | { |
@@ -893,21 +942,21 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
893 | 942 | ||
894 | ushort ll,cc; | 943 | ushort ll,cc; |
895 | if (!perm) | 944 | if (!perm) |
896 | return -EPERM; | 945 | goto eperm; |
897 | if (get_user(ll, &vtsizes->v_rows) || | 946 | if (get_user(ll, &vtsizes->v_rows) || |
898 | get_user(cc, &vtsizes->v_cols)) | 947 | get_user(cc, &vtsizes->v_cols)) |
899 | return -EFAULT; | 948 | ret = -EFAULT; |
900 | 949 | else { | |
901 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 950 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
902 | vc = vc_cons[i].d; | 951 | vc = vc_cons[i].d; |
903 | 952 | ||
904 | if (vc) { | 953 | if (vc) { |
905 | vc->vc_resize_user = 1; | 954 | vc->vc_resize_user = 1; |
906 | vc_lock_resize(vc_cons[i].d, cc, ll); | 955 | vc_lock_resize(vc_cons[i].d, cc, ll); |
956 | } | ||
907 | } | 957 | } |
908 | } | 958 | } |
909 | 959 | break; | |
910 | return 0; | ||
911 | } | 960 | } |
912 | 961 | ||
913 | case VT_RESIZEX: | 962 | case VT_RESIZEX: |
@@ -915,10 +964,13 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
915 | struct vt_consize __user *vtconsize = up; | 964 | struct vt_consize __user *vtconsize = up; |
916 | ushort ll,cc,vlin,clin,vcol,ccol; | 965 | ushort ll,cc,vlin,clin,vcol,ccol; |
917 | if (!perm) | 966 | if (!perm) |
918 | return -EPERM; | 967 | goto eperm; |
919 | if (!access_ok(VERIFY_READ, vtconsize, | 968 | if (!access_ok(VERIFY_READ, vtconsize, |
920 | sizeof(struct vt_consize))) | 969 | sizeof(struct vt_consize))) { |
921 | return -EFAULT; | 970 | ret = -EFAULT; |
971 | break; | ||
972 | } | ||
973 | /* FIXME: Should check the copies properly */ | ||
922 | __get_user(ll, &vtconsize->v_rows); | 974 | __get_user(ll, &vtconsize->v_rows); |
923 | __get_user(cc, &vtconsize->v_cols); | 975 | __get_user(cc, &vtconsize->v_cols); |
924 | __get_user(vlin, &vtconsize->v_vlin); | 976 | __get_user(vlin, &vtconsize->v_vlin); |
@@ -928,21 +980,28 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
928 | vlin = vlin ? vlin : vc->vc_scan_lines; | 980 | vlin = vlin ? vlin : vc->vc_scan_lines; |
929 | if (clin) { | 981 | if (clin) { |
930 | if (ll) { | 982 | if (ll) { |
931 | if (ll != vlin/clin) | 983 | if (ll != vlin/clin) { |
932 | return -EINVAL; /* Parameters don't add up */ | 984 | /* Parameters don't add up */ |
985 | ret = -EINVAL; | ||
986 | break; | ||
987 | } | ||
933 | } else | 988 | } else |
934 | ll = vlin/clin; | 989 | ll = vlin/clin; |
935 | } | 990 | } |
936 | if (vcol && ccol) { | 991 | if (vcol && ccol) { |
937 | if (cc) { | 992 | if (cc) { |
938 | if (cc != vcol/ccol) | 993 | if (cc != vcol/ccol) { |
939 | return -EINVAL; | 994 | ret = -EINVAL; |
995 | break; | ||
996 | } | ||
940 | } else | 997 | } else |
941 | cc = vcol/ccol; | 998 | cc = vcol/ccol; |
942 | } | 999 | } |
943 | 1000 | ||
944 | if (clin > 32) | 1001 | if (clin > 32) { |
945 | return -EINVAL; | 1002 | ret = -EINVAL; |
1003 | break; | ||
1004 | } | ||
946 | 1005 | ||
947 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 1006 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
948 | if (!vc_cons[i].d) | 1007 | if (!vc_cons[i].d) |
@@ -956,19 +1015,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
956 | vc_resize(vc_cons[i].d, cc, ll); | 1015 | vc_resize(vc_cons[i].d, cc, ll); |
957 | release_console_sem(); | 1016 | release_console_sem(); |
958 | } | 1017 | } |
959 | return 0; | 1018 | break; |
960 | } | 1019 | } |
961 | 1020 | ||
962 | case PIO_FONT: { | 1021 | case PIO_FONT: { |
963 | if (!perm) | 1022 | if (!perm) |
964 | return -EPERM; | 1023 | goto eperm; |
965 | op.op = KD_FONT_OP_SET; | 1024 | op.op = KD_FONT_OP_SET; |
966 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ | 1025 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ |
967 | op.width = 8; | 1026 | op.width = 8; |
968 | op.height = 0; | 1027 | op.height = 0; |
969 | op.charcount = 256; | 1028 | op.charcount = 256; |
970 | op.data = up; | 1029 | op.data = up; |
971 | return con_font_op(vc_cons[fg_console].d, &op); | 1030 | ret = con_font_op(vc_cons[fg_console].d, &op); |
1031 | break; | ||
972 | } | 1032 | } |
973 | 1033 | ||
974 | case GIO_FONT: { | 1034 | case GIO_FONT: { |
@@ -978,100 +1038,124 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
978 | op.height = 32; | 1038 | op.height = 32; |
979 | op.charcount = 256; | 1039 | op.charcount = 256; |
980 | op.data = up; | 1040 | op.data = up; |
981 | return con_font_op(vc_cons[fg_console].d, &op); | 1041 | ret = con_font_op(vc_cons[fg_console].d, &op); |
1042 | break; | ||
982 | } | 1043 | } |
983 | 1044 | ||
984 | case PIO_CMAP: | 1045 | case PIO_CMAP: |
985 | if (!perm) | 1046 | if (!perm) |
986 | return -EPERM; | 1047 | ret = -EPERM; |
987 | return con_set_cmap(up); | 1048 | else |
1049 | ret = con_set_cmap(up); | ||
1050 | break; | ||
988 | 1051 | ||
989 | case GIO_CMAP: | 1052 | case GIO_CMAP: |
990 | return con_get_cmap(up); | 1053 | ret = con_get_cmap(up); |
1054 | break; | ||
991 | 1055 | ||
992 | case PIO_FONTX: | 1056 | case PIO_FONTX: |
993 | case GIO_FONTX: | 1057 | case GIO_FONTX: |
994 | return do_fontx_ioctl(cmd, up, perm, &op); | 1058 | ret = do_fontx_ioctl(cmd, up, perm, &op); |
1059 | break; | ||
995 | 1060 | ||
996 | case PIO_FONTRESET: | 1061 | case PIO_FONTRESET: |
997 | { | 1062 | { |
998 | if (!perm) | 1063 | if (!perm) |
999 | return -EPERM; | 1064 | goto eperm; |
1000 | 1065 | ||
1001 | #ifdef BROKEN_GRAPHICS_PROGRAMS | 1066 | #ifdef BROKEN_GRAPHICS_PROGRAMS |
1002 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default | 1067 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default |
1003 | font is not saved. */ | 1068 | font is not saved. */ |
1004 | return -ENOSYS; | 1069 | ret = -ENOSYS; |
1070 | break; | ||
1005 | #else | 1071 | #else |
1006 | { | 1072 | { |
1007 | op.op = KD_FONT_OP_SET_DEFAULT; | 1073 | op.op = KD_FONT_OP_SET_DEFAULT; |
1008 | op.data = NULL; | 1074 | op.data = NULL; |
1009 | i = con_font_op(vc_cons[fg_console].d, &op); | 1075 | ret = con_font_op(vc_cons[fg_console].d, &op); |
1010 | if (i) | 1076 | if (ret) |
1011 | return i; | 1077 | break; |
1012 | con_set_default_unimap(vc_cons[fg_console].d); | 1078 | con_set_default_unimap(vc_cons[fg_console].d); |
1013 | return 0; | 1079 | break; |
1014 | } | 1080 | } |
1015 | #endif | 1081 | #endif |
1016 | } | 1082 | } |
1017 | 1083 | ||
1018 | case KDFONTOP: { | 1084 | case KDFONTOP: { |
1019 | if (copy_from_user(&op, up, sizeof(op))) | 1085 | if (copy_from_user(&op, up, sizeof(op))) { |
1020 | return -EFAULT; | 1086 | ret = -EFAULT; |
1087 | break; | ||
1088 | } | ||
1021 | if (!perm && op.op != KD_FONT_OP_GET) | 1089 | if (!perm && op.op != KD_FONT_OP_GET) |
1022 | return -EPERM; | 1090 | goto eperm; |
1023 | i = con_font_op(vc, &op); | 1091 | ret = con_font_op(vc, &op); |
1024 | if (i) return i; | 1092 | if (ret) |
1093 | break; | ||
1025 | if (copy_to_user(up, &op, sizeof(op))) | 1094 | if (copy_to_user(up, &op, sizeof(op))) |
1026 | return -EFAULT; | 1095 | ret = -EFAULT; |
1027 | return 0; | 1096 | break; |
1028 | } | 1097 | } |
1029 | 1098 | ||
1030 | case PIO_SCRNMAP: | 1099 | case PIO_SCRNMAP: |
1031 | if (!perm) | 1100 | if (!perm) |
1032 | return -EPERM; | 1101 | ret = -EPERM; |
1033 | return con_set_trans_old(up); | 1102 | else |
1103 | ret = con_set_trans_old(up); | ||
1104 | break; | ||
1034 | 1105 | ||
1035 | case GIO_SCRNMAP: | 1106 | case GIO_SCRNMAP: |
1036 | return con_get_trans_old(up); | 1107 | ret = con_get_trans_old(up); |
1108 | break; | ||
1037 | 1109 | ||
1038 | case PIO_UNISCRNMAP: | 1110 | case PIO_UNISCRNMAP: |
1039 | if (!perm) | 1111 | if (!perm) |
1040 | return -EPERM; | 1112 | ret = -EPERM; |
1041 | return con_set_trans_new(up); | 1113 | else |
1114 | ret = con_set_trans_new(up); | ||
1115 | break; | ||
1042 | 1116 | ||
1043 | case GIO_UNISCRNMAP: | 1117 | case GIO_UNISCRNMAP: |
1044 | return con_get_trans_new(up); | 1118 | ret = con_get_trans_new(up); |
1119 | break; | ||
1045 | 1120 | ||
1046 | case PIO_UNIMAPCLR: | 1121 | case PIO_UNIMAPCLR: |
1047 | { struct unimapinit ui; | 1122 | { struct unimapinit ui; |
1048 | if (!perm) | 1123 | if (!perm) |
1049 | return -EPERM; | 1124 | goto eperm; |
1050 | i = copy_from_user(&ui, up, sizeof(struct unimapinit)); | 1125 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); |
1051 | if (i) return -EFAULT; | 1126 | if (!ret) |
1052 | con_clear_unimap(vc, &ui); | 1127 | con_clear_unimap(vc, &ui); |
1053 | return 0; | 1128 | break; |
1054 | } | 1129 | } |
1055 | 1130 | ||
1056 | case PIO_UNIMAP: | 1131 | case PIO_UNIMAP: |
1057 | case GIO_UNIMAP: | 1132 | case GIO_UNIMAP: |
1058 | return do_unimap_ioctl(cmd, up, perm, vc); | 1133 | ret = do_unimap_ioctl(cmd, up, perm, vc); |
1134 | break; | ||
1059 | 1135 | ||
1060 | case VT_LOCKSWITCH: | 1136 | case VT_LOCKSWITCH: |
1061 | if (!capable(CAP_SYS_TTY_CONFIG)) | 1137 | if (!capable(CAP_SYS_TTY_CONFIG)) |
1062 | return -EPERM; | 1138 | goto eperm; |
1063 | vt_dont_switch = 1; | 1139 | vt_dont_switch = 1; |
1064 | return 0; | 1140 | break; |
1065 | case VT_UNLOCKSWITCH: | 1141 | case VT_UNLOCKSWITCH: |
1066 | if (!capable(CAP_SYS_TTY_CONFIG)) | 1142 | if (!capable(CAP_SYS_TTY_CONFIG)) |
1067 | return -EPERM; | 1143 | goto eperm; |
1068 | vt_dont_switch = 0; | 1144 | vt_dont_switch = 0; |
1069 | return 0; | 1145 | break; |
1070 | case VT_GETHIFONTMASK: | 1146 | case VT_GETHIFONTMASK: |
1071 | return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg); | 1147 | ret = put_user(vc->vc_hi_font_mask, |
1148 | (unsigned short __user *)arg); | ||
1149 | break; | ||
1072 | default: | 1150 | default: |
1073 | return -ENOIOCTLCMD; | 1151 | ret = -ENOIOCTLCMD; |
1074 | } | 1152 | } |
1153 | out: | ||
1154 | unlock_kernel(); | ||
1155 | return ret; | ||
1156 | eperm: | ||
1157 | ret = -EPERM; | ||
1158 | goto out; | ||
1075 | } | 1159 | } |
1076 | 1160 | ||
1077 | /* | 1161 | /* |