From 73b50895813bd4c961a86cbeb3aa9d02ee66f73b Mon Sep 17 00:00:00 2001 From: "Kate J. Temkin" Date: Thu, 3 Jan 2019 06:08:21 -0700 Subject: [PATCH] Fix communications failures on USB suspend. (#97) Linux issues a `GET_STATUS` request to validate that a USB device has correctly resumed after an idle suspend; but HackRF has thus far not implemented `GET_STATUS`. As a result, Linux assumes our USB devices are failing to resume, and winds up resetting them. Oops. ^-^ --- firmware/common/usb_standard_request.c | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/firmware/common/usb_standard_request.c b/firmware/common/usb_standard_request.c index bf82ab4a..dd763862 100644 --- a/firmware/common/usb_standard_request.c +++ b/firmware/common/usb_standard_request.c @@ -337,6 +337,40 @@ static usb_request_status_t usb_standard_request_get_configuration( } } + +static usb_request_status_t usb_standard_request_get_status_setup( + usb_endpoint_t* const endpoint +) { + if( endpoint->setup.length == 2 ) { + endpoint->buffer[0] = 0; + endpoint->buffer[1] = 0; + + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } else { + return USB_REQUEST_STATUS_STALL; + } +} + + +static usb_request_status_t usb_standard_request_get_status( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( stage ) { + case USB_TRANSFER_STAGE_SETUP: + return usb_standard_request_get_status_setup(endpoint); + + case USB_TRANSFER_STAGE_DATA: + case USB_TRANSFER_STAGE_STATUS: + return USB_REQUEST_STATUS_OK; + + default: + return USB_REQUEST_STATUS_STALL; + } +} + /*********************************************************************/ usb_request_status_t usb_standard_request( @@ -344,6 +378,9 @@ usb_request_status_t usb_standard_request( const usb_transfer_stage_t stage ) { switch( endpoint->setup.request ) { + case USB_STANDARD_REQUEST_GET_STATUS: + return usb_standard_request_get_status(endpoint, stage); + case USB_STANDARD_REQUEST_GET_DESCRIPTOR: return usb_standard_request_get_descriptor(endpoint, stage);