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/b8655cffd59b
branches: trunk
changeset: 850292:b8655cffd59b
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 213b7872931c -r b8655cffd59b 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