/********************************************************************* * Copyright (C) 2003 Tord Lindstrom (pukko@home.se) * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com) * This file is subject to the terms and conditions of the PS2Link License. * See the file LICENSE in the main directory of this distribution for more * details. */ #include #include #include #include #include #include #include #include #include "net_fio.h" #define IOCTL_RENAME 0xFEEDC0DE //dlanor: Used for the Ioctl request code => Rename #ifdef DEBUG #define dbgprintf(args...) printf(args) #else #define dbgprintf(args...) do { } while(0) #endif static char fsname[] = "host"; //---------------------------------------------------------------------------- /* File desc struct is probably larger than this, but we only * need to access the word @ offset 0x0C (in which we put our identifier) */ struct filedesc_info { int unkn0; int unkn4; int device_id; // the X in hostX int own_fd; }; //dlanor: In fact this struct is declared elsewhere as iop_file_t, with //dlanor: well known fields. The one declared as "int own_fd;" above is //dlanor: there declared as "void *privdata;" but it doesn't matter, as //dlanor: it is up to each driver how to use that field. So using it as //dlanor: a simple "int" instead of a pointer will work fine. //---------------------------------------------------------------------------- /* We need(?) to protect the net access, so the server doesn't get * confused if two processes calls a fsys func at the same time */ static int fsys_sema; static int fsys_pid = 0; //---------------------------------------------------------------------------- //dlanor: We need variables to remember a file/folder descriptor used //dlanor: with the Ioctl Rename function, so that we can avoid passing //dlanor: the following fioClose call to PC, where it's already closed. //dlanor: We also need a flag to note when we must ignore an Mkdir call //dlanor: because it is caused by the bug IOMAN.IRX has for fioRemove. // int lastopen_fd; //descriptor of the most recently opened file/folder int renamed_fd; //descriptor of renamed file/folder awaiting closure int remove_flag=0; //Set in fsysRemove, cleared by all other fsysXXXXX int remove_result; //Set in fsysRemove, so fsysMkdir can use it for bug typedef void (*th_func_p)(void *); //dlanor: added to suppress warnings //---------------------------------------------------------------------------- static void fsysInit(iop_device_t *driver) { struct _iop_thread mythread; int pid; int i; dbgprintf("initializing %s\n", driver->name); remove_flag = 0; // Start socket server thread mythread.attr = 0x02000000; // attr mythread.option = 0; // option mythread.thread = (th_func_p) pko_file_serv; // entry mythread.stacksize = 0x800; mythread.priority = 0x45; // We really should choose prio w more effort pid = CreateThread(&mythread); if (pid > 0) { if ((i=StartThread(pid, NULL)) < 0) { printf("StartThread failed (%d)\n", i); } } else { printf("CreateThread failed (%d)\n", pid); } fsys_pid = pid; dbgprintf("Thread id: %x\n", pid); } //---------------------------------------------------------------------------- static int fsysDestroy(void) { remove_flag = 0; WaitSema(fsys_sema); pko_close_fsys(); // ExitDeleteThread(fsys_pid); SignalSema(fsys_sema); DeleteSema(fsys_sema); return 0; } //---------------------------------------------------------------------------- static int dummyFormat() { remove_flag = 0; printf("dummy Format function called\n"); return -5; } //---------------------------------------------------------------------------- static int fsysOpen( int fd, char *name, int mode) { struct filedesc_info *fd_info; int fsys_fd; dbgprintf("fsysOpen..\n"); dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode); remove_flag = 0; fd_info = (struct filedesc_info *)fd; WaitSema(fsys_sema); fsys_fd = pko_open_file(name, mode); SignalSema(fsys_sema); fd_info->own_fd = fsys_fd; renamed_fd = -1; lastopen_fd = fsys_fd; return fsys_fd; } //---------------------------------------------------------------------------- static int fsysClose( int fd) { int remote_fd = ((struct filedesc_info *)fd)->own_fd; int ret; dbgprintf("fsys_close..\n" " fd: %x\n\n", fd); remove_flag = 0; if (remote_fd != renamed_fd){ WaitSema(fsys_sema); ret = pko_close_file(remote_fd); SignalSema(fsys_sema); } else ret = 0; renamed_fd = -1; return ret; } //---------------------------------------------------------------------------- static int fsysRead( int fd, char *buf, int size) { struct filedesc_info *fd_info; int ret; fd_info = (struct filedesc_info *)fd; dbgprintf("fsysRead..." " fd: %x\n" " bf: %x\n" " sz: %d\n" " ow: %d\n\n", fd, (int)buf, size, fd_info->own_fd); remove_flag = 0; WaitSema(fsys_sema); ret = pko_read_file(fd_info->own_fd, buf, size); SignalSema(fsys_sema); return ret; } //---------------------------------------------------------------------------- static int fsysWrite( int fd, char *buf, int size) { struct filedesc_info *fd_info; int ret; dbgprintf("fsysWrite..." " fd: %x\n", fd); remove_flag = 0; fd_info = (struct filedesc_info *)fd; WaitSema(fsys_sema); ret = pko_write_file(fd_info->own_fd, buf, size); SignalSema(fsys_sema); return ret; } //---------------------------------------------------------------------------- static int fsysLseek( int fd, unsigned int offset, int whence) { struct filedesc_info *fd_info; int ret; dbgprintf("fsysLseek..\n" " fd: %x\n" " of: %x\n" " wh: %x\n\n", fd, offset, whence); remove_flag = 0; fd_info = (struct filedesc_info *)fd; WaitSema(fsys_sema); ret = pko_lseek_file(fd_info->own_fd, offset, whence); SignalSema(fsys_sema); return ret; } //---------------------------------------------------------------------------- static int fsysIoctl(iop_file_t* file, unsigned long request, void *data) { int remote_fd = ((struct filedesc_info *) file)->own_fd; int ret; dbgprintf("fsysioctl..\n"); dbgprintf(" fd: %x\n" " rq: %x\n" " dp: %x\n\n", ); remove_flag = 0; if (request == IOCTL_RENAME){ if (lastopen_fd == remote_fd){ WaitSema(fsys_sema); ret = pko_ioctl(remote_fd, request, data); SignalSema(fsys_sema); if ((ret == 0) || (ret == -6)) renamed_fd = remote_fd; } else { printf("Ioctl Rename function used incorrectly.\n"); ret = -5; } } else { printf("Ioctl function called with invalid request code\n"); ret = -5; } return ret; } //---------------------------------------------------------------------------- static int fsysRemove(iop_file_t* file, char *name) { int ret; dbgprintf("fsysRemove..\n"); dbgprintf(" name: %s\n\n", name); remove_flag = 1; WaitSema(fsys_sema); ret = pko_remove(name); SignalSema(fsys_sema); remove_result = ret; return ret; } //---------------------------------------------------------------------------- static int fsysMkdir(iop_file_t* file, char *name, int mode) { int ret; dbgprintf("fsysMkdir..\n"); dbgprintf(" name: '%s'\n\n", name); if (remove_flag == 0){ WaitSema(fsys_sema); ret = pko_mkdir(name, mode); SignalSema(fsys_sema); } else { remove_flag = 0; ret = remove_result; } return ret; } //---------------------------------------------------------------------------- static int fsysRmdir(iop_file_t* file, char *name) { int ret; dbgprintf("fsysRmdir..\n"); dbgprintf(" name: %s\n\n", name); remove_flag = 0; WaitSema(fsys_sema); ret = pko_rmdir(name); SignalSema(fsys_sema); return ret; } //---------------------------------------------------------------------------- static int fsysDopen(int fd, char *name) { struct filedesc_info *fd_info; int fsys_fd; dbgprintf("fsysDopen..\n"); dbgprintf(" fd: %x, name: %s\n\n", fd, name); fd_info = (struct filedesc_info *)fd; remove_flag = 0; WaitSema(fsys_sema); fsys_fd = pko_open_dir(name); SignalSema(fsys_sema); fd_info->own_fd = fsys_fd; renamed_fd = -1; lastopen_fd = fsys_fd; return fsys_fd; } //---------------------------------------------------------------------------- static int fsysDclose(int fd) { int remote_fd = ((struct filedesc_info *)fd)->own_fd; int ret; dbgprintf("fsys_dclose..\n" " fd: %x\n\n", fd); remove_flag = 0; if (remote_fd != renamed_fd){ WaitSema(fsys_sema); ret = pko_close_dir(remote_fd); SignalSema(fsys_sema); } else ret = 0; renamed_fd = -1; return ret; } //---------------------------------------------------------------------------- static int fsysDread(int fd, void *buf) { struct filedesc_info *fd_info; int ret; fd_info = (struct filedesc_info *)fd; dbgprintf("fsysDread..." " fd: %x\n" " bf: %x\n" " ow: %d\n\n", fd, (int)buf, fd_info->own_fd); remove_flag = 0; WaitSema(fsys_sema); ret = pko_read_dir(fd_info->own_fd, buf); SignalSema(fsys_sema); return ret; } //---------------------------------------------------------------------------- static int dummyGetstat() { remove_flag = 0; printf("dummy Getstat function called\n"); return -5; } //---------------------------------------------------------------------------- static int dummyChstat() { remove_flag = 0; printf("dummy Chstat function called\n"); return -5; } //---------------------------------------------------------------------------- iop_device_ops_t fsys_functarray = { (void *)fsysInit, (void *)fsysDestroy, (void *)dummyFormat, //init, deinit, format (void *)fsysOpen, (void *)fsysClose, (void *)fsysRead, //open, close, read, (void *)fsysWrite, (void *)fsysLseek, (void *)fsysIoctl, //write, lseek, ioctl (void *)fsysRemove, (void *)fsysMkdir, (void *)fsysRmdir, //remove, mkdir, rmdir (void *)fsysDopen, (void *)fsysDclose, (void *)fsysDread, //dopen, dclose, dread (void *)dummyGetstat, (void *)dummyChstat }; //getstat, chstat iop_device_t fsys_driver = { fsname, 16, 1, "fsys driver", &fsys_functarray }; //---------------------------------------------------------------------------- // Entry point for mounting the file system int fsysMount(void) { iop_sema_t sema_info; sema_info.attr = 1; sema_info.option = 0; sema_info.initial = 1; sema_info.max = 1; fsys_sema = CreateSema(&sema_info); DelDrv(fsname); AddDrv(&fsys_driver); return 0; } //---------------------------------------------------------------------------- int fsysUnmount(void) { DelDrv(fsname); return 0; } //---------------------------------------------------------------------------- //End of file: net_fsys.c //----------------------------------------------------------------------------