Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ieee1394 Various small changes.
details: https://anonhg.NetBSD.org/src/rev/f101d6c5cb7f
branches: trunk
changeset: 509891:f101d6c5cb7f
user: jmc <jmc%NetBSD.org@localhost>
date: Tue May 15 06:52:30 2001 +0000
description:
Various small changes.
Clean up one bug in a DPRINTF in arrs_input which could panic on some packets.
Gut the ack/response functionality and clean it up so all packets get checked
correctly and the abuf struct isn't used once the ab_cb has happened (there
still could be ack packets waiting to be processed at that time).
Finally, add some documentation explaining read/write/inreg and their
purpose/argument calling.
diffstat:
sys/dev/ieee1394/fwohci.c | 374 ++++++++++++++++++++++++++++------------
sys/dev/ieee1394/fwohcivar.h | 15 +-
sys/dev/ieee1394/ieee1394var.h | 3 +-
3 files changed, 271 insertions(+), 121 deletions(-)
diffs (truncated from 586 to 300 lines):
diff -r d5c74b356329 -r f101d6c5cb7f sys/dev/ieee1394/fwohci.c
--- a/sys/dev/ieee1394/fwohci.c Tue May 15 06:30:30 2001 +0000
+++ b/sys/dev/ieee1394/fwohci.c Tue May 15 06:52:30 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci.c,v 1.30 2001/05/13 05:01:42 jmc Exp $ */
+/* $NetBSD: fwohci.c,v 1.31 2001/05/15 06:52:30 jmc Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -147,9 +147,9 @@
void (*)(struct device *, struct mbuf *));
static int fwohci_read(struct ieee1394_abuf *);
static int fwohci_write(struct ieee1394_abuf *);
-static int fwohci_extract_resp(struct fwohci_softc *, void *,
- struct fwohci_pkt *);
-static int fwohci_multi_resp(struct fwohci_softc *, void *,
+static int fwohci_read_resp(struct fwohci_softc *, void *, struct fwohci_pkt *);
+static int fwohci_write_ack(struct fwohci_softc *, void *, struct fwohci_pkt *);
+static int fwohci_read_multi_resp(struct fwohci_softc *, void *,
struct fwohci_pkt *);
static int fwohci_inreg(struct ieee1394_abuf *, int);
static int fwohci_parse_input(struct fwohci_softc *, void *,
@@ -1550,15 +1550,8 @@
break;
}
}
-#ifdef FW_DEBUG
- if (fh == NULL) {
+ if (fh == NULL)
DPRINTFN(1, ("fwohci_arrs_input: no listner\n"));
- DPRINTFN(1, ("src: %d, rcode: %d, tlabel: %d, tcode: "
- "%d hdr[3]: 0x%08x, data: 0x%08lx\n", srcid, rcode,
- tlabel, pkt.fp_tcode, pkt.fp_hdr[3],
- (unsigned long)(*((int *)pkt.fp_iov[0].iov_base))));
- }
-#endif
}
fwohci_buf_next(sc, fc);
OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx,
@@ -2771,6 +2764,52 @@
* send/receive data.
*/
+/*
+ * These break down into 4 routines as follows:
+ *
+ * int fwohci_read(struct ieee1394_abuf *)
+ *
+ * This routine will attempt to read a region from the requested node.
+ * A callback must be provided which will be called when either the completed
+ * read is done or an unrecoverable error occurs. This is mainly a convenience
+ * routine since it will encapsulate retrying a region as quadlet vs. block reads
+ * and recombining all the returned data. This could also be done with a series
+ * of write/inreg's for each packet sent.
+ *
+ * int fwohci_write(struct ieee1394_abuf *)
+ *
+ * The work horse main entry point for putting packets on the bus. This is the
+ * generalized interface for fwnode/etc code to put packets out onto the bus.
+ * It accepts all standard ieee1394 tcodes (XXX: only a few today) and optionally
+ * will callback via a func pointer to the calling code with the resulting ACK
+ * code from the packet. If the ACK code is to be ignored (i.e. no cb) then the
+ * write routine will take care of free'ing the abuf since the fwnode/etc code
+ * won't have any knowledge of when to do this. This allows for simple one-off
+ * packets to be sent from the upper-level code without worrying about a callback
+ * for cleanup.
+ *
+ * int fwohci_inreg(struct ieee1394_abuf *, int)
+ *
+ * This is very simple. It evals the abuf passed in and registers an internal
+ * handler as the callback for packets received for that operation.
+ * The integer argument specifies whether on a block read/write operation to
+ * allow sub-regions to be read/written (in block form) as well.
+ *
+ * XXX: This whole structure needs to be redone as a list of regions and
+ * operations allowed on those regions.
+ *
+ * int fwohci_unreg(struct ieee1394_abuf *, int)
+ *
+ * XXX: TBD. For now passing in a NULL ab_cb to inreg will unregister. This
+ * routine will simply verify ab_cb is NULL and call inreg.
+ *
+ * This simply unregisters the respective callback done via inreg for items
+ * which only need to register an area for a one-time operation (like a status
+ * buffer a remote node will write to when the current operation is done). The
+ * int argument specifies the same behavior as inreg, except in reverse (i.e.
+ * it unregisters).
+ */
+
static int
fwohci_read(struct ieee1394_abuf *ab)
{
@@ -2778,9 +2817,19 @@
struct ieee1394_softc *sc = ab->ab_req;
struct fwohci_softc *psc =
(struct fwohci_softc *)sc->sc1394_dev.dv_parent;
+ struct fwohci_cb *fcb;
u_int32_t high, lo;
int rv, tcode;
+ /* Have to have a callback when reading. */
+ if (ab->ab_cb == NULL)
+ return -1;
+
+ fcb = malloc(sizeof(struct fwohci_cb), M_DEVBUF, M_WAITOK);
+ fcb->ab = ab;
+ fcb->count = 0;
+ fcb->abuf_valid = 1;
+
high = ((ab->ab_csr & 0x0000ffff00000000) >> 32);
lo = (ab->ab_csr & 0x00000000ffffffff);
@@ -2802,15 +2851,19 @@
pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) |
(psc->sc_tlabel << 10) | (pkt.fp_tcode << 4);
- pkt.fp_statusarg = ab;
- pkt.fp_statuscb = fwohci_extract_resp;
+ pkt.fp_statusarg = fcb;
+ pkt.fp_statuscb = fwohci_read_resp;
rv = fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id,
- psc->sc_tlabel, fwohci_extract_resp, ab);
+ psc->sc_tlabel, fwohci_read_resp, fcb);
if (rv)
return rv;
+ rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt);
+ if (rv)
+ fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id,
+ psc->sc_tlabel, NULL, NULL);
psc->sc_tlabel = (psc->sc_tlabel + 1) & 0x3f;
- rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt);
+ fcb->count = 1;
return rv;
}
@@ -2836,6 +2889,9 @@
pkt.fp_uio.uio_segflg = UIO_SYSSPACE;
pkt.fp_uio.uio_rw = UIO_WRITE;
+ pkt.fp_statusarg = ab;
+ pkt.fp_statuscb = fwohci_write_ack;
+
switch (ab->ab_tcode) {
case IEEE1394_TCODE_WRITE_RESP:
pkt.fp_hlen = 12;
@@ -2880,12 +2936,6 @@
rv = fwohci_at_output(psc, psc->sc_ctx_atrs, &pkt);
break;
default:
- rv = fwohci_handler_set(psc, IEEE1394_TCODE_WRITE_RESP,
- ab->ab_req->sc1394_node_id, psc->sc_tlabel,
- fwohci_extract_resp, ab);
- if (rv)
- return rv;
- psc->sc_tlabel = (psc->sc_tlabel + 1) & 0x3f;
rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt);
break;
}
@@ -2893,76 +2943,70 @@
}
static int
-fwohci_extract_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
+fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
{
- struct ieee1394_abuf *ab = (struct ieee1394_abuf *)arg;
+ struct fwohci_cb *fcb = arg;
+ struct ieee1394_abuf *ab = fcb->ab;
struct fwohci_pkt newpkt;
- u_int16_t status;
u_int32_t *cur, high, lo;
- int i, rcode, rv;
-
- status = 0;
+ int i, tcode, rcode, status, rv;
/*
- * No callback just means we want to have something clean up the abuf.
+ * Both the ACK handling and normal response callbacks are handled here.
+ * The main reason for this is the various error conditions that can
+ * occur trying to block read some areas and the ways that gets reported
+ * back to calling station. This is a variety of ACK codes, responses,
+ * etc which makes it much more difficult to process if both aren't
+ * handled here.
*/
-
- if (ab->ab_cb == NULL) {
- if (ab->ab_data)
- free(ab->ab_data, M_1394DATA);
- if (ab)
- free(ab, M_1394DATA);
- return 0;
- }
-
+
/* Check for status packet. */
if (pkt->fp_tcode == -1) {
status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK;
- pkt->fp_tcode = (pkt->fp_hdr[0] >> 4) & 0xf;
-
- /* See below for this exception that's trapped internally. */
- if (ab->ab_ackcb &&
- !((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) &&
- (pkt->fp_tcode == IEEE1394_TCODE_READ_REQ_BLOCK))) {
-
- /*
- * XXX: Deal with this better. Trap OHCI code and
- * translate/deal with the results.
- */
-
- if (status >= OHCI_CTXCTL_EVENT_RESERVED16)
- status = status & 0xf;
- else
- status = 0;
- ab->ab_ackcb(ab, status);
+ rcode = -1;
+ tcode = (pkt->fp_hdr[0] >> 4) & 0xf;
+ if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) &&
+ (status != OHCI_CTXCTL_EVENT_ACK_PENDING))
+ DPRINTF(("Got status packet: 0x%02x\n",
+ (unsigned int)status));
+ fcb->count--;
+
+ /*
+ * Got all the ack's back and the buffer is invalid (i.e. the
+ * callback has been called. Clean up.
+ */
+
+ if (fcb->abuf_valid == 0) {
+ if (fcb->count == 0)
+ free(fcb, M_DEVBUF);
return IEEE1394_RCODE_COMPLETE;
}
- if (!((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) &&
- (pkt->fp_tcode == IEEE1394_TCODE_READ_REQ_BLOCK)))
- return IEEE1394_RCODE_COMPLETE;
-
- } else
+ } else {
+ status = -1;
+ tcode = pkt->fp_tcode;
rcode = (pkt->fp_hdr[1] & 0x0000f000) >> 12;
+ }
/*
* Some area's (like the config rom want to be read as quadlets only.
*
* The current ideas to try are:
*
- * Got an ACK_TYPE_ERROR on a block read
+ * Got an ACK_TYPE_ERROR on a block read.
*
- * Got either RCODE_TYPE or RCODE_ADDRESS errors in a read block response
+ * Got either RCODE_TYPE or RCODE_ADDRESS errors in a block read
+ * response.
*
- * If all cases construct a new packet for a quadlet read and let
+ * In all cases construct a new packet for a quadlet read and let
* mutli_resp handle the iteration over the space.
*/
if (((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) &&
- (pkt->fp_tcode == IEEE1394_TCODE_READ_REQ_BLOCK)) ||
+ (tcode == IEEE1394_TCODE_READ_REQ_BLOCK)) ||
(((rcode == IEEE1394_RCODE_TYPE_ERROR) ||
- (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) &&
- (pkt->fp_tcode == IEEE1394_TCODE_READ_RESP_BLOCK))) {
+ (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) &&
+ (tcode == IEEE1394_TCODE_READ_RESP_BLOCK))) {
/* Read the area in quadlet chunks (internally track this). */
@@ -2982,49 +3026,80 @@
rv = fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD,
ab->ab_req->sc1394_node_id, sc->sc_tlabel,
- fwohci_multi_resp, ab);
- if (rv)
- return rv;
+ fwohci_read_multi_resp, fcb);
+ if (rv) {
+ (*ab->ab_cb)(ab, -1);
+ goto cleanup;
+ }
+ newpkt.fp_statusarg = fcb;
+ newpkt.fp_statuscb = fwohci_read_resp;
+ rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt);
+ if (rv) {
+ fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD,
+ ab->ab_req->sc1394_node_id, sc->sc_tlabel, NULL,
+ NULL);
+ (*ab->ab_cb)(ab, -1);
+ goto cleanup;
+ }
+ fcb->count++;
sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f;
- if (ab->ab_ackcb) {
- newpkt.fp_statusarg = ab;
Home |
Main Index |
Thread Index |
Old Index