Applied a patch by Toru Nishimura:
Fixed kmutex usage error and replaced tsleep by cv_waitsig. Now "cat /dev/satmgr" no longer panics when pressing a button.
This commit is contained in:
parent
d71ac89211
commit
7e7ef0c0e2
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: satmgr.c,v 1.1 2010/05/29 22:47:02 phx Exp $ */
|
||||
/* $NetBSD: satmgr.c,v 1.2 2010/06/03 10:44:21 phx Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
|
@ -59,7 +59,6 @@ struct satmgr_softc {
|
|||
device_t sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
kmutex_t sc_lock;
|
||||
struct selinfo sc_rsel;
|
||||
callout_t sc_ch_wdog;
|
||||
callout_t sc_ch_pbutton;
|
||||
|
@ -67,6 +66,8 @@ struct satmgr_softc {
|
|||
int sc_open;
|
||||
void *sc_si;
|
||||
uint32_t sc_ierror, sc_overr;
|
||||
kmutex_t sc_lock;
|
||||
kcondvar_t sc_rdcv, sc_wrcv;
|
||||
char sc_rd_buf[16], *sc_rd_lim, *sc_rd_cur, *sc_rd_ptr;
|
||||
char sc_wr_buf[16], *sc_wr_lim, *sc_wr_cur, *sc_wr_ptr;
|
||||
int sc_rd_cnt, sc_wr_cnt;
|
||||
|
@ -100,6 +101,7 @@ static void wdog_tickle(void *);
|
|||
static void send_sat(struct satmgr_softc *, const char *);
|
||||
static int hwintr(void *);
|
||||
static void rxintr(struct satmgr_softc *);
|
||||
static void txintr(struct satmgr_softc *);
|
||||
static void startoutput(struct satmgr_softc *);
|
||||
static void swintr(void *);
|
||||
static void kbutton(struct satmgr_softc *, int);
|
||||
|
@ -114,11 +116,12 @@ struct satmsg {
|
|||
void (*dispatch)(struct satmgr_softc *, int);
|
||||
};
|
||||
|
||||
const struct satmsg satmodel[] = {
|
||||
static const struct satmsg satmodel[] = {
|
||||
{ "kurobox", "CCGG", "EEGG", kbutton },
|
||||
{ "synology", "C", "1", sbutton },
|
||||
{ "qnap", "f", "A", qbutton }
|
||||
} *satmgr_msg;
|
||||
};
|
||||
static const struct satmsg *satmgr_msg;
|
||||
|
||||
/* single byte stride register layout */
|
||||
#define RBR 0
|
||||
|
@ -182,10 +185,13 @@ satmgr_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_wr_cnt = 0;
|
||||
sc->sc_wr_cur = sc->sc_wr_ptr = &sc->sc_wr_buf[0];
|
||||
sc->sc_wr_lim = sc->sc_wr_cur + sizeof(sc->sc_wr_buf);
|
||||
sc->sc_ierror = sc->sc_overr = 0;
|
||||
selinit(&sc->sc_rsel);
|
||||
callout_init(&sc->sc_ch_wdog, 0);
|
||||
callout_init(&sc->sc_ch_pbutton, 0);
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
|
||||
cv_init(&sc->sc_rdcv, "satrd");
|
||||
cv_init(&sc->sc_wrcv, "satwr");
|
||||
|
||||
epicirq = (eaa->eumb_unit == 0) ? 24 : 25;
|
||||
intr_establish(epicirq + 16, IST_LEVEL, IPL_SERIAL, hwintr, sc);
|
||||
|
@ -345,12 +351,14 @@ satread(dev_t dev, struct uio *uio, int flags)
|
|||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
mutex_spin_enter(&sc->sc_lock);
|
||||
if (sc->sc_rd_cnt == 0 && (flags & IO_NDELAY))
|
||||
return EWOULDBLOCK;
|
||||
mutex_enter(&sc->sc_lock);
|
||||
if (sc->sc_rd_cnt == 0 && (flags & IO_NDELAY)) {
|
||||
error = EWOULDBLOCK;
|
||||
goto out;
|
||||
}
|
||||
error = 0;
|
||||
while (sc->sc_rd_cnt == 0) {
|
||||
error = tsleep(sc->sc_rd_buf, PZERO|PCATCH, "satrd", 0);
|
||||
error = cv_wait_sig(&sc->sc_rdcv, &sc->sc_lock);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
@ -366,7 +374,7 @@ satread(dev_t dev, struct uio *uio, int flags)
|
|||
sc->sc_rd_ptr = &sc->sc_rd_buf[0];
|
||||
}
|
||||
out:
|
||||
mutex_spin_exit(&sc->sc_lock);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -381,12 +389,14 @@ satwrite(dev_t dev, struct uio *uio, int flags)
|
|||
if (sc == NULL)
|
||||
return ENXIO;
|
||||
|
||||
mutex_spin_enter(&sc->sc_lock);
|
||||
if (sc->sc_wr_cnt == sizeof(sc->sc_wr_buf) && (flags & IO_NDELAY))
|
||||
return EWOULDBLOCK;
|
||||
mutex_enter(&sc->sc_lock);
|
||||
if (sc->sc_wr_cnt == sizeof(sc->sc_wr_buf) && (flags & IO_NDELAY)) {
|
||||
error = EWOULDBLOCK;
|
||||
goto out;
|
||||
}
|
||||
error = 0;
|
||||
while (sc->sc_wr_cnt == sizeof(sc->sc_wr_buf)) {
|
||||
error = tsleep(sc->sc_wr_buf, PZERO|PCATCH, "satwr", 0);
|
||||
error = cv_wait_sig(&sc->sc_wrcv, &sc->sc_lock);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
@ -403,7 +413,7 @@ satwrite(dev_t dev, struct uio *uio, int flags)
|
|||
}
|
||||
startoutput(sc); /* start xmit */
|
||||
out:
|
||||
mutex_spin_exit(&sc->sc_lock);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -448,7 +458,7 @@ filt_read(struct knote *kn, long hint)
|
|||
static const struct filterops read_filtops =
|
||||
{ 1, NULL, filt_rdetach, filt_read };
|
||||
|
||||
int
|
||||
static int
|
||||
satkqfilter(dev_t dev, struct knote *kn)
|
||||
{
|
||||
struct satmgr_softc *sc = device_lookup_private(&satmgr_cd, 0);
|
||||
|
@ -493,7 +503,7 @@ hwintr(void *arg)
|
|||
rxintr(sc);
|
||||
break;
|
||||
case IIR_TXRDY: /* TxFIFO is ready to swallow data */
|
||||
startoutput(sc);
|
||||
txintr(sc);
|
||||
break;
|
||||
case IIR_MLSC: /* MSR updated */
|
||||
break;
|
||||
|
@ -533,6 +543,14 @@ rxintr(struct satmgr_softc *sc)
|
|||
softint_schedule(sc->sc_si);
|
||||
}
|
||||
|
||||
static void
|
||||
txintr(struct satmgr_softc *sc)
|
||||
{
|
||||
|
||||
cv_signal(&sc->sc_wrcv);
|
||||
startoutput(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
startoutput(struct satmgr_softc *sc)
|
||||
{
|
||||
|
@ -555,6 +573,7 @@ swintr(void *arg)
|
|||
int n;
|
||||
|
||||
/* we're now in softint(9) context */
|
||||
mutex_spin_enter(&sc->sc_lock);
|
||||
ptr = sc->sc_rd_ptr;
|
||||
for (n = 0; n < sc->sc_rd_cnt; n++) {
|
||||
(*satmgr_msg->dispatch)(sc, *ptr);
|
||||
|
@ -564,13 +583,15 @@ swintr(void *arg)
|
|||
if (sc->sc_open == 0) {
|
||||
sc->sc_rd_cnt = 0;
|
||||
sc->sc_rd_ptr = ptr;
|
||||
mutex_spin_exit(&sc->sc_lock);
|
||||
return; /* drop characters down to floor */
|
||||
}
|
||||
wakeup(sc->sc_rd_buf);
|
||||
cv_signal(&sc->sc_rdcv);
|
||||
selnotify(&sc->sc_rsel, 0, 0);
|
||||
mutex_spin_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
kbutton(struct satmgr_softc *sc, int ch)
|
||||
{
|
||||
|
||||
|
@ -594,7 +615,7 @@ kbutton(struct satmgr_softc *sc, int ch)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
sbutton(struct satmgr_softc *sc, int ch)
|
||||
{
|
||||
|
||||
|
@ -603,13 +624,13 @@ sbutton(struct satmgr_softc *sc, int ch)
|
|||
/* notified after 3 secord guard time */
|
||||
sysmon_task_queue_sched(0, sched_sysmon_pbutton, sc);
|
||||
break;
|
||||
case '?':
|
||||
case 'a':
|
||||
case '`':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
qbutton(struct satmgr_softc *sc, int ch)
|
||||
{
|
||||
/* research in progress */
|
||||
|
|
Loading…
Reference in New Issue