diff options
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r-- | drivers/char/cyclades.c | 89 |
1 files changed, 27 insertions, 62 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index c8e7daecad72..39c61a71176e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -641,6 +641,7 @@ static char rcsid[] = | |||
641 | #include <linux/timer.h> | 641 | #include <linux/timer.h> |
642 | #include <linux/interrupt.h> | 642 | #include <linux/interrupt.h> |
643 | #include <linux/tty.h> | 643 | #include <linux/tty.h> |
644 | #include <linux/tty_flip.h> | ||
644 | #include <linux/serial.h> | 645 | #include <linux/serial.h> |
645 | #include <linux/major.h> | 646 | #include <linux/major.h> |
646 | #include <linux/string.h> | 647 | #include <linux/string.h> |
@@ -1086,7 +1087,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1086 | int had_work; | 1087 | int had_work; |
1087 | int mdm_change; | 1088 | int mdm_change; |
1088 | int mdm_status; | 1089 | int mdm_status; |
1089 | 1090 | int len; | |
1090 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ | 1091 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ |
1091 | #ifdef CY_DEBUG_INTERRUPTS | 1092 | #ifdef CY_DEBUG_INTERRUPTS |
1092 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | 1093 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); |
@@ -1163,63 +1164,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1163 | info->icount.rx++; | 1164 | info->icount.rx++; |
1164 | continue; | 1165 | continue; |
1165 | } | 1166 | } |
1166 | if (tty->flip.count < TTY_FLIPBUF_SIZE){ | 1167 | if (tty_buffer_request_room(tty, 1)) { |
1167 | tty->flip.count++; | ||
1168 | if (data & info->read_status_mask){ | 1168 | if (data & info->read_status_mask){ |
1169 | if(data & CyBREAK){ | 1169 | if(data & CyBREAK){ |
1170 | *tty->flip.flag_buf_ptr++ = | 1170 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK); |
1171 | TTY_BREAK; | ||
1172 | *tty->flip.char_buf_ptr++ = | ||
1173 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1174 | info->icount.rx++; | 1171 | info->icount.rx++; |
1175 | if (info->flags & ASYNC_SAK){ | 1172 | if (info->flags & ASYNC_SAK){ |
1176 | do_SAK(tty); | 1173 | do_SAK(tty); |
1177 | } | 1174 | } |
1178 | }else if(data & CyFRAME){ | 1175 | }else if(data & CyFRAME){ |
1179 | *tty->flip.flag_buf_ptr++ = | 1176 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1180 | TTY_FRAME; | ||
1181 | *tty->flip.char_buf_ptr++ = | ||
1182 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1183 | info->icount.rx++; | 1177 | info->icount.rx++; |
1184 | info->idle_stats.frame_errs++; | 1178 | info->idle_stats.frame_errs++; |
1185 | }else if(data & CyPARITY){ | 1179 | }else if(data & CyPARITY){ |
1186 | *tty->flip.flag_buf_ptr++ = | 1180 | /* Pieces of seven... */ |
1187 | TTY_PARITY; | 1181 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY); |
1188 | *tty->flip.char_buf_ptr++ = | ||
1189 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1190 | info->icount.rx++; | 1182 | info->icount.rx++; |
1191 | info->idle_stats.parity_errs++; | 1183 | info->idle_stats.parity_errs++; |
1192 | }else if(data & CyOVERRUN){ | 1184 | }else if(data & CyOVERRUN){ |
1193 | *tty->flip.flag_buf_ptr++ = | 1185 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1194 | TTY_OVERRUN; | ||
1195 | *tty->flip.char_buf_ptr++ = 0; | ||
1196 | info->icount.rx++; | 1186 | info->icount.rx++; |
1197 | /* If the flip buffer itself is | 1187 | /* If the flip buffer itself is |
1198 | overflowing, we still lose | 1188 | overflowing, we still lose |
1199 | the next incoming character. | 1189 | the next incoming character. |
1200 | */ | 1190 | */ |
1201 | if(tty->flip.count | 1191 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); |
1202 | < TTY_FLIPBUF_SIZE){ | 1192 | info->icount.rx++; |
1203 | tty->flip.count++; | ||
1204 | *tty->flip.flag_buf_ptr++ = | ||
1205 | TTY_NORMAL; | ||
1206 | *tty->flip.char_buf_ptr++ = | ||
1207 | cy_readb(base_addr+(CyRDSR<<index)); | ||
1208 | info->icount.rx++; | ||
1209 | } | ||
1210 | info->idle_stats.overruns++; | 1193 | info->idle_stats.overruns++; |
1211 | /* These two conditions may imply */ | 1194 | /* These two conditions may imply */ |
1212 | /* a normal read should be done. */ | 1195 | /* a normal read should be done. */ |
1213 | /* }else if(data & CyTIMEOUT){ */ | 1196 | /* }else if(data & CyTIMEOUT){ */ |
1214 | /* }else if(data & CySPECHAR){ */ | 1197 | /* }else if(data & CySPECHAR){ */ |
1215 | }else{ | 1198 | }else { |
1216 | *tty->flip.flag_buf_ptr++ = 0; | 1199 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1217 | *tty->flip.char_buf_ptr++ = 0; | 1200 | info->icount.rx++; |
1218 | info->icount.rx++; | ||
1219 | } | 1201 | } |
1220 | }else{ | 1202 | }else{ |
1221 | *tty->flip.flag_buf_ptr++ = 0; | 1203 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1222 | *tty->flip.char_buf_ptr++ = 0; | ||
1223 | info->icount.rx++; | 1204 | info->icount.rx++; |
1224 | } | 1205 | } |
1225 | }else{ | 1206 | }else{ |
@@ -1240,14 +1221,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1240 | info->mon.char_max = char_count; | 1221 | info->mon.char_max = char_count; |
1241 | info->mon.char_last = char_count; | 1222 | info->mon.char_last = char_count; |
1242 | #endif | 1223 | #endif |
1243 | while(char_count--){ | 1224 | len = tty_buffer_request_room(tty, char_count); |
1244 | if (tty->flip.count >= TTY_FLIPBUF_SIZE){ | 1225 | while(len--){ |
1245 | break; | ||
1246 | } | ||
1247 | tty->flip.count++; | ||
1248 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1226 | data = cy_readb(base_addr+(CyRDSR<<index)); |
1249 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | 1227 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1250 | *tty->flip.char_buf_ptr++ = data; | ||
1251 | info->idle_stats.recv_bytes++; | 1228 | info->idle_stats.recv_bytes++; |
1252 | info->icount.rx++; | 1229 | info->icount.rx++; |
1253 | #ifdef CY_16Y_HACK | 1230 | #ifdef CY_16Y_HACK |
@@ -1256,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1256 | } | 1233 | } |
1257 | info->idle_stats.recv_idle = jiffies; | 1234 | info->idle_stats.recv_idle = jiffies; |
1258 | } | 1235 | } |
1259 | schedule_delayed_work(&tty->flip.work, 1); | 1236 | schedule_delayed_work(&tty->buf.work, 1); |
1260 | } | 1237 | } |
1261 | /* end of service */ | 1238 | /* end of service */ |
1262 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); | 1239 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); |
@@ -1551,6 +1528,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1551 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1528 | struct cyclades_card *cinfo = &cy_card[info->card]; |
1552 | struct tty_struct *tty = info->tty; | 1529 | struct tty_struct *tty = info->tty; |
1553 | volatile int char_count; | 1530 | volatile int char_count; |
1531 | int len; | ||
1554 | #ifdef BLOCKMOVE | 1532 | #ifdef BLOCKMOVE |
1555 | int small_count; | 1533 | int small_count; |
1556 | #else | 1534 | #else |
@@ -1606,18 +1584,11 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1606 | tty->flip.count += small_count; | 1584 | tty->flip.count += small_count; |
1607 | } | 1585 | } |
1608 | #else | 1586 | #else |
1609 | while(char_count--){ | 1587 | len = tty_buffer_request_room(tty, char_count); |
1610 | if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt) | 1588 | while(len--){ |
1611 | break; | ||
1612 | |||
1613 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
1614 | break; | ||
1615 | |||
1616 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); | 1589 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); |
1617 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); | 1590 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); |
1618 | tty->flip.count++; | 1591 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1619 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
1620 | *tty->flip.char_buf_ptr++ = data; | ||
1621 | info->idle_stats.recv_bytes++; | 1592 | info->idle_stats.recv_bytes++; |
1622 | info->icount.rx++; | 1593 | info->icount.rx++; |
1623 | } | 1594 | } |
@@ -1635,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1635 | } | 1606 | } |
1636 | #endif | 1607 | #endif |
1637 | info->idle_stats.recv_idle = jiffies; | 1608 | info->idle_stats.recv_idle = jiffies; |
1638 | schedule_delayed_work(&tty->flip.work, 1); | 1609 | schedule_delayed_work(&tty->buf.work, 1); |
1639 | } | 1610 | } |
1640 | /* Update rx_get */ | 1611 | /* Update rx_get */ |
1641 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1612 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
@@ -1763,23 +1734,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1763 | 1734 | ||
1764 | switch(cmd) { | 1735 | switch(cmd) { |
1765 | case C_CM_PR_ERROR: | 1736 | case C_CM_PR_ERROR: |
1766 | tty->flip.count++; | 1737 | tty_insert_flip_char(tty, 0, TTY_PARITY); |
1767 | *tty->flip.flag_buf_ptr++ = TTY_PARITY; | ||
1768 | *tty->flip.char_buf_ptr++ = 0; | ||
1769 | info->icount.rx++; | 1738 | info->icount.rx++; |
1770 | special_count++; | 1739 | special_count++; |
1771 | break; | 1740 | break; |
1772 | case C_CM_FR_ERROR: | 1741 | case C_CM_FR_ERROR: |
1773 | tty->flip.count++; | 1742 | tty_insert_flip_char(tty, 0, TTY_FRAME); |
1774 | *tty->flip.flag_buf_ptr++ = TTY_FRAME; | ||
1775 | *tty->flip.char_buf_ptr++ = 0; | ||
1776 | info->icount.rx++; | 1743 | info->icount.rx++; |
1777 | special_count++; | 1744 | special_count++; |
1778 | break; | 1745 | break; |
1779 | case C_CM_RXBRK: | 1746 | case C_CM_RXBRK: |
1780 | tty->flip.count++; | 1747 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1781 | *tty->flip.flag_buf_ptr++ = TTY_BREAK; | ||
1782 | *tty->flip.char_buf_ptr++ = 0; | ||
1783 | info->icount.rx++; | 1748 | info->icount.rx++; |
1784 | special_count++; | 1749 | special_count++; |
1785 | break; | 1750 | break; |
@@ -1844,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1844 | if(delta_count) | 1809 | if(delta_count) |
1845 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1810 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); |
1846 | if(special_count) | 1811 | if(special_count) |
1847 | schedule_delayed_work(&tty->flip.work, 1); | 1812 | schedule_delayed_work(&tty->buf.work, 1); |
1848 | } | 1813 | } |
1849 | } | 1814 | } |
1850 | 1815 | ||