int NetManRpcNetIFSendPacket(const void *packet, unsigned int length){ struct PacketTag *PacketTag; WaitSema(NetManTxSemaID); NetmanTxWaitingThread=GetThreadId(); WaitSema(TxBankAccessSema); //Check is there is space in the current Tx FIFO. If not, wait for the Tx thread to empty out the other FIFO. */ while(CurrentTxFIFOData->PacketReqs.NumPackets>=NETMAN_RPC_BLOCK_SIZE){ SignalSema(TxBankAccessSema); WakeupThread(TxThreadID); SleepThread(); WaitSema(TxBankAccessSema); } memcpy(&CurrentTxFIFOData->FrameBuffer[CurrentTxFIFOData->PacketReqs.TotalLength], packet, length); PacketTag=&CurrentTxFIFOData->PacketReqs.tags[CurrentTxFIFOData->PacketReqs.NumPackets]; PacketTag->offset=CurrentTxFIFOData->PacketReqs.TotalLength; PacketTag->length=length; CurrentTxFIFOData->PacketReqs.TotalLength+=(length+3)&~3; CurrentTxFIFOData->PacketReqs.NumPackets++; WakeupThread(TxThreadID); SignalSema(TxBankAccessSema); NetmanTxWaitingThread=-1; SignalSema(NetManTxSemaID); return 0; }
Ps2File *findInCache(int64 id) { if (id <= 0) return NULL; WaitSema(cacheListSema); FioHandleCache *node = cacheListStart; while (node) { if (node->file->_cacheId == id) { if (node == cacheListStart) cacheListStart = node->next; if (node == cacheListEnd) cacheListEnd = node->prev; if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; Ps2File *ret = node->file; delete node; cacheListLen--; SignalSema(cacheListSema); return ret; } else node = node->next; } SignalSema(cacheListSema); return NULL; }
//-------------------------------------------------------------- int ntpbserverEndReply(void) { int rcvSize, sndSize, recv_size, sent_size, ntpbpktSize, packetSize; // Waiting io semaphore WaitSema(ntpbserver_io_sema); // Build up ntpb packet memcpy(&ntpb_buf[0], ntpb_hdrmagic, ntpb_MagicSize); //copying NTPB Magic *((u16 *)&ntpb_buf[ntpb_MagicSize]) = 0; *((u16 *)&ntpb_buf[ntpb_MagicSize+2]) = 0xffff; packetSize = ntpb_hdrSize; // Send ntpb packet to client sent_size = 0; // fragmented packet handling while (sent_size < packetSize) { sndSize = lwip_send(client_socket, &ntpb_buf[sent_size], packetSize - sent_size, 0); if (sndSize < 0) return -1; sent_size += sndSize; } // receive the response packet from client rcvSize = recv_noblock(client_socket, &ntpb_buf[0], sizeof(ntpb_buf)); if (rcvSize <= 0) return -1; ntpbpktSize = *((u16 *)&ntpb_buf[ntpb_MagicSize]); packetSize = ntpbpktSize + ntpb_hdrSize; recv_size = rcvSize; // fragmented packet handling while (recv_size < packetSize) { rcvSize = recv_noblock(client_socket, &ntpb_buf[recv_size], sizeof(ntpb_buf) - recv_size); if (rcvSize <= 0) return -1; recv_size += rcvSize; } // parses packet if (!check_ntpb_header(ntpb_buf)) return -2; // check client reply if (*((u16 *)&ntpb_buf[ntpb_hdrSize]) != 1) return -2; // Posting semaphore for server Thread so it's able to wait for requests again SignalSema(ntpbserver_cmd_sema); // posting io semaphore SignalSema(ntpbserver_io_sema); return 0; }
s32 sceCdSearchFile(sceCdlFILE * file, const char *name) { s32 i; sceCdSemaInit(); if (PollSema(nCmdSemaId) != nCmdSemaId) return 0; nCmdNum = CD_SERVER_SEARCHFILE; ReferThreadStatus(sceCdThreadId, &sceCdThreadParam); if (sceCdSync(1)) { SignalSema(nCmdSemaId); return 0; } SifInitRpc(0); if (bindSearchFile < 0) { while (1) { if (SifBindRpc(&clientSearchFile, CD_SERVER_SEARCHFILE, 0) < 0) { if (sceCdDebug > 0) printf("libsceCdvd bind err sceCdSearchFile\n"); } if (clientSearchFile.server != 0) break; i = 0x10000; while (i--); } bindSearchFile = 0; } strncpy(searchFileSendBuff.name, name, 255); searchFileSendBuff.name[255] = '\0'; searchFileSendBuff.dest = &searchFileSendBuff; if (sceCdDebug > 0) printf("ee call cmd search %s\n", searchFileSendBuff.name); if (SifCallRpc(&clientSearchFile, 0, 0, &searchFileSendBuff, sizeof(SearchFilePkt), nCmdRecvBuff, 4, 0, 0) < 0) { SignalSema(nCmdSemaId); return 0; } memcpy(file, UNCACHED_SEG(&searchFileSendBuff), 32); if (sceCdDebug > 0) { printf("search name %s\n", file->name); printf("search size %d\n", file->size); printf("search loc lnn %d\n", file->lsn); printf("search loc date %02X %02X %02X %02X %02X %02X %02X %02X\n", file->date[0], file->date[1], file->date[2], file->date[3], file->date[4], file->date[5], file->date[6], file->date[7]); printf("search loc date %02d %02d %02d %02d %02d %02d %02d %02d\n", file->date[0], file->date[1], file->date[2], file->date[3], file->date[4], file->date[5], file->date[6], file->date[7]); } SignalSema(nCmdSemaId); // return 1; return *(s32*)UNCACHED_SEG(nCmdRecvBuff); }
// Unofficial helper for renaming APA partitions. static int apaRename(s32 device, const apa_params_t *oldParams, const apa_params_t *newParams) { apa_cache_t *clink; int i, rv; // look to see if can make(newname) or not... if((clink = apaFindPartition(device, newParams->id, &rv)) != NULL) { apaCacheFree(clink); SignalSema(fioSema); return -EEXIST; // File exists } // look to see if open(oldname) for(i=0;i<apaMaxOpen;i++) { if(hddFileSlots[i].f!=NULL) { if(memcmp(hddFileSlots[i].id, oldParams->id, APA_IDMAX)==0) { SignalSema(fioSema); return -EBUSY; } } } // Do not allow system partitions (__*) to be renamed. if(oldParams->id[0]=='_' && oldParams->id[1]=='_') return -EACCES; // find :) if((clink = apaFindPartition(device, oldParams->id, &rv)) == NULL) { SignalSema(fioSema); return rv; } // Check for access rights. if(apaPassCmp(clink->header->fpwd, oldParams->fpwd) != 0) { apaCacheFree(clink); return -EACCES; } // do the renaming :) note: subs have no names!! memcpy(clink->header->id, newParams->id, APA_IDMAX); // Update passwords memcpy(clink->header->rpwd, newParams->rpwd, APA_PASSMAX); memcpy(clink->header->fpwd, newParams->fpwd, APA_PASSMAX); clink->flags|=APA_CACHE_FLAG_DIRTY; apaCacheFlushAllDirty(device); apaCacheFree(clink); return 0; }
int hddReName(iop_file_t *f, const char *oldname, const char *newname) { int rv; int i; apa_cache *clink; char tmpBuf[APA_IDMAX]; if(f->unit >= 2 || hddDeviceBuf[f->unit].status!=0) return -ENODEV;// No such device WaitSema(fioSema); // look to see if can make(newname) or not... memset(tmpBuf, 0, APA_IDMAX); strncpy(tmpBuf, newname, APA_IDMAX - 1); tmpBuf[APA_IDMAX - 1] = '\0'; if((clink=apaFindPartition(f->unit, tmpBuf, &rv))){ cacheAdd(clink); SignalSema(fioSema); return -EEXIST; // File exists } // look to see if open(oldname) memset(tmpBuf, 0, APA_IDMAX); strncpy(tmpBuf, oldname, APA_IDMAX - 1); tmpBuf[APA_IDMAX - 1] = '\0'; for(i=0;i<maxOpen;i++) { if(fileSlots[i].f!=0) if(fileSlots[i].f->unit==f->unit) if(memcmp(fileSlots[i].id, oldname, APA_IDMAX)==0) { SignalSema(fioSema); return -EBUSY; } } // find :) if(!(clink=apaFindPartition(f->unit, tmpBuf, &rv))) { SignalSema(fioSema); return -ENOENT; } // do the renameing :) note: subs have no names!! memset(clink->header->id, 0, APA_IDMAX); // all cmp are done with memcmp! strncpy(clink->header->id, newname, APA_IDMAX - 1); clink->header->id[APA_IDMAX - 1] = '\0'; clink->flags|=CACHE_FLAG_DIRTY; cacheFlushAllDirty(f->unit); cacheAdd(clink); SignalSema(fioSema); return 0; }
void OSystem_PS2::unlockMutex(MutexRef mutex) { WaitSema(_mutexSema); Ps2Mutex *sysMutex = (Ps2Mutex*)mutex; int tid = GetThreadId(); if (sysMutex->owner && sysMutex->count && (sysMutex->owner == tid)) sysMutex->count--; else { assert(sysMutex->count == 0); SignalSema(sysMutex->sema); sysMutex->owner = 0; } SignalSema(_mutexSema); }
static void ioWorkerThread(void) { while (!gIOTerminate) { SleepThread(); // no processing when io is blocked if (isIOBlocked) continue; // if term requested exit immediately from the loop if (gIOTerminate) break; // do we have a request in the queue? while (gReqList) { WaitSema(gProcSemaId); struct io_request_t* req = gReqList; ioProcessRequest(req); // lock the queue tip as well now WaitSema(gEndSemaId); // can't be sure if the request was gReqList = req->next; free(req); if (!gReqList) gReqEnd = NULL; SignalSema(gProcSemaId); SignalSema(gEndSemaId); } } // delete the pending requests while (gReqList) { struct io_request_t* req = gReqList; gReqList = gReqList->next; free(req); // TODO: Leak over here - we need a propper flag to free/not the user data } // delete the semaphores DeleteSema(gProcSemaId); DeleteSema(gEndSemaId); isIORunning = 0; ExitDeleteThread(); }
static void TxThread(void *arg){ struct TxFIFOData *TxFIFODataToTransmit; SifDmaTransfer_t dmat; int dmat_id, ThreadToWakeUp; while(1){ SleepThread(); WaitSema(TxBankAccessSema); if(CurrentTxFIFOData->PacketReqs.NumPackets>0){ // Switch banks TxFIFODataToTransmit=CurrentTxFIFOData; if(TxActiveBankID==0){ CurrentTxFIFOData=&TxFIFOData2; TxActiveBankID=1; } else{ CurrentTxFIFOData=&TxFIFOData1; TxActiveBankID=0; } SignalSema(TxBankAccessSema); SifWriteBackDCache(&TxFIFODataToTransmit->PacketReqs, sizeof(TxFIFODataToTransmit->PacketReqs)); dmat.src=&TxFIFODataToTransmit->PacketReqs; dmat.dest=TxFrameTagBuffer; dmat.size=8+sizeof(struct PacketTag)*TxFIFODataToTransmit->PacketReqs.NumPackets; dmat.attr=0; while((dmat_id=SifSetDma(&dmat, 1))==0){}; WaitSema(NetManIOSemaID); SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_SEND_PACKETS, 0, TxFIFODataToTransmit->FrameBuffer, TxFIFODataToTransmit->PacketReqs.TotalLength, NULL, 0, NULL, NULL); SignalSema(NetManIOSemaID); TxFIFODataToTransmit->PacketReqs.NumPackets=0; TxFIFODataToTransmit->PacketReqs.TotalLength=0; } else SignalSema(TxBankAccessSema); if(NetmanTxWaitingThread>=0){ ThreadToWakeUp=NetmanTxWaitingThread; NetmanTxWaitingThread=-1; //To prevent a race condition from occurring, invalidate NetmanTxWaitingThread before invoking WakeupThread. WakeupThread(ThreadToWakeUp); } } }
static void ioWorkerThread(void *arg) { while (!gIOTerminate) { SleepThread(); // if term requested exit immediately from the loop if (gIOTerminate) break; // do we have a request in the queue? WaitSema(gProcSemaId); while (gReqList) { // if term requested exit immediately from the loop if (gIOTerminate) break; struct io_request_t* req = gReqList; ioProcessRequest(req); // lock the queue tip as well now WaitSema(gEndSemaId); // can't be sure if the request was gReqList = req->next; free(req); if (!gReqList) gReqEnd = NULL; SignalSema(gEndSemaId); } SignalSema(gProcSemaId); } // delete the pending requests while (gReqList) { struct io_request_t* req = gReqList; gReqList = gReqList->next; free(req); } // delete the semaphores DeleteSema(gProcSemaId); DeleteSema(gEndSemaId); isIORunning = 0; ExitDeleteThread(); }
int NetManRegisterNetIF(struct NetManNetIF *NetIF){ unsigned int i; int result; iop_event_t EventFlag; WaitSema(NetManIOSemaID); for(i=0, result=-ENOMEM; i<NETMAN_MAX_NETIF_COUNT; i++){ if(!(NetIFs[i].flags&NETMAN_NETIF_IN_USE)){ if(NetIF->init()==0){ EventFlag.attr = 0; EventFlag.option = 0; EventFlag.bits = 0; if((result = NetIF->EventFlagID = CreateEventFlag(&EventFlag)) >= 0){ memcpy(&NetIFs[i], NetIF, sizeof(NetIFs[i])); NetIFs[i].flags|=NETMAN_NETIF_IN_USE; result=NetIFs[i].id=((unsigned int)NextNetIFID)<<8|i; UpdateNetIFStatus(); NextNetIFID++; } } else result=-EIO; break; } } SignalSema(NetManIOSemaID); return result; }
/** call back for most lowlevel usb funtions */ void PS2CamCallback(int resultCode, int bytes, void *arg) { if(resultCode !=0) printf("callback: result= %d, bytes= %d, arg= %p \n", resultCode, bytes, arg); SignalSema(ps2cam_sema); }
void sys_sem_signal(sys_sem_t Sema) { dbgprintf("sys_sem_signal: Sema: %d (TID: %d)\n",Sema,GetThreadId()); SignalSema(Sema); }
int ps2_fclose(FILE *stream) { Ps2File *file = (Ps2File*)stream; if (file->_cacheId > 0) { // this is a file on the CD, could be smart to cache it FioHandleCache *newHandle = new FioHandleCache; newHandle->file = file; file->seek(0, SEEK_SET); WaitSema(cacheListSema); if (!cacheListEnd) { assert(!cacheListStart); newHandle->prev = newHandle->next = NULL; cacheListEnd = cacheListStart = newHandle; } else { assert(cacheListStart); newHandle->prev = NULL; newHandle->next = cacheListStart; cacheListStart->prev = newHandle; cacheListStart = newHandle; } cacheListLen++; checkCacheListLen(); SignalSema(cacheListSema); } else { openFileCount--; delete file; } return 0; }
int Ps2ReadFile::seek(int32 offset, int origin) { WaitSema(_sema); int seekDest; int res = -1; switch (origin) { case SEEK_SET: seekDest = offset; break; case SEEK_CUR: seekDest = _filePos + offset; break; case SEEK_END: seekDest = _fileSize + offset; break; default: seekDest = -1; break; } if ((seekDest >= 0) && (seekDest <= (int)_fileSize)) { _filePos = seekDest; res = 0; } SignalSema(_sema); return res; }
int audsrv_play_audio(const char *chunk, int bytes) { int copy, maxcopy, copied; int packet_size; int sent = 0; set_error(AUDSRV_ERR_NOERROR); maxcopy = sizeof(sbuff) - sizeof(int); while (bytes > 0) { WaitSema(completion_sema); copy = MIN(bytes, maxcopy); sbuff[0] = copy; memcpy(&sbuff[1], chunk, copy); packet_size = copy + sizeof(int); SifCallRpc(&cd0, AUDSRV_PLAY_AUDIO, 0, sbuff, packet_size, sbuff, 1*4, NULL, NULL); copied = sbuff[0]; SignalSema(completion_sema); if (copied < 0) { /* there was an error */ set_error(-copied); break; } chunk = chunk + copy; bytes = bytes - copy; sent = sent + copied; } return sent; }
int NetManRpcIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length){ int result; /* void *AlignedOutput; int AlignedSize; */ WaitSema(NetManIOSemaID); ((struct NetManIoctl*)UNCACHED_SEG(TransmitBuffer))->command=command; memcpy(((struct NetManIoctl*)UNCACHED_SEG(TransmitBuffer))->args, args, args_len); ((struct NetManIoctl*)UNCACHED_SEG(TransmitBuffer))->args_len=args_len; ((struct NetManIoctl*)UNCACHED_SEG(TransmitBuffer))->output=output; ((struct NetManIoctl*)UNCACHED_SEG(TransmitBuffer))->length=length; /* !!! This entire system is not working. And I don't know why. AlignedOutput=(void*)(((unsigned int)output+0x3F)&~0x3F); AlignedSize=length-((unsigned int)AlignedOutput-(unsigned int)output); AlignedSize-=(AlignedSize&0x3F); if(AlignedSize>0){ SifWriteBackDCache(AlignedOutput, AlignedSize); } */ if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_IOCTL, SIF_RPC_M_NOWBDC, TransmitBuffer, sizeof(struct NetManIoctl), ReceiveBuffer, sizeof(struct NetManIoctlResult), NULL, NULL))>=0){ result=((struct NetManIoctlResult*)UNCACHED_SEG(ReceiveBuffer))->result; memcpy(output, ((struct NetManIoctlResult*)UNCACHED_SEG(ReceiveBuffer))->output, length); } SignalSema(NetManIOSemaID); return result; }
static void ethInitSMB(void) { int ret; WaitSema(ethInitSemaID); ret = ethInitApplyConfig(); SignalSema(ethInitSemaID); if(ret != 0) { ethDisplayErrorStatus(); return; } // connect ethSMBConnect(); if (gNetworkStartup == 0) { // update Themes char path[256]; sprintf(path, "%sTHM", ethPrefix); thmAddElements(path, "\\", ethGameList.mode); sbCreateFolders(ethPrefix, 1); } else if (gPCShareName[0] || !(gNetworkStartup >= ERROR_ETH_SMB_OPENSHARE)) { ethDisplayErrorStatus(); } }
int PS2CamReadPacket(int handle) { int *ret; int *iop_addr; WaitSema(sem); ret = (int *)&data[0]; ret[0] = handle; SifCallRpc(&cdata, PS2CAM_RPC_READPACKET, 0, (void*)(&data[0]),4,(void*)(&data[0]),4*2,0,0); if(ret[0] < 0) return ret[0]; DI(); ee_kmode_enter(); iop_addr = (int *)(0xbc000000+ret[1]); memcpy(&campacket[0],iop_addr, ret[0]); ee_kmode_exit(); EI(); //if i add a printf here, the ps2 will exit to sony's explorer SignalSema(sem); return ret[0]; }
int hddOpen(iop_file_t *f, const char *name, int flags, int mode) { int rv; apa_params_t params; hdd_file_slot_t *fileSlot; if(f->unit >= 2 || hddDevices[f->unit].status!=0) return -ENODEV; if(!(f->mode & O_DIROPEN)) if((rv=fioGetInput(name, ¶ms)) < 0) return rv; WaitSema(fioSema); if((rv=getFileSlot(¶ms, &fileSlot))==0) { if(!(f->mode & O_DIROPEN)) { if((rv=apaOpen(f->unit, fileSlot, ¶ms, flags))==0){ fileSlot->f=f; f->privdata=fileSlot; } } else { fileSlot->f=f; f->privdata=fileSlot; } } SignalSema(fioSema); return rv; }
int hddClose(iop_file_t *f) { WaitSema(fioSema); memset(f->privdata, 0, sizeof(hdd_file_slot_t)); SignalSema(fioSema); return 0; }
static int fioDataTransfer(iop_file_t *f, void *buf, int size, int mode) { hdd_file_slot_t *fileSlot=(hdd_file_slot_t *)f->privdata; if((size & 0x1FF)) return -EINVAL; size>>=9; // size/512 if(fileSlot->post+size>=0x1FF9)// no over reading size=0x1FF8-fileSlot->post; if(size!=0) { int rv=0; WaitSema(fioSema); if(ata_device_sector_io(f->unit, buf, fileSlot->post+fileSlot->parts[0].start+8, size, mode)) rv=-EIO; SignalSema(fioSema); if(rv==0) { fileSlot->post+=size; return size<<9; } return rv; } return 0; }
static err_t SMapLowLevelOutput ( NetIF* pNetIF, PBuf* pOutput ) { while ( 1 ) { int iFlags; SMapStatus Res; if ( ( Res = AddToQueue ( pOutput ) ) == SMap_OK ) return ERR_OK; if ( Res == SMap_Err ) return ERR_IF; if ( Res == SMap_Con ) return ERR_CONN; WaitSema ( iSendMutex ); CpuSuspendIntr ( &iFlags ); if ( iReqCNT == MAX_REQ_CNT ) { iSendReq = iSendReqMutex; CpuResumeIntr ( iFlags ); WaitSema ( iSendReqMutex ); } else CpuResumeIntr ( iFlags ); SignalSema ( iSendMutex ); } /* end while */ } /* end SMapLowLevelOutput */
int ioPutRequest(int type, void* data) { if (isIOBlocked) return IO_ERR_IO_BLOCKED; // check the type before queueing if (!ioGetHandler(type)) return IO_ERR_INVALID_HANDLER; WaitSema(gEndSemaId); // We don't have to lock the tip of the queue... // If it exists, it won't be touched, if it does not exist, it is not being processed struct io_request_t* req = gReqEnd; if (!req) { gReqList = (struct io_request_t*)malloc(sizeof(struct io_request_t)); req = gReqList; gReqEnd = gReqList; } else { req->next = (struct io_request_t*)malloc(sizeof(struct io_request_t)); req = req->next; gReqEnd = req; } req->next = NULL; req->type = type; req->data = data; SignalSema(gEndSemaId); WakeupThread(gIOThreadId); return IO_OK; }
static void TxThread(void *arg) { int ThreadToWakeUp; while(1) { SleepThread(); if(PacketReqs.count > 0) { while(PacketReqs.count > 0) { WaitSema(NetManIOSemaID); while(SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_SEND_PACKETS, 0, &PacketReqs, sizeof(PacketReqs), &ReceiveBuffer, sizeof(ReceiveBuffer.result), &TxEndCallback, NULL) < 0){}; SignalSema(NetManIOSemaID); } } else { if(NetmanTxWaitingThread >= 0) { DI(); ThreadToWakeUp=NetmanTxWaitingThread; NetmanTxWaitingThread=-1; EI(); WakeupThread(ThreadToWakeUp); } } } }
int McAccess::getDir(const char *name, unsigned int mode, int max, void *dest) { int res; WaitSema(_sema); mcGetDir(_port, _slot, name, mode, max, (mcTable*)dest); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
void poweroffShutdown(void) { poweroffInit(); SignalSema(PowerOffSema); SifCallRpc(&cd0, PWROFF_SHUTDOWN, 0, NULL, 0, NULL, 0, NULL, NULL); }
int McAccess::getInfo(int *type, int *free, int *format) { int res; WaitSema(_sema); mcGetInfo(_port, _slot, type, free, format); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::open(const char *name, int mode) { int res; WaitSema(_sema); mcOpen(_port, _slot, name, mode); mcSync(0, NULL, &res); SignalSema(_sema); return res; }
int McAccess::close(int fd) { int res; WaitSema(_sema); mcClose(fd); mcSync(0, NULL, &res); SignalSema(_sema); return res; }