Commit d61000a8 authored by Hans de Goede's avatar Hans de Goede Committed by Gerd Hoffmann
Browse files

usb: add USB_RET_IOERROR



We already have USB_RET_NAK, but that means that a device does not want
to send/receive right now. But with host / network redirection we can
actually have a transaction fail due to some io error, rather then ie
the device just not having any data atm.

This patch adds a new error code named USB_RET_IOERROR for this, and uses
it were appropriate.

Notes:
-Currently all usb-controllers handle this the same as NODEV, but that
 may change in the future, OHCI could indicate a CRC error instead for example.
-This patch does not touch hw/usb-musb.c, that is because the code in there
 handles STALL and NAK specially and has a if status < 0 generic catch all
 for all other errors

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 4d819a9b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1299,6 +1299,7 @@ static void ehci_execute_complete(EHCIQueue *q)

    if (q->usb_status < 0) {
        switch(q->usb_status) {
        case USB_RET_IOERROR:
        case USB_RET_NODEV:
            q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR);
            set_field(&q->qh.token, 0, QTD_TOKEN_CERR);
@@ -1471,6 +1472,7 @@ static int ehci_process_itd(EHCIState *ehci,
                default:
                    fprintf(stderr, "Unexpected iso usb result: %d\n", ret);
                    /* Fall through */
                case USB_RET_IOERROR:
                case USB_RET_NODEV:
                    /* 3.3.2: XACTERR is only allowed on IN transactions */
                    if (dir) {
+2 −0
Original line number Diff line number Diff line
@@ -837,6 +837,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
                        OHCI_CC_DATAUNDERRUN);
        } else {
            switch (ret) {
            case USB_RET_IOERROR:
            case USB_RET_NODEV:
                OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
                            OHCI_CC_DEVICENOTRESPONDING);
@@ -1052,6 +1053,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
            OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
        } else {
            switch (ret) {
            case USB_RET_IOERROR:
            case USB_RET_NODEV:
                OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
            case USB_RET_NAK:
+1 −0
Original line number Diff line number Diff line
@@ -765,6 +765,7 @@ out:
            break;
	return 1;

    case USB_RET_IOERROR:
    case USB_RET_NODEV:
    default:
	break;
+6 −5
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@
#define USB_RET_NAK     (-2)
#define USB_RET_STALL   (-3)
#define USB_RET_BABBLE  (-4)
#define USB_RET_ASYNC  (-5)
#define USB_RET_IOERROR (-5)
#define USB_RET_ASYNC   (-6)

#define USB_SPEED_LOW   0
#define USB_SPEED_FULL  1
+2 −2
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ static void async_complete(void *opaque)
                break;

            default:
                p->result = USB_RET_NAK;
                p->result = USB_RET_IOERROR;
                break;
            }

@@ -729,7 +729,7 @@ static int urb_status_to_usb_ret(int status)
    case -EOVERFLOW:
        return USB_RET_BABBLE;
    default:
        return USB_RET_NAK;
        return USB_RET_IOERROR;
    }
}

Loading