]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[xhci] Allow for residual byte counts exceeding 64kB 1791/head
authorMichael Brown <mcb30@ipxe.org>
Mon, 3 Aug 2026 21:04:54 +0000 (22:04 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 3 Aug 2026 21:04:54 +0000 (22:04 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/usb/xhci.c
src/include/ipxe/xhci.h

index f812ed338dc032af5866346049a6b95d37745351..110e15f4c556a98defac63cb575e9ff21a6257c3 100644 (file)
@@ -1598,6 +1598,8 @@ static void xhci_transfer ( struct xhci_device *xhci,
        struct xhci_slot *slot;
        struct xhci_endpoint *endpoint;
        struct io_buffer *iobuf;
+       uint32_t cmplt;
+       unsigned int code;
        int rc;
 
        /* Profile transfer events */
@@ -1628,14 +1630,18 @@ static void xhci_transfer ( struct xhci_device *xhci,
        /* Unmap I/O buffer */
        iob_unmap ( iobuf );
 
+       /* Parse completion */
+       cmplt = le32_to_cpu ( trb->cmplt );
+       code = XHCI_CMPLT_CODE ( cmplt );
+
        /* Check for errors */
-       if ( ! ( ( trb->code == XHCI_CMPLT_SUCCESS ) ||
-                ( trb->code == XHCI_CMPLT_SHORT ) ) ) {
+       if ( ! ( ( code == XHCI_CMPLT_SUCCESS ) ||
+                ( code == XHCI_CMPLT_SHORT ) ) ) {
 
                /* Construct error */
-               rc = -ECODE ( trb->code );
+               rc = -ECODE ( code );
                DBGC ( xhci, "XHCI %s slot %d ctx %d failed (code %d): %s\n",
-                      xhci->name, slot->id, endpoint->ctx, trb->code,
+                      xhci->name, slot->id, endpoint->ctx, code,
                       strerror ( rc ) );
                DBGC_HDA ( xhci, 0, trb, sizeof ( *trb ) );
 
@@ -1649,7 +1655,7 @@ static void xhci_transfer ( struct xhci_device *xhci,
        }
 
        /* Record actual transfer size */
-       iob_unput ( iobuf, le16_to_cpu ( trb->residual ) );
+       iob_unput ( iobuf, XHCI_CMPLT_RESIDUAL ( cmplt ) );
 
        /* Sanity check (for successful completions only) */
        assert ( xhci_ring_consumed ( &endpoint->ring ) ==
index 2f5c256a09e2f73baa0a22af9bb18d58874f922f..d699c3373dc90aeedc0948760de7907fcbdbba4f 100644 (file)
@@ -589,12 +589,8 @@ struct xhci_trb_set_tr_dequeue_pointer {
 struct xhci_trb_transfer {
        /** Transfer TRB pointer */
        uint64_t transfer;
-       /** Residual transfer length */
-       uint16_t residual;
-       /** Reserved */
-       uint8_t reserved;
-       /** Completion code */
-       uint8_t code;
+       /** Completion status */
+       uint32_t cmplt;
        /** Flags */
        uint8_t flags;
        /** Type */
@@ -608,6 +604,12 @@ struct xhci_trb_transfer {
 /** A transfer event transfer request block */
 #define XHCI_TRB_TRANSFER XHCI_TRB_TYPE ( 32 )
 
+/** Completion code */
+#define XHCI_CMPLT_CODE( cmplt ) ( (cmplt) >> 24 )
+
+/** Residual bytes not transferred */
+#define XHCI_CMPLT_RESIDUAL( cmplt ) ( (cmplt) & 0xffffff )
+
 /** A command completion event transfer request block */
 struct xhci_trb_complete {
        /** Command TRB pointer */