X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fcyclades.c;h=c1c67281750da61ef1750706bb8351e780cb3e43;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=6ceaee64b2697f00286642cdf4cee2aae2d7eb4e;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 6ceaee64b..c1c672817 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -281,7 +281,7 @@ static char rcsid[] = * make sure "cyc" appears in all kernel messages; all soft interrupts * handled by same routine; recognize out-of-band reception; comment * out some diagnostic messages; leave RTS/CTS flow control to hardware; - * fix race condition in -Z buffer management; only -Y needs to explictly + * fix race condition in -Z buffer management; only -Y needs to explicitly * flush chars; tidy up some startup messages; * * Revision 1.36.4.18 1996/07/25 18:57:31 bentson @@ -633,7 +633,6 @@ static char rcsid[] = /* * Include section */ -#include #include #include #include @@ -641,6 +640,7 @@ static char rcsid[] = #include #include #include +#include #include #include #include @@ -652,12 +652,12 @@ static char rcsid[] = #include #include #include +#include #include #include #include #include -#include #define CY_LOCK(info,flags) \ do { \ @@ -723,14 +723,14 @@ static unsigned int cy_isa_addresses[] = { 0xDE000, 0,0,0,0,0,0,0,0 }; -#define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*)) +#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) #ifdef MODULE static long maddr[NR_CARDS] = { 0, }; static int irq[NR_CARDS] = { 0, }; -MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l"); -MODULE_PARM(irq, "1-" __MODULE_STRING(NR_CARDS) "i"); +module_param_array(maddr, long, NULL, 0); +module_param_array(irq, int, NULL, 0); #endif #endif /* CONFIG_ISA */ @@ -758,7 +758,6 @@ static int cy_next_channel; /* next minor available */ * allocated when the first cy_open occurs. */ static unsigned char *tmp_buf; -DECLARE_MUTEX(tmp_buf_sem); /* * This is used to look up the divisor speeds and the timeouts @@ -866,7 +865,7 @@ static void cyz_poll(unsigned long); static long cyz_polling_cycle = CZ_DEF_POLL; static int cyz_timeron = 0; -static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0); +static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); #else /* CONFIG_CYZ_INTR */ static void cyz_rx_restart(unsigned long); @@ -1087,7 +1086,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) int had_work; int mdm_change; int mdm_status; - + int len; if((cinfo = (struct cyclades_card *)dev_id) == 0){ #ifdef CY_DEBUG_INTERRUPTS printk("cyy_interrupt: spurious interrupt %d\n\r", irq); @@ -1164,63 +1163,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) info->icount.rx++; continue; } - if (tty->flip.count < TTY_FLIPBUF_SIZE){ - tty->flip.count++; + if (tty_buffer_request_room(tty, 1)) { if (data & info->read_status_mask){ if(data & CyBREAK){ - *tty->flip.flag_buf_ptr++ = - TTY_BREAK; - *tty->flip.char_buf_ptr++ = - cy_readb(base_addr+(CyRDSR<icount.rx++; if (info->flags & ASYNC_SAK){ do_SAK(tty); } }else if(data & CyFRAME){ - *tty->flip.flag_buf_ptr++ = - TTY_FRAME; - *tty->flip.char_buf_ptr++ = - cy_readb(base_addr+(CyRDSR<icount.rx++; info->idle_stats.frame_errs++; }else if(data & CyPARITY){ - *tty->flip.flag_buf_ptr++ = - TTY_PARITY; - *tty->flip.char_buf_ptr++ = - cy_readb(base_addr+(CyRDSR<icount.rx++; info->idle_stats.parity_errs++; }else if(data & CyOVERRUN){ - *tty->flip.flag_buf_ptr++ = - TTY_OVERRUN; - *tty->flip.char_buf_ptr++ = 0; + tty_insert_flip_char(tty, 0, TTY_OVERRUN); info->icount.rx++; /* If the flip buffer itself is overflowing, we still lose the next incoming character. */ - if(tty->flip.count - < TTY_FLIPBUF_SIZE){ - tty->flip.count++; - *tty->flip.flag_buf_ptr++ = - TTY_NORMAL; - *tty->flip.char_buf_ptr++ = - cy_readb(base_addr+(CyRDSR<icount.rx++; - } + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<icount.rx++; info->idle_stats.overruns++; /* These two conditions may imply */ /* a normal read should be done. */ /* }else if(data & CyTIMEOUT){ */ /* }else if(data & CySPECHAR){ */ - }else{ - *tty->flip.flag_buf_ptr++ = 0; - *tty->flip.char_buf_ptr++ = 0; - info->icount.rx++; + }else { + tty_insert_flip_char(tty, 0, TTY_NORMAL); + info->icount.rx++; } }else{ - *tty->flip.flag_buf_ptr++ = 0; - *tty->flip.char_buf_ptr++ = 0; + tty_insert_flip_char(tty, 0, TTY_NORMAL); info->icount.rx++; } }else{ @@ -1241,14 +1220,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) info->mon.char_max = char_count; info->mon.char_last = char_count; #endif - while(char_count--){ - if (tty->flip.count >= TTY_FLIPBUF_SIZE){ - break; - } - tty->flip.count++; + len = tty_buffer_request_room(tty, char_count); + while(len--){ data = cy_readb(base_addr+(CyRDSR<flip.flag_buf_ptr++ = TTY_NORMAL; - *tty->flip.char_buf_ptr++ = data; + tty_insert_flip_char(tty, data, TTY_NORMAL); info->idle_stats.recv_bytes++; info->icount.rx++; #ifdef CY_16Y_HACK @@ -1257,7 +1232,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) } info->idle_stats.recv_idle = jiffies; } - schedule_delayed_work(&tty->flip.work, 1); + tty_schedule_flip(tty); } /* end of service */ cy_writeb(base_addr+(CyRIR<card]; struct tty_struct *tty = info->tty; volatile int char_count; + int len; #ifdef BLOCKMOVE int small_count; #else @@ -1607,18 +1583,11 @@ cyz_handle_rx(struct cyclades_port *info, tty->flip.count += small_count; } #else - while(char_count--){ - if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt) - break; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - + len = tty_buffer_request_room(tty, char_count); + while(len--){ data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); - tty->flip.count++; - *tty->flip.flag_buf_ptr++ = TTY_NORMAL; - *tty->flip.char_buf_ptr++ = data; + tty_insert_flip_char(tty, data, TTY_NORMAL); info->idle_stats.recv_bytes++; info->icount.rx++; } @@ -1636,7 +1605,7 @@ cyz_handle_rx(struct cyclades_port *info, } #endif info->idle_stats.recv_idle = jiffies; - schedule_delayed_work(&tty->flip.work, 1); + tty_schedule_flip(tty); } /* Update rx_get */ cy_writel(&buf_ctrl->rx_get, new_rx_get); @@ -1764,23 +1733,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo) switch(cmd) { case C_CM_PR_ERROR: - tty->flip.count++; - *tty->flip.flag_buf_ptr++ = TTY_PARITY; - *tty->flip.char_buf_ptr++ = 0; + tty_insert_flip_char(tty, 0, TTY_PARITY); info->icount.rx++; special_count++; break; case C_CM_FR_ERROR: - tty->flip.count++; - *tty->flip.flag_buf_ptr++ = TTY_FRAME; - *tty->flip.char_buf_ptr++ = 0; + tty_insert_flip_char(tty, 0, TTY_FRAME); info->icount.rx++; special_count++; break; case C_CM_RXBRK: - tty->flip.count++; - *tty->flip.flag_buf_ptr++ = TTY_BREAK; - *tty->flip.char_buf_ptr++ = 0; + tty_insert_flip_char(tty, 0, TTY_BREAK); info->icount.rx++; special_count++; break; @@ -1845,7 +1808,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) if(delta_count) cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); if(special_count) - schedule_delayed_work(&tty->flip.work, 1); + tty_schedule_flip(tty); } } @@ -2690,20 +2653,16 @@ cy_wait_until_sent(struct tty_struct *tty, int timeout) #ifdef CY_DEBUG_WAIT_UNTIL_SENT printk("Not clean (jiff=%lu)...", jiffies); #endif - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(char_time); - if (signal_pending(current)) + if (msleep_interruptible(jiffies_to_msecs(char_time))) break; if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } - current->state = TASK_RUNNING; } else { // Nothing to do! } /* Run one more char cycle */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(char_time * 5); + msleep_interruptible(jiffies_to_msecs(char_time * 5)); #ifdef CY_DEBUG_WAIT_UNTIL_SENT printk("Clean (jiff=%lu)...done\n", jiffies); #endif @@ -2828,8 +2787,7 @@ cy_close(struct tty_struct *tty, struct file *filp) if (info->blocked_open) { CY_UNLOCK(info, flags); if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); + msleep_interruptible(jiffies_to_msecs(info->close_delay)); } wake_up_interruptible(&info->open_wait); CY_LOCK(info, flags); @@ -2860,8 +2818,7 @@ cy_close(struct tty_struct *tty, struct file *filp) * */ static int -cy_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) +cy_write(struct tty_struct * tty, const unsigned char *buf, int count) { struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; @@ -2875,60 +2832,25 @@ cy_write(struct tty_struct * tty, int from_user, return 0; } - if (!tty || !info->xmit_buf || !tmp_buf){ - return 0; - } - - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - - c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), - (int)(SERIAL_XMIT_SIZE - info->xmit_head))); - if (c <= 0) - break; + if (!info->xmit_buf || !tmp_buf) + return 0; - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) { - ret = -EFAULT; - } - break; - } - CY_LOCK(info, flags); - c1 = min(c, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), - (int)(SERIAL_XMIT_SIZE - info->xmit_head))); - - if (c1 < c) - c = c1; - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - CY_UNLOCK(info, flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - CY_LOCK(info, flags); - while (1) { - c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), + CY_LOCK(info, flags); + while (1) { + c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), (int)(SERIAL_XMIT_SIZE - info->xmit_head))); - if (c <= 0) - break; + if (c <= 0) + break; - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt += c; - buf += c; - count -= c; - ret += c; - } - CY_UNLOCK(info, flags); + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + buf += c; + count -= c; + ret += c; } + CY_UNLOCK(info, flags); info->idle_stats.xmit_bytes += ret; info->idle_stats.xmit_idle = jiffies; @@ -2960,7 +2882,7 @@ cy_put_char(struct tty_struct *tty, unsigned char ch) if (serial_paranoia_check(info, tty->name, "cy_put_char")) return; - if (!tty || !info->xmit_buf) + if (!info->xmit_buf) return; CY_LOCK(info, flags); @@ -4690,7 +4612,7 @@ cy_detect_isa(void) /* allocate IRQ */ if(request_irq(cy_isa_irq, cyy_interrupt, - SA_INTERRUPT, "Cyclom-Y", &cy_card[j])) + IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { printk("Cyclom-Y/ISA found at 0x%lx ", (unsigned long) cy_isa_address); @@ -4765,7 +4687,7 @@ cy_detect_pci(void) for (i = 0; i < NR_CARDS; i++) { /* look for a Cyclades card by vendor and device id */ while((device_id = cy_pci_dev_id[dev_index]) != 0) { - if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES, + if((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, device_id, pdev)) == NULL) { dev_index++; /* try next device id */ } else { @@ -4863,7 +4785,7 @@ cy_detect_pci(void) /* allocate IRQ */ if(request_irq(cy_pci_irq, cyy_interrupt, - SA_SHIRQ, "Cyclom-Y", &cy_card[j])) + IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { printk("Cyclom-Y/PCI found at 0x%lx ", (ulong) cy_pci_phys2); @@ -5043,7 +4965,7 @@ cy_detect_pci(void) /* allocate IRQ only if board has an IRQ */ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) { if(request_irq(cy_pci_irq, cyz_interrupt, - SA_SHIRQ, "Cyclades-Z", &cy_card[j])) + IRQF_SHARED, "Cyclades-Z", &cy_card[j])) { printk("Cyclom-8Zo/PCI found at 0x%lx ", (ulong) cy_pci_phys2); @@ -5137,7 +5059,7 @@ cy_detect_pci(void) /* allocate IRQ only if board has an IRQ */ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) { if(request_irq(cy_pci_irq, cyz_interrupt, - SA_SHIRQ, "Cyclades-Z", &cy_card[j])) + IRQF_SHARED, "Cyclades-Z", &cy_card[j])) { printk("Cyclom-Ze/PCI found at 0x%lx ", (ulong) cy_pci_phys2); @@ -5327,7 +5249,6 @@ cy_init(void) cy_serial_driver->owner = THIS_MODULE; cy_serial_driver->driver_name = "cyclades"; cy_serial_driver->name = "ttyC"; - cy_serial_driver->devfs_name = "tts/C"; cy_serial_driver->major = CYCLADES_MAJOR; cy_serial_driver->minor_start = 0; cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; @@ -5578,24 +5499,4 @@ cy_cleanup_module(void) module_init(cy_init); module_exit(cy_cleanup_module); -#ifndef MODULE -/* called by linux/init/main.c to parse command line options */ -void -cy_setup(char *str, int *ints) -{ -#ifdef CONFIG_ISA - int i, j; - - for (i = 0 ; i < NR_ISA_ADDRS ; i++) { - if (cy_isa_addresses[i] == 0) break; - } - for (j = 1; j <= ints[0]; j++){ - if ( i < NR_ISA_ADDRS ){ - cy_isa_addresses[i++] = (unsigned char *)(ints[j]); - } - } -#endif /* CONFIG_ISA */ -} /* cy_setup */ -#endif /* MODULE */ - MODULE_LICENSE("GPL");