diff --git a/ehcmodule/Makefile b/ehcmodule/Makefile index 3618ccb9..2d894c15 100644 --- a/ehcmodule/Makefile +++ b/ehcmodule/Makefile @@ -98,13 +98,13 @@ LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) ARCH = -mcpu=arm9tdmi -mtune=arm9tdmi -mthumb -mthumb-interwork -mbig-endian -CFLAGS += -g $(ARCH) $(INCLUDE) -fno-strict-aliasing -Wall -Os -fomit-frame-pointer -ffast-math -fverbose-asm -Wpointer-arith -Winline -Wundef -g -ffunction-sections -fdata-sections -fno-exceptions +CFLAGS += $(ARCH) $(INCLUDE) -fno-strict-aliasing -Wall -Os -fomit-frame-pointer -ffast-math -fverbose-asm -Wpointer-arith -Winline -Wundef -g -ffunction-sections -fdata-sections -fno-exceptions CFLAGS += -Wstrict-prototypes -AFLAGS = -g $(ARCH) -x assembler-with-cpp +AFLAGS = $(ARCH) -x assembler-with-cpp -LDFLAGS = -g $(ARCH) -specs=$(SPECS) -T$(LINKSCRIPT) $(LIBPATHS) $(LIBS) -Wl,--gc-sections -Wl,-static -Wl,-Map,$(TARGET).map -nostartfiles +LDFLAGS = $(ARCH) -specs=$(SPECS) -T$(LINKSCRIPT) $(LIBPATHS) $(LIBS) -Wl,--gc-sections -Wl,-static -Wl,-Map,$(TARGET).map -nostartfiles $(OUTPUT).elf: $(TARGET).elf @@ -114,7 +114,7 @@ $(OUTPUT).elf: $(TARGET).elf %.elf: $(OFILES) @echo linking $(notdir $@) - @$(LD) -g -o $@ $(OFILES) $(LDFLAGS) $(STYLEFIX) + @$(LD) -o $@ $(OFILES) $(LDFLAGS) $(STYLEFIX) %_cpp.o : %.cpp diff --git a/ehcmodule/bin/convert.bat b/ehcmodule/bin/convert.bat index 62e3ef26..0e010c23 100644 --- a/ehcmodule/bin/convert.bat +++ b/ehcmodule/bin/convert.bat @@ -5,6 +5,8 @@ del C:\devkitPro\soft\usbloader\source\mload\modules\ehcmodule_5.c del C:\devkitPro\soft\usbloader\source\mload\modules\ehcmodule_5.h copy ehcmodule_5.c C:\devkitPro\soft\usbloader\source\mload\modules\ copy ehcmodule_5.h C:\devkitPro\soft\usbloader\source\mload\modules\ +touch C:\devkitPro\soft\usbloader\source\mload\modules\ehcmodule_5.c +touch C:\devkitPro\soft\usbloader\source\mload\modules\ehcmodule_5.h diff --git a/ehcmodule/source/crt0.s b/ehcmodule/source/crt0.s index 46b7fc79..ab523f42 100644 --- a/ehcmodule/source/crt0.s +++ b/ehcmodule/source/crt0.s @@ -170,8 +170,8 @@ write_access_perm: .string "EHC_CFG" .long 0x12340001 - .global use_usb_port1 -use_usb_port1: + .global initial_port +initial_port: .byte 0x0 .global use_reset_bulk diff --git a/ehcmodule/source/ehc_loop.c b/ehcmodule/source/ehc_loop.c index eb341661..e1a6aab4 100644 --- a/ehcmodule/source/ehc_loop.c +++ b/ehcmodule/source/ehc_loop.c @@ -113,8 +113,6 @@ int verbose = 0; wbfs_disc_t * wbfs_init_with_partition(u8*discid, int partition); -extern char use_usb_port1; - int USBStorage_DVD_Test(void); @@ -144,6 +142,8 @@ char *parse_hex(char *base,int *val) *val = v; return ptr-1; } + +/* int parse_and_open_device(char *devname,int fd) { char *ptr = devname; @@ -159,7 +159,7 @@ int parse_and_open_device(char *devname,int fd) return -6; return ehci_open_device(vid,pid,fd); } - +*/ int DVD_speed_limit=0; // ingame it can fix x6 speed @@ -345,7 +345,7 @@ extern int is_watchdog_read_sector; extern u32 n_sec,sec_size; -int last_sector=0; +u32 last_sector=0; void direct_os_sync_before_read(void* ptr, int size); @@ -439,11 +439,13 @@ int ehc_loop(void) { ipcmessage* message; int timer2_id=-1; + extern char initial_port; + int init_mode=initial_port; static bool first_read=true; char port; - extern int ums_init_done; - + extern int ums_init_done[2]; + extern u32 current_port; int must_read_sectors=0; @@ -464,7 +466,7 @@ int ehc_loop(void) timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x0); int ums_mode = 0; - int already_discovered = 0; +// int already_discovered = 0; wbfs_disc_t *d = 0; int usb_lock=0; @@ -515,16 +517,16 @@ int ehc_loop(void) if(unplug_device==0) { - if(sec_size!=0 && sec_size<4096) // only support sector size minor to 2048 + if(sec_size!=0 && sec_size<=4096) { - + extern int is_dvd[2]; is_watchdog_read_sector=1; r=USBStorage_Read_Sectors(last_sector, 1, mem_sector); is_watchdog_read_sector=0; - if(r!=0 && sec_size==512) + if(r!=0 && !is_dvd[current_port]) last_sector+=0x1000000/sec_size; // steps of 16MB if(last_sector>=n_sec) last_sector=0; } @@ -645,8 +647,8 @@ int ehc_loop(void) break; case USB_IOCTL_GETDEVLIST: debug_printf("get dev list\n"); - if(dev)result= -6; - else + //if(dev)result= -6; + //else result = ehci_get_device_list(ioctlv_u8(vec[0]),ioctlv_u8(vec[1]), ioctlv_voidp(vec[2]),ioctlv_voidp(vec[3])); break; @@ -658,12 +660,14 @@ int ehc_loop(void) case USB_IOCTL_UMS_INIT: must_read_sectors=0; - if(!already_discovered ) - ehci_discover(); - already_discovered=1; - - result = USBStorage_Init(); - + result = USBStorage_Init(init_mode); + if(result>=0 && result <3) + { + if(result==0 || result==2) + current_port = 0; + else + current_port = 1; + } //result=-os_thread_get_priority(); if(result>=0) {must_read_sectors=1;watchdog_enable=1;} @@ -673,7 +677,7 @@ int ehc_loop(void) case USB_IOCTL_UMS_UMOUNT: must_read_sectors=0; watchdog_enable=0; - // USBStorage_Umount(); + USBStorage_Umount(); result =0; break; case USB_IOCTL_UMS_TESTMODE: @@ -684,19 +688,14 @@ int ehc_loop(void) case USB_IOCTL_SET_PORT: result =0; port=ioctlv_u32(vec[0]); - if(use_usb_port1!=port) + init_mode=port; + //if(ums_init_done==0) init_mode=port; + //else { - if(ums_init_done) - { - USBStorage_Umount(); - ehci_close_devices(); - ehci_release_externals_usb_ports(); - use_usb_port1=port; - ehci_discover(); - result = USBStorage_Init(); - } - } - use_usb_port1=port; + if(port==0 || port==1) current_port=port; + result = current_port; + } + break; case USB_IOCTL_UMS_OFF: @@ -727,6 +726,12 @@ int ehc_loop(void) #ifdef VIGILANTE enable_button=1; #endif + if(watchdog_enable && timer2_id!=-1) + { + os_stop_timer(timer2_id); // stops the timeout timer + os_destroy_timer(timer2_id); + timer2_id=-1; + } result = USBStorage_Read_Sectors(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2])); if(first_read) { @@ -739,6 +744,7 @@ int ehc_loop(void) else s_printf("first read sector (%i) ERROR\n",ioctlv_u32(vec[0])); } + if(watchdog_enable && timer2_id==-1)timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x0); break; case USB_IOCTL_UMS_WRITE_SECTORS: @@ -806,7 +812,14 @@ int ehc_loop(void) case USB_IOCTL_WBFS_READ_DIRECT_DISC: // used to read USB DVD usb_lock=1; watchdog_enable=1; + if(watchdog_enable && timer2_id!=-1) + { + os_stop_timer(timer2_id); // stops the timeout timer + os_destroy_timer(timer2_id); + timer2_id=-1; + } result = WBFS_direct_disc_read(ioctlv_u32(vec[0]),ioctlv_voidp(vec[2]),ioctlv_u32(vec[1])); + if(watchdog_enable)timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x0); usb_lock=0; break; @@ -823,7 +836,14 @@ int ehc_loop(void) usb_lock=1; //os_stop_timer(timer2_id); - result = wbfs_disc_read(d,ioctlv_u32(vec[0]),ioctlv_voidp(vec[2]),ioctlv_u32(vec[1])); + if(watchdog_enable && timer2_id!=-1) + { + os_stop_timer(timer2_id); // stops the timeout timer + os_destroy_timer(timer2_id); + timer2_id=-1; + } + result = wbfs_disc_read(d,ioctlv_u32(vec[0]),ioctlv_voidp(vec[2]),ioctlv_u32(vec[1])); + if(watchdog_enable)timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x0); usb_lock=0; if(result){ //debug_printf("wbfs failed! %d\n",result); diff --git a/ehcmodule/source/main.c b/ehcmodule/source/main.c index 64bf9b0c..233cc579 100644 --- a/ehcmodule/source/main.c +++ b/ehcmodule/source/main.c @@ -256,13 +256,13 @@ int copy_int_vect(u32 ios, u32 none) return 0; } -extern char use_usb_port1; +extern char initial_port; extern u32 current_port; int main(void) { -current_port= ((u32) use_usb_port1)!=0; +current_port=initial_port; // changes IOS vector interrupt to crt0.s routine //swi_mload_led_on(); diff --git a/ehcmodule/source/wbfs_glue.c b/ehcmodule/source/wbfs_glue.c index 4fff5928..06b81e32 100644 --- a/ehcmodule/source/wbfs_glue.c +++ b/ehcmodule/source/wbfs_glue.c @@ -104,7 +104,8 @@ wbfs_disc_t * wbfs_init_with_partition(u8*discid, int partition) // opens the hd only is is not opened if(!p) { - USBStorage_Init(); + extern u32 current_port; + USBStorage_Init(current_port); n_sec = USBStorage_Get_Capacity(&sec_size); //debug_printf("hd found n_sec:%x sec_size %x\n",n_sec,sec_size); if (n_sec==0) diff --git a/test/data/ehcmodule.elf b/test/data/ehcmodule.elf index 24f58176..cb6aa68e 100644 Binary files a/test/data/ehcmodule.elf and b/test/data/ehcmodule.elf differ diff --git a/test/source/main.c b/test/source/main.c index aa0a91f9..d7546b89 100644 --- a/test/source/main.c +++ b/test/source/main.c @@ -1,441 +1,353 @@ -/************************************************************/ -/* USB speed test */ -/* */ -/* */ -/************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "mload.h" -#include "../build/ehcmodule_elf.h" -//#include "../build/fat_elf.h" -data_elf my_data_elf; -int my_thread_id = 0; - - -#include - -#include -#include -#include -#include "usb2storage.h" - - - -const DISC_INTERFACE* sd = &__io_wiisd; -const DISC_INTERFACE* usb = &__io_usbstorage; -//const DISC_INTERFACE* usb1 = &__io_usb1storage; - -static bool reset_pressed = false; -static bool power_pressed = false; - -static void *xfb = NULL; -static GXRModeObj *rmode = NULL; -static const u32 CACHE_PAGES = 8; - -static u8 memsector[4*1024]; - - -void initialise_video() -{ - VIDEO_Init(); - rmode = VIDEO_GetPreferredMode(NULL); - xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); - console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ); - VIDEO_Configure(rmode); - VIDEO_SetNextFramebuffer(xfb); - VIDEO_SetBlack(FALSE); - VIDEO_Flush(); - VIDEO_WaitVSync(); - - if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); - - printf("\x1b[2;0H"); - - VIDEO_WaitVSync(); -} - -#include -//#define ticks_to_secs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK*1000))) -//#define ticks_to_msecs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK))) - -void showdir(char *path) -{ - char filename[MAXPATHLEN]; - DIR_ITER *dp; - - struct stat fstat; - //chdir("usb:/"); - dp = diropen(path); - - if (dp == NULL) - { - printf("Error diropen\n"); - return ; - } - - else printf("Ok diropen\n"); - - int cnt = 0; - - while ( dirnext( dp, filename, &fstat ) == 0 ) - { - //if(cnt==20) break; - cnt++; - - if ( fstat.st_mode & S_IFDIR ) printf("/"); - - printf("%s\n", filename); - - } - - dirclose(dp); - printf("\nEnd show dirrectory (%d).\n", cnt); -} - -static void reset_cb (void) -{ - reset_pressed = true; -} - -static void power_cb (void) -{ - power_pressed = true; -} - -#include - - -#define VERSION "1.52" - -void save_log() // at now all data is sent to usbgecko, sd log disabled -{ - FILE *fp; - u8 *temp_data = NULL; - u32 level, len; - - temp_data = memalign(32, 256 * 1024); - - mload_seek(0x13750000, SEEK_SET); - mload_read(temp_data, 128*1024); - - //mload_init(); - - //mload_close(); - - for (len = 0;len < 4096 && temp_data[len] != 0;len++); - - fatUnmount("sd"); - - if (fatMount("sd", sd, 0, 128, 2) ) - { - - fp = fopen("sd:/log_usb2.txt", "wb"); - - if (fp != 0) - { - fprintf(fp, "USB2 device test program. v%s\n------------------------------\n", VERSION); - fwrite(temp_data, 1, len , fp); - - fclose(fp); - } - } - - if (usb_isgeckoalive(1)) - { - level = IRQ_Disable(); - usb_sendbuffer(1, temp_data, len); - IRQ_Restore(level); - } - - //printf("\nlog:\n-------\n%s", temp_data); - free(temp_data); -} - -void TryUSBDevice() -{ - printf("Initializing usb device.\n"); - bool s; - - USB2Enable(true); - s = usb->startup(); - usleep(10000); - - if (s > 0) - s = __usb2storage_ReadSectors(0, 1, memsector); - - usleep(10000); - - - if (s > 0) - { - - printf("usb device detected, your device is fully compatible with this usb2 driver\n"); - } - - else - { - //(s==-1) printf("usb device NOT INSERTED, log file not created\n"); - //se - { - printf("usb device NOT detected or not inserted, report 'ubs2 init' value and log file\n"); - printf("Log saved to sd:/log_usb2.txt file\n"); - } - } - - save_log(); -} - -static s32 initialise_network() -{ - s32 result; - - while ((result = net_init()) == -EAGAIN) - { - if (reset_pressed) exit(1); - - usleep(100); - } - - return result; -} - -int wait_for_network_initialisation() -{ - printf("Waiting for network to initialise...\n"); - - if (initialise_network() >= 0) - { - char myIP[16]; - - if (if_config(myIP, NULL, NULL, true) < 0) - { - printf("Error reading IP address\n"); - return 0; - } - - else - { - printf("Network initialised. Wii IP address: %s\n", myIP); - return 1; - } - } - - printf("Unable to initialise network\n"); - return 0; -} - -#define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f) -static bool usblan_detected(void) -{ - u8 *buffer; - u8 dummy; - u8 i; - u16 vid, pid; - - USB_Initialize(); - - buffer = (u8*)ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (32 * 1024))); - - memset(buffer, 0, 8 << 3); - - if (USB_GetDeviceList("/dev/usb/oh0", buffer, 8, 0, &dummy) < 0) - { - return false; - } - - for (i = 0; i < 8; i++) - { - memcpy(&vid, (buffer + (i << 3) + 4), 2); - memcpy(&pid, (buffer + (i << 3) + 6), 2); - - if ( (vid == 0x0b95) && (pid == 0x7720)) - { - return true; - } - } - - return false; -} - -void init_mload() -{ - int ret; - ret = mload_init(); - - if (ret < 0) - { - printf("fail to get dev/mload, mload cios not detected. Quit\n"); - sleep(3); - exit(0); - //goto out; - } -} - -void loadehcimodule() -{ - u32 addr; - int len; - - mload_get_load_base(&addr, &len); - - if (((u32) ehcmodule_elf) & 3) {printf("Unaligned elf!\n"); return ;} - - mload_elf((void *) ehcmodule_elf, &my_data_elf); - my_thread_id = mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, /*my_data_elf.prio*/0x47); - //my_thread_id=mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - - if (my_thread_id < 0) - { - printf("EHCI module can NOT be loaded (%i).. Quit\n", my_thread_id); - sleep(3); - exit(0); - } - - printf("EHCI module loaded (%i).\n", my_thread_id); - VIDEO_WaitVSync(); -} - -int main(int argc, char **argv) -{ - int ret; - bool usblan; - int usblanport; - - initialise_video(); - CON_EnableGecko(1, 0); - - usblan = usblan_detected(); - printf("ios 202 reload\n"); - IOS_ReloadIOS(202); - printf("ios 202 reloaded\n"); - init_mload(); - mload_reset_log(); - loadehcimodule(); - - if (usblan) - { - printf("uslan detected\n"); - usblanport = GetUSB2LanPort(); - printf("usblanport: %i\n", usblanport); - USB2Storage_Close(); - - mload_close(); - IOS_ReloadIOS(202); - init_mload(); - loadehcimodule(); - printf("SetUSBMode(%i)\n", usblanport); - - if (usblanport == 1) - SetUSB2Mode(1); - else - SetUSB2Mode(2); - - } - - else - printf("usblan NOT found\n"); - - SYS_SetResetCallback (reset_cb); - - SYS_SetPowerCallback (power_cb); - - // usleep(10000); - //WIIDVD_Init(false); - // usleep(10000); - - TryUSBDevice(); // init usb2 device - - // usleep(10000); - // save_log(); - // usleep(10000); - /* - if(WIIDVD_DiscPresent()) printf("dvd inserted\n"); - else printf("dvd NOT inserted\n"); - usleep(10000); - save_log(); - - if(fatMount("usb",usb,0,3,128)) - { - showdir("usb:/"); - } - else printf("can't mount usb\n"); - - sleep(6); - return 0; - wait_for_network_initialisation(); // check if lan is working - sleep(1); - */ - printf("Press Home or reset to exit. Press A or power to try to detect usb device again.\n"); - - VIDEO_WaitVSync(); - - VIDEO_WaitVSync(); - - while (1) //wait home press to exit - { - WPAD_ScanPads(); - - if (reset_pressed) break; - - u32 pressed = WPAD_ButtonsDown(0); - - if ( pressed & WPAD_BUTTON_HOME ) - { - mload_close(); - printf ("\n\nExit ..."); - exit(0); - } - - if ( (pressed & WPAD_BUTTON_A) || power_pressed) - { - power_pressed = false; - - TryUSBDevice(); - //usleep(5000); - power_pressed = false; - /* - if(fatMount("usb",usb,0,3,128)) - { - showdir("usb:/"); - } - else printf("can't mount usb\n"); - */ - //TryUSBDevice(); - /* - printf("deinit (5secs)\n"); - sleep(1); - net_deinit(); - sleep(4); - printf("init\n"); - wait_for_network_initialisation(); - */ - //power_pressed=false; - } - - usleep(5000); - VIDEO_WaitVSync(); - } - -out: - mload_close(); - printf ("\n\nExit ..."); - exit(0); -} +/************************************************************/ +/* USB speed test */ +/* */ +/* */ +/************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "mload.h" +#include "../build/ehcmodule_elf.h" +//#include "../build/fat_elf.h" +data_elf my_data_elf; +int my_thread_id=0; + + +#include + +#include +#include +#include +#include "usbstorage2.h" + + + +const DISC_INTERFACE* sd = &__io_wiisd; + +//const DISC_INTERFACE* usb1 = &__io_usb1storage; + +static bool reset_pressed = false; +static bool power_pressed = false; + +static void *xfb = NULL; +static GXRModeObj *rmode = NULL; +static const u32 CACHE_PAGES = 8; + +static u8 memsector[4*1024]; + + +void initialise_video() +{ + VIDEO_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(xfb); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); + printf("\x1b[2;0H"); + VIDEO_WaitVSync(); +} + +#include +//#define ticks_to_secs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK*1000))) +//#define ticks_to_msecs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK))) +/* +void showdir(char *path) +{ + char filename[MAXPATHLEN]; + DIR_ITER *dp; + struct stat fstat; + //chdir("usb:/"); + dp = diropen(path); + + if(dp==NULL) + { + printf("Error diropen\n"); + return; + } + else printf("Ok diropen\n"); + + int cnt=0; + while( dirnext( dp, filename, &fstat ) == 0 ) + { + //if(cnt==20) break; + cnt++; + + if( fstat.st_mode & S_IFDIR ) printf("/"); + printf("%s\n",filename); + + } + dirclose(dp); + printf("\nEnd show dirrectory (%d).\n",cnt); +} +*/ +static void reset_cb (void) { + reset_pressed = true; +} +static void power_cb (void) { + power_pressed = true; +} + +#include + + +#define VERSION "2.1" + + +void save_log() // at now all data is sent to usbgecko, sd log disabled +{ + FILE *fp; + u8 *temp_data= NULL; + u32 level,len; + + temp_data=memalign(32,256*1024); + + + mload_init(); + len=mload_get_log(); + + if(len>0) + mload_read(temp_data, len); + + + mload_close(); + + for(len=0;len <2*4096 && temp_data[len]!=0;len++); + /* + fatUnmount("sd"); + if(fatMount("sd",sd,0,128,2) ) + { + + fp=fopen("sd:/log_usb2.txt","wb"); + + if(fp!=0) + { + fprintf(fp,"USB2 device test program. v%s\n------------------------------\n",VERSION); + fwrite(temp_data,1, len ,fp); + + fclose(fp); + } + } + */ + if (usb_isgeckoalive(1)) { + level = IRQ_Disable(); + usb_sendbuffer(1, temp_data, len); + IRQ_Restore(level); + } + + //printf("\nlog:\n-------\n%s", temp_data); + free(temp_data); +} + +void TryUSBDevice(int port) +{ + printf("Initializing usb device port: %i.\n",port); + bool s; + DISC_INTERFACE* usb; + + if(port==0) usb= &__io_usbstorage2_port0; + else usb= &__io_usbstorage2_port1; + + //USB2Enable(true); + s=usb->startup(); + usleep(10000); + /* + if(s) + { + s = __usbstorage_ReadSectors(0, 1, memsector); + } + usleep(10000);*/ + + + if(s>0) + { + + printf("usb device detected, your device is fully compatible with this usb2 driver(%i)\n",s); + } + else + { + //(s==-1) printf("usb device NOT INSERTED, log file not created\n"); + //se + { + printf("usb device NOT detected or not inserted, report log file(%i)\n",s); + printf("Log saved to sd:/log_usb2.txt file\n"); + } + } + save_log(); +} + +void init_mload() +{ + int ret; + ret=mload_init(); + + if(ret<0) + { + printf("fail to get dev/mload, mload cios not detected. Quit\n"); + sleep(3); + exit(0); + //goto out; + } +} +void loadehcimodule() +{ + u32 addr; + int len; + + mload_get_load_base(&addr, &len); + + if(((u32) ehcmodule_elf) & 3) {printf("Unaligned elf!\n"); return;} + mload_elf((void *) ehcmodule_elf, &my_data_elf); + my_thread_id=mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); + //my_thread_id=mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); + if(my_thread_id<0) + { + printf("EHCI module can NOT be loaded (%i).. Quit\n",my_thread_id); + sleep(3); + exit(0); + } + + printf("EHCI module loaded (%i).\n",my_thread_id); + VIDEO_WaitVSync(); +} + +int main(int argc, char **argv) +{ + int ret; + bool usblan; + int usblanport; + + initialise_video(); + CON_EnableGecko(1,0); + + + + IOS_ReloadIOS(222); + init_mload(); + //mload_reset_log(); + loadehcimodule(); + + + SYS_SetResetCallback (reset_cb); + SYS_SetPowerCallback (power_cb); + WPAD_Init(); +// usleep(10000); +//WIIDVD_Init(false); +// usleep(10000); + +// TryUSBDevice(); // init usb2 device +// usleep(10000); +// save_log(); +// usleep(10000); +/* + if(WIIDVD_DiscPresent()) printf("dvd inserted\n"); + else printf("dvd NOT inserted\n"); + usleep(10000); + save_log(); + + if(fatMount("usb",usb,0,3,128)) + { + showdir("usb:/"); + } + else printf("can't mount usb\n"); + + sleep(6); + return 0; + wait_for_network_initialisation(); // check if lan is working + sleep(1); +*/ + printf("Press Home or reset to exit. Press A or power to try to detect usb device again.\n"); + + VIDEO_WaitVSync(); + VIDEO_WaitVSync(); + //exit(0); + while(1) //wait home press to exit + { + WPAD_ScanPads(); + if(reset_pressed) break; + u32 pressed = WPAD_ButtonsDown(0); + if ( pressed & WPAD_BUTTON_HOME ) + { + mload_close(); + printf ("\n\nExit ..."); + exit(0); + } + if ( (pressed & WPAD_BUTTON_A) || power_pressed) + { + power_pressed=false; + + TryUSBDevice(0); + //usleep(5000); + power_pressed=false; + /* + if(fatMount("usb",usb,0,3,128)) + { + showdir("usb:/"); + } + else printf("can't mount usb\n"); + */ + //TryUSBDevice(); + /* + printf("deinit (5secs)\n"); + sleep(1); + net_deinit(); + sleep(4); + printf("init\n"); + wait_for_network_initialisation(); + */ + //power_pressed=false; + } + if ( (pressed & WPAD_BUTTON_B) || power_pressed) + { + power_pressed=false; + + TryUSBDevice(1); + //usleep(5000); + power_pressed=false; + /* + if(fatMount("usb",usb,0,3,128)) + { + showdir("usb:/"); + } + else printf("can't mount usb\n"); + */ + //TryUSBDevice(); + /* + printf("deinit (5secs)\n"); + sleep(1); + net_deinit(); + sleep(4); + printf("init\n"); + wait_for_network_initialisation(); + */ + //power_pressed=false; + } + usleep(500); + VIDEO_WaitVSync(); + } +out: + mload_close(); + printf ("\n\nExit ..."); + exit(0); +} diff --git a/test/source/mload.c b/test/source/mload.c index e4fd17af..09ffecb1 100644 --- a/test/source/mload.c +++ b/test/source/mload.c @@ -1,493 +1,492 @@ -/* mload.c (for PPC) (c) 2009, Hermes - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "mload.h" - -static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload"; - -static s32 mload_fd = -1; -static s32 hid = -1; - -/*--------------------------------------------------------------------------------------------------------------*/ - -// to init/test if the device is running - -int mload_init() -{ - int n; - - if (hid < 0) hid = iosCreateHeap(0x800); - - if (hid < 0) - { - if (mload_fd >= 0) - IOS_Close(mload_fd); - - mload_fd = -1; - - return hid; - } - - if (mload_fd >= 0) - { - return 0; - } - - for (n = 0;n < 20;n++) // try 5 seconds - { - mload_fd = IOS_Open(mload_fs, 0); - - if (mload_fd >= 0) break; - - usleep(250*1000); - } - - if (mload_fd < 0) - { - - if (hid >= 0) - { - iosDestroyHeap(hid); - hid = -1; - } - } - - return mload_fd; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// to close the device (remember call it when rebooting the IOS!) - -int mload_close() -{ - int ret; - - if (hid >= 0) - { - iosDestroyHeap(hid); - hid = -1; - } - - if (mload_fd < 0) return -1; - - ret = IOS_Close(mload_fd); - - mload_fd = -1; - - return ret; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// to get the thread id of mload - -int mload_get_thread_id() -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":"); - - return ret; - -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// get the base and the size of the memory readable/writable to load modules - -int mload_get_load_base(u32 *starlet_base, int *size) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii", starlet_base, size); - - return ret; - -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// load and run a module from starlet (it need to allocate MEM2 to send the elf file) -// the module must be a elf made with stripios - -int mload_module(void *addr, int len) -{ - int ret; - void *buf = NULL; - - - if (mload_init() < 0) return -1; - - if (hid >= 0) - { - iosDestroyHeap(hid); - hid = -1; - } - - hid = iosCreateHeap(len + 0x800); - - if (hid < 0) return hid; - - buf = iosAlloc(hid, len); - -if (!buf) {ret = -1;goto out;} - - - memcpy(buf, addr, len); - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len); - - if (ret < 0) goto out; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":"); - -if (ret < 0) {ret = -666;goto out;} - -out: - - if (hid >= 0) - { - iosDestroyHeap(hid); - hid = -1; - } - - return ret; - -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// load a module from the PPC -// the module must be a elf made with stripios - -int mload_elf(void *my_elf, data_elf *data_elf) -{ - int n, m; - int p; - u8 *adr; - u32 elf = (u32) my_elf; - - if (elf & 3) return -1; // aligned to 4 please! - - elfheader *head = (void *) elf; - - elfphentry *entries; - - if (head->ident0 != 0x7F454C46) return -1; - - if (head->ident1 != 0x01020161) return -1; - - if (head->ident2 != 0x01000000) return -1; - - p = head->phoff; - - data_elf->start = (void *) head->entry; - - for (n = 0; n < head->phnum; n++) - { - entries = (void *) (elf + p); - p += sizeof(elfphentry); - - if (entries->type == 4) - { - adr = (void *) (elf + entries->offset); - - if (getbe32(0) != 0) return -2; // bad info (sure) - - for (m = 4; m < entries->memsz; m += 8) - { - switch (getbe32(m)) - { - case 0x9: - data_elf->start = (void *) getbe32(m + 4); - break; - case 0x7D: - data_elf->prio = getbe32(m + 4); - break; - case 0x7E: - data_elf->size_stack = getbe32(m + 4); - break; - case 0x7F: - data_elf->stack = (void *) (getbe32(m + 4)); - break; - - } - - } - - } - - else - if (entries->type == 1 && entries->memsz != 0 && entries->vaddr != 0) - { - - if (mload_memset((void *) entries->vaddr, 0, entries->memsz) < 0) return -1; - - if (mload_seek(entries->vaddr, SEEK_SET) < 0) return -1; - - if (mload_write((void *) (elf + entries->offset), entries->filesz) < 0) return -1; - - } - } - - return 0; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// run one thread (you can use to load modules or binary files) - -int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority) -{ - int ret; - - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr, starlet_top_stack, stack_size, priority); - - - return ret; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// stops one starlet thread - -int mload_stop_thread(int id) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id); - - return ret; - -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// continue one stopped starlet thread - -int mload_continue_thread(int id) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id); - - return ret; - -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// fix starlet address to read/write (uses SEEK_SET, etc as mode) - -int mload_seek(int offset, int mode) -{ - if (mload_init() < 0) return -1; - - return IOS_Seek(mload_fd, offset, mode); -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// read bytes from starlet (it update the offset) - -int mload_read(void* buf, u32 size) -{ - if (mload_init() < 0) return -1; - - return IOS_Read(mload_fd, buf, size); -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// write bytes from starlet (it update the offset) - -int mload_write(const void * buf, u32 size) -{ - if (mload_init() < 0) return -1; - - return IOS_Write(mload_fd, buf, size); -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// fill a block (similar to memset) - -int mload_memset(void *starlet_addr, int set, int len) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len); - - - return ret; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// get the ehci datas ( ehcmodule.elf uses this address) - -void * mload_get_ehci_data() -{ - int ret; - - if (mload_init() < 0) return NULL; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":"); - - if (ret < 0) return NULL; - - return (void *) ret; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// set the dev/es ioctlv in routine - -int mload_set_ES_ioctlv_vector(void *starlet_addr) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr); - - return ret; -} - - - -int mload_getw(const void * addr, u32 *dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETW, "i:i", addr, dat); - - return ret; -} - -int mload_geth(const void * addr, u16 *dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETH, "i:h", addr, dat); - - return ret; -} - -int mload_getb(const void * addr, u8 *dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETB, "i:b", addr, dat); - - return ret; -} - -int mload_setw(const void * addr, u32 dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETW, "ii:", addr, dat); - - return ret; -} - -int mload_seth(const void * addr, u16 dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETH, "ih:", addr, dat); - - return ret; -} - -int mload_setb(const void * addr, u8 dat) -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETB, "ib:", addr, dat); - - return ret; -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// to get log buffer -// this function return the size of the log buffer and prepare it to read with mload_read() the datas - -int mload_get_log() -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOG, ":"); - - return ret; - -} - -void mload_reset_log() -{ - if (mload_init() < 0) return ; - - IOS_IoctlvFormat(hid, mload_fd, MLOAD_RESET_LOG, ":"); -} - -/*--------------------------------------------------------------------------------------------------------------*/ - -// to get IOS base for dev/es to create the cIOS - -int mload_get_IOS_base() -{ - int ret; - - if (mload_init() < 0) return -1; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":"); - - return ret; - -} - - +/* mload.c (for PPC) (c) 2009, Hermes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "mload.h" + +static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload"; + +static s32 mload_fd = -1; +static s32 hid = -1; + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to init/test if the device is running + +int mload_init() +{ + int n; + + if(hid<0) hid = iosCreateHeap(0x10000); + + if(hid<0) + { + if(mload_fd>=0) + IOS_Close(mload_fd); + + mload_fd=-1; + + return hid; + } + + if(mload_fd>=0) + { + return 0; + } + + for(n=0;n<20;n++) // try 5 seconds + { + mload_fd=IOS_Open(mload_fs, 0); + + if(mload_fd>=0) break; + + usleep(250*1000); + } + + return mload_fd; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to close the device (remember call it when rebooting the IOS!) + +int mload_close() +{ + int ret; + + if(mload_fd<0) return -1; + + ret=IOS_Close(mload_fd); + + mload_fd=-1; + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to get the thread id of mload + +int mload_get_thread_id() +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":"); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// get the base and the size of the memory readable/writable to load modules + +int mload_get_load_base(u32 *starlet_base, int *size) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii",starlet_base, size); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// load and run a module from starlet (it need to allocate MEM2 to send the elf file) +// the module must be a elf made with stripios + +int mload_module(void *addr, int len) +{ + int ret; + void *buf=NULL; + + buf= iosAlloc(hid, len); + + if(!buf) + return -1; + + memcpy(buf, addr,len); + + ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len); + if(ret<0) + return ret; + + ret=IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":"); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// load a module from the PPC +// the module must be a elf made with stripios + +int mload_elf(void *my_elf, data_elf *data_elf) +{ + int n,m; + int p; + u8 *adr; + u32 elf=(u32) my_elf; + + if(elf & 3) return -1; // aligned to 4 please! + + elfheader *head=(void *) elf; + elfphentry *entries; + + if(head->ident0!=0x7F454C46) return -1; + if(head->ident1!=0x01020161) return -1; + if(head->ident2!=0x01000000) return -1; + + p=head->phoff; + + data_elf->start=(void *) head->entry; + + for(n=0; nphnum; n++) + { + entries=(void *) (elf+p); + p+=sizeof(elfphentry); + + if(entries->type == 4) + { + adr=(void *) (elf + entries->offset); + + if(getbe32(0)!=0) return -2; // bad info (sure) + + for(m=4; (u32)m < entries->memsz; m+=8) + { + switch(getbe32(m)) + { + case 0x9: + data_elf->start= (void *) getbe32(m+4); + break; + case 0x7D: + data_elf->prio= getbe32(m+4); + break; + case 0x7E: + data_elf->size_stack= getbe32(m+4); + break; + case 0x7F: + data_elf->stack= (void *) (getbe32(m+4)); + break; + + } + + } + + } + else + if(entries->type == 1 && entries->memsz != 0 && entries->vaddr!=0) + { + + if(mload_memset((void *) entries->vaddr, 0, entries->memsz)<0) return -1; + if(mload_seek(entries->vaddr, SEEK_SET)<0) return -1; + if(mload_write((void *) (elf + entries->offset), entries->filesz)<0) return -1; + + } + } + + return 0; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// run one thread (you can use to load modules or binary files) + +int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr,starlet_top_stack, stack_size, priority); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// stops one starlet thread + +int mload_stop_thread(int id) +{ +int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id); + +return ret; + +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// continue one stopped starlet thread + +int mload_continue_thread(int id) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id); + + return ret; +} +/*--------------------------------------------------------------------------------------------------------------*/ + +// fix starlet address to read/write (uses SEEK_SET, etc as mode) + +int mload_seek(int offset, int mode) +{ + if(mload_init()<0) return -1; + + return IOS_Seek(mload_fd, offset, mode); +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// read bytes from starlet (it update the offset) + +int mload_read(void* buf, u32 size) +{ + if(mload_init()<0) return -1; + + return IOS_Read(mload_fd, buf, size); +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// write bytes from starlet (it update the offset) + +int mload_write(const void * buf, u32 size) +{ + if(mload_init()<0) return -1; + + return IOS_Write(mload_fd, buf, size); +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// fill a block (similar to memset) + +int mload_memset(void *starlet_addr, int set, int len) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// get the ehci datas ( ehcmodule.elf uses this address) + +void * mload_get_ehci_data() +{ + int ret; + + if(mload_init()<0) return NULL; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":"); + if(ret<0) return NULL; + + return (void *) ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// set the dev/es ioctlv in routine + +int mload_set_ES_ioctlv_vector(void *starlet_addr) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr); + + return ret; +} + + + +int mload_getw(const void * addr, u32 *dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETW, "i:i", addr, dat); + + return ret; +} + +int mload_geth(const void * addr, u16 *dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETH, "i:h", addr, dat); + + return ret; +} + +int mload_getb(const void * addr, u8 *dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETB, "i:b", addr, dat); + + return ret; +} + +int mload_setw(const void * addr, u32 dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETW, "ii:", addr, dat); + + return ret; +} + +int mload_seth(const void * addr, u16 dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETH, "ih:", addr, dat); + + return ret; +} + +int mload_setb(const void * addr, u8 dat) +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETB, "ib:", addr, dat); + + return ret; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to get log buffer +// this function return the size of the log buffer and prepare it to read with mload_read() the datas + +int mload_get_log() +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOG, ":"); + + return ret; + +} + + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to get IOS base for dev/es to create the cIOS + +int mload_get_IOS_base() +{ + int ret; + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":"); + + return ret; + +} + + +int mload_get_version() +{ + int ret; + if(mload_init()<0) return -1; + ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_MLOAD_VERSION, ":"); + return ret; +} + +/* IOS info structure */ +typedef struct { + /* Syscall base */ + u32 syscall; + + /* Module versions */ + u32 dipVersion; + u32 esVersion; + u32 ffsVersion; + u32 iopVersion; +} iosInfo; + +int wanin_mload_get_IOS_base() +{ + int ret; + iosInfo ios; + memset(&ios, 0, sizeof(ios)); + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":d", &ios, sizeof(ios)); + //gprintf("get_ios_base: %d %x\n", ret, ios.dipVersion); + if (ret == 0) { + switch(ios.dipVersion) { + case 0x48776F72: /* DIP: 07/11/08 14:34:26 */ + return 37; + + case 0x4888E14C: /* DIP: 07/24/08 20:08:44 */ + return 38; + + case 0x4A262AF5: /* DIP: 06/03/09 07:49:09 */ + return 57; + + case 0x492ACA9D: /* DIP: 11/24/08 15:39:09 */ + return 60; + } + } + return ret; +} + +int mload_set_gecko_debug() +{ + int ret; + u32 log_mode = 2; // GECKO + if(mload_init()<0) return -1; + + gprintf("Setting debug mode..."); + ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_LOG_MODE, ":d", &log_mode, sizeof(log_mode)); + gprintf("%d\n", ret); + return ret; +} diff --git a/test/source/mload.h b/test/source/mload.h index ff900fa7..43f21d4c 100644 --- a/test/source/mload.h +++ b/test/source/mload.h @@ -1,240 +1,233 @@ -/* mload.c (for PPC) (c) 2009, Hermes - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef __MLOAD_H__ -#define __MLOAD_H__ - - -#include -#include -#include -#include -#include -#include "unistd.h" - -#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400 -#define MLOAD_GET_IOS_BASE 0x4D4C4401 -#define MLOAD_LOAD_MODULE 0x4D4C4480 -#define MLOAD_RUN_MODULE 0x4D4C4481 -#define MLOAD_RUN_THREAD 0x4D4C4482 - -#define MLOAD_STOP_THREAD 0x4D4C4484 -#define MLOAD_CONTINUE_THREAD 0x4D4C4485 - -#define MLOAD_GET_LOAD_BASE 0x4D4C4490 -#define MLOAD_MEMSET 0x4D4C4491 - -#define MLOAD_GET_EHCI_DATA 0x4D4C44A0 -#define MLOAD_GET_LOG 0x4D4C44A1 -#define MLOAD_RESET_LOG 0x4D4C44A2 - -#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0 - -#define MLOAD_GETW 0x4D4C44C0 -#define MLOAD_GETH 0x4D4C44C1 -#define MLOAD_GETB 0x4D4C44C2 -#define MLOAD_SETW 0x4D4C44C3 -#define MLOAD_SETH 0x4D4C44C4 -#define MLOAD_SETB 0x4D4C44C5 - -#ifdef __cplusplus -extern "C" -{ -#endif - - - // from IOS ELF stripper of neimod - -#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3])) - - typedef struct - { - u32 ident0; - u32 ident1; - u32 ident2; - u32 ident3; - u32 machinetype; - u32 version; - u32 entry; - u32 phoff; - u32 shoff; - u32 flags; - u16 ehsize; - u16 phentsize; - u16 phnum; - u16 shentsize; - u16 shnum; - u16 shtrndx; - } - - elfheader; - - typedef struct - { - u32 type; - u32 offset; - u32 vaddr; - u32 paddr; - u32 filesz; - u32 memsz; - u32 flags; - u32 align; - } - - elfphentry; - - typedef struct - { - void *start; - int prio; - void *stack; - int size_stack; - } - - data_elf; - - /*--------------------------------------------------------------------------------------------------------------*/ - - // to init/test if the device is running - - int mload_init(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // to close the device (remember call it when rebooting the IOS!) - - int mload_close(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // to get the thread id of mload - - int mload_get_thread_id(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // get the base and the size of the memory readable/writable to load modules - - int mload_get_load_base(u32 *starlet_base, int *size); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // load and run a module from starlet (it need to allocate MEM2 to send the elf file) - // the module must be a elf made with stripios - - int mload_module(void *addr, int len); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // load a module from the PPC - // the module must be a elf made with stripios - - int mload_elf(void *my_elf, data_elf *data_elf); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // run one thread (you can use to load modules or binary files) - - int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // stops one starlet thread - - int mload_stop_thread(int id); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // continue one stopped starlet thread - - int mload_continue_thread(int id); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // fix starlet address to read/write (uses SEEK_SET, etc as mode) - - int mload_seek(int offset, int mode); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // read bytes from starlet (it update the offset) - - int mload_read(void* buf, u32 size); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // write bytes from starlet (it update the offset) - - int mload_write(const void * buf, u32 size); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // fill a block (similar to memset) - - int mload_memset(void *starlet_addr, int set, int len); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // get the ehci datas ( ehcmodule.elf uses this address) - - void * mload_get_ehci_data(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - // set the dev/es ioctlv in routine - - int mload_set_ES_ioctlv_vector(void *starlet_addr); - - /*--------------------------------------------------------------------------------------------------------------*/ - - - // to get log buffer - // this function return the size of the log buffer and prepare it to read with mload_read() the datas - - int mload_get_log(); - - void mload_reset_log(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - - // to get IOS base for dev/es to create the cIOS - - int mload_get_IOS_base(); - - /*--------------------------------------------------------------------------------------------------------------*/ - - int mload_getw(const void * addr, u32 *dat); - - int mload_geth(const void * addr, u16 *dat); - - int mload_getb(const void * addr, u8 *dat); - - int mload_setw(const void * addr, u32 dat); - - int mload_seth(const void * addr, u16 dat); - - int mload_setb(const void * addr, u8 dat); - -#ifdef __cplusplus - -} - -#endif - - -#endif +/* mload.c (for PPC) (c) 2009, Hermes + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __MLOAD_H__ +#define __MLOAD_H__ + + +#include +#include +#include +#include +#include +#include "unistd.h" + +#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400 +#define MLOAD_GET_IOS_BASE 0x4D4C4401 +#define MLOAD_GET_MLOAD_VERSION 0x4D4C4402 + +#define MLOAD_LOAD_MODULE 0x4D4C4480 +#define MLOAD_RUN_MODULE 0x4D4C4481 +#define MLOAD_RUN_THREAD 0x4D4C4482 + +#define MLOAD_STOP_THREAD 0x4D4C4484 +#define MLOAD_CONTINUE_THREAD 0x4D4C4485 + +#define MLOAD_GET_LOAD_BASE 0x4D4C4490 +#define MLOAD_MEMSET 0x4D4C4491 + +#define MLOAD_GET_EHCI_DATA 0x4D4C44A0 +#define MLOAD_GET_LOG 0x4D4C44A1 + +#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0 + +#define MLOAD_GETW 0x4D4C44C0 +#define MLOAD_GETH 0x4D4C44C1 +#define MLOAD_GETB 0x4D4C44C2 +#define MLOAD_SETW 0x4D4C44C3 +#define MLOAD_SETH 0x4D4C44C4 +#define MLOAD_SETB 0x4D4C44C5 + +#define MLOAD_SET_LOG_MODE 0x4D4C44D0 +#define MLOAD_GET_LOG_BUFFER 0x4D4C44D1 + +#ifdef __cplusplus +extern "C" { +#endif + +// from IOS ELF stripper of neimod + +#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3])) + +typedef struct +{ + u32 ident0; + u32 ident1; + u32 ident2; + u32 ident3; + u32 machinetype; + u32 version; + u32 entry; + u32 phoff; + u32 shoff; + u32 flags; + u16 ehsize; + u16 phentsize; + u16 phnum; + u16 shentsize; + u16 shnum; + u16 shtrndx; +} elfheader; + +typedef struct +{ + u32 type; + u32 offset; + u32 vaddr; + u32 paddr; + u32 filesz; + u32 memsz; + u32 flags; + u32 align; +} elfphentry; + +typedef struct +{ + void *start; + int prio; + void *stack; + int size_stack; +} data_elf; + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to init/test if the device is running + +int mload_init(); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to close the device (remember call it when rebooting the IOS!) + +int mload_close(); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// to get the thread id of mload + +int mload_get_thread_id(); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// get the base and the size of the memory readable/writable to load modules + +int mload_get_load_base(u32 *starlet_base, int *size); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// load and run a module from starlet (it need to allocate MEM2 to send the elf file) +// the module must be a elf made with stripios + +int mload_module(void *addr, int len); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// load a module from the PPC +// the module must be a elf made with stripios + +int mload_elf(void *my_elf, data_elf *data_elf); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// run one thread (you can use to load modules or binary files) + +int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// stops one starlet thread + +int mload_stop_thread(int id); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// continue one stopped starlet thread + +int mload_continue_thread(int id); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// fix starlet address to read/write (uses SEEK_SET, etc as mode) + +int mload_seek(int offset, int mode); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// read bytes from starlet (it update the offset) + +int mload_read(void* buf, u32 size); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// write bytes from starlet (it update the offset) + +int mload_write(const void * buf, u32 size); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// fill a block (similar to memset) + +int mload_memset(void *starlet_addr, int set, int len); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// get the ehci datas ( ehcmodule.elf uses this address) + +void * mload_get_ehci_data(); + +/*--------------------------------------------------------------------------------------------------------------*/ + +// set the dev/es ioctlv in routine + +int mload_set_ES_ioctlv_vector(void *starlet_addr); + +/*--------------------------------------------------------------------------------------------------------------*/ + + +// to get log buffer +// this function return the size of the log buffer and prepare it to read with mload_read() the datas + +int mload_get_log(); + +/*--------------------------------------------------------------------------------------------------------------*/ + + +// to get IOS base for dev/es to create the cIOS + +int mload_get_IOS_base(); + +int mload_get_version(); + +/*--------------------------------------------------------------------------------------------------------------*/ + +int mload_getw(const void * addr, u32 *dat); +int mload_geth(const void * addr, u16 *dat); +int mload_getb(const void * addr, u8 *dat); + +int mload_setw(const void * addr, u32 dat); +int mload_seth(const void * addr, u16 dat); +int mload_setb(const void * addr, u8 dat); + +int wanin_mload_get_IOS_base(); +int mload_set_gecko_debug(); + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/test/source/usbstorage2.c b/test/source/usbstorage2.c new file mode 100644 index 00000000..0694fcfb --- /dev/null +++ b/test/source/usbstorage2.c @@ -0,0 +1,344 @@ +/*------------------------------------------------------------- + + usbstorage_starlet.c -- USB mass storage support, inside starlet + Copyright (C) 2011 Dimok + Copyright (C) 2011 Rodries + Copyright (C) 2009 Kwiirk + + If this driver is linked before libogc, this will replace the original + usbstorage driver by svpe from libogc + 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 +#include +#include +#include +#include "usbstorage2.h" +//#include "memory/mem2.h" +//#include "gecko.h" + + +/* IOCTL commands */ +#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8)) +#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1) +#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2) +#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3) +#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4) +#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5) +#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6) +#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10) +#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80) + +#define USB_IOCTL_UMS_TESTMODE (UMS_BASE+0x81) +#define USB_IOCTL_SET_PORT (UMS_BASE+0x83) + +#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8)) +#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1) +#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2) +#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x50) +#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x51) + +#define isMEM2Buffer(p) (((u32) p & 0x10000000) != 0) + +#define MAX_SECTOR_SIZE 4096 +#define MAX_BUFFER_SECTORS 128 +#define UMS_HEAPSIZE 2*1024 //it's enoguh, only used for ipc calls, don't waste ios heap + +/* Variables */ +static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2"; +static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb123"; +static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc"; + +static u8 * mem2_ptr = NULL; +static s32 hid = -1, fd = -1; +static u32 usb2_port = -1; //current USB port +bool hddInUse[2] = { false, false }; +u32 hdd_sector_size[2] = { 512, 512 }; + +s32 USBStorage2_Init(u32 port) +{ + s32 ret; + + /* Create heap */ + if (hid < 0) + { + hid = iosCreateHeap(UMS_HEAPSIZE + 4*1024); //added 4kb for testing, must be deleted because mem2_ptr will be created with mem2 manager + if (hid < 0) return IPC_ENOMEM; + } + + /* Open USB device */ + if (fd < 0) + { + if (fd < 0) fd = IOS_Open(fs, 0); + if (fd < 0) fd = IOS_Open(fs2, 0); + if (fd < 0) fd = IOS_Open(fs3, 0); + if (fd < 0) return fd; + } + USBStorage2_SetPort(port); + + /* Initialize USB storage */ + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":"); + if(ret!=port) return -1; + + /* Get device capacity */ + if (USBStorage2_GetCapacity(port, &hdd_sector_size[port]) == 0) + return IPC_ENOENT; + + hddInUse[port] = true; + + return 0; // 0->HDD, 1->DVD +} + +void USBStorage2_Deinit(u32 port) +{ + /* Close USB device */ + if (fd >= 0) + { + if(!hddInUse[!port]) + { + IOS_Close(fd); // not sure to close the fd is needed + fd = -1; + } + hddInUse[port] = false; + } + + hdd_sector_size[port] = 512; +} + +s32 USBStorage2_SetPort(u32 port) +{ + //! Port = 2 is handle in the loader, no need to handle it in cIOS + if(port > 1) + return -1; + + if(port == usb2_port) + return 0; + + s32 ret = -1; + usb2_port = port; + + //gprintf("Changing USB port to port %i....\n", port); + //must be called before USBStorage2_Init (default port 0) + if (fd >= 0) + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_SET_PORT, "i:", usb2_port); + + return ret; +} + +s32 USBStorage2_GetPort() +{ + return usb2_port; +} + +s32 USBStorage2_GetCapacity(u32 port, u32 *_sector_size) +{ + if (fd >= 0) + { + s32 ret; + u32 sector_size = 0; + USBStorage2_SetPort(port); + + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", §or_size); + + if (ret && _sector_size) *_sector_size = sector_size; + + return ret; + } + + return IPC_ENOENT; +} + +s32 USBStorage2_ReadSectors(u32 port, u32 sector, u32 numSectors, void *buffer) +{ + u8 *buf = (u8 *) buffer; + s32 ret = -1; + + /* Device not opened */ + if (fd < 0) return fd; + + if (!mem2_ptr) + //mem2_ptr = (u8 *) MEM2_alloc(MAX_SECTOR_SIZE * MAX_BUFFER_SECTORS); + mem2_ptr = (u8 *) __lwp_heap_allocate(&hid, 4*1024); //patch for testing mem2 manager must be used + + USBStorage2_SetPort(port); + + s32 read_secs, read_size; + + while(numSectors > 0) + { + read_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors; + read_size = read_secs*hdd_sector_size[port]; + + // Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow! + if (!isMEM2Buffer(buffer)) + { + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, read_secs, mem2_ptr, read_size); + if(ret < 0) + return ret; + + memcpy(buf, mem2_ptr, read_size); + } + else + { + /* Read data */ + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, read_secs, buf, read_size); + if(ret < 0) + return ret; + } + + sector += read_secs; + numSectors -= read_secs; + buf += read_size; + } + + return ret; +} + +s32 USBStorage2_WriteSectors(u32 port, u32 sector, u32 numSectors, const void *buffer) +{ + u8 *buf = (u8 *) buffer; + s32 ret = -1; + + /* Device not opened */ + if (fd < 0) return fd; + + /* Device not opened */ + if (!mem2_ptr) + //mem2_ptr = (u8 *) MEM2_alloc(MAX_SECTOR_SIZE * MAX_BUFFER_SECTORS); + mem2_ptr = (u8 *) __lwp_heap_allocate(&hid, 4*1024); //patch for testing mem2 manager must be used + + USBStorage2_SetPort(port); + + s32 write_size, write_secs; + + while(numSectors > 0) + { + write_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors; + write_size = write_secs*hdd_sector_size[port]; + + /* MEM1 buffer */ + if (!isMEM2Buffer(buffer)) + { + // Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow! + memcpy(mem2_ptr, buf, write_size); + + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, write_secs, mem2_ptr, write_size); + if(ret < 0) + return ret; + } + else + { + /* Write data */ + ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, write_secs, buf, write_size); + if(ret < 0) + return ret; + } + + sector += write_secs; + numSectors -= write_secs; + buf += write_size; + } + + return ret; +} + +static bool __usbstorage_Startup(void) +{ + return USBStorage2_Init(0) >= 0; +} + +static bool __usbstorage_IsInserted(void) +{ + return (USBStorage2_GetCapacity(0, NULL) != 0); +} + +static bool __usbstorage_ReadSectors(u32 sector, u32 numSectors, void *buffer) +{ + return (USBStorage2_ReadSectors(0, sector, numSectors, buffer) >= 0); +} + +static bool __usbstorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer) +{ + return (USBStorage2_WriteSectors(0, sector, numSectors, buffer) >= 0); +} + +static bool __usbstorage_ClearStatus(void) +{ + return true; +} + +static bool __usbstorage_Shutdown(void) +{ + USBStorage2_Deinit(0); + return true; +} + +const DISC_INTERFACE __io_usbstorage2_port0 = { + DEVICE_TYPE_WII_UMS, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB, + (FN_MEDIUM_STARTUP) &__usbstorage_Startup, + (FN_MEDIUM_ISINSERTED) &__usbstorage_IsInserted, + (FN_MEDIUM_READSECTORS) &__usbstorage_ReadSectors, + (FN_MEDIUM_WRITESECTORS) &__usbstorage_WriteSectors, + (FN_MEDIUM_CLEARSTATUS) &__usbstorage_ClearStatus, + (FN_MEDIUM_SHUTDOWN) &__usbstorage_Shutdown +}; + +static bool __usbstorage_Startup2(void) +{ + return USBStorage2_Init(1) >= 0; +} + +static bool __usbstorage_IsInserted2(void) +{ + return (USBStorage2_GetCapacity(1, NULL) != 0); +} + +static bool __usbstorage_ReadSectors2(u32 sector, u32 numSectors, void *buffer) +{ + return (USBStorage2_ReadSectors(1, sector, numSectors, buffer) >= 0); +} + +static bool __usbstorage_WriteSectors2(u32 sector, u32 numSectors, const void *buffer) +{ + return (USBStorage2_WriteSectors(1, sector, numSectors, buffer) >= 0); +} + +static bool __usbstorage_ClearStatus2(void) +{ + return true; +} + +static bool __usbstorage_Shutdown2(void) +{ + USBStorage2_Deinit(1); + return true; +} + +const DISC_INTERFACE __io_usbstorage2_port1 = { + DEVICE_TYPE_WII_UMS, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB, + (FN_MEDIUM_STARTUP) &__usbstorage_Startup2, + (FN_MEDIUM_ISINSERTED) &__usbstorage_IsInserted2, + (FN_MEDIUM_READSECTORS) &__usbstorage_ReadSectors2, + (FN_MEDIUM_WRITESECTORS) &__usbstorage_WriteSectors2, + (FN_MEDIUM_CLEARSTATUS) &__usbstorage_ClearStatus2, + (FN_MEDIUM_SHUTDOWN) &__usbstorage_Shutdown2 +}; diff --git a/test/source/usbstorage2.h b/test/source/usbstorage2.h new file mode 100644 index 00000000..80687eea --- /dev/null +++ b/test/source/usbstorage2.h @@ -0,0 +1,31 @@ +#ifndef _USBSTORAGE2_H_ +#define _USBSTORAGE2_H_ + +#include "ogc/disc_io.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Prototypes */ + s32 USBStorage2_Init(u32 port); + void USBStorage2_Deinit(u32 port); + s32 USBStorage2_GetCapacity(u32 port, u32 *size); + + s32 USBStorage2_ReadSectors(u32 port, u32 sector, u32 numSectors, void *buffer); + s32 USBStorage2_WriteSectors(u32 port, u32 sector, u32 numSectors, const void *buffer); + + s32 USBStorage2_SetPort(u32 port); + s32 USBStorage2_GetPort(); + +#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S') + + extern const DISC_INTERFACE __io_usbstorage2_port0; + extern const DISC_INTERFACE __io_usbstorage2_port1; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tinyehci/ehci.c b/tinyehci/ehci.c index caddc158..79bee390 100644 --- a/tinyehci/ehci.c +++ b/tinyehci/ehci.c @@ -25,8 +25,6 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -extern char use_usb_port1; - /* magic numbers that can affect system performance */ #define EHCI_TUNE_CERR 0 /* 0-3 qtd retries; 0 == don't stop */ /* by Hermes: i have replaced 3 by 0 and now it donīt hang when i extract the device*/ #define EHCI_TUNE_RL_HS 4 //4 /* nak throttle; see 4.9 */ @@ -175,7 +173,7 @@ void dump_qh(struct ehci_qh *qh) * bridge shutdown: shutting down the bridge before the devices using it. */ -int unplug_device=0; +int unplug_device[2]={0,0}; #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) @@ -535,7 +533,7 @@ cleanup: return NULL; } -u32 usb_timeout=1000*1000; +u32 usb_timeout=500*1000; int mode_int=0; @@ -659,7 +657,7 @@ u32 temp; { if((temp & 1)!=1) // off { - unplug_device=2; + unplug_device[current_port]=2; // *((volatile u32 *)0x0d8000c0) &=~0x20; // LED OFF (you can do it in Interrupt mode) } @@ -752,7 +750,7 @@ u32 temp; { - unplug_device=1; + unplug_device[current_port]=1; // *((volatile u32 *)0x0d8000c0) &=~0x20; // LED OFF (you can do it in Interrupt mode) ret=-ENODEV; @@ -813,7 +811,7 @@ extern int qtd_alt_mem; if(urb->ep==0) //control message { - unplug_device=0; + unplug_device[current_port]=0; urb->setup_dma = ehci_dma_map_to(urb->setup_buffer,sizeof (usbctrlrequest)); } @@ -938,9 +936,9 @@ extern int qtd_alt_mem; }while(retval==-9); mode_int=0; if(enable_urb_debug) s_printf("urb retval: %i\n",retval); - if(retval!=0 || unplug_device!=0) + if(retval!=0 || unplug_device[current_port]!=0) { - if((ehci_readl(&ehci->regs->port_status[current_port]) & 5) !=5) unplug_device=1; + if((ehci_readl(&ehci->regs->port_status[current_port]) & 5) !=5) unplug_device[current_port]=1; //retval=-ETIMEDOUT; } @@ -1503,8 +1501,8 @@ int ehci_adquire_usb_port(int port) ehci_mdelay(60); return 1; } - -int ehci_discover(void) +/* +int ehci_discover(void) //NOT USED { int i,ret,from,to; u32 status; @@ -1551,6 +1549,7 @@ int ehci_discover(void) } return ret; } +*/ int ehci_release_port(int port) { u32 __iomem *status_reg = &ehci->regs->port_status[port]; @@ -1601,15 +1600,12 @@ int ehci_release_externals_usb_ports(void) } return 0; } - +/* int ehci_open_device(int vid,int pid,int fd) { int i; - // for(i=0;inum_port;i++) - // { - - i=use_usb_port1!=0; - + for(i=0;inum_port;i++) + { //ehci_dbg("try device: %d\n",i); if(ehci->devices[i].fd == 0 && le16_to_cpu(ehci->devices[i].desc.idVendor) == vid && @@ -1619,14 +1615,19 @@ int ehci_open_device(int vid,int pid,int fd) ehci->devices[i].fd = fd; return fd; } - //} + } return -6; } +*/ int ehci_close_device(struct ehci_device *dev) { - if (dev) - dev->fd = -1; - return 0; + if (dev) + { + dev->fd = -1; + dev->id=0; + } + + return 0; } void ehci_close_devices() @@ -1641,45 +1642,27 @@ void ehci_close_devices() } - void * ehci_fd_to_dev(int fd) +void * ehci_fd_to_dev(int fd) { - int i; - // for(i=0;inum_port;i++) - current_port=use_usb_port1!=0; - - i=use_usb_port1!=0; - - - { - - struct ehci_device *dev = &ehci->devices[i]; - - return dev; // return always device[0] - - #if 0 - //ehci_dbg ( "device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); - if(dev->fd == fd){ - return dev; - - } - #endif - } - ehci_dbg("unknown fd! %d\n",fd); - return 0; + int i; + for(i=0;inum_port;i++) + { + struct ehci_device *dev = &ehci->devices[i]; + if(dev->fd == fd) return dev; + } + //ehci_dbg("unknown fd! %d\n",fd); + return 0; } #define g_ehci #error int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf) { int i,j = 0; - // for(i=0;inum_port && jnum_port && jdevices[i]; if(dev->id != 0){ //ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct)); - buf[j*4] = 0; + buf[j*4] = i; //port buf[j*4+1] = 0; buf[j*4+2] = le16_to_cpu(dev->desc.idVendor); buf[j*4+3] = le16_to_cpu(dev->desc.idProduct); @@ -1688,7 +1671,7 @@ int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf) } //ehci_dbg("found %d devices\n",j); *num = j; - return 0; + return j; } diff --git a/tinyehci/ehci.h b/tinyehci/ehci.h index 27412da0..c9300420 100644 --- a/tinyehci/ehci.h +++ b/tinyehci/ehci.h @@ -258,7 +258,7 @@ void create_qtd_dummy(void); s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *buf); s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u32 wLength,void *rpData); -int ehci_discover(void); +//int ehci_discover(void); int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf); int ehci_reset_port2(int port); @@ -266,12 +266,13 @@ int ehci_reset_port2(int port); extern struct ehci_hcd *ehci; /* @todo put ehci as a static global and remove ehci from APIs.. */ extern int ehci_open_device(int vid,int pid,int fd); extern int ehci_close_device(struct ehci_device *dev); +extern void ehci_close_devices(void); extern void * ehci_fd_to_dev(int fd); extern int ehci_release_ports(void); /* UMS API */ -s32 USBStorage_Init(void); +s32 USBStorage_Init(int mode); u32 USBStorage_Get_Capacity(u32*sector_size); s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer); s32 USBStorage_Read_Stress(u32 sector, u32 numSectors, void *buffer); diff --git a/tinyehci/usbstorage.c b/tinyehci/usbstorage.c index 15b5f64d..654caa70 100644 --- a/tinyehci/usbstorage.c +++ b/tinyehci/usbstorage.c @@ -87,16 +87,17 @@ extern char use_reset_bulk; extern char force_flags; extern char use_alternative_timeout; -int is_dvd=0; +int is_dvd[2] = {0,0}; -int ums_init_done = 0; +int ums_init_done[2] = {0,0}; -static usbstorage_handle __usbfd; -static u8 __lun = 16; -static u8 __mounted = 0; -static u16 __vid = 0; -static u16 __pid = 0; +static usbstorage_handle __usbfd[2]; +static u8 __lun[2] = {16,16}; +static u8 __mounted[2] = {0,0}; +static u16 __vid[2] = {0,0}; +static u16 __pid[2] = {0,0}; extern u32 current_port; +static u8* glob_buff =NULL; void reinit_ehci_headers(void); void ehci_stop(void); @@ -433,14 +434,14 @@ static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, // s8 retries = USBSTORAGE_CYCLE_RETRIES + 1; - unplug_device=0; + unplug_device[current_port]=0; do { // if(unplug_device) {return -ENODEV;} - if(retval==-ETIMEDOUT || retval==-ENODEV) {unplug_device=1;break;} + if(retval==-ETIMEDOUT || retval==-ENODEV) {unplug_device[current_port]=1;break;} if(retval < 0 /*&& retval!=USBSTORAGE_ESTATUS*/) @@ -455,7 +456,7 @@ static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, retries2++; if(retval<0) { - if(retries2>2) {unplug_device=1;break;} else {ehci_msleep(10);continue;} + if(retries2>2) {unplug_device[current_port]=1;break;} else {ehci_msleep(10);continue;} } else retries2=0; ///// @@ -615,10 +616,10 @@ static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, } while(retval < 0 && retries > 0); // force unplug - if(retval < 0) {unplug_device=1;} + if(retval < 0) {unplug_device[current_port]=1;} - if(retval>=0) unplug_device=0; + if(retval>=0) unplug_device[current_port]=0; if(_status != NULL) @@ -730,7 +731,7 @@ static s32 __usbstorage_reset(usbstorage_handle *dev,int hard_reset) // device unplugged if (!(PORT_CONNECT & status)) { - unplug_device=1; + unplug_device[current_port]=1; usb_timeout=old_usb_timeout; return -ENODEV; } @@ -812,7 +813,7 @@ end: usb_timeout=old_usb_timeout; - unplug_device=1; // force the unplug method + unplug_device[current_port]=1; // force the unplug method return retval; } @@ -853,7 +854,8 @@ struct _device_data u16 pad2; -} ATTRIBUTE_PACKED _old_device={0}; +} +ATTRIBUTE_PACKED _old_device[2]; s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) @@ -867,7 +869,7 @@ s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) usb_endpointdesc *ued; - __lun= 16; // select bad LUN + __lun[current_port]= 16; // select bad LUN //max_lun = USB_Alloc(1); //if(max_lun==NULL) return -ENOMEM; @@ -894,15 +896,15 @@ s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) goto free_and_return; // test device changed without unmount (prevent device write corruption) - if(ums_init_done) + if(ums_init_done[current_port]) { - if(_old_device.bDeviceClass!=udd.bDeviceClass || - _old_device.bDeviceSubClass!=udd.bDeviceSubClass || - _old_device.idVendor!=udd.idVendor || - _old_device.idProduct!=udd.idProduct || - _old_device.iManufacturer!=udd.iManufacturer || - _old_device.iProduct!=udd.iProduct || - _old_device.iSerialNumber!=udd.iSerialNumber) + if(_old_device[current_port].bDeviceClass!=udd.bDeviceClass || + _old_device[current_port].bDeviceSubClass!=udd.bDeviceSubClass || + _old_device[current_port].idVendor!=udd.idVendor || + _old_device[current_port].idProduct!=udd.idProduct || + _old_device[current_port].iManufacturer!=udd.iManufacturer || + _old_device[current_port].iProduct!=udd.iProduct || + _old_device[current_port].iSerialNumber!=udd.iSerialNumber) { //USB_Free(max_lun); USB_FreeDescriptors(&udd); @@ -914,13 +916,13 @@ s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) } } - _old_device.bDeviceClass=udd.bDeviceClass; - _old_device.bDeviceSubClass=udd.bDeviceSubClass; - _old_device.idVendor=udd.idVendor; - _old_device.idProduct=udd.idProduct; - _old_device.iManufacturer=udd.iManufacturer; - _old_device.iProduct=udd.iProduct; - _old_device.iSerialNumber=udd.iSerialNumber; + _old_device[current_port].bDeviceClass=udd.bDeviceClass; + _old_device[current_port].bDeviceSubClass=udd.bDeviceSubClass; + _old_device[current_port].idVendor=udd.idVendor; + _old_device[current_port].idProduct=udd.idProduct; + _old_device[current_port].iManufacturer=udd.iManufacturer; + _old_device[current_port].iProduct=udd.iProduct; + _old_device[current_port].iSerialNumber=udd.iSerialNumber; try_status=-128; @@ -981,12 +983,12 @@ s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd) s_printf("ep_in %x ep_out %x\n", (u32) dev->ep_in, (u32) dev->ep_out); #endif - _old_device.ep_in=dev->ep_in; - _old_device.ep_out=dev->ep_out; + _old_device[current_port].ep_in=dev->ep_in; + _old_device[current_port].ep_out=dev->ep_out; dev->configuration = ucd->bConfigurationValue; dev->interface = uid->bInterfaceNumber; - _old_device.interface=dev->interface; + _old_device[current_port].interface=dev->interface; dev->altInterface = uid->bAlternateSetting; goto found; @@ -1133,7 +1135,11 @@ usb_timeout=1000*1000; //USB_ClearHalt(dev->usb_fd, dev->ep_out); if(dev->buffer == NULL) - dev->buffer = (void *) ((((u32) USB_Alloc(MAX_TRANSFER_SIZE+32))+31) & ~31); + { + if(glob_buff==NULL) + glob_buff = (void *) ((((u32) USB_Alloc(MAX_TRANSFER_SIZE+32))+31) & ~31); + dev->buffer = glob_buff; + } if(dev->buffer == NULL) {retval = -ENOMEM;try_status=-1205;} else retval = USBSTORAGE_OK; @@ -1271,10 +1277,10 @@ s32 USBStorage_Inquiry(usbstorage_handle *dev, u8 lun) // info from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type case 5: // CDROM case 7: // optical memory device (e.g., some optical disks) - is_dvd=1; + is_dvd[current_port]=1; break; default: - is_dvd=0; + is_dvd[current_port]=0; break; } } @@ -1300,7 +1306,7 @@ s32 USBStorage_ReadCapacity(usbstorage_handle *dev, u8 lun, u32 *sector_size, u3 memcpy(&val, response + 4, 4); if(sector_size != NULL) *sector_size = be32_to_cpu(val); - if(be32_to_cpu(val)==2048)is_dvd=1; + //if(be32_to_cpu(val)==2048)is_dvd[current_port]=1; retval = USBSTORAGE_OK; } // USB_Free(response); @@ -1425,65 +1431,65 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) int maxLun,j,retval; int test_max_lun=1; - __vid=0; - __pid=0; - __mounted = 0; - __lun = 0; + __vid[current_port]=0; + __pid[current_port]=0; + __mounted[current_port] = 0; + __lun[current_port] = 0; try_status=-120; // swi_mload_led_on(); - if(USBStorage_Open(&__usbfd, fd) < 0) + if(USBStorage_Open(&__usbfd[current_port], fd) < 0) return -EINVAL; maxLun= 1; - __usbfd.max_lun = 1; + __usbfd[current_port].max_lun = 1; j=0; // fast re-mount - if(_old_device.mounted) + if(_old_device[current_port].mounted) { - if(_old_device.use_maxlun || (force_flags & 1)) + if(_old_device[current_port].use_maxlun || (force_flags & 1)) { - __usbfd.max_lun = 0; + __usbfd[current_port].max_lun = 0; usb_timeout=10000*1000; - retval = __USB_CtrlMsgTimeout(&__usbfd, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), - USBSTORAGE_GET_MAX_LUN, 0, __usbfd.interface, 1, &__usbfd.max_lun); + retval = __USB_CtrlMsgTimeout(&__usbfd[current_port], (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), + USBSTORAGE_GET_MAX_LUN, 0, __usbfd[current_port].interface, 1, &__usbfd[current_port].max_lun); usb_timeout=1000*1000; if(retval < 0) { - __usbfd.max_lun = 1; + __usbfd[current_port].max_lun = 1; goto bad_mount; } - else {__usbfd.max_lun++;} + else {__usbfd[current_port].max_lun++;} } - j=_old_device.lun; + j=_old_device[current_port].lun; #ifdef MEM_PRINT s_printf("Fast USBStorage_MountLUN %i#\n", j); #endif - retval = USBStorage_MountLUN(&__usbfd, j); + retval = USBStorage_MountLUN(&__usbfd[current_port], j); #ifdef MEM_PRINT s_printf("USBStorage_MountLUN: ret %i\n", retval); #endif if(retval == USBSTORAGE_ETIMEDOUT || retval==-ENODEV /*&& test_max_lun==0*/) { - USBStorage_Reset(&__usbfd); + USBStorage_Reset(&__usbfd[current_port]); try_status=-121; - __mounted = 0; - USBStorage_Close(&__usbfd); + __mounted[current_port] = 0; + USBStorage_Close(&__usbfd[current_port]); return -EINVAL; } if(retval < 0) goto bad_mount; - __mounted = 1; - __lun = j; + __mounted[current_port] = 1; + __lun[current_port] = j; usb_timeout=1000*1000; try_status=0; // swi_mload_led_off(); @@ -1491,7 +1497,7 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) return 0; } - _old_device.use_maxlun=0; + _old_device[current_port].use_maxlun=0; //for(j = 0; j < maxLun; j++) while(1) { @@ -1500,7 +1506,7 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) #ifdef MEM_PRINT s_printf("USBStorage_MountLUN %i#\n", j); #endif - retval = USBStorage_MountLUN(&__usbfd, j); + retval = USBStorage_MountLUN(&__usbfd[current_port], j); #ifdef MEM_PRINT s_printf("USBStorage_MountLUN: ret %i\n", retval); #endif @@ -1509,10 +1515,10 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) if((retval == USBSTORAGE_ETIMEDOUT || retval==-ENODEV) && j!=0) { usb_timeout=1000*1000; - USBStorage_Reset(&__usbfd); + USBStorage_Reset(&__usbfd[current_port]); try_status=-121; - __mounted = 0; - USBStorage_Close(&__usbfd); + __mounted[current_port]= 0; + USBStorage_Close(&__usbfd[current_port]); return -EINVAL; // break; } @@ -1524,18 +1530,18 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) { if(test_max_lun) { - unplug_device=0; - __usbfd.max_lun = 0; + unplug_device[current_port]=0; + __usbfd[current_port].max_lun = 0; usb_timeout=10000*1000; - retval = __USB_CtrlMsgTimeout(&__usbfd, + retval = __USB_CtrlMsgTimeout(&__usbfd[current_port], (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), - USBSTORAGE_GET_MAX_LUN, 0, __usbfd.interface, 1, &__usbfd.max_lun); + USBSTORAGE_GET_MAX_LUN, 0, __usbfd[current_port].interface, 1, &__usbfd[current_port].max_lun); usb_timeout=1000*1000; if(retval < 0 ) - {__usbfd.max_lun = 1;unplug_device=0;} - else {__usbfd.max_lun++;_old_device.use_maxlun=1;} - maxLun = __usbfd.max_lun; + {__usbfd[current_port].max_lun = 1;unplug_device[current_port]=0;} + else {__usbfd[current_port].max_lun++;_old_device[current_port].use_maxlun=1;} + maxLun = __usbfd[current_port].max_lun; #ifdef MEM_PRINT s_printf("USBSTORAGE_GET_MAX_LUN ret %i maxlun %i\n", retval,maxLun); @@ -1549,13 +1555,13 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) continue; } - _old_device.mounted=1; - _old_device.lun=j; + _old_device[current_port].mounted=1; + _old_device[current_port].lun=j; - __vid=fd->desc.idVendor; - __pid=fd->desc.idProduct; - __mounted = 1; - __lun = j; + __vid[current_port]=fd->desc.idVendor; + __pid[current_port]=fd->desc.idProduct; + __mounted[current_port] = 1; + __lun[current_port] = j; usb_timeout=1000*1000; try_status=0; // swi_mload_led_off(); @@ -1564,9 +1570,9 @@ s32 USBStorage_Try_Device(struct ehci_device *fd) bad_mount: try_status=-122; - USBStorage_Reset(&__usbfd); - __mounted = 0; - USBStorage_Close(&__usbfd); + USBStorage_Reset(&__usbfd[current_port]); + __mounted[current_port] = 0; + USBStorage_Close(&__usbfd[current_port]); #ifdef MEM_PRINT s_printf("USBStorage_MountLUN fail!!!\n"); @@ -1577,7 +1583,7 @@ bad_mount: void USBStorage_Umount(void) { -if(!ums_init_done) return; +if(!ums_init_done[current_port]) return; /* if(__mounted && !unplug_device) { @@ -1585,66 +1591,70 @@ if(!ums_init_done) return; ehci_msleep(1000); } */ - USBStorage_Close(&__usbfd);__lun= 16; - __mounted=0; - ums_init_done=0; - unplug_device=0; - memset(&_old_device,0,sizeof(_old_device)); + if(__mounted[current_port]) + { + USBStorage_Close(&__usbfd[current_port]);__lun[current_port]= 16; + __mounted[current_port]=0; + unplug_device[current_port]=0; + memset(&_old_device[current_port],0,sizeof(_old_device[current_port])); + } + + ums_init_done[current_port]=0; } -s32 USBStorage_Init(void) +s32 USBStorage_Init(int mode) { int i; u32 status; - int ret; + int ret[2]; int from=0,to=0; //debug_printf("usbstorage init %d\n", ums_init_done); - - if(ums_init_done) - return 0; - + if(mode==1)from=to=1; + else if(mode==2) + { + from=0; + to=1; + } + /* + for(i = from;i<=to; i++) + { + if(!ums_init_done[i]) break; + } + if(i==2)//already mounted + return 10; + */ ehci_writel (0, &ehci->regs->intr_enable); ehci_int_passive_callback(NULL); // interrupt port changes detection + //use_alternative_timeout=1; try_status=-100; - unplug_device=1; - __mounted=0; - use_alternative_timeout=1; + #ifdef MEM_PRINT s_printf("\n***************************************************\nRodries ehcmodule 1.0\nUSBStorage_Init()\n***************************************************\n\n"); #endif - -/*if(use_usb_port1!=0) - { - struct ehci_device *dev = &ehci->devices[0]; - - - dev->port=0; - dev->id=0; - ret=ehci_reset_port(0); - } -*/ - if(use_usb_port1==1)from=to=1; - else if(use_usb_port1==2) - { - from=0; - to=1; - } - //current_port=use_usb_port1!=0; - //for(i = use_usb_port1!=0;i<(1+(use_usb_port1!=0))/*ehci->num_port*/; i++){ + ret[0]=-1; + ret[1]=-1; + for(i = from;i<=to; i++){ struct ehci_device *dev = &ehci->devices[i]; + ums_init_done[i]=0; + unplug_device[i]=1; + __mounted[i]=0; + _old_device[i].mounted=0; + + + dev->port=i; current_port=i; @@ -1661,19 +1671,19 @@ s_printf("\n***************************************************\nRodries ehcmodu if(status & 1) { - ret=ehci_reset_port(i); - if(ret==-1119 || ret==-1120) + ret[i]=ehci_reset_port(i); + if(ret[i]==-1119 || ret[i]==-1120) { - try_status=ret; + try_status=ret[i]; try_status=-100; continue; } - ret=ehci_reset_port2(i); + ret[i]=ehci_reset_port2(i); ehci_msleep(20); status=ehci_readl(&ehci->regs->port_status[i]); - if(ret<0 || (status & 0x3905)!=0x1005) - ret=ehci_reset_port(i); + if(ret[i]<0 || (status & 0x3905)!=0x1005) + ret[i]=ehci_reset_port(i); } @@ -1681,7 +1691,7 @@ s_printf("\n***************************************************\nRodries ehcmodu } if(dev->id != 0) { - unplug_device=1; + unplug_device[current_port]=1; /* ret=ehci_reset_port(i); if(ret==-1119 || ret==-1120) @@ -1699,48 +1709,43 @@ s_printf("\n***************************************************\nRodries ehcmodu status=ehci_readl(&ehci->regs->port_status[i]); } */ - unplug_device=1; + unplug_device[current_port]=1; //if(ret>=0 && (status & 0x3105)==0x1005 ) // { - if(USBStorage_Try_Device(dev)==0) - { - ums_init_done = 1;unplug_device=0; - ehci_int_passive_callback(passive_callback_hand); // interrupt port changes detection - ehci_writel (STS_PCD, &ehci->regs->intr_enable); - + { + extern u8 mem_sector[4096]; + ums_init_done[current_port] = 1;unplug_device[current_port]=0; + + if(is_dvd[current_port]) s_printf("Device is a dvd\n"); + else s_printf("Device is a usbhd\n"); s_printf("USBStorage_Init() Ok\n"); ehci_msleep(100); - u8 *buf; - buf = (u8 *) USB_Alloc(2048); usb_timeout=10000*1000; extern bool enable_urb_debug; enable_urb_debug=true; - ehci_writel (0, &ehci->regs->intr_enable); - ehci_int_passive_callback(NULL); s_printf("Reading sector 0\n"); - ret=USBStorage_Read(&__usbfd, __lun, 0, 1, buf); - ehci_int_passive_callback(passive_callback_hand); - ehci_writel (STS_PCD, &ehci->regs->intr_enable); + ret[i]=USBStorage_Read(&__usbfd[current_port], __lun[current_port], 0, 1, mem_sector); enable_urb_debug=false; - usb_timeout=1000*1000; - USB_Free(buf); - if(ret<0) + usb_timeout=500*1000; + if(ret[i]<0) s_printf("Error Reading sector 0\n"); else s_printf("OK Reading sector 0\n"); - if(ret<0) + if(ret[i]<0) { ehci_release_port(i); - return -1118; + ret[i] = -1118; } - if(is_dvd) return i+2; // is DVD medium - return i; + else ret[i]=1; + //if(is_dvd) return i+2; // is DVD medium + //return i; + // 0 -> port0 1 -> port1 2 -> dvdport0 3 -> dvdport1 - } - else ehci_release_port(i); } + else ehci_release_port(i); + } // } /* else @@ -1784,19 +1789,27 @@ s_printf("\n***************************************************\nRodries ehcmodu ehci_int_passive_callback(passive_callback_hand); // interrupt port changes detection ehci_writel (STS_PCD, &ehci->regs->intr_enable); - + if(ret[0]==1) + { + try_status=0; + if(ret[1]==1) try_status=2; + } + else + { + if(ret[1]==1) try_status=1; + } return try_status; } u32 USBStorage_Get_Capacity(u32*sector_size) { if(sector_size) *sector_size = 0; - if(__mounted == 1 && __lun!=16) + if(__mounted[current_port]== 1 && __lun[current_port]!=16) { if(sector_size){ - *sector_size = __usbfd.sector_size[__lun]; + *sector_size = __usbfd[current_port].sector_size[__lun[current_port]]; } - return __usbfd.n_sector[__lun]; + return __usbfd[current_port].n_sector[__lun[current_port]]; } return 0; } @@ -1808,27 +1821,27 @@ int retval; //u8 conf=0; usb_devdesc udd; -if(!ums_init_done) return -1009; +if(!ums_init_done[current_port]) return -1009; // swi_mload_led_on(); retval=0; - __lun=16; + __lun[current_port]=16; if(use_alternative_timeout) usb_timeout=1000*1000; else usb_timeout=200*1000; udd.configurations=NULL; - retval = USB_GetDescriptors(__usbfd.usb_fd, &udd); + retval = USB_GetDescriptors(__usbfd[current_port].usb_fd, &udd); - if(_old_device.bDeviceClass!=udd.bDeviceClass || - _old_device.bDeviceSubClass!=udd.bDeviceSubClass || - _old_device.idVendor!=udd.idVendor || - _old_device.idProduct!=udd.idProduct || - _old_device.iManufacturer!=udd.iManufacturer || - _old_device.iProduct!=udd.iProduct || - _old_device.iSerialNumber!=udd.iSerialNumber) + if(_old_device[current_port].bDeviceClass!=udd.bDeviceClass || + _old_device[current_port].bDeviceSubClass!=udd.bDeviceSubClass || + _old_device[current_port].idVendor!=udd.idVendor || + _old_device[current_port].idProduct!=udd.idProduct || + _old_device[current_port].iManufacturer!=udd.iManufacturer || + _old_device[current_port].iProduct!=udd.iProduct || + _old_device[current_port].iSerialNumber!=udd.iSerialNumber) { USB_FreeDescriptors(&udd); @@ -1844,11 +1857,11 @@ if(!ums_init_done) return -1009; //if(USB_GetConfiguration(__usbfd.usb_fd, &conf) <0) return -1000; - usb_timeout=10000*1000; + usb_timeout=800*1000; - if(USB_SetConfiguration(__usbfd.usb_fd, __usbfd.configuration) < 0) return -1001; + if(USB_SetConfiguration(__usbfd[current_port].usb_fd, __usbfd[current_port].configuration) < 0) return -1001; - if(__usbfd.altInterface != 0 && USB_SetAlternativeInterface(__usbfd.usb_fd, __usbfd.interface, __usbfd.altInterface) < 0) return -1002; + if(__usbfd[current_port].altInterface != 0 && USB_SetAlternativeInterface(__usbfd[current_port].usb_fd, __usbfd[current_port].interface, __usbfd[current_port].altInterface) < 0) return -1002; /* if((conf != __usbfd.configuration || (force_flags & 2)) && USB_SetConfiguration(__usbfd.usb_fd, __usbfd.configuration) < 0) return -1001; @@ -1860,38 +1873,38 @@ if(!ums_init_done) return -1009; //if( __usbstorage_reset(&__usbfd,0)<0) return -1003; - usb_timeout=1000*1000; + //usb_timeout=1000*1000; //if(_old_device.use_maxlun || (force_flags & 1)) { - __usbfd.max_lun = 0; + __usbfd[current_port].max_lun = 0; - usb_timeout=10000*1000; - retval = __USB_CtrlMsgTimeout(&__usbfd, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), - USBSTORAGE_GET_MAX_LUN, 0, __usbfd.interface, 1, &__usbfd.max_lun); - usb_timeout=1000*1000; + //usb_timeout=10000*1000; + retval = __USB_CtrlMsgTimeout(&__usbfd[current_port], (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), + USBSTORAGE_GET_MAX_LUN, 0, __usbfd[current_port].interface, 1, &__usbfd[current_port].max_lun); + //usb_timeout=1000*1000; if(retval < 0) { - __usbfd.max_lun = 1; - __usbstorage_reset(&__usbfd,0); + __usbfd[current_port].max_lun = 1; + __usbstorage_reset(&__usbfd[current_port],0); return -1004; } - else {__usbfd.max_lun++;} + else {__usbfd[current_port].max_lun++;} } //retval = USBStorage_MountLUN(&__usbfd, _old_device.lun); - usb_timeout=20000*1000; - retval = __usbstorage_clearerrors(&__usbfd, _old_device.lun); + //usb_timeout=20000*1000; + retval = __usbstorage_clearerrors(&__usbfd[current_port], _old_device[current_port].lun); #ifdef MEM_PRINT // s_printf(" Clear error ret %i\n",retval); #endif - usb_timeout=1000*1000; + //usb_timeout=1000*1000; if(retval<0) return -1005; - retval = USBStorage_Inquiry(&__usbfd, _old_device.lun); + retval = USBStorage_Inquiry(&__usbfd[current_port], _old_device[current_port].lun); #ifdef MEM_PRINT // s_printf(" Inquiry ret %i\n",retval); #endif @@ -1899,8 +1912,8 @@ if(!ums_init_done) return -1009; if(retval<0) return -1006; - __lun=_old_device.lun; - __mounted=1; + __lun[current_port]=_old_device[current_port].lun; + __mounted[current_port]=1; return retval; @@ -1912,8 +1925,7 @@ int unplug_procedure(void) int retval=1; u32 status; -current_port=use_usb_port1!=0; - if(unplug_device!=0 ) + if(unplug_device[current_port]!=0 ) { // unplug detection method @@ -1957,7 +1969,7 @@ current_port=use_usb_port1!=0; #endif - unplug_device=1; + unplug_device[current_port]=1; if(ret>=0 && (status & 0x3105)==0x1005 ) { @@ -1966,12 +1978,12 @@ current_port=use_usb_port1!=0; /*if(__usbfd.buffer != NULL) USB_Free(__usbfd.buffer); __usbfd.buffer= NULL;*/ - __mounted=0;unplug_device=0; - USBStorage_Close(&__usbfd); + __mounted[current_port]=0;unplug_device[current_port]=0; + USBStorage_Close(&__usbfd[current_port]); retval=fast_remount(); - usb_timeout=1000*1000; + //usb_timeout=1000*1000; if(retval>=0) { #ifdef MEM_PRINT @@ -1981,18 +1993,18 @@ current_port=use_usb_port1!=0; #endif // swi_mload_led_off(); - retval=0;unplug_device=0;__mounted=1; + retval=0;unplug_device[current_port]=0;__mounted[current_port]=1; ehci_int_passive_callback(passive_callback_hand); // interrupt port changes detection ehci_writel (STS_PCD, &ehci->regs->intr_enable); } else { - unplug_device=1; + unplug_device[current_port]=1; #ifdef MEM_PRINT s_printf("fast_remount KO ret %i\n", ret); #endif - __mounted=0; + __mounted[current_port]=0; retval=1; //swi_mload_led_off(); ehci_msleep(100); @@ -2014,28 +2026,29 @@ int USBStorage_DVD_Test(void) int retval; - if(!ums_init_done) return 0; + if(!ums_init_done[current_port]) return 0; unplug_procedure(); - if(unplug_device!=0 || __mounted==0) return 0; + if(unplug_device[current_port]!=0 || __mounted[current_port]==0) return 0; // usb_timeout=1000*1000; // retval = __usbstorage_clearerrors(&__usbfd, _old_device.lun); // if(retval<0) return 0; - usb_timeout=1000*1000; - retval = USBStorage_Inquiry(&__usbfd, _old_device.lun); + //usb_timeout=1000*1000; + retval = USBStorage_Inquiry(&__usbfd[current_port], _old_device[current_port].lun); if(retval<0) return 0; - usb_timeout=1000*1000; - retval = USBStorage_ReadCapacity(&__usbfd, _old_device.lun, &__usbfd.sector_size[_old_device.lun], &__usbfd.n_sector[_old_device.lun]); + //usb_timeout=1000*1000; + retval = USBStorage_ReadCapacity(&__usbfd[current_port], _old_device[current_port].lun, + &__usbfd[current_port].sector_size[_old_device[current_port].lun], &__usbfd[current_port].n_sector[_old_device[current_port].lun]); if(retval<0) return 0; // sector size check for USB DVD mode (must be 2048 bytes) - if(retval>=0 && is_dvd) + if(retval>=0 && is_dvd[current_port]) { - if(__usbfd.sector_size[_old_device.lun]!=2048) return 0; + if(__usbfd[current_port].sector_size[_old_device[current_port].lun]!=2048) return 0; } - if(!is_dvd) return 0; + if(!is_dvd[current_port]) return 0; return 1; } @@ -2045,7 +2058,7 @@ int is_watchdog_read_sector=0; extern int test_mode; -extern int last_sector; +extern u32 last_sector; s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer) { @@ -2053,11 +2066,12 @@ s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer) int retry; - if(!is_watchdog_read_sector && is_dvd) last_sector=(int) (sector & 0x7fffffff);//return false; +// if(!is_watchdog_read_sector && is_dvd[current_port]) last_sector=(int) (sector & 0x7fffffff);//return false; + if(!is_watchdog_read_sector && is_dvd[current_port]) last_sector=sector;//return false; - if(test_mode && unplug_device>=2) + if(test_mode && unplug_device[current_port]>=2) { - unplug_device=1; + unplug_device[current_port]=1; return false; } @@ -2072,20 +2086,20 @@ s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer) retval=0; } - if(test_mode && unplug_device==3) break; + if(test_mode && unplug_device[current_port]==3) break; - if(retval<0 || __mounted != 1) + if(retval<0 || __mounted[current_port] != 1) { - unplug_device=1; + unplug_device[current_port]=1; retval=-1; } - if(unplug_device!=0 ) { continue;} + if(unplug_device[current_port]!=0 ) { continue;} - if(is_dvd) + if(is_dvd[current_port]) usb_timeout=10000*1000; else - usb_timeout=3000*1000; + usb_timeout=800*1000; if(retval >= 0) { @@ -2093,20 +2107,20 @@ s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer) ehci_int_passive_callback(NULL); ehci_writel (0, &ehci->regs->intr_enable); - retval = USBStorage_Read(&__usbfd, __lun, sector, numSectors, buffer); + retval = USBStorage_Read(&__usbfd[current_port], __lun[current_port], sector, numSectors, buffer); ehci_int_passive_callback(passive_callback_hand); ehci_writel (STS_PCD, &ehci->regs->intr_enable); } - usb_timeout=1000*1000; + usb_timeout=500*1000; - if(retval<0) unplug_device=1; + if(retval<0) unplug_device[current_port]=1; - if(test_mode && unplug_device!=0 ) {retval=-1;/*__mounted=0;*/break;} + if(test_mode && unplug_device[current_port]!=0 ) {retval=-1;/*__mounted[current_port]=0;*/break;} - if(unplug_device!=0 || __mounted != 1) continue; + if(unplug_device[current_port]!=0 || __mounted[current_port] != 1) continue; if(retval>=0) break; @@ -2122,7 +2136,7 @@ s32 USBStorage_Write_Sectors(u32 sector, u32 numSectors, const void *buffer) { s32 retval=0; - if(is_dvd) return false; // quieto!!! + if(is_dvd[current_port]) return false; // quieto!!! while(1) { @@ -2132,31 +2146,31 @@ s32 USBStorage_Write_Sectors(u32 sector, u32 numSectors, const void *buffer) retval=0; } - if(retval<0 || __mounted != 1) + if(retval<0 || __mounted[current_port] != 1) { - unplug_device=1; + unplug_device[current_port]=1; retval=-1; } - if(unplug_device!=0 ) continue; + if(unplug_device[current_port]!=0 ) continue; - usb_timeout=3000*1000; + usb_timeout=1000*1000; if(retval >=0) { ehci_writel (0, &ehci->regs->intr_enable); ehci_int_passive_callback(NULL); - retval = USBStorage_Write(&__usbfd, __lun, sector, numSectors, buffer); + retval = USBStorage_Write(&__usbfd[current_port], __lun[current_port], sector, numSectors, buffer); ehci_int_passive_callback(passive_callback_hand); ehci_writel (STS_PCD, &ehci->regs->intr_enable); } - usb_timeout=1000*1000; - if(retval<0) unplug_device=1; + usb_timeout=500*1000; + if(retval<0) unplug_device[current_port]=1; - if(unplug_device!=0 ) continue; + if(unplug_device[current_port]!=0 ) continue; if(retval>=0) break; } diff --git a/tinyehci/usbstorage.h b/tinyehci/usbstorage.h index 4ed87ddf..a626d173 100644 --- a/tinyehci/usbstorage.h +++ b/tinyehci/usbstorage.h @@ -46,7 +46,7 @@ typedef struct u8 *buffer; } usbstorage_handle; -s32 USBStorage_Init(void); +s32 USBStorage_Init(int mode); void USBStorage_Umount(void); s32 USBStorage_Open(usbstorage_handle *dev, struct ehci_device *fd);