From ed4f09f0521fc58024cf8b723bcb2414a0f91283 Mon Sep 17 00:00:00 2001 From: Julian Uy Date: Sat, 30 May 2026 18:36:59 -0500 Subject: [PATCH] improvement: Use GetThreadId/WakeupThread/SleepThread instead of CreateSema/SignalSema/WaitSema Will improve handling in borderline cases where semaphore limit is exhausted Replaced in the cases where initial_value=0, SignalSema was in callback and CreateSema/WaitSema is in same thread --- ee/kernel/src/delaythread.c | 22 +++----- ee/kernel/src/sifrpc.c | 51 ++++++------------ ee/libcglue/src/sleep.c | 24 +++------ ee/mpeg/src/libmpeg_core.c | 15 ++---- iop/cdvd/poffsim/src/imports.lst | 10 ++-- iop/cdvd/poffsim/src/irx_imports.h | 1 - iop/cdvd/poffsim/src/poweroff.c | 16 +++--- iop/usb/usbhdfsd/include/usbhdfsd.h | 1 - iop/usb/usbhdfsd/src/imports.lst | 3 ++ iop/usb/usbhdfsd/src/usb_driver.c | 66 +++++++++++------------ iop/usb/usbmass_bd/src/imports.lst | 3 ++ iop/usb/usbmass_bd/src/usb_mass.c | 82 +++++++++++++++-------------- 12 files changed, 123 insertions(+), 171 deletions(-) diff --git a/ee/kernel/src/delaythread.c b/ee/kernel/src/delaythread.c index 0717c8b4150a..0ded5df99041 100644 --- a/ee/kernel/src/delaythread.c +++ b/ee/kernel/src/delaythread.c @@ -27,7 +27,7 @@ static u64 DelayThreadWakeup_callback(s32 alarm_id, u64 scheduled_time, u64 actu (void)actual_time; (void)pc_value; - iSignalSema((s32)arg); + iWakeupThread((s32)arg); ExitHandler(); return 0; } @@ -35,31 +35,23 @@ static u64 DelayThreadWakeup_callback(s32 alarm_id, u64 scheduled_time, u64 actu s32 DelayThread(s32 microseconds) { u32 eie; - s32 sema_id; + volatile s32 thread_id; s32 timer_alarm_id; - ee_sema_t sema; eie = get_mips_cop_reg(0, COP0_REG_Status); if ((eie & 0x10000) == 0) { return 0x80008008; // ECPUDI } - sema.max_count = 1; - sema.option = (u32)"DelayThread"; - sema.init_count = 0; - sema_id = CreateSema(&sema); - if (sema_id < 0) - { - return 0x80008003; // ESEMAPHORE - } - timer_alarm_id = SetTimerAlarm(TimerUSec2BusClock(0, microseconds), DelayThreadWakeup_callback, (void *)sema_id); + thread_id = GetThreadId(); + timer_alarm_id = SetTimerAlarm(TimerUSec2BusClock(0, microseconds), DelayThreadWakeup_callback, (void *)thread_id); if (timer_alarm_id < 0) { - DeleteSema(sema_id); + thread_id = -1; return timer_alarm_id; } - WaitSema(sema_id); - DeleteSema(sema_id); + SleepThread(); + thread_id = -1; return 0; } #endif diff --git a/ee/kernel/src/sifrpc.c b/ee/kernel/src/sifrpc.c index 42c676599391..f13197589cd4 100644 --- a/ee/kernel/src/sifrpc.c +++ b/ee/kernel/src/sifrpc.c @@ -112,7 +112,6 @@ void *_rpc_get_fpacket(struct rpc_data *rpc_data) #ifdef F_sceSifBindRpc int sceSifBindRpc(SifRpcClientData_t *cd, int sid, int mode) { - ee_sema_t sema; SifRpcBindPkt_t *bind; bind = (SifRpcBindPkt_t *)_rpc_get_packet(&_sif_rpc_data); @@ -138,22 +137,16 @@ int sceSifBindRpc(SifRpcClientData_t *cd, int sid, int mode) return 0; } - sema.max_count = 1; - sema.init_count = 0; - cd->hdr.sema_id = CreateSema(&sema); - if (cd->hdr.sema_id < 0) { - rpc_packet_free(bind); - return -E_LIB_SEMA_CREATE; - } + cd->hdr.sema_id = GetThreadId(); if (!sceSifSendCmd(SIF_CMD_RPC_BIND, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(bind); - DeleteSema(cd->hdr.sema_id); + cd->hdr.sema_id = -1; return -E_SIF_PKT_SEND; } - WaitSema(cd->hdr.sema_id); - DeleteSema(cd->hdr.sema_id); + SleepThread(); + cd->hdr.sema_id = -1; return 0; } @@ -163,7 +156,6 @@ int sceSifBindRpc(SifRpcClientData_t *cd, int sid, int mode) int sceSifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbuf, int ssize, void *recvbuf, int rsize, SifRpcEndFunc_t end_function, void *end_param) { - ee_sema_t sema; SifRpcCallPkt_t *call; call = (SifRpcCallPkt_t *)_rpc_get_packet(&_sif_rpc_data); @@ -204,22 +196,16 @@ int sceSifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbu return 0; } - sema.max_count = 1; - sema.init_count = 0; - cd->hdr.sema_id = CreateSema(&sema); - if (cd->hdr.sema_id < 0) { - rpc_packet_free(call); - return -E_LIB_SEMA_CREATE; - } + cd->hdr.sema_id = GetThreadId(); if (!sceSifSendCmd(SIF_CMD_RPC_CALL, call, RPC_PACKET_SIZE, sendbuf, cd->buf, ssize)) { rpc_packet_free(call); - DeleteSema(cd->hdr.sema_id); + cd->hdr.sema_id = -1; return -E_SIF_PKT_SEND; } - WaitSema(cd->hdr.sema_id); - DeleteSema(cd->hdr.sema_id); + SleepThread(); + cd->hdr.sema_id = -1; return 0; } @@ -228,7 +214,6 @@ int sceSifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbu #ifdef F_sceSifGetOtherData int sceSifGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, int mode) { - ee_sema_t sema; SifRpcOtherDataPkt_t *other; other = (SifRpcOtherDataPkt_t *)_rpc_get_packet(&_sif_rpc_data); @@ -253,22 +238,16 @@ int sceSifGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, return 0; } - sema.max_count = 1; - sema.init_count = 0; - rd->hdr.sema_id = CreateSema(&sema); - if (rd->hdr.sema_id < 0) { - rpc_packet_free(other); - return -E_LIB_SEMA_CREATE; - } + rd->hdr.sema_id = GetThreadId(); if (!sceSifSendCmd(SIF_CMD_RPC_RDATA, other, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(other); - DeleteSema(rd->hdr.sema_id); + rd->hdr.sema_id = -1; return -E_SIF_PKT_SEND; } - WaitSema(rd->hdr.sema_id); - DeleteSema(rd->hdr.sema_id); + SleepThread(); + rd->hdr.sema_id = -1; return 0; } @@ -312,8 +291,10 @@ static void _request_end(SifRpcRendPkt_t *request, void *data) cd->cbuf = request->cbuf; } - if (cd->hdr.sema_id >= 0) - iSignalSema(cd->hdr.sema_id); + if (cd->hdr.sema_id >= 0) { + iWakeupThread(cd->hdr.sema_id); + cd->hdr.sema_id = -1; + } rpc_packet_free(cd->hdr.pkt_addr); cd->hdr.pkt_addr = NULL; diff --git a/ee/libcglue/src/sleep.c b/ee/libcglue/src/sleep.c index 602d8b26c681..596d90a8f55d 100755 --- a/ee/libcglue/src/sleep.c +++ b/ee/libcglue/src/sleep.c @@ -28,7 +28,7 @@ static u64 nanosleep_wakeup_callback(s32 alarm_id, u64 scheduled_time, u64 actua (void)actual_time; (void)pc_value; - iSignalSema((s32)arg); + iWakeupThread((s32)arg); ExitHandler(); return 0; } @@ -36,9 +36,8 @@ static u64 nanosleep_wakeup_callback(s32 alarm_id, u64 scheduled_time, u64 actua int nanosleep(const struct timespec *req, struct timespec *rem) { u32 eie; - s32 sema_id; + volatile s32 thread_id; s32 timer_alarm_id; - ee_sema_t sema; eie = get_mips_cop_reg(0, COP0_REG_Status); if ((eie & 0x10000) == 0) @@ -46,25 +45,16 @@ int nanosleep(const struct timespec *req, struct timespec *rem) errno = ENOSYS; // Functionality not available return -1; } - sema.max_count = 1; - sema.option = (u32)"nanosleep"; - sema.init_count = 0; - sema_id = CreateSema(&sema); - if (sema_id < 0) - { - errno = EAGAIN; // Resource temporarily unavailable - return -1; - } - timer_alarm_id = SetTimerAlarm(Sec2TimerBusClock(req->tv_sec) + NSec2TimerBusClock(req->tv_nsec), nanosleep_wakeup_callback, (void *)sema_id); + thread_id = GetThreadId(); + timer_alarm_id = SetTimerAlarm(Sec2TimerBusClock(req->tv_sec) + NSec2TimerBusClock(req->tv_nsec), nanosleep_wakeup_callback, (void *)thread_id); if (timer_alarm_id < 0) { - DeleteSema(sema_id); + thread_id = -1; errno = EAGAIN; // Resource temporarily unavailable return -1; } - WaitSema(sema_id); - DeleteSema(sema_id); - + SleepThread(); + thread_id = -1; if (rem != NULL) { rem->tv_sec = 0; diff --git a/ee/mpeg/src/libmpeg_core.c b/ee/mpeg/src/libmpeg_core.c index 8fe566018508..2af74b9d6c69 100644 --- a/ee/mpeg/src/libmpeg_core.c +++ b/ee/mpeg/src/libmpeg_core.c @@ -49,7 +49,7 @@ static int (*s_SetDMA_func)(void *userdata); static void *s_SetDMA_arg; static struct IPUState s_IPUState; static int *s_pEOF; -static int s_Sema; +static volatile s32 s_Thread; static struct CSCParam s_CSCParam; static int s_CSCID; static u8 s_CSCFlag; @@ -126,7 +126,6 @@ extern s32 _mpeg_dmac_handler(s32 channel, void *arg, void *addr); void _MPEG_Initialize(_MPEGContext *mc, int (*data_cb)(void *userdata), void *cb_user, int *eof_flag) { (void)mc; - ee_sema_t sema; *R_EE_IPU_CTRL = IPU_CTRL_RST; while (*R_EE_IPU_CTRL & IPU_CTRL_BUSY) @@ -142,11 +141,6 @@ void _MPEG_Initialize(_MPEGContext *mc, int (*data_cb)(void *userdata), void *cb s_pEOF = eof_flag; *s_pEOF = 0; - memset(&sema, 0, sizeof(sema)); - sema.init_count = 0; - sema.max_count = 1; - sema.option = 0; - s_Sema = CreateSema(&sema); s_CSCID = AddDmacHandler2(3, _mpeg_dmac_handler, 0, &s_CSCParam); s_BitsBuffered = 0; s_LocalBits = 0; @@ -157,7 +151,6 @@ void _MPEG_Destroy(void) while (READ_ONCE(s_CSCFlag) != 0) ; RemoveDmacHandler(3, s_CSCID); - DeleteSema(s_Sema); } void _ipu_suspend(void) @@ -248,7 +241,7 @@ s32 _mpeg_dmac_handler(s32 channel, void *arg, void *addr) if (cp->blocks == 0) { iDisableDmac(3); - iSignalSema(s_Sema); + iWakeupThread(s_Thread); WRITE_ONCE(s_CSCFlag, 0); return -1; } @@ -291,13 +284,15 @@ int _MPEG_CSCImage(void *source, void *dest, int mbcount) *R_EE_D4_QWC = (mbc * sizeof(_MPEGMacroBlock8)) >> 4; *R_EE_D3_QWC = (mbc * RGBA32_BLOCK_SIZE) >> 4; + s_Thread = GetThreadId(); EnableDmac(3); *R_EE_D4_CHCR = 0x101; *R_EE_IPU_CMD = IPU_COMMAND_CSC | mbc; *R_EE_D3_CHCR = 0x100; WRITE_ONCE(s_CSCFlag, 1); - WaitSema(s_Sema); + SleepThread(); + s_Thread = -1; _ipu_resume(); return mbc; } diff --git a/iop/cdvd/poffsim/src/imports.lst b/iop/cdvd/poffsim/src/imports.lst index 451736cbf427..766d747dbf0b 100644 --- a/iop/cdvd/poffsim/src/imports.lst +++ b/iop/cdvd/poffsim/src/imports.lst @@ -9,15 +9,11 @@ sysmem_IMPORTS_end thbase_IMPORTS_start I_SetAlarm +I_GetThreadId +I_iWakeupThread +I_SleepThread thbase_IMPORTS_end thevent_IMPORTS_start I_iSetEventFlag thevent_IMPORTS_end - -thsemap_IMPORTS_start -I_CreateSema -I_DeleteSema -I_iSignalSema -I_WaitSema -thsemap_IMPORTS_end diff --git a/iop/cdvd/poffsim/src/irx_imports.h b/iop/cdvd/poffsim/src/irx_imports.h index baabb5f41ab3..f84eaa67c226 100644 --- a/iop/cdvd/poffsim/src/irx_imports.h +++ b/iop/cdvd/poffsim/src/irx_imports.h @@ -17,6 +17,5 @@ #include #include #include -#include #endif /* IOP_IRX_IMPORTS_H */ diff --git a/iop/cdvd/poffsim/src/poweroff.c b/iop/cdvd/poffsim/src/poweroff.c index de638b8b9ccf..5c5b861f439d 100644 --- a/iop/cdvd/poffsim/src/poweroff.c +++ b/iop/cdvd/poffsim/src/poweroff.c @@ -17,7 +17,7 @@ struct poffemu_param_stru int m_cdvdman_intr_efid; void (*m_cdvdman_poff_cb)(void *arg); void *m_cdvdman_poffarg; - int m_sema_id; + int m_thread_id; }; static struct poffemu_param_stru sCdPtbl; @@ -32,25 +32,21 @@ static unsigned int _sceCdPoffEmu(void *userdata) iSetEventFlag(arg->m_cdvdman_intr_efid, 0x10); if ( arg->m_cdvdman_poff_cb ) arg->m_cdvdman_poff_cb(arg->m_cdvdman_poffarg); - iSignalSema(arg->m_sema_id); + iWakeupThread(arg->m_thread_id); return 0; } int _start(int ac, char **av) { int unusedval; - iop_sema_t semaparam; // Unofficial: the following variable has been made local stack iop_sys_clock_t sCdPoff_time; (void)ac; (void)av; - semaparam.attr = 1; - semaparam.initial = 0; - semaparam.max = 1; - semaparam.option = 0; - sCdPtbl.m_sema_id = CreateSema(&semaparam); + // Unofficial: Use GetThreadId/iWakeupThread/SleepThread instead of CreateSema/iSignalSema/WaitSema + sCdPtbl.m_thread_id = GetThreadId(); sCdPtbl.m_cdvdman_intr_efid = sceCdSC(0xFFFFFFF5, &unusedval); sCdPtbl.m_cdvdman_poff_cb = 0; if ( (unsigned int)sceCdSC(0xFFFFFFF7, &unusedval) < 0x222 ) @@ -64,7 +60,7 @@ int _start(int ac, char **av) sCdPoff_time.hi = 0; sCdPoff_time.lo = 0x90000; SetAlarm(&sCdPoff_time, _sceCdPoffEmu, &sCdPtbl); - WaitSema(sCdPtbl.m_sema_id); - DeleteSema(sCdPtbl.m_sema_id); + SleepThread(); + sCdPtbl.m_thread_id = -1; return 1; } diff --git a/iop/usb/usbhdfsd/include/usbhdfsd.h b/iop/usb/usbhdfsd/include/usbhdfsd.h index 6f31a3419d8c..8522c38a09d7 100644 --- a/iop/usb/usbhdfsd/include/usbhdfsd.h +++ b/iop/usb/usbhdfsd/include/usbhdfsd.h @@ -73,7 +73,6 @@ struct _mass_dev unsigned char interfaceAlt; // interface alternate setting unsigned int sectorSize; // = 512; // store size of sector from usb mass unsigned int maxLBA; - int ioSema; cache_set *cache; usbmass_cb_t callback; }; diff --git a/iop/usb/usbhdfsd/src/imports.lst b/iop/usb/usbhdfsd/src/imports.lst index c1ec1b2feeff..cfe7c16395df 100644 --- a/iop/usb/usbhdfsd/src/imports.lst +++ b/iop/usb/usbhdfsd/src/imports.lst @@ -30,6 +30,9 @@ sysclib_IMPORTS_end thbase_IMPORTS_start I_DelayThread +I_GetThreadId +I_WakeupThread +I_SleepThread thbase_IMPORTS_end thsemap_IMPORTS_start diff --git a/iop/usb/usbhdfsd/src/usb_driver.c b/iop/usb/usbhdfsd/src/usb_driver.c index 76c6274f16ca..6653a82832f8 100644 --- a/iop/usb/usbhdfsd/src/usb_driver.c +++ b/iop/usb/usbhdfsd/src/usb_driver.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -104,7 +104,7 @@ static sceUsbdLddOps driver; typedef struct _usb_callback_data { - int sema; + int thid; int returnCode; int returnSize; } usb_callback_data; @@ -113,7 +113,7 @@ typedef struct _usb_callback_data typedef struct _usb_transfer_callback_data { - int sema; + int thid; int pipe; u8 *buffer; int returnCode; @@ -134,7 +134,7 @@ static void usb_callback(int resultCode, int bytes, void *arg) data->returnCode = resultCode; data->returnSize = bytes; XPRINTF("callback: res %d, bytes %d, arg %p \n", resultCode, bytes, arg); - SignalSema(data->sema); + WakeupThread(data->thid); } static int perform_bulk_transfer(usb_transfer_callback_data *data) @@ -167,10 +167,10 @@ static void usb_transfer_callback(int resultCode, int bytes, void *arg) ret = perform_bulk_transfer(data); if (ret != USB_RC_OK) { data->returnCode = ret; - SignalSema(data->sema); + WakeupThread(data->thid); } } else { - SignalSema(data->sema); + WakeupThread(data->thid); } } @@ -179,15 +179,16 @@ static int usb_set_configuration(mass_dev *dev, int configNumber) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); XPRINTF("setting configuration controlEp=%i, confNum=%i \n", dev->controlEp, configNumber); ret = sceUsbdSetConfiguration(dev->controlEp, configNumber, usb_callback, (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; return ret; } @@ -197,15 +198,16 @@ static int usb_set_interface(mass_dev *dev, int interface, int altSetting) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); XPRINTF("setting interface controlEp=%i, interface=%i altSetting=%i\n", dev->controlEp, interface, altSetting); ret = sceUsbdSetInterface(dev->controlEp, interface, altSetting, usb_callback, (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; return ret; } @@ -215,7 +217,7 @@ static int usb_bulk_clear_halt(mass_dev *dev, int endpoint) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); ret = sceUsbdClearEndpointFeature( dev->controlEp, // Config pipe @@ -225,9 +227,10 @@ static int usb_bulk_clear_halt(mass_dev *dev, int endpoint) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret != USB_RC_OK) { printf("USBHDFSD: Error - sending clear halt %d\n", ret); } @@ -240,7 +243,7 @@ static void usb_bulk_reset(mass_dev *dev, int mode) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); // Call Bulk only mass storage reset ret = sceUsbdControlTransfer( @@ -255,9 +258,10 @@ static void usb_bulk_reset(mass_dev *dev, int mode) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret == USB_RC_OK) { // clear bulk-in endpoint if (mode & 0x01) @@ -279,7 +283,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); csw->signature = CSW_TAG; csw->tag = tag; @@ -294,7 +298,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; if (cb_data.returnSize != 13) @@ -303,6 +307,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) printf("USBHDFSD: bulk csw.status residue: %u\n", csw->dataResidue); XPRINTF("bulk csw result: %d, csw.status: %u\n", ret, csw->status); } + cb_data.thid = -1; return ret; } @@ -344,7 +349,7 @@ static int usb_bulk_get_max_lun(mass_dev *dev) usb_callback_data cb_data; char max_lun; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); // Call Bulk only mass storage reset ret = sceUsbdControlTransfer( @@ -359,9 +364,10 @@ static int usb_bulk_get_max_lun(mass_dev *dev) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret == USB_RC_OK) { ret = max_lun; } else { @@ -385,7 +391,7 @@ static int usb_bulk_command(mass_dev *dev, cbw_packet *packet) return -1; } - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); ret = sceUsbdBulkTransfer( dev->bulkEpO, // bulk output pipe @@ -395,9 +401,10 @@ static int usb_bulk_command(mass_dev *dev, cbw_packet *packet) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret != USB_RC_OK) { printf("USBHDFSD: Error - sending bulk command %d. Calling reset recovery.\n", ret); usb_bulk_reset(dev, 3); @@ -411,7 +418,7 @@ static int usb_bulk_transfer(mass_dev *dev, int direction, void *buffer, unsigne int ret; usb_transfer_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); cb_data.pipe = (direction == USB_BLK_EP_IN) ? dev->bulkEpI : dev->bulkEpO; cb_data.buffer = buffer; cb_data.returnCode = 0; @@ -419,10 +426,10 @@ static int usb_bulk_transfer(mass_dev *dev, int direction, void *buffer, unsigne ret = perform_bulk_transfer(&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } - + cb_data.thid = -1; if (ret != USB_RC_OK) { printf("USBHDFSD: Error - bulk data transfer %d. Clearing HALT state.\n", cb_data.returnCode); usb_bulk_clear_halt(dev, direction); @@ -878,7 +885,6 @@ int mass_stor_connect(int devId) UsbConfigDescriptor *config; UsbInterfaceDescriptor *interface; UsbEndpointDescriptor *endpoint; - iop_sema_t SemaData; mass_dev *dev; printf("USBHDFSD: connect: devId=%i\n", devId); @@ -930,16 +936,6 @@ int mass_stor_connect(int devId) return -1; } - SemaData.initial = 0; - SemaData.max = 1; - SemaData.option = 0; - SemaData.attr = 0; - if ((dev->ioSema = CreateSema(&SemaData)) < 0) { - mass_stor_release(dev); - printf("USBHDFSD: Failed to allocate I/O semaphore.\n"); - return -1; - } - /*store current configuration id - can't call set_configuration here */ dev->devId = devId; dev->configId = config->bConfigurationValue; @@ -987,8 +983,6 @@ int mass_stor_disconnect(int devId) dev->cache = NULL; dev->devId = -1; - DeleteSema(dev->ioSema); - if (dev->callback != NULL) dev->callback(USBMASS_DEV_EV_DISCONN); } diff --git a/iop/usb/usbmass_bd/src/imports.lst b/iop/usb/usbmass_bd/src/imports.lst index 1f1674d17367..d8c5fde237b0 100644 --- a/iop/usb/usbmass_bd/src/imports.lst +++ b/iop/usb/usbmass_bd/src/imports.lst @@ -19,6 +19,9 @@ I_CreateThread I_StartThread I_DeleteThread I_DelayThread +I_GetThreadId +I_WakeupThread +I_SleepThread thbase_IMPORTS_end thsemap_IMPORTS_start diff --git a/iop/usb/usbmass_bd/src/usb_mass.c b/iop/usb/usbmass_bd/src/usb_mass.c index 8e11032d716d..dc0a38744591 100644 --- a/iop/usb/usbmass_bd/src/usb_mass.c +++ b/iop/usb/usbmass_bd/src/usb_mass.c @@ -47,7 +47,6 @@ typedef struct _mass_dev unsigned char status; unsigned char interfaceNumber; // interface number unsigned char interfaceAlt; // interface alternate setting - int ioSema; struct scsi_interface scsi; } mass_dev; @@ -74,7 +73,7 @@ static sceUsbdLddOps driver; typedef struct _usb_callback_data { - int sema; + int thid; int returnCode; int returnSize; } usb_callback_data; @@ -83,7 +82,7 @@ typedef struct _usb_callback_data typedef struct _usb_transfer_callback_data { - int sema; + int thid; int pipe; u8 *buffer; int returnCode; @@ -107,7 +106,7 @@ static void usb_callback(int resultCode, int bytes, void *arg) data->returnCode = resultCode; data->returnSize = bytes; M_DEBUG("callback: res %d, bytes %d, arg %p \n", resultCode, bytes, arg); - SignalSema(data->sema); + WakeupThread(data->thid); } #ifndef ASYNC @@ -141,10 +140,10 @@ static void usb_transfer_callback(int resultCode, int bytes, void *arg) ret = perform_bulk_transfer(data); if (ret != USB_RC_OK) { data->returnCode = ret; - SignalSema(data->sema); + WakeupThread(data->thid); } } else { - SignalSema(data->sema); + WakeupThread(data->thid); } } #endif @@ -154,15 +153,16 @@ static int usb_set_configuration(mass_dev *dev, int configNumber) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); M_DEBUG("setting configuration controlEp=%i, confNum=%i \n", dev->controlEp, configNumber); ret = sceUsbdSetConfiguration(dev->controlEp, configNumber, usb_callback, (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; return ret; } @@ -172,15 +172,16 @@ static int usb_set_interface(mass_dev *dev, int interface, int altSetting) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); M_DEBUG("setting interface controlEp=%i, interface=%i altSetting=%i\n", dev->controlEp, interface, altSetting); ret = sceUsbdSetInterface(dev->controlEp, interface, altSetting, usb_callback, (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; return ret; } @@ -190,7 +191,7 @@ static int usb_bulk_clear_halt(mass_dev *dev, int endpoint) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); ret = sceUsbdClearEndpointFeature( dev->controlEp, // Config pipe @@ -200,9 +201,10 @@ static int usb_bulk_clear_halt(mass_dev *dev, int endpoint) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret != USB_RC_OK) { M_DEBUG("ERROR: sending clear halt %d\n", ret); } @@ -216,7 +218,7 @@ static void usb_bulk_reset(mass_dev *dev, int mode) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); // Call Bulk only mass storage reset ret = sceUsbdControlTransfer( @@ -231,9 +233,10 @@ static void usb_bulk_reset(mass_dev *dev, int mode) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret == USB_RC_OK) { // clear bulk-in endpoint if (mode & 0x01) @@ -255,7 +258,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) int ret; usb_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); csw->signature = CSW_TAG; csw->tag = tag; @@ -270,7 +273,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; #ifdef DEBUG @@ -281,6 +284,7 @@ static int usb_bulk_status(mass_dev *dev, csw_packet *csw, unsigned int tag) M_DEBUG("bulk csw result: %d, csw.status: %i\n", ret, csw->status); #endif } + cb_data.thid = -1; return ret; } @@ -324,7 +328,7 @@ static int usb_bulk_get_max_lun(struct scsi_interface *scsi) usb_callback_data cb_data; char max_lun; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); // Call Bulk only mass storage reset ret = sceUsbdControlTransfer( @@ -339,9 +343,10 @@ static int usb_bulk_get_max_lun(struct scsi_interface *scsi) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret == USB_RC_OK) { ret = max_lun; } else { @@ -363,6 +368,7 @@ struct usbmass_cmd csw_packet csw; int cmd_count; + int thid; int returnCode; }; @@ -377,7 +383,7 @@ static int usb_bulk_command(mass_dev *dev, cbw_packet *packet) return -1; } - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); ret = sceUsbdBulkTransfer( dev->bulkEpO, // bulk output pipe @@ -387,9 +393,10 @@ static int usb_bulk_command(mass_dev *dev, cbw_packet *packet) (void *)&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret != USB_RC_OK) { M_DEBUG("ERROR: sending bulk command %d. Calling reset recovery.\n", ret); usb_bulk_reset(dev, 3); @@ -403,7 +410,7 @@ static int usb_bulk_transfer(mass_dev *dev, int direction, void *buffer, unsigne int ret; usb_transfer_callback_data cb_data; - cb_data.sema = dev->ioSema; + cb_data.thid = GetThreadId(); cb_data.pipe = (direction == USB_BLK_EP_IN) ? dev->bulkEpI : dev->bulkEpO; cb_data.buffer = buffer; cb_data.returnCode = 0; @@ -411,9 +418,10 @@ static int usb_bulk_transfer(mass_dev *dev, int direction, void *buffer, unsigne ret = perform_bulk_transfer(&cb_data); if (ret == USB_RC_OK) { - WaitSema(cb_data.sema); + SleepThread(); ret = cb_data.returnCode; } + cb_data.thid = -1; if (ret != USB_RC_OK) { M_DEBUG("ERROR: bulk data transfer %d. Clearing HALT state.\n", ret); @@ -436,7 +444,7 @@ static void scsi_cmd_callback(int resultCode, int bytes, void *arg) if ((resultCode != USB_RC_OK) || (ucmd->cmd_count == 0)) { // TODO: handle error in an async way (cannot block in usb callback) ucmd->returnCode = resultCode; - SignalSema(dev->ioSema); + WakeupThread(ucmd->thid); } } #endif @@ -490,19 +498,24 @@ int usb_queue_cmd(struct scsi_interface *scsi, const unsigned char *cmd, unsigne return result; #else + ucmd.thid = GetThreadId(); // Send the CBW (command) ucmd.cmd_count++; result = sceUsbdBulkTransfer(dev->bulkEpO, &ucmd.cbw, 31, scsi_cmd_callback, (void *)&ucmd); - if (result != USB_RC_OK) + if (result != USB_RC_OK) { + ucmd.thid = -1; return -EIO; + } // Send/Receive data while (data_len > 0) { unsigned int tr_len = (data_len < USB_BLOCK_SIZE) ? data_len : USB_BLOCK_SIZE; ucmd.cmd_count++; result = sceUsbdBulkTransfer(data_wr ? dev->bulkEpO : dev->bulkEpI, data, tr_len, scsi_cmd_callback, (void *)&ucmd); - if (result != USB_RC_OK) + if (result != USB_RC_OK) { + ucmd.thid = -1; return -EIO; + } data_len -= tr_len; data += tr_len; } @@ -510,11 +523,14 @@ int usb_queue_cmd(struct scsi_interface *scsi, const unsigned char *cmd, unsigne // Receive CSW (status) ucmd.cmd_count++; result = sceUsbdBulkTransfer(dev->bulkEpI, &ucmd.csw, 13, scsi_cmd_callback, (void *)&ucmd); - if (result != USB_RC_OK) + if (result != USB_RC_OK) { + ucmd.thid = -1; return -EIO; + } // Wait for SCSI command to finish - WaitSema(dev->ioSema); + SleepThread(); + ucmd.thid = -1; if (ucmd.returnCode != USB_RC_OK) return -EIO; @@ -621,7 +637,6 @@ static int usb_mass_connect(int devId) UsbConfigDescriptor *config; UsbInterfaceDescriptor *interface; UsbEndpointDescriptor *endpoint; - iop_sema_t SemaData; mass_dev *dev; M_PRINTF("connect: devId=%i\n", devId); @@ -671,15 +686,6 @@ static int usb_mass_connect(int devId) return -1; } - SemaData.initial = 0; - SemaData.max = 1; - SemaData.option = 0; - SemaData.attr = 0; - if ((dev->ioSema = CreateSema(&SemaData)) < 0) { - M_PRINTF("ERROR: Failed to allocate I/O semaphore\n"); - return -1; - } - /*store current configuration id - can't call set_configuration here */ dev->configId = config->bConfigurationValue; dev->status = USBMASS_DEV_STAT_CONN; @@ -723,8 +729,6 @@ static int usb_mass_disconnect(int devId) usb_mass_release(dev); dev->devId = -1; - DeleteSema(dev->ioSema); - // Should this move to the thread // just like the scsi_connect? scsi_disconnect(&dev->scsi);