Skip to content

Commit

Permalink
- Implement iclear methods for QUICC and SAB 82532. With r253161 in p…
Browse files Browse the repository at this point in the history
…lace,

  this is is crucial at least for the latter.
  What happens is that attaching uart(4) to scc(4) causes the SAB 82532 to
  "receive" something and trigger a SER_INT_RXREADY interrupt, given that
  at least fast/filter interrupts are already enabled. Prior to r253161,
  uart_bus_ihand() was set up at this point and handled that condition,
  i. e. read the RX FIFO and issued a Receive Message Complete.
  Now, uart_bus_ihand() and uart_intr() are setup after attaching uart(4),
  leaving the SER_INT_RXREADY interrupt triggered during the latter to
  be handled by the iclear method. However, with that method not implement,
  this in turn causes SAB 82532 to not issue any further SER_INT_RXREADY
  interrupts until the RX FIFO is full again. Thus, 15 received bytes go
  to nowhere, given that "the other half" of the RX FIFO is used for status
  information. Hence, implementing sab82532_bfe_iclear() fixes things again.
  Potentially, the same problem exists for QUICC.
- Remove unnecessary __RMAN_RESOURCE_VISIBLE.
- Remove a superfluous header.
- Use KOBJMETHOD_END.
- Mark unused arguments as such.
- Remove variables unused after initialization.

Reviewed by:	marcel (earlier version)
  • Loading branch information
sparcplug committed Aug 2, 2013
1 parent 4e4d1a0 commit ea5d5d3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 24 deletions.
24 changes: 14 additions & 10 deletions sys/dev/scc/scc_dev_quicc.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,10 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#define __RMAN_RESOURCE_VISIBLE

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/endian.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/serial.h>
Expand Down Expand Up @@ -63,7 +60,7 @@ static kobj_method_t quicc_methods[] = {
KOBJMETHOD(scc_iclear, quicc_bfe_iclear),
KOBJMETHOD(scc_ipend, quicc_bfe_ipend),
KOBJMETHOD(scc_probe, quicc_bfe_probe),
{ 0, 0 }
KOBJMETHOD_END
};

struct scc_class scc_quicc_class = {
Expand All @@ -77,11 +74,9 @@ struct scc_class scc_quicc_class = {
};

static int
quicc_bfe_attach(struct scc_softc *sc, int reset)
quicc_bfe_attach(struct scc_softc *sc __unused, int reset __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}

Expand All @@ -104,7 +99,18 @@ quicc_bfe_enabled(struct scc_softc *sc, struct scc_chan *ch)
static int
quicc_bfe_iclear(struct scc_softc *sc, struct scc_chan *ch)
{
struct scc_bas *bas;
uint16_t rb, st;

bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
if (ch->ch_ipend & SER_INT_RXREADY) {
rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(ch->ch_nr - 1));
st = quicc_read2(bas, rb);
(void)quicc_read4(bas, rb + 4);
quicc_write2(bas, rb, st | 0x9000);
}
mtx_unlock_spin(&sc->sc_hwmtx);
return (0);
}

Expand Down Expand Up @@ -142,10 +148,8 @@ quicc_bfe_ipend(struct scc_softc *sc)
}

static int
quicc_bfe_probe(struct scc_softc *sc)
quicc_bfe_probe(struct scc_softc *sc __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}
31 changes: 24 additions & 7 deletions sys/dev/scc/scc_dev_sab82532.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static kobj_method_t sab82532_methods[] = {
KOBJMETHOD(scc_iclear, sab82532_bfe_iclear),
KOBJMETHOD(scc_ipend, sab82532_bfe_ipend),
KOBJMETHOD(scc_probe, sab82532_bfe_probe),
{ 0, 0 }
KOBJMETHOD_END
};

struct scc_class scc_sab82532_class = {
Expand All @@ -66,18 +66,37 @@ struct scc_class scc_sab82532_class = {
};

static int
sab82532_bfe_attach(struct scc_softc *sc, int reset)
sab82532_bfe_attach(struct scc_softc *sc __unused, int reset __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}

static int
sab82532_bfe_iclear(struct scc_softc *sc, struct scc_chan *ch)
{
struct scc_bas *bas;
int i, ofs, rbcl;

bas = &sc->sc_bas;
ofs = (ch->ch_nr - 1) * SAB_CHANLEN;
mtx_lock_spin(&sc->sc_hwmtx);
if (ch->ch_ipend & SER_INT_RXREADY) {
if (scc_getreg(bas, ofs + SAB_STAR) & SAB_STAR_RFNE) {
rbcl = scc_getreg(bas, ofs + SAB_RBCL) & 31;
if (rbcl == 0)
rbcl = 32;
for (i = 0; i < rbcl; i += 2) {
(void)scc_getreg(bas, ofs + SAB_RFIFO);
(void)scc_getreg(bas, ofs + SAB_RFIFO + 1);
}
}
while (scc_getreg(bas, ofs + SAB_STAR) & SAB_STAR_CEC)
;
scc_setreg(bas, ofs + SAB_CMDR, SAB_CMDR_RMC);
scc_barrier(bas);
}
mtx_unlock_spin(&sc->sc_hwmtx);
return (0);
}

Expand Down Expand Up @@ -124,10 +143,8 @@ sab82532_bfe_ipend(struct scc_softc *sc)
}

static int
sab82532_bfe_probe(struct scc_softc *sc)
sab82532_bfe_probe(struct scc_softc *sc __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}
10 changes: 3 additions & 7 deletions sys/dev/scc/scc_dev_z8530.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static kobj_method_t z8530_methods[] = {
KOBJMETHOD(scc_iclear, z8530_bfe_iclear),
KOBJMETHOD(scc_ipend, z8530_bfe_ipend),
KOBJMETHOD(scc_probe, z8530_bfe_probe),
{ 0, 0 }
KOBJMETHOD_END
};

struct scc_class scc_z8530_class = {
Expand Down Expand Up @@ -85,11 +85,9 @@ scc_getmreg(struct scc_bas *bas, int ch, int reg)
}

static int
z8530_bfe_attach(struct scc_softc *sc, int reset)
z8530_bfe_attach(struct scc_softc *sc __unused, int reset __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}

Expand Down Expand Up @@ -189,10 +187,8 @@ z8530_bfe_ipend(struct scc_softc *sc)
}

static int
z8530_bfe_probe(struct scc_softc *sc)
z8530_bfe_probe(struct scc_softc *sc __unused)
{
struct scc_bas *bas;

bas = &sc->sc_bas;
return (0);
}

0 comments on commit ea5d5d3

Please sign in to comment.