11#include "irx_imports.h"
15IRX_ID(
"USB_module_loader", 2, 1);
31 char *m_driverargs[8];
38static int module_unload(
void);
39static int do_parse_config_file(
const char *fn);
40static void do_print_device_config_info(
USBDEV_t *devinfo);
41static int usbmload_drv_probe(
int dev_id);
42static int usbmload_drv_connect(
int dev_id);
43static int usbmload_drv_disconenct(
int dev_id);
44static void ldd_loader_thread(
void *userdata);
45static void default_loadfunc(sceUsbmlPopDevinfo pop_devinfo);
46static void do_push_device_rb(
USBDEV_t *devinfo);
47static USBDEV_t *is_rb_ok_callback(
void);
48static void do_clear_rb(
void);
49static int split_config_line(
char *curbuf,
int cursplitind,
char **dstptr);
50static int do_parse_cmd_int(
const char *buf);
51static void clean_config_line(
char *buf);
52static void sanitize_devicename(
char *buf);
53static void init_config_pos(
void);
54static char *read_config_line(
char *dstbuf,
int maxlen,
int fd);
62 &usbmload_drv_connect,
63 &usbmload_drv_disconenct,
71static int g_config_chr_pos;
72static int g_param_conffile[128];
73static char g_config_line_buf[256];
74static char g_config_device_name_tmp[256];
75static int g_param_debug;
76static int g_usbmload_enabled;
77static int g_param_rbsize;
78static int g_rb_offset_read;
79static int g_rb_offset_write;
82static USBDEV_t *g_usbm_entry_list_end;
83static USBDEV_t *g_usbm_entry_list_cur;
86static sceUsbmlLoadFunc g_loadfunc_cb;
87static char g_config_chr_buf[2048];
89int _start(
int ac,
char *av[],
void *startaddr,
ModuleInfo_t *mi)
102 return module_unload();
103 printf(
"----- USB auto module loader %s -----\n",
"0.4.0");
105 g_loadfunc_cb = default_loadfunc;
107 g_usbmload_enabled = 0;
108 g_rb_offset_read = 0;
109 g_rb_offset_write = 0;
111 g_usbm_entry_list_end = 0;
112 g_usbm_entry_list_cur = 0;
113 for ( i = 1; i < ac; i += 1 )
115 for ( j = 0; av[i][j] && av[i][j] !=
'='; j += 1 )
122 if ( !strcmp(av[i],
"conffile") )
124 if ( (
unsigned int)strlen(&(av[i])[j]) < 0x200 )
126 strcpy((
char *)g_param_conffile, &(av[i])[j]);
128 if ( g_param_debug > 0 )
129 printf(
"conffile=%s\n", g_param_conffile);
133 printf(
"Too long file name : %s\n", &(av[i])[j]);
136 else if ( !strcmp(av[i],
"debug") )
138 g_param_debug = do_parse_cmd_int(&(av[i])[j]);
139 printf(
"Debug level is %d\n", g_param_debug);
141 else if ( !strcmp(av[i],
"rbsize") )
143 g_param_rbsize = do_parse_cmd_int(&(av[i])[j]);
144 g_param_rbsize = (g_param_rbsize > 256) ? 256 : g_param_rbsize;
145 g_param_rbsize = (g_param_rbsize < 8) ? 8 : g_param_rbsize;
146 if ( g_param_debug > 0 )
147 printf(
"usbmload : ring buffer size = %d\n", g_param_rbsize);
150 if ( g_param_debug > 0 )
151 printf(
"allocsize(for ring buffer) : %d\n", (
int)(
sizeof(
USBDEV_t *) * g_param_rbsize));
153 g_rb_entries = (
USBDEV_t **)AllocSysMemory(0,
sizeof(
USBDEV_t *) * g_param_rbsize, 0);
157 printf(
"Ring buffer Initialize Error!!\n");
158 return MODULE_NO_RESIDENT_END;
160 if ( RegisterLibraryEntries(&_exp_usbmload) )
161 return MODULE_NO_RESIDENT_END;
162 if ( has_conffile == 1 )
164 if ( do_parse_config_file((
const char *)g_param_conffile) == -1 )
166 printf(
"usbmload : load_config NG\n");
170 if ( g_param_debug > 0 )
171 printf(
"usbmload : load_config OK\n");
174 memset(&efparam, 0,
sizeof(efparam));
175 g_ef = CreateEventFlag(&efparam);
178 printf(
"usbmload : CreateEventFlag NG\n");
179 return MODULE_NO_RESIDENT_END;
182 thparam.thread = ldd_loader_thread;
183 thparam.priority = 88;
184 thparam.stacksize = 4096;
186 thid1 = CreateThread(&thparam);
189 printf(
"usbmload : CreateThread NG\n");
190 DeleteEventFlag(g_ef);
191 return MODULE_NO_RESIDENT_END;
193 if ( g_param_debug > 0 )
194 printf(
"usbmload : CreateThread ID = %d\n", thid1);
195 StartThread(thid1, 0);
198 return MODULE_REMOVABLE_END;
200 if ( mi && ((mi->
newflags & 2) != 0) )
202 return MODULE_RESIDENT_END;
206static int module_unload(
void)
213 if ( ReleaseLibraryEntries(&_exp_usbmload) )
215 return MODULE_REMOVABLE_END;
218 TerminateThread(g_thid);
219 DeleteThread(g_thid);
220 DeleteEventFlag(g_ef);
221 listent_1 = g_usbm_entry_list_end;
226 if ( StopModule(listent_1->modid, 0, 0, &stopres) >= 0 )
228 if ( g_param_debug > 0 )
229 printf(
"usbmload : Unload LDD module (%xh)\n", listent_1->modid);
230 UnloadModule(listent_1->modid);
233 for ( i = 0; i < listent_1->argc; i += 1 )
235 FreeSysMemory(listent_1->argv[i]);
237 FreeSysMemory(listent_1->dispname);
238 FreeSysMemory(listent_1->category);
239 FreeSysMemory(listent_1->path);
240 listent_3 = listent_1;
241 listent_1 = listent_1->forw;
242 FreeSysMemory(listent_3);
246 FreeSysMemory(g_rb_entries);
248 return MODULE_NO_RESIDENT_END;
251static int do_parse_config_file(
const char *fn)
265 if ( g_param_debug > 0 )
266 printf(
"open '%s'\n", fn);
271 printf(
"Cannot open '%s'\n", fn);
274 while ( read_config_line(g_config_line_buf,
sizeof(g_config_line_buf), fd) )
279 if ( g_param_debug >= 2 )
281 strcpy(g_config_device_name_tmp, g_config_line_buf);
282 sanitize_devicename(g_config_device_name_tmp);
283 printf(
"%4d : %s\n", lineind, g_config_device_name_tmp);
285 clean_config_line(g_config_line_buf);
286 tokencnt = split_config_line(g_config_line_buf, 3, p);
289 if ( !strcmp(p[0],
"end") )
293 if ( !strcmp(p[0],
"DeviceName") )
297 if ( g_usbm_entry_list_cur )
298 g_usbm_entry_list_cur->forw = devstr;
300 g_usbm_entry_list_end = devstr;
302 g_usbm_entry_list_cur = devstr;
303 if ( g_param_debug > 0 )
305 printf(
"Resistered\n");
306 do_print_device_config_info(devstr);
318 devstr->dispname = (
char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
320 if ( !devstr->dispname )
325 strcpy(devstr->dispname, p[1]);
327 devstr->product = -1;
328 devstr->release = -1;
330 devstr->subclass = -1;
331 devstr->protocol = -1;
332 devstr->category = 0;
335 devstr->activate_flag = 0;
337 devstr->modname[0] = 0;
338 devstr->load_result = -1;
340 else if ( !strcmp(p[0],
"Use") )
343 if ( strcmp(p[1],
"1") )
345 if ( g_param_debug > 0 )
347 sanitize_devicename(devstr->dispname);
348 printf(
"Disable '%s'\n", devstr->dispname);
351 if ( devstr->dispname )
354 FreeSysMemory(devstr->dispname);
356 devstr->dispname = 0;
361 FreeSysMemory(devstr);
367 else if ( has_encountered )
369 if ( !strcmp(p[0],
"Vendor") )
371 devstr->vendor = do_parse_cmd_int(p[1]);
373 else if ( !strcmp(p[0],
"Product") )
375 devstr->product = do_parse_cmd_int(p[1]);
377 else if ( !strcmp(p[0],
"Release") )
379 devstr->release = do_parse_cmd_int(p[1]);
381 else if ( !strcmp(p[0],
"Class") )
383 devstr->class_ = do_parse_cmd_int(p[1]);
385 else if ( !strcmp(p[0],
"SubClass") )
387 devstr->subclass = do_parse_cmd_int(p[1]);
389 else if ( !strcmp(p[0],
"Protocol") )
391 devstr->protocol = do_parse_cmd_int(p[1]);
393 else if ( !strcmp(p[0],
"Category") )
395 if ( devstr->category )
398 FreeSysMemory(devstr->category);
400 devstr->category = 0;
403 devstr->category = (
char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
405 if ( !devstr->category )
410 strcpy(devstr->category, p[1]);
412 else if ( !strcmp(p[0],
"DriverPath") )
417 FreeSysMemory(devstr->path);
422 devstr->path = (
char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
429 strcpy(devstr->path, p[1]);
431 else if ( !strcmp(p[0],
"DriverArg") && devstr->argc < 8 )
434 devstr->argv[devstr->argc] = (
char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
436 if ( !devstr->argv[devstr->argc] )
441 strcpy(devstr->argv[devstr->argc], p[1]);
446 if ( g_param_debug > 0 )
447 printf(
"%s : %d : Illegal parameter '%s'\n", fn, lineind, p[0]);
455 printf(
"%s : %d : malloc error\n", fn, lineind);
461 if ( g_usbm_entry_list_cur )
462 g_usbm_entry_list_cur->forw = devstr;
464 g_usbm_entry_list_end = devstr;
466 g_usbm_entry_list_cur = devstr;
467 if ( g_param_debug > 0 )
469 printf(
"Resistered\n");
470 do_print_device_config_info(devstr);
477static void do_print_device_config_info(
USBDEV_t *devinfo)
480 char dispname_tmp[256];
482 strcpy(dispname_tmp, devinfo->dispname);
483 sanitize_devicename(dispname_tmp);
484 printf(
" DeviceName:%s\n", dispname_tmp);
485 printf(
" Vendor :%04X\n", devinfo->vendor);
486 printf(
" Product :%04X\n", devinfo->product);
487 printf(
" Release :%04X\n", devinfo->release);
488 printf(
" Class :%02X\n", devinfo->class_);
489 printf(
" SubClass :%02X\n", devinfo->subclass);
490 printf(
" Protocol :%02X\n", devinfo->protocol);
491 printf(
" Category :%s\n", devinfo->category);
492 printf(
" DriverPath:%s\n", devinfo->path);
493 for ( i = 0; i < devinfo->argc; i += 1 )
495 printf(
" DriverArg%d:%s\n", i, devinfo->argv[i]);
500static int usbmload_drv_probe(
int dev_id)
504 int found_info_count;
507 if ( g_param_debug > 0 )
508 printf(
"Call usbmload_probe\n");
515 found_info_count = 0;
516 if ( !g_usbm_entry_list_end )
518 if ( g_param_debug > 0 )
519 printf(
"usbmload : Not registered\n");
522 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
525 devinfo->activate_flag && (devinfo->vendor == devdesc->idVendor || devinfo->vendor == -1)
526 && (devinfo->product == devdesc->idProduct || devinfo->product == -1)
527 && (devinfo->release == devdesc->bcdUSB || devinfo->release == -1)
528 && (devinfo->class_ == intfdesc->bInterfaceClass || devinfo->class_ == -1)
529 && (devinfo->protocol == intfdesc->bInterfaceProtocol || devinfo->protocol == -1)
530 && (devinfo->subclass == intfdesc->bInterfaceSubClass || devinfo->subclass == -1) )
532 if ( g_param_debug > 0 )
533 printf(
"push_devinfo : %s\n", devinfo->path);
534 do_push_device_rb(devinfo);
535 found_info_count += 1;
538 if ( found_info_count )
540 if ( g_param_debug > 0 )
541 printf(
"SetEventFlag\n");
542 SetEventFlag(g_ef, 1u);
547static int usbmload_drv_connect(
int dev_id)
554static int usbmload_drv_disconenct(
int dev_id)
561static void ldd_loader_thread(
void *userdata)
568 WaitEventFlag(g_ef, 1u, WEF_OR | WEF_CLEAR, &efres);
569 if ( g_param_debug > 0 )
570 printf(
"ldd_loader_thread : get event!\n");
571 g_loadfunc_cb(is_rb_ok_callback);
576static void default_loadfunc(sceUsbmlPopDevinfo pop_devinfo)
580 unsigned int cur_argv_len;
581 unsigned int cur_argv_len_1;
587 if ( g_param_debug > 0 )
588 printf(
"Entering default_loadfunc()\n");
593 curdev = pop_devinfo();
596 if ( curdev->modid < 0 || ReferModuleStatus(modid, &modstat) || strcmp(modstat.name, curdev->modname) )
598 if ( g_param_debug > 0 )
600 do_print_device_config_info(curdev);
603 for ( i = 0; i < curdev->argc; i += 1 )
605 cur_argv_len_1 = cur_argv_len + strlen(curdev->argv[i]) + 1;
606 if ( cur_argv_len_1 > (
int)(
sizeof(modarg) - 16) )
608 cur_argv_len = cur_argv_len_1;
609 strcpy(&modarg[cur_argv_len], curdev->argv[i]);
611 strcpy(&modarg[cur_argv_len],
"lmode=AUTOLOAD");
612 if ( g_param_debug > 0 )
613 printf(
"LoadStartModule : %s\n", curdev->path);
614 modid = LoadStartModule(curdev->path, cur_argv_len + strlen(
"lmode=AUTOLOAD") + 1, modarg, &modres);
615 if ( g_param_debug > 0 )
616 printf(
"LoadStartModule done: %d\n", modid);
619 curdev->modid = modid;
620 curdev->load_result = modres;
621 ReferModuleStatus(modid, &modstat);
622 strcpy(curdev->modname, modstat.name);
628static void do_push_device_rb(
USBDEV_t *devinfo)
633 if ( g_rb_count < g_param_rbsize )
635 g_rb_entries[g_rb_offset_write] = devinfo;
636 g_rb_offset_write += 1;
637 if ( g_rb_offset_write >= g_param_rbsize )
638 g_rb_offset_write = 0;
644static USBDEV_t *is_rb_ok_callback(
void)
653 devinfo = g_rb_entries[g_rb_offset_read];
654 g_rb_offset_read += 1;
655 if ( g_rb_offset_read >= g_param_rbsize )
656 g_rb_offset_read = 0;
663static void do_clear_rb(
void)
672static int split_config_line(
char *curbuf,
int cursplitind,
char **dstptr)
683 if ( cursplitind <= 0 || !strlen(curbuf) )
686 while ( splitfound != cursplitind )
688 for ( i = 0; curbuf_1[i] ==
' ' || curbuf_1[i] ==
'\t'; i += 1 )
691 if ( !curbuf_1[i] || curbuf_1[i] ==
'\r' || curbuf_1[i] ==
'\n' )
696 *dstptr_1 = curbuf_2;
698 if ( curbuf_1[i] !=
'"' )
700 for ( ; curbuf_1[i] && curbuf_1[i] !=
'\r' && curbuf_1[i] !=
'\n' && curbuf_1[i] !=
' ' && curbuf_1[i] !=
'\t';
710 *dstptr_1 = curbuf_2;
716 for ( ; curbuf_1[i] && curbuf_1[i] !=
'\r' && curbuf_1[i] !=
'\n' && curbuf_1[i] !=
'"'; i += 1 )
722 if ( !curbuf_1[i] || curbuf_1[i] ==
'\r' || curbuf_1[i] ==
'\n' )
734static int do_parse_cmd_int(
const char *buf)
742 if ( *buf !=
'0' || buf[1] !=
'x' )
743 return strtol(buf, 0, 10);
744 for ( i = buf + 2; *i; i += 1 )
746 hexval = (16 * hexval) + (*i & 0xF) + ((*i >=
':') ? 9 : 0);
751static void clean_config_line(
char *buf)
756 for ( ; *buf !=
'\n' && *buf !=
'\r' && *buf; buf += 1 )
759 in_quotes = !in_quotes;
760 if ( *buf ==
'#' && !in_quotes )
766static void sanitize_devicename(
char *buf)
768 while ( *buf && *buf !=
'\n' && *buf !=
'\r' )
770 unsigned int curchr_2;
771 unsigned int curchr_3;
773 curchr_2 = (u8)buf[0];
774 curchr_3 = (u8)buf[1];
776 curchr_2 < 0x80 || (
char)curchr_2 - 0xA0 < 0x40 || (
char)curchr_2 - 0xF0 < 0x10 || curchr_3 < 0x40
777 || curchr_3 == 0x7F || curchr_3 - 0xFD < 3 )
783 if ( curchr_3 >= 0x9F )
785 buf[0] = curchr_2 >= 0xA0 ? 2 * curchr_2 + 32 : 2 * curchr_2 -
'`';
786 buf[1] = curchr_3 + 2;
790 if ( curchr_3 >= 0x80 )
791 curchr_3 = curchr_3 - 1;
792 buf[0] = curchr_2 >= 0xA0 ? 2 * curchr_2 + 31 : 2 * curchr_2 -
'a';
793 buf[1] = curchr_3 +
'a';
800int sceUsbmlDisable(
void)
804 unregres = sceUsbdUnregisterAutoloader();
807 printf(
"sceUsbmlDisable:Error(0x%X)\n", unregres);
810 g_usbmload_enabled = 0;
814int sceUsbmlEnable(
void)
818 sceUsbdUnregisterAutoloader();
819 regres = sceUsbdRegisterAutoloader(&g_usbmload_drv);
822 printf(
"sceUsbmlEnable:Error(0x%X)\n", regres);
825 g_usbmload_enabled = 1;
829int sceUsbmlActivateCategory(
const char *category)
835 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
837 if ( !strcmp(devinfo->category, category) )
839 devinfo->activate_flag = 1;
843 if ( g_usbmload_enabled == 1 )
848int sceUsbmlInactivateCategory(
const char *category)
854 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
856 if ( !strcmp(devinfo->category, category) )
858 devinfo->activate_flag = 0;
862 if ( g_usbmload_enabled == 1 )
867int sceUsbmlRegisterLoadFunc(sceUsbmlLoadFunc loadfunc)
869 if ( g_loadfunc_cb == default_loadfunc )
871 g_loadfunc_cb = loadfunc;
877void sceUsbmlUnregisterLoadFunc(
void)
879 g_loadfunc_cb = default_loadfunc;
882int sceUsbmlLoadConffile(
const char *conffile)
884 return do_parse_config_file(conffile);
887int sceUsbmlRegisterDevice(
USBDEV_t *device)
905 memcpy(devinfo, device,
sizeof(
USBDEV_t));
907 devinfo->dispname = (
char *)AllocSysMemory(0, strlen(device->dispname) + 1, 0);
909 if ( !devinfo->dispname )
916 strcpy(devinfo->dispname, device->dispname);
918 devinfo->path = (
char *)AllocSysMemory(0, strlen(device->path) + 1, 0);
920 if ( !devinfo->path )
927 strcpy(devinfo->path, device->path);
928 for ( i = 0; i < device->argc; i += 1 )
931 devinfo->argv[i] = (
char *)AllocSysMemory(0, strlen(device->argv[i]) + 1, 0);
933 if ( !devinfo->argv[i] )
938 strcpy(devinfo->argv[i], device->argv[i]);
943 printf(
"sceUsbmlRegisterDevice : malloc error%d\n", failed);
950 for ( j = 0; j < i; j += 1 )
952 FreeSysMemory(devinfo->argv[j]);
954 FreeSysMemory(devinfo->path);
958 FreeSysMemory(devinfo->dispname);
962 FreeSysMemory(devinfo);
967 if ( g_usbm_entry_list_cur )
968 g_usbm_entry_list_cur->forw = devinfo;
970 g_usbm_entry_list_end = devinfo;
972 g_usbm_entry_list_cur = devinfo;
976int sceUsbmlChangeThreadPriority(
int prio1)
978 return ChangeThreadPriority(g_thid, prio1) ? -1 : 0;
981static void init_config_pos(
void)
983 g_config_chr_pos =
sizeof(g_config_chr_buf);
986static char read_config_byte(
int fd)
990 if ( g_config_chr_pos ==
sizeof(g_config_chr_buf) )
992 read(fd, g_config_chr_buf,
sizeof(g_config_chr_buf));
993 g_config_chr_pos = 0;
995 tmpret = g_config_chr_buf[g_config_chr_pos];
996 g_config_chr_pos += 1;
1000static char *read_config_line(
char *dstbuf,
int maxlen,
int fd)
1004 for ( i = 0; i < maxlen; i += 1 )
1006 dstbuf[i] = read_config_byte(fd);
1007 if ( dstbuf[i] ==
'\n' )
1009 dstbuf[i] = dstbuf[i] ==
'\r' ? 0 : dstbuf[i];
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)