1 /*-------------------------------------------------------------
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
28 -------------------------------------------------------------*/
40 #include <processor.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
65 static s32
__usb_device_notificationCB(s32 result
,void *usrdata
)
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
);
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
);
88 static s32
__usb_control_messageCB(s32 result
,void *usrdata
)
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
);
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
);
113 static s32
__usb_bulk_messageCB(s32 result
,void *usrdata
)
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
);
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
);
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
;
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
;
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
;
177 vec
[0].data
= pRqType
;
178 vec
[0].len
= sizeof(u8
);
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
);
188 vec
[5].len
= sizeof(u8
);
189 vec
[6].data
= rpData
;
190 vec
[6].len
= wLength
;
193 ret
= IOS_Ioctlv(fd
,USB_IOCTL_CTRLMSG
,6,1,vec
);
195 msgcb
= iosAlloc(hId
,sizeof(struct _usb_cb
));
196 if(msgcb
==NULL
) goto done
;
200 msgcb
->usrdata
= usrdata
;
202 return IOS_IoctlvAsync(fd
,USB_IOCTL_CTRLMSG
,6,1,vec
,__usb_control_messageCB
,msgcb
);
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
);
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
;
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
;
236 pLength
= iosAlloc(hId
,32);
237 if(pLength
==NULL
) goto done
;
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
;
248 ret
= IOS_Ioctlv(fd
,ioctl
,2,1,vec
);
250 msgcb
= iosAlloc(hId
,sizeof(struct _usb_cb
));
251 if(msgcb
==NULL
) goto done
;
255 msgcb
->usrdata
= usrdata
;
257 return IOS_IoctlvAsync(fd
,ioctl
,2,1,vec
,__usb_bulk_messageCB
,msgcb
);
261 if(pLength
!=NULL
) iosFree(hId
,pLength
);
262 if(pEndP
!=NULL
) iosFree(hId
,pEndP
);
263 if(vec
!=NULL
) iosFree(hId
,vec
);
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
)
278 if(buffer
[1]==USB_DT_ENDPOINT
|| buffer
[1]==USB_DT_INTERFACE
) break;
284 return (buffer
- ptr
);
289 if(hId
==-1) hId
= iosCreateHeap(USB_HEAPSIZE
);
290 if(hId
<0) return IPC_ENOMEM
;
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
)
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);
316 if(devicepath
!=NULL
) iosFree(hId
,devicepath
);
320 s32
USB_CloseDevice(s32
*fd
)
325 ret
= IOS_Close(*fd
);
331 s32
USB_CloseDeviceAsync(s32
*fd
,usbcallback cb
,void *usrdata
)
334 return IOS_CloseAsync(*fd
,cb
,usrdata
);
339 s32
USB_GetDeviceDescription(s32 fd
,usb_devdesc
*devdesc
)
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
);
355 s32
USB_GetDescriptors(s32 fd
, usb_devdesc
*udd
)
359 usb_configurationdesc
*ucd
= NULL
;
360 usb_interfacedesc
*uid
= NULL
;
361 usb_endpointdesc
*ued
= NULL
;
364 u32 iConf
, iInterface
, iEndpoint
;
366 buffer
= iosAlloc(hId
, sizeof(*udd
));
369 retval
= IPC_ENOHEAP
;
373 retval
= __usb_getdesc(fd
, buffer
, USB_DT_DEVICE
, 0, USB_DT_DEVICE_SIZE
);
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
)
390 for(iConf
= 0; iConf
< udd
->bNumConfigurations
; iConf
++)
392 buffer
= iosAlloc(hId
, USB_DT_CONFIG_SIZE
);
395 retval
= IPC_ENOHEAP
;
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
);
409 retval
= IPC_ENOHEAP
;
413 retval
= __usb_getdesc(fd
, buffer
, USB_DT_CONFIG
, iConf
, ucd
->wTotalLength
);
419 size
-= ucd
->bLength
;
422 ucd
->interfaces
= calloc(ucd
->bNumInterfaces
, sizeof(*ucd
->interfaces
));
423 if(ucd
->interfaces
== NULL
)
425 for(iInterface
= 0; iInterface
< ucd
->bNumInterfaces
; iInterface
++)
427 uid
= &ucd
->interfaces
[iInterface
];
428 memcpy(uid
, ptr
, USB_DT_INTERFACE_SIZE
);
430 size
-= uid
->bLength
;
432 uid
->endpoints
= calloc(uid
->bNumEndpoints
, sizeof(*uid
->endpoints
));
433 if(uid
->endpoints
== NULL
)
436 /* This skips vendor and class specific descriptors */
437 i
= __find_next_endpoint(ptr
, size
);
441 uid
->extra
= malloc(i
);
442 if(uid
->extra
== NULL
)
444 memcpy(uid
->extra
, ptr
, 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
);
454 ued
->wMaxPacketSize
= bswap16(ued
->wMaxPacketSize
);
457 iosFree(hId
, buffer
);
464 iosFree(hId
, buffer
);
466 USB_FreeDescriptors(udd
);
470 s32
USB_GetHIDDescriptor(s32 fd
,usb_hiddesc
*uhd
)
475 buffer
= iosAlloc(hId
,sizeof(usb_hiddesc
));
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
);
491 if(buffer
!=NULL
) iosFree(hId
,buffer
);
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
)
515 free(ucd
->interfaces
);
518 free(udd
->configurations
);
522 s32
USB_GetAsciiString(s32 fd
,u16 wIndex
,u16 wLangID
,u16 wLength
,void *rpData
)
527 u8
*rp
= (u8
*)rpData
;
532 buf
= iosAlloc(hId
, 255); /* 255 is the highest possible length of a descriptor */
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 */
542 memcpy(rpData
, buf
, wLength
);
551 while(ro
< (wLength
- 1) && bo
< buf
[0])
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
)
636 s32 ret
= IPC_ENOMEM
;
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
);
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
;
664 ppid
= iosAlloc(hId
,32);
665 if(ppid
==NULL
) goto done
;
669 vec
[0].len
= sizeof(u16
);
671 vec
[1].len
= sizeof(u16
);
676 msgcb
->usrdata
= usrdata
;
677 return IOS_IoctlvAsync(fd
,USB_IOCTL_DEVINSERTHOOK
,2,0,vec
,__usb_device_notificationCB
,msgcb
);
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
);
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
)
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
);
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
;
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
)
738 _configuration
= iosAlloc(hId
, 1);
739 if(_configuration
== NULL
)
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
);
744 *configuration
= *_configuration
;
745 iosFree(hId
, _configuration
);
750 s32
USB_SetAlternativeInterface(s32 fd
, u8 interface
, u8 alternateSetting
)
752 if(alternateSetting
== 0)
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) */