patch-2.2.10 linux/drivers/char/cyclades.c
Next file: linux/drivers/char/n_hdlc.c
Previous file: linux/drivers/char/bttv.h
Back to the patch index
Back to the overall index
- Lines: 763
- Date:
Mon May 24 22:38:02 1999
- Orig file:
v2.2.9/linux/drivers/char/cyclades.c
- Orig date:
Fri Apr 16 14:47:30 1999
diff -u --recursive --new-file v2.2.9/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
@@ -1,7 +1,7 @@
#define BLOCKMOVE
#define Z_WAKE
static char rcsid[] =
-"$Revision: 2.2.2.1 $$Date: 1999/04/08 16:17:43 $";
+"$Revision: 2.2.2.2 $$Date: 1999/05/21 17:18:15 $";
/*
* linux/drivers/char/cyclades.c
@@ -21,7 +21,7 @@
* extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
* and then fixed as suggested by Michael K. Johnson 12/12/92.
*
- * This version does not support shared irq's.
+ * This version supports shared IRQ's (only for PCI boards).
*
* This module exports the following rs232 io functions:
* int cy_init(void);
@@ -31,6 +31,17 @@
* void cleanup_module(void);
*
* $Log: cyclades.c,v $
+ * Revision 2.2.2.2 1999/05/14 17:18:15 ivan
+ * /proc entry location changed to /proc/tty/driver/cyclades;
+ * Added support to shared IRQ's (only for PCI boards);
+ * Added support for Cobalt Qube2 systems;
+ * IRQ [de]allocation scheme revisited;
+ * BREAK implementation changed in order to make use of the 'break_ctl'
+ * TTY facility;
+ * Fixed typo in TTY structure field 'driver_name';
+ * Included a PCI bridge reset and EEPROM reload in the board
+ * initialization code (for both Y and Z series).
+ *
* Revision 2.2.2.1 1999/04/08 16:17:43 ivan
* Fixed a bug in cy_wait_until_sent that was preventing the port to be
* closed properly after a SIGINT;
@@ -536,7 +547,7 @@
#undef CY_16Y_HACK
#undef CY_ENABLE_MONITORING
#undef CY_PCI_DEBUG
-#define CY_PROC
+#undef CY_PROC
#if 0
#define PAUSE __asm__("nop");
@@ -600,6 +611,14 @@
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#ifdef CONFIG_COBALT_27
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & \
+ (unsigned long)0x1fffffff) + KSEG1)
+#endif
+
#define cy_put_user put_user
static unsigned long cy_get_user(unsigned long *addr)
@@ -638,6 +657,7 @@
static struct tty_driver cy_serial_driver, cy_callout_driver;
static int serial_refcount;
+#ifndef CONFIG_COBALT_27
static volatile int cy_irq_triggered;
static volatile int cy_triggered;
static int cy_wild_int_mask;
@@ -665,6 +685,8 @@
};
#define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
+#endif /* CONFIG_COBALT_27 */
+
/* This is the per-card data structure containing address, irq, number of
channels, etc. This driver supports a maximum of NR_CARDS cards.
*/
@@ -681,11 +703,6 @@
static struct termios *serial_termios[NR_PORTS];
static struct termios *serial_termios_locked[NR_PORTS];
-/* This is the per-irq data structure,
- it maps an irq to the corresponding card */
-
-static struct cyclades_card *IRQ_cards[NR_IRQS];
-
/*
* tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the copy_from_user blocks while swapping in a page,
@@ -790,7 +807,9 @@
static void cy_start(struct tty_struct *);
static void set_line_char(struct cyclades_port *);
+#ifndef CONFIG_COBALT_27
static void cy_probe(int, void *, struct pt_regs *);
+#endif /* CONFIG_COBALT_27 */
static void cyz_poll(unsigned long);
#ifdef CYCLOM_SHOW_STATUS
static void show_status(int);
@@ -959,6 +978,8 @@
return(0);
} /* cyy_issue_cmd */
+#ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */
+
static int probe_ready;
/*
@@ -1149,6 +1170,8 @@
return;
} /* cy_probe */
+#endif /* CONFIG_COBALT_27 */
+
/* The real interrupt service routine is called
whenever the card wants its hand held--chars
received, out buffer empty, modem change, etc.
@@ -1172,9 +1195,9 @@
int mdm_change;
int mdm_status;
- if((cinfo = IRQ_cards[irq]) == 0){
+ if((cinfo = (struct cyclades_card *)dev_id) == 0){
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: spurious interrupt %d\n\r", irq);
+ printk("cy_interrupt: spurious interrupt %d\n\r", irq);
#endif
return; /* spurious interrupt */
}
@@ -1206,7 +1229,7 @@
}
if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
+ printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
#endif
/* determine the channel & change to that context */
save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
@@ -1333,7 +1356,7 @@
is empty, we know we can always stuff a dozen
characters. */
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
+ printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
#endif
/* determine the channel & change to that context */
@@ -1368,37 +1391,19 @@
info->x_char = 0;
}
- if (info->x_break){
- /* The Cirrus chip requires the "Embedded
- Transmit Commands" of start break, delay,
- and end break sequences to be sent. The
- duration of the break is given in TICs,
- which runs at HZ (typically 100) and the
- PPR runs at 200 Hz, so the delay is
- duration * 200/HZ, and thus a break can
- run from 1/100 sec to about 5/4 sec.
- For CD1400 J or later, replace the 200 Hz
- by 500 Hz.
- */
- /* start break */
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
- /* delay a bit */
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0x82);
- if (info->chip_rev >= CD1400_REV_J ) {
- /* It is a CD1400 rev. J or later */
- cy_writeb((u_long)base_addr + (CyTDR<<index),
- info->x_break*500/HZ);
- } else {
- cy_writeb((u_long)base_addr + (CyTDR<<index),
- info->x_break*200/HZ);
+ if (info->breakon || info->breakoff) {
+ if (info->breakon) {
+ cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
+ cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
+ info->breakon = 0;
+ char_count -= 2;
+ }
+ if (info->breakoff) {
+ cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
+ cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
+ info->breakoff = 0;
+ char_count -= 2;
}
- /* finish break */
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
- cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
- char_count -= 7;
- info->x_break = 0;
}
while (char_count-- > 0){
@@ -1871,12 +1876,6 @@
info->last_active = jiffies;
info->jiffies[2] = jiffies;
}
- if (info->x_break){
- printk("cyc cyz_poll shouldn't see x_break\n");
- info->x_break = 0;
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
- }
#ifdef BLOCKMOVE
while(0 < (small_count
= cy_min((tx_bufsize - tx_put),
@@ -1946,26 +1945,35 @@
startup(struct cyclades_port * info)
{
unsigned long flags;
+ int retval = 0;
unsigned char *base_addr;
int card,chip,channel,index;
+ unsigned long page;
+
+ page = get_free_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ save_flags(flags); cli();
if (info->flags & ASYNC_INITIALIZED){
- return 0;
+ free_page(page);
+ goto errout;
}
if (!info->type){
if (info->tty){
set_bit(TTY_IO_ERROR, &info->tty->flags);
}
- return 0;
- }
- if (!info->xmit_buf){
- info->xmit_buf = (unsigned char *) get_free_page (GFP_KERNEL);
- if (!info->xmit_buf){
- return -ENOMEM;
- }
+ free_page(page);
+ goto errout;
}
+ if (info->xmit_buf)
+ free_page(page);
+ else
+ info->xmit_buf = (unsigned char *) page;
+
set_line_char(info);
card = info->card;
@@ -1982,39 +1990,40 @@
card, chip, channel, (long)base_addr);/**/
#endif
- save_flags(flags); cli();
- cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
+ cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
- cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
- ? info->default_timeout
- : 0x02)); /* 10ms rx timeout */
+ cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
+ ? info->default_timeout : 0x02)); /* 10ms rx timeout */
- cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
+ cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
- cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
- cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
- cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
+ cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
+ cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
+ cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:startup raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr+(CyMSVR1<<index)),
- cy_readb(base_addr+(CyMSVR2<<index)));
+ printk("cyc:startup raising DTR\n");
+ printk(" status: 0x%x, 0x%x\n",
+ cy_readb(base_addr+(CyMSVR1<<index)),
+ cy_readb(base_addr+(CyMSVR2<<index)));
#endif
- cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) | CyRxData);
- info->flags |= ASYNC_INITIALIZED;
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ cy_readb(base_addr+(CySRER<<index)) | CyRxData);
+ info->flags |= ASYNC_INITIALIZED;
+
+ if (info->tty){
+ clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ }
+ info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+ info->breakon = info->breakoff = 0;
+ memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+ info->idle_stats.in_use =
+ info->idle_stats.recv_idle =
+ info->idle_stats.xmit_idle = jiffies;
- if (info->tty){
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
- }
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
- info->idle_stats.in_use =
- info->idle_stats.recv_idle =
- info->idle_stats.xmit_idle = jiffies;
restore_flags(flags);
+
} else {
struct FIRM_ID *firm_id;
struct ZFW_CTRL *zfw_ctrl;
@@ -2022,6 +2031,8 @@
struct CH_CTRL *ch_ctrl;
int retval;
+ restore_flags(flags);
+
base_addr = (unsigned char*) (cy_card[card].base_addr);
firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
@@ -2074,7 +2085,7 @@
clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
+ info->breakon = info->breakoff = 0;
memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
info->idle_stats.in_use =
info->idle_stats.recv_idle =
@@ -2085,6 +2096,10 @@
printk(" cyc startup done\n");
#endif
return 0;
+
+errout:
+ restore_flags(flags);
+ return retval;
} /* startup */
@@ -3763,36 +3778,62 @@
return 0;
} /* set_modem_info */
+/*
+ * cy_break() --- routine which turns the break handling on or off
+ */
static void
-send_break( struct cyclades_port * info, int duration)
+cy_break(struct tty_struct *tty, int break_state)
{
+ struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+ if (serial_paranoia_check(info, tty->device, "cy_break"))
+ return;
+
+ save_flags(flags); cli();
if (!IS_CYC_Z(cy_card[info->card])) {
/* Let the transmit ISR take care of this (since it
requires stuffing characters into the output stream).
*/
- info->x_break = duration;
- if (!info->xmit_cnt ) {
- start_xmit(info);
+ if (break_state == -1) {
+ if (!info->breakon) {
+ info->breakon = 1;
+ if (!info->xmit_cnt ) {
+ start_xmit(info);
+ }
+ }
+ } else {
+ if (!info->breakoff) {
+ info->breakoff = 1;
+ if (!info->xmit_cnt ) {
+ start_xmit(info);
+ }
+ }
}
} else {
- /* For the moment we ignore the duration parameter!!!
- A better implementation will use C_CM_SET_BREAK
- and C_CM_CLR_BREAK with the appropriate delay.
- */
-#if 1
-// this appears to wedge the output data stream
-int retval;
- retval = cyz_issue_cmd(&cy_card[info->card],
+ int retval;
+
+ if (break_state == -1) {
+ retval = cyz_issue_cmd(&cy_card[info->card],
(info->line) - (cy_card[info->card].first_line),
- C_CM_SENDBRK, 0L);
- if (retval != 0){
- printk("cyc:send_break retval at %d was %x\n",
- __LINE__, retval);
+ C_CM_SET_BREAK, 0L);
+ if (retval != 0) {
+ printk("cyc:cy_break (set) retval at %d was %x\n",
+ __LINE__, retval);
+ }
+ } else {
+ retval = cyz_issue_cmd(&cy_card[info->card],
+ (info->line) - (cy_card[info->card].first_line),
+ C_CM_CLR_BREAK, 0L);
+ if (retval != 0) {
+ printk("cyc:cy_break (clr) retval at %d was %x\n",
+ __LINE__, retval);
+ }
}
-#endif
}
-} /* send_break */
+ restore_flags(flags);
+
+} /* cy_break */
static int
get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
@@ -4026,21 +4067,6 @@
case CYGETWAIT:
ret_val = info->closing_wait / (HZ/100);
break;
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- ret_val = tty_check_change(tty);
- if (ret_val)
- return ret_val;
- tty_wait_until_sent(tty,0);
- if (!arg)
- send_break(info, HZ/4); /* 1/4 second */
- break;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- ret_val = tty_check_change(tty);
- if (ret_val)
- return ret_val;
- tty_wait_until_sent(tty,0);
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
- break;
case TIOCMGET:
ret_val = get_modem_info(info, (unsigned int *) arg);
break;
@@ -4091,7 +4117,13 @@
tty->stopped = 0;
cy_start(tty);
}
-#ifdef tytso_patch_94Nov25_1726
+#if 0
+ /*
+ * No need to wake up processes in open wait, since they
+ * sample the CLOCAL flag once, and don't recheck it.
+ * XXX It's not clear whether the current behavior is correct
+ * or not. Hence, this may change.....
+ */
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
wake_up_interruptible(&info->open_wait);
@@ -4100,16 +4132,6 @@
return;
} /* cy_set_termios */
-
-/*
- * void (*set_ldisc)(struct tty_struct *tty);
- *
- * This routine allows the tty driver to be notified when the
- * device's termios settings have changed.
- *
- */
-
-
/* This routine is called by the upper-layer tty layer to signal
that incoming characters should be throttled because the input
buffers are close to full.
@@ -4467,6 +4489,7 @@
return chip_number;
} /* cyy_init_card */
+#ifndef CONFIG_COBALT_27
/*
* ---------------------------------------------------------------------
* cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
@@ -4530,7 +4553,7 @@
/* allocate IRQ */
if(request_irq(cy_isa_irq, cyy_interrupt,
- SA_INTERRUPT, "cyclomY", NULL))
+ SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
{
printk("Cyclom-Y/ISA found at 0x%lx ",
(unsigned long) cy_isa_address);
@@ -4546,7 +4569,6 @@
cy_card[j].bus_index = 0;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_isa_nchan/4;
- IRQ_cards[cy_isa_irq] = &cy_card[j];
nboard++;
/* print message */
@@ -4561,6 +4583,20 @@
return(nboard);
} /* cy_detect_isa */
+#endif /* CONFIG_COBALT_27 */
+
+static void plx_init(uclong addr, uclong initctl)
+{
+ /* Reset PLX */
+ cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+ udelay(100L);
+ cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+
+ /* Reload Config. Registers from EEPROM */
+ cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+ udelay(100L);
+ cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+}
/*
* ---------------------------------------------------------------------
@@ -4621,6 +4657,12 @@
cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+ if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+ printk(" Warning: PCI I/O bit incorrectly set. "
+ "Ignoring it...\n");
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+ }
+
#if defined(__alpha__)
if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
@@ -4673,7 +4715,7 @@
/* allocate IRQ */
if(request_irq(cy_pci_irq, cyy_interrupt,
- SA_INTERRUPT, "cyclomY", NULL))
+ SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
{
printk("Cyclom-Y/PCI found at 0x%lx ",
(ulong) cy_pci_addr2);
@@ -4689,13 +4731,14 @@
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_pci_nchan/4;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* enable interrupts in the PCI interface */
plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
switch (plx_ver) {
case PLX_9050:
+ plx_init(cy_pci_addr0, 0x50);
+
cy_writew(cy_pci_addr0+0x4c,
cy_readw(cy_pci_addr0+0x4c)|0x0040);
break;
@@ -4704,6 +4747,8 @@
case PLX_9080:
default: /* Old boards, use PLX_9060 */
+ plx_init(cy_pci_addr0, 0x6c);
+
cy_writew(cy_pci_addr0+0x68,
cy_readw(cy_pci_addr0+0x68)|0x0900);
break;
@@ -4742,9 +4787,18 @@
#if !defined(__alpha__)
cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
#endif
+
+ plx_init(cy_pci_addr0, 0x6c);
+
mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
cy_pci_addr0)->mail_box_0);
cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+
+ if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+ printk(" Warning: PCI I/O bit incorrectly set. "
+ "Ignoring it...\n");
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+ }
if (mailbox == ZE_V1) {
#if !defined(__alpha__)
cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ze_win);
@@ -4821,7 +4875,7 @@
/* allocate IRQ only if board has an IRQ */
if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
if(request_irq(cy_pci_irq,cyz_interrupt,
- SA_INTERRUPT,"cyclomZ",NULL))
+ SA_SHIRQ,"Cyclades-Z",&cy_card[j]))
{
printk("Could not allocate IRQ%d ",
cy_pci_irq);
@@ -4839,7 +4893,6 @@
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = -1;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* print message */
/* don't report IRQ if board is no IRQ */
@@ -4905,7 +4958,7 @@
/* allocate IRQ only if board has an IRQ */
if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
if(request_irq(cy_pci_irq,cyz_interrupt,
- SA_INTERRUPT,"cyclomZ",NULL))
+ SA_SHIRQ,"Cyclades-Z",&cy_card[j]))
{
printk("Could not allocate IRQ%d ",
cy_pci_irq);
@@ -4922,7 +4975,6 @@
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = -1;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* print message */
/* don't report IRQ if board is no IRQ */
@@ -4971,7 +5023,6 @@
__DATE__, __TIME__);
} /* show_version */
-#ifdef CY_PROC
static int
cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
int *eof, void *data)
@@ -5028,7 +5079,6 @@
len = 0;
return len;
}
-#endif
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
@@ -5062,13 +5112,15 @@
struct proc_dir_entry *ent;
#endif
+ init_bh(CYCLADES_BH, do_cyclades_bh);
+
show_version();
/* Initialize the tty_driver structure */
memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
cy_serial_driver.magic = TTY_DRIVER_MAGIC;
- cy_serial_driver.name = "cyclades";
+ cy_serial_driver.driver_name = "cyclades";
cy_serial_driver.name = "ttyC";
cy_serial_driver.major = CYCLADES_MAJOR;
cy_serial_driver.minor_start = 0;
@@ -5083,6 +5135,7 @@
cy_serial_driver.table = serial_table;
cy_serial_driver.termios = serial_termios;
cy_serial_driver.termios_locked = serial_termios_locked;
+
cy_serial_driver.open = cy_open;
cy_serial_driver.close = cy_close;
cy_serial_driver.write = cy_write;
@@ -5098,7 +5151,9 @@
cy_serial_driver.stop = cy_stop;
cy_serial_driver.start = cy_start;
cy_serial_driver.hangup = cy_hangup;
+ cy_serial_driver.break_ctl = cy_break;
cy_serial_driver.wait_until_sent = cy_wait_until_sent;
+ cy_serial_driver.read_proc = cyclades_get_proc_info;
/*
* The callout device is just like normal device except for
@@ -5117,12 +5172,6 @@
if (tty_register_driver(&cy_callout_driver))
panic("Couldn't register Cyclades callout driver\n");
- init_bh(CYCLADES_BH, do_cyclades_bh);
-
- for (i = 0; i < NR_IRQS; i++) {
- IRQ_cards[i] = 0;
- }
-
for (i = 0; i < NR_CARDS; i++) {
/* base_addr=0 indicates board not found */
cy_card[i].base_addr = 0;
@@ -5135,9 +5184,11 @@
availability of cy_card and cy_port data structures and updating
the cy_next_channel. */
+#ifndef CONFIG_COBALT_27
/* look for isa boards */
cy_isa_nboard = cy_detect_isa();
-
+#endif /* CONFIG_COBALT_27 */
+
/* look for pci boards */
cy_pci_nboard = cy_detect_pci();
@@ -5323,6 +5374,7 @@
cleanup_module(void)
{
int i;
+ int e1, e2;
unsigned long flags;
if (cyz_timeron){
@@ -5333,11 +5385,12 @@
save_flags(flags); cli();
remove_bh(CYCLADES_BH);
- free_page((unsigned long)tmp_buf);
- if (tty_unregister_driver(&cy_callout_driver))
- printk("Couldn't unregister Cyclades callout driver\n");
- if (tty_unregister_driver(&cy_serial_driver))
- printk("Couldn't unregister Cyclades serial driver\n");
+ if ((e1 = tty_unregister_driver(&cy_serial_driver)))
+ printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
+ e1);
+ if ((e2 = tty_unregister_driver(&cy_callout_driver)))
+ printk("cyc: failed to unregister Cyclades callout driver (%d)\n",
+ e2);
restore_flags(flags);
@@ -5345,9 +5398,13 @@
if (cy_card[i].base_addr != 0
&& cy_card[i].irq)
{
- free_irq(cy_card[i].irq,NULL);
+ free_irq(cy_card[i].irq, &cy_card[i]);
}
}
+ if (tmp_buf) {
+ free_page((unsigned long) tmp_buf);
+ tmp_buf = NULL;
+ }
#ifdef CY_PROC
remove_proc_entry("cyclades", 0);
#endif
@@ -5358,6 +5415,7 @@
void
cy_setup(char *str, int *ints)
{
+#ifndef CONFIG_COBALT_27
int i, j;
for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
@@ -5368,6 +5426,7 @@
cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
}
}
+#endif /* CONFIG_COBALT_27 */
} /* cy_setup */
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)