PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
usbd_api.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 "usbdpriv.h"
12
13int sceUsbdRegisterLdd(sceUsbdLddOps *driver)
14{
15 void *OldGP;
16 int res;
17
18#if USE_GP_REGISTER
19 OldGP = SetModuleGP();
20#else
21 OldGP = NULL;
22#endif
24 if ( usbdLock() )
25 {
26#if USE_GP_REGISTER
27 SetGP(OldGP);
28#endif
29 return res;
30 }
31 res = doRegisterDriver(driver, OldGP);
32 usbdUnlock();
33#if USE_GP_REGISTER
34 SetGP(OldGP);
35#endif
36 return res;
37}
38
39int sceUsbdRegisterAutoloader(sceUsbdLddOps *drv)
40{
41 void *OldGP;
42 int res;
43
44#if USE_GP_REGISTER
45 OldGP = SetModuleGP();
46#else
47 OldGP = NULL;
48#endif
50 if ( usbdLock() )
51 {
52#if USE_GP_REGISTER
53 SetGP(OldGP);
54#endif
55 return res;
56 }
57 res = doRegisterAutoLoader(drv, OldGP);
58 usbdUnlock();
59#if USE_GP_REGISTER
60 SetGP(OldGP);
61#endif
62 return res;
63}
64
65int sceUsbdUnregisterLdd(sceUsbdLddOps *driver)
66{
67 void *OldGP;
68 int res;
69
70#if USE_GP_REGISTER
71 OldGP = SetModuleGP();
72#else
73 OldGP = NULL;
74#endif
76 if ( usbdLock() )
77 {
78#if USE_GP_REGISTER
79 SetGP(OldGP);
80#endif
81 return res;
82 }
83 res = doUnregisterDriver(driver);
84 usbdUnlock();
85#if USE_GP_REGISTER
86 SetGP(OldGP);
87#endif
88 return res;
89}
90
91int sceUsbdUnregisterAutoloader(void)
92{
93 void *OldGP;
94 int res;
95
96#if USE_GP_REGISTER
97 OldGP = SetModuleGP();
98#else
99 OldGP = NULL;
100#endif
101 res = USB_RC_BADCONTEXT;
102 if ( usbdLock() )
103 {
104#if USE_GP_REGISTER
105 SetGP(OldGP);
106#endif
107 return res;
108 }
109 res = doUnregisterAutoLoader();
110 usbdUnlock();
111#if USE_GP_REGISTER
112 SetGP(OldGP);
113#endif
114 return res;
115}
116
117void *sceUsbdScanStaticDescriptor(int devId, void *data, u8 type)
118{
119 void *OldGP;
120 const UsbdDevice_t *dev;
121 void *res;
122
123#if USE_GP_REGISTER
124 OldGP = SetModuleGP();
125#else
126 OldGP = NULL;
127#endif
128 res = NULL;
129 if ( usbdLock() )
130 {
131#if USE_GP_REGISTER
132 SetGP(OldGP);
133#endif
134 return res;
135 }
136 dev = fetchDeviceById(devId);
137 if ( dev && dev->m_deviceStatus == DEVICE_READY )
138 res = doGetDeviceStaticDescriptor(devId, data, type);
139 usbdUnlock();
140#if USE_GP_REGISTER
141 SetGP(OldGP);
142#endif
143 return res;
144}
145
146int sceUsbdGetDeviceLocation(int devId, u8 *path)
147{
148 void *OldGP;
149 int res;
150 UsbdDevice_t *dev;
151
152#if USE_GP_REGISTER
153 OldGP = SetModuleGP();
154#else
155 OldGP = NULL;
156#endif
157 res = USB_RC_BADCONTEXT;
158 if ( usbdLock() )
159 {
160#if USE_GP_REGISTER
161 SetGP(OldGP);
162#endif
163 return res;
164 }
165 res = USB_RC_BADDEV;
166 dev = fetchDeviceById(devId);
167 if ( dev && dev->m_deviceStatus == DEVICE_READY )
168 res = doGetDeviceLocation(dev, path);
169 usbdUnlock();
170#if USE_GP_REGISTER
171 SetGP(OldGP);
172#endif
173 return res;
174}
175
176int sceUsbdSetPrivateData(int devId, void *data)
177{
178 void *OldGP;
179 int res;
180 UsbdDevice_t *dev;
181
182#if USE_GP_REGISTER
183 OldGP = SetModuleGP();
184#else
185 OldGP = NULL;
186#endif
187 res = USB_RC_BADCONTEXT;
188 if ( usbdLock() )
189 {
190#if USE_GP_REGISTER
191 SetGP(OldGP);
192#endif
193 return res;
194 }
195 res = USB_RC_BADDEV;
196 dev = fetchDeviceById(devId);
197 if ( dev )
198 {
199 dev->m_privDataField = data;
200 res = USB_RC_OK;
201 }
202 usbdUnlock();
203#if USE_GP_REGISTER
204 SetGP(OldGP);
205#endif
206 return res;
207}
208
209void *sceUsbdGetPrivateData(int devId)
210{
211 void *OldGP;
212 void *res;
213 UsbdDevice_t *dev;
214
215#if USE_GP_REGISTER
216 OldGP = SetModuleGP();
217#else
218 OldGP = NULL;
219#endif
220 res = NULL;
221 if ( usbdLock() )
222 {
223#if USE_GP_REGISTER
224 SetGP(OldGP);
225#endif
226 return res;
227 }
228 dev = fetchDeviceById(devId);
229 if ( dev )
230 res = dev->m_privDataField;
231 usbdUnlock();
232#if USE_GP_REGISTER
233 SetGP(OldGP);
234#endif
235 return res;
236}
237
238int sceUsbdOpenPipe(int devId, UsbEndpointDescriptor *desc)
239{
240 void *OldGP;
241 UsbdDevice_t *dev;
242 int res;
243 const UsbdEndpoint_t *ep;
244
245#if USE_GP_REGISTER
246 OldGP = SetModuleGP();
247#else
248 OldGP = NULL;
249#endif
250 res = -1;
251 if ( usbdLock() )
252 {
253#if USE_GP_REGISTER
254 SetGP(OldGP);
255#endif
256 return res;
257 }
258 ep = NULL;
259 dev = fetchDeviceById(devId);
260 if ( dev )
261 ep = doOpenEndpoint(dev, desc, 0);
262 if ( ep )
263 res = ep->m_id;
264 usbdUnlock();
265#if USE_GP_REGISTER
266 SetGP(OldGP);
267#endif
268 return res;
269}
270
271int sceUsbdOpenPipeAligned(int devId, UsbEndpointDescriptor *desc)
272{
273 void *OldGP;
274 UsbdDevice_t *dev;
275 int res;
276 const UsbdEndpoint_t *ep;
277
278#if USE_GP_REGISTER
279 OldGP = SetModuleGP();
280#else
281 OldGP = NULL;
282#endif
283 res = -1;
284 if ( usbdLock() )
285 {
286#if USE_GP_REGISTER
287 SetGP(OldGP);
288#endif
289 return res;
290 }
291 ep = NULL;
292 dev = fetchDeviceById(devId);
293 if ( dev )
294 ep = doOpenEndpoint(dev, desc, 1u);
295 if ( ep )
296 res = ep->m_id;
297 usbdUnlock();
298#if USE_GP_REGISTER
299 SetGP(OldGP);
300#endif
301 return res;
302}
303
304int sceUsbdClosePipe(int id)
305{
306 void *OldGP;
307 UsbdEndpoint_t *ep;
308 int res;
309
310#if USE_GP_REGISTER
311 OldGP = SetModuleGP();
312#else
313 OldGP = NULL;
314#endif
315 res = USB_RC_BADCONTEXT;
316 if ( usbdLock() )
317 {
318#if USE_GP_REGISTER
319 SetGP(OldGP);
320#endif
321 return res;
322 }
323 res = USB_RC_BADPIPE;
324 ep = fetchEndpointById(id);
325 if ( ep )
326 res = doCloseEndpoint(ep);
327 usbdUnlock();
328#if USE_GP_REGISTER
329 SetGP(OldGP);
330#endif
331 return res;
332}
333
334static void signalCallbackThreadFunc(UsbdIoRequest_t *req)
335{
336 int state;
337
338 CpuSuspendIntr(&state);
339 req->m_prev = cbListEnd;
340 if ( !cbListEnd )
341 cbListStart = req;
342 else
343 cbListEnd->m_next = req;
344 req->m_next = NULL;
345 cbListEnd = req;
346 CpuResumeIntr(state);
347 SetEventFlag(usbKernelResources.m_callbackEvent, 1u);
348}
349
350static int usbdTransferPipeImpl(
351 void *gp_val,
352 int id,
353 void *data,
354 u32 length,
355 UsbDeviceRequest *option,
356 void *callback,
357 void *cbArg,
359{
360 int res;
361 UsbdEndpoint_t *ep;
362 int bNumPackets;
363 UsbdIoRequest_t *req;
364
365 res = USB_RC_BADCONTEXT;
366 if ( usbdLock() )
367 {
368 return res;
369 }
370 res = USB_RC_OK;
371 ep = fetchEndpointById(id);
372 if ( !ep )
373 {
374 dbg_printf("sceUsbdTransferPipe: UsbdEndpoint_t %d not found\n", id);
375 res = USB_RC_BADPIPE;
376 }
377 bNumPackets = 0;
378 if ( request && res == USB_RC_OK )
379 {
380 bNumPackets = request->bNumPackets;
381 data = request->bBufStart;
382 }
383 if ( request && res == USB_RC_OK )
384 {
385 if ( (unsigned int)(bNumPackets - 1) >= 8 || !data )
386 {
387 res = USB_RC_BADLENGTH;
388 }
389 }
390 if ( (request || (data && (int)length > 0)) && res == USB_RC_OK )
391 {
392 if ( ep->m_alignFlag && ((uiptr)data & 3) != 0 )
393 {
394 res = USB_RC_BADALIGN;
395 }
396 }
397 if ( request && res == USB_RC_OK )
398 {
399 if ( ep->m_endpointType != TYPE_ISOCHRON )
400 {
401 res = USB_RC_BADPIPE;
402 }
403 }
404 if ( request && res == USB_RC_OK )
405 {
406 int i_pkt;
407
408 length = 0;
409 for ( i_pkt = 0; i_pkt < bNumPackets; i_pkt += 1 )
410 {
411 if ( (ep->m_hcEd->m_hcArea.stru.m_maxPacketSize & 0x7FFu) < request->Packets[i_pkt].bLength )
412 {
413 res = USB_RC_BADLENGTH;
414 break;
415 }
416 length += request->Packets[i_pkt].bLength;
417 if ( ep->m_alignFlag && (((((uiptr)data) & 0xFF) + (length & 0xFF)) & 3) != 0 )
418 {
419 res = USB_RC_BADALIGN;
420 break;
421 }
422 }
423 }
424 if ( (request || (data && (int)length > 0)) && res == USB_RC_OK )
425 {
426 if ( (((uiptr)data + length - 1) >> 12) - ((uiptr)data >> 12) >= 2 )
427 {
428 res = USB_RC_BADLENGTH;
429 }
430 }
431 if ( (!request && (data && (int)length > 0)) && res == USB_RC_OK )
432 {
433 switch ( ep->m_endpointType )
434 {
435 case TYPE_CONTROL:
436 {
437 if ( ((uiptr)data & 3) != 0 && (option->requesttype & 0x80) == 0 )
438 {
439 if ( (ep->m_hcEd->m_hcArea.stru.m_maxPacketSize & 0x7FF) == 64 && (int)length >= 63 )
440 {
441 res = USB_RC_BADALIGN;
442 }
443 }
444 break;
445 }
446 case TYPE_ISOCHRON:
447 {
448 if ( (ep->m_hcEd->m_hcArea.stru.m_maxPacketSize & 0x7FFu) < length )
449 {
450 res = USB_RC_BADLENGTH;
451 }
452 break;
453 }
454 default:
455 {
456 break;
457 }
458 }
459 }
460 if ( res == USB_RC_OK )
461 {
462 req = allocIoRequest();
463 if ( !req )
464 {
465 dbg_printf("Ran out of IoReqs\n");
466 res = USB_RC_IOREQ;
467 }
468 }
469 if ( res == USB_RC_OK )
470 {
471 req->m_userCallbackArg = cbArg;
472 req->m_gpSeg = gp_val;
473 req->m_req.bNumPackets = 0;
474 req->m_userCallbackProc = callback;
475 switch ( ep->m_endpointType )
476 {
477 case TYPE_ISOCHRON:
478 {
479 if ( request )
480 {
481 req->m_waitFrames = request->bRelStartFrame;
482 memcpy(&(req->m_req), request, sizeof(sceUsbdMultiIsochronousRequest));
483 }
484 else
485 {
486 req->m_waitFrames = (u32)option;
487 }
488 res = attachIoReqToEndpoint(ep, req, data, length, signalCallbackThreadFunc);
489 break;
490 }
491 case TYPE_CONTROL:
492 {
493 if ( !option )
494 {
495 freeIoRequest(req);
496 res = USB_RC_BADOPTION;
497 }
498 if ( res == USB_RC_OK )
499 {
500 if ( option->length != length )
501 {
502 freeIoRequest(req);
503 res = USB_RC_BADLENGTH;
504 }
505 }
506 if ( res == USB_RC_OK )
507 {
508 res = doControlTransfer(
509 ep,
510 req,
511 option->requesttype,
512 option->request,
513 option->value,
514 option->index,
515 option->length,
516 data,
517 signalCallbackThreadFunc);
518 }
519 break;
520 }
521 default:
522 {
523 res = attachIoReqToEndpoint(ep, req, data, length, signalCallbackThreadFunc);
524 break;
525 }
526 }
527 }
528 usbdUnlock();
529 return res;
530}
531
532int sceUsbdTransferPipe(int id, void *data, u32 len, void *option, sceUsbdDoneCallback callback, void *cbArg)
533{
534 void *OldGP;
535 int res;
536
537#if USE_GP_REGISTER
538 OldGP = SetModuleGP();
539#else
540 OldGP = NULL;
541#endif
542 res = usbdTransferPipeImpl(OldGP, id, data, len, (UsbDeviceRequest *)option, callback, cbArg, NULL);
543#if USE_GP_REGISTER
544 SetGP(OldGP);
545#endif
546 return res;
547}
548
549int sceUsbdMultiIsochronousTransfer(
550 int pipeId, sceUsbdMultiIsochronousRequest *request, sceUsbdMultiIsochronousDoneCallback callback, void *cbArg)
551{
552 void *OldGP;
553 int res;
554
555#if USE_GP_REGISTER
556 OldGP = SetModuleGP();
557#else
558 OldGP = NULL;
559#endif
560 res = usbdTransferPipeImpl(OldGP, pipeId, NULL, 0, NULL, callback, cbArg, request);
561#if USE_GP_REGISTER
562 SetGP(OldGP);
563#endif
564 return res;
565}
566
567int sceUsbdChangeThreadPriority(int prio1, int prio2)
568{
569 void *OldGP;
570 int res;
571
572#if USE_GP_REGISTER
573 OldGP = SetModuleGP();
574#else
575 OldGP = NULL;
576#endif
577 res = 0;
578 if ( usbConfig.m_hcdThreadPrio != prio1 )
579 {
580 usbConfig.m_hcdThreadPrio = prio1;
581 res = ChangeThreadPriority(usbKernelResources.m_hcdTid, prio1);
582 }
583 if ( res == 0 && usbConfig.m_cbThreadPrio != prio2 )
584 {
585 usbConfig.m_cbThreadPrio = prio2;
586 res = ChangeThreadPriority(usbKernelResources.m_callbackTid, prio2);
587 }
588#if USE_GP_REGISTER
589 SetGP(OldGP);
590#endif
591 return res;
592}
593
594int sceUsbdGetReportDescriptor(int devId, int cfgNum, int ifNum, void **desc, u32 *len)
595{
596 void *OldGP;
597 int res;
598 UsbdDevice_t *dev;
599 UsbdReportDescriptor_t *hidDescriptorStart;
600
601#if USE_GP_REGISTER
602 OldGP = SetModuleGP();
603#else
604 OldGP = NULL;
605#endif
606 res = USB_RC_BADCONTEXT;
607 if ( usbdLock() )
608 {
609#if USE_GP_REGISTER
610 SetGP(OldGP);
611#endif
612 return res;
613 }
614 res = USB_RC_BADDEV;
615 hidDescriptorStart = NULL;
616 dev = fetchDeviceById(devId);
617 if ( dev )
618 {
619 res = USB_RC_UNKNOWN;
620 for ( hidDescriptorStart = dev->m_reportDescriptorStart;
621 hidDescriptorStart
622 && ((int)hidDescriptorStart->m_cfgNum != cfgNum || (int)hidDescriptorStart->m_ifNum != ifNum);
623 hidDescriptorStart = hidDescriptorStart->m_next )
624 {
625 }
626 }
627 if ( hidDescriptorStart )
628 {
629 res = USB_RC_OK;
630 if ( desc )
631 *desc = hidDescriptorStart->m_data;
632 if ( len )
633 *len = hidDescriptorStart->m_length;
634 }
635 usbdUnlock();
636#if USE_GP_REGISTER
637 SetGP(OldGP);
638#endif
639 return res;
640}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
#define USB_RC_BADPIPE
Definition usbd.h:269
#define USB_RC_BADCONTEXT
Definition usbd.h:275
#define USB_RC_UNKNOWN
Definition usbd.h:294
#define USB_RC_OK
Definition usbd.h:238
#define USB_RC_IOREQ
Definition usbd.h:282
#define USB_RC_BADOPTION
Definition usbd.h:284
#define USB_RC_BADLENGTH
Definition usbd.h:271
#define USB_RC_BADDEV
Definition usbd.h:267