diff --git a/nsul_ndxt_patch.diff b/nsul_nxdt_patch.diff similarity index 56% rename from nsul_ndxt_patch.diff rename to nsul_nxdt_patch.diff index 28df861..5abd734 100644 --- a/nsul_ndxt_patch.diff +++ b/nsul_nxdt_patch.diff @@ -1,26 +1,107 @@ diff --git a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java -index 054f03a..f46fed9 100644 +index 9e5fd9b..fcd33a3 100644 --- a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java +++ b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java -@@ -40,6 +40,8 @@ class NxdtUsbAbi1 { - private boolean isWindows; +@@ -22,6 +22,7 @@ import nsusbloader.COM.USB.UsbErrorCodes; + import nsusbloader.ModelControllers.ILogPrinter; + import nsusbloader.NSLDataTypes.EMsgType; + import org.usb4java.DeviceHandle; ++import org.usb4java.DeviceDescriptor; + import org.usb4java.LibUsb; + + import java.io.*; +@@ -40,9 +41,21 @@ class NxdtUsbAbi1 { + private final boolean isWindows; private boolean isWindows10; -+ private BufferedOutputStream bos; ++ private short endpointMaxPacketSize = 0; + private static final int NXDT_MAX_DIRECTIVE_SIZE = 0x1000; private static final int NXDT_FILE_CHUNK_SIZE = 0x800000; private static final int NXDT_FILE_PROPERTIES_MAX_NAME_LENGTH = 0x300; -@@ -50,6 +52,8 @@ class NxdtUsbAbi1 { - private static final int CMD_HANDSHAKE = 0; - private static final int CMD_SEND_FILE_PROPERTIES = 1; - private static final int CMD_ENDSESSION = 3; -+ + private static final int NXDT_USB_TIMEOUT = 5000; ++ ++ private static final short NXDT_USB_FS_BCD_REVISION = 0x0110; ++ private static final short NXDT_USB_FS_EP_MAX_PACKET_SIZE = 0x40; ++ ++ private static final short NXDT_USB_HS_BCD_REVISION = 0x0200; ++ private static final short NXDT_USB_HS_EP_MAX_PACKET_SIZE = 0x200; ++ ++ private static final short NXDT_USB_SS_BCD_REVISION = 0x0300; ++ private static final short NXDT_USB_SS_EP_MAX_PACKET_SIZE = 0x400; - // Standard set of possible replies - private static final byte[] USBSTATUS_SUCCESS = { 0x4e, 0x58, 0x44, 0x54, -@@ -186,6 +190,8 @@ class NxdtUsbAbi1 { + private static final byte ABI_VERSION = 1; + private static final byte[] MAGIC_NXDT = { 0x4e, 0x58, 0x44, 0x54 }; +@@ -77,8 +90,6 @@ class NxdtUsbAbi1 { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + +- private static final long W_MAX_PACKET_SIZE = 0x200; +- + public NxdtUsbAbi1(DeviceHandle handler, + ILogPrinter logPrinter, + String saveToPath, +@@ -174,7 +185,58 @@ class NxdtUsbAbi1 { + writeUsb(USBSTATUS_UNSUPPORTED_ABI); + throw new Exception("ABI v"+versionABI+" is not supported in current version."); + } +- writeUsb(USBSTATUS_SUCCESS); ++ ++ // Get endpoint max packet size ++ getEndpointMaxPacketSize(); ++ ++ // Send status response + endpoint max packet size ++ byte[] response = new byte[USBSTATUS_SUCCESS.length + 2]; ++ System.arraycopy(USBSTATUS_SUCCESS, 0, response, 0, USBSTATUS_SUCCESS.length); ++ response[USBSTATUS_SUCCESS.length] = (byte)(endpointMaxPacketSize & 0xFF); ++ response[USBSTATUS_SUCCESS.length + 1] = (byte)((endpointMaxPacketSize >> 8) & 0xFF); ++ ++ writeUsb(response); ++ } ++ ++ private void getEndpointMaxPacketSize() throws Exception{ ++ // Get device descriptor to determine the max packet size in use. We'll send it to the console. ++ // We'll get the device descriptor instead of an endpoint descriptor because it's a non-blocking call (the device descriptor is cached in memory by usb4java). ++ DeviceDescriptor deviceDescriptor = getDeviceDescriptor(); ++ ++ short bcdUsbRevision = deviceDescriptor.bcdUSB(); ++ byte usbRevisionUpper = (byte)((bcdUsbRevision >> 8) & 0xFF); ++ byte usbRevisionLower = (byte)(bcdUsbRevision & 0xFF); ++ ++ switch(bcdUsbRevision){ ++ case NXDT_USB_FS_BCD_REVISION: // USB 1.1 (Full Speed). ++ endpointMaxPacketSize = NXDT_USB_FS_EP_MAX_PACKET_SIZE; ++ break; ++ case NXDT_USB_HS_BCD_REVISION: // USB 2.0 (High Speed). ++ endpointMaxPacketSize = NXDT_USB_HS_EP_MAX_PACKET_SIZE; ++ break; ++ case NXDT_USB_SS_BCD_REVISION: // USB 3.0 (Super Speed). ++ endpointMaxPacketSize = NXDT_USB_SS_EP_MAX_PACKET_SIZE; ++ break; ++ default: ++ writeUsb(USBSTATUS_HOSTIOERROR); ++ throw new Exception("Invalid BCD USB release number \""+usbRevisionUpper+"."+usbRevisionLower+"\" in device descriptor!"); ++ } ++ ++ //logPrinter.print("USB revision: "+usbRevisionUpper+"."+usbRevisionLower+".", EMsgType.INFO); ++ //logPrinter.print("Max packet size: "+endpointMaxPacketSize+" b.", EMsgType.INFO); ++ } ++ ++ private DeviceDescriptor getDeviceDescriptor() throws Exception{ ++ int result; ++ DeviceDescriptor descriptor = new DeviceDescriptor(); ++ ++ result = LibUsb.getDeviceDescriptor(LibUsb.getDevice(handlerNS), descriptor); ++ if (result != LibUsb.SUCCESS){ ++ writeUsb(USBSTATUS_HOSTIOERROR); ++ throw new Exception("Failed to get device descriptor! Returned "+result+" ("+UsbErrorCodes.getErrCode(result)+")."); ++ } ++ ++ return descriptor; + } + + private void handleSendFileProperties(byte[] message) throws Exception{ +@@ -188,6 +250,8 @@ class NxdtUsbAbi1 { return; } @@ -29,7 +110,7 @@ index 054f03a..f46fed9 100644 // If RomFs related if (isRomFs(filename)) { if (isWindows) -@@ -196,7 +202,6 @@ class NxdtUsbAbi1 { +@@ -198,7 +262,6 @@ class NxdtUsbAbi1 { createPath(filename); } else { @@ -37,7 +118,7 @@ index 054f03a..f46fed9 100644 filename = saveToPath + filename; } -@@ -220,13 +225,11 @@ class NxdtUsbAbi1 { +@@ -222,13 +285,11 @@ class NxdtUsbAbi1 { if (fileSize == 0) return; @@ -49,106 +130,128 @@ index 054f03a..f46fed9 100644 writeUsb(USBSTATUS_SUCCESS); -+ logPrinter.print("Transfer finished!", EMsgType.INFO); ++ //logPrinter.print("File transfer successfully finished!", EMsgType.INFO); } private int getLEint(byte[] bytes, int fromOffset){ -@@ -255,45 +258,43 @@ class NxdtUsbAbi1 { - throw new Exception("Unable to create dir(s) for file in "+folderForTheFile); +@@ -258,63 +319,46 @@ class NxdtUsbAbi1 { } -- private void dumpFile(File file, long size) throws Exception{ -- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file, false)); + private void dumpFile(File file, long size) throws Exception{ +- try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file, false))) { +- byte[] readBuffer; +- long received = 0; +- int bufferSize; - -- byte[] readBuffer; -- long received = 0; -- int bufferSize; +- boolean zlt_expected = isAligned(size); - -- while (received < size){ -- readBuffer = readUsbFile(); -- bos.write(readBuffer); -- bufferSize = readBuffer.length; -- received += bufferSize; -- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0); +- while (received < size) { +- readBuffer = readUsbFile(); +- bos.write(readBuffer); +- bufferSize = readBuffer.length; +- received += bufferSize; +- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0); +- } ++ byte[] readBuffer; ++ long received = 0; ++ int chunkSize = NXDT_FILE_CHUNK_SIZE; + +- if (zlt_expected) { +- logPrinter.print("Finishing with ZLT packet request", EMsgType.INFO); +- readUsbFile(); +- } +- } finally { +- logPrinter.updateProgress(1.0); - } -- logPrinter.updateProgress(1.0); -- bos.close(); +- } ++ boolean zltExpected = isAligned(size, endpointMaxPacketSize); ++ //logPrinter.print("ZLT packet expected: "+zlt_expected, EMsgType.INFO); + +- // @see https://bugs.openjdk.java.net/browse/JDK-8146538 +- private void dumpFileOnWindowsTen(File file, long size) throws Exception{ +- FileOutputStream fos = new FileOutputStream(file, true); ++ FileOutputStream fos = new FileOutputStream(file, false); ++ FileDescriptor fd = fos.getFD(); + + try (BufferedOutputStream bos = new BufferedOutputStream(fos)) { +- FileDescriptor fd = fos.getFD(); +- byte[] readBuffer; +- long received = 0; +- int bufferSize; +- +- boolean zlt_expected = isAligned(size); ++ while(true){ ++ // Check if we aren't expecting a ZLT packet and the whole file has already been received. ++ if (!zltExpected && received >= size) break; ++ ++ // Update chunk size if needed. ++ if (received < size && (long)chunkSize > (size - received)) chunkSize = (int)(size - received); ++ ++ // Read current chunk. Don't attempt to read more than we're supposed to by allocating a buffer with a size equal to the current chunk size. ++ // Immediately check if we're dealing with a ZLT packet afterwards. ++ readBuffer = readUsbFile(chunkSize); ++ if (readBuffer == null || readBuffer.length == 0) ++ { ++ //logPrinter.print("ZLT packet received.", EMsgType.INFO); ++ if (zltExpected && received >= size) break; ++ continue; ++ } + +- while (received < size) { +- readBuffer = readUsbFile(); + bos.write(readBuffer); +- fd.sync(); // Fixes flushing under Windows (unharmful for other OS) +- bufferSize = readBuffer.length; +- received += bufferSize; ++ if (isWindows10) fd.sync(); // Fixes flushing under Windows 10. See https://bugs.openjdk.java.net/browse/JDK-8146538 ++ received += readBuffer.length; + +- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0); ++ //logPrinter.print("Received "+readBuffer.length+" b. Got thus far: "+received+" b.", EMsgType.INFO); ++ logPrinter.updateProgress((double)received / (double)size); + } +- +- if (zlt_expected) { +- logPrinter.print("Finishing with ZLT packet request", EMsgType.INFO); +- readUsbFile(); +- } +- } finally { +- logPrinter.updateProgress(1.0); + } + } + /** Handle Zero-length terminator **/ +- private boolean isAligned(long size){ +- return ((size & (W_MAX_PACKET_SIZE - 1)) == 0); + private boolean isAligned(long size, long alignment){ + return ((size & (alignment - 1)) == 0); } - // @see https://bugs.openjdk.java.net/browse/JDK-8146538 -- private void dumpFileOnWindowsTen(File file, long size) throws Exception{ -- FileOutputStream fos = new FileOutputStream(file, true); -- BufferedOutputStream bos = new BufferedOutputStream(fos); -+ private void dumpFile(File file, long size) throws Exception{ -+ FileOutputStream fos = new FileOutputStream(file, false); - FileDescriptor fd = fos.getFD(); -+ bos = new BufferedOutputStream(fos); - - byte[] readBuffer; - long received = 0; -- int bufferSize; -+ int chunk_size = NXDT_FILE_CHUNK_SIZE; -+ boolean zlt_expected = (isAligned(size, 0x40) || isAligned(size, 0x200) || isAligned(size, 0x400)); // wMaxPacketSize -+ //logPrinter.print("ZLT packet expected: "+zlt_expected, EMsgType.INFO); -+ -+ while(true){ -+ if (!zlt_expected && received >= size) break; -+ -+ if (received < size && (long)chunk_size > (size - received)) chunk_size = (int)(size - received); -+ -+ readBuffer = readUsbFile(chunk_size); -+ if (readBuffer == null || readBuffer.length == 0) -+ { -+ //logPrinter.print("ZLT packet received.", EMsgType.INFO); -+ if (zlt_expected && received >= size) break; -+ continue; -+ } - -- while (received < size){ -- readBuffer = readUsbFile(); - bos.write(readBuffer); -- fd.sync(); // Fixes flushing under Windows (unharmful for other OS) -- bufferSize = readBuffer.length; -- received += bufferSize; -+ if (isWindows10) fd.sync(); // Fixes flushing under Windows 10 -+ received += readBuffer.length; - -- logPrinter.updateProgress((received + bufferSize) / (size / 100.0) / 100.0); -+ //logPrinter.print("Received "+readBuffer.length+" b. Got thus far: "+received+" b.", EMsgType.INFO); -+ logPrinter.updateProgress((double)received / (double)size); - } - -- logPrinter.updateProgress(1.0); - bos.close(); - } - -@@ -310,7 +311,7 @@ class NxdtUsbAbi1 { + /** Sending any byte array to USB device **/ +@@ -326,7 +370,7 @@ class NxdtUsbAbi1 { if ( parent.isCancelled() ) throw new InterruptedException("Execution interrupted"); - int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050); + int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, NXDT_USB_TIMEOUT); - switch (result){ - case LibUsb.SUCCESS: -@@ -324,7 +325,6 @@ class NxdtUsbAbi1 { - "\n Returned: "+ UsbErrorCodes.getErrCode(result) + - "\n (execution stopped)"); - } + if (result == LibUsb.SUCCESS) { + if (writeBufTransferred.get() == message.length) +@@ -338,7 +382,6 @@ class NxdtUsbAbi1 { + throw new Exception("Data transfer issue [write]" + + "\n Returned: " + UsbErrorCodes.getErrCode(result) + + "\n (execution stopped)"); - } /** * Reading what USB device responded (command). -@@ -360,29 +360,29 @@ class NxdtUsbAbi1 { +@@ -374,29 +417,25 @@ class NxdtUsbAbi1 { * @return byte array if data read successful * 'null' if read failed * */ - private byte[] readUsbFile() throws Exception{ - ByteBuffer readBuffer = ByteBuffer.allocateDirect(NXDT_FILE_CHUNK_SIZE); -+ private byte[] readUsbFile(int chunk_size) throws Exception{ -+ ByteBuffer readBuffer = ByteBuffer.allocateDirect(chunk_size); ++ private byte[] readUsbFile(int chunkSize) throws Exception{ ++ ByteBuffer readBuffer = ByteBuffer.allocateDirect(chunkSize); IntBuffer readBufTransferred = IntBuffer.allocate(1); - int result; - int countDown = 0; @@ -170,10 +273,7 @@ index 054f03a..f46fed9 100644 - "\n (execution stopped)"); - } + if ( parent.isCancelled() ) -+ { -+ bos.close(); + throw new InterruptedException(); -+ } + + int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, NXDT_USB_TIMEOUT); + @@ -184,7 +284,6 @@ index 054f03a..f46fed9 100644 + readBuffer.get(receivedBytes); + return receivedBytes; + default: -+ bos.close(); + throw new Exception("Data transfer issue [read file]" + + "\n Returned: " + UsbErrorCodes.getErrCode(result)+ + "\n (execution stopped)"); diff --git a/source/usb.c b/source/usb.c index d30d93f..51609dc 100644 --- a/source/usb.c +++ b/source/usb.c @@ -31,6 +31,14 @@ #define USB_TRANSFER_ALIGNMENT 0x1000 /* 4 KiB. */ #define USB_TRANSFER_TIMEOUT 5 /* 5 seconds. */ +#define USB_FS_BCD_REVISION 0x0110 +#define USB_FS_EP_MAX_PACKET_SIZE 0x40 + +#define USB_HS_BCD_REVISION 0x0200 +#define USB_HS_EP_MAX_PACKET_SIZE 0x200 + +#define USB_SS_BCD_REVISION 0x0300 +#define USB_SS_EP_MAX_PACKET_SIZE 0x400 /* Type definitions. */ typedef struct { @@ -108,6 +116,7 @@ static atomic_bool g_usbDetectionThreadCreated = false; static u8 *g_usbTransferBuffer = NULL; static u64 g_usbTransferRemainingSize = 0, g_usbTransferWrittenSize = 0; static u32 g_usbUrbId = 0; +static u16 g_usbEndpointMaxPacketSize = 0; /* Function prototypes. */ @@ -117,6 +126,7 @@ static int usbDetectionThreadFunc(void *arg); static bool usbStartSession(void); static void usbEndSession(void); +static bool usbGetMaxPacketSizeFromHost(void); NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size); static u32 usbSendCommand(size_t cmd_size); @@ -304,8 +314,8 @@ bool usbSendFileData(void *data, u64 data_size) /* First, check if this is the last data chunk for this file. */ if ((g_usbTransferRemainingSize - data_size) == 0) { - /* Enable ZLT if the last chunk size is aligned to the USB max packet size. */ - if (IS_ALIGNED(data_size, 0x40) || IS_ALIGNED(data_size, 0x200) || IS_ALIGNED(data_size, 0x400)) /* USB1, USB2 and USB3 max packet sizes, respectively. */ + /* Enable ZLT if the last chunk size is aligned to the USB endpoint max packet size. */ + if (IS_ALIGNED(data_size, g_usbEndpointMaxPacketSize)) { zlt_required = true; usbSetZltPacket(true); @@ -335,9 +345,6 @@ bool usbSendFileData(void *data, u64 data_size) /* Check if this is the last chunk. */ if (!g_usbTransferRemainingSize) { - /* Disable ZLT if it was previously enabled. */ - if (zlt_required) usbSetZltPacket(false); - /* Check response from host device. */ if (!usbRead(g_usbTransferBuffer, sizeof(UsbStatus), true)) { @@ -360,6 +367,10 @@ bool usbSendFileData(void *data, u64 data_size) } end: + /* Disable ZLT if it was previously enabled. */ + if (zlt_required) usbSetZltPacket(false); + + /* Reset remaining and written sizes in case of errors. */ if (!ret) g_usbTransferRemainingSize = g_usbTransferWrittenSize = 0; rwlockWriteUnlock(&(g_usbDeviceInterface.lock)); @@ -441,16 +452,20 @@ static int usbDetectionThreadFunc(void *arg) g_usbHostAvailable = usbIsHostAvailable(); g_usbSessionStarted = false; g_usbTransferRemainingSize = g_usbTransferWrittenSize = 0; + g_usbEndpointMaxPacketSize = 0; /* Start an USB session if we're connected to a host device. */ /* This will essentially hang this thread and all other threads that call USB-related functions until: */ - /* a) A session is established. */ - /* b) The console is disconnected. */ + /* a) A session is successfully established. */ + /* b) The console is disconnected from the USB host. */ /* c) The thread exit event is triggered. */ if (g_usbHostAvailable) { /* Wait until a session is established. */ - g_usbSessionStarted = usbStartSession(); + /* If the session is successfully established, then we'll get the endpoint max packet size from the data chunk sent by the USB host. */ + /* This is done to accurately know when and where to enable Zero Length Termination (ZLT) packets during bulk transfers. */ + /* As much as I'd like to avoid this, usb:ds doesn't disclose information such as the exact device descriptor and/or speed used by the USB host. */ + g_usbSessionStarted = (usbStartSession() && usbGetMaxPacketSizeFromHost()); /* Check if the exit event was triggered while waiting for a session to be established. */ if (!g_usbSessionStarted && g_usbDetectionThreadExitFlag) break; @@ -464,6 +479,7 @@ static int usbDetectionThreadFunc(void *arg) if (g_usbHostAvailable && g_usbSessionStarted) usbEndSession(); g_usbHostAvailable = g_usbSessionStarted = g_usbDetectionThreadExitFlag = false; g_usbTransferRemainingSize = g_usbTransferWrittenSize = 0; + g_usbEndpointMaxPacketSize = 0; rwlockWriteUnlock(&(g_usbDeviceInterface.lock)); rwlockWriteUnlock(&g_usbDeviceLock); @@ -514,6 +530,32 @@ static void usbEndSession(void) if (!usbWrite(g_usbTransferBuffer, sizeof(UsbCommandHeader), true)) LOGFILE("Failed to send EndSession command!"); } +static bool usbGetMaxPacketSizeFromHost(void) +{ + /* Get the endpoint max packet size from the data chunk sent by the USB host. */ + g_usbEndpointMaxPacketSize = *((u16*)(g_usbTransferBuffer + sizeof(UsbStatus))); + + /* Verify the max packet size value. */ + if (g_usbEndpointMaxPacketSize != USB_FS_EP_MAX_PACKET_SIZE && g_usbEndpointMaxPacketSize != USB_HS_EP_MAX_PACKET_SIZE && g_usbEndpointMaxPacketSize != USB_SS_EP_MAX_PACKET_SIZE) + { + /* Stall input (write) endpoint. */ + /* This will force the client to stop the current session, so a new one will have to be established. */ + rwlockWriteLock(&(g_usbDeviceInterface.lock_in)); + usbDsEndpoint_Stall(g_usbDeviceInterface.endpoint_in); + rwlockWriteUnlock(&(g_usbDeviceInterface.lock_in)); + + /* Reset updated variables. */ + g_usbSessionStarted = false; + g_usbEndpointMaxPacketSize = 0; + + return false; + } + + LOGFILE("USB session successfully established. Endpoint max packet size: 0x%04X.", g_usbEndpointMaxPacketSize); + + return true; +} + NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size) { if (cmd > UsbCommandType_EndSession) return; @@ -542,7 +584,11 @@ static u32 usbSendCommand(size_t cmd_size) return UsbStatusType_WriteCommandFailed; } - if (!usbRead(g_usbTransferBuffer, sizeof(UsbStatus), true)) + /* Make sure to read the USB endpoint max packet size being used by the host if this is a StartSession command. It must be part of the response after the UsbStatus block. */ + u64 read_size = sizeof(UsbStatus); + if (cmd == UsbCommandType_StartSession) read_size += sizeof(g_usbEndpointMaxPacketSize); + + if (!usbRead(g_usbTransferBuffer, read_size, true)) { /* Log error message only if the USB session has been started, or if thread exit flag hasn't been enabled. */ if (g_usbSessionStarted || !g_usbDetectionThreadExitFlag) LOGFILE("Failed to read 0x%lX bytes long status block for type 0x%X command!", sizeof(UsbStatus), cmd); @@ -623,36 +669,36 @@ static bool usbInitializeComms(void) u8 manufacturer = 0, product = 0, serial_number = 0; static const u16 supported_langs[1] = { 0x0409 }; - /* Send language descriptor. */ + /* Set language. */ rc = usbDsAddUsbLanguageStringDescriptor(NULL, supported_langs, sizeof(supported_langs) / sizeof(u16)); if (R_FAILED(rc)) LOGFILE("usbDsAddUsbLanguageStringDescriptor failed! (0x%08X).", rc); - /* Send manufacturer. */ + /* Set manufacturer. */ if (R_SUCCEEDED(rc)) { rc = usbDsAddUsbStringDescriptor(&manufacturer, APP_AUTHOR); if (R_FAILED(rc)) LOGFILE("usbDsAddUsbStringDescriptor failed! (0x%08X) (manufacturer).", rc); } - /* Send product. */ + /* Set product. */ if (R_SUCCEEDED(rc)) { rc = usbDsAddUsbStringDescriptor(&product, APP_TITLE); if (R_FAILED(rc)) LOGFILE("usbDsAddUsbStringDescriptor failed! (0x%08X) (product).", rc); } - /* Send serial number. */ + /* Set serial number. */ if (R_SUCCEEDED(rc)) { rc = usbDsAddUsbStringDescriptor(&serial_number, APP_VERSION); if (R_FAILED(rc)) LOGFILE("usbDsAddUsbStringDescriptor failed! (0x%08X) (serial number).", rc); } - /* Send device descriptors. */ + /* Set device descriptors. */ struct usb_device_descriptor device_descriptor = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0110, + .bcdUSB = USB_FS_BCD_REVISION, .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, @@ -674,7 +720,7 @@ static bool usbInitializeComms(void) } /* High Speed is USB 2.0. */ - device_descriptor.bcdUSB = 0x0200; + device_descriptor.bcdUSB = USB_HS_BCD_REVISION; if (R_SUCCEEDED(rc)) { rc = usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, &device_descriptor); @@ -683,7 +729,7 @@ static bool usbInitializeComms(void) /* Super Speed is USB 3.0. */ /* Upgrade packet size to 512 (1 << 9). */ - device_descriptor.bcdUSB = 0x0300; + device_descriptor.bcdUSB = USB_SS_BCD_REVISION; device_descriptor.bMaxPacketSize0 = 0x09; if (R_SUCCEEDED(rc)) { @@ -824,7 +870,7 @@ static bool usbInitializeDeviceInterface5x(void) .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_ENDPOINT_IN, .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x40, + .wMaxPacketSize = USB_FS_EP_MAX_PACKET_SIZE, }; struct usb_endpoint_descriptor endpoint_descriptor_out = { @@ -832,7 +878,7 @@ static bool usbInitializeDeviceInterface5x(void) .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_ENDPOINT_OUT, .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x40, + .wMaxPacketSize = USB_FS_EP_MAX_PACKET_SIZE, }; struct usb_ss_endpoint_companion_descriptor endpoint_companion = { @@ -881,8 +927,8 @@ static bool usbInitializeDeviceInterface5x(void) } /* High Speed config (USB 2.0). */ - endpoint_descriptor_in.wMaxPacketSize = 0x200; - endpoint_descriptor_out.wMaxPacketSize = 0x200; + endpoint_descriptor_in.wMaxPacketSize = USB_HS_EP_MAX_PACKET_SIZE; + endpoint_descriptor_out.wMaxPacketSize = USB_HS_EP_MAX_PACKET_SIZE; rc = usbDsInterface_AppendConfigurationData(g_usbDeviceInterface.interface, UsbDeviceSpeed_High, &interface_descriptor, USB_DT_INTERFACE_SIZE); if (R_FAILED(rc)) @@ -906,8 +952,8 @@ static bool usbInitializeDeviceInterface5x(void) } /* Super Speed config (USB 3.0). */ - endpoint_descriptor_in.wMaxPacketSize = 0x400; - endpoint_descriptor_out.wMaxPacketSize = 0x400; + endpoint_descriptor_in.wMaxPacketSize = USB_SS_EP_MAX_PACKET_SIZE; + endpoint_descriptor_out.wMaxPacketSize = USB_SS_EP_MAX_PACKET_SIZE; rc = usbDsInterface_AppendConfigurationData(g_usbDeviceInterface.interface, UsbDeviceSpeed_Super, &interface_descriptor, USB_DT_INTERFACE_SIZE); if (R_FAILED(rc)) @@ -987,7 +1033,7 @@ static bool usbInitializeDeviceInterface1x(void) .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_ENDPOINT_IN, .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, + .wMaxPacketSize = USB_HS_EP_MAX_PACKET_SIZE, }; struct usb_endpoint_descriptor endpoint_descriptor_out = { @@ -995,7 +1041,7 @@ static bool usbInitializeDeviceInterface1x(void) .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_ENDPOINT_OUT, .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, + .wMaxPacketSize = USB_HS_EP_MAX_PACKET_SIZE, }; /* Enable device interface. */