diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-27 13:18:03 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-27 13:18:03 +0000 |
commit | 568b04875d9d783e68f4726ab424be00ca0ae228 (patch) | |
tree | cd30a2d9f0ed5d3881c192afd82273f112a73be6 /sys/dev | |
parent | 3aeaa70bc28f155c6888807b772b5899765d61f4 (diff) |
Timeout service request in the uncommon case that the port is blocked
(there needs to be correct clocking on the port or all service request
will be ignored). Without the timeout the interface will just hang till
reboot. OK deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_art.c | 7 | ||||
-rw-r--r-- | sys/dev/pci/musycc.c | 31 | ||||
-rw-r--r-- | sys/dev/pci/musyccvar.h | 5 |
3 files changed, 39 insertions, 4 deletions
diff --git a/sys/dev/pci/if_art.c b/sys/dev/pci/if_art.c index 1dc42bc6bb5..9a833a6573f 100644 --- a/sys/dev/pci/if_art.c +++ b/sys/dev/pci/if_art.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_art.c,v 1.5 2005/08/14 22:28:47 claudio Exp $ */ +/* $OpenBSD: if_art.c,v 1.6 2005/08/27 13:18:02 claudio Exp $ */ /* * Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland @@ -355,6 +355,11 @@ art_onesec(void *arg) } /* + * run musycc onesec job + */ + musycc_tick(ac->art_channel); + + /* * Schedule another timeout one second from now. */ timeout_add(&ac->art_onesec, hz); diff --git a/sys/dev/pci/musycc.c b/sys/dev/pci/musycc.c index c1f03b68c68..5b89e0becc6 100644 --- a/sys/dev/pci/musycc.c +++ b/sys/dev/pci/musycc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: musycc.c,v 1.5 2005/08/27 13:07:56 claudio Exp $ */ +/* $OpenBSD: musycc.c,v 1.6 2005/08/27 13:18:02 claudio Exp $ */ /* * Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland @@ -1483,9 +1483,11 @@ musycc_sreq(struct musycc_group *mg, int channel, u_int32_t req, int dir, mg->mg_hdlc->mc_dev.dv_xname); \ } while (0) - int needskick; + struct timeval tv; + int needskick; needskick = (mg->mg_sreqpend == mg->mg_sreqprod); + getmicrouptime(&tv); ACCOOM_PRINTF(4, ("musycc_sreq: g# %d c# %d req %x dir %x\n", mg->mg_gnum, channel, req, dir)); @@ -1494,6 +1496,8 @@ musycc_sreq(struct musycc_group *mg, int channel, u_int32_t req, int dir, req &= ~MUSYCC_SREQ_TXDIR & ~MUSYCC_SREQ_MASK; req |= MUSYCC_SREQ_CHSET(channel); mg->mg_sreq[mg->mg_sreqprod].sreq = req; + mg->mg_sreq[mg->mg_sreqprod].timeout = tv.tv_sec + + MUSYCC_SREQTIMEOUT; if (dir == MUSYCC_SREQ_RX) mg->mg_sreq[mg->mg_sreqprod].event = event; else @@ -1504,6 +1508,8 @@ musycc_sreq(struct musycc_group *mg, int channel, u_int32_t req, int dir, req &= ~MUSYCC_SREQ_MASK; req |= MUSYCC_SREQ_TXDIR; req |= MUSYCC_SREQ_CHSET(channel); + mg->mg_sreq[mg->mg_sreqprod].timeout = tv.tv_sec + + MUSYCC_SREQTIMEOUT; mg->mg_sreq[mg->mg_sreqprod].sreq = req; mg->mg_sreq[mg->mg_sreqprod].event = event; MUSYCC_SREQINC(mg->mg_sreqprod, mg->mg_sreqpend); @@ -1515,8 +1521,29 @@ musycc_sreq(struct musycc_group *mg, int channel, u_int32_t req, int dir, #undef MUSYCC_SREQINC } +void +musycc_tick(struct channel_softc *cc) +{ + struct musycc_group *mg = cc->cc_group; + struct timeval tv; + if (mg->mg_sreqpend == mg->mg_sreqprod) + return; + getmicrouptime(&tv); + if (mg->mg_sreq[mg->mg_sreqpend].timeout < tv.tv_sec) { + log(LOG_ERR, "%s: service request timeout\n", + cc->cc_ifp->if_xname); + mg->mg_sreqpend++; + /* digest all timed out SREQ */ + while (mg->mg_sreq[mg->mg_sreqpend].timeout < tv.tv_sec && + mg->mg_sreqpend != mg->mg_sreqprod) + mg->mg_sreqpend++; + + if (mg->mg_sreqpend != mg->mg_sreqprod) + musycc_kick(mg); + } +} /* * Extension Bus API diff --git a/sys/dev/pci/musyccvar.h b/sys/dev/pci/musyccvar.h index 42a99fd4864..b9a024db56f 100644 --- a/sys/dev/pci/musyccvar.h +++ b/sys/dev/pci/musyccvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: musyccvar.h,v 1.4 2005/08/14 22:28:47 claudio Exp $ */ +/* $OpenBSD: musyccvar.h,v 1.5 2005/08/27 13:18:02 claudio Exp $ */ /* * Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland @@ -28,6 +28,7 @@ #define MUSYCC_NUMPORT 8 /* max 8 ports per controller */ #define MUSYCC_SREQNUM 16 /* pending SREQ */ #define MUSYCC_SREQMASK (MUSYCC_SREQNUM - 1) +#define MUSYCC_SREQTIMEOUT 2 /* dma ring sizes */ #define MUSYCC_DMA_CNT 256 @@ -100,6 +101,7 @@ struct musycc_group { int mg_freecnt; struct { + long timeout; u_int32_t sreq; enum musycc_event event; } mg_sreq[MUSYCC_SREQNUM]; @@ -186,6 +188,7 @@ void musycc_stop_channel(struct channel_softc *); void musycc_free_channel(struct musycc_group *, int); void musycc_start(struct ifnet *); void musycc_watchdog(struct ifnet *); +void musycc_tick(struct channel_softc *); int musycc_intr(void *); int ebus_intr(void *); |