938b48121cbd9ccf2e3489bdb71a514a7bb0f6ed
[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_dev_desc_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_dev_desc(struct usb_device *dev, u8 *buf, u8 size)
190 {
191         if (size < 0x12 || usb_get_dev_desc_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_configuration(struct usb_device *dev, u8 index, u8 *buf, u8 size)
214 {
215         if(size < 8) {
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         return 0;
221 }
222
223 s8 usb_set_address(struct usb_device *dev, u8 address)
224 {
225         u8 buf[64];
226         usb_control_msg(dev, 0x00, SET_ADDRESS, address, 0, 0, buf, 0);
227         return 0;
228 }
229
230 s8 usb_set_configuration(struct usb_device *dev, u8 configuration)
231 {
232
233         return 0;
234 }
235
236 s8 usb_set_altinterface(struct usb_device *dev, u8 alternate)
237 {
238
239         return 0;
240 }
241
242
243
244 /******************* Bulk Transfer **********************/
245
246 /**
247  * Write to an a bulk endpoint.
248  */
249 s8 usb_bulk_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
250 {
251         struct usb_irp * irp = (struct usb_irp*)malloc(sizeof(struct usb_irp));
252         irp->dev = dev;
253         //irp->devaddress = dev->address;
254         
255         irp->endpoint = ep;
256         irp->epsize = dev->epSize[ep]; // ermitteln
257         irp->type = USB_BULK;
258
259         irp->buffer = buf;
260         irp->len = size;
261         irp->timeout = timeout;
262
263         usb_submit_irp(irp);
264         free(irp);
265
266         return 0;
267 }
268
269 /**
270  * Read from an bulk endpoint.
271  */
272 s8 usb_bulk_read(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->devaddress = dev->address;
276         irp->dev = dev;
277         
278         irp->endpoint = ep | 0x80;      // from device to host
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 /******************* Interrupt Transfer **********************/
294 /**
295  * Write to an interrupt endpoint.
296  */
297 s8 usb_interrupt_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
298 {
299
300         return 0;
301 }
302
303 /**
304  * Read from an interrupt endpoint.
305  */
306 s8 usb_interrupt_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
307 {
308
309         return 0;
310 }
311
312
313 /******************* Isochron Transfer **********************/
314
315 /**
316  * Write to an isochron endpoint.
317  */
318 s8 usb_isochron_write(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
319 {
320
321         return 0;
322 }
323
324 /**
325  * Read from an isochron endpoint.
326  */
327 s8 usb_isochron_read(struct usb_device *dev, u8 ep, u8 *buf, u8 size, u8 timeout)
328 {
329
330
331         return 0;
332 }
333
334
335 //#endif        //_USB_H_