diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 17 | ||||
-rw-r--r-- | drivers/char/apm-emulation.c | 2 | ||||
-rw-r--r-- | drivers/char/cyclades.c | 767 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 25 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 29 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 268 | ||||
-rw-r--r-- | drivers/char/isicom.c | 10 | ||||
-rw-r--r-- | drivers/char/moxa.c | 148 | ||||
-rw-r--r-- | drivers/char/mxser.c | 23 | ||||
-rw-r--r-- | drivers/char/mxser_new.c | 120 | ||||
-rw-r--r-- | drivers/char/pty.c | 24 | ||||
-rw-r--r-- | drivers/char/random.c | 2 | ||||
-rw-r--r-- | drivers/char/rocket.c | 91 | ||||
-rw-r--r-- | drivers/char/rocket_int.h | 7 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 11 | ||||
-rw-r--r-- | drivers/char/vt.c | 6 |
16 files changed, 733 insertions, 817 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 69f851854782..65491103e0fb 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -36,23 +36,6 @@ config VT | |||
36 | If unsure, say Y, or else you won't be able to do much with your new | 36 | If unsure, say Y, or else you won't be able to do much with your new |
37 | shiny Linux system :-) | 37 | shiny Linux system :-) |
38 | 38 | ||
39 | config VT_UNICODE | ||
40 | bool "Virtual console is Unicode by default" | ||
41 | depends on VT | ||
42 | default n | ||
43 | ---help--- | ||
44 | If you say Y here, the virtual terminal will be in UTF-8 by default, | ||
45 | and the keyboard will run in unicode mode. | ||
46 | |||
47 | If you say N here, the virtual terminal will not be in UTF-8 by | ||
48 | default, and the keyboard will run in XLATE mode. | ||
49 | |||
50 | This can also be changed by passing 'default_utf8=<0|1>' on the | ||
51 | kernel command line. | ||
52 | |||
53 | Historically, the kernel has defaulted to non-UTF8 and XLATE mode. | ||
54 | If unsure, say N here. | ||
55 | |||
56 | config VT_CONSOLE | 39 | config VT_CONSOLE |
57 | bool "Support for console on virtual terminal" if EMBEDDED | 40 | bool "Support for console on virtual terminal" if EMBEDDED |
58 | depends on VT | 41 | depends on VT |
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index ec116df919d9..c99e43b837f5 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/apm_bios.h> | 18 | #include <linux/apm_bios.h> |
19 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/pm.h> | 21 | #include <linux/suspend.h> |
22 | #include <linux/apm-emulation.h> | 22 | #include <linux/apm-emulation.h> |
23 | #include <linux/freezer.h> | 23 | #include <linux/freezer.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 9e0adfe27c12..d15234c5965e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -662,7 +662,7 @@ | |||
662 | static void cy_throttle(struct tty_struct *tty); | 662 | static void cy_throttle(struct tty_struct *tty); |
663 | static void cy_send_xchar(struct tty_struct *tty, char ch); | 663 | static void cy_send_xchar(struct tty_struct *tty, char ch); |
664 | 664 | ||
665 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 665 | #define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1) |
666 | 666 | ||
667 | #define Z_FPGA_CHECK(card) \ | 667 | #define Z_FPGA_CHECK(card) \ |
668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ | 668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
@@ -897,71 +897,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
897 | return 0; | 897 | return 0; |
898 | } /* serial_paranoia_check */ | 898 | } /* serial_paranoia_check */ |
899 | 899 | ||
900 | /* | ||
901 | * This routine is used by the interrupt handler to schedule | ||
902 | * processing in the software interrupt portion of the driver | ||
903 | * (also known as the "bottom half"). This can be called any | ||
904 | * number of times for any channel without harm. | ||
905 | */ | ||
906 | static inline void cy_sched_event(struct cyclades_port *info, int event) | ||
907 | { | ||
908 | info->event |= 1 << event; /* remember what kind of event and who */ | ||
909 | schedule_work(&info->tqueue); | ||
910 | } /* cy_sched_event */ | ||
911 | |||
912 | /* | ||
913 | * This routine is used to handle the "bottom half" processing for the | ||
914 | * serial driver, known also the "software interrupt" processing. | ||
915 | * This processing is done at the kernel interrupt level, after the | ||
916 | * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This | ||
917 | * is where time-consuming activities which can not be done in the | ||
918 | * interrupt driver proper are done; the interrupt driver schedules | ||
919 | * them using cy_sched_event(), and they get done here. | ||
920 | * | ||
921 | * This is done through one level of indirection--the task queue. | ||
922 | * When a hardware interrupt service routine wants service by the | ||
923 | * driver's bottom half, it enqueues the appropriate tq_struct (one | ||
924 | * per port) to the keventd work queue and sets a request flag | ||
925 | * that the work queue be processed. | ||
926 | * | ||
927 | * Although this may seem unwieldy, it gives the system a way to | ||
928 | * pass an argument (in this case the pointer to the cyclades_port | ||
929 | * structure) to the bottom half of the driver. Previous kernels | ||
930 | * had to poll every port to see if that port needed servicing. | ||
931 | */ | ||
932 | static void | ||
933 | do_softint(struct work_struct *work) | ||
934 | { | ||
935 | struct cyclades_port *info = | ||
936 | container_of(work, struct cyclades_port, tqueue); | ||
937 | struct tty_struct *tty; | ||
938 | |||
939 | tty = info->tty; | ||
940 | if (!tty) | ||
941 | return; | ||
942 | |||
943 | if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { | ||
944 | tty_hangup(info->tty); | ||
945 | wake_up_interruptible(&info->open_wait); | ||
946 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
947 | } | ||
948 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) | ||
949 | wake_up_interruptible(&info->open_wait); | ||
950 | #ifdef CONFIG_CYZ_INTR | ||
951 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && | ||
952 | !timer_pending(&cyz_rx_full_timer[info->line])) | ||
953 | mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); | ||
954 | #endif | ||
955 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) | ||
956 | wake_up_interruptible(&info->delta_msr_wait); | ||
957 | tty_wakeup(tty); | ||
958 | #ifdef Z_WAKE | ||
959 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) | ||
960 | complete(&info->shutdown_wait); | ||
961 | #endif | ||
962 | } /* do_softint */ | ||
963 | |||
964 | |||
965 | /***********************************************************/ | 900 | /***********************************************************/ |
966 | /********* Start of block of Cyclom-Y specific code ********/ | 901 | /********* Start of block of Cyclom-Y specific code ********/ |
967 | 902 | ||
@@ -1045,382 +980,332 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1045 | } | 980 | } |
1046 | #endif /* CONFIG_ISA */ | 981 | #endif /* CONFIG_ISA */ |
1047 | 982 | ||
1048 | static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | 983 | static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, |
1049 | void __iomem * base_addr, int status, int index) | 984 | void __iomem *base_addr) |
1050 | { | 985 | { |
1051 | struct cyclades_port *info; | 986 | struct cyclades_port *info; |
1052 | struct tty_struct *tty; | 987 | struct tty_struct *tty; |
1053 | int char_count; | 988 | int len, index = cinfo->bus_index; |
1054 | int j, len, mdm_change, mdm_status, outch; | 989 | u8 save_xir, channel, save_car, data, char_count; |
1055 | int save_xir, channel, save_car; | ||
1056 | char data; | ||
1057 | 990 | ||
1058 | if (status & CySRReceive) { /* reception interrupt */ | ||
1059 | #ifdef CY_DEBUG_INTERRUPTS | 991 | #ifdef CY_DEBUG_INTERRUPTS |
1060 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); | 992 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
1061 | #endif | 993 | #endif |
1062 | /* determine the channel & change to that context */ | 994 | /* determine the channel & change to that context */ |
1063 | spin_lock(&cinfo->card_lock); | 995 | save_xir = readb(base_addr + (CyRIR << index)); |
1064 | save_xir = (u_char) readb(base_addr + (CyRIR << index)); | 996 | channel = save_xir & CyIRChannel; |
1065 | channel = (u_short) (save_xir & CyIRChannel); | 997 | info = &cinfo->ports[channel + chip * 4]; |
1066 | info = &cinfo->ports[channel + chip * 4]; | 998 | save_car = readb(base_addr + (CyCAR << index)); |
1067 | save_car = readb(base_addr + (CyCAR << index)); | 999 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1068 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1000 | |
1069 | 1001 | /* if there is nowhere to put the data, discard it */ | |
1070 | /* if there is nowhere to put the data, discard it */ | 1002 | if (info->tty == NULL) { |
1071 | if (info->tty == NULL) { | 1003 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1072 | j = (readb(base_addr + (CyRIVR << index)) & | 1004 | CyIVRRxEx) { /* exception */ |
1073 | CyIVRMask); | 1005 | data = readb(base_addr + (CyRDSR << index)); |
1074 | if (j == CyIVRRxEx) { /* exception */ | 1006 | } else { /* normal character reception */ |
1007 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1008 | while (char_count--) | ||
1075 | data = readb(base_addr + (CyRDSR << index)); | 1009 | data = readb(base_addr + (CyRDSR << index)); |
1076 | } else { /* normal character reception */ | 1010 | } |
1077 | char_count = readb(base_addr + | 1011 | goto end; |
1078 | (CyRDCR << index)); | 1012 | } |
1079 | while (char_count--) { | 1013 | /* there is an open port for this data */ |
1080 | data = readb(base_addr + | 1014 | tty = info->tty; |
1081 | (CyRDSR << index)); | 1015 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1082 | } | 1016 | CyIVRRxEx) { /* exception */ |
1083 | } | 1017 | data = readb(base_addr + (CyRDSR << index)); |
1084 | } else { /* there is an open port for this data */ | 1018 | |
1085 | tty = info->tty; | 1019 | /* For statistics only */ |
1086 | j = (readb(base_addr + (CyRIVR << index)) & | 1020 | if (data & CyBREAK) |
1087 | CyIVRMask); | 1021 | info->icount.brk++; |
1088 | if (j == CyIVRRxEx) { /* exception */ | 1022 | else if (data & CyFRAME) |
1089 | data = readb(base_addr + (CyRDSR << index)); | 1023 | info->icount.frame++; |
1090 | 1024 | else if (data & CyPARITY) | |
1091 | /* For statistics only */ | 1025 | info->icount.parity++; |
1092 | if (data & CyBREAK) | 1026 | else if (data & CyOVERRUN) |
1093 | info->icount.brk++; | 1027 | info->icount.overrun++; |
1094 | else if (data & CyFRAME) | 1028 | |
1095 | info->icount.frame++; | 1029 | if (data & info->ignore_status_mask) { |
1096 | else if (data & CyPARITY) | 1030 | info->icount.rx++; |
1097 | info->icount.parity++; | 1031 | return; |
1098 | else if (data & CyOVERRUN) | 1032 | } |
1099 | info->icount.overrun++; | 1033 | if (tty_buffer_request_room(tty, 1)) { |
1100 | 1034 | if (data & info->read_status_mask) { | |
1101 | if (data & info->ignore_status_mask) { | 1035 | if (data & CyBREAK) { |
1036 | tty_insert_flip_char(tty, | ||
1037 | readb(base_addr + (CyRDSR << | ||
1038 | index)), TTY_BREAK); | ||
1039 | info->icount.rx++; | ||
1040 | if (info->flags & ASYNC_SAK) | ||
1041 | do_SAK(tty); | ||
1042 | } else if (data & CyFRAME) { | ||
1043 | tty_insert_flip_char( tty, | ||
1044 | readb(base_addr + (CyRDSR << | ||
1045 | index)), TTY_FRAME); | ||
1046 | info->icount.rx++; | ||
1047 | info->idle_stats.frame_errs++; | ||
1048 | } else if (data & CyPARITY) { | ||
1049 | /* Pieces of seven... */ | ||
1050 | tty_insert_flip_char(tty, | ||
1051 | readb(base_addr + (CyRDSR << | ||
1052 | index)), TTY_PARITY); | ||
1053 | info->icount.rx++; | ||
1054 | info->idle_stats.parity_errs++; | ||
1055 | } else if (data & CyOVERRUN) { | ||
1056 | tty_insert_flip_char(tty, 0, | ||
1057 | TTY_OVERRUN); | ||
1058 | info->icount.rx++; | ||
1059 | /* If the flip buffer itself is | ||
1060 | overflowing, we still lose | ||
1061 | the next incoming character. | ||
1062 | */ | ||
1063 | tty_insert_flip_char(tty, | ||
1064 | readb(base_addr + (CyRDSR << | ||
1065 | index)), TTY_FRAME); | ||
1102 | info->icount.rx++; | 1066 | info->icount.rx++; |
1103 | spin_unlock(&cinfo->card_lock); | ||
1104 | return; | ||
1105 | } | ||
1106 | if (tty_buffer_request_room(tty, 1)) { | ||
1107 | if (data & info->read_status_mask) { | ||
1108 | if (data & CyBREAK) { | ||
1109 | tty_insert_flip_char( | ||
1110 | tty, | ||
1111 | readb( | ||
1112 | base_addr + | ||
1113 | (CyRDSR << | ||
1114 | index)), | ||
1115 | TTY_BREAK); | ||
1116 | info->icount.rx++; | ||
1117 | if (info->flags & | ||
1118 | ASYNC_SAK) { | ||
1119 | do_SAK(tty); | ||
1120 | } | ||
1121 | } else if (data & CyFRAME) { | ||
1122 | tty_insert_flip_char( | ||
1123 | tty, | ||
1124 | readb( | ||
1125 | base_addr + | ||
1126 | (CyRDSR << | ||
1127 | index)), | ||
1128 | TTY_FRAME); | ||
1129 | info->icount.rx++; | ||
1130 | info->idle_stats. | ||
1131 | frame_errs++; | ||
1132 | } else if (data & CyPARITY) { | ||
1133 | /* Pieces of seven... */ | ||
1134 | tty_insert_flip_char( | ||
1135 | tty, | ||
1136 | readb( | ||
1137 | base_addr + | ||
1138 | (CyRDSR << | ||
1139 | index)), | ||
1140 | TTY_PARITY); | ||
1141 | info->icount.rx++; | ||
1142 | info->idle_stats. | ||
1143 | parity_errs++; | ||
1144 | } else if (data & CyOVERRUN) { | ||
1145 | tty_insert_flip_char( | ||
1146 | tty, 0, | ||
1147 | TTY_OVERRUN); | ||
1148 | info->icount.rx++; | ||
1149 | /* If the flip buffer itself is | ||
1150 | overflowing, we still lose | ||
1151 | the next incoming character. | ||
1152 | */ | ||
1153 | tty_insert_flip_char( | ||
1154 | tty, | ||
1155 | readb( | ||
1156 | base_addr + | ||
1157 | (CyRDSR << | ||
1158 | index)), | ||
1159 | TTY_FRAME); | ||
1160 | info->icount.rx++; | ||
1161 | info->idle_stats. | ||
1162 | overruns++; | ||
1163 | /* These two conditions may imply */ | ||
1164 | /* a normal read should be done. */ | ||
1165 | /* }else if(data & CyTIMEOUT){ */ | ||
1166 | /* }else if(data & CySPECHAR){ */ | ||
1167 | } else { | ||
1168 | tty_insert_flip_char( | ||
1169 | tty, 0, | ||
1170 | TTY_NORMAL); | ||
1171 | info->icount.rx++; | ||
1172 | } | ||
1173 | } else { | ||
1174 | tty_insert_flip_char(tty, 0, | ||
1175 | TTY_NORMAL); | ||
1176 | info->icount.rx++; | ||
1177 | } | ||
1178 | } else { | ||
1179 | /* there was a software buffer | ||
1180 | overrun and nothing could be | ||
1181 | done about it!!! */ | ||
1182 | info->icount.buf_overrun++; | ||
1183 | info->idle_stats.overruns++; | 1067 | info->idle_stats.overruns++; |
1068 | /* These two conditions may imply */ | ||
1069 | /* a normal read should be done. */ | ||
1070 | /* } else if(data & CyTIMEOUT) { */ | ||
1071 | /* } else if(data & CySPECHAR) { */ | ||
1072 | } else { | ||
1073 | tty_insert_flip_char(tty, 0, | ||
1074 | TTY_NORMAL); | ||
1075 | info->icount.rx++; | ||
1184 | } | 1076 | } |
1185 | } else { /* normal character reception */ | 1077 | } else { |
1186 | /* load # chars available from the chip */ | 1078 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1187 | char_count = readb(base_addr + | 1079 | info->icount.rx++; |
1188 | (CyRDCR << index)); | 1080 | } |
1081 | } else { | ||
1082 | /* there was a software buffer overrun and nothing | ||
1083 | * could be done about it!!! */ | ||
1084 | info->icount.buf_overrun++; | ||
1085 | info->idle_stats.overruns++; | ||
1086 | } | ||
1087 | } else { /* normal character reception */ | ||
1088 | /* load # chars available from the chip */ | ||
1089 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1189 | 1090 | ||
1190 | #ifdef CY_ENABLE_MONITORING | 1091 | #ifdef CY_ENABLE_MONITORING |
1191 | ++info->mon.int_count; | 1092 | ++info->mon.int_count; |
1192 | info->mon.char_count += char_count; | 1093 | info->mon.char_count += char_count; |
1193 | if (char_count > info->mon.char_max) | 1094 | if (char_count > info->mon.char_max) |
1194 | info->mon.char_max = char_count; | 1095 | info->mon.char_max = char_count; |
1195 | info->mon.char_last = char_count; | 1096 | info->mon.char_last = char_count; |
1196 | #endif | 1097 | #endif |
1197 | len = tty_buffer_request_room(tty, char_count); | 1098 | len = tty_buffer_request_room(tty, char_count); |
1198 | while (len--) { | 1099 | while (len--) { |
1199 | data = readb(base_addr + | 1100 | data = readb(base_addr + (CyRDSR << index)); |
1200 | (CyRDSR << index)); | 1101 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1201 | tty_insert_flip_char(tty, data, | 1102 | info->idle_stats.recv_bytes++; |
1202 | TTY_NORMAL); | 1103 | info->icount.rx++; |
1203 | info->idle_stats.recv_bytes++; | ||
1204 | info->icount.rx++; | ||
1205 | #ifdef CY_16Y_HACK | 1104 | #ifdef CY_16Y_HACK |
1206 | udelay(10L); | 1105 | udelay(10L); |
1207 | #endif | 1106 | #endif |
1208 | } | ||
1209 | info->idle_stats.recv_idle = jiffies; | ||
1210 | } | ||
1211 | tty_schedule_flip(tty); | ||
1212 | } | 1107 | } |
1213 | /* end of service */ | 1108 | info->idle_stats.recv_idle = jiffies; |
1214 | cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f)); | ||
1215 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1216 | spin_unlock(&cinfo->card_lock); | ||
1217 | } | 1109 | } |
1110 | tty_schedule_flip(tty); | ||
1111 | end: | ||
1112 | /* end of service */ | ||
1113 | cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); | ||
1114 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1115 | } | ||
1116 | |||
1117 | static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | ||
1118 | void __iomem *base_addr) | ||
1119 | { | ||
1120 | struct cyclades_port *info; | ||
1121 | int char_count, index = cinfo->bus_index; | ||
1122 | u8 save_xir, channel, save_car, outch; | ||
1218 | 1123 | ||
1219 | if (status & CySRTransmit) { /* transmission interrupt */ | 1124 | /* Since we only get here when the transmit buffer |
1220 | /* Since we only get here when the transmit buffer | 1125 | is empty, we know we can always stuff a dozen |
1221 | is empty, we know we can always stuff a dozen | 1126 | characters. */ |
1222 | characters. */ | ||
1223 | #ifdef CY_DEBUG_INTERRUPTS | 1127 | #ifdef CY_DEBUG_INTERRUPTS |
1224 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); | 1128 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); |
1225 | #endif | 1129 | #endif |
1226 | 1130 | ||
1227 | /* determine the channel & change to that context */ | 1131 | /* determine the channel & change to that context */ |
1228 | spin_lock(&cinfo->card_lock); | 1132 | save_xir = readb(base_addr + (CyTIR << index)); |
1229 | save_xir = (u_char) readb(base_addr + (CyTIR << index)); | 1133 | channel = save_xir & CyIRChannel; |
1230 | channel = (u_short) (save_xir & CyIRChannel); | 1134 | save_car = readb(base_addr + (CyCAR << index)); |
1231 | save_car = readb(base_addr + (CyCAR << index)); | 1135 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1232 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1233 | 1136 | ||
1234 | /* validate the port# (as configured and open) */ | 1137 | /* validate the port# (as configured and open) */ |
1235 | if (channel + chip * 4 >= cinfo->nports) { | 1138 | if (channel + chip * 4 >= cinfo->nports) { |
1236 | cy_writeb(base_addr + (CySRER << index), | 1139 | cy_writeb(base_addr + (CySRER << index), |
1237 | readb(base_addr + (CySRER << index)) & | 1140 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1238 | ~CyTxRdy); | 1141 | goto end; |
1239 | goto txend; | 1142 | } |
1240 | } | 1143 | info = &cinfo->ports[channel + chip * 4]; |
1241 | info = &cinfo->ports[channel + chip * 4]; | 1144 | if (info->tty == NULL) { |
1242 | if (info->tty == NULL) { | 1145 | cy_writeb(base_addr + (CySRER << index), |
1243 | cy_writeb(base_addr + (CySRER << index), | 1146 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1244 | readb(base_addr + (CySRER << index)) & | 1147 | goto end; |
1245 | ~CyTxRdy); | 1148 | } |
1246 | goto txdone; | ||
1247 | } | ||
1248 | 1149 | ||
1249 | /* load the on-chip space for outbound data */ | 1150 | /* load the on-chip space for outbound data */ |
1250 | char_count = info->xmit_fifo_size; | 1151 | char_count = info->xmit_fifo_size; |
1251 | 1152 | ||
1252 | if (info->x_char) { /* send special char */ | 1153 | if (info->x_char) { /* send special char */ |
1253 | outch = info->x_char; | 1154 | outch = info->x_char; |
1254 | cy_writeb(base_addr + (CyTDR << index), outch); | 1155 | cy_writeb(base_addr + (CyTDR << index), outch); |
1255 | char_count--; | 1156 | char_count--; |
1256 | info->icount.tx++; | 1157 | info->icount.tx++; |
1257 | info->x_char = 0; | 1158 | info->x_char = 0; |
1258 | } | 1159 | } |
1259 | 1160 | ||
1260 | if (info->breakon || info->breakoff) { | 1161 | if (info->breakon || info->breakoff) { |
1261 | if (info->breakon) { | 1162 | if (info->breakon) { |
1262 | cy_writeb(base_addr + (CyTDR << index), 0); | 1163 | cy_writeb(base_addr + (CyTDR << index), 0); |
1263 | cy_writeb(base_addr + (CyTDR << index), 0x81); | 1164 | cy_writeb(base_addr + (CyTDR << index), 0x81); |
1264 | info->breakon = 0; | 1165 | info->breakon = 0; |
1265 | char_count -= 2; | 1166 | char_count -= 2; |
1266 | } | 1167 | } |
1267 | if (info->breakoff) { | 1168 | if (info->breakoff) { |
1268 | cy_writeb(base_addr + (CyTDR << index), 0); | 1169 | cy_writeb(base_addr + (CyTDR << index), 0); |
1269 | cy_writeb(base_addr + (CyTDR << index), 0x83); | 1170 | cy_writeb(base_addr + (CyTDR << index), 0x83); |
1270 | info->breakoff = 0; | 1171 | info->breakoff = 0; |
1271 | char_count -= 2; | 1172 | char_count -= 2; |
1272 | } | ||
1273 | } | 1173 | } |
1174 | } | ||
1274 | 1175 | ||
1275 | while (char_count-- > 0) { | 1176 | while (char_count-- > 0) { |
1276 | if (!info->xmit_cnt) { | 1177 | if (!info->xmit_cnt) { |
1277 | if (readb(base_addr + (CySRER << index)) & | 1178 | if (readb(base_addr + (CySRER << index)) & CyTxMpty) { |
1278 | CyTxMpty) { | 1179 | cy_writeb(base_addr + (CySRER << index), |
1279 | cy_writeb(base_addr + (CySRER << index), | 1180 | readb(base_addr + (CySRER << index)) & |
1280 | readb(base_addr + | ||
1281 | (CySRER << index)) & | ||
1282 | ~CyTxMpty); | 1181 | ~CyTxMpty); |
1283 | } else { | 1182 | } else { |
1284 | cy_writeb(base_addr + (CySRER << index), | 1183 | cy_writeb(base_addr + (CySRER << index), |
1285 | (readb(base_addr + | 1184 | (readb(base_addr + (CySRER << index)) & |
1286 | (CySRER << index)) & | ||
1287 | ~CyTxRdy) | CyTxMpty); | 1185 | ~CyTxRdy) | CyTxMpty); |
1288 | } | ||
1289 | goto txdone; | ||
1290 | } | 1186 | } |
1291 | if (info->xmit_buf == NULL) { | 1187 | goto done; |
1292 | cy_writeb(base_addr + (CySRER << index), | 1188 | } |
1293 | readb(base_addr + (CySRER << index)) & | 1189 | if (info->xmit_buf == NULL) { |
1190 | cy_writeb(base_addr + (CySRER << index), | ||
1191 | readb(base_addr + (CySRER << index)) & | ||
1294 | ~CyTxRdy); | 1192 | ~CyTxRdy); |
1295 | goto txdone; | 1193 | goto done; |
1296 | } | 1194 | } |
1297 | if (info->tty->stopped || info->tty->hw_stopped) { | 1195 | if (info->tty->stopped || info->tty->hw_stopped) { |
1298 | cy_writeb(base_addr + (CySRER << index), | 1196 | cy_writeb(base_addr + (CySRER << index), |
1299 | readb(base_addr + (CySRER << index)) & | 1197 | readb(base_addr + (CySRER << index)) & |
1300 | ~CyTxRdy); | 1198 | ~CyTxRdy); |
1301 | goto txdone; | 1199 | goto done; |
1302 | } | 1200 | } |
1303 | /* Because the Embedded Transmit Commands have | 1201 | /* Because the Embedded Transmit Commands have been enabled, |
1304 | been enabled, we must check to see if the | 1202 | * we must check to see if the escape character, NULL, is being |
1305 | escape character, NULL, is being sent. If it | 1203 | * sent. If it is, we must ensure that there is room for it to |
1306 | is, we must ensure that there is room for it | 1204 | * be doubled in the output stream. Therefore we no longer |
1307 | to be doubled in the output stream. Therefore | 1205 | * advance the pointer when the character is fetched, but |
1308 | we no longer advance the pointer when the | 1206 | * rather wait until after the check for a NULL output |
1309 | character is fetched, but rather wait until | 1207 | * character. This is necessary because there may not be room |
1310 | after the check for a NULL output character. | 1208 | * for the two chars needed to send a NULL.) |
1311 | This is necessary because there may not be | 1209 | */ |
1312 | room for the two chars needed to send a NULL.) | 1210 | outch = info->xmit_buf[info->xmit_tail]; |
1313 | */ | 1211 | if (outch) { |
1314 | outch = info->xmit_buf[info->xmit_tail]; | 1212 | info->xmit_cnt--; |
1315 | if (outch) { | 1213 | info->xmit_tail = (info->xmit_tail + 1) & |
1214 | (SERIAL_XMIT_SIZE - 1); | ||
1215 | cy_writeb(base_addr + (CyTDR << index), outch); | ||
1216 | info->icount.tx++; | ||
1217 | } else { | ||
1218 | if (char_count > 1) { | ||
1316 | info->xmit_cnt--; | 1219 | info->xmit_cnt--; |
1317 | info->xmit_tail = (info->xmit_tail + 1) & | 1220 | info->xmit_tail = (info->xmit_tail + 1) & |
1318 | (SERIAL_XMIT_SIZE - 1); | 1221 | (SERIAL_XMIT_SIZE - 1); |
1319 | cy_writeb(base_addr + (CyTDR << index), outch); | 1222 | cy_writeb(base_addr + (CyTDR << index), outch); |
1223 | cy_writeb(base_addr + (CyTDR << index), 0); | ||
1320 | info->icount.tx++; | 1224 | info->icount.tx++; |
1321 | } else { | 1225 | char_count--; |
1322 | if (char_count > 1) { | ||
1323 | info->xmit_cnt--; | ||
1324 | info->xmit_tail = (info->xmit_tail + 1)& | ||
1325 | (SERIAL_XMIT_SIZE - 1); | ||
1326 | cy_writeb(base_addr + (CyTDR << index), | ||
1327 | outch); | ||
1328 | cy_writeb(base_addr + (CyTDR << index), | ||
1329 | 0); | ||
1330 | info->icount.tx++; | ||
1331 | char_count--; | ||
1332 | } | ||
1333 | } | 1226 | } |
1334 | } | 1227 | } |
1335 | |||
1336 | txdone: | ||
1337 | if (info->xmit_cnt < WAKEUP_CHARS) { | ||
1338 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1339 | } | ||
1340 | txend: | ||
1341 | /* end of service */ | ||
1342 | cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f)); | ||
1343 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1344 | spin_unlock(&cinfo->card_lock); | ||
1345 | } | 1228 | } |
1346 | 1229 | ||
1347 | if (status & CySRModem) { /* modem interrupt */ | 1230 | done: |
1231 | tty_wakeup(info->tty); | ||
1232 | end: | ||
1233 | /* end of service */ | ||
1234 | cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); | ||
1235 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1236 | } | ||
1348 | 1237 | ||
1349 | /* determine the channel & change to that context */ | 1238 | static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, |
1350 | spin_lock(&cinfo->card_lock); | 1239 | void __iomem *base_addr) |
1351 | save_xir = (u_char) readb(base_addr + (CyMIR << index)); | 1240 | { |
1352 | channel = (u_short) (save_xir & CyIRChannel); | 1241 | struct cyclades_port *info; |
1353 | info = &cinfo->ports[channel + chip * 4]; | 1242 | int index = cinfo->bus_index; |
1354 | save_car = readb(base_addr + (CyCAR << index)); | 1243 | u8 save_xir, channel, save_car, mdm_change, mdm_status; |
1355 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1356 | 1244 | ||
1357 | mdm_change = readb(base_addr + (CyMISR << index)); | 1245 | /* determine the channel & change to that context */ |
1358 | mdm_status = readb(base_addr + (CyMSVR1 << index)); | 1246 | save_xir = readb(base_addr + (CyMIR << index)); |
1247 | channel = save_xir & CyIRChannel; | ||
1248 | info = &cinfo->ports[channel + chip * 4]; | ||
1249 | save_car = readb(base_addr + (CyCAR << index)); | ||
1250 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1359 | 1251 | ||
1360 | if (info->tty) { | 1252 | mdm_change = readb(base_addr + (CyMISR << index)); |
1361 | if (mdm_change & CyANY_DELTA) { | 1253 | mdm_status = readb(base_addr + (CyMSVR1 << index)); |
1362 | /* For statistics only */ | ||
1363 | if (mdm_change & CyDCD) | ||
1364 | info->icount.dcd++; | ||
1365 | if (mdm_change & CyCTS) | ||
1366 | info->icount.cts++; | ||
1367 | if (mdm_change & CyDSR) | ||
1368 | info->icount.dsr++; | ||
1369 | if (mdm_change & CyRI) | ||
1370 | info->icount.rng++; | ||
1371 | |||
1372 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1373 | } | ||
1374 | 1254 | ||
1375 | if ((mdm_change & CyDCD) && | 1255 | if (!info->tty) |
1376 | (info->flags & ASYNC_CHECK_CD)) { | 1256 | goto end; |
1377 | if (mdm_status & CyDCD) { | 1257 | |
1378 | cy_sched_event(info, | 1258 | if (mdm_change & CyANY_DELTA) { |
1379 | Cy_EVENT_OPEN_WAKEUP); | 1259 | /* For statistics only */ |
1380 | } else { | 1260 | if (mdm_change & CyDCD) |
1381 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1261 | info->icount.dcd++; |
1382 | } | 1262 | if (mdm_change & CyCTS) |
1383 | } | 1263 | info->icount.cts++; |
1384 | if ((mdm_change & CyCTS) && | 1264 | if (mdm_change & CyDSR) |
1385 | (info->flags & ASYNC_CTS_FLOW)) { | 1265 | info->icount.dsr++; |
1386 | if (info->tty->hw_stopped) { | 1266 | if (mdm_change & CyRI) |
1387 | if (mdm_status & CyCTS) { | 1267 | info->icount.rng++; |
1388 | /* cy_start isn't used | 1268 | |
1389 | because... !!! */ | 1269 | wake_up_interruptible(&info->delta_msr_wait); |
1390 | info->tty->hw_stopped = 0; | 1270 | } |
1391 | cy_writeb(base_addr + | 1271 | |
1392 | (CySRER << index), | 1272 | if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) { |
1393 | readb(base_addr + | 1273 | if (!(mdm_status & CyDCD)) { |
1394 | (CySRER << | 1274 | tty_hangup(info->tty); |
1395 | index))| | 1275 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
1396 | CyTxRdy); | 1276 | } |
1397 | cy_sched_event(info, | 1277 | wake_up_interruptible(&info->open_wait); |
1398 | Cy_EVENT_WRITE_WAKEUP); | 1278 | } |
1399 | } | 1279 | if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) { |
1400 | } else { | 1280 | if (info->tty->hw_stopped) { |
1401 | if (!(mdm_status & CyCTS)) { | 1281 | if (mdm_status & CyCTS) { |
1402 | /* cy_stop isn't used | 1282 | /* cy_start isn't used |
1403 | because ... !!! */ | 1283 | because... !!! */ |
1404 | info->tty->hw_stopped = 1; | 1284 | info->tty->hw_stopped = 0; |
1405 | cy_writeb(base_addr + | 1285 | cy_writeb(base_addr + (CySRER << index), |
1406 | (CySRER << index), | 1286 | readb(base_addr + (CySRER << index)) | |
1407 | readb(base_addr + | 1287 | CyTxRdy); |
1408 | (CySRER << | 1288 | tty_wakeup(info->tty); |
1409 | index)) & | ||
1410 | ~CyTxRdy); | ||
1411 | } | ||
1412 | } | ||
1413 | } | 1289 | } |
1414 | /* if (mdm_change & CyDSR) { | 1290 | } else { |
1291 | if (!(mdm_status & CyCTS)) { | ||
1292 | /* cy_stop isn't used | ||
1293 | because ... !!! */ | ||
1294 | info->tty->hw_stopped = 1; | ||
1295 | cy_writeb(base_addr + (CySRER << index), | ||
1296 | readb(base_addr + (CySRER << index)) & | ||
1297 | ~CyTxRdy); | ||
1415 | } | 1298 | } |
1416 | if (mdm_change & CyRI) { | ||
1417 | }*/ | ||
1418 | } | 1299 | } |
1419 | /* end of service */ | ||
1420 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | ||
1421 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1422 | spin_unlock(&cinfo->card_lock); | ||
1423 | } | 1300 | } |
1301 | /* if (mdm_change & CyDSR) { | ||
1302 | } | ||
1303 | if (mdm_change & CyRI) { | ||
1304 | }*/ | ||
1305 | end: | ||
1306 | /* end of service */ | ||
1307 | cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); | ||
1308 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1424 | } | 1309 | } |
1425 | 1310 | ||
1426 | /* The real interrupt service routine is called | 1311 | /* The real interrupt service routine is called |
@@ -1432,10 +1317,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1432 | int status; | 1317 | int status; |
1433 | struct cyclades_card *cinfo = dev_id; | 1318 | struct cyclades_card *cinfo = dev_id; |
1434 | void __iomem *base_addr, *card_base_addr; | 1319 | void __iomem *base_addr, *card_base_addr; |
1435 | int chip; | 1320 | unsigned int chip, too_many, had_work; |
1436 | int index; | 1321 | int index; |
1437 | int too_many; | ||
1438 | int had_work; | ||
1439 | 1322 | ||
1440 | if (unlikely(cinfo == NULL)) { | 1323 | if (unlikely(cinfo == NULL)) { |
1441 | #ifdef CY_DEBUG_INTERRUPTS | 1324 | #ifdef CY_DEBUG_INTERRUPTS |
@@ -1470,11 +1353,16 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1470 | chips to be checked in a round-robin fashion (after | 1353 | chips to be checked in a round-robin fashion (after |
1471 | draining each of a bunch (1000) of characters). | 1354 | draining each of a bunch (1000) of characters). |
1472 | */ | 1355 | */ |
1473 | if (1000 < too_many++) { | 1356 | if (1000 < too_many++) |
1474 | break; | 1357 | break; |
1475 | } | 1358 | spin_lock(&cinfo->card_lock); |
1476 | cyy_intr_chip(cinfo, chip, base_addr, status, | 1359 | if (status & CySRReceive) /* rx intr */ |
1477 | index); | 1360 | cyy_chip_rx(cinfo, chip, base_addr); |
1361 | if (status & CySRTransmit) /* tx intr */ | ||
1362 | cyy_chip_tx(cinfo, chip, base_addr); | ||
1363 | if (status & CySRModem) /* modem intr */ | ||
1364 | cyy_chip_modem(cinfo, chip, base_addr); | ||
1365 | spin_unlock(&cinfo->card_lock); | ||
1478 | } | 1366 | } |
1479 | } | 1367 | } |
1480 | } while (had_work); | 1368 | } while (had_work); |
@@ -1529,7 +1417,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1529 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1417 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1530 | struct BOARD_CTRL __iomem *board_ctrl; | 1418 | struct BOARD_CTRL __iomem *board_ctrl; |
1531 | __u32 __iomem *pci_doorbell; | 1419 | __u32 __iomem *pci_doorbell; |
1532 | int index; | 1420 | unsigned int index; |
1533 | 1421 | ||
1534 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1422 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1535 | if (!ISZLOADED(*cinfo)) { | 1423 | if (!ISZLOADED(*cinfo)) { |
@@ -1554,13 +1442,12 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1554 | return 0; | 1442 | return 0; |
1555 | } /* cyz_issue_cmd */ | 1443 | } /* cyz_issue_cmd */ |
1556 | 1444 | ||
1557 | static void | 1445 | static void cyz_handle_rx(struct cyclades_port *info, |
1558 | cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1559 | struct BUF_CTRL __iomem *buf_ctrl) | 1446 | struct BUF_CTRL __iomem *buf_ctrl) |
1560 | { | 1447 | { |
1561 | struct cyclades_card *cinfo = info->card; | 1448 | struct cyclades_card *cinfo = info->card; |
1562 | struct tty_struct *tty = info->tty; | 1449 | struct tty_struct *tty = info->tty; |
1563 | int char_count; | 1450 | unsigned int char_count; |
1564 | int len; | 1451 | int len; |
1565 | #ifdef BLOCKMOVE | 1452 | #ifdef BLOCKMOVE |
1566 | unsigned char *buf; | 1453 | unsigned char *buf; |
@@ -1633,9 +1520,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1633 | char_count = rx_put - rx_get; | 1520 | char_count = rx_put - rx_get; |
1634 | else | 1521 | else |
1635 | char_count = rx_put - rx_get + rx_bufsize; | 1522 | char_count = rx_put - rx_get + rx_bufsize; |
1636 | if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { | 1523 | if (char_count >= readl(&buf_ctrl->rx_threshold) && |
1637 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1524 | !timer_pending(&cyz_rx_full_timer[ |
1638 | } | 1525 | info->line])) |
1526 | mod_timer(&cyz_rx_full_timer[info->line], | ||
1527 | jiffies + 1); | ||
1639 | #endif | 1528 | #endif |
1640 | info->idle_stats.recv_idle = jiffies; | 1529 | info->idle_stats.recv_idle = jiffies; |
1641 | tty_schedule_flip(tty); | 1530 | tty_schedule_flip(tty); |
@@ -1645,14 +1534,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1645 | } | 1534 | } |
1646 | } | 1535 | } |
1647 | 1536 | ||
1648 | static void | 1537 | static void cyz_handle_tx(struct cyclades_port *info, |
1649 | cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1650 | struct BUF_CTRL __iomem *buf_ctrl) | 1538 | struct BUF_CTRL __iomem *buf_ctrl) |
1651 | { | 1539 | { |
1652 | struct cyclades_card *cinfo = info->card; | 1540 | struct cyclades_card *cinfo = info->card; |
1653 | struct tty_struct *tty = info->tty; | 1541 | struct tty_struct *tty = info->tty; |
1654 | char data; | 1542 | u8 data; |
1655 | int char_count; | 1543 | unsigned int char_count; |
1656 | #ifdef BLOCKMOVE | 1544 | #ifdef BLOCKMOVE |
1657 | int small_count; | 1545 | int small_count; |
1658 | #endif | 1546 | #endif |
@@ -1717,9 +1605,7 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1717 | } | 1605 | } |
1718 | #endif | 1606 | #endif |
1719 | ztxdone: | 1607 | ztxdone: |
1720 | if (info->xmit_cnt < WAKEUP_CHARS) { | 1608 | tty_wakeup(tty); |
1721 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1722 | } | ||
1723 | /* Update tx_put */ | 1609 | /* Update tx_put */ |
1724 | cy_writel(&buf_ctrl->tx_put, tx_put); | 1610 | cy_writel(&buf_ctrl->tx_put, tx_put); |
1725 | } | 1611 | } |
@@ -1781,10 +1667,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1781 | if ((fw_ver > 241 ? ((u_long) param) : | 1667 | if ((fw_ver > 241 ? ((u_long) param) : |
1782 | readl(&ch_ctrl->rs_status)) & | 1668 | readl(&ch_ctrl->rs_status)) & |
1783 | C_RS_DCD) { | 1669 | C_RS_DCD) { |
1784 | cy_sched_event(info, | 1670 | wake_up_interruptible(&info->open_wait); |
1785 | Cy_EVENT_OPEN_WAKEUP); | ||
1786 | } else { | 1671 | } else { |
1787 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1672 | tty_hangup(info->tty); |
1673 | wake_up_interruptible(&info->open_wait); | ||
1674 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1788 | } | 1675 | } |
1789 | } | 1676 | } |
1790 | break; | 1677 | break; |
@@ -1802,7 +1689,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1802 | break; | 1689 | break; |
1803 | #ifdef Z_WAKE | 1690 | #ifdef Z_WAKE |
1804 | case C_CM_IOCTLW: | 1691 | case C_CM_IOCTLW: |
1805 | cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); | 1692 | complete(&info->shutdown_wait); |
1806 | break; | 1693 | break; |
1807 | #endif | 1694 | #endif |
1808 | #ifdef CONFIG_CYZ_INTR | 1695 | #ifdef CONFIG_CYZ_INTR |
@@ -1814,7 +1701,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1814 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " | 1701 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1815 | "port %ld\n", info->card, channel); | 1702 | "port %ld\n", info->card, channel); |
1816 | #endif | 1703 | #endif |
1817 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1704 | cyz_handle_rx(info, buf_ctrl); |
1818 | break; | 1705 | break; |
1819 | case C_CM_TXBEMPTY: | 1706 | case C_CM_TXBEMPTY: |
1820 | case C_CM_TXLOWWM: | 1707 | case C_CM_TXLOWWM: |
@@ -1824,7 +1711,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1824 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " | 1711 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1825 | "port %ld\n", info->card, channel); | 1712 | "port %ld\n", info->card, channel); |
1826 | #endif | 1713 | #endif |
1827 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1714 | cyz_handle_tx(info, buf_ctrl); |
1828 | break; | 1715 | break; |
1829 | #endif /* CONFIG_CYZ_INTR */ | 1716 | #endif /* CONFIG_CYZ_INTR */ |
1830 | case C_CM_FATAL: | 1717 | case C_CM_FATAL: |
@@ -1834,7 +1721,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1834 | break; | 1721 | break; |
1835 | } | 1722 | } |
1836 | if (delta_count) | 1723 | if (delta_count) |
1837 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1724 | wake_up_interruptible(&info->delta_msr_wait); |
1838 | if (special_count) | 1725 | if (special_count) |
1839 | tty_schedule_flip(tty); | 1726 | tty_schedule_flip(tty); |
1840 | } | 1727 | } |
@@ -1893,10 +1780,9 @@ static void cyz_poll(unsigned long arg) | |||
1893 | struct FIRM_ID __iomem *firm_id; | 1780 | struct FIRM_ID __iomem *firm_id; |
1894 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1781 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1895 | struct BOARD_CTRL __iomem *board_ctrl; | 1782 | struct BOARD_CTRL __iomem *board_ctrl; |
1896 | struct CH_CTRL __iomem *ch_ctrl; | ||
1897 | struct BUF_CTRL __iomem *buf_ctrl; | 1783 | struct BUF_CTRL __iomem *buf_ctrl; |
1898 | unsigned long expires = jiffies + HZ; | 1784 | unsigned long expires = jiffies + HZ; |
1899 | int card, port; | 1785 | unsigned int port, card; |
1900 | 1786 | ||
1901 | for (card = 0; card < NR_CARDS; card++) { | 1787 | for (card = 0; card < NR_CARDS; card++) { |
1902 | cinfo = &cy_card[card]; | 1788 | cinfo = &cy_card[card]; |
@@ -1923,12 +1809,11 @@ static void cyz_poll(unsigned long arg) | |||
1923 | for (port = 0; port < cinfo->nports; port++) { | 1809 | for (port = 0; port < cinfo->nports; port++) { |
1924 | info = &cinfo->ports[port]; | 1810 | info = &cinfo->ports[port]; |
1925 | tty = info->tty; | 1811 | tty = info->tty; |
1926 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | ||
1927 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1812 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
1928 | 1813 | ||
1929 | if (!info->throttle) | 1814 | if (!info->throttle) |
1930 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1815 | cyz_handle_rx(info, buf_ctrl); |
1931 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1816 | cyz_handle_tx(info, buf_ctrl); |
1932 | } | 1817 | } |
1933 | /* poll every 'cyz_polling_cycle' period */ | 1818 | /* poll every 'cyz_polling_cycle' period */ |
1934 | expires = jiffies + cyz_polling_cycle; | 1819 | expires = jiffies + cyz_polling_cycle; |
@@ -2491,11 +2376,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2491 | static int cy_open(struct tty_struct *tty, struct file *filp) | 2376 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2492 | { | 2377 | { |
2493 | struct cyclades_port *info; | 2378 | struct cyclades_port *info; |
2494 | unsigned int i; | 2379 | unsigned int i, line; |
2495 | int retval, line; | 2380 | int retval; |
2496 | 2381 | ||
2497 | line = tty->index; | 2382 | line = tty->index; |
2498 | if ((line < 0) || (NR_PORTS <= line)) { | 2383 | if ((tty->index < 0) || (NR_PORTS <= line)) { |
2499 | return -ENODEV; | 2384 | return -ENODEV; |
2500 | } | 2385 | } |
2501 | for (i = 0; i < NR_CARDS; i++) | 2386 | for (i = 0; i < NR_CARDS; i++) |
@@ -2812,7 +2697,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2812 | spin_lock_irqsave(&card->card_lock, flags); | 2697 | spin_lock_irqsave(&card->card_lock, flags); |
2813 | 2698 | ||
2814 | tty->closing = 0; | 2699 | tty->closing = 0; |
2815 | info->event = 0; | ||
2816 | info->tty = NULL; | 2700 | info->tty = NULL; |
2817 | if (info->blocked_open) { | 2701 | if (info->blocked_open) { |
2818 | spin_unlock_irqrestore(&card->card_lock, flags); | 2702 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -4444,7 +4328,6 @@ static void cy_hangup(struct tty_struct *tty) | |||
4444 | 4328 | ||
4445 | cy_flush_buffer(tty); | 4329 | cy_flush_buffer(tty); |
4446 | shutdown(info); | 4330 | shutdown(info); |
4447 | info->event = 0; | ||
4448 | info->count = 0; | 4331 | info->count = 0; |
4449 | #ifdef CY_DEBUG_COUNT | 4332 | #ifdef CY_DEBUG_COUNT |
4450 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", | 4333 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", |
@@ -4467,9 +4350,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4467 | { | 4350 | { |
4468 | struct cyclades_port *info; | 4351 | struct cyclades_port *info; |
4469 | u32 uninitialized_var(mailbox); | 4352 | u32 uninitialized_var(mailbox); |
4470 | unsigned int nports; | 4353 | unsigned int nports, port; |
4471 | unsigned short chip_number; | 4354 | unsigned short chip_number; |
4472 | int uninitialized_var(index), port; | 4355 | int uninitialized_var(index); |
4473 | 4356 | ||
4474 | spin_lock_init(&cinfo->card_lock); | 4357 | spin_lock_init(&cinfo->card_lock); |
4475 | 4358 | ||
@@ -4502,7 +4385,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4502 | info->closing_wait = CLOSING_WAIT_DELAY; | 4385 | info->closing_wait = CLOSING_WAIT_DELAY; |
4503 | info->close_delay = 5 * HZ / 10; | 4386 | info->close_delay = 5 * HZ / 10; |
4504 | 4387 | ||
4505 | INIT_WORK(&info->tqueue, do_softint); | ||
4506 | init_waitqueue_head(&info->open_wait); | 4388 | init_waitqueue_head(&info->open_wait); |
4507 | init_waitqueue_head(&info->close_wait); | 4389 | init_waitqueue_head(&info->close_wait); |
4508 | init_completion(&info->shutdown_wait); | 4390 | init_completion(&info->shutdown_wait); |
@@ -5236,7 +5118,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5236 | } | 5118 | } |
5237 | } | 5119 | } |
5238 | #endif /* CONFIG_CYZ_INTR */ | 5120 | #endif /* CONFIG_CYZ_INTR */ |
5239 | cy_card[card_no].num_chips = -1; | 5121 | cy_card[card_no].num_chips = (unsigned int)-1; |
5240 | } | 5122 | } |
5241 | 5123 | ||
5242 | /* set cy_card */ | 5124 | /* set cy_card */ |
@@ -5480,13 +5362,13 @@ static int __init cy_init(void) | |||
5480 | #ifdef CONFIG_PCI | 5362 | #ifdef CONFIG_PCI |
5481 | /* look for pci boards */ | 5363 | /* look for pci boards */ |
5482 | retval = pci_register_driver(&cy_pci_driver); | 5364 | retval = pci_register_driver(&cy_pci_driver); |
5483 | if (retval && !nboards) | 5365 | if (retval && !nboards) { |
5484 | goto err_unr; | 5366 | tty_unregister_driver(cy_serial_driver); |
5367 | goto err_frtty; | ||
5368 | } | ||
5485 | #endif | 5369 | #endif |
5486 | 5370 | ||
5487 | return 0; | 5371 | return 0; |
5488 | err_unr: | ||
5489 | tty_unregister_driver(cy_serial_driver); | ||
5490 | err_frtty: | 5372 | err_frtty: |
5491 | put_tty_driver(cy_serial_driver); | 5373 | put_tty_driver(cy_serial_driver); |
5492 | err: | 5374 | err: |
@@ -5496,7 +5378,7 @@ err: | |||
5496 | static void __exit cy_cleanup_module(void) | 5378 | static void __exit cy_cleanup_module(void) |
5497 | { | 5379 | { |
5498 | struct cyclades_card *card; | 5380 | struct cyclades_card *card; |
5499 | int i, e1; | 5381 | unsigned int i, e1; |
5500 | 5382 | ||
5501 | #ifndef CONFIG_CYZ_INTR | 5383 | #ifndef CONFIG_CYZ_INTR |
5502 | del_timer_sync(&cyz_timerlist); | 5384 | del_timer_sync(&cyz_timerlist); |
@@ -5524,8 +5406,7 @@ static void __exit cy_cleanup_module(void) | |||
5524 | #endif /* CONFIG_CYZ_INTR */ | 5406 | #endif /* CONFIG_CYZ_INTR */ |
5525 | ) | 5407 | ) |
5526 | free_irq(card->irq, card); | 5408 | free_irq(card->irq, card); |
5527 | for (e1 = card->first_line; | 5409 | for (e1 = card->first_line; e1 < card->first_line + |
5528 | e1 < card->first_line + | ||
5529 | card->nports; e1++) | 5410 | card->nports; e1++) |
5530 | tty_unregister_device(cy_serial_driver, e1); | 5411 | tty_unregister_device(cy_serial_driver, e1); |
5531 | kfree(card->ports); | 5412 | kfree(card->ports); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8435fba73daf..5dc1265ce1d5 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -221,10 +221,8 @@ struct ipmi_smi | |||
221 | void *send_info; | 221 | void *send_info; |
222 | 222 | ||
223 | #ifdef CONFIG_PROC_FS | 223 | #ifdef CONFIG_PROC_FS |
224 | /* A list of proc entries for this interface. This does not | 224 | /* A list of proc entries for this interface. */ |
225 | need a lock, only one thread creates it and only one thread | 225 | struct mutex proc_entry_lock; |
226 | destroys it. */ | ||
227 | spinlock_t proc_entry_lock; | ||
228 | struct ipmi_proc_entry *proc_entries; | 226 | struct ipmi_proc_entry *proc_entries; |
229 | #endif | 227 | #endif |
230 | 228 | ||
@@ -1891,11 +1889,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | |||
1891 | file->write_proc = write_proc; | 1889 | file->write_proc = write_proc; |
1892 | file->owner = owner; | 1890 | file->owner = owner; |
1893 | 1891 | ||
1894 | spin_lock(&smi->proc_entry_lock); | 1892 | mutex_lock(&smi->proc_entry_lock); |
1895 | /* Stick it on the list. */ | 1893 | /* Stick it on the list. */ |
1896 | entry->next = smi->proc_entries; | 1894 | entry->next = smi->proc_entries; |
1897 | smi->proc_entries = entry; | 1895 | smi->proc_entries = entry; |
1898 | spin_unlock(&smi->proc_entry_lock); | 1896 | mutex_unlock(&smi->proc_entry_lock); |
1899 | } | 1897 | } |
1900 | #endif /* CONFIG_PROC_FS */ | 1898 | #endif /* CONFIG_PROC_FS */ |
1901 | 1899 | ||
@@ -1939,7 +1937,7 @@ static void remove_proc_entries(ipmi_smi_t smi) | |||
1939 | #ifdef CONFIG_PROC_FS | 1937 | #ifdef CONFIG_PROC_FS |
1940 | struct ipmi_proc_entry *entry; | 1938 | struct ipmi_proc_entry *entry; |
1941 | 1939 | ||
1942 | spin_lock(&smi->proc_entry_lock); | 1940 | mutex_lock(&smi->proc_entry_lock); |
1943 | while (smi->proc_entries) { | 1941 | while (smi->proc_entries) { |
1944 | entry = smi->proc_entries; | 1942 | entry = smi->proc_entries; |
1945 | smi->proc_entries = entry->next; | 1943 | smi->proc_entries = entry->next; |
@@ -1948,7 +1946,7 @@ static void remove_proc_entries(ipmi_smi_t smi) | |||
1948 | kfree(entry->name); | 1946 | kfree(entry->name); |
1949 | kfree(entry); | 1947 | kfree(entry); |
1950 | } | 1948 | } |
1951 | spin_unlock(&smi->proc_entry_lock); | 1949 | mutex_unlock(&smi->proc_entry_lock); |
1952 | remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); | 1950 | remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); |
1953 | #endif /* CONFIG_PROC_FS */ | 1951 | #endif /* CONFIG_PROC_FS */ |
1954 | } | 1952 | } |
@@ -2614,6 +2612,14 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
2614 | return; | 2612 | return; |
2615 | } | 2613 | } |
2616 | 2614 | ||
2615 | void ipmi_poll_interface(ipmi_user_t user) | ||
2616 | { | ||
2617 | ipmi_smi_t intf = user->intf; | ||
2618 | |||
2619 | if (intf->handlers->poll) | ||
2620 | intf->handlers->poll(intf->send_info); | ||
2621 | } | ||
2622 | |||
2617 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | 2623 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, |
2618 | void *send_info, | 2624 | void *send_info, |
2619 | struct ipmi_device_id *device_id, | 2625 | struct ipmi_device_id *device_id, |
@@ -2671,7 +2677,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2671 | } | 2677 | } |
2672 | intf->curr_seq = 0; | 2678 | intf->curr_seq = 0; |
2673 | #ifdef CONFIG_PROC_FS | 2679 | #ifdef CONFIG_PROC_FS |
2674 | spin_lock_init(&intf->proc_entry_lock); | 2680 | mutex_init(&intf->proc_entry_lock); |
2675 | #endif | 2681 | #endif |
2676 | spin_lock_init(&intf->waiting_msgs_lock); | 2682 | spin_lock_init(&intf->waiting_msgs_lock); |
2677 | INIT_LIST_HEAD(&intf->waiting_msgs); | 2683 | INIT_LIST_HEAD(&intf->waiting_msgs); |
@@ -4166,6 +4172,7 @@ EXPORT_SYMBOL(ipmi_destroy_user); | |||
4166 | EXPORT_SYMBOL(ipmi_get_version); | 4172 | EXPORT_SYMBOL(ipmi_get_version); |
4167 | EXPORT_SYMBOL(ipmi_request_settime); | 4173 | EXPORT_SYMBOL(ipmi_request_settime); |
4168 | EXPORT_SYMBOL(ipmi_request_supply_msgs); | 4174 | EXPORT_SYMBOL(ipmi_request_supply_msgs); |
4175 | EXPORT_SYMBOL(ipmi_poll_interface); | ||
4169 | EXPORT_SYMBOL(ipmi_register_smi); | 4176 | EXPORT_SYMBOL(ipmi_register_smi); |
4170 | EXPORT_SYMBOL(ipmi_unregister_smi); | 4177 | EXPORT_SYMBOL(ipmi_unregister_smi); |
4171 | EXPORT_SYMBOL(ipmi_register_for_cmd); | 4178 | EXPORT_SYMBOL(ipmi_register_for_cmd); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index c1222e98525d..4f560d0bb808 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -675,7 +675,8 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | /* Called on timeouts and events. Timeouts should pass the elapsed | 677 | /* Called on timeouts and events. Timeouts should pass the elapsed |
678 | time, interrupts should pass in zero. */ | 678 | time, interrupts should pass in zero. Must be called with |
679 | si_lock held and interrupts disabled. */ | ||
679 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | 680 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, |
680 | int time) | 681 | int time) |
681 | { | 682 | { |
@@ -892,13 +893,16 @@ static int ipmi_thread(void *data) | |||
892 | static void poll(void *send_info) | 893 | static void poll(void *send_info) |
893 | { | 894 | { |
894 | struct smi_info *smi_info = send_info; | 895 | struct smi_info *smi_info = send_info; |
896 | unsigned long flags; | ||
895 | 897 | ||
896 | /* | 898 | /* |
897 | * Make sure there is some delay in the poll loop so we can | 899 | * Make sure there is some delay in the poll loop so we can |
898 | * drive time forward and timeout things. | 900 | * drive time forward and timeout things. |
899 | */ | 901 | */ |
900 | udelay(10); | 902 | udelay(10); |
903 | spin_lock_irqsave(&smi_info->si_lock, flags); | ||
901 | smi_event_handler(smi_info, 10); | 904 | smi_event_handler(smi_info, 10); |
905 | spin_unlock_irqrestore(&smi_info->si_lock, flags); | ||
902 | } | 906 | } |
903 | 907 | ||
904 | static void request_events(void *send_info) | 908 | static void request_events(void *send_info) |
@@ -1006,6 +1010,10 @@ static int smi_start_processing(void *send_info, | |||
1006 | 1010 | ||
1007 | new_smi->intf = intf; | 1011 | new_smi->intf = intf; |
1008 | 1012 | ||
1013 | /* Try to claim any interrupts. */ | ||
1014 | if (new_smi->irq_setup) | ||
1015 | new_smi->irq_setup(new_smi); | ||
1016 | |||
1009 | /* Set up the timer that drives the interface. */ | 1017 | /* Set up the timer that drives the interface. */ |
1010 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); | 1018 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); |
1011 | new_smi->last_timeout_jiffies = jiffies; | 1019 | new_smi->last_timeout_jiffies = jiffies; |
@@ -2372,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2372 | /* Otherwise, we got some data. */ | 2380 | /* Otherwise, we got some data. */ |
2373 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | 2381 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, |
2374 | resp, IPMI_MAX_MSG_LENGTH); | 2382 | resp, IPMI_MAX_MSG_LENGTH); |
2375 | if (resp_len < 14) { | ||
2376 | /* That's odd, it should be longer. */ | ||
2377 | rv = -EINVAL; | ||
2378 | goto out; | ||
2379 | } | ||
2380 | 2383 | ||
2381 | if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) { | 2384 | /* Check and record info from the get device id, in case we need it. */ |
2382 | /* That's odd, it shouldn't be able to fail. */ | 2385 | rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id); |
2383 | rv = -EINVAL; | ||
2384 | goto out; | ||
2385 | } | ||
2386 | |||
2387 | /* Record info from the get device id, in case we need it. */ | ||
2388 | ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id); | ||
2389 | 2386 | ||
2390 | out: | 2387 | out: |
2391 | kfree(resp); | 2388 | kfree(resp); |
@@ -2765,10 +2762,6 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2765 | setup_oem_data_handler(new_smi); | 2762 | setup_oem_data_handler(new_smi); |
2766 | setup_xaction_handlers(new_smi); | 2763 | setup_xaction_handlers(new_smi); |
2767 | 2764 | ||
2768 | /* Try to claim any interrupts. */ | ||
2769 | if (new_smi->irq_setup) | ||
2770 | new_smi->irq_setup(new_smi); | ||
2771 | |||
2772 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); | 2765 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); |
2773 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); | 2766 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); |
2774 | new_smi->curr_msg = NULL; | 2767 | new_smi->curr_msg = NULL; |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 41f78e2c158f..e686fc925168 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -50,10 +50,19 @@ | |||
50 | #include <linux/poll.h> | 50 | #include <linux/poll.h> |
51 | #include <linux/string.h> | 51 | #include <linux/string.h> |
52 | #include <linux/ctype.h> | 52 | #include <linux/ctype.h> |
53 | #include <linux/delay.h> | ||
53 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
54 | 55 | ||
55 | #ifdef CONFIG_X86_LOCAL_APIC | 56 | #ifdef CONFIG_X86 |
56 | #include <asm/apic.h> | 57 | /* This is ugly, but I've determined that x86 is the only architecture |
58 | that can reasonably support the IPMI NMI watchdog timeout at this | ||
59 | time. If another architecture adds this capability somehow, it | ||
60 | will have to be a somewhat different mechanism and I have no idea | ||
61 | how it will work. So in the unlikely event that another | ||
62 | architecture supports this, we can figure out a good generic | ||
63 | mechanism for it at that time. */ | ||
64 | #include <asm/kdebug.h> | ||
65 | #define HAVE_DIE_NMI | ||
57 | #endif | 66 | #endif |
58 | 67 | ||
59 | #define PFX "IPMI Watchdog: " | 68 | #define PFX "IPMI Watchdog: " |
@@ -166,8 +175,6 @@ static char expect_close; | |||
166 | 175 | ||
167 | static int ifnum_to_use = -1; | 176 | static int ifnum_to_use = -1; |
168 | 177 | ||
169 | static DECLARE_RWSEM(register_sem); | ||
170 | |||
171 | /* Parameters to ipmi_set_timeout */ | 178 | /* Parameters to ipmi_set_timeout */ |
172 | #define IPMI_SET_TIMEOUT_NO_HB 0 | 179 | #define IPMI_SET_TIMEOUT_NO_HB 0 |
173 | #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1 | 180 | #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1 |
@@ -193,11 +200,9 @@ static int set_param_int(const char *val, struct kernel_param *kp) | |||
193 | if (endp == val) | 200 | if (endp == val) |
194 | return -EINVAL; | 201 | return -EINVAL; |
195 | 202 | ||
196 | down_read(®ister_sem); | ||
197 | *((int *)kp->arg) = l; | 203 | *((int *)kp->arg) = l; |
198 | if (watchdog_user) | 204 | if (watchdog_user) |
199 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 205 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
200 | up_read(®ister_sem); | ||
201 | 206 | ||
202 | return rv; | 207 | return rv; |
203 | } | 208 | } |
@@ -226,17 +231,15 @@ static int set_param_str(const char *val, struct kernel_param *kp) | |||
226 | 231 | ||
227 | s = strstrip(valcp); | 232 | s = strstrip(valcp); |
228 | 233 | ||
229 | down_read(®ister_sem); | ||
230 | rv = fn(s, NULL); | 234 | rv = fn(s, NULL); |
231 | if (rv) | 235 | if (rv) |
232 | goto out_unlock; | 236 | goto out; |
233 | 237 | ||
234 | check_parms(); | 238 | check_parms(); |
235 | if (watchdog_user) | 239 | if (watchdog_user) |
236 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 240 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
237 | 241 | ||
238 | out_unlock: | 242 | out: |
239 | up_read(®ister_sem); | ||
240 | return rv; | 243 | return rv; |
241 | } | 244 | } |
242 | 245 | ||
@@ -319,9 +322,12 @@ static unsigned char ipmi_version_minor; | |||
319 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ | 322 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ |
320 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); | 323 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); |
321 | 324 | ||
322 | static int ipmi_heartbeat(void); | 325 | #ifdef HAVE_DIE_NMI |
323 | static void panic_halt_ipmi_heartbeat(void); | 326 | static int testing_nmi; |
327 | static int nmi_handler_registered; | ||
328 | #endif | ||
324 | 329 | ||
330 | static int ipmi_heartbeat(void); | ||
325 | 331 | ||
326 | /* We use a mutex to make sure that only one thing can send a set | 332 | /* We use a mutex to make sure that only one thing can send a set |
327 | timeout at one time, because we only have one copy of the data. | 333 | timeout at one time, because we only have one copy of the data. |
@@ -360,6 +366,9 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
360 | int hbnow = 0; | 366 | int hbnow = 0; |
361 | 367 | ||
362 | 368 | ||
369 | /* These can be cleared as we are setting the timeout. */ | ||
370 | pretimeout_since_last_heartbeat = 0; | ||
371 | |||
363 | data[0] = 0; | 372 | data[0] = 0; |
364 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 373 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
365 | 374 | ||
@@ -434,31 +443,75 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
434 | 443 | ||
435 | wait_for_completion(&set_timeout_wait); | 444 | wait_for_completion(&set_timeout_wait); |
436 | 445 | ||
446 | mutex_unlock(&set_timeout_lock); | ||
447 | |||
437 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | 448 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) |
438 | || ((send_heartbeat_now) | 449 | || ((send_heartbeat_now) |
439 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | 450 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) |
440 | { | ||
441 | rv = ipmi_heartbeat(); | 451 | rv = ipmi_heartbeat(); |
442 | } | ||
443 | mutex_unlock(&set_timeout_lock); | ||
444 | 452 | ||
445 | out: | 453 | out: |
446 | return rv; | 454 | return rv; |
447 | } | 455 | } |
448 | 456 | ||
449 | static void dummy_smi_free(struct ipmi_smi_msg *msg) | 457 | static atomic_t panic_done_count = ATOMIC_INIT(0); |
458 | |||
459 | static void panic_smi_free(struct ipmi_smi_msg *msg) | ||
450 | { | 460 | { |
461 | atomic_dec(&panic_done_count); | ||
451 | } | 462 | } |
452 | static void dummy_recv_free(struct ipmi_recv_msg *msg) | 463 | static void panic_recv_free(struct ipmi_recv_msg *msg) |
453 | { | 464 | { |
465 | atomic_dec(&panic_done_count); | ||
466 | } | ||
467 | |||
468 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | ||
469 | { | ||
470 | .done = panic_smi_free | ||
471 | }; | ||
472 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | ||
473 | { | ||
474 | .done = panic_recv_free | ||
475 | }; | ||
476 | |||
477 | static void panic_halt_ipmi_heartbeat(void) | ||
478 | { | ||
479 | struct kernel_ipmi_msg msg; | ||
480 | struct ipmi_system_interface_addr addr; | ||
481 | int rv; | ||
482 | |||
483 | /* Don't reset the timer if we have the timer turned off, that | ||
484 | re-enables the watchdog. */ | ||
485 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | ||
486 | return; | ||
487 | |||
488 | addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
489 | addr.channel = IPMI_BMC_CHANNEL; | ||
490 | addr.lun = 0; | ||
491 | |||
492 | msg.netfn = 0x06; | ||
493 | msg.cmd = IPMI_WDOG_RESET_TIMER; | ||
494 | msg.data = NULL; | ||
495 | msg.data_len = 0; | ||
496 | rv = ipmi_request_supply_msgs(watchdog_user, | ||
497 | (struct ipmi_addr *) &addr, | ||
498 | 0, | ||
499 | &msg, | ||
500 | NULL, | ||
501 | &panic_halt_heartbeat_smi_msg, | ||
502 | &panic_halt_heartbeat_recv_msg, | ||
503 | 1); | ||
504 | if (!rv) | ||
505 | atomic_add(2, &panic_done_count); | ||
454 | } | 506 | } |
507 | |||
455 | static struct ipmi_smi_msg panic_halt_smi_msg = | 508 | static struct ipmi_smi_msg panic_halt_smi_msg = |
456 | { | 509 | { |
457 | .done = dummy_smi_free | 510 | .done = panic_smi_free |
458 | }; | 511 | }; |
459 | static struct ipmi_recv_msg panic_halt_recv_msg = | 512 | static struct ipmi_recv_msg panic_halt_recv_msg = |
460 | { | 513 | { |
461 | .done = dummy_recv_free | 514 | .done = panic_recv_free |
462 | }; | 515 | }; |
463 | 516 | ||
464 | /* Special call, doesn't claim any locks. This is only to be called | 517 | /* Special call, doesn't claim any locks. This is only to be called |
@@ -470,13 +523,21 @@ static void panic_halt_ipmi_set_timeout(void) | |||
470 | int send_heartbeat_now; | 523 | int send_heartbeat_now; |
471 | int rv; | 524 | int rv; |
472 | 525 | ||
526 | /* Wait for the messages to be free. */ | ||
527 | while (atomic_read(&panic_done_count) != 0) | ||
528 | ipmi_poll_interface(watchdog_user); | ||
473 | rv = i_ipmi_set_timeout(&panic_halt_smi_msg, | 529 | rv = i_ipmi_set_timeout(&panic_halt_smi_msg, |
474 | &panic_halt_recv_msg, | 530 | &panic_halt_recv_msg, |
475 | &send_heartbeat_now); | 531 | &send_heartbeat_now); |
476 | if (!rv) { | 532 | if (!rv) { |
533 | atomic_add(2, &panic_done_count); | ||
477 | if (send_heartbeat_now) | 534 | if (send_heartbeat_now) |
478 | panic_halt_ipmi_heartbeat(); | 535 | panic_halt_ipmi_heartbeat(); |
479 | } | 536 | } else |
537 | printk(KERN_WARNING PFX | ||
538 | "Unable to extend the watchdog timeout."); | ||
539 | while (atomic_read(&panic_done_count) != 0) | ||
540 | ipmi_poll_interface(watchdog_user); | ||
480 | } | 541 | } |
481 | 542 | ||
482 | /* We use a semaphore to make sure that only one thing can send a | 543 | /* We use a semaphore to make sure that only one thing can send a |
@@ -505,24 +566,14 @@ static struct ipmi_recv_msg heartbeat_recv_msg = | |||
505 | .done = heartbeat_free_recv | 566 | .done = heartbeat_free_recv |
506 | }; | 567 | }; |
507 | 568 | ||
508 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | ||
509 | { | ||
510 | .done = dummy_smi_free | ||
511 | }; | ||
512 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | ||
513 | { | ||
514 | .done = dummy_recv_free | ||
515 | }; | ||
516 | |||
517 | static int ipmi_heartbeat(void) | 569 | static int ipmi_heartbeat(void) |
518 | { | 570 | { |
519 | struct kernel_ipmi_msg msg; | 571 | struct kernel_ipmi_msg msg; |
520 | int rv; | 572 | int rv; |
521 | struct ipmi_system_interface_addr addr; | 573 | struct ipmi_system_interface_addr addr; |
522 | 574 | ||
523 | if (ipmi_ignore_heartbeat) { | 575 | if (ipmi_ignore_heartbeat) |
524 | return 0; | 576 | return 0; |
525 | } | ||
526 | 577 | ||
527 | if (ipmi_start_timer_on_heartbeat) { | 578 | if (ipmi_start_timer_on_heartbeat) { |
528 | ipmi_start_timer_on_heartbeat = 0; | 579 | ipmi_start_timer_on_heartbeat = 0; |
@@ -533,7 +584,6 @@ static int ipmi_heartbeat(void) | |||
533 | We don't want to set the action, though, we want to | 584 | We don't want to set the action, though, we want to |
534 | leave that alone (thus it can't be combined with the | 585 | leave that alone (thus it can't be combined with the |
535 | above operation. */ | 586 | above operation. */ |
536 | pretimeout_since_last_heartbeat = 0; | ||
537 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 587 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
538 | } | 588 | } |
539 | 589 | ||
@@ -586,35 +636,6 @@ static int ipmi_heartbeat(void) | |||
586 | return rv; | 636 | return rv; |
587 | } | 637 | } |
588 | 638 | ||
589 | static void panic_halt_ipmi_heartbeat(void) | ||
590 | { | ||
591 | struct kernel_ipmi_msg msg; | ||
592 | struct ipmi_system_interface_addr addr; | ||
593 | |||
594 | |||
595 | /* Don't reset the timer if we have the timer turned off, that | ||
596 | re-enables the watchdog. */ | ||
597 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | ||
598 | return; | ||
599 | |||
600 | addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
601 | addr.channel = IPMI_BMC_CHANNEL; | ||
602 | addr.lun = 0; | ||
603 | |||
604 | msg.netfn = 0x06; | ||
605 | msg.cmd = IPMI_WDOG_RESET_TIMER; | ||
606 | msg.data = NULL; | ||
607 | msg.data_len = 0; | ||
608 | ipmi_request_supply_msgs(watchdog_user, | ||
609 | (struct ipmi_addr *) &addr, | ||
610 | 0, | ||
611 | &msg, | ||
612 | NULL, | ||
613 | &panic_halt_heartbeat_smi_msg, | ||
614 | &panic_halt_heartbeat_recv_msg, | ||
615 | 1); | ||
616 | } | ||
617 | |||
618 | static struct watchdog_info ident = | 639 | static struct watchdog_info ident = |
619 | { | 640 | { |
620 | .options = 0, /* WDIOF_SETTIMEOUT, */ | 641 | .options = 0, /* WDIOF_SETTIMEOUT, */ |
@@ -895,7 +916,6 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
895 | { | 916 | { |
896 | int rv = -EBUSY; | 917 | int rv = -EBUSY; |
897 | 918 | ||
898 | down_write(®ister_sem); | ||
899 | if (watchdog_user) | 919 | if (watchdog_user) |
900 | goto out; | 920 | goto out; |
901 | 921 | ||
@@ -921,15 +941,56 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
921 | printk(KERN_CRIT PFX "Unable to register misc device\n"); | 941 | printk(KERN_CRIT PFX "Unable to register misc device\n"); |
922 | } | 942 | } |
923 | 943 | ||
924 | out: | 944 | #ifdef HAVE_DIE_NMI |
925 | up_write(®ister_sem); | 945 | if (nmi_handler_registered) { |
946 | int old_pretimeout = pretimeout; | ||
947 | int old_timeout = timeout; | ||
948 | int old_preop_val = preop_val; | ||
949 | |||
950 | /* Set the pretimeout to go off in a second and give | ||
951 | ourselves plenty of time to stop the timer. */ | ||
952 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | ||
953 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | ||
954 | pretimeout = 99; | ||
955 | timeout = 100; | ||
956 | |||
957 | testing_nmi = 1; | ||
958 | |||
959 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | ||
960 | if (rv) { | ||
961 | printk(KERN_WARNING PFX "Error starting timer to" | ||
962 | " test NMI: 0x%x. The NMI pretimeout will" | ||
963 | " likely not work\n", rv); | ||
964 | rv = 0; | ||
965 | goto out_restore; | ||
966 | } | ||
967 | |||
968 | msleep(1500); | ||
926 | 969 | ||
970 | if (testing_nmi != 2) { | ||
971 | printk(KERN_WARNING PFX "IPMI NMI didn't seem to" | ||
972 | " occur. The NMI pretimeout will" | ||
973 | " likely not work\n"); | ||
974 | } | ||
975 | out_restore: | ||
976 | testing_nmi = 0; | ||
977 | preop_val = old_preop_val; | ||
978 | pretimeout = old_pretimeout; | ||
979 | timeout = old_timeout; | ||
980 | } | ||
981 | #endif | ||
982 | |||
983 | out: | ||
927 | if ((start_now) && (rv == 0)) { | 984 | if ((start_now) && (rv == 0)) { |
928 | /* Run from startup, so start the timer now. */ | 985 | /* Run from startup, so start the timer now. */ |
929 | start_now = 0; /* Disable this function after first startup. */ | 986 | start_now = 0; /* Disable this function after first startup. */ |
930 | ipmi_watchdog_state = action_val; | 987 | ipmi_watchdog_state = action_val; |
931 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 988 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
932 | printk(KERN_INFO PFX "Starting now!\n"); | 989 | printk(KERN_INFO PFX "Starting now!\n"); |
990 | } else { | ||
991 | /* Stop the timer now. */ | ||
992 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | ||
993 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | ||
933 | } | 994 | } |
934 | } | 995 | } |
935 | 996 | ||
@@ -937,8 +998,6 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
937 | { | 998 | { |
938 | int rv; | 999 | int rv; |
939 | 1000 | ||
940 | down_write(®ister_sem); | ||
941 | |||
942 | if (!watchdog_user) | 1001 | if (!watchdog_user) |
943 | goto out; | 1002 | goto out; |
944 | 1003 | ||
@@ -963,20 +1022,44 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
963 | watchdog_user = NULL; | 1022 | watchdog_user = NULL; |
964 | 1023 | ||
965 | out: | 1024 | out: |
966 | up_write(®ister_sem); | 1025 | return; |
967 | } | 1026 | } |
968 | 1027 | ||
969 | #ifdef HAVE_NMI_HANDLER | 1028 | #ifdef HAVE_DIE_NMI |
970 | static int | 1029 | static int |
971 | ipmi_nmi(void *dev_id, int cpu, int handled) | 1030 | ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) |
972 | { | 1031 | { |
1032 | struct die_args *args = data; | ||
1033 | |||
1034 | if (val != DIE_NMI) | ||
1035 | return NOTIFY_OK; | ||
1036 | |||
1037 | /* Hack, if it's a memory or I/O error, ignore it. */ | ||
1038 | if (args->err & 0xc0) | ||
1039 | return NOTIFY_OK; | ||
1040 | |||
1041 | /* | ||
1042 | * If we get here, it's an NMI that's not a memory or I/O | ||
1043 | * error. We can't truly tell if it's from IPMI or not | ||
1044 | * without sending a message, and sending a message is almost | ||
1045 | * impossible because of locking. | ||
1046 | */ | ||
1047 | |||
1048 | if (testing_nmi) { | ||
1049 | testing_nmi = 2; | ||
1050 | return NOTIFY_STOP; | ||
1051 | } | ||
1052 | |||
973 | /* If we are not expecting a timeout, ignore it. */ | 1053 | /* If we are not expecting a timeout, ignore it. */ |
974 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1054 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
975 | return NOTIFY_DONE; | 1055 | return NOTIFY_OK; |
1056 | |||
1057 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | ||
1058 | return NOTIFY_OK; | ||
976 | 1059 | ||
977 | /* If no one else handled the NMI, we assume it was the IPMI | 1060 | /* If no one else handled the NMI, we assume it was the IPMI |
978 | watchdog. */ | 1061 | watchdog. */ |
979 | if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { | 1062 | if (preop_val == WDOG_PREOP_PANIC) { |
980 | /* On some machines, the heartbeat will give | 1063 | /* On some machines, the heartbeat will give |
981 | an error and not work unless we re-enable | 1064 | an error and not work unless we re-enable |
982 | the timer. So do so. */ | 1065 | the timer. So do so. */ |
@@ -985,18 +1068,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled) | |||
985 | panic(PFX "pre-timeout"); | 1068 | panic(PFX "pre-timeout"); |
986 | } | 1069 | } |
987 | 1070 | ||
988 | return NOTIFY_DONE; | 1071 | return NOTIFY_STOP; |
989 | } | 1072 | } |
990 | 1073 | ||
991 | static struct nmi_handler ipmi_nmi_handler = | 1074 | static struct notifier_block ipmi_nmi_handler = { |
992 | { | 1075 | .notifier_call = ipmi_nmi |
993 | .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), | ||
994 | .dev_name = "ipmi_watchdog", | ||
995 | .dev_id = NULL, | ||
996 | .handler = ipmi_nmi, | ||
997 | .priority = 0, /* Call us last. */ | ||
998 | }; | 1076 | }; |
999 | int nmi_handler_registered; | ||
1000 | #endif | 1077 | #endif |
1001 | 1078 | ||
1002 | static int wdog_reboot_handler(struct notifier_block *this, | 1079 | static int wdog_reboot_handler(struct notifier_block *this, |
@@ -1009,7 +1086,7 @@ static int wdog_reboot_handler(struct notifier_block *this, | |||
1009 | /* Make sure we only do this once. */ | 1086 | /* Make sure we only do this once. */ |
1010 | reboot_event_handled = 1; | 1087 | reboot_event_handled = 1; |
1011 | 1088 | ||
1012 | if (code == SYS_DOWN || code == SYS_HALT) { | 1089 | if (code == SYS_POWER_OFF || code == SYS_HALT) { |
1013 | /* Disable the WDT if we are shutting down. */ | 1090 | /* Disable the WDT if we are shutting down. */ |
1014 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 1091 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
1015 | panic_halt_ipmi_set_timeout(); | 1092 | panic_halt_ipmi_set_timeout(); |
@@ -1113,7 +1190,7 @@ static int preaction_op(const char *inval, char *outval) | |||
1113 | preaction_val = WDOG_PRETIMEOUT_NONE; | 1190 | preaction_val = WDOG_PRETIMEOUT_NONE; |
1114 | else if (strcmp(inval, "pre_smi") == 0) | 1191 | else if (strcmp(inval, "pre_smi") == 0) |
1115 | preaction_val = WDOG_PRETIMEOUT_SMI; | 1192 | preaction_val = WDOG_PRETIMEOUT_SMI; |
1116 | #ifdef HAVE_NMI_HANDLER | 1193 | #ifdef HAVE_DIE_NMI |
1117 | else if (strcmp(inval, "pre_nmi") == 0) | 1194 | else if (strcmp(inval, "pre_nmi") == 0) |
1118 | preaction_val = WDOG_PRETIMEOUT_NMI; | 1195 | preaction_val = WDOG_PRETIMEOUT_NMI; |
1119 | #endif | 1196 | #endif |
@@ -1147,7 +1224,7 @@ static int preop_op(const char *inval, char *outval) | |||
1147 | 1224 | ||
1148 | static void check_parms(void) | 1225 | static void check_parms(void) |
1149 | { | 1226 | { |
1150 | #ifdef HAVE_NMI_HANDLER | 1227 | #ifdef HAVE_DIE_NMI |
1151 | int do_nmi = 0; | 1228 | int do_nmi = 0; |
1152 | int rv; | 1229 | int rv; |
1153 | 1230 | ||
@@ -1160,20 +1237,9 @@ static void check_parms(void) | |||
1160 | preop_op("preop_none", NULL); | 1237 | preop_op("preop_none", NULL); |
1161 | do_nmi = 0; | 1238 | do_nmi = 0; |
1162 | } | 1239 | } |
1163 | #ifdef CONFIG_X86_LOCAL_APIC | ||
1164 | if (nmi_watchdog == NMI_IO_APIC) { | ||
1165 | printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" | ||
1166 | " mode (value is %d), that is incompatible" | ||
1167 | " with using NMI in the IPMI watchdog." | ||
1168 | " Disabling IPMI nmi pretimeout.\n", | ||
1169 | nmi_watchdog); | ||
1170 | preaction_val = WDOG_PRETIMEOUT_NONE; | ||
1171 | do_nmi = 0; | ||
1172 | } | ||
1173 | #endif | ||
1174 | } | 1240 | } |
1175 | if (do_nmi && !nmi_handler_registered) { | 1241 | if (do_nmi && !nmi_handler_registered) { |
1176 | rv = request_nmi(&ipmi_nmi_handler); | 1242 | rv = register_die_notifier(&ipmi_nmi_handler); |
1177 | if (rv) { | 1243 | if (rv) { |
1178 | printk(KERN_WARNING PFX | 1244 | printk(KERN_WARNING PFX |
1179 | "Can't register nmi handler\n"); | 1245 | "Can't register nmi handler\n"); |
@@ -1181,7 +1247,7 @@ static void check_parms(void) | |||
1181 | } else | 1247 | } else |
1182 | nmi_handler_registered = 1; | 1248 | nmi_handler_registered = 1; |
1183 | } else if (!do_nmi && nmi_handler_registered) { | 1249 | } else if (!do_nmi && nmi_handler_registered) { |
1184 | release_nmi(&ipmi_nmi_handler); | 1250 | unregister_die_notifier(&ipmi_nmi_handler); |
1185 | nmi_handler_registered = 0; | 1251 | nmi_handler_registered = 0; |
1186 | } | 1252 | } |
1187 | #endif | 1253 | #endif |
@@ -1217,9 +1283,9 @@ static int __init ipmi_wdog_init(void) | |||
1217 | 1283 | ||
1218 | rv = ipmi_smi_watcher_register(&smi_watcher); | 1284 | rv = ipmi_smi_watcher_register(&smi_watcher); |
1219 | if (rv) { | 1285 | if (rv) { |
1220 | #ifdef HAVE_NMI_HANDLER | 1286 | #ifdef HAVE_DIE_NMI |
1221 | if (preaction_val == WDOG_PRETIMEOUT_NMI) | 1287 | if (nmi_handler_registered) |
1222 | release_nmi(&ipmi_nmi_handler); | 1288 | unregister_die_notifier(&ipmi_nmi_handler); |
1223 | #endif | 1289 | #endif |
1224 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1290 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1225 | &wdog_panic_notifier); | 1291 | &wdog_panic_notifier); |
@@ -1238,9 +1304,9 @@ static void __exit ipmi_wdog_exit(void) | |||
1238 | ipmi_smi_watcher_unregister(&smi_watcher); | 1304 | ipmi_smi_watcher_unregister(&smi_watcher); |
1239 | ipmi_unregister_watchdog(watchdog_ifnum); | 1305 | ipmi_unregister_watchdog(watchdog_ifnum); |
1240 | 1306 | ||
1241 | #ifdef HAVE_NMI_HANDLER | 1307 | #ifdef HAVE_DIE_NMI |
1242 | if (nmi_handler_registered) | 1308 | if (nmi_handler_registered) |
1243 | release_nmi(&ipmi_nmi_handler); | 1309 | unregister_die_notifier(&ipmi_nmi_handler); |
1244 | #endif | 1310 | #endif |
1245 | 1311 | ||
1246 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1312 | atomic_notifier_chain_unregister(&panic_notifier_list, |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 77a7a4a06620..85d596a3c18c 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1529,7 +1529,7 @@ static int __devinit reset_card(struct pci_dev *pdev, | |||
1529 | portcount = inw(base + 0x2); | 1529 | portcount = inw(base + 0x2); |
1530 | if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && | 1530 | if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && |
1531 | portcount != 8 && portcount != 16)) { | 1531 | portcount != 8 && portcount != 16)) { |
1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.", | 1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", |
1533 | card + 1); | 1533 | card + 1); |
1534 | retval = -EIO; | 1534 | retval = -EIO; |
1535 | goto end; | 1535 | goto end; |
@@ -1622,7 +1622,9 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1622 | 1622 | ||
1623 | if ((status = inw(base + 0x4)) != 0) { | 1623 | if ((status = inw(base + 0x4)) != 0) { |
1624 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" | 1624 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" |
1625 | "Address:0x%x\nCount:0x%x\nStatus:0x%x\n", | 1625 | KERN_WARNING "Address:0x%x\n" |
1626 | KERN_WARNING "Count:0x%x\n" | ||
1627 | KERN_WARNING "Status:0x%x\n", | ||
1626 | index + 1, frame->addr, frame->count, status); | 1628 | index + 1, frame->addr, frame->count, status); |
1627 | goto errrelfw; | 1629 | goto errrelfw; |
1628 | } | 1630 | } |
@@ -1666,7 +1668,9 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1666 | 1668 | ||
1667 | if ((status = inw(base + 0x4)) != 0) { | 1669 | if ((status = inw(base + 0x4)) != 0) { |
1668 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" | 1670 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" |
1669 | "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n", | 1671 | KERN_WARNING "Address:0x%x\n" |
1672 | KERN_WARNING "Count:0x%x\n" | ||
1673 | KERN_WARNING "Status: 0x%x\n", | ||
1670 | index + 1, frame->addr, frame->count, status); | 1674 | index + 1, frame->addr, frame->count, status); |
1671 | goto errrelfw; | 1675 | goto errrelfw; |
1672 | } | 1676 | } |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index ed76f0a127fd..2fc255a21486 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/bitops.h> | 43 | #include <linux/bitops.h> |
44 | #include <linux/completion.h> | ||
44 | 45 | ||
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
@@ -142,7 +143,7 @@ struct moxa_port { | |||
142 | struct tty_struct *tty; | 143 | struct tty_struct *tty; |
143 | int cflag; | 144 | int cflag; |
144 | wait_queue_head_t open_wait; | 145 | wait_queue_head_t open_wait; |
145 | wait_queue_head_t close_wait; | 146 | struct completion close_wait; |
146 | 147 | ||
147 | struct timer_list emptyTimer; | 148 | struct timer_list emptyTimer; |
148 | 149 | ||
@@ -166,7 +167,6 @@ struct moxa_port { | |||
166 | 167 | ||
167 | #define WAKEUP_CHARS 256 | 168 | #define WAKEUP_CHARS 256 |
168 | 169 | ||
169 | static int verbose = 0; | ||
170 | static int ttymajor = MOXAMAJOR; | 170 | static int ttymajor = MOXAMAJOR; |
171 | /* Variables for insmod */ | 171 | /* Variables for insmod */ |
172 | #ifdef MODULE | 172 | #ifdef MODULE |
@@ -184,7 +184,6 @@ module_param_array(baseaddr, int, NULL, 0); | |||
184 | module_param_array(numports, int, NULL, 0); | 184 | module_param_array(numports, int, NULL, 0); |
185 | #endif | 185 | #endif |
186 | module_param(ttymajor, int, 0); | 186 | module_param(ttymajor, int, 0); |
187 | module_param(verbose, bool, 0644); | ||
188 | 187 | ||
189 | /* | 188 | /* |
190 | * static functions: | 189 | * static functions: |
@@ -208,13 +207,13 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file); | |||
208 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | 207 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, |
209 | unsigned int set, unsigned int clear); | 208 | unsigned int set, unsigned int clear); |
210 | static void moxa_poll(unsigned long); | 209 | static void moxa_poll(unsigned long); |
211 | static void set_tty_param(struct tty_struct *); | 210 | static void moxa_set_tty_param(struct tty_struct *); |
212 | static int block_till_ready(struct tty_struct *, struct file *, | 211 | static int moxa_block_till_ready(struct tty_struct *, struct file *, |
213 | struct moxa_port *); | 212 | struct moxa_port *); |
214 | static void setup_empty_event(struct tty_struct *); | 213 | static void moxa_setup_empty_event(struct tty_struct *); |
215 | static void check_xmit_empty(unsigned long); | 214 | static void moxa_check_xmit_empty(unsigned long); |
216 | static void shut_down(struct moxa_port *); | 215 | static void moxa_shut_down(struct moxa_port *); |
217 | static void receive_data(struct moxa_port *); | 216 | static void moxa_receive_data(struct moxa_port *); |
218 | /* | 217 | /* |
219 | * moxa board interface functions: | 218 | * moxa board interface functions: |
220 | */ | 219 | */ |
@@ -283,8 +282,10 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
283 | int retval; | 282 | int retval; |
284 | 283 | ||
285 | retval = pci_enable_device(pdev); | 284 | retval = pci_enable_device(pdev); |
286 | if (retval) | 285 | if (retval) { |
286 | dev_err(&pdev->dev, "can't enable pci device\n"); | ||
287 | goto err; | 287 | goto err; |
288 | } | ||
288 | 289 | ||
289 | for (i = 0; i < MAX_BOARDS; i++) | 290 | for (i = 0; i < MAX_BOARDS; i++) |
290 | if (moxa_boards[i].basemem == NULL) | 291 | if (moxa_boards[i].basemem == NULL) |
@@ -292,16 +293,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
292 | 293 | ||
293 | retval = -ENODEV; | 294 | retval = -ENODEV; |
294 | if (i >= MAX_BOARDS) { | 295 | if (i >= MAX_BOARDS) { |
295 | if (verbose) | 296 | dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards " |
296 | printk("More than %d MOXA Intellio family boards " | ||
297 | "found. Board is ignored.\n", MAX_BOARDS); | 297 | "found. Board is ignored.\n", MAX_BOARDS); |
298 | goto err; | 298 | goto err; |
299 | } | 299 | } |
300 | 300 | ||
301 | board = &moxa_boards[i]; | 301 | board = &moxa_boards[i]; |
302 | board->basemem = pci_iomap(pdev, 2, 0x4000); | 302 | board->basemem = pci_iomap(pdev, 2, 0x4000); |
303 | if (board->basemem == NULL) | 303 | if (board->basemem == NULL) { |
304 | dev_err(&pdev->dev, "can't remap io space 2\n"); | ||
304 | goto err; | 305 | goto err; |
306 | } | ||
305 | 307 | ||
306 | board->boardType = board_type; | 308 | board->boardType = board_type; |
307 | switch (board_type) { | 309 | switch (board_type) { |
@@ -347,7 +349,8 @@ static int __init moxa_init(void) | |||
347 | int i, numBoards, retval = 0; | 349 | int i, numBoards, retval = 0; |
348 | struct moxa_port *ch; | 350 | struct moxa_port *ch; |
349 | 351 | ||
350 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); | 352 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
353 | MOXA_VERSION); | ||
351 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); | 354 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); |
352 | if (!moxaDriver) | 355 | if (!moxaDriver) |
353 | return -ENOMEM; | 356 | return -ENOMEM; |
@@ -372,13 +375,13 @@ static int __init moxa_init(void) | |||
372 | ch->closing_wait = 30 * HZ; | 375 | ch->closing_wait = 30 * HZ; |
373 | ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 376 | ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
374 | init_waitqueue_head(&ch->open_wait); | 377 | init_waitqueue_head(&ch->open_wait); |
375 | init_waitqueue_head(&ch->close_wait); | 378 | init_completion(&ch->close_wait); |
376 | 379 | ||
377 | setup_timer(&ch->emptyTimer, check_xmit_empty, | 380 | setup_timer(&ch->emptyTimer, moxa_check_xmit_empty, |
378 | (unsigned long)ch); | 381 | (unsigned long)ch); |
379 | } | 382 | } |
380 | 383 | ||
381 | printk("Tty devices major number = %d\n", ttymajor); | 384 | pr_debug("Moxa tty devices major number = %d\n", ttymajor); |
382 | 385 | ||
383 | if (tty_register_driver(moxaDriver)) { | 386 | if (tty_register_driver(moxaDriver)) { |
384 | printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); | 387 | printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); |
@@ -400,11 +403,10 @@ static int __init moxa_init(void) | |||
400 | moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; | 403 | moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; |
401 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; | 404 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; |
402 | moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; | 405 | moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; |
403 | if (verbose) | 406 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", |
404 | printk("Board %2d: %s board(baseAddr=%lx)\n", | 407 | numBoards + 1, |
405 | numBoards + 1, | 408 | moxa_brdname[moxa_boards[numBoards].boardType-1], |
406 | moxa_brdname[moxa_boards[numBoards].boardType - 1], | 409 | moxa_boards[numBoards].baseAddr); |
407 | moxa_boards[numBoards].baseAddr); | ||
408 | numBoards++; | 410 | numBoards++; |
409 | } | 411 | } |
410 | } | 412 | } |
@@ -413,14 +415,13 @@ static int __init moxa_init(void) | |||
413 | for (i = 0; i < MAX_BOARDS; i++) { | 415 | for (i = 0; i < MAX_BOARDS; i++) { |
414 | if ((type[i] == MOXA_BOARD_C218_ISA) || | 416 | if ((type[i] == MOXA_BOARD_C218_ISA) || |
415 | (type[i] == MOXA_BOARD_C320_ISA)) { | 417 | (type[i] == MOXA_BOARD_C320_ISA)) { |
416 | if (verbose) | 418 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", |
417 | printk("Board %2d: %s board(baseAddr=%lx)\n", | 419 | numBoards + 1, moxa_brdname[type[i] - 1], |
418 | numBoards + 1, | 420 | (unsigned long)baseaddr[i]); |
419 | moxa_brdname[type[i] - 1], | ||
420 | (unsigned long) baseaddr[i]); | ||
421 | if (numBoards >= MAX_BOARDS) { | 421 | if (numBoards >= MAX_BOARDS) { |
422 | if (verbose) | 422 | printk(KERN_WARNING "More than %d MOXA " |
423 | printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); | 423 | "Intellio family boards found. Board " |
424 | "is ignored.\n", MAX_BOARDS); | ||
424 | continue; | 425 | continue; |
425 | } | 426 | } |
426 | moxa_boards[numBoards].boardType = type[i]; | 427 | moxa_boards[numBoards].boardType = type[i]; |
@@ -456,16 +457,14 @@ static void __exit moxa_exit(void) | |||
456 | { | 457 | { |
457 | int i; | 458 | int i; |
458 | 459 | ||
459 | if (verbose) | ||
460 | printk("Unloading module moxa ...\n"); | ||
461 | |||
462 | del_timer_sync(&moxaTimer); | 460 | del_timer_sync(&moxaTimer); |
463 | 461 | ||
464 | for (i = 0; i < MAX_PORTS; i++) | 462 | for (i = 0; i < MAX_PORTS; i++) |
465 | del_timer_sync(&moxa_ports[i].emptyTimer); | 463 | del_timer_sync(&moxa_ports[i].emptyTimer); |
466 | 464 | ||
467 | if (tty_unregister_driver(moxaDriver)) | 465 | if (tty_unregister_driver(moxaDriver)) |
468 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); | 466 | printk(KERN_ERR "Couldn't unregister MOXA Intellio family " |
467 | "serial driver\n"); | ||
469 | put_tty_driver(moxaDriver); | 468 | put_tty_driver(moxaDriver); |
470 | 469 | ||
471 | #ifdef CONFIG_PCI | 470 | #ifdef CONFIG_PCI |
@@ -475,9 +474,6 @@ static void __exit moxa_exit(void) | |||
475 | for (i = 0; i < MAX_BOARDS; i++) | 474 | for (i = 0; i < MAX_BOARDS; i++) |
476 | if (moxa_boards[i].basemem) | 475 | if (moxa_boards[i].basemem) |
477 | iounmap(moxa_boards[i].basemem); | 476 | iounmap(moxa_boards[i].basemem); |
478 | |||
479 | if (verbose) | ||
480 | printk("Done\n"); | ||
481 | } | 477 | } |
482 | 478 | ||
483 | module_init(moxa_init); | 479 | module_init(moxa_init); |
@@ -504,12 +500,12 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
504 | ch->tty = tty; | 500 | ch->tty = tty; |
505 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { | 501 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { |
506 | ch->statusflags = 0; | 502 | ch->statusflags = 0; |
507 | set_tty_param(tty); | 503 | moxa_set_tty_param(tty); |
508 | MoxaPortLineCtrl(ch->port, 1, 1); | 504 | MoxaPortLineCtrl(ch->port, 1, 1); |
509 | MoxaPortEnable(ch->port); | 505 | MoxaPortEnable(ch->port); |
510 | ch->asyncflags |= ASYNC_INITIALIZED; | 506 | ch->asyncflags |= ASYNC_INITIALIZED; |
511 | } | 507 | } |
512 | retval = block_till_ready(tty, filp, ch); | 508 | retval = moxa_block_till_ready(tty, filp, ch); |
513 | 509 | ||
514 | moxa_unthrottle(tty); | 510 | moxa_unthrottle(tty); |
515 | 511 | ||
@@ -532,9 +528,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
532 | return; | 528 | return; |
533 | } | 529 | } |
534 | if (!MoxaPortIsValid(port)) { | 530 | if (!MoxaPortIsValid(port)) { |
535 | #ifdef SERIAL_DEBUG_CLOSE | 531 | pr_debug("Invalid portno in moxa_close\n"); |
536 | printk("Invalid portno in moxa_close\n"); | ||
537 | #endif | ||
538 | tty->driver_data = NULL; | 532 | tty->driver_data = NULL; |
539 | return; | 533 | return; |
540 | } | 534 | } |
@@ -547,13 +541,13 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
547 | ch = (struct moxa_port *) tty->driver_data; | 541 | ch = (struct moxa_port *) tty->driver_data; |
548 | 542 | ||
549 | if ((tty->count == 1) && (ch->count != 1)) { | 543 | if ((tty->count == 1) && (ch->count != 1)) { |
550 | printk("moxa_close: bad serial port count; tty->count is 1, " | 544 | printk(KERN_WARNING "moxa_close: bad serial port count; " |
551 | "ch->count is %d\n", ch->count); | 545 | "tty->count is 1, ch->count is %d\n", ch->count); |
552 | ch->count = 1; | 546 | ch->count = 1; |
553 | } | 547 | } |
554 | if (--ch->count < 0) { | 548 | if (--ch->count < 0) { |
555 | printk("moxa_close: bad serial port count, device=%s\n", | 549 | printk(KERN_WARNING "moxa_close: bad serial port count, " |
556 | tty->name); | 550 | "device=%s\n", tty->name); |
557 | ch->count = 0; | 551 | ch->count = 0; |
558 | } | 552 | } |
559 | if (ch->count) { | 553 | if (ch->count) { |
@@ -563,11 +557,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
563 | 557 | ||
564 | ch->cflag = tty->termios->c_cflag; | 558 | ch->cflag = tty->termios->c_cflag; |
565 | if (ch->asyncflags & ASYNC_INITIALIZED) { | 559 | if (ch->asyncflags & ASYNC_INITIALIZED) { |
566 | setup_empty_event(tty); | 560 | moxa_setup_empty_event(tty); |
567 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | 561 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ |
568 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); | 562 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); |
569 | } | 563 | } |
570 | shut_down(ch); | 564 | moxa_shut_down(ch); |
571 | MoxaPortFlushData(port, 2); | 565 | MoxaPortFlushData(port, 2); |
572 | 566 | ||
573 | if (tty->driver->flush_buffer) | 567 | if (tty->driver->flush_buffer) |
@@ -584,7 +578,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
584 | wake_up_interruptible(&ch->open_wait); | 578 | wake_up_interruptible(&ch->open_wait); |
585 | } | 579 | } |
586 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 580 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
587 | wake_up_interruptible(&ch->close_wait); | 581 | complete_all(&ch->close_wait); |
588 | } | 582 | } |
589 | 583 | ||
590 | static int moxa_write(struct tty_struct *tty, | 584 | static int moxa_write(struct tty_struct *tty, |
@@ -653,7 +647,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
653 | * in tty_ioctl.c, etc. | 647 | * in tty_ioctl.c, etc. |
654 | */ | 648 | */ |
655 | if (!(ch->statusflags & EMPTYWAIT)) | 649 | if (!(ch->statusflags & EMPTYWAIT)) |
656 | setup_empty_event(tty); | 650 | moxa_setup_empty_event(tty); |
657 | } | 651 | } |
658 | return (chars); | 652 | return (chars); |
659 | } | 653 | } |
@@ -751,7 +745,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
751 | retval = tty_check_change(tty); | 745 | retval = tty_check_change(tty); |
752 | if (retval) | 746 | if (retval) |
753 | return (retval); | 747 | return (retval); |
754 | setup_empty_event(tty); | 748 | moxa_setup_empty_event(tty); |
755 | tty_wait_until_sent(tty, 0); | 749 | tty_wait_until_sent(tty, 0); |
756 | if (!arg) | 750 | if (!arg) |
757 | MoxaPortSendBreak(ch->port, 0); | 751 | MoxaPortSendBreak(ch->port, 0); |
@@ -760,7 +754,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
760 | retval = tty_check_change(tty); | 754 | retval = tty_check_change(tty); |
761 | if (retval) | 755 | if (retval) |
762 | return (retval); | 756 | return (retval); |
763 | setup_empty_event(tty); | 757 | moxa_setup_empty_event(tty); |
764 | tty_wait_until_sent(tty, 0); | 758 | tty_wait_until_sent(tty, 0); |
765 | MoxaPortSendBreak(ch->port, arg); | 759 | MoxaPortSendBreak(ch->port, arg); |
766 | return (0); | 760 | return (0); |
@@ -809,7 +803,7 @@ static void moxa_set_termios(struct tty_struct *tty, | |||
809 | 803 | ||
810 | if (ch == NULL) | 804 | if (ch == NULL) |
811 | return; | 805 | return; |
812 | set_tty_param(tty); | 806 | moxa_set_tty_param(tty); |
813 | if (!(old_termios->c_cflag & CLOCAL) && | 807 | if (!(old_termios->c_cflag & CLOCAL) && |
814 | (tty->termios->c_cflag & CLOCAL)) | 808 | (tty->termios->c_cflag & CLOCAL)) |
815 | wake_up_interruptible(&ch->open_wait); | 809 | wake_up_interruptible(&ch->open_wait); |
@@ -845,7 +839,7 @@ static void moxa_hangup(struct tty_struct *tty) | |||
845 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 839 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; |
846 | 840 | ||
847 | moxa_flush_buffer(tty); | 841 | moxa_flush_buffer(tty); |
848 | shut_down(ch); | 842 | moxa_shut_down(ch); |
849 | ch->event = 0; | 843 | ch->event = 0; |
850 | ch->count = 0; | 844 | ch->count = 0; |
851 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | 845 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -875,7 +869,7 @@ static void moxa_poll(unsigned long ignored) | |||
875 | continue; | 869 | continue; |
876 | if (!(ch->statusflags & THROTTLE) && | 870 | if (!(ch->statusflags & THROTTLE) && |
877 | (MoxaPortRxQueue(ch->port) > 0)) | 871 | (MoxaPortRxQueue(ch->port) > 0)) |
878 | receive_data(ch); | 872 | moxa_receive_data(ch); |
879 | if ((tp = ch->tty) == 0) | 873 | if ((tp = ch->tty) == 0) |
880 | continue; | 874 | continue; |
881 | if (ch->statusflags & LOWWAIT) { | 875 | if (ch->statusflags & LOWWAIT) { |
@@ -909,7 +903,7 @@ static void moxa_poll(unsigned long ignored) | |||
909 | 903 | ||
910 | /******************************************************************************/ | 904 | /******************************************************************************/ |
911 | 905 | ||
912 | static void set_tty_param(struct tty_struct *tty) | 906 | static void moxa_set_tty_param(struct tty_struct *tty) |
913 | { | 907 | { |
914 | register struct ktermios *ts; | 908 | register struct ktermios *ts; |
915 | struct moxa_port *ch; | 909 | struct moxa_port *ch; |
@@ -934,7 +928,7 @@ static void set_tty_param(struct tty_struct *tty) | |||
934 | MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); | 928 | MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); |
935 | } | 929 | } |
936 | 930 | ||
937 | static int block_till_ready(struct tty_struct *tty, struct file *filp, | 931 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, |
938 | struct moxa_port *ch) | 932 | struct moxa_port *ch) |
939 | { | 933 | { |
940 | DECLARE_WAITQUEUE(wait,current); | 934 | DECLARE_WAITQUEUE(wait,current); |
@@ -948,7 +942,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
948 | */ | 942 | */ |
949 | if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { | 943 | if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { |
950 | if (ch->asyncflags & ASYNC_CLOSING) | 944 | if (ch->asyncflags & ASYNC_CLOSING) |
951 | interruptible_sleep_on(&ch->close_wait); | 945 | wait_for_completion_interruptible(&ch->close_wait); |
952 | #ifdef SERIAL_DO_RESTART | 946 | #ifdef SERIAL_DO_RESTART |
953 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) | 947 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) |
954 | return (-EAGAIN); | 948 | return (-EAGAIN); |
@@ -971,10 +965,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
971 | */ | 965 | */ |
972 | retval = 0; | 966 | retval = 0; |
973 | add_wait_queue(&ch->open_wait, &wait); | 967 | add_wait_queue(&ch->open_wait, &wait); |
974 | #ifdef SERIAL_DEBUG_OPEN | 968 | pr_debug("block_til_ready before block: ttys%d, count = %d\n", |
975 | printk("block_til_ready before block: ttys%d, count = %d\n", | 969 | ch->port, ch->count); |
976 | ch->line, ch->count); | ||
977 | #endif | ||
978 | spin_lock_irqsave(&moxa_lock, flags); | 970 | spin_lock_irqsave(&moxa_lock, flags); |
979 | if (!tty_hung_up_p(filp)) | 971 | if (!tty_hung_up_p(filp)) |
980 | ch->count--; | 972 | ch->count--; |
@@ -1013,10 +1005,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1013 | ch->count++; | 1005 | ch->count++; |
1014 | ch->blocked_open--; | 1006 | ch->blocked_open--; |
1015 | spin_unlock_irqrestore(&moxa_lock, flags); | 1007 | spin_unlock_irqrestore(&moxa_lock, flags); |
1016 | #ifdef SERIAL_DEBUG_OPEN | 1008 | pr_debug("block_til_ready after blocking: ttys%d, count = %d\n", |
1017 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 1009 | ch->port, ch->count); |
1018 | ch->line, ch->count); | ||
1019 | #endif | ||
1020 | if (retval) | 1010 | if (retval) |
1021 | return (retval); | 1011 | return (retval); |
1022 | /* FIXME: review to see if we need to use set_bit on these */ | 1012 | /* FIXME: review to see if we need to use set_bit on these */ |
@@ -1024,7 +1014,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1024 | return 0; | 1014 | return 0; |
1025 | } | 1015 | } |
1026 | 1016 | ||
1027 | static void setup_empty_event(struct tty_struct *tty) | 1017 | static void moxa_setup_empty_event(struct tty_struct *tty) |
1028 | { | 1018 | { |
1029 | struct moxa_port *ch = tty->driver_data; | 1019 | struct moxa_port *ch = tty->driver_data; |
1030 | unsigned long flags; | 1020 | unsigned long flags; |
@@ -1035,24 +1025,24 @@ static void setup_empty_event(struct tty_struct *tty) | |||
1035 | spin_unlock_irqrestore(&moxa_lock, flags); | 1025 | spin_unlock_irqrestore(&moxa_lock, flags); |
1036 | } | 1026 | } |
1037 | 1027 | ||
1038 | static void check_xmit_empty(unsigned long data) | 1028 | static void moxa_check_xmit_empty(unsigned long data) |
1039 | { | 1029 | { |
1040 | struct moxa_port *ch; | 1030 | struct moxa_port *ch; |
1041 | 1031 | ||
1042 | ch = (struct moxa_port *) data; | 1032 | ch = (struct moxa_port *) data; |
1043 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); | ||
1044 | if (ch->tty && (ch->statusflags & EMPTYWAIT)) { | 1033 | if (ch->tty && (ch->statusflags & EMPTYWAIT)) { |
1045 | if (MoxaPortTxQueue(ch->port) == 0) { | 1034 | if (MoxaPortTxQueue(ch->port) == 0) { |
1046 | ch->statusflags &= ~EMPTYWAIT; | 1035 | ch->statusflags &= ~EMPTYWAIT; |
1047 | tty_wakeup(ch->tty); | 1036 | tty_wakeup(ch->tty); |
1048 | return; | 1037 | return; |
1049 | } | 1038 | } |
1050 | mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); | 1039 | mod_timer(&moxa_ports[ch->port].emptyTimer, |
1040 | round_jiffies(jiffies + HZ)); | ||
1051 | } else | 1041 | } else |
1052 | ch->statusflags &= ~EMPTYWAIT; | 1042 | ch->statusflags &= ~EMPTYWAIT; |
1053 | } | 1043 | } |
1054 | 1044 | ||
1055 | static void shut_down(struct moxa_port *ch) | 1045 | static void moxa_shut_down(struct moxa_port *ch) |
1056 | { | 1046 | { |
1057 | struct tty_struct *tp; | 1047 | struct tty_struct *tp; |
1058 | 1048 | ||
@@ -1072,7 +1062,7 @@ static void shut_down(struct moxa_port *ch) | |||
1072 | ch->asyncflags &= ~ASYNC_INITIALIZED; | 1062 | ch->asyncflags &= ~ASYNC_INITIALIZED; |
1073 | } | 1063 | } |
1074 | 1064 | ||
1075 | static void receive_data(struct moxa_port *ch) | 1065 | static void moxa_receive_data(struct moxa_port *ch) |
1076 | { | 1066 | { |
1077 | struct tty_struct *tp; | 1067 | struct tty_struct *tp; |
1078 | struct ktermios *ts; | 1068 | struct ktermios *ts; |
@@ -1406,8 +1396,8 @@ static struct mon_str moxaLog; | |||
1406 | static int moxaFuncTout = HZ / 2; | 1396 | static int moxaFuncTout = HZ / 2; |
1407 | 1397 | ||
1408 | static void moxafunc(void __iomem *, int, ushort); | 1398 | static void moxafunc(void __iomem *, int, ushort); |
1409 | static void wait_finish(void __iomem *); | 1399 | static void moxa_wait_finish(void __iomem *); |
1410 | static void low_water_check(void __iomem *); | 1400 | static void moxa_low_water_check(void __iomem *); |
1411 | static int moxaloadbios(int, unsigned char __user *, int); | 1401 | static int moxaloadbios(int, unsigned char __user *, int); |
1412 | static int moxafindcard(int); | 1402 | static int moxafindcard(int); |
1413 | static int moxaload320b(int, unsigned char __user *, int); | 1403 | static int moxaload320b(int, unsigned char __user *, int); |
@@ -1473,7 +1463,7 @@ void MoxaPortFlushData(int port, int mode) | |||
1473 | moxafunc(ofsAddr, FC_FlushQueue, mode); | 1463 | moxafunc(ofsAddr, FC_FlushQueue, mode); |
1474 | if (mode != 1) { | 1464 | if (mode != 1) { |
1475 | moxa_ports[port].lowChkFlag = 0; | 1465 | moxa_ports[port].lowChkFlag = 0; |
1476 | low_water_check(ofsAddr); | 1466 | moxa_low_water_check(ofsAddr); |
1477 | } | 1467 | } |
1478 | } | 1468 | } |
1479 | 1469 | ||
@@ -1654,7 +1644,7 @@ int MoxaDriverPoll(void) | |||
1654 | if (moxa_ports[p].lowChkFlag) { | 1644 | if (moxa_ports[p].lowChkFlag) { |
1655 | moxa_ports[p].lowChkFlag = 0; | 1645 | moxa_ports[p].lowChkFlag = 0; |
1656 | ofsAddr = moxa_ports[p].tableAddr; | 1646 | ofsAddr = moxa_ports[p].tableAddr; |
1657 | low_water_check(ofsAddr); | 1647 | moxa_low_water_check(ofsAddr); |
1658 | } | 1648 | } |
1659 | } | 1649 | } |
1660 | } | 1650 | } |
@@ -2081,7 +2071,7 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) | |||
2081 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); | 2071 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); |
2082 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); | 2072 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); |
2083 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); | 2073 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); |
2084 | wait_finish(ofsAddr); | 2074 | moxa_wait_finish(ofsAddr); |
2085 | 2075 | ||
2086 | } | 2076 | } |
2087 | return (0); | 2077 | return (0); |
@@ -2480,10 +2470,10 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) | |||
2480 | 2470 | ||
2481 | writew(arg, ofsAddr + FuncArg); | 2471 | writew(arg, ofsAddr + FuncArg); |
2482 | writew(cmd, ofsAddr + FuncCode); | 2472 | writew(cmd, ofsAddr + FuncCode); |
2483 | wait_finish(ofsAddr); | 2473 | moxa_wait_finish(ofsAddr); |
2484 | } | 2474 | } |
2485 | 2475 | ||
2486 | static void wait_finish(void __iomem *ofsAddr) | 2476 | static void moxa_wait_finish(void __iomem *ofsAddr) |
2487 | { | 2477 | { |
2488 | unsigned long i, j; | 2478 | unsigned long i, j; |
2489 | 2479 | ||
@@ -2496,7 +2486,7 @@ static void wait_finish(void __iomem *ofsAddr) | |||
2496 | } | 2486 | } |
2497 | } | 2487 | } |
2498 | 2488 | ||
2499 | static void low_water_check(void __iomem *ofsAddr) | 2489 | static void moxa_low_water_check(void __iomem *ofsAddr) |
2500 | { | 2490 | { |
2501 | int len; | 2491 | int len; |
2502 | ushort rptr, wptr, mask; | 2492 | ushort rptr, wptr, mask; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 2aee3fef0416..661aca0e155d 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -383,7 +383,6 @@ static int mxser_init(void); | |||
383 | 383 | ||
384 | /* static void mxser_poll(unsigned long); */ | 384 | /* static void mxser_poll(unsigned long); */ |
385 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); | 385 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); |
386 | static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); | ||
387 | static void mxser_do_softint(struct work_struct *); | 386 | static void mxser_do_softint(struct work_struct *); |
388 | static int mxser_open(struct tty_struct *, struct file *); | 387 | static int mxser_open(struct tty_struct *, struct file *); |
389 | static void mxser_close(struct tty_struct *, struct file *); | 388 | static void mxser_close(struct tty_struct *, struct file *); |
@@ -422,7 +421,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout); | |||
422 | static void mxser_startrx(struct tty_struct *tty); | 421 | static void mxser_startrx(struct tty_struct *tty); |
423 | static void mxser_stoprx(struct tty_struct *tty); | 422 | static void mxser_stoprx(struct tty_struct *tty); |
424 | 423 | ||
425 | 424 | #ifdef CONFIG_PCI | |
426 | static int CheckIsMoxaMust(int io) | 425 | static int CheckIsMoxaMust(int io) |
427 | { | 426 | { |
428 | u8 oldmcr, hwid; | 427 | u8 oldmcr, hwid; |
@@ -445,6 +444,7 @@ static int CheckIsMoxaMust(int io) | |||
445 | } | 444 | } |
446 | return MOXA_OTHER_UART; | 445 | return MOXA_OTHER_UART; |
447 | } | 446 | } |
447 | #endif | ||
448 | 448 | ||
449 | /* above is modified by Victor Yu. 08-15-2002 */ | 449 | /* above is modified by Victor Yu. 08-15-2002 */ |
450 | 450 | ||
@@ -1938,14 +1938,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
1938 | inb(info->base + UART_MSR); | 1938 | inb(info->base + UART_MSR); |
1939 | continue; | 1939 | continue; |
1940 | } | 1940 | } |
1941 | /* above add by Victor Yu. 09-13-2002 */ | ||
1942 | /* | ||
1943 | if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) { | ||
1944 | info->IER |= MOXA_MUST_RECV_ISR; | ||
1945 | outb(info->IER, info->base + UART_IER); | ||
1946 | } | ||
1947 | */ | ||
1948 | |||
1949 | 1941 | ||
1950 | /* mask by Victor Yu. 09-13-2002 | 1942 | /* mask by Victor Yu. 09-13-2002 |
1951 | if ( !info->tty || | 1943 | if ( !info->tty || |
@@ -2599,19 +2591,8 @@ static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_te | |||
2599 | info->IER |= UART_IER_MSI; | 2591 | info->IER |= UART_IER_MSI; |
2600 | if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { | 2592 | if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { |
2601 | info->MCR |= UART_MCR_AFE; | 2593 | info->MCR |= UART_MCR_AFE; |
2602 | /* status = mxser_get_msr(info->base, 0, info->port); */ | ||
2603 | /* | ||
2604 | save_flags(flags); | ||
2605 | cli(); | ||
2606 | status = inb(baseaddr + UART_MSR); | ||
2607 | restore_flags(flags); | ||
2608 | */ | ||
2609 | /* mxser_check_modem_status(info, status); */ | ||
2610 | } else { | 2594 | } else { |
2611 | /* status = mxser_get_msr(info->base, 0, info->port); */ | ||
2612 | /* MX_LOCK(&info->slock); */ | ||
2613 | status = inb(info->base + UART_MSR); | 2595 | status = inb(info->base + UART_MSR); |
2614 | /* MX_UNLOCK(&info->slock); */ | ||
2615 | if (info->tty->hw_stopped) { | 2596 | if (info->tty->hw_stopped) { |
2616 | if (status & UART_MSR_CTS) { | 2597 | if (status & UART_MSR_CTS) { |
2617 | info->tty->hw_stopped = 0; | 2598 | info->tty->hw_stopped = 0; |
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 6a563932ba19..854dbf59eb68 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. | 2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). | 4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). |
5 | * Copyright (C) 2006 Jiri Slaby <jirislaby@gmail.com> | 5 | * Copyright (C) 2006-2007 Jiri Slaby <jirislaby@gmail.com> |
6 | * | 6 | * |
7 | * This code is loosely based on the 1.8 moxa driver which is based on | 7 | * This code is loosely based on the 1.8 moxa driver which is based on |
8 | * Linux serial driver, written by Linus Torvalds, Theodore T'so and | 8 | * Linux serial driver, written by Linus Torvalds, Theodore T'so and |
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #include "mxser_new.h" | 49 | #include "mxser_new.h" |
50 | 50 | ||
51 | #define MXSER_VERSION "2.0.1" /* 1.9.15 */ | 51 | #define MXSER_VERSION "2.0.2" /* 1.10 */ |
52 | #define MXSERMAJOR 174 | 52 | #define MXSERMAJOR 174 |
53 | #define MXSERCUMAJOR 175 | 53 | #define MXSERCUMAJOR 175 |
54 | 54 | ||
@@ -72,6 +72,12 @@ | |||
72 | #define UART_MCR_AFE 0x20 | 72 | #define UART_MCR_AFE 0x20 |
73 | #define UART_LSR_SPECIAL 0x1E | 73 | #define UART_LSR_SPECIAL 0x1E |
74 | 74 | ||
75 | #define PCI_DEVICE_ID_CB108 0x1080 | ||
76 | #define PCI_DEVICE_ID_CB114 0x1142 | ||
77 | #define PCI_DEVICE_ID_CB134I 0x1341 | ||
78 | #define PCI_DEVICE_ID_CP138U 0x1380 | ||
79 | #define PCI_DEVICE_ID_POS104UL 0x1044 | ||
80 | |||
75 | 81 | ||
76 | #define C168_ASIC_ID 1 | 82 | #define C168_ASIC_ID 1 |
77 | #define C104_ASIC_ID 2 | 83 | #define C104_ASIC_ID 2 |
@@ -107,71 +113,63 @@ struct mxser_cardinfo { | |||
107 | }; | 113 | }; |
108 | 114 | ||
109 | static const struct mxser_cardinfo mxser_cards[] = { | 115 | static const struct mxser_cardinfo mxser_cards[] = { |
110 | { 8, "C168 series", }, /* C168-ISA */ | 116 | /* 0*/ { 8, "C168 series", }, |
111 | { 4, "C104 series", }, /* C104-ISA */ | 117 | { 4, "C104 series", }, |
112 | { 4, "CI-104J series", }, /* CI104J */ | 118 | { 4, "CI-104J series", }, |
113 | { 8, "C168H/PCI series", }, /* C168-PCI */ | 119 | { 8, "C168H/PCI series", }, |
114 | { 4, "C104H/PCI series", }, /* C104-PCI */ | 120 | { 4, "C104H/PCI series", }, |
115 | { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ | 121 | /* 5*/ { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ |
116 | { 4, "CI-132 series", MXSER_HAS2 }, /* CI132 */ | 122 | { 4, "CI-132 series", MXSER_HAS2 }, |
117 | { 4, "CI-134 series", }, /* CI134 */ | 123 | { 4, "CI-134 series", }, |
118 | { 2, "CP-132 series", }, /* CP132 */ | 124 | { 2, "CP-132 series", }, |
119 | { 4, "CP-114 series", }, /* CP114 */ | 125 | { 4, "CP-114 series", }, |
120 | { 4, "CT-114 series", }, /* CT114 */ | 126 | /*10*/ { 4, "CT-114 series", }, |
121 | { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */ | 127 | { 2, "CP-102 series", MXSER_HIGHBAUD }, |
122 | { 4, "CP-104U series", }, /* CP104U */ | 128 | { 4, "CP-104U series", }, |
123 | { 8, "CP-168U series", }, /* CP168U */ | 129 | { 8, "CP-168U series", }, |
124 | { 2, "CP-132U series", }, /* CP132U */ | 130 | { 2, "CP-132U series", }, |
125 | { 4, "CP-134U series", }, /* CP134U */ | 131 | /*15*/ { 4, "CP-134U series", }, |
126 | { 4, "CP-104JU series", }, /* CP104JU */ | 132 | { 4, "CP-104JU series", }, |
127 | { 8, "Moxa UC7000 Serial", }, /* RC7000 */ | 133 | { 8, "Moxa UC7000 Serial", }, /* RC7000 */ |
128 | { 8, "CP-118U series", }, /* CP118U */ | 134 | { 8, "CP-118U series", }, |
129 | { 2, "CP-102UL series", }, /* CP102UL */ | 135 | { 2, "CP-102UL series", }, |
130 | { 2, "CP-102U series", }, /* CP102U */ | 136 | /*20*/ { 2, "CP-102U series", }, |
131 | { 8, "CP-118EL series", }, /* CP118EL */ | 137 | { 8, "CP-118EL series", }, |
132 | { 8, "CP-168EL series", }, /* CP168EL */ | 138 | { 8, "CP-168EL series", }, |
133 | { 4, "CP-104EL series", } /* CP104EL */ | 139 | { 4, "CP-104EL series", }, |
140 | { 8, "CB-108 series", }, | ||
141 | /*25*/ { 4, "CB-114 series", }, | ||
142 | { 4, "CB-134I series", }, | ||
143 | { 8, "CP-138U series", }, | ||
144 | { 4, "POS-104UL series", } | ||
134 | }; | 145 | }; |
135 | 146 | ||
136 | /* driver_data correspond to the lines in the structure above | 147 | /* driver_data correspond to the lines in the structure above |
137 | see also ISA probe function before you change something */ | 148 | see also ISA probe function before you change something */ |
138 | static struct pci_device_id mxser_pcibrds[] = { | 149 | static struct pci_device_id mxser_pcibrds[] = { |
139 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), | 150 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, |
140 | .driver_data = 3 }, | 151 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, |
141 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104), | 152 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, |
142 | .driver_data = 4 }, | 153 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, |
143 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132), | 154 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, |
144 | .driver_data = 8 }, | 155 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, |
145 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114), | 156 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, |
146 | .driver_data = 9 }, | 157 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, |
147 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114), | 158 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, |
148 | .driver_data = 10 }, | 159 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, |
149 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102), | 160 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, |
150 | .driver_data = 11 }, | 161 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, |
151 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U), | 162 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, |
152 | .driver_data = 12 }, | 163 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, |
153 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U), | 164 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, |
154 | .driver_data = 13 }, | 165 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, |
155 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U), | 166 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, |
156 | .driver_data = 14 }, | 167 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, |
157 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U), | 168 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, |
158 | .driver_data = 15 }, | 169 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, |
159 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU), | 170 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, |
160 | .driver_data = 16 }, | 171 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, |
161 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000), | 172 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, |
162 | .driver_data = 17 }, | ||
163 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U), | ||
164 | .driver_data = 18 }, | ||
165 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL), | ||
166 | .driver_data = 19 }, | ||
167 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U), | ||
168 | .driver_data = 20 }, | ||
169 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL), | ||
170 | .driver_data = 21 }, | ||
171 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL), | ||
172 | .driver_data = 22 }, | ||
173 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL), | ||
174 | .driver_data = 23 }, | ||
175 | { } | 173 | { } |
176 | }; | 174 | }; |
177 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); | 175 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 73de77105fea..706ff34728f1 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -318,7 +318,7 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT; | |||
318 | static int pty_limit_min = 0; | 318 | static int pty_limit_min = 0; |
319 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 319 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
320 | 320 | ||
321 | ctl_table pty_table[] = { | 321 | static struct ctl_table pty_table[] = { |
322 | { | 322 | { |
323 | .ctl_name = PTY_MAX, | 323 | .ctl_name = PTY_MAX, |
324 | .procname = "max", | 324 | .procname = "max", |
@@ -340,6 +340,27 @@ ctl_table pty_table[] = { | |||
340 | } | 340 | } |
341 | }; | 341 | }; |
342 | 342 | ||
343 | static struct ctl_table pty_kern_table[] = { | ||
344 | { | ||
345 | .ctl_name = KERN_PTY, | ||
346 | .procname = "pty", | ||
347 | .mode = 0555, | ||
348 | .child = pty_table, | ||
349 | }, | ||
350 | {} | ||
351 | }; | ||
352 | |||
353 | static struct ctl_table pty_root_table[] = { | ||
354 | { | ||
355 | .ctl_name = CTL_KERN, | ||
356 | .procname = "kernel", | ||
357 | .mode = 0555, | ||
358 | .child = pty_kern_table, | ||
359 | }, | ||
360 | {} | ||
361 | }; | ||
362 | |||
363 | |||
343 | static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | 364 | static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, |
344 | unsigned int cmd, unsigned long arg) | 365 | unsigned int cmd, unsigned long arg) |
345 | { | 366 | { |
@@ -404,6 +425,7 @@ static void __init unix98_pty_init(void) | |||
404 | panic("Couldn't register Unix98 pts driver"); | 425 | panic("Couldn't register Unix98 pts driver"); |
405 | 426 | ||
406 | pty_table[1].data = &ptm_driver->refcount; | 427 | pty_table[1].data = &ptm_driver->refcount; |
428 | register_sysctl_table(pty_root_table); | ||
407 | } | 429 | } |
408 | #else | 430 | #else |
409 | static inline void unix98_pty_init(void) { } | 431 | static inline void unix98_pty_init(void) { } |
diff --git a/drivers/char/random.c b/drivers/char/random.c index af274e5a25ee..1756b1f7cb72 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -649,7 +649,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness); | |||
649 | 649 | ||
650 | void add_interrupt_randomness(int irq) | 650 | void add_interrupt_randomness(int irq) |
651 | { | 651 | { |
652 | if (irq >= NR_IRQS || irq_timer_state[irq] == 0) | 652 | if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) |
653 | return; | 653 | return; |
654 | 654 | ||
655 | DEBUG_ENT("irq event %d\n", irq); | 655 | DEBUG_ENT("irq event %d\n", irq); |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 56cbba7b6ec0..7e6a3a413bb2 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -84,6 +84,7 @@ | |||
84 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
85 | #include <linux/ioport.h> | 85 | #include <linux/ioport.h> |
86 | #include <linux/delay.h> | 86 | #include <linux/delay.h> |
87 | #include <linux/completion.h> | ||
87 | #include <linux/wait.h> | 88 | #include <linux/wait.h> |
88 | #include <linux/pci.h> | 89 | #include <linux/pci.h> |
89 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
@@ -548,8 +549,8 @@ static void rp_handle_port(struct r_port *info) | |||
548 | static void rp_do_poll(unsigned long dummy) | 549 | static void rp_do_poll(unsigned long dummy) |
549 | { | 550 | { |
550 | CONTROLLER_t *ctlp; | 551 | CONTROLLER_t *ctlp; |
551 | int ctrl, aiop, ch, line, i; | 552 | int ctrl, aiop, ch, line; |
552 | unsigned int xmitmask; | 553 | unsigned int xmitmask, i; |
553 | unsigned int CtlMask; | 554 | unsigned int CtlMask; |
554 | unsigned char AiopMask; | 555 | unsigned char AiopMask; |
555 | Word_t bit; | 556 | Word_t bit; |
@@ -650,7 +651,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
650 | info->closing_wait = 3000; | 651 | info->closing_wait = 3000; |
651 | info->close_delay = 50; | 652 | info->close_delay = 50; |
652 | init_waitqueue_head(&info->open_wait); | 653 | init_waitqueue_head(&info->open_wait); |
653 | init_waitqueue_head(&info->close_wait); | 654 | init_completion(&info->close_wait); |
654 | info->flags &= ~ROCKET_MODE_MASK; | 655 | info->flags &= ~ROCKET_MODE_MASK; |
655 | switch (pc104[board][line]) { | 656 | switch (pc104[board][line]) { |
656 | case 422: | 657 | case 422: |
@@ -699,8 +700,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
699 | spin_lock_init(&info->slock); | 700 | spin_lock_init(&info->slock); |
700 | mutex_init(&info->write_mtx); | 701 | mutex_init(&info->write_mtx); |
701 | rp_table[line] = info; | 702 | rp_table[line] = info; |
702 | if (pci_dev) | 703 | tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : |
703 | tty_register_device(rocket_driver, line, &pci_dev->dev); | 704 | NULL); |
704 | } | 705 | } |
705 | 706 | ||
706 | /* | 707 | /* |
@@ -878,7 +879,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
878 | if (tty_hung_up_p(filp)) | 879 | if (tty_hung_up_p(filp)) |
879 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 880 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
880 | if (info->flags & ROCKET_CLOSING) { | 881 | if (info->flags & ROCKET_CLOSING) { |
881 | interruptible_sleep_on(&info->close_wait); | 882 | if (wait_for_completion_interruptible(&info->close_wait)) |
883 | return -ERESTARTSYS; | ||
882 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 884 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
883 | } | 885 | } |
884 | 886 | ||
@@ -983,8 +985,10 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
983 | return -ENOMEM; | 985 | return -ENOMEM; |
984 | 986 | ||
985 | if (info->flags & ROCKET_CLOSING) { | 987 | if (info->flags & ROCKET_CLOSING) { |
986 | interruptible_sleep_on(&info->close_wait); | 988 | retval = wait_for_completion_interruptible(&info->close_wait); |
987 | free_page(page); | 989 | free_page(page); |
990 | if (retval) | ||
991 | return retval; | ||
988 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 992 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
989 | } | 993 | } |
990 | 994 | ||
@@ -1176,7 +1180,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1176 | } | 1180 | } |
1177 | info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); | 1181 | info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); |
1178 | tty->closing = 0; | 1182 | tty->closing = 0; |
1179 | wake_up_interruptible(&info->close_wait); | 1183 | complete_all(&info->close_wait); |
1180 | atomic_dec(&rp_num_ports_open); | 1184 | atomic_dec(&rp_num_ports_open); |
1181 | 1185 | ||
1182 | #ifdef ROCKET_DEBUG_OPEN | 1186 | #ifdef ROCKET_DEBUG_OPEN |
@@ -1869,8 +1873,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1869 | int fast_clock = 0; | 1873 | int fast_clock = 0; |
1870 | int altChanRingIndicator = 0; | 1874 | int altChanRingIndicator = 0; |
1871 | int ports_per_aiop = 8; | 1875 | int ports_per_aiop = 8; |
1872 | int ret; | ||
1873 | unsigned int class_rev; | ||
1874 | WordIO_t ConfigIO = 0; | 1876 | WordIO_t ConfigIO = 0; |
1875 | ByteIO_t UPCIRingInd = 0; | 1877 | ByteIO_t UPCIRingInd = 0; |
1876 | 1878 | ||
@@ -1878,12 +1880,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1878 | return 0; | 1880 | return 0; |
1879 | 1881 | ||
1880 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); | 1882 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); |
1881 | ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | ||
1882 | |||
1883 | if (ret) { | ||
1884 | printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n"); | ||
1885 | return 0; | ||
1886 | } | ||
1887 | 1883 | ||
1888 | rcktpt_type[i] = ROCKET_TYPE_NORMAL; | 1884 | rcktpt_type[i] = ROCKET_TYPE_NORMAL; |
1889 | rocketModel[i].loadrm2 = 0; | 1885 | rocketModel[i].loadrm2 = 0; |
@@ -2037,8 +2033,9 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2037 | ports_per_aiop = 6; | 2033 | ports_per_aiop = 6; |
2038 | str = "6-port"; | 2034 | str = "6-port"; |
2039 | 2035 | ||
2040 | /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */ | 2036 | /* If revision is 1, the rocketmodem flash must be loaded. |
2041 | if ((class_rev & 0xFF) == 1) { | 2037 | * If it is 2 it is a "socketed" version. */ |
2038 | if (dev->revision == 1) { | ||
2042 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; | 2039 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; |
2043 | rocketModel[i].loadrm2 = 1; | 2040 | rocketModel[i].loadrm2 = 1; |
2044 | } else { | 2041 | } else { |
@@ -2053,7 +2050,7 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2053 | max_num_aiops = 1; | 2050 | max_num_aiops = 1; |
2054 | ports_per_aiop = 4; | 2051 | ports_per_aiop = 4; |
2055 | str = "4-port"; | 2052 | str = "4-port"; |
2056 | if ((class_rev & 0xFF) == 1) { | 2053 | if (dev->revision == 1) { |
2057 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; | 2054 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; |
2058 | rocketModel[i].loadrm2 = 1; | 2055 | rocketModel[i].loadrm2 = 1; |
2059 | } else { | 2056 | } else { |
@@ -2362,26 +2359,14 @@ static const struct tty_operations rocket_ops = { | |||
2362 | */ | 2359 | */ |
2363 | static int __init rp_init(void) | 2360 | static int __init rp_init(void) |
2364 | { | 2361 | { |
2365 | int retval, pci_boards_found, isa_boards_found, i; | 2362 | int ret = -ENOMEM, pci_boards_found, isa_boards_found, i; |
2366 | 2363 | ||
2367 | printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", | 2364 | printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", |
2368 | ROCKET_VERSION, ROCKET_DATE); | 2365 | ROCKET_VERSION, ROCKET_DATE); |
2369 | 2366 | ||
2370 | rocket_driver = alloc_tty_driver(MAX_RP_PORTS); | 2367 | rocket_driver = alloc_tty_driver(MAX_RP_PORTS); |
2371 | if (!rocket_driver) | 2368 | if (!rocket_driver) |
2372 | return -ENOMEM; | 2369 | goto err; |
2373 | |||
2374 | /* | ||
2375 | * Initialize the array of pointers to our own internal state | ||
2376 | * structures. | ||
2377 | */ | ||
2378 | memset(rp_table, 0, sizeof (rp_table)); | ||
2379 | memset(xmit_flags, 0, sizeof (xmit_flags)); | ||
2380 | |||
2381 | for (i = 0; i < MAX_RP_PORTS; i++) | ||
2382 | lineNumbers[i] = 0; | ||
2383 | nextLineNumber = 0; | ||
2384 | memset(rocketModel, 0, sizeof (rocketModel)); | ||
2385 | 2370 | ||
2386 | /* | 2371 | /* |
2387 | * If board 1 is non-zero, there is at least one ISA configured. If controller is | 2372 | * If board 1 is non-zero, there is at least one ISA configured. If controller is |
@@ -2396,8 +2381,11 @@ static int __init rp_init(void) | |||
2396 | 2381 | ||
2397 | /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ | 2382 | /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ |
2398 | if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { | 2383 | if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { |
2399 | printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller); | 2384 | printk(KERN_ERR "Unable to reserve IO region for first " |
2400 | return -EBUSY; | 2385 | "configured ISA RocketPort controller 0x%lx. " |
2386 | "Driver exiting\n", controller); | ||
2387 | ret = -EBUSY; | ||
2388 | goto err_tty; | ||
2401 | } | 2389 | } |
2402 | 2390 | ||
2403 | /* Store ISA variable retrieved from command line or .conf file. */ | 2391 | /* Store ISA variable retrieved from command line or .conf file. */ |
@@ -2434,15 +2422,14 @@ static int __init rp_init(void) | |||
2434 | rocket_driver->init_termios.c_ispeed = 9600; | 2422 | rocket_driver->init_termios.c_ispeed = 9600; |
2435 | rocket_driver->init_termios.c_ospeed = 9600; | 2423 | rocket_driver->init_termios.c_ospeed = 9600; |
2436 | #ifdef ROCKET_SOFT_FLOW | 2424 | #ifdef ROCKET_SOFT_FLOW |
2437 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 2425 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW; |
2438 | #endif | 2426 | #endif |
2439 | tty_set_operations(rocket_driver, &rocket_ops); | 2427 | tty_set_operations(rocket_driver, &rocket_ops); |
2440 | 2428 | ||
2441 | retval = tty_register_driver(rocket_driver); | 2429 | ret = tty_register_driver(rocket_driver); |
2442 | if (retval < 0) { | 2430 | if (ret < 0) { |
2443 | printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval); | 2431 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); |
2444 | put_tty_driver(rocket_driver); | 2432 | goto err_tty; |
2445 | return -1; | ||
2446 | } | 2433 | } |
2447 | 2434 | ||
2448 | #ifdef ROCKET_DEBUG_OPEN | 2435 | #ifdef ROCKET_DEBUG_OPEN |
@@ -2469,14 +2456,18 @@ static int __init rp_init(void) | |||
2469 | max_board = pci_boards_found + isa_boards_found; | 2456 | max_board = pci_boards_found + isa_boards_found; |
2470 | 2457 | ||
2471 | if (max_board == 0) { | 2458 | if (max_board == 0) { |
2472 | printk(KERN_INFO "No rocketport ports found; unloading driver.\n"); | 2459 | printk(KERN_ERR "No rocketport ports found; unloading driver\n"); |
2473 | del_timer_sync(&rocket_timer); | 2460 | ret = -ENXIO; |
2474 | tty_unregister_driver(rocket_driver); | 2461 | goto err_ttyu; |
2475 | put_tty_driver(rocket_driver); | ||
2476 | return -ENXIO; | ||
2477 | } | 2462 | } |
2478 | 2463 | ||
2479 | return 0; | 2464 | return 0; |
2465 | err_ttyu: | ||
2466 | tty_unregister_driver(rocket_driver); | ||
2467 | err_tty: | ||
2468 | put_tty_driver(rocket_driver); | ||
2469 | err: | ||
2470 | return ret; | ||
2480 | } | 2471 | } |
2481 | 2472 | ||
2482 | 2473 | ||
@@ -2491,10 +2482,14 @@ static void rp_cleanup_module(void) | |||
2491 | if (retval) | 2482 | if (retval) |
2492 | printk(KERN_INFO "Error %d while trying to unregister " | 2483 | printk(KERN_INFO "Error %d while trying to unregister " |
2493 | "rocketport driver\n", -retval); | 2484 | "rocketport driver\n", -retval); |
2494 | put_tty_driver(rocket_driver); | ||
2495 | 2485 | ||
2496 | for (i = 0; i < MAX_RP_PORTS; i++) | 2486 | for (i = 0; i < MAX_RP_PORTS; i++) |
2497 | kfree(rp_table[i]); | 2487 | if (rp_table[i]) { |
2488 | tty_unregister_device(rocket_driver, i); | ||
2489 | kfree(rp_table[i]); | ||
2490 | } | ||
2491 | |||
2492 | put_tty_driver(rocket_driver); | ||
2498 | 2493 | ||
2499 | for (i = 0; i < NUM_BOARDS; i++) { | 2494 | for (i = 0; i < NUM_BOARDS; i++) { |
2500 | if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) | 2495 | if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) |
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index b4c53dfa7951..55b8f2d71a96 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -1163,13 +1163,8 @@ struct r_port { | |||
1163 | int read_status_mask; | 1163 | int read_status_mask; |
1164 | int cps; | 1164 | int cps; |
1165 | 1165 | ||
1166 | #ifdef DECLARE_WAITQUEUE | ||
1167 | wait_queue_head_t open_wait; | 1166 | wait_queue_head_t open_wait; |
1168 | wait_queue_head_t close_wait; | 1167 | struct completion close_wait; |
1169 | #else | ||
1170 | struct wait_queue *open_wait; | ||
1171 | struct wait_queue *close_wait; | ||
1172 | #endif | ||
1173 | spinlock_t slock; | 1168 | spinlock_t slock; |
1174 | struct mutex write_mtx; | 1169 | struct mutex write_mtx; |
1175 | }; | 1170 | }; |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 745d552620bf..0def089cc1f2 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -228,7 +228,8 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); | |||
228 | * and will all go away once this is done. | 228 | * and will all go away once this is done. |
229 | */ | 229 | */ |
230 | 230 | ||
231 | void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) | 231 | void tty_termios_encode_baud_rate(struct ktermios *termios, |
232 | speed_t ibaud, speed_t obaud) | ||
232 | { | 233 | { |
233 | int i = 0; | 234 | int i = 0; |
234 | int ifound = -1, ofound = -1; | 235 | int ifound = -1, ofound = -1; |
@@ -263,11 +264,15 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed | |||
263 | */ | 264 | */ |
264 | 265 | ||
265 | do { | 266 | do { |
266 | if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { | 267 | if (obaud - oclose <= baud_table[i] && |
268 | obaud + oclose >= baud_table[i]) { | ||
267 | termios->c_cflag |= baud_bits[i]; | 269 | termios->c_cflag |= baud_bits[i]; |
268 | ofound = i; | 270 | ofound = i; |
269 | } | 271 | } |
270 | if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { | 272 | if (ibaud - iclose <= baud_table[i] && |
273 | ibaud + iclose >= baud_table[i]) { | ||
274 | /* For the case input == output don't set IBAUD bits | ||
275 | if the user didn't do so */ | ||
271 | if (ofound == i && !ibinput) | 276 | if (ofound == i && !ibinput) |
272 | ifound = i; | 277 | ifound = i; |
273 | #ifdef IBSHIFT | 278 | #ifdef IBSHIFT |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 645ad9808982..1764c67b585f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -158,11 +158,7 @@ static void blank_screen_t(unsigned long dummy); | |||
158 | static void set_palette(struct vc_data *vc); | 158 | static void set_palette(struct vc_data *vc); |
159 | 159 | ||
160 | static int printable; /* Is console ready for printing? */ | 160 | static int printable; /* Is console ready for printing? */ |
161 | #ifdef CONFIG_VT_UNICODE | 161 | int default_utf8 = true; |
162 | int default_utf8 = 1; | ||
163 | #else | ||
164 | int default_utf8; | ||
165 | #endif | ||
166 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | 162 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); |
167 | 163 | ||
168 | /* | 164 | /* |