From f1ef3bdcd7e2b22ecce67705d931de6b43fb9a20 Mon Sep 17 00:00:00 2001 From: Florin9doi Date: Wed, 1 May 2024 12:50:44 +0300 Subject: [PATCH] USB: Allow UsbPspCm passthrough --- rpcs3/Emu/Cell/lv2/sys_usbd.cpp | 21 ++++++++++++++++++--- rpcs3/Emu/Io/usb_device.cpp | 4 ++-- rpcs3/Emu/Io/usb_device.h | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp index 764456459f..3bcce1bef8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_usbd.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_usbd.cpp @@ -363,6 +363,9 @@ usb_handler_thread::usb_handler_thread() // Tony Hawk RIDE Skateboard check_device(0x12BA, 0x0400, 0x0400, "Tony Hawk RIDE Skateboard Controller"); + + // PSP in UsbPspCm mode + check_device(0x054C, 0x01CB, 0x01CB, "UsbPspcm"); } libusb_free_device_list(list, 1); @@ -588,7 +591,15 @@ void usb_handler_thread::transfer_complete(struct libusb_transfer* transfer) case LIBUSB_TRANSFER_CANCELLED: case LIBUSB_TRANSFER_STALL: case LIBUSB_TRANSFER_NO_DEVICE: - default: usbd_transfer->result = EHCI_CC_HALTED; break; + default: + usbd_transfer->result = EHCI_CC_HALTED; + if (usbd_transfer->assigned_number && handled_devices.erase(usbd_transfer->assigned_number)) + { + send_message(SYS_USBD_DETACH, usbd_transfer->assigned_number); + sys_usbd.warning("USB transfer failed, detach the device %d", usbd_transfer->assigned_number); + usbd_transfer->assigned_number = 0; + } + break; } usbd_transfer->count = transfer->actual_length; @@ -971,6 +982,7 @@ error_code sys_usbd_register_ldd(ppu_thread& ppu, u32 handle, vm::cptr s_p // Unsure how many more devices might need similar treatment (i.e. just a compare and force VID/PID add), or if it's worth adding a full promiscuous capability static const std::unordered_map> predefined_ldds { + {"cellUsbPspcm", {0x054C, 0x01CB, 0x01CB}}, {"guncon3", {0x0B9A, 0x0800, 0x0800}}, {"PS3A-USJ", {0x0B9A, 0x0900, 0x0910}} }; @@ -995,11 +1007,12 @@ error_code sys_usbd_unregister_ldd(ppu_thread& ppu, u32 handle, vm::cptr s } // TODO: determine what the unknown params are -error_code sys_usbd_open_pipe(ppu_thread& ppu, u32 handle, u32 device_handle, u32 unk1, u64 unk2, u64 unk3, u32 endpoint, u64 unk4) +// attributes (bmAttributes) : 2=Bulk, 3=Interrupt +error_code sys_usbd_open_pipe(ppu_thread& ppu, u32 handle, u32 device_handle, u32 unk1, u64 unk2, u64 unk3, u32 endpoint, u64 attributes) { ppu.state += cpu_flag::wait; - sys_usbd.warning("sys_usbd_open_pipe(handle=0x%x, device_handle=0x%x, unk1=0x%x, unk2=0x%x, unk3=0x%x, endpoint=0x%x, unk4=0x%x)", handle, device_handle, unk1, unk2, unk3, endpoint, unk4); + sys_usbd.warning("sys_usbd_open_pipe(handle=0x%x, device_handle=0x%x, unk1=0x%x, unk2=0x%x, unk3=0x%x, endpoint=0x%x, attributes=0x%x)", handle, device_handle, unk1, unk2, unk3, endpoint, attributes); auto& usbh = g_fxo->get>(); @@ -1166,6 +1179,8 @@ error_code sys_usbd_transfer_data(ppu_thread& ppu, u32 handle, u32 id_pipe, vm:: const auto& pipe = usbh.get_pipe(id_pipe); auto&& [transfer_id, transfer] = usbh.get_free_transfer(); + transfer.assigned_number = pipe.device->assigned_number; + // Default endpoint is control endpoint if (pipe.endpoint == 0) { diff --git a/rpcs3/Emu/Io/usb_device.cpp b/rpcs3/Emu/Io/usb_device.cpp index 58a8a55b79..a7c3812b41 100644 --- a/rpcs3/Emu/Io/usb_device.cpp +++ b/rpcs3/Emu/Io/usb_device.cpp @@ -85,7 +85,7 @@ void usb_device_passthrough::send_libusb_transfer(libusb_transfer* transfer) case LIBUSB_ERROR_BUSY: continue; default: { - sys_usbd.error("Unexpected error from libusb_submit_transfer: %d", res); + sys_usbd.error("Unexpected error from libusb_submit_transfer: %d(%s)", res, libusb_error_name(res)); return; } } @@ -114,7 +114,7 @@ void usb_device_passthrough::read_descriptors() int ssize = libusb_control_transfer(lusb_handle, +LIBUSB_ENDPOINT_IN | +LIBUSB_REQUEST_TYPE_STANDARD | +LIBUSB_RECIPIENT_DEVICE, LIBUSB_REQUEST_GET_DESCRIPTOR, 0x0200 | index, 0, buf, 1000, 0); if (ssize < 0) { - sys_usbd.fatal("Couldn't get the config from the device: %d", ssize); + sys_usbd.fatal("Couldn't get the config from the device: %d(%s)", ssize, libusb_error_name(ssize)); continue; } diff --git a/rpcs3/Emu/Io/usb_device.h b/rpcs3/Emu/Io/usb_device.h index 2a09db58da..e0fad67966 100644 --- a/rpcs3/Emu/Io/usb_device.h +++ b/rpcs3/Emu/Io/usb_device.h @@ -88,6 +88,7 @@ struct UsbDeviceHID struct UsbTransfer { + u32 assigned_number = 0; u32 transfer_id = 0; s32 result = 0;