Messages in this thread Patches in this message | | | From | patrick@bitwizar ... | Date | Thu, 27 Jul 2000 15:49:38 +0200 (CEST) | Subject | [PATCH] sx, rio, generic_serial for 2.2.17-11 |
| |
Hi,
Here are the patches for the 2.2.x tree to ge the sx, rio and generic_serial drivers in sync with the 2.4.0 tree. The patches are against 2.2.17-pre11.
Patrick
diff -u -r --new-file linux-2.2.17-pre11/drivers/char/sx.c linux-2.2.17-11.sx/drivers/char/sx.c --- linux-2.2.17-pre11/drivers/char/sx.c Thu Jul 13 11:50:53 2000 +++ linux-2.2.17-11.sx/drivers/char/sx.c Thu Jul 27 13:37:18 2000 @@ -33,7 +33,12 @@ * * Revision history: * $Log: sx.c,v $ - * Revision 1.32 2000/03/07 90:00:00 wolff,pvdl + * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff + * - Fixed module and port counting + * - Fixed signal handling + * - Fixed an Ooops + * + * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl * - Fixed some sx_dprintk typos * - added detection for an invalid board/module configuration * @@ -195,8 +200,8 @@ * */ -#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $" -#define RCS_REV "$Revision: 1.32 $" +#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $" +#define RCS_REV "$Revision: 1.33 $" #include <linux/module.h> @@ -414,22 +419,9 @@ */ static struct file_operations sx_fw_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - sx_fw_ioctl, - NULL, /* mmap */ - sx_fw_open, -#ifndef TWO_ZERO - NULL, /* flush */ -#endif - sx_fw_release, - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* check_media_change */ - NULL, /* revalidate */ + open: sx_fw_open, + release: sx_fw_release, + ioctl: sx_fw_ioctl }; struct miscdevice sx_fw_device = { @@ -781,6 +773,7 @@ if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS); sx_write_channel_byte (port, hi_op, t); sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); + func_exit (); } @@ -1035,8 +1028,8 @@ if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; - sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) \n", - c, SERIAL_XMIT_SIZE- port->gs.xmit_tail); + sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", + c, (long)SERIAL_XMIT_SIZE- port->gs.xmit_tail); /* If for one reason or another, we can't copy more data, we're done! */ if (c == 0) break; @@ -1060,14 +1053,13 @@ sx_disable_tx_interrupts (port); } - if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup) (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", port->gs.wakeup_chars); wake_up_interruptible(&port->gs.tty->write_wait); - wake_up_interruptible(&port->gs.tty->poll_wait); } clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks); @@ -1087,7 +1079,7 @@ struct tty_struct *tty; int copied=0; - /* func_enter2 (); */ + func_enter2 (); tty = port->gs.tty; while (1) { rx_op = sx_read_channel_byte (port, hi_rxopos); @@ -1142,7 +1134,7 @@ /* tty_schedule_flip (tty); */ } - /* func_exit (); */ + func_exit (); } /* Inlined: it is called only once. Remove the inline if you add another @@ -1312,6 +1304,8 @@ sx_interrupt (0, board, NULL); + init_timer(&board->timer); + board->timer.expires = jiffies + sx_poll; add_timer (&board->timer); func_exit (); @@ -1407,7 +1401,7 @@ func_enter(); port->gs.flags &= ~ GS_ACTIVE; - if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) { + if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { sx_setsignals (port, 0, 0); sx_reconfigure_port(port); } @@ -1424,7 +1418,6 @@ * interface with the rest of the system * * ********************************************************************** */ - static int sx_fw_open(struct inode *inode, struct file *filp) { func_enter (); @@ -1443,6 +1436,7 @@ } + static int sx_open (struct tty_struct * tty, struct file * filp) { struct sx_port *port; @@ -1470,6 +1464,8 @@ tty->driver_data = port; port->gs.tty = tty; + if (!port->gs.count) + MOD_INC_USE_COUNT; port->gs.count++; sx_dprintk (SX_DEBUG_OPEN, "starting port\n"); @@ -1481,19 +1477,13 @@ sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n"); if (retval) { port->gs.count--; + if (port->gs.count) MOD_DEC_USE_COUNT; return retval; } port->gs.flags |= GS_ACTIVE; sx_setsignals (port, 1,1); - sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", - port->gs.count); - if (port->gs.count == 1) { - MOD_INC_USE_COUNT; - } - sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n"); - #if 0 if (sx_debug & SX_DEBUG_OPEN) my_hd ((unsigned char *)port, sizeof (*port)); @@ -1505,8 +1495,8 @@ if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n"); - MOD_DEC_USE_COUNT; port->gs.count--; + if (!port->gs.count) MOD_DEC_USE_COUNT; return -EIO; } @@ -1515,8 +1505,10 @@ retval, port->gs.count); if (retval) { - MOD_DEC_USE_COUNT; - port->gs.count--; + /* + * Don't lower gs.count here because sx_close() will be called later + */ + return retval; } /* tty->low_latency = 1; */ @@ -1548,25 +1540,15 @@ exit minicom. I expect an "oops". -- REW */ static void sx_hungup (void *ptr) { -/* - func_enter (); - MOD_DEC_USE_COUNT; - func_exit (); -*/ - /* - * Got this from the 2.4.0-test1 serie. The port was closed before - * the lines were set in the proper condition. -- pvdl - */ struct sx_port *port = ptr; func_enter (); - /* - * Set the lines in the proper codition before closing the port. - * Got the from 2.4.0-test1 series. -- pvdl - */ + /* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */ + /* For some reson we added this code. Don't know why anymore ;-) -- pvdl */ + /* sx_setsignals (port, 0, 0); sx_reconfigure_port(port); - sx_send_command (port, HS_CLOSE, -1, HS_IDLE_CLOSED); + sx_send_command (port, HS_CLOSE, 0, 0); if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) { if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) { @@ -1575,7 +1557,7 @@ } else sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n"); } - + */ MOD_DEC_USE_COUNT; func_exit (); } @@ -1611,6 +1593,11 @@ sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 5 * HZ - to - 1, port->gs.count); + if(port->gs.count) { + sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count); + port->gs.count = 0; + } + MOD_DEC_USE_COUNT; func_exit (); } @@ -1953,10 +1940,7 @@ func_enter(); /* This is preceded by downloading the download code. */ - /* - * The board should be set to initialized to make sure - * we can boot the other cards. --pvdl - */ + board->flags |= SX_BOARD_INITIALIZED; if (read_sx_byte (board, 0)) @@ -2362,6 +2346,13 @@ #ifdef NEW_WRITE_LOCKING port->gs.port_write_sem = MUTEX; #endif + /* + * Initializing wait queue + */ + /* + init_waitqueue_head(&port->gs.open_wait); + init_waitqueue_head(&port->gs.close_wait); + */ port++; } } @@ -2403,7 +2394,7 @@ return 0; } - +#ifdev MODULE static void sx_release_drivers(void) { func_enter(); @@ -2411,6 +2402,7 @@ tty_unregister_driver(&sx_callout_driver); func_exit(); } +#endif #ifdef TWO_ZERO #define PDEV unsigned char pci_bus, unsigned pci_fun @@ -2491,6 +2483,10 @@ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { + /* + if (pci_enable_device(pdev)) + continue; + */ #else for (i=0;i< SX_NBOARDS;i++) { if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, @@ -2526,10 +2522,14 @@ &tint); else pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, - &tint); - board->hw_base = tint & PCI_BASE_ADDRESS_MEM_MASK; + &tint); board->base2 = board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board)); + if (!board->base) { + printk(KERN_ERR "ioremap failed\n"); + /* XXX handle error */ + } + /* Most of the stuff on the CF board is offset by 0x18000 .... */ if (IS_CF_BOARD (board)) board->base += 0x18000;diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/func.h linux/drivers/char/rio/func.h --- linux-2.2.17-pre11/drivers/char/rio/func.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/func.h Thu Jul 27 10:42:00 2000 @@ -168,4 +168,6 @@ extern int rio_ismodem (kdev_t device); extern void rio_udelay (int usecs); +extern void rio_start_card_running (struct Host * HostP); + #endif /* __func_h_def */ diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/host.h linux/drivers/char/rio/host.h --- linux-2.2.17-pre11/drivers/char/rio/host.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/host.h Thu Jul 27 10:42:00 2000 @@ -56,16 +56,16 @@ uchar Mode; /* Control stuff */ uchar Slot; /* Slot */ volatile caddr_t Caddr; /* KV address of DPRAM */ - volatile struct DpRam *CardP; /* KV address of DPRAM, with overlay */ + volatile struct DpRam *CardP; /* KV address of DPRAM, with overlay */ paddr_t PaddrP; /* Phys. address of DPRAM */ char Name[MAX_NAME_LEN]; /* The name of the host */ uint UniqueNum; /* host unique number */ - semtype HostLock; /* Lock structure for MPX */ - /*struct pci_devinfo PciDevInfo; *//* PCI Bus/Device/Function stuff */ + spinlock_t HostLock; /* Lock structure for MPX */ + /*struct pci_devinfo PciDevInfo; *//* PCI Bus/Device/Function stuff */ /*struct lockb HostLock; *//* Lock structure for MPX */ uint WorkToBeDone; /* set to true each interrupt */ uint InIntr; /* Being serviced? */ - uint IntSrvDone; /* host's interrupt has been serviced */ + uint IntSrvDone;/* host's interrupt has been serviced */ int (*Copy)( caddr_t, caddr_t, int ); /* copy func */ struct timer_list timer; /* diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/linux_compat.h linux/drivers/char/rio/linux_compat.h --- linux-2.2.17-pre11/drivers/char/rio/linux_compat.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/linux_compat.h Thu Jul 27 10:42:00 2000 @@ -47,9 +47,6 @@ #define SEM_SIGIGNORE 0x1234 -typedef struct semaphore semtype; - - #ifdef DEBUG_SEM #define swait(a,b) printk ("waiting: " __FILE__ " line %d\n", __LINE__) #define ssignal(sem) printk ("signalling: " __FILE__ " line %d\n", __LINE__) diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rio_linux.c linux/drivers/char/rio/rio_linux.c --- linux-2.2.17-pre11/drivers/char/rio/rio_linux.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rio_linux.c Thu Jul 27 14:05:49 2000 @@ -109,108 +109,6 @@ more than 512 ports.... */ -/* ************************************************************** */ -/* * This section can be removed when 2.0 becomes outdated.... * */ -/* ************************************************************** */ - -#if LINUX_VERSION_CODE < 0x020100 /* Less than 2.1.0 */ -#define TWO_ZERO -#else -#if LINUX_VERSION_CODE < 0x020209 /* less than 2.2.x */ -#warning "Please use a recent 2.2.x kernel. " -#endif -#endif - - -#ifdef TWO_ZERO - -/* Here is the section that makes the 2.2 compatible driver source - work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2, - and provide for compatibility stuff here if possible. */ - -#include <linux/bios32.h> - -#define Get_user(a,b) a = get_user(b) -#define Put_user(a,b) 0,put_user(a,b) -#define copy_to_user(a,b,c) memcpy_tofs(a,b,c) - -static inline int copy_from_user(void *to,const void *from, int c) -{ - memcpy_fromfs(to, from, c); - return 0; -} - -#define pci_present pcibios_present -#define pci_read_config_word pcibios_read_config_word -#define pci_read_config_dword pcibios_read_config_dword - -static inline unsigned char get_irq (unsigned char bus, unsigned char fn) -{ - unsigned char t; - pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &t); - return t; -} - -static inline void *ioremap(unsigned long base, long length) -{ - if (base < 0x100000) return (void *)base; - return vremap (base, length); -} - -#define my_iounmap(x, b) (((long)x<0x100000)?0:vfree ((void*)x)) - -#define capable(x) suser() - -#define queue_task queue_task_irq_off -#define tty_flip_buffer_push(tty) queue_task(&tty->flip.tqueue, &tq_timer) -#define signal_pending(current) (current->signal & ~current->blocked) -#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0) -#define time_after(t1,t2) (((long)t1-t2) > 0) - - -#define test_and_set_bit(nr, addr) set_bit(nr, addr) -#define test_and_clear_bit(nr, addr) clear_bit(nr, addr) - -/* Not yet implemented on 2.0 */ -#define ASYNC_SPD_SHI -1 -#define ASYNC_SPD_WARP -1 - - -/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it - to the "name" field that does exist. As long as the assignments are - done in the right order, there is nothing to worry about. */ -#define driver_name name - -/* Should be in a header somewhere. They are in tty.h on 2.2 */ -#define TTY_HW_COOK_OUT 14 /* Flag to tell ntty what we can handle */ -#define TTY_HW_COOK_IN 15 /* in hardware - output and input */ - -/* The return type of a "close" routine. */ -#define INT void -#define NO_ERROR /* Nothing */ - -#else - -/* The 2.2.x compatibility section. */ -#include <asm/uaccess.h> - -#define Get_user(a,b) get_user(a,b) -#define Put_user(a,b) put_user(a,b) -#define get_irq(pdev) pdev->irq - -#define INT int -#define NO_ERROR 0 - -#define my_iounmap(x,b) (iounmap((char *)(b))) - -#endif - -/* ************************************************************** */ -/* * End of compatibility section.. * */ -/* ************************************************************** */ - - - /* Why the hell am I defining these here? */ #define RIO_TYPE_NORMAL 1 #define RIO_TYPE_CALLOUT 2 @@ -373,55 +271,15 @@ NULL }; - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ -#define DEBUG - -#ifdef DEBUG -#define rio_dprintk(f, str...) if (rio_debug & f) printk (str) -#else -#define rio_dprintk(f, str...) /* nothing */ -#endif - - -#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n") -#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit " __FUNCTION__ "\n") - -#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \ - "(port %d)\n", port->line) - - - - /* * Firmware loader driver specific routines * */ static struct file_operations rio_fw_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - rio_fw_ioctl, - NULL, /* mmap */ - rio_fw_open, -#ifndef TWO_ZERO - NULL, /* flush */ -#endif - rio_fw_release, - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* check_media_change */ - NULL, /* revalidate */ + open: rio_fw_open, + release: rio_fw_release, + ioctl: rio_fw_ioctl, }; struct miscdevice rio_fw_device = { @@ -446,11 +304,11 @@ KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; if (!port) { - printk(badinfo, kdevname(device), routine); + printk (badinfo, kdevname(device), routine); return 1; } if (port->magic != RIO_MAGIC) { - printk(badmagic, kdevname(device), routine); + printk (badmagic, kdevname(device), routine); return 1; } @@ -468,15 +326,15 @@ unsigned char *addr = ad; for (i=0;i<len;i+=16) { - printk ("%08x ", (int) addr+i); + rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i); for (j=0;j<16;j++) { - printk ("%02x %s", addr[j+i], (j==7)?" ":""); + rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":""); } for (j=0;j<16;j++) { ch = addr[j+i]; - printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch)); + rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch)); } - printk ("\n"); + rio_dprintk (RIO_DEBUG_PARAM, "\n"); } } #else @@ -568,21 +426,26 @@ void rio_reset_interrupt (struct Host *HostP) { + func_enter(); + switch( HostP->Type ) { case RIO_AT: case RIO_MCA: case RIO_PCI: WBYTE(HostP->ResetInt , 0xff); } + + func_exit(); } static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs) { struct Host *HostP; + func_enter (); - HostP = &p->RIOHosts[(long)ptr]; - /* func_enter (); */ + HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */ + rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); @@ -627,7 +490,7 @@ } } #endif - + rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); if (HostP->Ivec == irq) { /* Tell the card we've noticed the interrupt. */ rio_reset_interrupt (HostP); @@ -649,7 +512,7 @@ clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks); rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); - /* func_exit (); */ + func_exit (); } @@ -657,7 +520,7 @@ { func_enter (); - rio_interrupt (0, (void *)data, NULL); + rio_interrupt (0, &p->RIOHosts[data], NULL); p->RIOHosts[data].timer.expires = jiffies + rio_poll; add_timer (&p->RIOHosts[data].timer); @@ -756,11 +619,11 @@ #if 0 port->gs.flags &= ~ GS_ACTIVE; if (!port->gs.tty) { - printk ("No tty.\n"); + rio_dprintk (RIO_DBUG_TTY, "No tty.\n"); return; } if (!port->gs.tty->termios) { - printk ("No termios.\n"); + rio_dprintk (RIO_DEBUG_TTY, "No termios.\n"); return; } if (port->gs.tty->termios->c_cflag & HUPCL) { @@ -772,7 +635,6 @@ } - /* ********************************************************************** * * Here are the routines that actually * * interface with the rest of the system * @@ -1000,6 +862,8 @@ if (rio_debug & RIO_DEBUG_PROBE) my_hd ((char *)&vpdp, 0x20); + + func_exit(); return &vpdp; } @@ -1099,7 +963,7 @@ /* However, the RIO driver allows users to configure their first RTA as the ports numbered 504-511. We therefore need to allocate the whole range. :-( -- REW */ - + #define RI_SZ sizeof(struct rio_info) #define HOST_SZ sizeof(struct Host) #define PORT_SZ sizeof(struct Port *) @@ -1138,11 +1002,14 @@ port->gs.close_delay = HZ/2; port->gs.closing_wait = 30 * HZ; port->gs.rd = &rio_real_driver; + } #else /* We could postpone initializing them to when they are configured. */ #endif + + if (rio_debug & RIO_DEBUG_INIT) { my_hd (&rio_real_driver, sizeof (rio_real_driver)); } @@ -1165,7 +1032,7 @@ return -ENOMEM; } - +#ifdef MODULE static void rio_release_drivers(void) { func_enter(); @@ -1175,6 +1042,7 @@ tty_unregister_driver (&rio_driver); func_exit(); } +#endif #ifdef TWO_ZERO #define PDEV unsigned char pci_bus, unsigned pci_fun @@ -1211,7 +1079,7 @@ unsigned int t; #define CNTRL_REG_OFFSET 0x50 -#define CNTRL_REG_GOODVALUE 0x00260000 +#define CNTRL_REG_GOODVALUE 0x18260000 pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); hwbase &= PCI_BASE_ADDRESS_MEM_MASK; @@ -1292,7 +1160,6 @@ pci_read_config_dword (pdev, 0x2c, &tint); tshort = (tint >> 16) & 0xffff; rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); - /* rio_dprintk (RIO_DEBUG_PROBE, "pdev = %d/%d (%x)\n", pdev, tint); */ if (tshort != 0x0100) { rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); @@ -1305,49 +1172,51 @@ hp = &p->RIOHosts[p->RIONumHosts]; hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; hp->Ivec = get_irq (pdev); - if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0; + if (((1 << hp->Ivec) & rio_irqmask) == 0) + hp->Ivec = 0; hp->CardP = (struct DpRam *) hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); hp->Type = RIO_PCI; hp->Copy = rio_pcicopy; - hp->Mode = RIO_PCI_DEFAULT_MODE; - + hp->Mode = RIO_PCI_BOOT_FROM_RAM; + rio_reset_interrupt (hp); + rio_start_card_running (hp); + rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *)p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) { - WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)| - ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)| - ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)| - ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24); - rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", - p->RIOHosts[p->RIONumHosts].UniqueNum); - -#if 1 - fix_rio_pci (pdev); -#endif - p->RIOLastPCISearch = RIO_SUCCESS; - p->RIONumHosts++; - found++; + rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n"); + WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff); + p->RIOHosts[p->RIONumHosts].UniqueNum = + ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)| + ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)| + ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)| + ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24); + rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", + p->RIOHosts[p->RIONumHosts].UniqueNum); + + fix_rio_pci (pdev); + p->RIOLastPCISearch = RIO_SUCCESS; + p->RIONumHosts++; + found++; } else { - my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, - p->RIOHosts[p->RIONumHosts].Caddr); + my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, + p->RIOHosts[p->RIONumHosts].Caddr); } - + #ifdef TWO_ZERO } /* We have two variants with the opening brace, so to prevent */ #else } /* Emacs from getting confused we have two closing braces too. */ #endif - /* Then look for the older PCI card.... : */ #ifndef TWO_ZERO + /* These older PCI cards have problems (only byte-mode access is supported), which makes them a bit awkward to support. They also have problems sharing interrupts. Be careful. @@ -1372,15 +1241,21 @@ hp = &p->RIOHosts[p->RIONumHosts]; hp->PaddrP = tint & PCI_BASE_ADDRESS_MEM_MASK; hp->Ivec = get_irq (pdev); - if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0; + if (((1 << hp->Ivec) & rio_irqmask) == 0) + hp->Ivec = 0; hp->Ivec |= 0x8000; /* Mark as non-sharable */ hp->CardP = (struct DpRam *) hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); hp->Type = RIO_PCI; hp->Copy = rio_pcicopy; - hp->Mode = RIO_PCI_DEFAULT_MODE; - - rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", + hp->Mode = RIO_PCI_BOOT_FROM_RAM; + + rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); + rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); + + rio_reset_interrupt (hp); + rio_start_card_running (hp); + rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *)p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP, @@ -1423,11 +1298,15 @@ hp->CardP = (struct DpRam *) hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); hp->Type = RIO_AT; - hp->Copy = rio_pcicopy; + hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL + * -- YES! this is now a normal copy. Only the + * old PCI card uses the special PCI copy. + * Moreover, the ISA card will work with the + * special PCI copy anyway. -- REW */ hp->Mode = 0; vpdp = get_VPD_PROM (hp); - + rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n"); okboard = 0; if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || @@ -1458,11 +1337,21 @@ if (hp->Ivec) { int mode = SA_SHIRQ; if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;} - if (request_irq (hp->Ivec, rio_interrupt, mode, "rio", (void *)i)) { - printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); - hp->Ivec = 0; + rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode); + retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp); + rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); + if (retval) { + printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); + hp->Ivec = 0; } rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); + if (hp->Ivec != 0){ + rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); + hp->Mode |= RIO_PCI_INT_ENABLE; + } else + hp->Mode &= !RIO_PCI_INT_ENABLE; + rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); + rio_start_card_running (hp); } /* Init the timer "always" to make sure that it can safely be deleted when we unload... */ @@ -1479,7 +1368,7 @@ } if (found) { - printk (KERN_INFO "rio: total of %d boards detected.\n", found); + rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); if (misc_register(&rio_fw_device) < 0) { printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); @@ -1504,7 +1393,7 @@ for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) { RIOHostReset (hp->Type, hp->CardP, hp->Slot); if (hp->Ivec) { - free_irq (hp->Ivec, (void *)i); + free_irq (hp->Ivec, hp); rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); } /* It is safe/allowed to del_timer a non-active timer */ diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rio_linux.h linux/drivers/char/rio/rio_linux.h --- linux-2.2.17-pre11/drivers/char/rio/rio_linux.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rio_linux.h Thu Jul 27 14:31:04 2000 @@ -23,6 +23,7 @@ * Version 1.0 -- July, 1999. * */ +#include <linux/config.h> #define RIO_NBOARDS 4 #define RIO_PORTSPERBOARD 128 @@ -157,5 +158,30 @@ #else #define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) #define rio_memcpy_fromio memcpy_fromio +#endif + +#define DEBUG + + +/* + This driver can spew a whole lot of debugging output at you. If you + need maximum performance, you should disable the DEBUG define. To + aid in debugging in the field, I'm leaving the compile-time debug + features enabled, and disable them "runtime". That allows me to + instruct people with problems to enable debugging without requiring + them to recompile... +*/ + +#ifdef DEBUG +#define rio_dprintk(f, str...) if (rio_debug & f) printk (str) +#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n") +#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit " __FUNCTION__ "\n") +#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \ + "(port %d)\n", port->line) +#else +#define rio_dprintk(f, str...) /* nothing */ +#define func_enter() +#define func_exit() +#define func_enter2() #endif diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rioboot.c linux/drivers/char/rio/rioboot.c --- linux-2.2.17-pre11/drivers/char/rio/rioboot.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rioboot.c Thu Jul 27 10:42:00 2000 @@ -35,7 +35,6 @@ #endif #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -82,7 +81,6 @@ #include "cmdblk.h" #include "route.h" - static uchar RIOAtVec2Ctrl[] = { @@ -114,6 +112,8 @@ { int offset; + func_enter (); + /* Linux doesn't allow you to disable interrupts during a "copyin". (Crash when a pagefault occurs). */ /* disable(oldspl); */ @@ -127,6 +127,7 @@ rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n")); p->RIOError.Error = HOST_FILE_TOO_LARGE; /* restore(oldspl); */ + func_exit (); return ENOMEM; } @@ -134,6 +135,7 @@ rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n")); p->RIOError.Error = BOOT_IN_PROGRESS; /* restore(oldspl); */ + func_exit (); return EBUSY; } @@ -161,6 +163,7 @@ rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n")); p->RIOError.Error = COPYIN_FAILED; /* restore(oldspl); */ + func_exit (); return EFAULT; } @@ -172,9 +175,61 @@ p->RIOBootCount = rbp->Count; /* restore(oldspl); */ + func_exit(); return 0; } +void rio_start_card_running (struct Host * HostP) +{ + func_enter (); + + switch ( HostP->Type ) { + case RIO_AT: + rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n")); + WBYTE(HostP->Control, + BOOT_FROM_RAM | EXTERNAL_BUS_ON + | HostP->Mode + | RIOAtVec2Ctrl[HostP->Ivec & 0xF] ); + break; + +#ifdef FUTURE_RELEASE + case RIO_MCA: + /* + ** MCA handles IRQ vectors differently, so we don't write + ** them to this register. + */ + rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n")); + WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode); + break; + + case RIO_EISA: + /* + ** EISA is totally different and expects OUTBZs to turn it on. + */ + rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n"); + OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM ); + break; +#endif + + case RIO_PCI: + /* + ** PCI is much the same as MCA. Everything is once again memory + ** mapped, so we are writing to memory registers instead of io + ** ports. + */ + rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n")); + WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode); + break; + default: + rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type)); + break; + } +/* + printk (KERN_INFO "Done with starting the card\n"); + func_exit (); +*/ + return; +} /* ** Load in the host boot code - load it directly onto all halted hosts @@ -207,6 +262,10 @@ for ( host=0; host<p->RIONumHosts; host++ ) { rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host)); HostP = &p->RIOHosts[host]; + + rio_dprint(RIO_DEBUG_BOOT, ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", + HostP->Type, HostP->Mode, HostP->Ivec ) ); + if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) { rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host)); @@ -234,6 +293,7 @@ if ( p->RIOConf.HostLoadBase < rbp->Count ) { rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n")); p->RIOError.Error = HOST_FILE_TOO_LARGE; + func_exit (); return EFBIG; } /* @@ -260,6 +320,7 @@ if ( !DownCode ) { rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n")); p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; + func_exit (); return ENOMEM; } bzero(DownCode, rbp->Count); @@ -267,6 +328,7 @@ if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) { rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n")); p->RIOError.Error = COPYIN_FAILED; + func_exit (); return EFAULT; } @@ -277,6 +339,7 @@ else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) { rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n")); p->RIOError.Error = COPYIN_FAILED; + func_exit (); return EFAULT; } @@ -406,47 +469,8 @@ rio_dprint(RIO_DEBUG_BOOT, ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec ) ); - switch ( HostP->Type ) { - case RIO_AT: - rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n")); - WBYTE(HostP->Control, - BOOT_FROM_RAM | EXTERNAL_BUS_ON - | HostP->Mode - | RIOAtVec2Ctrl[HostP->Ivec & 0xF] ); - break; - -#ifdef FUTURE_RELEASE - case RIO_MCA: - /* - ** MCA handles IRQ vectors differently, so we don't write - ** them to this register. - */ - rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n")); - WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode); - break; - - case RIO_EISA: - /* - ** EISA is totally different and expects OUTBZs to turn it on. - */ - rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n"); - OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM ); - break; -#endif + rio_start_card_running(HostP); - case RIO_PCI: - /* - ** PCI is much the same as MCA. Everything is once again memory - ** mapped, so we are writing to memory registers instead of io - ** ports. - */ - rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n")); - WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode); - break; - default: - rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type)); - break; - } rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n")); /* @@ -454,9 +478,10 @@ ** pointer: */ for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&& - (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) { + (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) { rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR))); delay(HostP, HUNDRED_MS); + } /* @@ -614,6 +639,7 @@ p->RIOSystemUp++; rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec)); + func_exit (); return 0; } diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/riocmd.c linux/drivers/char/rio/riocmd.c --- linux-2.2.17-pre11/drivers/char/rio/riocmd.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/riocmd.c Thu Jul 27 10:42:00 2000 @@ -35,7 +35,6 @@ #endif #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -43,8 +42,6 @@ #include <asm/system.h> #include <asm/string.h> #include <asm/semaphore.h> -#include <asm/spinlock.h> - #include <linux/termios.h> #include <linux/serial.h> diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rioctrl.c linux/drivers/char/rio/rioctrl.c --- linux-2.2.17-pre11/drivers/char/rio/rioctrl.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rioctrl.c Thu Jul 27 10:42:00 2000 @@ -35,7 +35,6 @@ #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -202,6 +201,8 @@ int retval = 0; unsigned long flags; + func_enter (); + /* Confuse teh compiler to think that we've initialized these */ Host=0; PortP = NULL; @@ -1777,6 +1778,8 @@ } rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd)); p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; + + func_exit (); return EINVAL; } diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/riodrvr.h linux/drivers/char/rio/riodrvr.h --- linux-2.2.17-pre11/drivers/char/rio/riodrvr.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/riodrvr.h Thu Jul 27 10:42:00 2000 @@ -44,7 +44,7 @@ struct rio_info { int mode; /* Intr or polled, word/byte */ - semtype RIOIntrSem; /* Interrupt thread sem */ + spinlock_t RIOIntrSem; /* Interrupt thread sem */ int current_chan; /* current channel */ int RIOFailed; /* Not initialised ? */ int RIOInstallAttempts; /* no. of rio-install() calls */ diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rioinit.c linux/drivers/char/rio/rioinit.c --- linux-2.2.17-pre11/drivers/char/rio/rioinit.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rioinit.c Thu Jul 27 10:42:00 2000 @@ -1414,7 +1414,7 @@ (int)p->RIOHosts, sizeof(struct Host) ) ); for( host=0; host<RIO_HOSTS; host++ ) { - p->RIOHosts[host].HostLock = -1; /* Let the first guy takes it */ + spin_lock_init (&p->RIOHosts[host].HostLock); p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */ } /* diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/riointr.c linux/drivers/char/rio/riointr.c --- linux-2.2.17-pre11/drivers/char/rio/riointr.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/riointr.c Thu Jul 27 10:42:00 2000 @@ -35,7 +35,6 @@ #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -254,7 +253,6 @@ rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n", PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); wake_up_interruptible(&PortP->gs.tty->write_wait); - wake_up_interruptible(&PortP->gs.tty->poll_wait); } } diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rioparam.c linux/drivers/char/rio/rioparam.c --- linux-2.2.17-pre11/drivers/char/rio/rioparam.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rioparam.c Thu Jul 27 10:42:00 2000 @@ -35,7 +35,6 @@ #endif #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/rioroute.c linux/drivers/char/rio/rioroute.c --- linux-2.2.17-pre11/drivers/char/rio/rioroute.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/rioroute.c Thu Jul 27 10:42:00 2000 @@ -34,7 +34,6 @@ #endif #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/riotable.c linux/drivers/char/rio/riotable.c --- linux-2.2.17-pre11/drivers/char/rio/riotable.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/riotable.c Thu Jul 27 10:42:00 2000 @@ -34,7 +34,6 @@ #endif #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/riotty.c linux/drivers/char/rio/riotty.c --- linux-2.2.17-pre11/drivers/char/rio/riotty.c Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/riotty.c Thu Jul 27 10:42:00 2000 @@ -37,7 +37,6 @@ #define __EXPLICIT_DEF_H__ #define __NO_VERSION__ -#include <linux/config.h> #include <linux/module.h> #include <linux/malloc.h> #include <linux/errno.h> @@ -90,7 +89,6 @@ #include "list.h" #include "sam.h" - #if 0 static void ttyseth_pv(struct Port *, struct ttystatics *, struct termios *sg, int); @@ -155,13 +153,21 @@ unsigned long flags; int retval = 0; + func_enter (); + + /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close + is going to oops. + */ + tty->driver_data = NULL; + SysPort = rio_minor (tty->device); Modem = rio_ismodem (tty->device); if ( p->RIOFailed ) { rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n")); pseterr(ENXIO); - return 0; + func_exit (); + return -ENXIO; } rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n", @@ -177,22 +183,24 @@ if (SysPort >= RIO_PORTS) { /* out of range ? */ rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort)); pseterr(ENXIO); - return 0; + func_exit(); + return -ENXIO; } /* ** Grab pointer to the port stucture */ PortP = p->RIOPortp[SysPort]; /* Get control struc */ - + rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP); if ( !PortP->Mapped ) { /* we aren't mapped yet! */ /* ** The system doesn't know which RTA this port ** corresponds to. */ rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n")); + func_exit (); pseterr(ENXIO); - return 0; + return -ENXIO; } tty->driver_data = PortP; @@ -210,7 +218,8 @@ if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) { rio_dprint(RIO_DEBUG_TTY, ("Host not running\n")); pseterr(ENXIO); - return 0; + func_exit (); + return -ENXIO; } /* @@ -225,12 +234,14 @@ do { if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n")); + func_exit (); return -EINTR; } if (repeat_this -- <= 0) { rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n")); RIOPreemptiveCmd(p, PortP, FCLOSE ); pseterr(EINTR); + func_exit (); return -EIO; } } while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)); @@ -238,6 +249,7 @@ } else { rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n")); pseterr(ENXIO); + func_exit (); return 0; } } @@ -250,6 +262,7 @@ while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { if (!PortP->WaitUntilBooted) { rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n")); + func_exit (); return -ENXIO; } @@ -259,10 +272,12 @@ */ if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n")); + func_exit (); return -EINTR; } if (repeat_this -- <= 0) { rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n")); + func_exit (); return -EIO; } } @@ -277,8 +292,10 @@ } #if 0 retval = gs_init_port(&PortP->gs); - if (retval) - return retval; + if (retval){ + func_exit (); + return retval; + } #endif /* @@ -307,6 +324,7 @@ rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n")); rio_spin_unlock_irqrestore(&PortP->portSem, flags); retval = -ENXIO; + func_exit (); return retval; } @@ -376,6 +394,7 @@ if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n")); RIOPreemptiveCmd(p, PortP, FCLOSE ); + func_exit (); return -EINTR; } rio_spin_lock_irqsave(&PortP->portSem, flags); @@ -426,6 +445,7 @@ tp->tm.c_state &= ~WOPEN; PortP->State &= ~RIO_WOPEN; rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit (); return -EINTR; } } @@ -463,6 +483,7 @@ rio_spin_unlock_irqrestore(&PortP->portSem, flags); rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n")); + func_exit (); return 0; } diff -u -r --new-file linux-2.2.17-pre11/drivers/char/rio/unixrup.h linux/drivers/char/rio/unixrup.h --- linux-2.2.17-pre11/drivers/char/rio/unixrup.h Thu Jul 13 11:10:03 2000 +++ linux/drivers/char/rio/unixrup.h Thu Jul 27 10:42:00 2000 @@ -49,7 +49,7 @@ uint Id; /* Id number */ uint BaseSysPort; /* SysPort of first tty on this RTA */ uint ModTypes; /* Modules on this RTA */ - semtype RupLock; /* Lock structure for MPX */ + spinlock_t RupLock; /* Lock structure for MPX */ /* struct lockb RupLock; */ /* Lock structure for MPX */ }; diff -u -r --new-file linux-2.2.17-pre11/drivers/char/generic_serial.c linux/drivers/char/generic_serial.c --- linux-2.2.17-pre11/drivers/char/generic_serial.c Thu Jul 13 11:10:02 2000 +++ linux/drivers/char/generic_serial.c Thu Jul 27 15:44:43 2000 @@ -12,12 +12,18 @@ * Version 0.1 -- December, 1998. Initial version. * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. - */ + * + * BitWizard is actively maintaining this file. We sometimes find + * that someone submitted changes to this file. We really appreciate + * your help, but please submit changes through us. We're doing our + * best to be responsive. -- REW + * */ #include <linux/tty.h> #include <linux/serial.h> #include <linux/mm.h> #include <asm/semaphore.h> +#include <asm/uaccess.h> #include <linux/version.h> #include <linux/module.h> #include <linux/compatmac.h> @@ -40,8 +46,6 @@ #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n") #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit " __FUNCTION__ "\n") - - #if NEW_WRITE_LOCKING #define DECL /* Nothing */ #define LOCKIT down (& port->port_write_sem); @@ -52,6 +56,9 @@ #define RELEASEIT restore_flags (flags) #endif +#ifdef MODULE +MODULE_PARM(gs_debug, "i"); +#endif #ifdef DEBUG static void my_hd (unsigned char *addr, int len) @@ -77,10 +84,18 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; DECL - /* func_enter (); */ + func_enter (); + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + + if (! (port->flags & ASYNC_INITIALIZED)) return; /* Take a lock on the serial tranmit buffer! */ LOCKIT; @@ -96,7 +111,7 @@ port->xmit_cnt++; /* Characters in buffer */ RELEASEIT; - /* func_exit ();*/ + func_exit (); } @@ -112,11 +127,17 @@ int gs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; int c, total = 0; int t; - /* func_enter (); */ + func_enter (); + + if (!tty) return 0; + + port = tty->driver; + + if (!port) return 0; if (! (port->flags & ASYNC_INITIALIZED)) return 0; @@ -167,7 +188,7 @@ port->flags |= GS_TX_INTEN; port->rd->enable_tx_interrupts (port); } - /* func_exit (); */ + func_exit (); return total; } #else @@ -210,12 +231,9 @@ if (!port || !port->xmit_buf || !tmp_buf) return -EIO; - /* printk ("from_user = %d.\n", from_user); */ save_flags(flags); if (from_user) { - /* printk ("Going into the semaphore\n"); */ down(&tmp_buf_sem); - /* printk ("got out of the semaphore\n"); */ while (1) { c = count; @@ -309,11 +327,11 @@ struct gs_port *port = tty->driver_data; int ret; - /* func_enter (); */ + func_enter (); ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; if (ret < 0) ret = 0; - /* func_exit (); */ + func_exit (); return ret; } @@ -330,7 +348,7 @@ int gs_real_chars_in_buffer(struct tty_struct *tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; func_enter (); if (!tty) return 0; @@ -361,22 +379,17 @@ if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); - func_exit(); + func_exit(); return -EINVAL; /* This is an error which we don't know how to handle. */ } - gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n"); rcib = gs_real_chars_in_buffer(port->tty); - gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n"); - if(rcib <= 0) { gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); func_exit(); return rv; } - gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n"); - /* stop trying: now + twice the time it would normally take + seconds */ end_jiffies = jiffies; if (timeout != MAX_SCHEDULE_TIMEOUT) @@ -424,17 +437,23 @@ void gs_flush_buffer(struct tty_struct *tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; unsigned long flags; func_enter (); + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + /* XXX Would the write semaphore do? */ save_flags(flags); cli(); port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; restore_flags(flags); wake_up_interruptible(&tty->write_wait); - wake_up_interruptible(&tty->poll_wait); if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); @@ -444,9 +463,16 @@ void gs_flush_chars(struct tty_struct * tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; func_enter (); + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf) { func_exit (); @@ -462,9 +488,16 @@ void gs_stop(struct tty_struct * tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; func_enter (); + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + if (port->xmit_cnt && port->xmit_buf && (port->flags & GS_TX_INTEN) ) { @@ -477,7 +510,13 @@ void gs_start(struct tty_struct * tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; if (port->xmit_cnt && port->xmit_buf && @@ -492,7 +531,11 @@ void gs_shutdown_port (struct gs_port *port) { long flags; + func_enter(); + + if (!port) return; + if (!(port->flags & ASYNC_INITIALIZED)) return; @@ -517,10 +560,13 @@ void gs_hangup(struct tty_struct *tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; func_enter (); + if (!tty) return; + + port = tty->driver_data; tty = port->tty; if (!tty) return; @@ -541,15 +587,19 @@ struct gs_port *port = private_; struct tty_struct *tty; + func_enter (); + + if (!port) return; + tty = port->tty; - if(!tty) return; + + if (!tty) return; if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); wake_up_interruptible(&tty->write_wait); - wake_up_interruptible(&tty->poll_wait); } func_exit (); } @@ -565,8 +615,13 @@ struct tty_struct *tty; func_enter (); + + if (!port) return 0; + tty = port->tty; + if (!tty) return 0; + gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n"); /* * If the device is in the middle of being closed, then block @@ -625,8 +680,6 @@ do_clocal = 1; } - gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n"); - /* * Block waiting for the carrier detect and the line to become * free (i.e., not in use by the callout). While we are in @@ -635,10 +688,10 @@ * exit, either normal or abnormal. */ retval = 0; + add_wait_queue(&port->open_wait, &wait); gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); - cli(); if (!tty_hung_up_p(filp)) port->count--; @@ -690,15 +743,12 @@ struct gs_port *port; func_enter (); - port = (struct gs_port *) tty->driver_data; - gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n", - tty, port, port->tty); + if (!tty) return; - if(! port) { - func_exit(); - return; - } + port = (struct gs_port *) tty->driver_data; + + if (!port) return; if (!port->tty) { /* This seems to happen when this is called from vhangup. */ @@ -706,7 +756,6 @@ port->tty = tty; } - save_flags(flags); cli(); if (tty_hung_up_p(filp)) { @@ -800,14 +849,19 @@ void gs_set_termios (struct tty_struct * tty, struct termios * old_termios) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; int baudrate, tmp, rv; struct termios *tiosp; func_enter(); - tiosp = tty->termios; + if (!tty) return; + + port = tty->driver_data; + if (!port) return; + + tiosp = tty->termios; if (gs_debug & GS_DEBUG_TERMIOS) { gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); | |