mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-26 12:12:02 +00:00
Add endpoint max packet size field to the UsbStatus response block.
And fix typos. lol
This commit is contained in:
parent
7e2aa976b4
commit
c44b9c998e
2 changed files with 30 additions and 36 deletions
|
@ -97,7 +97,7 @@ TitleApplicationMetadata **titleGetApplicationMetadataEntries(bool is_system, u3
|
||||||
/// Returns NULL if an error occurs.
|
/// Returns NULL if an error occurs.
|
||||||
TitleInfo *titleGetInfoFromStorageByTitleId(u8 storage_id, u64 title_id);
|
TitleInfo *titleGetInfoFromStorageByTitleId(u8 storage_id, u64 title_id);
|
||||||
|
|
||||||
/// Populates a TitleUserApplicationData element using an user application ID.
|
/// Populates a TitleUserApplicationData element using a user application ID.
|
||||||
bool titleGetUserApplicationData(u64 app_id, TitleUserApplicationData *out);
|
bool titleGetUserApplicationData(u64 app_id, TitleUserApplicationData *out);
|
||||||
|
|
||||||
/// Returns true if orphan titles are available.
|
/// Returns true if orphan titles are available.
|
||||||
|
|
64
source/usb.c
64
source/usb.c
|
@ -98,8 +98,9 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 magic;
|
u32 magic;
|
||||||
u32 status; ///< UsbStatusType.
|
u32 status; ///< UsbStatusType.
|
||||||
u8 reserved[0x8];
|
u16 max_packet_size; ///< USB host endpoint max packet size.
|
||||||
|
u8 reserved[0x6];
|
||||||
} UsbStatus;
|
} UsbStatus;
|
||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
|
@ -127,7 +128,6 @@ static void usbDetectionThreadFunc(void *arg);
|
||||||
|
|
||||||
static bool usbStartSession(void);
|
static bool usbStartSession(void);
|
||||||
static void usbEndSession(void);
|
static void usbEndSession(void);
|
||||||
static bool usbGetMaxPacketSizeFromHost(void);
|
|
||||||
|
|
||||||
NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size);
|
NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size);
|
||||||
static u32 usbSendCommand(size_t cmd_size);
|
static u32 usbSendCommand(size_t cmd_size);
|
||||||
|
@ -470,11 +470,7 @@ static void usbDetectionThreadFunc(void *arg)
|
||||||
g_usbSessionStarted = usbStartSession();
|
g_usbSessionStarted = usbStartSession();
|
||||||
if (g_usbSessionStarted)
|
if (g_usbSessionStarted)
|
||||||
{
|
{
|
||||||
/* Get the endpoint max packet size from the response sent by the USB host. */
|
LOGFILE("USB session successfully established. Endpoint max packet size: 0x%04X.", g_usbEndpointMaxPacketSize);
|
||||||
/* 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. */
|
|
||||||
/* If this step fails (e.g. unexpected max packet size), the write endpoint will be stalled and we'll wait until a new USB session is established. */
|
|
||||||
if (!(skip_wait = !usbGetMaxPacketSizeFromHost())) LOGFILE("USB session successfully established. Endpoint max packet size: 0x%04X.", g_usbEndpointMaxPacketSize);
|
|
||||||
} else {
|
} else {
|
||||||
/* Check if the exit event was triggered while waiting for a session to be established. */
|
/* Check if the exit event was triggered while waiting for a session to be established. */
|
||||||
if (g_usbDetectionThreadExitFlag) break;
|
if (g_usbDetectionThreadExitFlag) break;
|
||||||
|
@ -522,7 +518,31 @@ static bool usbStartSession(void)
|
||||||
cmd_size = (sizeof(UsbCommandHeader) + sizeof(UsbCommandStartSession));
|
cmd_size = (sizeof(UsbCommandHeader) + sizeof(UsbCommandStartSession));
|
||||||
|
|
||||||
status = usbSendCommand(cmd_size);
|
status = usbSendCommand(cmd_size);
|
||||||
if (status != UsbStatusType_Success) usbLogStatusDetail(status);
|
if (status == UsbStatusType_Success)
|
||||||
|
{
|
||||||
|
/* Get the endpoint max packet size from the response 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. */
|
||||||
|
/* If this step fails (e.g. unexpected max packet size), the write endpoint will be stalled and we'll wait until a new USB session is established. */
|
||||||
|
UsbStatus *cmd_status = (UsbStatus*)g_usbTransferBuffer;
|
||||||
|
g_usbEndpointMaxPacketSize = cmd_status->max_packet_size;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
LOGFILE("Invalid endpoint max packet size value received from USB host: 0x%04X.", g_usbEndpointMaxPacketSize);
|
||||||
|
|
||||||
|
/* 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 flags. */
|
||||||
|
g_usbEndpointMaxPacketSize = 0;
|
||||||
|
cmd_status->status = status = UsbStatusType_HostIoError;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usbLogStatusDetail(status);
|
||||||
|
}
|
||||||
|
|
||||||
return (status == UsbStatusType_Success);
|
return (status == UsbStatusType_Success);
|
||||||
}
|
}
|
||||||
|
@ -540,30 +560,6 @@ static void usbEndSession(void)
|
||||||
if (!usbWrite(g_usbTransferBuffer, sizeof(UsbCommandHeader), true)) LOGFILE("Failed to send EndSession command!");
|
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 flags. */
|
|
||||||
g_usbSessionStarted = false;
|
|
||||||
g_usbEndpointMaxPacketSize = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size)
|
NX_INLINE void usbPrepareCommandHeader(u32 cmd, u32 cmd_block_size)
|
||||||
{
|
{
|
||||||
if (cmd > UsbCommandType_EndSession) return;
|
if (cmd > UsbCommandType_EndSession) return;
|
||||||
|
@ -592,9 +588,7 @@ static u32 usbSendCommand(size_t cmd_size)
|
||||||
return UsbStatusType_WriteCommandFailed;
|
return UsbStatusType_WriteCommandFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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);
|
u64 read_size = sizeof(UsbStatus);
|
||||||
if (cmd == UsbCommandType_StartSession) read_size += sizeof(g_usbEndpointMaxPacketSize);
|
|
||||||
|
|
||||||
if (!usbRead(g_usbTransferBuffer, read_size, true))
|
if (!usbRead(g_usbTransferBuffer, read_size, true))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue