summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_tht.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/sys/dev/pci/if_tht.c b/sys/dev/pci/if_tht.c
index 65f24c46a60..6bf392a397e 100644
--- a/sys/dev/pci/if_tht.c
+++ b/sys/dev/pci/if_tht.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tht.c,v 1.37 2007/04/21 12:25:42 dlg Exp $ */
+/* $OpenBSD: if_tht.c,v 1.38 2007/04/21 12:32:32 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -318,6 +318,20 @@ struct tht_fifo {
int tf_wptr;
};
+struct tht_pkt {
+ u_int64_t tp_id;
+
+ bus_dmamap_t tp_dmap;
+ struct mbuf *tp_m;
+
+ TAILQ_ENTRY(tht_pkt) tp_link;
+};
+
+struct tht_pkt_list {
+ struct tht_pkt *tpl_pkts;
+ TAILQ_HEAD(, tht_pkt) tpl_list;
+};
+
struct tht_softc {
struct device sc_dev;
struct thtc_softc *sc_thtc;
@@ -352,6 +366,14 @@ struct cfdriver tht_cd = {
NULL, "tht", DV_IFNET
};
+/* pkts */
+int tht_pkt_alloc(struct tht_softc *,
+ struct tht_pkt_list *, int, int);
+void tht_pkt_free(struct tht_softc *,
+ struct tht_pkt_list *);
+void tht_pkt_put(struct tht_pkt_list *, struct tht_pkt *);
+struct tht_pkt *tht_pkt_get(struct tht_pkt_list *);
+
/* fifos */
struct tht_fifo_desc tht_txt_desc = {
@@ -1137,3 +1159,63 @@ tht_dmamem_free(struct tht_softc *sc, struct tht_dmamem *tdm)
bus_dmamap_destroy(dmat, tdm->tdm_map);
free(tdm, M_DEVBUF);
}
+
+int
+tht_pkt_alloc(struct tht_softc *sc, struct tht_pkt_list *tpl, int npkts,
+ int nsegs)
+{
+ bus_dma_tag_t dmat = sc->sc_thtc->sc_dmat;
+ struct tht_pkt *pkt;
+ int i;
+
+ tpl->tpl_pkts = malloc(sizeof(struct tht_pkt) * npkts, M_DEVBUF,
+ M_WAITOK);
+ bzero(tpl->tpl_pkts, sizeof(struct tht_pkt) * npkts);
+
+ TAILQ_INIT(&tpl->tpl_list);
+ for (i = 0; i < npkts; i++) {
+ pkt = &tpl->tpl_pkts[i];
+
+ pkt->tp_id = i;
+ if (bus_dmamap_create(dmat, THT_PBD_PKTLEN, nsegs,
+ THT_PBD_PKTLEN, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
+ &pkt->tp_dmap) != 0) {
+ tht_pkt_free(sc, tpl);
+ return (1);
+ }
+
+ tht_pkt_put(tpl, pkt);
+ }
+
+ return (0);
+}
+
+void
+tht_pkt_free(struct tht_softc *sc, struct tht_pkt_list *tpl)
+{
+ bus_dma_tag_t dmat = sc->sc_thtc->sc_dmat;
+ struct tht_pkt *pkt;
+
+ while ((pkt = tht_pkt_get(tpl)) != NULL)
+ bus_dmamap_destroy(dmat, pkt->tp_dmap);
+ free(tpl->tpl_pkts, M_DEVBUF);
+ tpl->tpl_pkts = NULL;
+}
+
+void
+tht_pkt_put(struct tht_pkt_list *tpl, struct tht_pkt *pkt)
+{
+ TAILQ_INSERT_TAIL(&tpl->tpl_list, pkt, tp_link);
+}
+
+struct tht_pkt *
+tht_pkt_get(struct tht_pkt_list *tpl)
+{
+ struct tht_pkt *pkt;
+
+ pkt = TAILQ_FIRST(&tpl->tpl_list);
+ if (pkt != NULL)
+ TAILQ_REMOVE(&tpl->tpl_list, pkt, tp_link);
+
+ return (pkt);
+}