0b38e77d6c34ec6136a360041ba6d087ceee49f7
[ppcskel.git] / usb / core / core.c
1 /*
2  * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
3  * All rights reserved.
4  *
5  * Short descripton of file:
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions 
10  * are met:
11  *
12  *       * Redistributions of source code must retain the above copyright 
13  *               notice, this list of conditions and the following disclaimer.
14  *       * Redistributions in binary form must reproduce the above 
15  *               copyright notice, this list of conditions and the following 
16  *               disclaimer in the documentation and/or other materials provided 
17  *               with the distribution.
18  *       * Neither the name of the FH Augsburg nor the names of its 
19  *               contributors may be used to endorse or promote products derived 
20  *               from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 /*
35         ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader.
36         plugmii core
37
38 Copyright (C) 2009     Bernhard Urban <lewurm@gmx.net>
39 Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
40
41 # This code is licensed to you under the terms of the GNU GPL, version 2;
42 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
43 */
44
45 #include "core.h"
46 #include "../host/host.h"
47 #include "usb.h"
48 #include "../usbspec/usb11spec.h"
49 #include "../lib/list.h"
50 #include "../../malloc.h"
51 #include "../../bootmii_ppc.h" //printf
52 #include "../../string.h" //memset
53
54 /**
55  * Initialize USB stack.
56  */
57 void usb_init(u32 reg)
58 {
59         core.drivers = list_create();
60         core.devices = list_create();
61         core.nextaddress = 1;
62         hcdi_init(reg);
63 }
64
65 /**
66  * Get next free usb device address.
67  */
68 u8 usb_next_address()
69 {
70         u8 addr = core.nextaddress;
71         core.nextaddress++;
72         return addr;
73 }
74
75
76 /**
77  * Call this function periodically for 
78  * control and transfer management.
79  */
80 void usb_periodic()
81 {
82         // call ever registered driver  
83         struct usb_driver *drv;
84         struct element *iterator = core.drivers->head;
85         while (iterator != NULL) {
86                 drv = (struct usb_driver *) iterator->data;
87                 drv->check();
88                 iterator = iterator->next;
89         }
90 }
91
92
93 /** 
94  * Enumerate new device and create data structures 
95  * for the core. usb_add_device expected that
96  * the device answers to address zero.
97  */
98 struct usb_device *usb_add_device(u8 lowspeed, u32 reg)
99 {
100         struct usb_device *dev = (struct usb_device *) malloc(sizeof(struct usb_device));
101         dev->conf = (struct usb_conf *) malloc(sizeof(struct usb_conf));
102         dev->address = 0;
103         dev->fullspeed = lowspeed ? 0 : 1;
104         /* send at first time only 8 bytes for lowspeed devices
105          * 64 bytes for fullspeed
106          */
107         dev->bMaxPacketSize0 = lowspeed ? 8 : 64;
108         dev->ohci = reg;
109
110         dev->epSize[0] = 8;
111         dev->epSize[1] = 64;
112         dev->epSize[2] = 64;
113
114         dev->epTogl[0] = 0;
115         dev->epTogl[1] = 0;
116         dev->epTogl[2] = 0;
117
118         s8 ret;
119         ret = usb_get_desc_dev_simple(dev);
120         if(ret < 0) {
121                 return (void*) -1;
122         }
123
124 #define WTF
125 #ifdef WTF
126         volatile u8 wzf = 11;
127         if(0 == wzf) {
128                 printf("WTF WTF WTF WTF padding??? WTFWTF WTF\n");
129                 printf("WTF WTF WTF WTF padding??? WTF WTF WTF\n");
130                 printf("WTF TF WTF WTF padding??? WTF WTF WTF\n");
131                 printf("WTF WTF TF WTF padding??? WTF WTWTF\n");
132                 printf("TF WTF WTF WTF padding??? WTF WTF WTF\n");
133                 printf("WTF WTF WTF WT padding??? WTF WF WTF\n");
134                 printf("WTF WTF WTF WTF padding??? WTF WTF WTF\n");
135                 printf("WTF WTF WTF WTF padding??? WT WTF WTF\n");
136                 printf("WTF WTF WTF WTF pdding??? WTF WTF WTF\n");
137                 printf("WTF WTF WTF WTF paddin??? WTF WTF WTF\n");
138                 printf("WTF WTF WTF WTF padding??? WTF WTF WTF\n");
139                 printf("WTF WTF WTF WTF padding?? WT WTF WTF\n");
140                 printf("WTF WTF WTF WTF padding??? WTF WTF WTF\n");
141                 printf("WTF WTF WTF WTF padding??? WTFWTF WTF\n");
142         }
143 #endif
144         u8 address = usb_next_address();
145         ret = usb_set_address(dev, address);
146         dev->address = address;
147         printf("set address to %d\n", dev->address);
148
149         /* get device descriptor&co */
150         ret = usb_get_desc_dev(dev);
151         if(ret < 0)
152                 return (void*) -1;
153
154         /* print device info */
155         lsusb(dev);
156
157         /* add device to device list */
158         struct element *tmp = (struct element *) malloc(sizeof(struct element));
159         tmp->data = (void *) dev;
160         list_add_tail(core.devices, tmp);
161
162         usb_probe_driver();
163
164         return dev;
165 }
166
167 void lsusb(struct usb_device *dev)
168 {
169         printf("=== Device Descriptor === \n");
170         printf("bLength 0x%02X\n", dev->bLength);
171         printf("bDescriptorType 0x%02X\n", dev->bDeviceClass);
172         printf("bcdUSB 0x%04X\n", dev->bcdUSB);
173         printf("bDeviceClass 0x%02X\n", dev->bDeviceClass);
174         printf("bDeviceSubClass 0x%02X\n", dev->bDeviceSubClass);
175         printf("bDeviceProtocoll 0x%02X\n", dev->bDeviceProtocoll);
176         printf("bMaxPacketSize 0x%02X\n", dev->bMaxPacketSize0);
177         printf("idVendor 0x%04X\n", dev->idVendor);
178         printf("idProduct 0x%04X\n", dev->idProduct);
179         printf("bcdDevice 0x%04X\n", dev->bcdDevice);
180         printf("iManufacturer(0x%02X): \"%s\"\n", dev->iManufacturer, dev->iManufacturer ? usb_get_string_simple(dev, dev->iManufacturer) : "no String");
181         printf("iProduct(0x%02X): \"%s\"\n", dev->iProduct, dev->iProduct ? usb_get_string_simple(dev, dev->iProduct) : "no String");
182         printf("iSerialNumber(0x%02X): \"%s\"\n", dev->iSerialNumber, dev->iSerialNumber ? usb_get_string_simple(dev, dev->iSerialNumber) : "no String");
183         printf("bNumConfigurations 0x%02X\n", dev->bNumConfigurations);
184
185         u8 c, i, e;
186         struct usb_conf *conf = dev->conf;
187         for(c=0; c <= dev->bNumConfigurations; c++) {
188                 printf("  === Configuration Descriptor %d ===\n", c+1);
189                 printf("  bLength 0x%02X\n", conf->bLength);
190                 printf("  bDescriptorType 0x%02X\n", conf->bDescriptorType);
191                 printf("  wTotalLength 0x%04X\n", conf->wTotalLength);
192                 printf("  bNumInterfaces 0x%02X\n", conf->bNumInterfaces);
193                 printf("  bConfigurationValue 0x%02X\n", conf->bConfigurationValue);
194                 printf("  iConfiguration (0x%02X): \"%s\"\n", conf->iConfiguration, conf->iConfiguration ? usb_get_string_simple(dev, conf->iConfiguration) : "no String");
195                 printf("  bmAttributes 0x%02X\n", conf->bmAttributes);
196                 printf("  bMaxPower 0x%02X\n", conf->bMaxPower);
197
198                 struct usb_intf *ifs = conf->intf;
199                 for(i=1; i <= conf->bNumInterfaces; i++) {
200                         printf("    === Interface Descriptor %d ===\n", i);
201                         printf("    bLength 0x%02X\n", ifs->bLength);
202                         printf("    bDescriptorType 0x%02X\n", ifs->bDescriptorType);
203                         printf("    bInterfaceNumber 0x%02X\n", ifs->bInterfaceNumber);
204                         printf("    bAlternateSetting 0x%02X\n", ifs->bAlternateSetting);
205                         printf("    bNumEndpoints 0x%02X\n", ifs->bNumEndpoints);
206                         printf("    bInterfaceClass 0x%02X\n", ifs->bInterfaceClass);
207                         printf("    bInterfaceSubClass 0x%02X\n", ifs->bInterfaceSubClass);
208                         printf("    bInterfaceProtocol 0x%02X\n", ifs->bInterfaceProtocol);
209                         printf("    iInterface (0x%02X): \"%s\"\n", ifs->iInterface, ifs->iInterface ? usb_get_string_simple(dev, ifs->iInterface) : "no String");
210
211                         struct usb_endp *ed = ifs->endp;
212                         for(e=1; e <= ifs->bNumEndpoints; e++) {
213                                 printf("      === Endpoint Descriptor %d ===\n", e);
214                                 printf("      bLength 0x%02X\n", ed->bLength);
215                                 printf("      bDescriptorType 0x%02X\n", ed->bDescriptorType);
216                                 printf("      bEndpointAddress 0x%02X\n", ed->bEndpointAddress);
217                                 printf("      bmAttributes 0x%02X\n", ed->bmAttributes);
218                                 printf("      wMaxPacketSize 0x%02X\n", ed->wMaxPacketSize);
219                                 printf("      bInterval 0x%02X\n", ed->bInterval);
220
221                                 ed = ed->next;
222                         } //endpoint
223
224                         ifs = ifs->next;
225                 } //interface
226
227                 conf = conf->next;
228         } //configuration
229 }
230
231 /**
232  * Find currently detached device and remove
233  * data structures
234  */
235 u8 usb_remove_device(struct usb_device * dev)
236 {
237         // FIXME!!!! dieser quatsch ist nur temporaer
238         free(core.devices->head);
239         free(core.devices);
240         core.devices = list_create();
241         return 1;
242 }
243
244 /**
245  * Register new driver at usb stack.
246  */
247 u8 usb_register_driver(struct usb_driver *dev)
248 {
249         /* add driver to driver list */
250         struct element *tmp = (struct element *) malloc(sizeof(struct element));
251         tmp->data = (void *) dev;
252         tmp->next = NULL;
253         list_add_tail(core.drivers, tmp);
254
255         /** 
256          * first check to find a suitable device 
257          * (root hub drivers need this call here)
258          */
259         dev->probe();
260
261         return 1;
262 }
263
264
265 /**
266  * Call every probe function from every registered
267  * driver, to check if there is a valid driver
268  * for the new device.  
269  */
270 void usb_probe_driver()
271 {
272         // call ever registered driver  
273         struct usb_driver *drv;
274         struct element *iterator = core.drivers->head;
275         while (iterator != NULL) {
276                 drv = (struct usb_driver *) iterator->data;
277                 drv->probe();
278                 iterator = iterator->next;
279         }
280 }
281
282 /**
283  * Not implemented.
284  */
285 struct usb_irp *usb_get_irp()
286 {
287         return 0;
288 }
289
290 /**
291  * Not implemented.
292  */
293 u8 usb_remove_irp(struct usb_irp *irp)
294 {
295
296         return 1;
297 }
298
299 /**
300  * Takes usb_irp and split it into
301  * several usb packeges (SETUP,IN,OUT)
302  * In the usbstack they are transported with the
303  * usb_transfer_descriptor data structure.
304  */
305 u16 usb_submit_irp(struct usb_irp *irp)
306 {
307         struct usb_transfer_descriptor *td;
308         u8 runloop = 1;
309         u16 restlength = irp->len;
310         u8 *td_buf_ptr = irp->buffer;
311         u8 mybuf[64];
312
313         u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)];
314
315         switch (irp->type) {
316         case USB_CTRL:
317                 /* alle requests mit dem gleichen algorithmus zerteilen
318                  * das einzige ist der spezielle get_Device_descriptor request
319                  * bei dem eine laenge von 64 angegeben ist.
320                  * wenn man an adresse 0 einen get_device_desciptor schickt
321                  * dann reichen die ersten 8 byte.
322                  */
323
324                 /***************** Setup Stage ***********************/
325                 td = usb_create_transfer_descriptor(irp);
326                 td->pid = USB_PID_SETUP;
327                 td->buffer = irp->buffer;
328
329                 /* control message are always 8 bytes */
330                 td->actlen = 8;
331
332                 togl = 0;
333                 /* start with data0 */
334                 td->togl = togl;
335                 togl = togl ? 0 : 1;
336
337                 /**** send token ****/
338                 hcdi_enqueue(td, irp->dev->ohci);
339
340                 /***************** Data Stage ***********************/
341                 /**
342                  * You can see at bit 7 of bmRequestType if this stage is used,
343                  * default requests are always 8 byte greate, from
344                  * host to device. Stage 3 is only neccessary if the request
345                  * expected datas from the device.
346                  * bit7 - 1 = from device to host -> yes we need data stage
347                  * bit7 - 0 = from host to device -> no send zero packet
348                  *
349                  * nach einem setup token kann nur ein IN token in stage 3 folgen
350                  * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
351                  *
352                  *
353                  * bit7 = 1
354                  *      Device to Host
355                  *      - es kommen noch Daten mit PID_IN an
356                  *      - host beendet mit PID_OUT DATA1 Zero
357                  * bit7 - 0
358                  *      Host zu Device (wie set address)
359                  *      - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
360                  */
361                 memcpy(mybuf, irp->buffer, td->actlen);
362                 usb_device_request *setup = (usb_device_request *) mybuf;
363                 u8 bmRequestType = setup->bmRequestType;
364                 free(td);
365
366                 /* check bit 7 of bmRequestType */
367                 if (bmRequestType & 0x80) { 
368                         /* schleife die die tds generiert */
369                         while (runloop && (restlength > 0)) {
370                                 td = usb_create_transfer_descriptor(irp);
371                                 td->actlen = irp->epsize;
372                                 /* stop loop if all bytes are send */
373                                 if (restlength < irp->epsize) {
374                                         runloop = 0;
375                                         td->actlen = restlength;
376                                 }
377
378                                 td->buffer = td_buf_ptr;
379                                 /* move pointer for next packet */
380                                 td_buf_ptr += irp->epsize;
381
382                                 td->pid = USB_PID_IN;
383                                 td->togl = togl;
384                                 togl = togl ? 0 : 1;
385
386                                 /* wenn device descriptor von adresse 0 angefragt wird werden nur
387                                  * die ersten 8 byte abgefragt
388                                  */
389                                 if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue & 0xff) == 1
390                                                 && td->devaddress == 0) {
391                                         /* stop loop */
392                                         runloop = 0;
393                                 }
394
395                                 /**** send token ****/
396                                 hcdi_enqueue(td, irp->dev->ohci);
397
398                                 /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
399                                 restlength = restlength - irp->epsize;
400                                 free(td);
401                         }
402                 }
403
404
405                 /***************** Status Stage ***********************/
406                 /* Zero packet for end */
407                 td = usb_create_transfer_descriptor(irp);
408                 td->togl = 1;                                                           /* zero data packet = always DATA1 packet */
409                 td->actlen = 0;
410                 td->buffer = NULL;
411
412                 /**
413                  * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
414                  * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
415                  */
416                 /* check bit 7 of bmRequestType */
417                 if (bmRequestType & 0x80) {
418                         td->pid = USB_PID_OUT;
419                 } else {
420                         td->pid = USB_PID_IN;
421                 }
422                 /**** send token ****/
423                 hcdi_enqueue(td, irp->dev->ohci);
424                 free(td);
425                 break;
426
427         case USB_BULK:
428                 //u8 runloop=1;
429                 //u16 restlength = irp->len;
430                 //char * td_buf_ptr=irp->buffer;
431
432                 /* schleife die die tds generiert */
433                 while (runloop) {
434                         td = usb_create_transfer_descriptor(irp);
435                         td->endpoint = td->endpoint & 0x7F;                             /* clear direction bit */
436
437                         /* max packet size for given endpoint */
438                         td->actlen = irp->epsize;
439
440                         /* Generate In Packet  */
441                         if (irp->endpoint & 0x80)
442                                 td->pid = USB_PID_IN;
443                         else
444                                 /* Generate Out Packet */
445                                 td->pid = USB_PID_OUT;
446
447                         /* stop loop if all bytes are send */
448                         if (restlength <= irp->epsize) {
449                                 runloop = 0;
450                                 td->actlen = restlength;
451                         }
452
453                         td->buffer = td_buf_ptr;
454                         /* move pointer for next packet */
455                         td_buf_ptr = td_buf_ptr + irp->epsize;
456
457                         td->togl = togl;
458                         togl = togl ? 0 : 1;
459                                 /**** send token ****/
460                         hcdi_enqueue(td, irp->dev->ohci);
461                         free(td);
462                 }
463                 /* next togl */
464                 //if(td->pid == USB_PID_OUT) {
465                 //if(togl==0) togl=1; else togl=0;
466                 //}
467                 irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
468
469                 break;
470         
471         case USB_INTR:
472                 //u8 runloop=1;
473                 //u16 restlength = irp->len;
474                 //char * td_buf_ptr=irp->buffer;
475
476                 /* schleife die die tds generiert */
477                 while (runloop && (restlength > 0)) {
478                         td = usb_create_transfer_descriptor(irp);
479                         /* max packet size for given endpoint */
480                         td->actlen = irp->epsize;
481
482                         td->pid = USB_PID_IN;
483                         /* TODO: USB_PID_OUT */
484
485                         /* stop loop if all bytes are send */
486                         if (restlength < irp->epsize) {
487                                 runloop = 0;
488                                 td->actlen = restlength;
489                         }
490
491                         td->buffer = td_buf_ptr;
492                         /* move pointer for next packet */
493                         td_buf_ptr += irp->epsize;
494
495                         td->togl = togl;
496                         togl = togl ? 0 : 1;
497                                 
498                         /**** send token ****/
499                         hcdi_enqueue(td, irp->dev->ohci);
500                         restlength = restlength - irp->epsize;
501                         free(td);
502                 }
503                 break;
504                 irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
505         }
506         hcdi_fire(irp->dev->ohci);
507
508         return 1;
509 }
510
511
512
513 /** 
514  * Create a transfer descriptor with an parent irp.
515  */
516 struct usb_transfer_descriptor *usb_create_transfer_descriptor(struct usb_irp * irp)
517 {
518         struct usb_transfer_descriptor *td =
519                         (struct usb_transfer_descriptor *) malloc(sizeof(struct usb_transfer_descriptor));
520
521         td->devaddress = irp->dev->address;
522         td->endpoint = irp->endpoint;
523         td->iso = 0;
524         td->state = USB_TRANSFER_DESCR_NONE;
525         td->maxp = irp->epsize;
526         td->fullspeed = irp->dev->fullspeed;
527         td->type = irp->type;
528
529         return td;
530 }
531