PERFORCE change 108438 for review
Warner Losh
imp at FreeBSD.org
Wed Oct 25 14:11:49 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=108438
Change 108438 by imp at imp_lighthouse on 2006/10/25 21:11:20
Do interlocking on the write channel. Only one may be there.
All others block. Note: non-blocking I/O will block at this
point. libc_r is dead, so the need to support NBIO isn't
there for our apps anymore.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#14 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#14 (text+ko) ====
@@ -41,6 +41,7 @@
#include <arm/at91/at91_pdcreg.h>
#define MAX_BUF 1024
+#define NRX_BUF 2
struct at91_ssc_softc
{
@@ -51,12 +52,15 @@
struct mtx sc_mtx; /* basically a perimeter lock */
struct cdev *cdev;
int flags;
-#define OPENED 1
+#define OPENED 0x01
+#define WRITE_BUSY 0x02
bus_dma_tag_t tag; /* bus dma tag */
bus_dmamap_t tx_map;
int txdone;
uint8_t rx_buf[MAX_BUF];
- bus_dmamap_t rx_map;
+ uint8_t *rx_end;
+ bus_dmamap_t rx_map[NRX_BUF];
+ int rxdone;
};
static inline uint32_t
@@ -120,7 +124,7 @@
at91_ssc_attach(device_t dev)
{
struct at91_ssc_softc *sc = device_get_softc(dev);
- int err;
+ int err, i;
sc->dev = dev;
err = at91_ssc_activate(dev);
@@ -150,9 +154,11 @@
err = bus_dmamap_create(sc->tag, 0, &sc->tx_map);
if (err != 0)
goto out;
- err = bus_dmamap_create(sc->tag, 0, &sc->rx_map);
- if (err != 0)
- goto out;
+ for (i = 0; i < NRX_BUF; i++) {
+ err = bus_dmamap_create(sc->tag, 0, &sc->rx_map[i]);
+ if (err != 0)
+ goto out;
+ }
sc->cdev = make_dev(&at91_ssc_cdevsw, device_get_unit(dev), UID_ROOT,
GID_WHEEL, 0600, "ssc%d", device_get_unit(dev));
@@ -310,6 +316,15 @@
// must write a multiple of 4 bytes
if ((uio->uio_resid & 0x3) != 0 || uio->uio_resid > MAX_BUF)
return (EINVAL);
+ AT91_SSC_LOCK(sc);
+ err = 0;
+ // XXX non blocking I/O needs to bail here rather than wait.
+ while (err != EINTR && sc->flags & WRITE_BUSY)
+ err = msleep(&sc->txdone, &sc->sc_mtx, PCATCH | PZERO,
+ "sscwr2", 0);
+ if (err == EINTR)
+ return (EINTR);
+ sc->flags |= WRITE_BUSY;
WR4(sc, SSC_CR, SSC_CR_TXDIS);
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
txdone = sc->txdone;
@@ -317,11 +332,13 @@
sc, 0);
if (err != 0 && err != EINPROGRESS)
return (err);
- do {
+ err = 0;
+ while (txdone == sc->txdone && err != EINTR)
err = msleep(&sc->txdone, &sc->sc_mtx, PCATCH | PZERO,
- "sscwr", hz);
- } while (txdone == sc->txdone && err != EINTR);
+ "sscwr", 0);
bus_dmamap_sync(sc->tag, sc->tx_map, BUS_DMASYNC_POSTWRITE);
+ sc->flags &= ~WRITE_BUSY;
+ AT91_SSC_UNLOCK(sc);
if (err == 0)
uio->uio_resid = 0;
return err;
More information about the p4-projects
mailing list