Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Oct 2006 21:11:40 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108438 for review
Message-ID:  <200610252111.k9PLBeLx085707@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108438

Change 108438 by imp@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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610252111.k9PLBeLx085707>