* [PATCH] rio
@ 2000-11-30 14:38 Patrick van de Lageweg
0 siblings, 0 replies; 5+ messages in thread
From: Patrick van de Lageweg @ 2000-11-30 14:38 UTC (permalink / raw)
To: Linus Torvalds
Cc: kickstein, Oliver, Rogier Wolff, Linux Kernel Mailing List,
Alan Cox
Hi Linus,
This patch fixes several problems with the RIO driver:
- Implemented breaks
- Fixed close wait implementation
- Fixed a DCD up/down crash
- Fixed for DCD on open
- Initialization of the spinlocks
- Added kmalloc return value check
Most of these fixes have already been submitted but were silently
ignored. Most of these fixes have already been merged into 2.2.18pre
Patrick
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/generic_serial.c linux/drivers/char/generic_serial.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/generic_serial.c Thu Nov 16 21:51:27 2000
+++ linux/drivers/char/generic_serial.c Thu Nov 30 13:41:15 2000
@@ -345,7 +345,7 @@
struct gs_port *port = ptr;
long end_jiffies;
int jiffies_to_transmit, charsleft = 0, rv = 0;
- int to, rcib;
+ int rcib;
func_enter();
@@ -369,6 +369,7 @@
return rv;
}
/* stop trying: now + twice the time it would normally take + seconds */
+ if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT;
end_jiffies = jiffies;
if (timeout != MAX_SCHEDULE_TIMEOUT)
end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0;
@@ -377,11 +378,9 @@
gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n",
jiffies, end_jiffies, end_jiffies-jiffies);
- to = 100;
/* the expression is actually jiffies < end_jiffies, but that won't
work around the wraparound. Tricky eh? */
- while (to-- &&
- (charsleft = gs_real_chars_in_buffer (port->tty)) &&
+ while ((charsleft = gs_real_chars_in_buffer (port->tty)) &&
time_after (end_jiffies, jiffies)) {
/* Units check:
chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/linux_compat.h linux/drivers/char/rio/linux_compat.h
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/linux_compat.h Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/linux_compat.h Thu Nov 30 14:50:29 2000
@@ -16,11 +16,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <asm/hardirq.h>
+
#define disable(oldspl) save_flags (oldspl)
#define restore(oldspl) restore_flags (oldspl)
-#define sysbrk(x) kmalloc ((x), GFP_KERNEL)
+#define sysbrk(x) kmalloc ((x),in_interrupt()? GFP_ATOMIC : GFP_KERNEL)
#define sysfree(p,size) kfree ((p))
#define WBYTE(p,v) writeb(v, &p)
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/rio_linux.c linux/drivers/char/rio/rio_linux.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/rio_linux.c Thu Nov 16 21:51:27 2000
+++ linux/drivers/char/rio/rio_linux.c Thu Nov 30 13:46:22 2000
@@ -165,7 +165,7 @@
/* startuptime */ HZ*2, /* how long to wait for card to run */
/* slowcook */ 0, /* TRUE -> always use line disc. */
/* intrpolltime */ 1, /* The frequency of OUR polls */
- /* breakinterval */ 25, /* x10 mS */
+ /* breakinterval */ 25, /* x10 mS XXX: units seem to be 1ms not 10! -- REW*/
/* timer */ 10, /* mS */
/* RtaLoadBase */ 0x7000,
/* HostLoadBase */ 0x7C00,
@@ -203,11 +203,8 @@
unsigned int cmd, unsigned long arg);
static int rio_init_drivers(void);
-
void my_hd (void *addr, int len);
-
-
static struct tty_driver rio_driver, rio_callout_driver;
static struct tty_driver rio_driver2, rio_callout_driver2;
@@ -383,8 +380,8 @@
int rio_ismodem (kdev_t device)
{
- return (MAJOR (device) != RIO_NORMAL_MAJOR0) &&
- (MAJOR (device) != RIO_NORMAL_MAJOR1);
+ return (MAJOR (device) == RIO_NORMAL_MAJOR0) ||
+ (MAJOR (device) == RIO_NORMAL_MAJOR1);
}
@@ -455,7 +452,6 @@
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);
@@ -516,7 +512,7 @@
RIOServiceHost(p, HostP, irq);
- rio_dprintk ( RIO_DEBUG_IFLOW, "riointr() doing host %d type %d\n",
+ rio_dprintk ( RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n",
(int) ptr, HostP->Type);
clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
@@ -624,8 +620,12 @@
/* Nothing special here... */
static void rio_shutdown_port (void * ptr)
{
+ struct Port *PortP;
+
func_enter();
+ PortP = (struct Port *)ptr;
+ PortP->gs.tty = NULL;
#if 0
port->gs.flags &= ~ GS_ACTIVE;
if (!port->gs.tty) {
@@ -654,8 +654,14 @@
exit minicom. I expect an "oops". -- REW */
static void rio_hungup (void *ptr)
{
- func_enter ();
+ struct Port *PortP;
+
+ func_enter();
+
+ PortP = (struct Port *)ptr;
+ PortP->gs.tty = NULL;
rio_dec_mod_count ();
+
func_exit ();
}
@@ -679,9 +685,8 @@
PortP->gs.count = 0;
}
-
+ PortP->gs.tty = NULL;
rio_dec_mod_count ();
-
func_exit ();
}
@@ -700,24 +705,28 @@
return rc;
}
+extern int RIOShortCommand(struct rio_info *p, struct Port *PortP,
+ int command, int len, int arg);
static int rio_ioctl (struct tty_struct * tty, struct file * filp,
unsigned int cmd, unsigned long arg)
{
-#if 0
int rc;
- struct rio_port *port = tty->driver_data;
+ struct Port *PortP;
int ival;
- /* func_enter2(); */
+ func_enter();
+ PortP = (struct Port *)tty->driver_data;
rc = 0;
switch (cmd) {
+#if 0
case TIOCGSOFTCAR:
rc = Put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
(unsigned int *) arg);
break;
+#endif
case TIOCSSOFTCAR:
if ((rc = verify_area(VERIFY_READ, (void *) arg,
sizeof(int))) == 0) {
@@ -730,13 +739,39 @@
case TIOCGSERIAL:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(struct serial_struct))) == 0)
- gs_getserial(&port->gs, (struct serial_struct *) arg);
+ gs_getserial(&PortP->gs, (struct serial_struct *) arg);
+ break;
+ case TCSBRK:
+ if ( PortP->State & RIO_DELETED ) {
+ rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n");
+ rc = -EIO;
+ } else {
+ if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) {
+ rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
+ rc = -EIO;
+ }
+ }
+ break;
+ case TCSBRKP:
+ if ( PortP->State & RIO_DELETED ) {
+ rio_dprintk (RIO_DEBUG_TTY, "BREAK on deleted RTA\n");
+ rc = -EIO;
+ } else {
+ int l;
+ l = arg?arg*100:250;
+ if (l > 255) l = 255;
+ if (RIOShortCommand(p, PortP, SBREAK, 2, arg?arg*100:250) == RIO_FAIL) {
+ rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
+ rc = -EIO;
+ }
+ }
break;
case TIOCSSERIAL:
if ((rc = verify_area(VERIFY_READ, (void *) arg,
sizeof(struct serial_struct))) == 0)
- rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+ rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg);
break;
+#if 0
case TIOCMGET:
if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
sizeof(unsigned int))) == 0) {
@@ -768,17 +803,13 @@
((ival & TIOCM_RTS) ? 1 : 0));
}
break;
-
+#endif
default:
rc = -ENOIOCTLCMD;
break;
}
- /* func_exit(); */
+ func_exit();
return rc;
-#else
- return -ENOIOCTLCMD;
-#endif
-
}
@@ -1253,6 +1284,7 @@
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
+ hp->HostLock = SPIN_LOCK_UNLOCKED;
rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
@@ -1308,6 +1340,7 @@
* Moreover, the ISA card will work with the
* special PCI copy anyway. -- REW */
hp->Mode = 0;
+ hp->HostLock = SPIN_LOCK_UNLOCKED;
vpdp = get_VPD_PROM (hp);
rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/rio_linux.h linux/drivers/char/rio/rio_linux.h
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/rio_linux.h Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/rio_linux.h Thu Nov 30 14:50:29 2000
@@ -94,29 +94,28 @@
recompile.... */
#if 1
#define rio_spin_lock_irqsave(sem, flags) do { \
+ spin_lock_irqsave(sem, flags);\
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
- sem, __FILE__, __LINE__);\
- spin_lock_irqsave(sem, flags);\
- } while (0)
+ sem, __FILE__, __LINE__);\
+ } while (0)
#define rio_spin_unlock_irqrestore(sem, flags) do { \
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
- sem, __FILE__, __LINE__);\
- spin_unlock_irqrestore(sem, flags);\
- } while (0)
-
+ sem, __FILE__, __LINE__);\
+ spin_unlock_irqrestore(sem, flags);\
+ } while (0)
#define rio_spin_lock(sem) do { \
+ spin_lock(sem);\
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
- sem, __FILE__, __LINE__);\
- spin_lock(sem);\
- } while (0)
+ sem, __FILE__, __LINE__);\
+ } while (0)
#define rio_spin_unlock(sem) do { \
rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
- sem, __FILE__, __LINE__);\
- spin_unlock(sem);\
- } while (0)
+ sem, __FILE__, __LINE__);\
+ spin_unlock(sem);\
+ } while (0)
#else
#define rio_spin_lock_irqsave(sem, flags) \
spin_lock_irqsave(sem, flags)
@@ -165,7 +164,7 @@
#define rio_memcpy_fromio memcpy_fromio
#endif
-#define DEBUG
+#define DEBUG 1
/*
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/rioboot.c linux/drivers/char/rio/rioboot.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/rioboot.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/rioboot.c Wed Nov 29 11:35:35 2000
@@ -38,11 +38,11 @@
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/errno.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
#include <asm/semaphore.h>
-
#include <linux/termios.h>
#include <linux/serial.h>
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/riocmd.c linux/drivers/char/rio/riocmd.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/riocmd.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/riocmd.c Thu Nov 30 13:48:19 2000
@@ -38,6 +38,9 @@
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <asm/ptrace.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
@@ -80,7 +83,6 @@
#include "control.h"
#include "cirrus.h"
-
static struct IdentifyRta IdRta;
static struct KillNeighbour KillUnit;
@@ -548,6 +550,8 @@
*/
if (PortP->gs.tty == NULL)
break;
+ if (PortP->gs.tty->termios == NULL)
+ break;
if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
@@ -622,7 +626,8 @@
struct CmdBlk *CmdBlkP;
CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
- bzero(CmdBlkP, sizeof(struct CmdBlk));
+ if (CmdBlkP)
+ bzero(CmdBlkP, sizeof(struct CmdBlk));
return CmdBlkP;
}
@@ -782,6 +787,7 @@
** routine that uses the RUP lock.
*/
rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
+
FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
if (PacketP->data[5] == MEMDUMP) {
rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/rioinit.c linux/drivers/char/rio/rioinit.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/rioinit.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/rioinit.c Wed Nov 29 11:35:35 2000
@@ -1446,7 +1446,7 @@
}
RIODefaultName(p, HostP, rup);
}
- HostP->UnixRups[rup].RupLock = -1;
+ HostP->UnixRups[rup].RupLock = SPIN_LOCK_UNLOCKED;
}
}
}
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/riointr.c linux/drivers/char/rio/riointr.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/riointr.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/riointr.c Thu Nov 30 15:22:08 2000
@@ -273,7 +273,7 @@
for ( host=0; host<p->RIONumHosts; host++ ) {
struct Host *HostP = &p->RIOHosts[host];
- rio_dprintk (RIO_DEBUG_INTR, "riointr() doing host %d type %d\n", host, HostP->Type);
+ rio_dprintk (RIO_DEBUG_INTR, "riointr() doing host %p type %d\n", host, HostP->Type);
switch( HostP->Type ) {
case RIO_AT:
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/riotable.c linux/drivers/char/rio/riotable.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/riotable.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/riotable.c Wed Nov 29 11:35:35 2000
@@ -37,6 +37,8 @@
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/errno.h>
+#include <linux/interrupt.h>
+
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
diff -u -r linux-2.4.0-test12-pre3.clean/drivers/char/rio/riotty.c linux/drivers/char/rio/riotty.c
--- linux-2.4.0-test12-pre3.clean/drivers/char/rio/riotty.c Fri Aug 11 23:51:33 2000
+++ linux/drivers/char/rio/riotty.c Thu Nov 30 13:49:21 2000
@@ -95,7 +95,7 @@
#endif
static void RIOClearUp(struct Port *PortP);
-static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
+int RIOShortCommand(struct rio_info *p, struct Port *PortP,
int command, int len, int arg);
@@ -451,8 +451,11 @@
PortP->gs.tty->termios->c_state |= WOPEN;
*/
PortP->State |= RIO_WOPEN;
+ rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+ if (RIODelay (PortP, HUNDRED_MS) == RIO_FAIL)
#if 0
if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
+#endif
{
/*
** ACTION: verify that this is a good thing
@@ -470,7 +473,6 @@
func_exit ();
return -EINTR;
}
-#endif
}
PortP->State &= ~RIO_WOPEN;
}
@@ -507,6 +509,7 @@
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
+
func_exit ();
return 0;
}
@@ -526,8 +529,10 @@
#endif
struct Port *PortP =ptr; /* pointer to the port structure */
int deleted = 0;
- int try = 25;
- int repeat_this = 0xff;
+ int try = -1; /* Disable the timeouts by setting them to -1 */
+ int repeat_this = -1; /* Congrats to those having 15 years of
+ uptime! (You get to break the driver.) */
+ long end_time;
struct tty_struct * tty;
unsigned long flags;
int Modem;
@@ -540,6 +545,12 @@
/* tp = PortP->TtyP;*/ /* Get tty */
tty = PortP->gs.tty;
rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
+
+ if (PortP->gs.closing_wait)
+ end_time = jiffies + PortP->gs.closing_wait;
+ else
+ end_time = jiffies + MAX_SCHEDULE_TIMEOUT;
+
Modem = rio_ismodem(tty->device);
#if 0
/* What F.CKING cache? Even then, a higly idle multiprocessor,
@@ -572,7 +583,8 @@
** clear the open bits for this device
*/
PortP->State &= (Modem ? ~RIO_MOPEN : ~RIO_LOPEN);
-
+ PortP->State &= ~RIO_CARR_ON;
+ PortP->ModemState &= ~MSVR1_CD;
/*
** If the device was open as both a Modem and a tty line
** then we need to wimp out here, as the port has not really
@@ -604,7 +616,7 @@
*/
rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
-#if 0
+
if (!deleted)
while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted &&
(PortP->TxBufferIn != PortP->TxBufferOut) ) {
@@ -625,7 +637,7 @@
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
}
-#endif
+
PortP->TxBufferIn = PortP->TxBufferOut = 0;
repeat_this = 0xff;
@@ -661,7 +673,7 @@
if (!deleted)
while (try && (PortP->PortState & PORT_ISOPEN)) {
try--;
- if (try == 0) {
+ if (time_after (jiffies, end_time)) {
rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
RIOPreemptiveCmd(p, PortP,FCLOSE);
break;
@@ -673,7 +685,11 @@
RIOClearUp( PortP );
goto close_end;
}
- RIODelay_ni(PortP, HUNDRED_MS);
+ if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
+ rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
+ RIOPreemptiveCmd(p, PortP,FCLOSE);
+ break;
+ }
}
rio_spin_lock_irqsave(&PortP->portSem, flags);
rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
@@ -778,7 +794,7 @@
** Other values of len aren't allowed, and will cause
** a panic.
*/
-static int RIOShortCommand(struct rio_info *p, struct Port *PortP,
+int RIOShortCommand(struct rio_info *p, struct Port *PortP,
int command, int len, int arg)
{
PKT *PacketP;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] rio
@ 2000-12-01 12:40 Patrick van de Lageweg
2000-12-01 15:39 ` Rogier Wolff
0 siblings, 1 reply; 5+ messages in thread
From: Patrick van de Lageweg @ 2000-12-01 12:40 UTC (permalink / raw)
To: Alan Cox; +Cc: Rogier Wolff, Linux Kernel Mailing List
Hi alan,
This patches fixes several isues with the rio driver:
- Implemented breaks
- Fixed a DCD up/down crash
- Added kmalloc return value check
Sorry for the late moment we submit this: the DCD bug was very, very hard
to find.
Patrick
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rio
2000-12-01 12:40 [PATCH] rio Patrick van de Lageweg
@ 2000-12-01 15:39 ` Rogier Wolff
0 siblings, 0 replies; 5+ messages in thread
From: Rogier Wolff @ 2000-12-01 15:39 UTC (permalink / raw)
To: Patrick van de Lageweg; +Cc: Alan Cox, Rogier Wolff, Linux Kernel Mailing List
Patrick van de Lageweg wrote:
> Hi alan,
>
> This patches fixes several isues with the rio driver:
>
> - Implemented breaks
> - Fixed a DCD up/down crash
> - Added kmalloc return value check
Hmm. And introduces a new problem. Sorry. Please ignore this patch...
Roger.
--
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
* There are old pilots, and there are bold pilots.
* There are also old, bald pilots.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] RIO
@ 2004-12-08 13:29 Patrick van de Lageweg
2004-12-08 13:57 ` Christoph Hellwig
0 siblings, 1 reply; 5+ messages in thread
From: Patrick van de Lageweg @ 2004-12-08 13:29 UTC (permalink / raw)
To: Linus Torvalds
Cc: Linux Kernel list, Rogier Wolff, Eric Wood, bmckinlay, tmckinlay
[-- Attachment #1: Type: text/plain, Size: 330 bytes --]
Hi,
This patch converts all save_flags/restore_flags to the new
spin_lick_irqsave/spin_unlock_irqrestore calls, as well as some
other 2.6.X cleanups. This allows the "rio" driver to become
SMP safe.
Signed-off-by: Patrick vd Lageweg <patrick@bitwizard.nl>
Signed-off-by: Rogier Wolff <R.E.Wolff@BitWizard.nl>
Patrick
[-- Attachment #2: patch-08122004-2.6.10-rc3-rio --]
[-- Type: text/plain, Size: 6356 bytes --]
diff -u -r linux-2.6.10-rc3-clean/drivers/char/Kconfig linux-2.6.10-rc3-rio/drivers/char/Kconfig
--- linux-2.6.10-rc3-clean/drivers/char/Kconfig Fri Dec 3 15:13:32 2004
+++ linux-2.6.10-rc3-rio/drivers/char/Kconfig Fri Dec 3 15:28:48 2004
@@ -299,7 +299,7 @@
config RIO
tristate "Specialix RIO system support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD
help
This is a driver for the Specialix RIO, a smart serial card which
drives an outboard box that can support up to 128 ports. Product
diff -u -r linux-2.6.10-rc3-clean/drivers/char/rio/linux_compat.h linux-2.6.10-rc3-rio/drivers/char/rio/linux_compat.h
--- linux-2.6.10-rc3-clean/drivers/char/rio/linux_compat.h Fri Dec 3 15:11:52 2004
+++ linux-2.6.10-rc3-rio/drivers/char/rio/linux_compat.h Fri Dec 3 15:28:48 2004
@@ -19,8 +19,8 @@
#include <linux/interrupt.h>
-#define disable(oldspl) save_flags (oldspl)
-#define restore(oldspl) restore_flags (oldspl)
+#define disable(oldspl) local_irq_save(oldspl);
+#define restore(oldspl) local_irq_restore(oldspl) ;
#define sysbrk(x) kmalloc ((x),in_interrupt()? GFP_ATOMIC : GFP_KERNEL)
#define sysfree(p,size) kfree ((p))
diff -u -r linux-2.6.10-rc3-clean/drivers/char/rio/rio_linux.c linux-2.6.10-rc3-rio/drivers/char/rio/rio_linux.c
--- linux-2.6.10-rc3-clean/drivers/char/rio/rio_linux.c Fri Dec 3 15:13:33 2004
+++ linux-2.6.10-rc3-rio/drivers/char/rio/rio_linux.c Fri Dec 3 15:28:48 2004
@@ -354,7 +354,7 @@
int rio_minor(struct tty_struct *tty)
{
- return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+ return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
}
@@ -405,6 +405,8 @@
static irqreturn_t rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
{
struct Host *HostP;
+ int old_debug=rio_debug;
+ rio_debug=0;
func_enter ();
HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
@@ -458,12 +460,14 @@
rio_reset_interrupt (HostP);
}
- if ((HostP->Flags & RUN_STATE) != RC_RUNNING)
+ if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
+ rio_debug=old_debug;
return IRQ_HANDLED;
-
+ }
if (test_and_set_bit (RIO_BOARD_INTR_LOCK, &HostP->locks)) {
printk (KERN_ERR "Recursive interrupt! (host %d/irq%d)\n",
(int) ptr, HostP->Ivec);
+ rio_debug=old_debug;
return IRQ_HANDLED;
}
@@ -476,6 +480,7 @@
rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n",
irq, HostP->Ivec);
func_exit ();
+rio_debug=old_debug;
return IRQ_HANDLED;
}
@@ -726,6 +731,9 @@
rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg);
break;
#if 0
+ /* As far as we know this is impossible -- PVDL */
+
+
/*
* note: these IOCTLs no longer reach here. Use
* tiocmset/tiocmget driver methods instead. The
@@ -980,6 +988,7 @@
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &rio_real_driver;
port->portSem = SPIN_LOCK_UNLOCKED;
+ port->gs.driver_lock = SPIN_LOCK_UNLOCKED;
/*
* Initializing wait queue
*/
@@ -1048,7 +1057,7 @@
void fix_rio_pci (struct pci_dev *pdev)
{
unsigned int hwbase;
- unsigned long rebase;
+ char *rebase;
unsigned int t;
#define CNTRL_REG_OFFSET 0x50
@@ -1056,7 +1065,7 @@
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
- rebase = (ulong) ioremap(hwbase, 0x80);
+ rebase = ioremap(hwbase, 0x80);
t = readl (rebase + CNTRL_REG_OFFSET);
if (t != CNTRL_REG_GOODVALUE) {
printk (KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n",
@@ -1137,7 +1146,7 @@
if (((1 << hp->Ivec) & rio_irqmask) == 0)
hp->Ivec = 0;
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
- hp->CardP = (struct DpRam *) hp->Caddr;
+ hp->CardP = (struct DpRam *) hp->Caddr;
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
@@ -1195,7 +1204,7 @@
hp->Ivec = 0;
hp->Ivec |= 0x8000; /* Mark as non-sharable */
hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
- hp->CardP = (struct DpRam *) hp->Caddr;
+ hp->CardP = (struct DpRam *) hp->Caddr;
hp->Type = RIO_PCI;
hp->Copy = rio_pcicopy;
hp->Mode = RIO_PCI_BOOT_FROM_RAM;
diff -u -r linux-2.6.10-rc3-clean/drivers/char/rio/riotty.c linux-2.6.10-rc3-rio/drivers/char/rio/riotty.c
--- linux-2.6.10-rc3-clean/drivers/char/rio/riotty.c Sat Aug 14 07:36:56 2004
+++ linux-2.6.10-rc3-rio/drivers/char/rio/riotty.c Fri Dec 3 15:28:48 2004
@@ -202,7 +202,10 @@
}
tty->driver_data = PortP;
-
+
+ if (PortP->gs.flags & ASYNC_CLOSING){
+ interruptible_sleep_on(&PortP->gs.close_wait);
+ }
PortP->gs.tty = tty;
PortP->gs.count++;
@@ -408,6 +411,7 @@
bombout:
/* RIOClearUp( PortP ); */
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+ func_exit ();
return retval;
}
rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
@@ -458,15 +462,19 @@
*/
rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
SysPort);
- RIOPreemptiveCmd( p, PortP, FCLOSE );
+
+ // Do not close port on RTA if the port has multiple opens.
+ if( PortP->gs.count <= 1 )
+ RIOPreemptiveCmd( p, PortP, FCLOSE );
+
/*
tp->tm.c_state &= ~WOPEN;
*/
PortP->State &= ~RIO_WOPEN;
- rio_spin_unlock_irqrestore(&PortP->portSem, flags);
func_exit ();
return -EINTR;
}
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
}
PortP->State &= ~RIO_WOPEN;
}
@@ -525,7 +533,7 @@
int try = -1; /* Disable the timeouts by setting them to -1 */
int repeat_this = -1; /* Congrats to those having 15 years of
uptime! (You get to break the driver.) */
- long end_time;
+ unsigned long end_time;
struct tty_struct * tty;
unsigned long flags;
int Modem;
@@ -659,6 +667,7 @@
if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
RIOPreemptiveCmd(p, PortP,FCLOSE);
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
}
@@ -675,6 +684,7 @@
if ( p->RIOHalted ) {
RIOClearUp( PortP );
+ rio_spin_lock_irqsave(&PortP->portSem, flags);
goto close_end;
}
if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] RIO
2004-12-08 13:29 [PATCH] RIO Patrick van de Lageweg
@ 2004-12-08 13:57 ` Christoph Hellwig
0 siblings, 0 replies; 5+ messages in thread
From: Christoph Hellwig @ 2004-12-08 13:57 UTC (permalink / raw)
To: Patrick van de Lageweg
Cc: Linus Torvalds, Linux Kernel list, Rogier Wolff, Eric Wood,
bmckinlay, tmckinlay
On Wed, Dec 08, 2004 at 02:29:51PM +0100, Patrick van de Lageweg wrote:
> Hi,
>
> This patch converts all save_flags/restore_flags to the new
> spin_lick_irqsave/spin_unlock_irqrestore calls, as well as some
> other 2.6.X cleanups. This allows the "rio" driver to become
> SMP safe.
>
>
> Signed-off-by: Patrick vd Lageweg <patrick@bitwizard.nl>
> Signed-off-by: Rogier Wolff <R.E.Wolff@BitWizard.nl>
>
> Patrick
> diff -u -r linux-2.6.10-rc3-clean/drivers/char/Kconfig linux-2.6.10-rc3-rio/drivers/char/Kconfig
> --- linux-2.6.10-rc3-clean/drivers/char/Kconfig Fri Dec 3 15:13:32 2004
> +++ linux-2.6.10-rc3-rio/drivers/char/Kconfig Fri Dec 3 15:28:48 2004
> @@ -299,7 +299,7 @@
>
> config RIO
> tristate "Specialix RIO system support"
> - depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
> + depends on SERIAL_NONSTANDARD
> help
> This is a driver for the Specialix RIO, a smart serial card which
> drives an outboard box that can support up to 128 ports. Product
> diff -u -r linux-2.6.10-rc3-clean/drivers/char/rio/linux_compat.h linux-2.6.10-rc3-rio/drivers/char/rio/linux_compat.h
> --- linux-2.6.10-rc3-clean/drivers/char/rio/linux_compat.h Fri Dec 3 15:11:52 2004
> +++ linux-2.6.10-rc3-rio/drivers/char/rio/linux_compat.h Fri Dec 3 15:28:48 2004
> @@ -19,8 +19,8 @@
> #include <linux/interrupt.h>
>
>
> -#define disable(oldspl) save_flags (oldspl)
> -#define restore(oldspl) restore_flags (oldspl)
> +#define disable(oldspl) local_irq_save(oldspl);
> +#define restore(oldspl) local_irq_restore(oldspl) ;
This looks broken. local_irq_* really isn't for driver use except for
exception case. Also please kill such silly wrappers..
>
> #define sysbrk(x) kmalloc ((x),in_interrupt()? GFP_ATOMIC : GFP_KERNEL)
> #define sysfree(p,size) kfree ((p))
dito here. Also the in_interrupt() check is wrong.
Looking at the driver with it's deep mess and K&R prototypes you might
be better off with a start from scratch.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-12-08 13:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-08 13:29 [PATCH] RIO Patrick van de Lageweg
2004-12-08 13:57 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2000-12-01 12:40 [PATCH] rio Patrick van de Lageweg
2000-12-01 15:39 ` Rogier Wolff
2000-11-30 14:38 Patrick van de Lageweg
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.