fd47cdc538b74703314388dc9cf845c440229394
[ppcskel.git] / usb / core / usb.c
1 /*
2  * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
3  * All rights reserved.
4  *
5  * Short descripton of file:
6  * I take the function names and parameters mainly from
7  * libusb.sf.net.
8  *
9  *
10  * Redistribution and use in source and binary forms, with or without 
11  * modification, are permitted provided that the following conditions 
12  * are met:
13  *
14  *   * Redistributions of source code must retain the above copyright 
15  *     notice, this list of conditions and the following disclaimer.
16  *   * Redistributions in binary form must reproduce the above 
17  *     copyright notice, this list of conditions and the following 
18  *     disclaimer in the documentation and/or other materials provided 
19  *     with the distribution.
20  *   * Neither the name of the FH Augsburg nor the names of its 
21  *     contributors may be used to endorse or promote products derived 
22  *     from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 #include "usb.h"
38 #include "core.h"
39 #include "../host/host.h"
40 #include "../usbspec/usb11spec.h"
41 #include "../../malloc.h"
42 #include "../../string.h"
43
44 #define cleargbuf() memset(gbuf, 0, 0xff)
45 /* internal global buffer */
46 static u8 gbuf[0xff];
47
48
49 /******************* Device Operations **********************/
50
51 /**
52  * Open a device with verndor- and product-id for a communication.
53  */
54 struct usb_device *usb_open(u32 vendor_id, u32 product_id)
55 {
56         struct usb_device* dev;
57         struct element * iterator = core.devices->head;
58         while(iterator != NULL) {
59                 dev = (struct usb_device*)iterator->data;
60                 
61                 if(dev->idVendor==vendor_id&&dev->idProduct==product_id)
62                         return dev;
63
64                 iterator=iterator->next;
65         }
66
67         return NULL;
68 }
69
70
71 /**
72  * Open a device with an class code for a communication.
73  */
74 struct usb_device *usb_open_class(u8 class)
75 {
76         struct usb_device* dev;
77         struct element * iterator = core.devices->head;
78         while(iterator != NULL) {
79                 dev = (struct usb_device*)iterator->data;
80                 
81                 if(dev->bDeviceClass==class)
82                         return dev;
83
84                 iterator=iterator->next;
85         }
86         return NULL;
87 }
88
89 /* Close device after a communication.
90  */
91 s8 usb_close(struct usb_device *dev)
92 {
93
94         return 0;
95 }
96
97 s8 usb_reset(struct usb_device *dev)
98 {
99
100
101         return 0;
102 }
103
104
105 /******************* Control Transfer **********************/
106
107 /**
108  * Create a control transfer.
109  */
110 s8 usb_control_msg(struct usb_device *dev, u8 requesttype, u8 request,
111                 u16 value, u16 index, u16 length, u8 *buf, u16 timeout)
112 {
113         struct usb_irp *irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
114         irp->dev = dev;
115         irp->endpoint = 0;
116         
117         irp->epsize = dev->bMaxPacketSize0;
118         irp->type = USB_CTRL;
119
120         buf[0]=(u8)requesttype;
121         buf[1]=(u8)request;
122         buf[2]=(u8)(value);
123         buf[3]=(u8)(value >> 8);
124         buf[4]=(u8)(index);
125         buf[5]=(u8)(index >> 8);
126         buf[6]=(u8)(length);
127         buf[7]=(u8)(length >> 8);
128
129         irp->buffer = buf;
130         irp->len = length;
131         irp->timeout = timeout;
132
133         usb_submit_irp(irp);
134         free(irp);
135
136         return 0;
137 }
138
139 s8 usb_get_descriptor(struct usb_device *dev, u8 type, u8 index, u8 *buf, u8 size)
140 {
141         usb_control_msg(dev, 0x80, GET_DESCRIPTOR, (type << 8) | index, 0, size, buf, 0);
142         return 0;
143 }
144
145 s8 usb_get_string(struct usb_device *dev, u8 index, u8 langid)
146 {
147
148         return 0;
149 }
150
151 char *usb_get_string_simple(struct usb_device *dev, u8 index)
152 {
153         cleargbuf();
154         usb_get_descriptor(dev, STRING, index, gbuf, (u8) 8);
155         usb_get_descriptor(dev, STRING, index, gbuf, gbuf[0]);
156
157         char *str = (char*)malloc((gbuf[0]/2));
158         memset(str, '\0', (gbuf[0]/2));
159
160         u16 i;
161         for(i=0; i<(gbuf[0]/2)-1; i++) {
162                 str[i] = gbuf[2+(i*2)];
163                 printf("%c", str[i]);
164         }
165         printf("\n");
166
167         return str;
168 }
169
170 /* ask first 8 bytes of device descriptor with this special 
171  * GET Descriptor Request, when device address = 0
172  */
173 s8 usb_get_desc_dev_simple(struct usb_device *dev)
174 {
175         cleargbuf();
176         usb_get_descriptor(dev, DEVICE, 0, gbuf, 8);
177
178         if(!gbuf[7]) {
179                 printf("FU: %d\n", gbuf[7]);
180                 return -2;
181         }
182         dev->bMaxPacketSize0 = gbuf[7];
183         return 0;
184 }
185
186 s8 usb_get_desc_dev(struct usb_device *dev)
187 {
188         cleargbuf();
189         if (usb_get_desc_dev_simple(dev) < 0) {
190                 return -1;
191         }
192         usb_get_descriptor(dev, DEVICE, 0, gbuf, gbuf[0]);
193
194         dev->bLength = gbuf[0];
195         dev->bDescriptorType = gbuf[1];
196         dev->bcdUSB = (u16) (gbuf[3] << 8 | gbuf[2]);
197         dev->bDeviceClass = gbuf[4];
198         dev->bDeviceSubClass = gbuf[5];
199         dev->bDeviceProtocoll = gbuf[6];
200         dev->idVendor = (u16) (gbuf[9] << 8) | (gbuf[8]);
201         dev->idProduct = (u16) (gbuf[11] << 8) | (gbuf[10]);
202         dev->bcdDevice = (u16) (gbuf[13] << 8) | (gbuf[12]);
203         dev->iManufacturer = gbuf[14];
204         dev->iProduct = gbuf[15];
205         dev->iSerialNumber = gbuf[16];
206         dev->bNumConfigurations = gbuf[17];
207
208         return 0;
209 }
210
211 s8 usb_get_desc_configuration(struct usb_device *dev, u8 index)
212 {
213         cleargbuf();
214         usb_get_descriptor(dev, CONFIGURATION, index, gbuf, 8);
215         usb_get_descriptor(dev, CONFIGURATION, index, gbuf, gbuf[0]);
216
217         dev->conf->bLength = gbuf[0];
218         dev->conf->bDescriptorType = gbuf[1];
219         dev->conf->wTotalLength = (u16) (gbuf[3] << 8 | gbuf[2]);
220         dev->conf->bNumInterfaces = gbuf[4];
221         dev->conf->bConfigurationValue = gbuf[5];
222         dev->conf->iConfiguration = gbuf[6];
223         dev->conf->bmAttributes = gbuf[7];
224         dev->conf->bMaxPower = gbuf[8];
225
226         return 0;
227 }
228
229 /* returns more information about CONFIGURATION, including
230  * INTERFACE(s) and ENDPOINT(s)
231  * usb_get_desc_configuration() must be called for this device before
232  */
233 s8 usb_get_desc_config_ext(struct usb_device *dev, u8 index) {
234         cleargbuf();
235
236         usb_get_desc_configuration(dev, index);
237         usb_get_descriptor(dev, CONFIGURATION, index, gbuf, dev->conf->wTotalLength);
238
239
240         printf("=============\nafter usb_get_desc_config_ext:\n");
241         hexdump((void*) gbuf, dev->conf->wTotalLength);
242         return 0;
243 }
244
245 s8 usb_set_address(struct usb_device *dev, u8 address)
246 {
247         cleargbuf();
248         usb_control_msg(dev, 0x00, SET_ADDRESS, address, 0, 0, gbuf, 0);
249         return 0;
250 }
251
252 s8 usb_set_configuration(struct usb_device *dev, u8 configuration)
253 {
254         cleargbuf();
255         usb_control_msg(dev, 0x00, SET_CONFIGURATION, configuration, 0, 0, gbuf, 0);
256         return 0;
257 }
258
259 s8 usb_set_altinterface(struct usb_device *dev, u8 alternate)
260 {
261
262         return 0;
263 }
264
265
266
267 /******************* Bulk Transfer **********************/
268
269 /**
270  * Write to an a bulk endpoint.
271  */
272 s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
273 {
274         struct usb_irp * irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
275         irp->dev = dev;
276         //irp->devaddress = dev->address;
277         
278         irp->endpoint = ep;
279         irp->epsize = dev->epSize[ep]; // ermitteln
280         irp->type = USB_BULK;
281
282         irp->buffer = buf;
283         irp->len = size;
284         irp->timeout = timeout;
285
286         usb_submit_irp(irp);
287         free(irp);
288
289         return 0;
290 }
291
292 /**
293  * Read from an bulk endpoint.
294  */
295 s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
296 {
297         struct usb_irp * irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
298         //irp->devaddress = dev->address;
299         irp->dev = dev;
300         
301         irp->endpoint = ep | 0x80;      // from device to host
302         irp->epsize = dev->epSize[ep]; // ermitteln
303         irp->type = USB_BULK;
304
305         irp->buffer = buf;
306         irp->len = size;
307         irp->timeout = timeout;
308
309         usb_submit_irp(irp);
310         free(irp);
311
312         return 0;
313 }
314
315
316 /******************* Interrupt Transfer **********************/
317 /**
318  * Write to an interrupt endpoint.
319  */
320 s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
321 {
322
323         return 0;
324 }
325
326 /**
327  * Read from an interrupt endpoint.
328  */
329 s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
330 {
331
332         return 0;
333 }
334
335
336 /******************* Isochron Transfer **********************/
337
338 /**
339  * Write to an isochron endpoint.
340  */
341 s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
342 {
343
344         return 0;
345 }
346
347 /**
348  * Read from an isochron endpoint.
349  */
350 s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
351 {
352
353
354         return 0;
355 }
356
357
358 //#endif        //_USB_H_