will boot sysmenu when press reset button and again license stuff
[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         printf("lololololool PADDING WTF :O lolololololo \n");
127         printf("lolololool PADDING WTF :O lolololololo \n");
128         printf("lololololool PADDING WTF :O lolololololo \n");
129         printf("lololololool PADDING WTF :O lolololololo \n");
130         printf("lolololool PADDING WTF :O lolololololo \n");
131         printf("lololololool PADDING WTF :O lolololololo \n");
132         printf("lollllool PADDING WTF :O lolololololo \n");
133         printf("lololololool PADDING WTF :O lolololololo \n");
134         printf("lolololool PADDING WTF :O lololoololo \n");
135         printf("lololololool PADDING WTF :O lolololololo \n");
136         printf("lolololool PADDING WTF :O lolololololo \n");
137         printf("lololololool PADDING WTF :O lolololololo \n");
138         printf("lollllool PADDING WTF :O lolololololo \n");
139         printf("lololololool PADDING WTF :O lolololololo \n");
140         printf("lolololool PADDING WTF :O lololoololo \n");
141         printf("lololololool PADDING WTF :O lolololololo \n");
142         printf("lolololool PADDING WTF :O lolololololo \n");
143         printf("lololololool PADDING WTF :O lolololololo \n");
144         printf("lollllool PADDING WTF :O lolololololo \n");
145         printf("lololololool PADDING WTF :O lolololololo \n");
146         printf("lolololool PADDING WTF :O lololoololo \n");
147         printf("lololololool PADDING WTF :O lolololololo \n");
148         printf("lolololool PADDING WTF :O lolololololo \n");
149         printf("lololololool PADDING WTF :O lolololololo \n");
150         printf("lollllool PADDING WTF :O lolololololo \n");
151         printf("lolololool PADDING WTF :O lolololololo \n");
152         printf("lololololool PADDING WTF :O lolololololo \n");
153         printf("lollllool PADDING WTF :O lolololololo \n");
154 #endif
155         u8 address = usb_next_address();
156         ret = usb_set_address(dev, address);
157         dev->address = address;
158         printf("set address to %d\n", dev->address);
159
160         /* get device descriptor&co */
161         ret = usb_get_desc_dev(dev);
162         if(ret < 0)
163                 return (void*) -1;
164
165         /* print device info */
166         lsusb(dev);
167
168         /* add device to device list */
169         struct element *tmp = (struct element *) malloc(sizeof(struct element));
170         tmp->data = (void *) dev;
171         list_add_tail(core.devices, tmp);
172
173         usb_probe_driver();
174
175         return dev;
176 }
177
178 void lsusb(struct usb_device *dev)
179 {
180         printf("=== Device Descriptor === \n");
181         printf("bLength 0x%02X\n", dev->bLength);
182         printf("bDescriptorType 0x%02X\n", dev->bDeviceClass);
183         printf("bcdUSB 0x%04X\n", dev->bcdUSB);
184         printf("bDeviceClass 0x%02X\n", dev->bDeviceClass);
185         printf("bDeviceSubClass 0x%02X\n", dev->bDeviceSubClass);
186         printf("bDeviceProtocoll 0x%02X\n", dev->bDeviceProtocoll);
187         printf("bMaxPacketSize 0x%02X\n", dev->bMaxPacketSize0);
188         printf("idVendor 0x%04X\n", dev->idVendor);
189         printf("idProduct 0x%04X\n", dev->idProduct);
190         printf("bcdDevice 0x%04X\n", dev->bcdDevice);
191         printf("iManufacturer(0x%02X): \"%s\"\n", dev->iManufacturer, dev->iManufacturer ? usb_get_string_simple(dev, dev->iManufacturer) : "no String");
192         printf("iProduct(0x%02X): \"%s\"\n", dev->iProduct, dev->iProduct ? usb_get_string_simple(dev, dev->iProduct) : "no String");
193         printf("iSerialNumber(0x%02X): \"%s\"\n", dev->iSerialNumber, dev->iSerialNumber ? usb_get_string_simple(dev, dev->iSerialNumber) : "no String");
194         printf("bNumConfigurations 0x%02X\n", dev->bNumConfigurations);
195
196         u8 c, i, e;
197         struct usb_conf *conf = dev->conf;
198         for(c=0; c <= dev->bNumConfigurations; c++) {
199                 printf("  === Configuration Descriptor %d ===\n", c+1);
200                 printf("  bLength 0x%02X\n", conf->bLength);
201                 printf("  bDescriptorType 0x%02X\n", conf->bDescriptorType);
202                 printf("  wTotalLength 0x%04X\n", conf->wTotalLength);
203                 printf("  bNumInterfaces 0x%02X\n", conf->bNumInterfaces);
204                 printf("  bConfigurationValue 0x%02X\n", conf->bConfigurationValue);
205                 printf("  iConfiguration (0x%02X): \"%s\"\n", conf->iConfiguration, conf->iConfiguration ? usb_get_string_simple(dev, conf->iConfiguration) : "no String");
206                 printf("  bmAttributes 0x%02X\n", conf->bmAttributes);
207                 printf("  bMaxPower 0x%02X\n", conf->bMaxPower);
208
209                 struct usb_intf *ifs = conf->intf;
210                 for(i=1; i <= conf->bNumInterfaces; i++) {
211                         printf("    === Interface Descriptor %d ===\n", i);
212                         printf("    bLength 0x%02X\n", ifs->bLength);
213                         printf("    bDescriptorType 0x%02X\n", ifs->bDescriptorType);
214                         printf("    bInterfaceNumber 0x%02X\n", ifs->bInterfaceNumber);
215                         printf("    bAlternateSetting 0x%02X\n", ifs->bAlternateSetting);
216                         printf("    bNumEndpoints 0x%02X\n", ifs->bNumEndpoints);
217                         printf("    bInterfaceClass 0x%02X\n", ifs->bInterfaceClass);
218                         printf("    bInterfaceSubClass 0x%02X\n", ifs->bInterfaceSubClass);
219                         printf("    bInterfaceProtocol 0x%02X\n", ifs->bInterfaceProtocol);
220                         printf("    iInterface (0x%02X): \"%s\"\n", ifs->iInterface, ifs->iInterface ? usb_get_string_simple(dev, ifs->iInterface) : "no String");
221
222                         struct usb_endp *ed = ifs->endp;
223                         for(e=1; e <= ifs->bNumEndpoints; e++) {
224                                 printf("      === Endpoint Descriptor %d ===\n", e);
225                                 printf("      bLength 0x%02X\n", ed->bLength);
226                                 printf("      bDescriptorType 0x%02X\n", ed->bDescriptorType);
227                                 printf("      bEndpointAddress 0x%02X\n", ed->bEndpointAddress);
228                                 printf("      bmAttributes 0x%02X\n", ed->bmAttributes);
229                                 printf("      wMaxPacketSize 0x%02X\n", ed->wMaxPacketSize);
230                                 printf("      bInterval 0x%02X\n", ed->bInterval);
231
232                                 ed = ed->next;
233                         } //endpoint
234
235                         ifs = ifs->next;
236                 } //interface
237
238                 conf = conf->next;
239         } //configuration
240 }
241
242 /**
243  * Find currently detached device and remove
244  * data structures
245  */
246 u8 usb_remove_device(struct usb_device * dev)
247 {
248         // FIXME!!!! dieser quatsch ist nur temporaer
249         free(core.devices->head);
250         free(core.devices);
251         core.devices = list_create();
252         return 1;
253 }
254
255 /**
256  * Register new driver at usb stack.
257  */
258 u8 usb_register_driver(struct usb_driver *dev)
259 {
260         /* add driver to driver list */
261         struct element *tmp = (struct element *) malloc(sizeof(struct element));
262         tmp->data = (void *) dev;
263         tmp->next = NULL;
264         list_add_tail(core.drivers, tmp);
265
266         /** 
267          * first check to find a suitable device 
268          * (root hub drivers need this call here)
269          */
270         dev->probe();
271
272         return 1;
273 }
274
275
276 /**
277  * Call every probe function from every registered
278  * driver, to check if there is a valid driver
279  * for the new device.  
280  */
281 void usb_probe_driver()
282 {
283         // call ever registered driver  
284         struct usb_driver *drv;
285         struct element *iterator = core.drivers->head;
286         while (iterator != NULL) {
287                 drv = (struct usb_driver *) iterator->data;
288                 drv->probe();
289                 iterator = iterator->next;
290         }
291 }
292
293 /**
294  * Not implemented.
295  */
296 struct usb_irp *usb_get_irp()
297 {
298         return 0;
299 }
300
301 /**
302  * Not implemented.
303  */
304 u8 usb_remove_irp(struct usb_irp *irp)
305 {
306
307         return 1;
308 }
309
310 /**
311  * Takes usb_irp and split it into
312  * several usb packeges (SETUP,IN,OUT)
313  * In the usbstack they are transported with the
314  * usb_transfer_descriptor data structure.
315  */
316 u16 usb_submit_irp(struct usb_irp *irp)
317 {
318         struct usb_transfer_descriptor *td;
319         u8 runloop = 1;
320         u16 restlength = irp->len;
321         u8 *td_buf_ptr = irp->buffer;
322         u8 mybuf[64];
323
324         u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)];
325
326         switch (irp->type) {
327         case USB_CTRL:
328                 /* alle requests mit dem gleichen algorithmus zerteilen
329                  * das einzige ist der spezielle get_Device_descriptor request
330                  * bei dem eine laenge von 64 angegeben ist.
331                  * wenn man an adresse 0 einen get_device_desciptor schickt
332                  * dann reichen die ersten 8 byte.
333                  */
334
335                 /***************** Setup Stage ***********************/
336                 td = usb_create_transfer_descriptor(irp);
337                 td->pid = USB_PID_SETUP;
338                 td->buffer = irp->buffer;
339
340                 /* control message are always 8 bytes */
341                 td->actlen = 8;
342
343                 togl = 0;
344                 /* start with data0 */
345                 td->togl = togl;
346                 togl = togl ? 0 : 1;
347
348                 /**** send token ****/
349                 hcdi_enqueue(td, irp->dev->ohci);
350
351                 /***************** Data Stage ***********************/
352                 /**
353                  * You can see at bit 7 of bmRequestType if this stage is used,
354                  * default requests are always 8 byte greate, from
355                  * host to device. Stage 3 is only neccessary if the request
356                  * expected datas from the device.
357                  * bit7 - 1 = from device to host -> yes we need data stage
358                  * bit7 - 0 = from host to device -> no send zero packet
359                  *
360                  * nach einem setup token kann nur ein IN token in stage 3 folgen
361                  * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
362                  *
363                  *
364                  * bit7 = 1
365                  *      Device to Host
366                  *      - es kommen noch Daten mit PID_IN an
367                  *      - host beendet mit PID_OUT DATA1 Zero
368                  * bit7 - 0
369                  *      Host zu Device (wie set address)
370                  *      - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
371                  */
372                 memcpy(mybuf, irp->buffer, td->actlen);
373                 usb_device_request *setup = (usb_device_request *) mybuf;
374                 u8 bmRequestType = setup->bmRequestType;
375                 free(td);
376
377                 /* check bit 7 of bmRequestType */
378                 if (bmRequestType & 0x80) { 
379                         /* schleife die die tds generiert */
380                         while (runloop && (restlength > 0)) {
381                                 td = usb_create_transfer_descriptor(irp);
382                                 td->actlen = irp->epsize;
383                                 /* stop loop if all bytes are send */
384                                 if (restlength < irp->epsize) {
385                                         runloop = 0;
386                                         td->actlen = restlength;
387                                 }
388
389                                 td->buffer = td_buf_ptr;
390                                 /* move pointer for next packet */
391                                 td_buf_ptr += irp->epsize;
392
393                                 td->pid = USB_PID_IN;
394                                 td->togl = togl;
395                                 togl = togl ? 0 : 1;
396
397                                 /* wenn device descriptor von adresse 0 angefragt wird werden nur
398                                  * die ersten 8 byte abgefragt
399                                  */
400                                 if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue & 0xff) == 1
401                                                 && td->devaddress == 0) {
402                                         /* stop loop */
403                                         runloop = 0;
404                                 }
405
406                                 /**** send token ****/
407                                 hcdi_enqueue(td, irp->dev->ohci);
408
409                                 /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
410                                 restlength = restlength - irp->epsize;
411                                 free(td);
412                         }
413                 }
414
415
416                 /***************** Status Stage ***********************/
417                 /* Zero packet for end */
418                 td = usb_create_transfer_descriptor(irp);
419                 td->togl = 1;                                                           /* zero data packet = always DATA1 packet */
420                 td->actlen = 0;
421                 td->buffer = NULL;
422
423                 /**
424                  * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
425                  * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
426                  */
427                 /* check bit 7 of bmRequestType */
428                 if (bmRequestType & 0x80) {
429                         td->pid = USB_PID_OUT;
430                 } else {
431                         td->pid = USB_PID_IN;
432                 }
433                 /**** send token ****/
434                 hcdi_enqueue(td, irp->dev->ohci);
435                 free(td);
436                 break;
437
438         case USB_BULK:
439                 //u8 runloop=1;
440                 //u16 restlength = irp->len;
441                 //char * td_buf_ptr=irp->buffer;
442
443                 /* schleife die die tds generiert */
444                 while (runloop) {
445                         td = usb_create_transfer_descriptor(irp);
446                         td->endpoint = td->endpoint & 0x7F;                             /* clear direction bit */
447
448                         /* max packet size for given endpoint */
449                         td->actlen = irp->epsize;
450
451                         /* Generate In Packet  */
452                         if (irp->endpoint & 0x80)
453                                 td->pid = USB_PID_IN;
454                         else
455                                 /* Generate Out Packet */
456                                 td->pid = USB_PID_OUT;
457
458                         /* stop loop if all bytes are send */
459                         if (restlength <= irp->epsize) {
460                                 runloop = 0;
461                                 td->actlen = restlength;
462                         }
463
464                         td->buffer = td_buf_ptr;
465                         /* move pointer for next packet */
466                         td_buf_ptr = td_buf_ptr + irp->epsize;
467
468                         td->togl = togl;
469                         togl = togl ? 0 : 1;
470                                 /**** send token ****/
471                         hcdi_enqueue(td, irp->dev->ohci);
472                         free(td);
473                 }
474                 /* next togl */
475                 //if(td->pid == USB_PID_OUT) {
476                 //if(togl==0) togl=1; else togl=0;
477                 //}
478                 irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
479
480                 break;
481         
482         case USB_INTR:
483                 //u8 runloop=1;
484                 //u16 restlength = irp->len;
485                 //char * td_buf_ptr=irp->buffer;
486
487                 /* schleife die die tds generiert */
488                 while (runloop && (restlength > 0)) {
489                         td = usb_create_transfer_descriptor(irp);
490                         /* max packet size for given endpoint */
491                         td->actlen = irp->epsize;
492
493                         td->pid = USB_PID_IN;
494                         /* TODO: USB_PID_OUT */
495
496                         /* stop loop if all bytes are send */
497                         if (restlength < irp->epsize) {
498                                 runloop = 0;
499                                 td->actlen = restlength;
500                         }
501
502                         td->buffer = td_buf_ptr;
503                         /* move pointer for next packet */
504                         td_buf_ptr += irp->epsize;
505
506                         td->togl = togl;
507                         togl = togl ? 0 : 1;
508                                 
509                         /**** send token ****/
510                         hcdi_enqueue(td, irp->dev->ohci);
511                         restlength = restlength - irp->epsize;
512                         free(td);
513                 }
514                 break;
515                 irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
516         }
517         hcdi_fire(irp->dev->ohci);
518
519         return 1;
520 }
521
522
523
524 /** 
525  * Create a transfer descriptor with an parent irp.
526  */
527 struct usb_transfer_descriptor *usb_create_transfer_descriptor(struct usb_irp * irp)
528 {
529         struct usb_transfer_descriptor *td =
530                         (struct usb_transfer_descriptor *) malloc(sizeof(struct usb_transfer_descriptor));
531
532         td->devaddress = irp->dev->address;
533         td->endpoint = irp->endpoint;
534         td->iso = 0;
535         td->state = USB_TRANSFER_DESCR_NONE;
536         td->maxp = irp->epsize;
537         td->fullspeed = irp->dev->fullspeed;
538         td->type = irp->type;
539
540         return td;
541 }
542