diff --git a/nx/include/switch/services/usb.h b/nx/include/switch/services/usb.h index d1bc52d3..685b696a 100644 --- a/nx/include/switch/services/usb.h +++ b/nx/include/switch/services/usb.h @@ -207,3 +207,14 @@ enum usb_iso_usage_type { USB_ISO_USAGE_TYPE_IMPLICIT = 2, }; +/// USB Device States, per USB 2.0 spec +typedef enum { + UsbState_Detached = 0, ///< Device is not attached to USB. + UsbState_Attached = 1, ///< Device is attached, but is not powered. + UsbState_Powered = 2, ///< Device is attached and powered, but has not been reset. + UsbState_Default = 3, ///< Device is attached, powered, and has been reset, but does not have an address. + UsbState_Address = 4, ///< Device is attached, powered, has been reset, has an address, but is not configured. + UsbState_Configured = 5, ///< Device is attached, powered, has been reset, has an address, configured, and may be used. + UsbState_Suspended = 6, ///< Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used. +} UsbState; + diff --git a/nx/include/switch/services/usbds.h b/nx/include/switch/services/usbds.h index 7466f13f..1e70c6fe 100644 --- a/nx/include/switch/services/usbds.h +++ b/nx/include/switch/services/usbds.h @@ -79,7 +79,9 @@ Result usbDsParseReportData(UsbDsReportData *reportdata, u32 urbId, u32 *request ///@{ Event* usbDsGetStateChangeEvent(void); -Result usbDsGetState(u32* out); + +/// Gets the device state. See \ref UsbState. +Result usbDsGetState(UsbState* out); /// Removed in [5.0.0+]. Result usbDsGetDsInterface(UsbDsInterface** out, struct usb_interface_descriptor* descriptor, const char* interface_name); diff --git a/nx/source/services/usbds.c b/nx/source/services/usbds.c index c786f972..b5f8c357 100644 --- a/nx/source/services/usbds.c +++ b/nx/source/services/usbds.c @@ -223,18 +223,19 @@ static Result _usbDsBindDevice(UsbComplexId complexId, Handle prochandle) { return rc; } -Result usbDsGetState(u32 *out) { - return _usbDsCmdNoInOutU32(&g_usbDsSrv, out, hosversionAtLeast(11,0,0) ? 3 : 4); +Result usbDsGetState(UsbState *out) { + _Static_assert(sizeof(*out) == sizeof(u32)); + return _usbDsCmdNoInOutU32(&g_usbDsSrv, (u32 *)out, hosversionAtLeast(11,0,0) ? 3 : 4); } Result usbDsWaitReady(u64 timeout) { Result rc; - u32 state = 0; + UsbState state = UsbState_Detached; rc = usbDsGetState(&state); if (R_FAILED(rc)) return rc; - while (R_SUCCEEDED(rc) && state != 5) { + while (R_SUCCEEDED(rc) && state != UsbState_Configured) { eventWait(&g_usbDsStateChangeEvent, timeout); eventClear(&g_usbDsStateChangeEvent); rc = usbDsGetState(&state);