* 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
/*
* Include section
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
+#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
-#include <asm/bitops.h>
#define CY_LOCK(info,flags) \
do { \
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 */
* 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
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);
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);
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<<index));
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
info->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<<index));
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
info->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<<index));
+ /* Pieces of seven... */
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
info->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<<index));
- info->icount.rx++;
- }
+ tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
+ info->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{
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<<index));
- *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++;
#ifdef CY_16Y_HACK
}
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<<index), (save_xir & 0x3f));
struct cyclades_card *cinfo = &cy_card[info->card];
struct tty_struct *tty = info->tty;
volatile int char_count;
+ int len;
#ifdef BLOCKMOVE
int small_count;
#else
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++;
}
}
#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);
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;
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);
}
}
#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
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);
*
*/
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;
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;
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);
/* 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);
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 {
/* 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);
/* 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);
/* 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);
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;
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");