From c9d84161282a51f5c8120c9ac51947ac06134bba Mon Sep 17 00:00:00 2001 From: dborth Date: Wed, 28 Apr 2010 06:00:30 +0000 Subject: [PATCH] improved USB code --- source/utils/usb2storage.c | 322 +++++++++++++++---------------------- source/utils/usb2storage.h | 15 +- 2 files changed, 139 insertions(+), 198 deletions(-) diff --git a/source/utils/usb2storage.c b/source/utils/usb2storage.c index 6a8da8c..be5936a 100644 --- a/source/utils/usb2storage.c +++ b/source/utils/usb2storage.c @@ -1,36 +1,31 @@ -/*------------------------------------------------------------- - -usb2storage.c -- USB mass storage support, inside starlet -Copyright (C) 2008 Kwiirk -Improved for homebrew by rodries - -If this driver is linked before libogc, this will replace the original -usbstorage driver by svpe from libogc - -CIOS_usb2 must be loaded! - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you -must not claim that you wrote the original software. If you use -this software in a product, an acknowledgment in the product -documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - - -------------------------------------------------------------*/ - -#ifdef HW_RVL +/**************************************************************************** + * WiiMC + * usb2storage.c -- USB mass storage support, inside starlet + * Copyright (C) 2008 Kwiirk + * Improved for homebrew by rodries and Tantric + * + * IOS 202 and the ehcmodule must be loaded before using this! + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + ***************************************************************************/ #include @@ -43,7 +38,6 @@ distribution. #include #include #include -#include //#define DEBUG_USB2 @@ -72,12 +66,10 @@ distribution. #define UMS_MAXPATH 16 static s32 hId = -1; -static s32 fd = -1; +static s32 __usb2fd = -1; static u32 sector_size; -static s32 usb2 = -1; static mutex_t usb2_mutex = LWP_MUTEX_NULL; static u8 *fixed_buffer = NULL; -static s32 usb2_inited = 0; #define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f) #define USB2_BUFFER 128*1024 @@ -94,13 +86,10 @@ static s32 USB2CreateHeap() u32 level; void *usb2_heap_ptr; - _CPU_ISR_Disable(level); - if (__usb2_heap_created != 0) - { - _CPU_ISR_Restore(level); return IPC_OK; - } + + _CPU_ISR_Disable(level); usb2_heap_ptr = (void *) ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (USB2_BUFFER+(4*1024)))); if ((u32) usb2_heap_ptr < (u32) SYS_GetArena2Lo()) @@ -115,39 +104,53 @@ static s32 USB2CreateHeap() return IPC_OK; } -static s32 USB2Storage_Initialize(int verbose) +static s32 USB2Storage_Initialize() { - s32 ret = USB_OK; - u32 size = 0; - char *devicepath = NULL; - - //if(usb2_inited) return ret; + static bool inited = false; + + if(inited) + return 0; if (usb2_mutex == LWP_MUTEX_NULL) LWP_MutexInit(&usb2_mutex, false); - LWP_MutexLock(usb2_mutex); - if (hId == -1) hId = iosCreateHeap(UMS_HEAPSIZE); if (hId < 0) { - LWP_MutexUnlock(usb2_mutex); - debug_printf("error IPC_ENOMEM\n",fd); + debug_printf("error IPC_ENOMEM\n"); return IPC_ENOMEM; } if (USB2CreateHeap() != IPC_OK) { - debug_printf("error USB2 IPC_ENOMEM\n",fd); + debug_printf("error USB2 IPC_ENOMEM\n"); return IPC_ENOMEM; } if (fixed_buffer == NULL) fixed_buffer = __lwp_heap_allocate(&usb2_heap, USB2_BUFFER); - if (fd < 0) + inited = true; + return 0; +} + +static s32 USB2Storage_Open(int verbose) +{ + char *devicepath = NULL; + s32 ret = USB_OK; + u32 size = 0; + + if(__usb2fd > 0) + return 0; + + if(USB2Storage_Initialize() < 0) + return -1; + + LWP_MutexLock(usb2_mutex); + + if (__usb2fd <= 0) { devicepath = iosAlloc(hId, UMS_MAXPATH); if (devicepath == NULL) @@ -157,46 +160,42 @@ static s32 USB2Storage_Initialize(int verbose) } snprintf(devicepath, USB_MAXPATH, "/dev/usb2"); - fd = IOS_Open(devicepath, 0); + __usb2fd = IOS_Open(devicepath, 0); iosFree(hId, devicepath); } - ret = fd; - debug_printf("usb2 fd: %d\n",fd); - usleep(500); + if(__usb2fd <= 0) + return -1; - if (fd > 0) - { - if (verbose) - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_SET_VERBOSE, ":"); - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_INIT, ":"); - debug_printf("usb2 init value: %i\n", ret); + if (verbose) + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_SET_VERBOSE, ":"); + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_INIT, ":"); + debug_printf("usb2 init value: %i\n", ret); - if (ret < 0) - debug_printf("usb2 error init\n"); - else - size = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", - §or_size); - debug_printf("usb2 GET_CAPACITY: %d\n", size); - - if (size == 0) - ret = -2012; - else - ret = 1; - } + if (ret < 0) + debug_printf("usb2 error init\n"); else - { - ret = -1; - } + size = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", + §or_size); + debug_printf("usb2 GET_CAPACITY: %d\n", size); - LWP_MutexUnlock(usb2_mutex); - - if(ret >= 0) - usb2_inited = 1; + if (size == 0) + ret = -2012; + else + ret = 1; return ret; } +static void USB2Storage_Close() +{ + if(__usb2fd <= 0) + return; + + IOS_Close(__usb2fd); + __usb2fd = -1; +} + static inline int is_MEM2_buffer(const void *buffer) { u32 high_addr = ((u32) buffer) >> 24; @@ -213,128 +212,61 @@ void USB2Enable(bool enable) if(!enable) { - __io_usbstorage = __io_usb1storage; + memcpy(&__io_usbstorage, &__io_usb1storage, sizeof(DISC_INTERFACE)); } else { - //USB2Storage_Initialize(0); - __io_usbstorage = __io_usb2storage; + USB2Storage_Initialize(); + memcpy(&__io_usbstorage, &__io_usb2storage, sizeof(DISC_INTERFACE)); } } -/* -static s32 USB2Storage_Get_Capacity(u32*_sector_size) -{ - if(fd>0) - { - LWP_MutexLock(usb2_mutex); - s32 ret = IOS_IoctlvFormat(hId,fd,USB_IOCTL_UMS_GET_CAPACITY,":i",§or_size); - if(_sector_size) - *_sector_size = sector_size; - LWP_MutexUnlock(usb2_mutex); - return ret; - } - else - return IPC_ENOENT; -} - -s32 GetInitValue() -{ - return usb2_init_value; -} - -s32 USB2Unmount() -{ - return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_UMOUNT, ":"); -} -s32 USB2Start() -{ - return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_START, ":"); -} -s32 USB2Stop() -{ - return IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_STOP, ":"); -} - -void USB2Close() -{ - if (fd > 0) - IOS_Close(fd); - fd = -1; -} - -int USB2ReadSector(u32 sector) -{ - void *b; - s32 ret; - b = malloc(1024); - ret = USBStorage_Read_Sectors(sector, 1, b); - free(b); - return ret; -} -*/ - static bool __usb2storage_Startup(void) { - bool ret; + if(__usb2fd > 0) + return true; - usb2 = USB2Storage_Initialize(0); - - if(usb2 >= 0) + USB2Storage_Open(0); + + if(__usb2fd > 0) { currentMode = 2; - ret = true; + return true; } - else if (usb2 < 0) + + if(__io_usb1storage.startup()) { - ret = __io_usb1storage.startup(); - - if(ret) - currentMode = 1; + currentMode = 1; + return true; } - return ret; + return false; } static bool __usb2storage_IsInserted(void) { - int retval; - bool ret = false; - - if (usb2 == -1) + if (!__usb2storage_Startup()) + return false; + + if(usb2_mutex == LWP_MUTEX_NULL) + return false; + + if (__usb2fd > 0) { - retval = __usb2storage_Startup(); - debug_printf("__usb2storage_Startup ret: %d fd: %i\n",retval,fd); - } - //else - LWP_MutexLock(usb2_mutex); - if (fd > 0) - { - - retval = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_IS_INSERTED, ":"); + LWP_MutexLock(usb2_mutex); + int retval = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_IS_INSERTED, ":"); + LWP_MutexUnlock(usb2_mutex); debug_printf("isinserted usb2 retval: %d ret: %d\n",retval,ret); if (retval > 0) - { - currentMode = 2; - ret = true; - debug_printf("isinserted(2) usb2 retval: %d ret: %d\n",retval,ret); - } - + return true; } - if(ret==false) - { - retval = __io_usb1storage.isInserted(); - if (retval > 0) - { - debug_printf("isinserted usb1 retval: %d\n",retval); - currentMode = 1; - ret = true; - } + if (__io_usb1storage.isInserted() > 0) + { + debug_printf("isinserted usb1 retval: %d\n",retval); + return true; } - debug_printf("final isinserted usb2 retval: %d ret: %d\n",retval,ret); - LWP_MutexUnlock(usb2_mutex); - return ret; + return false; } static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer) @@ -342,12 +274,12 @@ static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer) s32 ret = 1; u32 sectors = 0; uint8_t *dest = buffer; - + if (currentMode == 1) return __io_usb1storage.readSectors(sector, numSectors, buffer); - if (fd < 1) - return IPC_ENOENT; + if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL) + return false; LWP_MutexLock(usb2_mutex); @@ -360,12 +292,12 @@ static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer) if (!is_MEM2_buffer(dest)) //libfat is not providing us good buffers :-( { - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, sectors, fixed_buffer, sector_size * sectors); memcpy(dest, fixed_buffer, sector_size * sectors); } else - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, sectors, dest, sector_size * sectors); dest += sector_size * sectors; @@ -374,7 +306,7 @@ static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer) sector += sectors; numSectors -= sectors; } - if(ret<1)usb2 = -1; + if(ret<1) USB2Storage_Close(); LWP_MutexUnlock(usb2_mutex); if (ret < 1) return false; return true; @@ -385,12 +317,12 @@ static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *b s32 ret = 1; u32 sectors = 0; uint8_t *dest = (uint8_t *) buffer; - + if (currentMode == 1) return __io_usb1storage.writeSectors(sector, numSectors, buffer); - - if (fd < 1) - return IPC_ENOENT; + + if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL) + return false; LWP_MutexLock(usb2_mutex); while (numSectors > 0 && ret > 0) @@ -405,12 +337,12 @@ static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *b if (!is_MEM2_buffer(dest)) // libfat is not providing us good buffers :-( { memcpy(fixed_buffer, dest, sector_size * sectors); - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_WRITE_SECTORS, + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, sectors, fixed_buffer, sector_size * sectors); } else - ret = IOS_IoctlvFormat(hId, fd, USB_IOCTL_UMS_WRITE_SECTORS, + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, sectors, dest, sector_size * sectors); if (ret < 1)break; @@ -435,9 +367,12 @@ static bool __usb2storage_Shutdown(void) if (currentMode == 1) return __io_usb1storage.shutdown(); + if(usb2_mutex == LWP_MUTEX_NULL) + return false; + LWP_MutexLock(usb2_mutex); + USB2Storage_Close(); debug_printf("__usb2storage_Shutdown\n"); - usb2 = -1; LWP_MutexUnlock(usb2_mutex); return true; } @@ -452,4 +387,3 @@ const DISC_INTERFACE __io_usb2storage = { (FN_MEDIUM_CLEARSTATUS) & __usb2storage_ClearStatus, (FN_MEDIUM_SHUTDOWN) & __usb2storage_Shutdown }; -#endif diff --git a/source/utils/usb2storage.h b/source/utils/usb2storage.h index 7193a30..b6b9eb9 100644 --- a/source/utils/usb2storage.h +++ b/source/utils/usb2storage.h @@ -1,16 +1,23 @@ +/**************************************************************************** + * WiiMC + * usb2storage.h -- USB mass storage support, inside starlet + * Copyright (C) 2008 Kwiirk + * Improved for homebrew by rodries and Tantric + * + * IOS 202 and the ehcimodule must be loaded before using this! + ***************************************************************************/ #ifndef __USB2STORAGE_H__ #define __USB2STORAGE_H__ #ifdef __cplusplus -extern "C" { + extern "C" { #endif -void USB2Enable(bool enable); +void USB2Enable(bool e); #ifdef __cplusplus - } + } #endif - #endif