dvd fixed (hopefully)
[libogc.git] / libogc / usb.c
blobb8c923f65e2f10d9f5c46e61efa7d8f6b7901821
1 /*-------------------------------------------------------------
3 usb.c -- USB lowlevel
5 Copyright (C) 2008
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any
11 damages arising from the use of this software.
13 Permission is granted to anyone to use this software for any
14 purpose, including commercial applications, and to alter it and
15 redistribute it freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you
18 must not claim that you wrote the original software. If you use
19 this software in a product, an acknowledgment in the product
20 documentation would be appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and
23 must not be misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source
26 distribution.
28 -------------------------------------------------------------*/
30 #if defined(HW_RVL)
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <malloc.h>
35 #include <time.h>
36 #include <gcutil.h>
37 #include <ogcsys.h>
38 #include <ipc.h>
39 #include <asm.h>
40 #include <processor.h>
42 #include "usb.h"
44 #define USB_HEAPSIZE 8192
45 #define USB_STRUCTSIZE 96
47 #define USB_IOCTL_CTRLMSG 0
48 #define USB_IOCTL_BLKMSG 1
49 #define USB_IOCTL_INTRMSG 2
50 #define USB_IOCTL_SUSPENDDEV 5
51 #define USB_IOCTL_RESUMEDEV 6
52 #define USB_IOCTL_GETDEVLIST 12
53 #define USB_IOCTL_DEVREMOVALHOOK 26
54 #define USB_IOCTL_DEVINSERTHOOK 27
56 struct _usb_cb {
57 usbcallback cb;
58 void *usrdata;
59 ioctlv *vec;
60 s32 fd;
63 static s32 hId = -1;
65 static s32 __usb_device_notificationCB(s32 result,void *usrdata)
67 ioctlv *vec = NULL;
68 struct _usb_cb *msgcb = (struct _usb_cb*)usrdata;
70 if(msgcb==NULL) return IPC_EINVAL;
72 if(msgcb->cb!=NULL) msgcb->cb(result,msgcb->usrdata);
74 if(msgcb->fd>=0) IOS_Close(msgcb->fd);
76 vec = msgcb->vec;
77 if(vec==NULL) return IPC_EINVAL;
79 if(vec[0].data!=NULL) iosFree(hId,vec[0].data);
80 if(vec[1].data!=NULL) iosFree(hId,vec[1].data);
82 iosFree(hId,vec);
83 iosFree(hId,msgcb);
85 return IPC_OK;
88 static s32 __usb_control_messageCB(s32 result,void *usrdata)
90 ioctlv *vec = NULL;
91 struct _usb_cb *msgcb = (struct _usb_cb*)usrdata;
93 if(msgcb==NULL) return IPC_EINVAL;
95 if(msgcb->cb!=NULL) msgcb->cb(result,msgcb->usrdata);
97 vec = msgcb->vec;
98 if(vec==NULL) return IPC_EINVAL;
100 if(vec[0].data!=NULL) iosFree(hId,vec[0].data);
101 if(vec[1].data!=NULL) iosFree(hId,vec[1].data);
102 if(vec[2].data!=NULL) iosFree(hId,vec[2].data);
103 if(vec[3].data!=NULL) iosFree(hId,vec[3].data);
104 if(vec[4].data!=NULL) iosFree(hId,vec[4].data);
105 if(vec[5].data!=NULL) iosFree(hId,vec[5].data);
107 iosFree(hId,vec);
108 iosFree(hId,msgcb);
110 return IPC_OK;
113 static s32 __usb_bulk_messageCB(s32 result,void *usrdata)
115 ioctlv *vec = NULL;
116 struct _usb_cb *msgcb = (struct _usb_cb*)usrdata;
118 if(msgcb==NULL) return IPC_EINVAL;
120 if(msgcb->cb!=NULL) msgcb->cb(result,msgcb->usrdata);
122 vec = msgcb->vec;
123 if(vec==NULL) return IPC_EINVAL;
125 if(vec[0].data!=NULL) iosFree(hId,vec[0].data);
126 if(vec[1].data!=NULL) iosFree(hId,vec[1].data);
128 iosFree(hId,vec);
129 iosFree(hId,msgcb);
131 return IPC_OK;
134 static inline s32 __usb_control_message(s32 fd,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
136 s32 ret = IPC_ENOMEM;
137 u8 *pRqType = NULL;
138 u8 *pRq = NULL;
139 u8 *pNull = NULL;
140 u16 *pValue = NULL;
141 u16 *pIndex = NULL;
142 u16 *pLength = NULL;
143 ioctlv *vec = NULL;
144 struct _usb_cb *msgcb = NULL;
146 if(((s32)rpData%32)!=0) return IPC_EINVAL;
147 if(wLength && !rpData) return IPC_EINVAL;
148 if(!wLength && rpData) return IPC_EINVAL;
150 vec = iosAlloc(hId,sizeof(ioctlv)*7);
151 if(vec==NULL) return IPC_ENOMEM;
153 pRqType = iosAlloc(hId,32);
154 if(pRqType==NULL) goto done;
155 *pRqType = bmRequestType;
157 pRq = iosAlloc(hId,32);
158 if(pRq==NULL) goto done;
159 *pRq = bmRequest;
161 pValue = iosAlloc(hId,32);
162 if(pValue==NULL) goto done;
163 *pValue = bswap16(wValue);
165 pIndex = iosAlloc(hId,32);
166 if(pIndex==NULL) goto done;
167 *pIndex = bswap16(wIndex);
169 pLength = iosAlloc(hId,32);
170 if(pLength==NULL) goto done;
171 *pLength = bswap16(wLength);
173 pNull = iosAlloc(hId,32);
174 if(pNull==NULL) goto done;
175 *pNull = 0;
177 vec[0].data = pRqType;
178 vec[0].len = sizeof(u8);
179 vec[1].data = pRq;
180 vec[1].len = sizeof(u8);
181 vec[2].data = pValue;
182 vec[2].len = sizeof(u16);
183 vec[3].data = pIndex;
184 vec[3].len = sizeof(u16);
185 vec[4].data = pLength;
186 vec[4].len = sizeof(u16);
187 vec[5].data = pNull;
188 vec[5].len = sizeof(u8);
189 vec[6].data = rpData;
190 vec[6].len = wLength;
192 if(cb==NULL)
193 ret = IOS_Ioctlv(fd,USB_IOCTL_CTRLMSG,6,1,vec);
194 else {
195 msgcb = iosAlloc(hId,sizeof(struct _usb_cb));
196 if(msgcb==NULL) goto done;
198 msgcb->fd = -1;
199 msgcb->cb = cb;
200 msgcb->usrdata = usrdata;
201 msgcb->vec = vec;
202 return IOS_IoctlvAsync(fd,USB_IOCTL_CTRLMSG,6,1,vec,__usb_control_messageCB,msgcb);
205 done:
206 if(pNull!=NULL) iosFree(hId,pNull);
207 if(pLength!=NULL) iosFree(hId,pLength);
208 if(pIndex!=NULL) iosFree(hId,pIndex);
209 if(pValue!=NULL) iosFree(hId,pValue);
210 if(pRq!=NULL) iosFree(hId,pRq);
211 if(pRqType!=NULL) iosFree(hId,pRqType);
212 if(vec!=NULL) iosFree(hId,vec);
214 return ret;
217 static inline s32 __usb_interrupt_bulk_message(s32 fd,u8 ioctl,u8 bEndpoint,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
219 s32 ret = IPC_ENOMEM;
220 u8 *pEndP = NULL;
221 u16 *pLength = NULL;
222 ioctlv *vec = NULL;
223 struct _usb_cb *msgcb = NULL;
225 if(((s32)rpData%32)!=0) return IPC_EINVAL;
226 if(wLength && !rpData) return IPC_EINVAL;
227 if(!wLength && rpData) return IPC_EINVAL;
229 vec = iosAlloc(hId,sizeof(ioctlv)*3);
230 if(vec==NULL) return IPC_ENOMEM;
232 pEndP = iosAlloc(hId,32);
233 if(pEndP==NULL) goto done;
234 *pEndP = bEndpoint;
236 pLength = iosAlloc(hId,32);
237 if(pLength==NULL) goto done;
238 *pLength = wLength;
240 vec[0].data = pEndP;
241 vec[0].len = sizeof(u8);
242 vec[1].data = pLength;
243 vec[1].len = sizeof(u16);
244 vec[2].data = rpData;
245 vec[2].len = wLength;
247 if(cb==NULL)
248 ret = IOS_Ioctlv(fd,ioctl,2,1,vec);
249 else {
250 msgcb = iosAlloc(hId,sizeof(struct _usb_cb));
251 if(msgcb==NULL) goto done;
253 msgcb->fd = -1;
254 msgcb->cb = cb;
255 msgcb->usrdata = usrdata;
256 msgcb->vec = vec;
257 return IOS_IoctlvAsync(fd,ioctl,2,1,vec,__usb_bulk_messageCB,msgcb);
260 done:
261 if(pLength!=NULL) iosFree(hId,pLength);
262 if(pEndP!=NULL) iosFree(hId,pEndP);
263 if(vec!=NULL) iosFree(hId,vec);
265 return ret;
268 static inline s32 __usb_getdesc(s32 fd, u8 *buffer, u8 type, u8 index, u8 size)
270 return __usb_control_message(fd, USB_ENDPOINT_IN ,USB_REQ_GETDESCRIPTOR, (type << 8) | index, 0, size, buffer, NULL, NULL);
273 static u32 __find_next_endpoint(u8 *buffer,u32 size)
275 u8 *ptr = buffer;
277 while(size>0) {
278 if(buffer[1]==USB_DT_ENDPOINT || buffer[1]==USB_DT_INTERFACE) break;
280 size -= buffer[0];
281 buffer += buffer[0];
284 return (buffer - ptr);
287 s32 USB_Initialize()
289 if(hId==-1) hId = iosCreateHeap(USB_HEAPSIZE);
290 if(hId<0) return IPC_ENOMEM;
291 return IPC_OK;
294 s32 USB_Deinitialize()
296 if(hId<0) return IPC_EINVAL;
297 return iosDestroyHeap(hId);
300 s32 USB_OpenDevice(const char *device,u16 vid,u16 pid,s32 *fd)
302 s32 _fd = -1;
303 s32 ret = USB_OK;
304 char *devicepath = NULL;
306 devicepath = iosAlloc(hId,USB_MAXPATH);
307 if(devicepath==NULL) return IPC_ENOMEM;
309 snprintf(devicepath,USB_MAXPATH,"/dev/usb/%s/%x/%x",device,vid,pid);
311 _fd = IOS_Open(devicepath,0);
312 if(_fd<0) ret = _fd;
314 *fd = _fd;
316 if(devicepath!=NULL) iosFree(hId,devicepath);
317 return ret;
320 s32 USB_CloseDevice(s32 *fd)
322 s32 ret = IPC_OK;
324 if(fd && *fd>=0) {
325 ret = IOS_Close(*fd);
326 if(ret>=0) *fd = -1;
328 return ret;
331 s32 USB_CloseDeviceAsync(s32 *fd,usbcallback cb,void *usrdata)
333 if(fd && *fd>=0)
334 return IOS_CloseAsync(*fd,cb,usrdata);
336 return IPC_OK;
339 s32 USB_GetDeviceDescription(s32 fd,usb_devdesc *devdesc)
341 s32 ret;
342 usb_devdesc *p;
344 p = iosAlloc(hId,USB_DT_DEVICE_SIZE);
345 if(p==NULL) return IPC_ENOMEM;
347 ret = __usb_control_message(fd,USB_ENDPOINT_IN,USB_REQ_GETDESCRIPTOR,(USB_DT_DEVICE<<8),0,USB_DT_DEVICE_SIZE,p,NULL,NULL);
348 if(ret>=0) memcpy(devdesc,p,USB_DT_DEVICE_SIZE);
349 devdesc->configurations = NULL;
351 if(p!=NULL) iosFree(hId,p);
352 return ret;
355 s32 USB_GetDescriptors(s32 fd, usb_devdesc *udd)
357 u8 *buffer = NULL;
358 u8 *ptr = NULL;
359 usb_configurationdesc *ucd = NULL;
360 usb_interfacedesc *uid = NULL;
361 usb_endpointdesc *ued = NULL;
362 s32 retval = 0;
363 u32 size,i;
364 u32 iConf, iInterface, iEndpoint;
366 buffer = iosAlloc(hId, sizeof(*udd));
367 if(buffer == NULL)
369 retval = IPC_ENOHEAP;
370 goto free_and_error;
373 retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE);
374 if(retval < 0)
375 goto free_and_error;
376 memcpy(udd, buffer, USB_DT_DEVICE_SIZE);
377 iosFree(hId, buffer);
379 udd->bcdUSB = bswap16(udd->bcdUSB);
380 udd->idVendor = bswap16(udd->idVendor);
381 udd->idProduct = bswap16(udd->idProduct);
382 udd->bcdDevice = bswap16(udd->bcdDevice);
384 udd->configurations = calloc(udd->bNumConfigurations, sizeof(*udd->configurations));
385 if(udd->configurations == NULL)
387 retval = IPC_ENOMEM;
388 goto free_and_error;
390 for(iConf = 0; iConf < udd->bNumConfigurations; iConf++)
392 buffer = iosAlloc(hId, USB_DT_CONFIG_SIZE);
393 if(buffer == NULL)
395 retval = IPC_ENOHEAP;
396 goto free_and_error;
399 retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, USB_DT_CONFIG_SIZE);
400 ucd = &udd->configurations[iConf];
401 memcpy(ucd, buffer, USB_DT_CONFIG_SIZE);
402 iosFree(hId, buffer);
404 ucd->wTotalLength = bswap16(ucd->wTotalLength);
405 size = ucd->wTotalLength;
406 buffer = iosAlloc(hId, size);
407 if(buffer == NULL)
409 retval = IPC_ENOHEAP;
410 goto free_and_error;
413 retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, ucd->wTotalLength);
414 if(retval < 0)
415 goto free_and_error;
417 ptr = buffer;
418 ptr += ucd->bLength;
419 size -= ucd->bLength;
421 retval = IPC_ENOMEM;
422 ucd->interfaces = calloc(ucd->bNumInterfaces, sizeof(*ucd->interfaces));
423 if(ucd->interfaces == NULL)
424 goto free_and_error;
425 for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++)
427 uid = &ucd->interfaces[iInterface];
428 memcpy(uid, ptr, USB_DT_INTERFACE_SIZE);
429 ptr += uid->bLength;
430 size -= uid->bLength;
432 uid->endpoints = calloc(uid->bNumEndpoints, sizeof(*uid->endpoints));
433 if(uid->endpoints == NULL)
434 goto free_and_error;
436 /* This skips vendor and class specific descriptors */
437 i = __find_next_endpoint(ptr, size);
438 uid->extra_size = i;
439 if(i>0)
441 uid->extra = malloc(i);
442 if(uid->extra == NULL)
443 goto free_and_error;
444 memcpy(uid->extra, ptr, i);
445 ptr += i;
446 size -= i;
448 memset(uid->endpoints,0,uid->bNumEndpoints* sizeof(*uid->endpoints));
449 for(iEndpoint = 0; iEndpoint < uid->bNumEndpoints; iEndpoint++)
451 ued = &uid->endpoints[iEndpoint];
452 memcpy(ued, ptr, USB_DT_ENDPOINT_SIZE);
453 ptr += ued->bLength;
454 ued->wMaxPacketSize = bswap16(ued->wMaxPacketSize);
457 iosFree(hId, buffer);
458 buffer = NULL;
460 retval = IPC_OK;
462 free_and_error:
463 if(buffer != NULL)
464 iosFree(hId, buffer);
465 if(retval < 0)
466 USB_FreeDescriptors(udd);
467 return retval;
470 s32 USB_GetHIDDescriptor(s32 fd,usb_hiddesc *uhd)
472 u8 *buffer = NULL;
473 s32 retval = IPC_OK;
475 buffer = iosAlloc(hId,sizeof(usb_hiddesc));
476 if(buffer==NULL) {
477 retval = IPC_ENOMEM;
478 goto free_and_error;
481 retval = __usb_getdesc(fd,buffer,USB_DT_HID,0,USB_DT_HID_SIZE);
482 if(retval<0) goto free_and_error;
484 memcpy(uhd,buffer,USB_DT_HID_SIZE);
485 uhd->bcdHID = bswap16(uhd->bcdHID);
486 uhd->descr[0].wDescriptorLength = bswap16(uhd->descr[0].wDescriptorLength);
488 retval = IPC_OK;
490 free_and_error:
491 if(buffer!=NULL) iosFree(hId,buffer);
492 return retval;
495 void USB_FreeDescriptors(usb_devdesc *udd)
497 int iConf, iInterface;
498 usb_configurationdesc *ucd;
499 usb_interfacedesc *uid;
500 if(udd->configurations != NULL)
502 for(iConf = 0; iConf < udd->bNumConfigurations; iConf++)
504 ucd = &udd->configurations[iConf];
505 if(ucd->interfaces != NULL)
507 for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++)
509 uid = &ucd->interfaces[iInterface];
510 if(uid->endpoints != NULL)
511 free(uid->endpoints);
512 if(uid->extra != NULL)
513 free(uid->extra);
515 free(ucd->interfaces);
518 free(udd->configurations);
522 s32 USB_GetAsciiString(s32 fd,u16 wIndex,u16 wLangID,u16 wLength,void *rpData)
524 s32 ret;
525 u8 bo, ro;
526 u8 *buf;
527 u8 *rp = (u8 *)rpData;
529 if(wLength > 255)
530 wLength = 255;
532 buf = iosAlloc(hId, 255); /* 255 is the highest possible length of a descriptor */
533 if(buf == NULL)
534 return IPC_ENOMEM;
536 ret = __usb_control_message(fd, USB_ENDPOINT_IN, USB_REQ_GETDESCRIPTOR, ((USB_DT_STRING << 8) + wIndex), wLangID, 255, buf, NULL, NULL);
538 /* index 0 gets a list of supported languages */
539 if(wIndex == 0)
541 if(ret > 0)
542 memcpy(rpData, buf, wLength);
543 iosFree(hId, buf);
544 return ret;
547 if(ret > 0)
549 bo = 2;
550 ro = 0;
551 while(ro < (wLength - 1) && bo < buf[0])
553 if(buf[bo + 1])
554 rp[ro++] = '?';
555 else
556 rp[ro++] = buf[bo];
557 bo += 2;
559 rp[ro] = 0;
560 ret = ro - 1;
563 iosFree(hId, buf);
564 return ret;
567 s32 USB_ReadIntrMsg(s32 fd,u8 bEndpoint,u16 wLength,void *rpData)
569 return __usb_interrupt_bulk_message(fd,USB_IOCTL_INTRMSG,bEndpoint,wLength,rpData,NULL,NULL);
572 s32 USB_ReadIntrMsgAsync(s32 fd,u8 bEndpoint,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
574 return __usb_interrupt_bulk_message(fd,USB_IOCTL_INTRMSG,bEndpoint,wLength,rpData,cb,usrdata);
577 s32 USB_WriteIntrMsg(s32 fd,u8 bEndpoint,u16 wLength,void *rpData)
579 return __usb_interrupt_bulk_message(fd,USB_IOCTL_INTRMSG,bEndpoint,wLength,rpData,NULL,NULL);
582 s32 USB_WriteIntrMsgAsync(s32 fd,u8 bEndpoint,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
584 return __usb_interrupt_bulk_message(fd,USB_IOCTL_INTRMSG,bEndpoint,wLength,rpData,cb,usrdata);
587 s32 USB_ReadBlkMsg(s32 fd,u8 bEndpoint,u16 wLength,void *rpData)
589 return __usb_interrupt_bulk_message(fd,USB_IOCTL_BLKMSG,bEndpoint,wLength,rpData,NULL,NULL);
592 s32 USB_ReadBlkMsgAsync(s32 fd,u8 bEndpoint,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
594 return __usb_interrupt_bulk_message(fd,USB_IOCTL_BLKMSG,bEndpoint,wLength,rpData,cb,usrdata);
597 s32 USB_WriteBlkMsg(s32 fd,u8 bEndpoint,u16 wLength,void *rpData)
599 return __usb_interrupt_bulk_message(fd,USB_IOCTL_BLKMSG,bEndpoint,wLength,rpData,NULL,NULL);
602 s32 USB_WriteBlkMsgAsync(s32 fd,u8 bEndpoint,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
604 return __usb_interrupt_bulk_message(fd,USB_IOCTL_BLKMSG,bEndpoint,wLength,rpData,cb,usrdata);
607 s32 USB_ReadCtrlMsg(s32 fd,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *rpData)
609 return __usb_control_message(fd,bmRequestType,bmRequest,wValue,wIndex,wLength,rpData,NULL,NULL);
612 s32 USB_ReadCtrlMsgAsync(s32 fd,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
614 return __usb_control_message(fd,bmRequestType,bmRequest,wValue,wIndex,wLength,rpData,cb,usrdata);
617 s32 USB_WriteCtrlMsg(s32 fd,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *rpData)
619 return __usb_control_message(fd,bmRequestType,bmRequest,wValue,wIndex,wLength,rpData,NULL,NULL);
622 s32 USB_WriteCtrlMsgAsync(s32 fd,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *rpData,usbcallback cb,void *usrdata)
624 return __usb_control_message(fd,bmRequestType,bmRequest,wValue,wIndex,wLength,rpData,cb,usrdata);
627 s32 USB_DeviceRemovalNotifyAsync(s32 fd,usbcallback cb,void *userdata)
629 return IOS_IoctlAsync(fd,USB_IOCTL_DEVREMOVALHOOK,NULL,0,NULL,0,cb,userdata);
632 s32 USB_DeviceInsertNotifyAsync(const char *devpath,u16 vid,u16 pid,usbcallback cb,void *usrdata)
634 char *path;
635 s32 fd = -1;
636 s32 ret = IPC_ENOMEM;
637 u16 *pvid = NULL;
638 u16 *ppid = NULL;
639 ioctlv *vec = NULL;
640 struct _usb_cb *msgcb = NULL;
642 if(devpath==NULL || *devpath=='\0') return IPC_EINVAL;
644 path = (char*)iosAlloc(hId,IPC_MAXPATH_LEN);
645 if(path==NULL) return IPC_ENOMEM;
647 strncpy(path,devpath,IPC_MAXPATH_LEN);
648 fd = IOS_Open(path,IPC_OPEN_NONE);
649 if(fd<0) {
650 ret = fd;
651 goto done;
654 vec = iosAlloc(hId,sizeof(ioctlv)*2);
655 if(vec==NULL) goto done;
657 msgcb = iosAlloc(hId,sizeof(struct _usb_cb));
658 if(msgcb==NULL) goto done;
660 pvid = iosAlloc(hId,32);
661 if(pvid==NULL) goto done;
662 *pvid = vid;
664 ppid = iosAlloc(hId,32);
665 if(ppid==NULL) goto done;
666 *ppid = pid;
668 vec[0].data = pvid;
669 vec[0].len = sizeof(u16);
670 vec[1].data = ppid;
671 vec[1].len = sizeof(u16);
673 msgcb->fd = fd;
674 msgcb->cb = cb;
675 msgcb->vec = vec;
676 msgcb->usrdata = usrdata;
677 return IOS_IoctlvAsync(fd,USB_IOCTL_DEVINSERTHOOK,2,0,vec,__usb_device_notificationCB,msgcb);
679 done:
680 if(ppid!=NULL) iosFree(hId,ppid);
681 if(pvid!=NULL) iosFree(hId,pvid);
682 if(msgcb!=NULL) iosFree(hId,msgcb);
683 if(vec!=NULL) iosFree(hId,vec);
684 if(path!=NULL) iosFree(hId,path);
686 if(fd>=0) IOS_Close(fd);
688 return ret;
691 void USB_SuspendDevice(s32 fd)
693 IOS_Ioctl(fd,USB_IOCTL_SUSPENDDEV,NULL,0,NULL,0);
696 void USB_ResumeDevice(s32 fd)
698 IOS_Ioctl(fd,USB_IOCTL_RESUMEDEV,NULL,0,NULL,0);
701 s32 USB_GetDeviceList(const char *devpath,void *descr_buffer,u8 num_descr,u8 b0,u8 *cnt_descr)
703 s32 fd,ret;
704 char *path;
705 u8 cntdevs;
707 if(devpath==NULL || *devpath=='\0') return IPC_EINVAL;
709 path = (char*)iosAlloc(hId,IPC_MAXPATH_LEN);
710 if(path==NULL) return IPC_ENOMEM;
712 strncpy(path,devpath,IPC_MAXPATH_LEN);
713 fd = IOS_Open(path,IPC_OPEN_NONE);
714 if(fd<0) {
715 iosFree(hId,path);
716 return fd;
719 cntdevs = 0;
720 ret = IOS_IoctlvFormat(hId,fd,USB_IOCTL_GETDEVLIST,"bb:dd",num_descr,b0,&cntdevs,sizeof(cntdevs),descr_buffer,(num_descr<<3));
721 if(ret>=0) *cnt_descr = cntdevs;
723 iosFree(hId,path);
724 IOS_Close(fd);
725 return ret;
728 s32 USB_SetConfiguration(s32 fd, u8 configuration)
730 return __usb_control_message(fd, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_DEVICE), USB_REQ_SETCONFIG, configuration, 0, 0, NULL, NULL, NULL);
733 s32 USB_GetConfiguration(s32 fd, u8 *configuration)
735 u8 *_configuration;
736 s32 retval;
738 _configuration = iosAlloc(hId, 1);
739 if(_configuration == NULL)
740 return IPC_ENOMEM;
742 retval = __usb_control_message(fd, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_DEVICE), USB_REQ_GETCONFIG, 0, 0, 1, _configuration, NULL, NULL);
743 if(retval >= 0)
744 *configuration = *_configuration;
745 iosFree(hId, _configuration);
747 return retval;
750 s32 USB_SetAlternativeInterface(s32 fd, u8 interface, u8 alternateSetting)
752 if(alternateSetting == 0)
753 return IPC_EINVAL;
754 return __usb_control_message(fd, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_INTERFACE), USB_REQ_SETINTERFACE, alternateSetting, interface, 0, NULL, NULL, NULL);
757 s32 USB_ClearHalt(s32 fd, u8 endpoint)
759 return __usb_control_message(fd, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_ENDPOINT), USB_REQ_CLEARFEATURE, USB_FEATURE_ENDPOINT_HALT, endpoint, 0, NULL, NULL, NULL);
762 #endif /* defined(HW_RVL) */