some usb stack related clean up; BULK still untested
[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         /* trigger driver for this device */
238         struct usb_driver *drv;
239         struct element *iterator = core.drivers->head;
240         while (iterator != NULL) {
241                 drv = (struct usb_driver *) iterator->data;
242                 if(drv->data && !memcmp(drv->data, dev, sizeof(struct usb_device))) {
243                         drv->remove();
244                         break;
245                 }
246                 iterator = iterator->next;
247         }
248
249         /* remove from device list */
250         struct element *tmp = (struct element *) malloc(sizeof(struct element));
251         tmp->data = (void *) dev;
252         list_delete_element(core.devices, tmp);
253
254         printf("REMOVED\n");
255
256         return 1;
257 }
258
259 /**
260  * Register new driver at usb stack.
261  */
262 u8 usb_register_driver(struct usb_driver *dev)
263 {
264         /* add driver to driver list */
265         struct element *tmp = (struct element *) malloc(sizeof(struct element));
266         tmp->data = (void *) dev;
267         tmp->next = NULL;
268         list_add_tail(core.drivers, tmp);
269
270         /** 
271          * first check to find a suitable device 
272          * (root hub drivers need this call here)
273          */
274         dev->probe();
275
276         return 1;
277 }
278
279
280 /**
281  * Call every probe function from every registered
282  * driver, to check if there is a valid driver
283  * for the new device.  
284  */
285 void usb_probe_driver()
286 {
287         // call ever registered driver  
288         struct usb_driver *drv;
289         struct element *iterator = core.drivers->head;
290         while (iterator != NULL) {
291                 drv = (struct usb_driver *) iterator->data;
292                 drv->probe();
293                 iterator = iterator->next;
294         }
295 }
296
297 /**
298  * Not implemented.
299  */
300 struct usb_irp *usb_get_irp()
301 {
302         return 0;
303 }
304
305 /**
306  * Not implemented.
307  */
308 u8 usb_remove_irp(struct usb_irp *irp)
309 {
310
311         return 1;
312 }
313
314 /**
315  * Takes usb_irp and split it into
316  * several usb packeges (SETUP,IN,OUT)
317  * In the usbstack they are transported with the
318  * usb_transfer_descriptor data structure.
319  */
320 u16 usb_submit_irp(struct usb_irp *irp)
321 {
322         struct usb_transfer_descriptor *td;
323         u8 runloop = 1;
324         u16 restlength = irp->len;
325         u8 *td_buf_ptr = irp->buffer;
326         u8 mybuf[64];
327
328         u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)];
329
330         switch (irp->type) {
331         case USB_CTRL:
332                 /* alle requests mit dem gleichen algorithmus zerteilen
333                  * das einzige ist der spezielle get_Device_descriptor request
334                  * bei dem eine laenge von 64 angegeben ist.
335                  * wenn man an adresse 0 einen get_device_desciptor schickt
336                  * dann reichen die ersten 8 byte.
337                  */
338
339                 /***************** Setup Stage ***********************/
340                 td = usb_create_transfer_descriptor(irp);
341                 td->pid = USB_PID_SETUP;
342                 td->buffer = irp->buffer;
343
344                 /* control message are always 8 bytes */
345                 td->actlen = 8;
346
347                 togl = 0;
348                 /* start with data0 */
349                 td->togl = togl;
350                 togl = togl ? 0 : 1;
351
352                 /**** send token ****/
353                 hcdi_enqueue(td, irp->dev->ohci);
354
355                 /***************** Data Stage ***********************/
356                 /**
357                  * You can see at bit 7 of bmRequestType if this stage is used,
358                  * default requests are always 8 byte greate, from
359                  * host to device. Stage 3 is only neccessary if the request
360                  * expected datas from the device.
361                  * bit7 - 1 = from device to host -> yes we need data stage
362                  * bit7 - 0 = from host to device -> no send zero packet
363                  *
364                  * nach einem setup token kann nur ein IN token in stage 3 folgen
365                  * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
366                  *
367                  *
368                  * bit7 = 1
369                  *      Device to Host
370                  *      - es kommen noch Daten mit PID_IN an
371                  *      - host beendet mit PID_OUT DATA1 Zero
372                  * bit7 - 0
373                  *      Host zu Device (wie set address)
374                  *      - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
375                  */
376                 memcpy(mybuf, irp->buffer, td->actlen);
377                 usb_device_request *setup = (usb_device_request *) mybuf;
378                 u8 bmRequestType = setup->bmRequestType;
379                 free(td);
380
381                 /* check bit 7 of bmRequestType */
382                 if (bmRequestType & 0x80) { 
383                         /* schleife die die tds generiert */
384                         while (runloop && (restlength > 0)) {
385                                 td = usb_create_transfer_descriptor(irp);
386                                 td->actlen = irp->epsize;
387                                 /* stop loop if all bytes are send */
388                                 if (restlength < irp->epsize) {
389                                         runloop = 0;
390                                         td->actlen = restlength;
391                                 }
392
393                                 td->buffer = td_buf_ptr;
394                                 /* move pointer for next packet */
395                                 td_buf_ptr += irp->epsize;
396
397                                 td->pid = USB_PID_IN;
398                                 td->togl = togl;
399                                 togl = togl ? 0 : 1;
400
401                                 /* wenn device descriptor von adresse 0 angefragt wird werden nur
402                                  * die ersten 8 byte abgefragt
403                                  */
404                                 if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue & 0xff) == 1
405                                                 && td->devaddress == 0) {
406                                         /* stop loop */
407                                         runloop = 0;
408                                 }
409
410                                 /**** send token ****/
411                                 hcdi_enqueue(td, irp->dev->ohci);
412
413                                 /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
414                                 restlength = restlength - irp->epsize;
415                                 free(td);
416                         }
417                 }
418
419
420                 /***************** Status Stage ***********************/
421                 /* Zero packet for end */
422                 td = usb_create_transfer_descriptor(irp);
423                 td->togl = 1;                                                           /* zero data packet = always DATA1 packet */
424                 td->actlen = 0;
425                 td->buffer = NULL;
426
427                 /**
428                  * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
429                  * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
430                  */
431                 /* check bit 7 of bmRequestType */
432                 if (bmRequestType & 0x80) {
433                         td->pid = USB_PID_OUT;
434                 } else {
435                         td->pid = USB_PID_IN;
436                 }
437                 /**** send token ****/
438                 hcdi_enqueue(td, irp->dev->ohci);
439                 free(td);
440                 break;
441
442         case USB_BULK:
443         case USB_INTR:
444                 while (runloop && (restlength > 0)) {
445                         td = usb_create_transfer_descriptor(irp);
446                         /* max packet size for given endpoint */
447                         td->actlen = irp->epsize;
448
449                         td->pid = irp->endpoint & 0x80 ? USB_PID_IN : USB_PID_OUT;
450
451                         /* stop loop if all bytes are send */
452                         if (restlength < irp->epsize) {
453                                 runloop = 0;
454                                 td->actlen = restlength;
455                         }
456
457                         td->buffer = td_buf_ptr;
458                         /* move pointer for next packet */
459                         td_buf_ptr += irp->epsize;
460
461                         td->togl = togl;
462                         togl = togl ? 0 : 1;
463                                 
464                         /**** send token ****/
465                         hcdi_enqueue(td, irp->dev->ohci);
466                         restlength = restlength - irp->epsize;
467                         free(td);
468                 }
469                 break;
470                 irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
471         }
472         hcdi_fire(irp->dev->ohci);
473
474         return 1;
475 }
476
477
478
479 /** 
480  * Create a transfer descriptor with an parent irp.
481  */
482 struct usb_transfer_descriptor *usb_create_transfer_descriptor(struct usb_irp * irp)
483 {
484         struct usb_transfer_descriptor *td =
485                         (struct usb_transfer_descriptor *) malloc(sizeof(struct usb_transfer_descriptor));
486
487         td->devaddress = irp->dev->address;
488         td->endpoint = irp->endpoint & 0x7F;
489         td->iso = 0;
490         td->state = USB_TRANSFER_DESCR_NONE;
491         td->maxp = irp->epsize;
492         td->fullspeed = irp->dev->fullspeed;
493         td->type = irp->type;
494
495         return td;
496 }
497