m00h @ previous commit: using wTotalLenght of CONFIGURATION you get
[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
45 /******************* Device Operations **********************/
46
47 /**
48  * Open a device with verndor- and product-id for a communication.
49  */
50 struct usb_device *usb_open(u32 vendor_id, u32 product_id)
51 {
52         struct usb_device* dev;
53         struct element * iterator = core.devices->head;
54         while(iterator != NULL) {
55                 dev = (struct usb_device*)iterator->data;
56                 
57                 if(dev->idVendor==vendor_id&&dev->idProduct==product_id)
58                         return dev;
59
60                 iterator=iterator->next;
61         }
62
63         return NULL;
64 }
65
66
67 /**
68  * Open a device with an class code for a communication.
69  */
70 struct usb_device *usb_open_class(u8 class)
71 {
72         struct usb_device* dev;
73         struct element * iterator = core.devices->head;
74         while(iterator != NULL) {
75                 dev = (struct usb_device*)iterator->data;
76                 
77                 if(dev->bDeviceClass==class)
78                         return dev;
79
80                 iterator=iterator->next;
81         }
82         return NULL;
83 }
84
85 /* Close device after a communication.
86  */
87 s8 usb_close(struct usb_device *dev)
88 {
89
90         return 0;
91 }
92
93 s8 usb_reset(struct usb_device *dev)
94 {
95
96
97         return 0;
98 }
99
100
101 /******************* Control Transfer **********************/
102
103 /**
104  * Create a control transfer.
105  */
106 s8 usb_control_msg(struct usb_device *dev, u8 requesttype, u8 request,
107                 u16 value, u16 index, u16 length, u8 *buf, u16 timeout)
108 {
109         struct usb_irp *irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
110         irp->dev = dev;
111         irp->endpoint = 0;
112         
113         irp->epsize = dev->bMaxPacketSize0;
114         irp->type = USB_CTRL;
115
116         buf[0]=(u8)requesttype;
117         buf[1]=(u8)request;
118         buf[2]=(u8)(value);
119         buf[3]=(u8)(value >> 8);
120         buf[4]=(u8)(index);
121         buf[5]=(u8)(index >> 8);
122         buf[6]=(u8)(length);
123         buf[7]=(u8)(length >> 8);
124
125         irp->buffer = buf;
126         irp->len = length;
127         irp->timeout = timeout;
128
129         usb_submit_irp(irp);
130         free(irp);
131
132         return 0;
133 }
134
135
136 s8 usb_get_string(struct usb_device *dev, u8 index, u8 langid, u8 *buf, u8 buflen)
137 {
138
139         return 0;
140 }
141
142
143 char *usb_get_string_simple(struct usb_device *dev, u8 index, u8 *buf, u8 size)
144 {
145         if(size < 8) {
146                 return (char*) -1;
147         }
148         usb_get_descriptor(dev, STRING, index, buf, (u8) 8);
149         size = size >= (buf[0]) ? (buf[0]) : size;
150         usb_get_descriptor(dev, STRING, index, buf, size);
151
152         char *str = (char*)malloc((size/2));
153         memset(str, '\0', (size/2));
154
155         u16 i;
156         for(i=0; i<(size/2)-1; i++) {
157                 str[i] = buf[2+(i*2)];
158                 printf("%c", str[i]);
159         }
160         printf("\n");
161
162         return str;
163 }
164
165 s8 usb_get_descriptor(struct usb_device *dev, u8 type, u8 index, u8 *buf, u8 size)
166 {
167         usb_control_msg(dev, 0x80, GET_DESCRIPTOR, (type << 8) | index, 0, size, buf, 0);
168         return 0;
169 }
170
171 /* ask first 8 bytes of device descriptor with this special 
172  * GET Descriptor Request, when device address = 0
173  */
174 s8 usb_get_desc_dev_simple(struct usb_device *dev, u8 *buf, u8 size)
175 {
176         if(size < 8) {
177                 return -1;
178         }
179         usb_get_descriptor(dev, DEVICE, 0, buf, 8);
180
181         if(!buf[7]) {
182                 printf("FU: %d\n", buf[7]);
183                 return -2;
184         }
185         dev->bMaxPacketSize0 = buf[7];
186         return 0;
187 }
188
189 s8 usb_get_desc_dev(struct usb_device *dev, u8 *buf, u8 size)
190 {
191         if (size < 0x12 || usb_get_desc_dev_simple(dev, buf, size) < 0) {
192                 return -1;
193         }
194         usb_get_descriptor(dev, DEVICE, 0, buf, size >= buf[0] ? buf[0] : size);
195
196         dev->bLength = buf[0];
197         dev->bDescriptorType = buf[1];
198         dev->bcdUSB = (u16) (buf[3] << 8 | buf[2]);
199         dev->bDeviceClass = buf[4];
200         dev->bDeviceSubClass = buf[5];
201         dev->bDeviceProtocoll = buf[6];
202         dev->idVendor = (u16) (buf[9] << 8) | (buf[8]);
203         dev->idProduct = (u16) (buf[11] << 8) | (buf[10]);
204         dev->bcdDevice = (u16) (buf[13] << 8) | (buf[12]);
205         dev->iManufacturer = buf[14];
206         dev->iProduct = buf[15];
207         dev->iSerialNumber = buf[16];
208         dev->bNumConfigurations = buf[17];
209
210         return 0;
211 }
212
213 s8 usb_get_desc_configuration(struct usb_device *dev, u8 index, u8 *buf, u8 size)
214 {
215         if(size < 9) {
216                 return -1;
217         }
218         usb_get_descriptor(dev, CONFIGURATION, index, buf, 8);
219         usb_get_descriptor(dev, CONFIGURATION, index, buf, size >= buf[0] ? buf[0] : size);
220
221         dev->conf->bLength = buf[0];
222         dev->conf->bDescriptorType = buf[1];
223         dev->conf->wTotalLength = (u16) (buf[3] << 8 | buf[2]);
224         dev->conf->bNumInterfaces = buf[4];
225         dev->conf->bConfigurationValue = buf[5];
226         dev->conf->iConfiguration = buf[6];
227         dev->conf->bmAttributes = buf[7];
228         dev->conf->bMaxPower = buf[8];
229         return 0;
230 }
231
232 s8 usb_get_desc_interface(struct usb_device *dev, u8 index, u8 *buf, u8 size)
233 {
234         if(size < 9) {
235                 return -1;
236         }
237         usb_get_descriptor(dev, INTERFACE, index, buf, 9);
238
239         return 0;
240 }
241
242 s8 usb_set_address(struct usb_device *dev, u8 address)
243 {
244         u8 buf[64];
245         usb_control_msg(dev, 0x00, SET_ADDRESS, address, 0, 0, buf, 0);
246         return 0;
247 }
248
249 s8 usb_set_configuration(struct usb_device *dev, u8 configuration)
250 {
251         u8 buf[64];
252         usb_control_msg(dev, 0x00, SET_CONFIGURATION, configuration, 0, 0, buf, 0);
253         return 0;
254 }
255
256 s8 usb_set_altinterface(struct usb_device *dev, u8 alternate)
257 {
258
259         return 0;
260 }
261
262
263
264 /******************* Bulk Transfer **********************/
265
266 /**
267  * Write to an a bulk endpoint.
268  */
269 s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
270 {
271         struct usb_irp * irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
272         irp->dev = dev;
273         //irp->devaddress = dev->address;
274         
275         irp->endpoint = ep;
276         irp->epsize = dev->epSize[ep]; // ermitteln
277         irp->type = USB_BULK;
278
279         irp->buffer = buf;
280         irp->len = size;
281         irp->timeout = timeout;
282
283         usb_submit_irp(irp);
284         free(irp);
285
286         return 0;
287 }
288
289 /**
290  * Read from an bulk endpoint.
291  */
292 s8 usb_bulk_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
293 {
294         struct usb_irp * irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
295         //irp->devaddress = dev->address;
296         irp->dev = dev;
297         
298         irp->endpoint = ep | 0x80;      // from device to host
299         irp->epsize = dev->epSize[ep]; // ermitteln
300         irp->type = USB_BULK;
301
302         irp->buffer = buf;
303         irp->len = size;
304         irp->timeout = timeout;
305
306         usb_submit_irp(irp);
307         free(irp);
308
309         return 0;
310 }
311
312
313 /******************* Interrupt Transfer **********************/
314 /**
315  * Write to an interrupt endpoint.
316  */
317 s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
318 {
319
320         return 0;
321 }
322
323 /**
324  * Read from an interrupt endpoint.
325  */
326 s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
327 {
328
329         return 0;
330 }
331
332
333 /******************* Isochron Transfer **********************/
334
335 /**
336  * Write to an isochron endpoint.
337  */
338 s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
339 {
340
341         return 0;
342 }
343
344 /**
345  * Read from an isochron endpoint.
346  */
347 s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
348 {
349
350
351         return 0;
352 }
353
354
355 //#endif        //_USB_H_