diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2000-04-11 19:59:07 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2000-04-11 19:59:07 +0000 |
commit | 1f61668b6cf24eec0a600dce89d52daabe855054 (patch) | |
tree | 863e9b0bf80ef53874fcd8973a4a904d18e0caa8 /sys/dev/pci/hifn7751.c | |
parent | b5d8de56e5bc0f250c08704c894e64ee4d9ff282 (diff) |
- add support for buffers that are not aligned (or end on a non 4byte boundary)
- recompute destination length from destination descriptors and reclaim the
destination ring there.
Diffstat (limited to 'sys/dev/pci/hifn7751.c')
-rw-r--r-- | sys/dev/pci/hifn7751.c | 82 |
1 files changed, 60 insertions, 22 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c index 1ba05a7d510..165d58424fe 100644 --- a/sys/dev/pci/hifn7751.c +++ b/sys/dev/pci/hifn7751.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751.c,v 1.28 2000/04/11 16:22:09 jason Exp $ */ +/* $OpenBSD: hifn7751.c,v 1.29 2000/04/11 19:59:06 jason Exp $ */ /* * Invertex AEON / Hi/fn 7751 driver @@ -96,7 +96,7 @@ u_int32_t hifn_next_signature __P((u_int a, u_int cnt)); int hifn_newsession __P((u_int32_t *, struct cryptoini *)); int hifn_freesession __P((u_int32_t)); int hifn_process __P((struct cryptop *)); -void hifn_callback __P((struct hifn_command *, u_int8_t *)); +void hifn_callback __P((struct hifn_softc *, struct hifn_command *, u_int8_t *)); int hifn_crypto __P((struct hifn_softc *, hifn_command_t *)); struct hifn_stats { @@ -1023,18 +1023,45 @@ hifn_crypto(sc, cmd) return (-1); if (nicealign == 0) { - cmd->dst_l = cmd->src_l; - MGETHDR(cmd->dst_m, M_DONTWAIT, MT_DATA); - if (cmd->dst_m == NULL) + int totlen, len; + struct mbuf *m, *top, **mp; + + totlen = cmd->dst_l = cmd->src_l; + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) return (-1); - if (cmd->src_l > MHLEN) { - MCLGET(cmd->dst_m, M_DONTWAIT); - if ((cmd->dst_m->m_flags & M_EXT) == 0) { - m_freem(cmd->dst_m); - return (-1); + len = MHLEN; + if (totlen >= MINCLSIZE) { + MCLGET(m, M_DONTWAIT); + if (m->m_flags & M_EXT) + len = MCLBYTES; + } + m->m_len = len; + top = NULL; + mp = ⊤ + + while (totlen > 0) { + if (top) { + MGET(m, M_DONTWAIT, MT_DATA); + if (m == NULL) { + m_freem(top); + return (-1); + } + len = MLEN; + } + if (top && totlen >= MINCLSIZE) { + MCLGET(m, M_DONTWAIT); + if (m->m_flags & M_EXT) + len = MCLBYTES; } + m->m_len = len = min(totlen, len); + totlen -= len; + *mp = m; + mp = &m->m_next; } - } else + cmd->dst_m = top; + } + else cmd->dst_m = cmd->src_m; cmd->dst_l = hifn_mbuf(cmd->dst_m, &cmd->dst_npa, @@ -1209,7 +1236,7 @@ hifn_intr(arg) } /* position is done, notify producer with callback */ - cmd->dest_ready_callback(cmd, macbuf); + cmd->dest_ready_callback(sc, cmd, macbuf); if (++dma->resk == HIFN_D_RES_RSIZE) dma->resk = 0; @@ -1227,15 +1254,6 @@ hifn_intr(arg) } dma->srck = i; dma->srcu = u; - i = dma->dstk; u = dma->dstu; - while (u != 0 && (dma->dstr[i].l & HIFN_D_VALID) == 0) { - hifnstats.hst_obytes += dma->dstr[i].l & 0xffff; - if (++i == HIFN_D_DST_RSIZE) - i = 0; - u--; - } - dma->dstk = i; dma->dstu = u; - i = dma->cmdk; u = dma->cmdu; while (u != 0 && (dma->cmdr[i].l & HIFN_D_VALID) == 0) { if (++i == HIFN_D_CMD_RSIZE) @@ -1516,18 +1534,38 @@ errout: } void -hifn_callback(cmd, macbuf) +hifn_callback(sc, cmd, macbuf) + struct hifn_softc *sc; struct hifn_command *cmd; u_int8_t *macbuf; { + struct hifn_dma *dma = sc->sc_dma; struct cryptop *crp = (struct cryptop *)cmd->private_data; struct cryptodesc *crd; + struct mbuf *m; if ((crp->crp_flags & CRYPTO_F_IMBUF) && (cmd->src_m != cmd->dst_m)) { m_freem(cmd->src_m); crp->crp_buf = (caddr_t)cmd->dst_m; } + if ((m = cmd->dst_m) != NULL) { + while (m) { + m->m_len = dma->dstr[dma->dstk].l & HIFN_D_LENGTH; + hifnstats.hst_obytes += m->m_len; + m = m->m_next; + if (++dma->dstk == HIFN_D_DST_RSIZE) + dma->dstk = 0; + dma->dstu--; + } + } + else { + hifnstats.hst_obytes += dma->dstr[dma->dstk].l & HIFN_D_LENGTH; + if (++dma->dstk == HIFN_D_DST_RSIZE) + dma->dstk = 0; + dma->dstu--; + } + if ((cmd->flags & HIFN_ENCODE) && ((cmd->flags & HIFN_CRYPT_DES) || (cmd->flags & HIFN_CRYPT_3DES))) { for (crd = crp->crp_desc; crd; crd = crd->crd_next) { |