kern/109152: [rp] RocketPort panic from device_unbusy()
Doug Ambrisko
ambrisko at ambrisko.com
Thu Mar 15 04:30:08 UTC 2007
The following reply was made to PR kern/109152; it has been noted by GNATS.
From: Doug Ambrisko <ambrisko at ambrisko.com>
To: Craig Leres <leres at ee.lbl.gov>
Cc: bug-followup at FreeBSD.org
Subject: Re: kern/109152: [rp] RocketPort panic from device_unbusy()
Date: Wed, 14 Mar 2007 19:55:48 -0800 (PST)
Craig Leres writes:
| I was still able to crash Doug Ambrisko's version of the rp driver.
| I think the problem is that in some cases rp_handle_port() calls
| rpclose() which calls device_unbusy(). Later rpclose() is called
| again and we hit the panic.
|
| I looked at the last known good version of the driver I'd used,
| 1.45.2.2 from 4.10-RELEASE, and found it has code to avoid calling
| rpclose() twice. I did something similar that seems to work.
|
| Note: The appended diffs are against version 1.67.2.2 of rp.c.
|
| Craig
|
| ===================================================================
| RCS file: RCS/rp.c,v
| retrieving revision 1.2
| retrieving revision 1.3
| diff -c -r1.2 -r1.3
| *** rp.c 2007/03/08 04:07:10 1.2
| --- rp.c 2007/03/14 02:23:17 1.3
| ***************
| *** 573,578 ****
| --- 573,579 ----
|
| static void rpbreak(struct tty *, int);
| static void rpclose(struct tty *tp);
| + static void rphardclose(struct tty *tp);
| static int rpmodem(struct tty *, int, int);
| static int rpparam(struct tty *, struct termios *);
| static void rpstart(struct tty *);
| ***************
| *** 697,703 ****
| if((tp->t_state & TS_CARR_ON)) {
| (void)ttyld_modem(tp, 0);
| if(ttyld_modem(tp, 0) == 0) {
| ! rpclose(tp);
| }
| }
| }
| --- 698,704 ----
| if((tp->t_state & TS_CARR_ON)) {
| (void)ttyld_modem(tp, 0);
| if(ttyld_modem(tp, 0) == 0) {
| ! rphardclose(tp);
| }
| }
| }
| ***************
| *** 936,941 ****
| --- 937,952 ----
| rpclose(struct tty *tp)
| {
| struct rp_port *rp;
| +
| + rp = tp->t_sc;
| + rphardclose(tp);
| + device_unbusy(rp->rp_ctlp->dev);
| + }
| +
| + static void
| + rphardclose(struct tty *tp)
| + {
| + struct rp_port *rp;
| CHANNEL_t *cp;
|
| rp = tp->t_sc;
| ***************
| *** 959,965 ****
| tp->t_actout = FALSE;
| wakeup(&tp->t_actout);
| wakeup(TSA_CARR_ON(tp));
| - device_unbusy(rp->rp_ctlp->dev);
| }
|
| static void
| --- 970,975 ----
|
I wonder if this should be a reference count? Good find.
Doug A.
More information about the freebsd-bugs
mailing list