Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/dev/ic Pull up revisions 1.20 (requested by ad):
details: https://anonhg.NetBSD.org/src/rev/266d2b50b60f
branches: netbsd-1-5
changeset: 492649:266d2b50b60f
user: he <he%NetBSD.org@localhost>
date: Tue Jan 29 23:31:01 2002 +0000
description:
Pull up revisions 1.20 (requested by ad):
Some fixes:
o Always validate return value read from outbound FIFO
o Copy access method into to softc to avoid double dereference
o Remove static on functions
Fixes PR#14453.
diffstat:
sys/dev/ic/cac.c | 82 ++++++++++++++++++++++++++++++-------------------------
1 files changed, 45 insertions(+), 37 deletions(-)
diffs (235 lines):
diff -r 4796eaad1d0c -r 266d2b50b60f sys/dev/ic/cac.c
--- a/sys/dev/ic/cac.c Tue Jan 29 23:30:45 2002 +0000
+++ b/sys/dev/ic/cac.c Tue Jan 29 23:31:01 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cac.c,v 1.6.2.3 2001/10/25 18:03:20 he Exp $ */
+/* $NetBSD: cac.c,v 1.6.2.4 2002/01/29 23:31:01 he Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -58,24 +58,24 @@
#include <dev/ic/cacreg.h>
#include <dev/ic/cacvar.h>
-static struct cac_ccb *cac_ccb_alloc(struct cac_softc *, int);
-static void cac_ccb_done(struct cac_softc *, struct cac_ccb *);
-static void cac_ccb_free(struct cac_softc *, struct cac_ccb *);
-static int cac_ccb_poll(struct cac_softc *, struct cac_ccb *, int);
-static int cac_ccb_start(struct cac_softc *, struct cac_ccb *);
-static int cac_print(void *, const char *);
-static void cac_shutdown(void *);
-static int cac_submatch(struct device *, struct cfdata *, void *);
+struct cac_ccb *cac_ccb_alloc(struct cac_softc *, int);
+void cac_ccb_done(struct cac_softc *, struct cac_ccb *);
+void cac_ccb_free(struct cac_softc *, struct cac_ccb *);
+int cac_ccb_poll(struct cac_softc *, struct cac_ccb *, int);
+int cac_ccb_start(struct cac_softc *, struct cac_ccb *);
+int cac_print(void *, const char *);
+void cac_shutdown(void *);
+int cac_submatch(struct device *, struct cfdata *, void *);
-static struct cac_ccb *cac_l0_completed(struct cac_softc *);
-static int cac_l0_fifo_full(struct cac_softc *);
-static void cac_l0_intr_enable(struct cac_softc *, int);
-static int cac_l0_intr_pending(struct cac_softc *);
-static void cac_l0_submit(struct cac_softc *, struct cac_ccb *);
+struct cac_ccb *cac_l0_completed(struct cac_softc *);
+int cac_l0_fifo_full(struct cac_softc *);
+void cac_l0_intr_enable(struct cac_softc *, int);
+int cac_l0_intr_pending(struct cac_softc *);
+void cac_l0_submit(struct cac_softc *, struct cac_ccb *);
static void *cac_sdh; /* shutdown hook */
-struct cac_linkage cac_l0 = {
+const struct cac_linkage cac_l0 = {
cac_l0_completed,
cac_l0_fifo_full,
cac_l0_intr_enable,
@@ -182,14 +182,14 @@
if (cac_sdh == NULL)
cac_sdh = shutdownhook_establish(cac_shutdown, NULL);
- (*sc->sc_cl->cl_intr_enable)(sc, CAC_INTR_ENABLE);
+ (*sc->sc_cl.cl_intr_enable)(sc, CAC_INTR_ENABLE);
return (0);
}
/*
* Shut down all `cac' controllers.
*/
-static void
+void
cac_shutdown(void *cookie)
{
extern struct cfdriver cac_cd;
@@ -210,7 +210,7 @@
/*
* Print autoconfiguration message for a sub-device.
*/
-static int
+int
cac_print(void *aux, const char *pnp)
{
struct cac_attach_args *caca;
@@ -226,7 +226,7 @@
/*
* Match a sub-device.
*/
-static int
+int
cac_submatch(struct device *parent, struct cfdata *cf, void *aux)
{
struct cac_attach_args *caca;
@@ -252,14 +252,14 @@
sc = (struct cac_softc *)cookie;
- if (!(*sc->sc_cl->cl_intr_pending)(sc)) {
+ if (!(*sc->sc_cl.cl_intr_pending)(sc)) {
#ifdef DEBUG
printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
#endif
return (0);
}
- while ((ccb = (*sc->sc_cl->cl_completed)(sc)) != NULL) {
+ while ((ccb = (*sc->sc_cl.cl_completed)(sc)) != NULL) {
cac_ccb_done(sc, ccb);
cac_ccb_start(sc, NULL);
}
@@ -325,14 +325,14 @@
s = splbio();
/* Synchronous commands musn't wait. */
- if ((*sc->sc_cl->cl_fifo_full)(sc)) {
+ if ((*sc->sc_cl.cl_fifo_full)(sc)) {
cac_ccb_free(sc, ccb);
rv = -1;
} else {
#ifdef DIAGNOSTIC
ccb->ccb_flags |= CAC_CCB_ACTIVE;
#endif
- (*sc->sc_cl->cl_submit)(sc, ccb);
+ (*sc->sc_cl.cl_submit)(sc, ccb);
rv = cac_ccb_poll(sc, ccb, 2000);
cac_ccb_free(sc, ccb);
}
@@ -349,7 +349,7 @@
/*
* Wait for the specified CCB to complete. Must be called at splbio.
*/
-static int
+int
cac_ccb_poll(struct cac_softc *sc, struct cac_ccb *wantccb, int timo)
{
struct cac_ccb *ccb;
@@ -358,13 +358,14 @@
do {
for (; timo != 0; timo--) {
- if ((ccb = (*sc->sc_cl->cl_completed)(sc)) != NULL)
+ ccb = (*sc->sc_cl.cl_completed)(sc);
+ if (ccb != NULL)
break;
DELAY(100);
}
if (timo == 0) {
- printf("%s: timeout", sc->sc_dv.dv_xname);
+ printf("%s: timeout\n", sc->sc_dv.dv_xname);
return (EBUSY);
}
cac_ccb_done(sc, ccb);
@@ -377,7 +378,7 @@
* Enqueue the specifed command (if any) and attempt to start all enqueued
* commands. Must be called at splbio.
*/
-static int
+int
cac_ccb_start(struct cac_softc *sc, struct cac_ccb *ccb)
{
@@ -385,13 +386,13 @@
SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ccb, ccb_chain);
while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
- if ((*sc->sc_cl->cl_fifo_full)(sc))
+ if ((*sc->sc_cl.cl_fifo_full)(sc))
return (EBUSY);
SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ccb, ccb_chain);
#ifdef DIAGNOSTIC
ccb->ccb_flags |= CAC_CCB_ACTIVE;
#endif
- (*sc->sc_cl->cl_submit)(sc, ccb);
+ (*sc->sc_cl.cl_submit)(sc, ccb);
}
return (0);
@@ -400,7 +401,7 @@
/*
* Process a finished CCB.
*/
-static void
+void
cac_ccb_done(struct cac_softc *sc, struct cac_ccb *ccb)
{
struct device *dv;
@@ -488,14 +489,14 @@
* Board specific linkage shared between multiple bus types.
*/
-static int
+int
cac_l0_fifo_full(struct cac_softc *sc)
{
return (cac_inl(sc, CAC_REG_CMD_FIFO) == 0);
}
-static void
+void
cac_l0_submit(struct cac_softc *sc, struct cac_ccb *ccb)
{
@@ -504,13 +505,20 @@
cac_outl(sc, CAC_REG_CMD_FIFO, ccb->ccb_paddr);
}
-static struct cac_ccb *
+struct cac_ccb *
cac_l0_completed(struct cac_softc *sc)
{
struct cac_ccb *ccb;
paddr_t off;
- off = (cac_inl(sc, CAC_REG_DONE_FIFO) & ~3) - sc->sc_ccbs_paddr;
+ if ((off = cac_inl(sc, CAC_REG_DONE_FIFO)) == 0)
+ return (NULL);
+
+ if ((off & 3) != 0)
+ printf("%s: failed command list returned: %lx\n",
+ sc->sc_dv.dv_xname, (long)off);
+
+ off = (off & ~3) - sc->sc_ccbs_paddr;
ccb = (struct cac_ccb *)(sc->sc_ccbs + off);
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, off, sizeof(struct cac_ccb),
@@ -519,14 +527,14 @@
return (ccb);
}
-static int
+int
cac_l0_intr_pending(struct cac_softc *sc)
{
- return (cac_inl(sc, CAC_REG_INTR_PENDING));
+ return (cac_inl(sc, CAC_REG_INTR_PENDING) & CAC_INTR_ENABLE);
}
-static void
+void
cac_l0_intr_enable(struct cac_softc *sc, int state)
{
Home |
Main Index |
Thread Index |
Old Index