PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
usbmload.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12#include <usbmload.h>
13
14#ifdef _IOP
15IRX_ID("USB_module_loader", 2, 1);
16#endif
17// Based on the module from SCE SDK 3.1.0.
18
20{
21 struct usbm_load_entry *m_next;
22 char *m_devicename;
23 int m_vendor;
24 int m_product;
25 int m_release;
26 int m_class;
27 int m_subclass;
28 int m_protocol;
29 char *m_category;
30 char *m_driverpath;
31 char *m_driverargs[8];
32 int m_driverargs_len;
33 int m_pad1[1];
34 int m_ldd_module_id;
35 int m_pad2[15];
36};
37
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);
55
56extern struct irx_export_table _exp_usbmload;
57static sceUsbdLddOps g_usbmload_drv = {
58 NULL,
59 NULL,
60 "usbmload",
61 &usbmload_drv_probe,
62 &usbmload_drv_connect,
63 &usbmload_drv_disconenct,
64 0u,
65 0u,
66 0u,
67 0u,
68 0u,
69 NULL};
70// Unofficial: move to bss
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;
80static int g_rb_count;
81static USBDEV_t **g_rb_entries;
82static USBDEV_t *g_usbm_entry_list_end;
83static USBDEV_t *g_usbm_entry_list_cur;
84static int g_ef;
85static int g_thid;
86static sceUsbmlLoadFunc g_loadfunc_cb;
87static char g_config_chr_buf[2048];
88
89int _start(int ac, char *av[], void *startaddr, ModuleInfo_t *mi)
90{
91 int has_conffile;
92 int i;
93 int j;
94 int thid1;
95 iop_event_t efparam;
96 iop_thread_t thparam;
97 int state;
98
99 (void)startaddr;
100 has_conffile = 0;
101 if ( ac < 0 )
102 return module_unload();
103 printf("----- USB auto module loader %s -----\n", "0.4.0");
104 g_param_rbsize = 32;
105 g_loadfunc_cb = default_loadfunc;
106 g_param_debug = 0;
107 g_usbmload_enabled = 0;
108 g_rb_offset_read = 0;
109 g_rb_offset_write = 0;
110 g_rb_count = 0;
111 g_usbm_entry_list_end = 0;
112 g_usbm_entry_list_cur = 0;
113 for ( i = 1; i < ac; i += 1 )
114 {
115 for ( j = 0; av[i][j] && av[i][j] != '='; j += 1 )
116 ;
117 if ( av[i][j] )
118 {
119 av[i][j] = 0;
120 j += 1;
121 }
122 if ( !strcmp(av[i], "conffile") )
123 {
124 if ( (unsigned int)strlen(&(av[i])[j]) < 0x200 )
125 {
126 strcpy((char *)g_param_conffile, &(av[i])[j]);
127 has_conffile = 1;
128 if ( g_param_debug > 0 )
129 printf("conffile=%s\n", g_param_conffile);
130 }
131 else
132 {
133 printf("Too long file name : %s\n", &(av[i])[j]);
134 }
135 }
136 else if ( !strcmp(av[i], "debug") )
137 {
138 g_param_debug = do_parse_cmd_int(&(av[i])[j]);
139 printf("Debug level is %d\n", g_param_debug);
140 }
141 else if ( !strcmp(av[i], "rbsize") )
142 {
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);
148 }
149 }
150 if ( g_param_debug > 0 )
151 printf("allocsize(for ring buffer) : %d\n", (int)(sizeof(USBDEV_t *) * g_param_rbsize));
152 CpuSuspendIntr(&state);
153 g_rb_entries = (USBDEV_t **)AllocSysMemory(0, sizeof(USBDEV_t *) * g_param_rbsize, 0);
154 CpuResumeIntr(state);
155 if ( !g_rb_entries )
156 {
157 printf("Ring buffer Initialize Error!!\n");
158 return MODULE_NO_RESIDENT_END;
159 }
160 if ( RegisterLibraryEntries(&_exp_usbmload) )
161 return MODULE_NO_RESIDENT_END;
162 if ( has_conffile == 1 )
163 {
164 if ( do_parse_config_file((const char *)g_param_conffile) == -1 )
165 {
166 printf("usbmload : load_config NG\n");
167 }
168 else
169 {
170 if ( g_param_debug > 0 )
171 printf("usbmload : load_config OK\n");
172 }
173 }
174 memset(&efparam, 0, sizeof(efparam));
175 g_ef = CreateEventFlag(&efparam);
176 if ( g_ef < 0 )
177 {
178 printf("usbmload : CreateEventFlag NG\n");
179 return MODULE_NO_RESIDENT_END;
180 }
181 thparam.attr = TH_C;
182 thparam.thread = ldd_loader_thread;
183 thparam.priority = 88;
184 thparam.stacksize = 4096;
185 thparam.option = 0;
186 thid1 = CreateThread(&thparam);
187 if ( thid1 <= 0 )
188 {
189 printf("usbmload : CreateThread NG\n");
190 DeleteEventFlag(g_ef);
191 return MODULE_NO_RESIDENT_END;
192 }
193 if ( g_param_debug > 0 )
194 printf("usbmload : CreateThread ID = %d\n", thid1);
195 StartThread(thid1, 0);
196 g_thid = thid1;
197#if 0
198 return MODULE_REMOVABLE_END;
199#else
200 if ( mi && ((mi->newflags & 2) != 0) )
201 mi->newflags |= 0x10;
202 return MODULE_RESIDENT_END;
203#endif
204}
205
206static int module_unload(void)
207{
208 USBDEV_t *listent_1;
209 int i;
210 int stopres;
211 int state;
212
213 if ( ReleaseLibraryEntries(&_exp_usbmload) )
214 {
215 return MODULE_REMOVABLE_END;
216 }
217 sceUsbmlDisable();
218 TerminateThread(g_thid);
219 DeleteThread(g_thid);
220 DeleteEventFlag(g_ef);
221 listent_1 = g_usbm_entry_list_end;
222 while ( listent_1 )
223 {
224 USBDEV_t *listent_3;
225
226 if ( StopModule(listent_1->modid, 0, 0, &stopres) >= 0 )
227 {
228 if ( g_param_debug > 0 )
229 printf("usbmload : Unload LDD module (%xh)\n", listent_1->modid);
230 UnloadModule(listent_1->modid);
231 }
232 CpuSuspendIntr(&state);
233 for ( i = 0; i < listent_1->argc; i += 1 )
234 {
235 FreeSysMemory(listent_1->argv[i]);
236 }
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);
243 CpuResumeIntr(state);
244 }
245 CpuSuspendIntr(&state);
246 FreeSysMemory(g_rb_entries);
247 CpuResumeIntr(state);
248 return MODULE_NO_RESIDENT_END;
249}
250
251static int do_parse_config_file(const char *fn)
252{
253 USBDEV_t *devstr;
254 int has_encountered;
255 int fd;
256 int lineind;
257 char *p[2];
258 int state;
259 int err;
260
261 err = 0;
262 devstr = 0;
263 init_config_pos();
264 has_encountered = 0;
265 if ( g_param_debug > 0 )
266 printf("open '%s'\n", fn);
267 fd = open(fn, 1);
268 lineind = 0;
269 if ( fd < 0 )
270 {
271 printf("Cannot open '%s'\n", fn);
272 return -1;
273 }
274 while ( read_config_line(g_config_line_buf, sizeof(g_config_line_buf), fd) )
275 {
276 int tokencnt;
277
278 lineind += 1;
279 if ( g_param_debug >= 2 )
280 {
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);
284 }
285 clean_config_line(g_config_line_buf);
286 tokencnt = split_config_line(g_config_line_buf, 3, p);
287 if ( tokencnt )
288 {
289 if ( !strcmp(p[0], "end") )
290 break;
291 if ( tokencnt >= 2 )
292 {
293 if ( !strcmp(p[0], "DeviceName") )
294 {
295 if ( devstr )
296 {
297 if ( g_usbm_entry_list_cur )
298 g_usbm_entry_list_cur->forw = devstr;
299 else
300 g_usbm_entry_list_end = devstr;
301 devstr->forw = 0;
302 g_usbm_entry_list_cur = devstr;
303 if ( g_param_debug > 0 )
304 {
305 printf("Resistered\n");
306 do_print_device_config_info(devstr);
307 }
308 }
309 CpuSuspendIntr(&state);
310 devstr = (USBDEV_t *)AllocSysMemory(0, sizeof(USBDEV_t), 0);
311 CpuResumeIntr(state);
312 if ( !devstr )
313 {
314 err = 1;
315 break;
316 }
317 CpuSuspendIntr(&state);
318 devstr->dispname = (char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
319 CpuResumeIntr(state);
320 if ( !devstr->dispname )
321 {
322 err = 1;
323 break;
324 }
325 strcpy(devstr->dispname, p[1]);
326 devstr->vendor = -1;
327 devstr->product = -1;
328 devstr->release = -1;
329 devstr->class_ = -1;
330 devstr->subclass = -1;
331 devstr->protocol = -1;
332 devstr->category = 0;
333 devstr->path = 0;
334 devstr->argc = 0;
335 devstr->activate_flag = 0;
336 devstr->modid = -1;
337 devstr->modname[0] = 0;
338 devstr->load_result = -1;
339 }
340 else if ( !strcmp(p[0], "Use") )
341 {
342 has_encountered = 1;
343 if ( strcmp(p[1], "1") )
344 {
345 if ( g_param_debug > 0 )
346 {
347 sanitize_devicename(devstr->dispname);
348 printf("Disable '%s'\n", devstr->dispname);
349 }
350 has_encountered = 0;
351 if ( devstr->dispname )
352 {
353 CpuSuspendIntr(&state);
354 FreeSysMemory(devstr->dispname);
355 CpuResumeIntr(state);
356 devstr->dispname = 0;
357 }
358 if ( devstr )
359 {
360 CpuSuspendIntr(&state);
361 FreeSysMemory(devstr);
362 devstr = 0;
363 CpuResumeIntr(state);
364 }
365 }
366 }
367 else if ( has_encountered )
368 {
369 if ( !strcmp(p[0], "Vendor") )
370 {
371 devstr->vendor = do_parse_cmd_int(p[1]);
372 }
373 else if ( !strcmp(p[0], "Product") )
374 {
375 devstr->product = do_parse_cmd_int(p[1]);
376 }
377 else if ( !strcmp(p[0], "Release") )
378 {
379 devstr->release = do_parse_cmd_int(p[1]);
380 }
381 else if ( !strcmp(p[0], "Class") )
382 {
383 devstr->class_ = do_parse_cmd_int(p[1]);
384 }
385 else if ( !strcmp(p[0], "SubClass") )
386 {
387 devstr->subclass = do_parse_cmd_int(p[1]);
388 }
389 else if ( !strcmp(p[0], "Protocol") )
390 {
391 devstr->protocol = do_parse_cmd_int(p[1]);
392 }
393 else if ( !strcmp(p[0], "Category") )
394 {
395 if ( devstr->category )
396 {
397 CpuSuspendIntr(&state);
398 FreeSysMemory(devstr->category);
399 CpuResumeIntr(state);
400 devstr->category = 0;
401 }
402 CpuSuspendIntr(&state);
403 devstr->category = (char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
404 CpuResumeIntr(state);
405 if ( !devstr->category )
406 {
407 err = 1;
408 break;
409 }
410 strcpy(devstr->category, p[1]);
411 }
412 else if ( !strcmp(p[0], "DriverPath") )
413 {
414 if ( devstr->path )
415 {
416 CpuSuspendIntr(&state);
417 FreeSysMemory(devstr->path);
418 CpuResumeIntr(state);
419 devstr->path = 0;
420 }
421 CpuSuspendIntr(&state);
422 devstr->path = (char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
423 CpuResumeIntr(state);
424 if ( !devstr->path )
425 {
426 err = 1;
427 break;
428 }
429 strcpy(devstr->path, p[1]);
430 }
431 else if ( !strcmp(p[0], "DriverArg") && devstr->argc < 8 )
432 {
433 CpuSuspendIntr(&state);
434 devstr->argv[devstr->argc] = (char *)AllocSysMemory(0, strlen(p[1]) + 1, 0);
435 CpuResumeIntr(state);
436 if ( !devstr->argv[devstr->argc] )
437 {
438 err = 1;
439 break;
440 }
441 strcpy(devstr->argv[devstr->argc], p[1]);
442 devstr->argc += 1;
443 }
444 else
445 {
446 if ( g_param_debug > 0 )
447 printf("%s : %d : Illegal parameter '%s'\n", fn, lineind, p[0]);
448 }
449 }
450 }
451 }
452 }
453 if ( err )
454 {
455 printf("%s : %d : malloc error\n", fn, lineind);
456 close(fd);
457 return -1;
458 }
459 if ( devstr )
460 {
461 if ( g_usbm_entry_list_cur )
462 g_usbm_entry_list_cur->forw = devstr;
463 else
464 g_usbm_entry_list_end = devstr;
465 devstr->forw = 0;
466 g_usbm_entry_list_cur = devstr;
467 if ( g_param_debug > 0 )
468 {
469 printf("Resistered\n");
470 do_print_device_config_info(devstr);
471 }
472 }
473 close(fd);
474 return 0;
475}
476
477static void do_print_device_config_info(USBDEV_t *devinfo)
478{
479 int i;
480 char dispname_tmp[256];
481
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 )
494 {
495 printf(" DriverArg%d:%s\n", i, devinfo->argv[i]);
496 }
497 printf("\n");
498}
499
500static int usbmload_drv_probe(int dev_id)
501{
502 UsbDeviceDescriptor *devdesc;
503 const UsbInterfaceDescriptor *intfdesc;
504 int found_info_count;
505 USBDEV_t *devinfo;
506
507 if ( g_param_debug > 0 )
508 printf("Call usbmload_probe\n");
509 devdesc = (UsbDeviceDescriptor *)sceUsbdScanStaticDescriptor(dev_id, 0, 1u);
510 if ( !devdesc )
511 return 0;
512 intfdesc = (UsbInterfaceDescriptor *)sceUsbdScanStaticDescriptor(dev_id, devdesc, 4u);
513 if ( !intfdesc )
514 return 0;
515 found_info_count = 0;
516 if ( !g_usbm_entry_list_end )
517 {
518 if ( g_param_debug > 0 )
519 printf("usbmload : Not registered\n");
520 return 0;
521 }
522 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
523 {
524 if (
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) )
531 {
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;
536 }
537 }
538 if ( found_info_count )
539 {
540 if ( g_param_debug > 0 )
541 printf("SetEventFlag\n");
542 SetEventFlag(g_ef, 1u);
543 }
544 return 0;
545}
546
547static int usbmload_drv_connect(int dev_id)
548{
549 (void)dev_id;
550
551 return -1;
552}
553
554static int usbmload_drv_disconenct(int dev_id)
555{
556 (void)dev_id;
557
558 return 0;
559}
560
561static void ldd_loader_thread(void *userdata)
562{
563 u32 efres;
564
565 (void)userdata;
566 while ( 1 )
567 {
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);
572 do_clear_rb();
573 }
574}
575
576static void default_loadfunc(sceUsbmlPopDevinfo pop_devinfo)
577{
578 int modid;
579 int i;
580 unsigned int cur_argv_len;
581 unsigned int cur_argv_len_1;
582 char modarg[256];
583 ModuleStatus modstat;
584 int modres;
585
586 modid = -1;
587 if ( g_param_debug > 0 )
588 printf("Entering default_loadfunc()\n");
589 while ( 1 )
590 {
591 USBDEV_t *curdev;
592
593 curdev = pop_devinfo();
594 if ( !curdev )
595 break;
596 if ( curdev->modid < 0 || ReferModuleStatus(modid, &modstat) || strcmp(modstat.name, curdev->modname) )
597 {
598 if ( g_param_debug > 0 )
599 {
600 do_print_device_config_info(curdev);
601 }
602 cur_argv_len = 0;
603 for ( i = 0; i < curdev->argc; i += 1 )
604 {
605 cur_argv_len_1 = cur_argv_len + strlen(curdev->argv[i]) + 1;
606 if ( cur_argv_len_1 > (int)(sizeof(modarg) - 16) )
607 break;
608 cur_argv_len = cur_argv_len_1;
609 strcpy(&modarg[cur_argv_len], curdev->argv[i]);
610 }
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);
617 if ( modid >= 0 )
618 {
619 curdev->modid = modid;
620 curdev->load_result = modres;
621 ReferModuleStatus(modid, &modstat);
622 strcpy(curdev->modname, modstat.name);
623 }
624 }
625 }
626}
627
628static void do_push_device_rb(USBDEV_t *devinfo)
629{
630 int state;
631
632 CpuSuspendIntr(&state);
633 if ( g_rb_count < g_param_rbsize )
634 {
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;
639 g_rb_count += 1;
640 }
641 CpuResumeIntr(state);
642}
643
644static USBDEV_t *is_rb_ok_callback(void)
645{
646 USBDEV_t *devinfo;
647 int state;
648
649 CpuSuspendIntr(&state);
650 devinfo = NULL;
651 if ( g_rb_count )
652 {
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;
657 g_rb_count -= 1;
658 }
659 CpuResumeIntr(state);
660 return devinfo;
661}
662
663static void do_clear_rb(void)
664{
665 int state;
666
667 CpuSuspendIntr(&state);
668 g_rb_count = 0;
669 CpuResumeIntr(state);
670}
671
672static int split_config_line(char *curbuf, int cursplitind, char **dstptr)
673{
674 char *curbuf_1;
675 char *curbuf_2;
676 int splitfound;
677 char **dstptr_1;
678 int i;
679
680 curbuf_1 = curbuf;
681 curbuf_2 = curbuf;
682 splitfound = 0;
683 if ( cursplitind <= 0 || !strlen(curbuf) )
684 return 0;
685 dstptr_1 = dstptr;
686 while ( splitfound != cursplitind )
687 {
688 for ( i = 0; curbuf_1[i] == ' ' || curbuf_1[i] == '\t'; i += 1 )
689 ;
690 curbuf_2 += i;
691 if ( !curbuf_1[i] || curbuf_1[i] == '\r' || curbuf_1[i] == '\n' )
692 {
693 curbuf_1[i] = 0;
694 break;
695 }
696 *dstptr_1 = curbuf_2;
697 splitfound += 1;
698 if ( curbuf_1[i] != '"' )
699 {
700 for ( ; curbuf_1[i] && curbuf_1[i] != '\r' && curbuf_1[i] != '\n' && curbuf_1[i] != ' ' && curbuf_1[i] != '\t';
701 i += 1 )
702 {
703 curbuf_2 += 1;
704 }
705 }
706 else
707 {
708 i += 1;
709 curbuf_2 += 1;
710 *dstptr_1 = curbuf_2;
711 if ( !curbuf_1[i] )
712 {
713 curbuf_1[i] = 0;
714 break;
715 }
716 for ( ; curbuf_1[i] && curbuf_1[i] != '\r' && curbuf_1[i] != '\n' && curbuf_1[i] != '"'; i += 1 )
717 {
718 curbuf_2 += 1;
719 }
720 }
721 dstptr_1 += 1;
722 if ( !curbuf_1[i] || curbuf_1[i] == '\r' || curbuf_1[i] == '\n' )
723 {
724 curbuf_1[i] = 0;
725 break;
726 }
727 curbuf_2 += 1;
728 curbuf_1[i] = 0;
729 curbuf_1 = curbuf_2;
730 }
731 return splitfound;
732}
733
734static int do_parse_cmd_int(const char *buf)
735{
736 int hexval;
737 const char *i;
738
739 hexval = 0;
740 if ( *buf == '*' )
741 return -1;
742 if ( *buf != '0' || buf[1] != 'x' )
743 return strtol(buf, 0, 10);
744 for ( i = buf + 2; *i; i += 1 )
745 {
746 hexval = (16 * hexval) + (*i & 0xF) + ((*i >= ':') ? 9 : 0);
747 }
748 return hexval;
749}
750
751static void clean_config_line(char *buf)
752{
753 int in_quotes;
754
755 in_quotes = 0;
756 for ( ; *buf != '\n' && *buf != '\r' && *buf; buf += 1 )
757 {
758 if ( *buf == '"' )
759 in_quotes = !in_quotes;
760 if ( *buf == '#' && !in_quotes )
761 break;
762 }
763 *buf = 0;
764}
765
766static void sanitize_devicename(char *buf)
767{
768 while ( *buf && *buf != '\n' && *buf != '\r' )
769 {
770 unsigned int curchr_2;
771 unsigned int curchr_3;
772
773 curchr_2 = (u8)buf[0];
774 curchr_3 = (u8)buf[1];
775 if (
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 )
778 {
779 buf += 1;
780 }
781 else
782 {
783 if ( curchr_3 >= 0x9F )
784 {
785 buf[0] = curchr_2 >= 0xA0 ? 2 * curchr_2 + 32 : 2 * curchr_2 - '`';
786 buf[1] = curchr_3 + 2;
787 }
788 else
789 {
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';
794 }
795 buf += 2;
796 }
797 }
798}
799
800int sceUsbmlDisable(void)
801{
802 int unregres;
803
804 unregres = sceUsbdUnregisterAutoloader();
805 if ( unregres )
806 {
807 printf("sceUsbmlDisable:Error(0x%X)\n", unregres);
808 return -1;
809 }
810 g_usbmload_enabled = 0;
811 return 0;
812}
813
814int sceUsbmlEnable(void)
815{
816 int regres;
817
818 sceUsbdUnregisterAutoloader();
819 regres = sceUsbdRegisterAutoloader(&g_usbmload_drv);
820 if ( regres )
821 {
822 printf("sceUsbmlEnable:Error(0x%X)\n", regres);
823 return -1;
824 }
825 g_usbmload_enabled = 1;
826 return 0;
827}
828
829int sceUsbmlActivateCategory(const char *category)
830{
831 USBDEV_t *devinfo;
832 int i;
833
834 i = 0;
835 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
836 {
837 if ( !strcmp(devinfo->category, category) )
838 {
839 devinfo->activate_flag = 1;
840 i += 1;
841 }
842 }
843 if ( g_usbmload_enabled == 1 )
844 sceUsbmlEnable();
845 return i ? i : -1;
846}
847
848int sceUsbmlInactivateCategory(const char *category)
849{
850 USBDEV_t *devinfo;
851 int i;
852
853 i = 0;
854 for ( devinfo = g_usbm_entry_list_end; devinfo; devinfo = devinfo->forw )
855 {
856 if ( !strcmp(devinfo->category, category) )
857 {
858 devinfo->activate_flag = 0;
859 i += 1;
860 }
861 }
862 if ( g_usbmload_enabled == 1 )
863 sceUsbmlEnable();
864 return i ? i : -1;
865}
866
867int sceUsbmlRegisterLoadFunc(sceUsbmlLoadFunc loadfunc)
868{
869 if ( g_loadfunc_cb == default_loadfunc )
870 {
871 g_loadfunc_cb = loadfunc;
872 return 0;
873 }
874 return -1;
875}
876
877void sceUsbmlUnregisterLoadFunc(void)
878{
879 g_loadfunc_cb = default_loadfunc;
880}
881
882int sceUsbmlLoadConffile(const char *conffile)
883{
884 return do_parse_config_file(conffile);
885}
886
887int sceUsbmlRegisterDevice(USBDEV_t *device)
888{
889 USBDEV_t *devinfo;
890 int i;
891 int state;
892 int failed;
893
894 failed = 0;
895 CpuSuspendIntr(&state);
896 devinfo = (USBDEV_t *)AllocSysMemory(0, sizeof(USBDEV_t), 0);
897 CpuResumeIntr(state);
898 if ( !devinfo )
899 {
900 failed = 1;
901 }
902 if ( !failed )
903 {
904 // The following memcpy was inlined
905 memcpy(devinfo, device, sizeof(USBDEV_t));
906 CpuSuspendIntr(&state);
907 devinfo->dispname = (char *)AllocSysMemory(0, strlen(device->dispname) + 1, 0);
908 CpuResumeIntr(state);
909 if ( !devinfo->dispname )
910 {
911 failed = 2;
912 }
913 }
914 if ( !failed )
915 {
916 strcpy(devinfo->dispname, device->dispname);
917 CpuSuspendIntr(&state);
918 devinfo->path = (char *)AllocSysMemory(0, strlen(device->path) + 1, 0);
919 CpuResumeIntr(state);
920 if ( !devinfo->path )
921 {
922 failed = 3;
923 }
924 }
925 if ( !failed )
926 {
927 strcpy(devinfo->path, device->path);
928 for ( i = 0; i < device->argc; i += 1 )
929 {
930 CpuSuspendIntr(&state);
931 devinfo->argv[i] = (char *)AllocSysMemory(0, strlen(device->argv[i]) + 1, 0);
932 CpuResumeIntr(state);
933 if ( !devinfo->argv[i] )
934 {
935 failed = 4;
936 break;
937 }
938 strcpy(devinfo->argv[i], device->argv[i]);
939 }
940 }
941 if ( failed )
942 {
943 printf("sceUsbmlRegisterDevice : malloc error%d\n", failed);
944 if ( failed >= 2 )
945 CpuSuspendIntr(&state);
946 if ( failed >= 4 )
947 {
948 int j;
949
950 for ( j = 0; j < i; j += 1 )
951 {
952 FreeSysMemory(devinfo->argv[j]);
953 }
954 FreeSysMemory(devinfo->path);
955 }
956 if ( failed >= 3 )
957 {
958 FreeSysMemory(devinfo->dispname);
959 }
960 if ( failed >= 2 )
961 {
962 FreeSysMemory(devinfo);
963 CpuResumeIntr(state);
964 }
965 return -1;
966 }
967 if ( g_usbm_entry_list_cur )
968 g_usbm_entry_list_cur->forw = devinfo;
969 else
970 g_usbm_entry_list_end = devinfo;
971 devinfo->forw = 0;
972 g_usbm_entry_list_cur = devinfo;
973 return 0;
974}
975
976int sceUsbmlChangeThreadPriority(int prio1)
977{
978 return ChangeThreadPriority(g_thid, prio1) ? -1 : 0;
979}
980
981static void init_config_pos(void)
982{
983 g_config_chr_pos = sizeof(g_config_chr_buf);
984}
985
986static char read_config_byte(int fd)
987{
988 char tmpret;
989
990 if ( g_config_chr_pos == sizeof(g_config_chr_buf) )
991 {
992 read(fd, g_config_chr_buf, sizeof(g_config_chr_buf));
993 g_config_chr_pos = 0;
994 }
995 tmpret = g_config_chr_buf[g_config_chr_pos];
996 g_config_chr_pos += 1;
997 return tmpret;
998}
999
1000static char *read_config_line(char *dstbuf, int maxlen, int fd)
1001{
1002 int i;
1003
1004 for ( i = 0; i < maxlen; i += 1 )
1005 {
1006 dstbuf[i] = read_config_byte(fd);
1007 if ( dstbuf[i] == '\n' )
1008 break;
1009 dstbuf[i] = dstbuf[i] == '\r' ? 0 : dstbuf[i];
1010 }
1011 dstbuf[i] = 0;
1012 return dstbuf;
1013}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
u16 newflags
Definition loadcore.h:36
Definition usbmload.c:20