add ability to disable DVDX
[libogc.git] / lwbt / physbusif.c
blob1a14263cdd74a3342e62eee0a38fb964a05293a7
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <malloc.h>
5 #include <ogcsys.h>
6 #include <gccore.h>
7 #include <usb.h>
9 #include "hci.h"
10 #include "btmemb.h"
11 #include "physbusif.h"
13 #define STACKSIZE 32768
15 #define NUM_ACL_BUFS 30
16 #define NUM_CTRL_BUFS 45
18 #define ACL_BUF_SIZE 1800
19 #define CTRL_BUF_SIZE 660
21 #define ROUNDUP32(v) (((u32)(v)+0x1f)&~0x1f)
22 #define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f)
24 struct usbtxbuf
26 u32 txsize;
27 void *rpData;
30 static u32 __ntd_ohci = 0;
31 static u32 __ntd_ohci_initflag = 0;
32 static u16 __ntd_vid = 0;
33 static u16 __ntd_pid = 0;
34 static u32 __ntd_vid_pid_specified = 0;
35 static s32 __ntd_usb_fd = -1;
36 static u32 __wait4hci = 1;
37 static struct _usb_p __usbdev;
39 static struct memb_blks ctrlbufs;
40 static struct memb_blks aclbufs;
42 static u8 __ppc_btstack1[STACKSIZE] ATTRIBUTE_ALIGN(8);
43 static u8 __ppc_btstack2[STACKSIZE] ATTRIBUTE_ALIGN(8);
45 static s32 __issue_bulkread();
46 static s32 __issue_intrread();
48 extern u32 __IPC_ClntInit();
50 static s32 __usb_closeCB(s32 result,void *usrdata)
52 __usbdev.fd = -1;
53 return result;
56 static s32 __writectrlmsgCB(s32 result,void *usrdata)
58 if(usrdata!=NULL) btmemb_free(&ctrlbufs,usrdata);
59 return result;
62 static s32 __writebulkmsgCB(s32 result,void *usrdata)
64 if(usrdata!=NULL) btmemb_free(&aclbufs,usrdata);
65 return result;
68 static s32 __readbulkdataCB(s32 result,void *usrdata)
70 u8 *ptr;
71 u32 len;
72 struct pbuf *p,*q;
73 struct usbtxbuf *buf = (struct usbtxbuf*)usrdata;
75 if(__usbdev.openstate!=0x0002) return 0;
77 if(result>0) {
78 len = result;
79 p = btpbuf_alloc(PBUF_RAW,len,PBUF_POOL);
80 if(p!=NULL) {
81 ptr = buf->rpData;
82 for(q=p;q!=NULL && len>0;q=q->next) {
83 memcpy(q->payload,ptr,q->len);
84 ptr += q->len;
85 len -= q->len;
88 SYS_SwitchFiber((u32)p,0,0,0,(u32)hci_acldata_handler,(u32)(&__ppc_btstack2[STACKSIZE]));
89 btpbuf_free(p);
90 } else
91 ERROR("__readbulkdataCB: Could not allocate memory for pbuf.\n");
93 btmemb_free(&aclbufs,buf);
95 return __issue_bulkread();
98 static s32 __readintrdataCB(s32 result,void *usrdata)
100 u8 *ptr;
101 u32 len;
102 struct pbuf *p,*q;
103 struct usbtxbuf *buf = (struct usbtxbuf*)usrdata;
105 if(__usbdev.openstate!=0x0002) return 0;
107 if(result>0) {
108 len = result;
109 p = btpbuf_alloc(PBUF_RAW,len,PBUF_POOL);
110 if(p!=NULL) {
111 ptr = buf->rpData;
112 for(q=p;q!=NULL && len>0;q=q->next) {
113 memcpy(q->payload,ptr,q->len);
114 ptr += q->len;
115 len -= q->len;
118 SYS_SwitchFiber((u32)p,0,0,0,(u32)hci_event_handler,(u32)(&__ppc_btstack1[STACKSIZE]));
119 btpbuf_free(p);
120 } else
121 ERROR("__readintrdataCB: Could not allocate memory for pbuf.\n");
123 btmemb_free(&ctrlbufs,buf);
125 return __issue_intrread();
128 static s32 __issue_intrread()
130 s32 ret;
131 u32 len;
132 u8 *ptr;
133 struct usbtxbuf *buf;
135 if(__usbdev.openstate!=0x0002) return IPC_OK;
137 buf = (struct usbtxbuf*)btmemb_alloc(&ctrlbufs);
138 if(buf!=NULL) {
139 ptr = (u8*)((u32)buf + sizeof(struct usbtxbuf));
140 buf->rpData = (void*)ROUNDUP32(ptr);
141 len = (ctrlbufs.size - ((u32)buf->rpData - (u32)buf));
142 buf->txsize = ROUNDDOWN32(len);
143 ret = USB_ReadIntrMsgAsync(__usbdev.fd,__usbdev.hci_evt,buf->txsize,buf->rpData,__readintrdataCB,buf);
144 } else
145 ret = IPC_ENOMEM;
147 return ret;
150 static s32 __issue_bulkread()
152 s32 ret;
153 u32 len;
154 u8 *ptr;
155 struct usbtxbuf *buf;
157 if(__usbdev.openstate!=0x0002) return IPC_OK;
159 buf = (struct usbtxbuf*)btmemb_alloc(&aclbufs);
160 if(buf!=NULL) {
161 ptr = (u8*)((u32)buf + sizeof(struct usbtxbuf));
162 buf->rpData = (void*)ROUNDUP32(ptr);
163 len = (aclbufs.size - ((u32)buf->rpData - (u32)buf));
164 buf->txsize = ROUNDDOWN32(len);
165 ret = USB_ReadBlkMsgAsync(__usbdev.fd,__usbdev.acl_in,buf->txsize,buf->rpData,__readbulkdataCB,buf);
166 } else
167 ret = IPC_ENOMEM;
169 return ret;
172 static s32 __initUsbIOBuffer(struct memb_blks *blk,u32 buf_size,u32 num_bufs)
174 u32 len;
175 u8 *ptr = NULL;
177 len = ((MEM_ALIGN_SIZE(buf_size)+sizeof(u32))*num_bufs);
178 ptr = (u8*)ROUNDDOWN32(((u32)SYS_GetArena2Hi() - len));
179 if((u32)ptr<(u32)SYS_GetArena2Lo()) return -4;
181 SYS_SetArena2Hi(ptr);
183 blk->size = buf_size;
184 blk->num = num_bufs;
185 blk->mem = ptr;
187 btmemb_init(blk);
188 return 0;
191 static s32 __getDeviceId(u16 vid,u16 pid)
193 s32 ret = 0;
195 if(__ntd_ohci_initflag==0x0001) {
196 if(__ntd_ohci==0x0000)
197 ret = USB_OpenDevice("oh0",vid,pid,&__usbdev.fd);
198 else if(__ntd_ohci==0x0001)
199 ret = USB_OpenDevice("oh1",vid,pid,&__usbdev.fd);
200 } else
201 ret = USB_OpenDevice("oh1",vid,pid,&__usbdev.fd);
203 //printf("__getDeviceId(%04x,%04x,%d)\n",vid,pid,__usbdev.fd);
204 if(ret==0) __ntd_usb_fd = __usbdev.fd;
205 return ret;
208 static s32 __usb_register(pbcallback cb)
210 s32 ret = 0;
212 memset(&__usbdev,0,sizeof(struct _usb_p));
213 __usbdev.openstate = 5;
215 ret = __IPC_ClntInit();
216 if(ret<0) return ret;
218 ret = USB_Initialize();
219 if(ret<0) return ret;
221 __usbdev.fd = -1;
222 __usbdev.unregcb = cb;
223 if(__ntd_vid_pid_specified) {
224 __usbdev.vid = __ntd_vid;
225 __usbdev.pid = __ntd_pid;
226 } else {
227 __usbdev.vid = 0x057E;
228 __usbdev.pid = 0x0305;
231 ret = __getDeviceId(__usbdev.vid,__usbdev.pid);
232 if(ret<0) return ret;
234 __usbdev.acl_out = 0x02;
235 __usbdev.acl_in = 0x82;
236 __usbdev.hci_evt = 0x81;
237 __usbdev.hci_ctrl = 0x00;
239 __initUsbIOBuffer(&ctrlbufs,CTRL_BUF_SIZE,NUM_CTRL_BUFS);
240 __initUsbIOBuffer(&aclbufs,ACL_BUF_SIZE,NUM_ACL_BUFS);
242 __usbdev.openstate = 4;
243 __wait4hci = 1;
245 return ret;
248 static s32 __usb_open(pbcallback cb)
250 if(__usbdev.openstate!=0x0004) return -1;
252 __usbdev.closecb = cb;
253 __usbdev.openstate = 2;
255 __issue_intrread();
256 __issue_bulkread();
258 __wait4hci = 0;
259 return 0;
262 void __ntd_set_ohci(u8 hci)
264 if(hci==0x0000) {
265 __ntd_ohci = 0;
266 __ntd_ohci_initflag = 1;
267 } else if(hci==0x0001) {
268 __ntd_ohci = 1;
269 __ntd_ohci_initflag = 1;
273 void __ntd_set_pid_vid(u16 vid,u16 pid)
275 __ntd_vid = vid;
276 __ntd_pid = pid;
277 __ntd_vid_pid_specified = 1;
281 void physbusif_init()
283 s32 ret;
285 ret = __usb_register(NULL);
286 if(ret<0) return;
288 __usb_open(NULL);
291 void physbusif_close()
293 if(__usbdev.openstate!=0x0002) return;
295 __usbdev.openstate = 4;
296 __wait4hci = 1;
299 void physbusif_shutdown()
301 if(__usbdev.openstate!=0x0004) return;
302 USB_CloseDeviceAsync(&__usbdev.fd,__usb_closeCB,NULL);
305 void physbusif_reset_all()
307 return;
310 void physbusif_output(struct pbuf *p,u16_t len)
312 s32 ret;
313 u32 pos;
314 u8 *ptr;
315 struct pbuf *q;
316 struct memb_blks *mblks;
317 struct usbtxbuf *blkbuf;
319 if(__usbdev.openstate!=0x0002) return;
321 if(((u8*)p->payload)[0]==HCI_COMMAND_DATA_PACKET) mblks = &ctrlbufs;
322 else if(((u8*)p->payload)[0]==HCI_ACL_DATA_PACKET) mblks = &aclbufs;
323 else return;
325 blkbuf = btmemb_alloc(mblks);
326 if(blkbuf!=NULL) {
327 blkbuf->txsize = --len;
328 blkbuf->rpData = (void*)ROUNDUP32(((u32)blkbuf+sizeof(struct usbtxbuf)));
330 ptr = blkbuf->rpData;
331 for(q=p,pos=1;q!=NULL && len>0;q=q->next,pos=0) {
332 memcpy(ptr,q->payload+pos,(q->len-pos));
333 ptr += (q->len-pos);
334 len -= (q->len-pos);
337 if(((u8*)p->payload)[0]==HCI_COMMAND_DATA_PACKET) {
338 ret = USB_WriteCtrlMsgAsync(__usbdev.fd,0x20,0,0,0,blkbuf->txsize,blkbuf->rpData,__writectrlmsgCB,blkbuf);
339 } else if(((u8*)p->payload)[0]==HCI_ACL_DATA_PACKET) {
340 ret = USB_WriteBlkMsgAsync(__usbdev.fd,__usbdev.acl_out,blkbuf->txsize,blkbuf->rpData,__writebulkmsgCB,blkbuf);