mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-18 07:51:54 +01:00
*Added support for starting .wbfs game files from fat32/ntfs partitions on a sector size > 512 (tested with 4096)
*modified libcustomfat and ntfs fragment fetch function to support >512 bytes per sector *Added new ehcmodule (thanks rodries) *Added real support of using both ports simultaniously without shutting down the other (thanks rodries for the ehcmodule works on this). There is no longer the limitation that the settings have to be on SD card for this. (ONLY HERMES CIOS) *Moved a few settings to Feature Settings and added a new Hard Drive Settings *Changed Wiinnertag path to only point to the path and not to the file. You must correct the path manually in custom path settings or reset you configs for this change or Winnertag won't work!! *Removed a few compile warnings for devkitPPC R23
This commit is contained in:
parent
e510233154
commit
7210addaf2
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
Binary file not shown.
@ -1,441 +1,353 @@
|
||||
/************************************************************/
|
||||
/* USB speed test */
|
||||
/* */
|
||||
/* */
|
||||
/************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <sys/dir.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <fcntl.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include "mload.h"
|
||||
#include "../build/ehcmodule_elf.h"
|
||||
//#include "../build/fat_elf.h"
|
||||
data_elf my_data_elf;
|
||||
int my_thread_id = 0;
|
||||
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
#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<ogc/lwp_watchdog.h>
|
||||
//#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 <errno.h>
|
||||
|
||||
|
||||
#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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <sys/dir.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <fcntl.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
|
||||
#include "mload.h"
|
||||
#include "../build/ehcmodule_elf.h"
|
||||
//#include "../build/fat_elf.h"
|
||||
data_elf my_data_elf;
|
||||
int my_thread_id=0;
|
||||
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
#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<ogc/lwp_watchdog.h>
|
||||
//#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 <errno.h>
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
@ -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; 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; (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;
|
||||
}
|
||||
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#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
|
||||
|
344
test/source/usbstorage2.c
Normal file
344
test/source/usbstorage2.c
Normal file
@ -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 <gccore.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
};
|
31
test/source/usbstorage2.h
Normal file
31
test/source/usbstorage2.h
Normal file
@ -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
|
@ -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;i<ehci->num_port;i++)
|
||||
// {
|
||||
|
||||
i=use_usb_port1!=0;
|
||||
|
||||
for(i=0;i<ehci->num_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;i<ehci->num_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;i<ehci->num_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;i<ehci->num_port && j<maxdev ;i++)
|
||||
current_port=use_usb_port1!=0;
|
||||
i=current_port;
|
||||
|
||||
for(i=0;i<ehci->num_port && j<maxdev ;i++)
|
||||
{
|
||||
struct ehci_device *dev = &ehci->devices[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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user