Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Allow short transfers. We introduce a third pack...



details:   https://anonhg.NetBSD.org/src/rev/12f036a14b86
branches:  trunk
changeset: 746428:12f036a14b86
user:      maxv <maxv%NetBSD.org@localhost>
date:      Tue Mar 31 16:17:32 2020 +0000

description:
Allow short transfers. We introduce a third packet, in the U->H list, that
contains a vhci_response_t, which indicates the size.

diffstat:

 sys/dev/usb/vhci.c |  56 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 47 insertions(+), 9 deletions(-)

diffs (167 lines):

diff -r e037f6de6d9c -r 12f036a14b86 sys/dev/usb/vhci.c
--- a/sys/dev/usb/vhci.c        Tue Mar 31 14:39:44 2020 +0000
+++ b/sys/dev/usb/vhci.c        Tue Mar 31 16:17:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vhci.c,v 1.13 2020/03/29 09:46:14 maxv Exp $ */
+/*     $NetBSD: vhci.c,v 1.14 2020/03/31 16:17:32 maxv Exp $ */
 
 /*
  * Copyright (c) 2019-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.13 2020/03/29 09:46:14 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.14 2020/03/31 16:17:32 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -182,6 +182,10 @@
        } u;
 } vhci_request_t;
 
+typedef struct {
+       size_t size;
+} vhci_response_t;
+
 struct vhci_xfer;
 
 typedef struct vhci_packet {
@@ -192,6 +196,13 @@
        bool utoh;
        uint8_t addr;
 
+       /* Type. */
+       struct {
+               bool req:1;
+               bool res:1;
+               bool dat:1;
+       } type;
+
        /* Exposed for FD operations. */
        uint8_t *buf;
        size_t size;
@@ -229,6 +240,7 @@
 
        /* Header storage. */
        vhci_request_t reqbuf;
+       vhci_response_t resbuf;
 
        /* Used for G/C. */
        TAILQ_ENTRY(vhci_xfer) freelist;
@@ -276,8 +288,8 @@
     uint8_t addr)
 {
        vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
-       vhci_packet_list_t *reqlist, *datlist;
-       vhci_packet_t *req, *dat = NULL;
+       vhci_packet_list_t *reqlist, *reslist, *datlist = NULL;
+       vhci_packet_t *req, *res = NULL, *dat = NULL;
        size_t npkts = 0;
 
        /* Request packet. */
@@ -286,6 +298,7 @@
        req->vxfer = vxfer;
        req->utoh = false;
        req->addr = addr;
+       req->type.req = true;
        req->buf = (uint8_t *)&vxfer->reqbuf;
        req->size = sizeof(vxfer->reqbuf);
        req->cursor = 0;
@@ -297,6 +310,20 @@
        memcpy(&vxfer->reqbuf.u.ctrl, &xfer->ux_request,
            sizeof(xfer->ux_request));
 
+       /* Response packet. */
+       if (utoh && (xfer->ux_length > 0)) {
+               reslist = &port->endpoints[addr].usb_to_host;
+               res = kmem_zalloc(sizeof(*res), KM_SLEEP);
+               res->vxfer = vxfer;
+               res->utoh = true;
+               res->addr = addr;
+               res->type.res = true;
+               res->buf = (uint8_t *)&vxfer->resbuf;
+               res->size = sizeof(vxfer->resbuf);
+               res->cursor = 0;
+               npkts++;
+       }
+
        /* Data packet. */
        if (xfer->ux_length > 0) {
                if (utoh) {
@@ -308,6 +335,7 @@
                dat->vxfer = vxfer;
                dat->utoh = utoh;
                dat->addr = addr;
+               dat->type.dat = true;
                dat->buf = xfer->ux_buf;
                dat->size = xfer->ux_length;
                dat->cursor = 0;
@@ -319,12 +347,16 @@
        vxfer->npkts = npkts;
        TAILQ_INIT(&vxfer->pkts);
        TAILQ_INSERT_TAIL(&vxfer->pkts, req, xferlist);
+       if (res != NULL)
+               TAILQ_INSERT_TAIL(&vxfer->pkts, res, xferlist);
        if (dat != NULL)
                TAILQ_INSERT_TAIL(&vxfer->pkts, dat, xferlist);
 
        /* Insert in the port. */
        KASSERT(mutex_owned(&port->lock));
        TAILQ_INSERT_TAIL(reqlist, req, portlist);
+       if (res != NULL)
+               TAILQ_INSERT_TAIL(reslist, res, portlist);
        if (dat != NULL)
                TAILQ_INSERT_TAIL(datlist, dat, portlist);
 }
@@ -1084,6 +1116,7 @@
        TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
                vxfer = pkt->vxfer;
                buf = pkt->buf + pkt->cursor;
+
                KASSERT(pkt->size >= pkt->cursor);
                size = uimin(uio->uio_resid, pkt->size - pkt->cursor);
 
@@ -1138,7 +1171,7 @@
        vhci_port_t *port;
        int error = 0;
        uint8_t *buf;
-       size_t size;
+       size_t pktsize, size;
 
        if (uio->uio_resid == 0)
                return 0;
@@ -1157,8 +1190,13 @@
        TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
                vxfer = pkt->vxfer;
                buf = pkt->buf + pkt->cursor;
-               KASSERT(pkt->size >= pkt->cursor);
-               size = uimin(uio->uio_resid, pkt->size - pkt->cursor);
+
+               pktsize = pkt->size;
+               if (pkt->type.dat)
+                       pktsize = ulmin(vxfer->resbuf.size, pktsize);
+
+               KASSERT(pktsize >= pkt->cursor);
+               size = uimin(uio->uio_resid, pktsize - pkt->cursor);
 
                KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
 
@@ -1170,7 +1208,7 @@
 
                pkt->cursor += size;
 
-               if (pkt->cursor == pkt->size) {
+               if (pkt->cursor == pktsize) {
                        vhci_pkt_destroy(sc, pkt);
                        if (vxfer->npkts == 0) {
                                TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
@@ -1189,7 +1227,7 @@
                TAILQ_REMOVE(&vxferlist, vxfer, freelist);
 
                mutex_enter(&sc->sc_lock);
-               xfer->ux_actlen = xfer->ux_length;
+               xfer->ux_actlen = ulmin(vxfer->resbuf.size, xfer->ux_length);
                xfer->ux_status = USBD_NORMAL_COMPLETION;
                usb_transfer_complete(xfer);
                mutex_exit(&sc->sc_lock);



Home | Main Index | Thread Index | Old Index