1 /*
2 * Implementation of DDEkit related calls/data
3 */
4
5 #include <string.h> /* memset */
6
7 #include <ddekit/usb.h>
8
9 #include <usbd/hcd_ddekit.h>
10 #include <usbd/hcd_interface.h>
11 #include <usbd/hcd_schedule.h>
12 #include <usbd/usbd_common.h>
13
14
15 /*===========================================================================*
16 * Local declarations *
17 *===========================================================================*/
18 /*
19 * In this file "struct ddekit_usb_dev" equals "hcd_device_state"
20 */
21 struct ddekit_usb_device_id;
22 struct ddekit_usb_urb;
23 struct ddekit_usb_dev;
24
25 /* Translates DDEKit UBR to one used by HCD */
26 static void hcd_decode_urb(hcd_urb *, struct ddekit_usb_urb *);
27 static void hcd_encode_urb(hcd_urb *, struct ddekit_usb_urb *);
28
29 /* HCD's URB create/destroy */
30 static hcd_urb * hcd_new_urb(void);
31 static void hcd_free_urb(hcd_urb *);
32
33 /* Decodes event from received info */
34 static void hcd_decode_info(long, long, hcd_event *, hcd_reg1 *);
35
36
37 /*===========================================================================*
38 * Global definitions *
39 *===========================================================================*/
40 ddekit_usb_completion_cb completion_cb = NULL;
41 ddekit_usb_connect_cb connect_cb = NULL;
42 ddekit_usb_disconnect_cb disconnect_cb = NULL;
43
44
45 /*===========================================================================*
46 * Implementation for usb_server.c *
47 *===========================================================================*/
48
49 /*===========================================================================*
50 * _ddekit_usb_get_manufacturer *
51 *===========================================================================*/
52 char *
_ddekit_usb_get_manufacturer(struct ddekit_usb_dev * ddev)53 _ddekit_usb_get_manufacturer(struct ddekit_usb_dev * ddev)
54 {
55 static const char mfg[] = "UNKNOWN";
56 DEBUG_DUMP;
57 /* TODO: UNUSED for argument won't work */
58 ((void)ddev);
59 return (char *)mfg;
60 }
61
62
63 /*===========================================================================*
64 * _ddekit_usb_get_product *
65 *===========================================================================*/
66 char *
_ddekit_usb_get_product(struct ddekit_usb_dev * ddev)67 _ddekit_usb_get_product(struct ddekit_usb_dev * ddev)
68 {
69 static const char prod[] = "UNKNOWN";
70 DEBUG_DUMP;
71 /* TODO: UNUSED for argument won't work */
72 ((void)ddev);
73 return (char *)prod;
74 }
75
76
77 /*===========================================================================*
78 * _ddekit_usb_get_serial *
79 *===========================================================================*/
80 char *
_ddekit_usb_get_serial(struct ddekit_usb_dev * ddev)81 _ddekit_usb_get_serial(struct ddekit_usb_dev * ddev)
82 {
83 static const char serial[] = "UNKNOWN";
84 DEBUG_DUMP;
85 /* TODO: UNUSED for argument won't work */
86 ((void)ddev);
87 return (char *)serial;
88 }
89
90
91 /*===========================================================================*
92 * _ddekit_usb_get_device_desc *
93 *===========================================================================*/
94 struct usb_device_descriptor *
_ddekit_usb_get_device_desc(struct ddekit_usb_dev * ddev)95 _ddekit_usb_get_device_desc(struct ddekit_usb_dev * ddev)
96 {
97 hcd_device_state * dev;
98
99 DEBUG_DUMP;
100
101 dev = (hcd_device_state *)ddev;
102
103 return (struct usb_device_descriptor *)
104 (&(dev->config_tree.descriptor));
105 }
106
107
108 /*===========================================================================*
109 * _ddekit_usb_get_interface_desc *
110 *===========================================================================*/
111 struct usb_interface_descriptor *
_ddekit_usb_get_interface_desc(struct ddekit_usb_dev * ddev,int inum)112 _ddekit_usb_get_interface_desc(struct ddekit_usb_dev * ddev, int inum)
113 {
114 hcd_device_state * dev;
115
116 DEBUG_DUMP;
117
118 dev = (hcd_device_state *)ddev;
119
120 return (struct usb_interface_descriptor *)
121 (&(dev->config_tree.interface[inum].descriptor));
122 }
123
124
125 /*===========================================================================*
126 * Implementation for <ddekit/usb.h> *
127 *===========================================================================*/
128
129 /*===========================================================================*
130 * ddekit_usb_dev_set_data *
131 *===========================================================================*/
132 int
ddekit_usb_dev_set_data(struct ddekit_usb_dev * dev,void * data)133 ddekit_usb_dev_set_data(struct ddekit_usb_dev * dev, void * data)
134 {
135 hcd_device_state * hcd_dev;
136
137 DEBUG_DUMP;
138
139 hcd_dev = (hcd_device_state *)dev;
140
141 hcd_dev->data = data;
142
143 return EXIT_SUCCESS;
144 }
145
146
147 /*===========================================================================*
148 * ddekit_usb_dev_get_data *
149 *===========================================================================*/
150 void *
ddekit_usb_dev_get_data(struct ddekit_usb_dev * dev)151 ddekit_usb_dev_get_data(struct ddekit_usb_dev * dev)
152 {
153 hcd_device_state * hcd_dev;
154
155 DEBUG_DUMP;
156
157 hcd_dev = (hcd_device_state *)dev;
158
159 return hcd_dev->data;
160 }
161
162
163 /* TODO: This was in 'ddekit/usb.h' header file, but is not used anywhere */
164 #if 0
165 /*===========================================================================*
166 * ddekit_usb_get_device_id *
167 *===========================================================================*/
168 void
169 ddekit_usb_get_device_id(struct ddekit_usb_dev * dev,
170 struct ddekit_usb_device_id * id)
171 {
172 DEBUG_DUMP;
173 /* TODO: UNUSED for argument won't work */
174 ((void)dev);
175 ((void)id);
176 return;
177 }
178 #endif
179
180
181 /*===========================================================================*
182 * ddekit_usb_submit_urb *
183 *===========================================================================*/
184 int
ddekit_usb_submit_urb(struct ddekit_usb_urb * d_urb)185 ddekit_usb_submit_urb(struct ddekit_usb_urb * d_urb)
186 {
187 hcd_urb * urb;
188
189 DEBUG_DUMP;
190
191 /* Get new URB */
192 urb = hcd_new_urb();
193
194 /* Turn DDEKit URB format to one that is easier to
195 * handle by HCD, also check if URB is valid */
196 hcd_decode_urb(urb, d_urb);
197
198 /* Add URB to scheduler */
199 return hcd_schedule_external_urb(urb);
200 }
201
202
203 /*===========================================================================*
204 * ddekit_usb_cancle_urb *
205 *===========================================================================*/
206 int
ddekit_usb_cancle_urb(struct ddekit_usb_urb * d_urb)207 ddekit_usb_cancle_urb(struct ddekit_usb_urb * d_urb)
208 {
209 DEBUG_DUMP;
210 /* TODO: UNUSED for argument won't work */
211 ((void)d_urb);
212 /* TODO: No driver will require this any time soon */
213 USB_ASSERT(0, "URB cancellation not supported");
214 return EXIT_SUCCESS;
215 }
216
217
218 /*===========================================================================*
219 * ddekit_usb_info *
220 *===========================================================================*/
221 long
ddekit_usb_info(struct ddekit_usb_dev * dev,long type,long value)222 ddekit_usb_info(struct ddekit_usb_dev * dev, long type, long value)
223 {
224 hcd_event event;
225 hcd_reg1 val;
226
227 DEBUG_DUMP;
228
229 /* Decode event */
230 hcd_decode_info(type, value, &event, &val);
231
232 if (HCD_EVENT_INVALID == event) {
233 USB_MSG("Invalid info message received");
234 return EXIT_FAILURE;
235 } else {
236 /* Let HCD handle info message */
237 hcd_handle_event((hcd_device_state *)dev, event, val);
238 return EXIT_SUCCESS;
239 }
240 }
241
242
243 /*===========================================================================*
244 * ddekit_usb_init *
245 *===========================================================================*/
246 int
ddekit_usb_init(struct ddekit_usb_driver * drv,ddekit_usb_malloc_fn * _m,ddekit_usb_free_fn * _f)247 ddekit_usb_init(struct ddekit_usb_driver * drv,
248 ddekit_usb_malloc_fn * _m,
249 ddekit_usb_free_fn * _f)
250 {
251 DEBUG_DUMP;
252
253 completion_cb = drv->completion;
254 connect_cb = drv->connect;
255 disconnect_cb = drv->disconnect;
256
257 *_m = (ddekit_usb_malloc_fn) malloc;
258 *_f = (ddekit_usb_free_fn) free;
259
260 return EXIT_SUCCESS;
261 }
262
263
264 /*===========================================================================*
265 * hcd_connect_cb *
266 *===========================================================================*/
267 void
hcd_connect_cb(hcd_device_state * dev)268 hcd_connect_cb(hcd_device_state * dev)
269 {
270 unsigned int if_bitmask;
271
272 DEBUG_DUMP;
273
274 /* TODO: Magic numbers like in ddekit/devman */
275 /* Each bit starting from 0, represents valid interface */
276 if_bitmask = 0xFFFFFFFF >> (32 - dev->config_tree.num_interfaces);
277
278 USB_DBG("Interfaces %d, mask %08X",
279 dev->config_tree.num_interfaces,
280 if_bitmask);
281
282 connect_cb((struct ddekit_usb_dev *)dev, (int)if_bitmask);
283 }
284
285
286 /*===========================================================================*
287 * hcd_disconnect_cb *
288 *===========================================================================*/
289 void
hcd_disconnect_cb(hcd_device_state * dev)290 hcd_disconnect_cb(hcd_device_state * dev)
291 {
292 DEBUG_DUMP;
293
294 disconnect_cb((struct ddekit_usb_dev *)dev);
295 }
296
297
298 /*===========================================================================*
299 * hcd_completion_cb *
300 *===========================================================================*/
301 void
hcd_completion_cb(hcd_urb * urb)302 hcd_completion_cb(hcd_urb * urb)
303 {
304 struct ddekit_usb_urb * d_urb;
305
306 DEBUG_DUMP;
307
308 /* Recollect original URB */
309 d_urb = (struct ddekit_usb_urb *)urb->original_urb;
310
311 /* Original URB will not be NULL if URB
312 * was external (from device driver) */
313 if (NULL != d_urb) {
314 /* Turn HCD URB format to one handled by DDEKit */
315 hcd_encode_urb(urb, d_urb);
316
317 /* No need for this URB anymore */
318 hcd_free_urb(urb);
319
320 completion_cb(d_urb->priv);
321 }
322 }
323
324
325 /*===========================================================================*
326 * hcd_decode_urb *
327 *===========================================================================*/
328 static void
hcd_decode_urb(hcd_urb * urb,struct ddekit_usb_urb * dde_urb)329 hcd_decode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb)
330 {
331 DEBUG_DUMP;
332
333 /* Remember original */
334 urb->original_urb = (void *)dde_urb;
335
336 /* No UBR error initially */
337 urb->inout_status = EXIT_SUCCESS;
338
339 /* Check transfer direction */
340 switch (dde_urb->direction) {
341 case DDEKIT_USB_IN:
342 urb->direction = HCD_DIRECTION_IN;
343 break;
344 case DDEKIT_USB_OUT:
345 urb->direction = HCD_DIRECTION_OUT;
346 break;
347 default:
348 USB_MSG("URB direction error");
349 goto URB_ERROR;
350 }
351
352 /* Check transfer type */
353 switch (dde_urb->type) {
354 case DDEKIT_USB_TRANSFER_ISO:
355 urb->type = HCD_TRANSFER_ISOCHRONOUS;
356 break;
357 case DDEKIT_USB_TRANSFER_INT:
358 urb->type = HCD_TRANSFER_INTERRUPT;
359 break;
360 case DDEKIT_USB_TRANSFER_CTL:
361 urb->type = HCD_TRANSFER_CONTROL;
362 break;
363 case DDEKIT_USB_TRANSFER_BLK:
364 urb->type = HCD_TRANSFER_BULK;
365 break;
366 default:
367 USB_MSG("URB type error");
368 goto URB_ERROR;
369 }
370
371 /* Check transfer endpoint validity */
372 if ((dde_urb->endpoint <= (int)HCD_LAST_EP) &&
373 (dde_urb->endpoint >= (int)HCD_DEFAULT_EP))
374 urb->endpoint = (hcd_reg1)dde_urb->endpoint;
375 else {
376 USB_MSG("URB endpoint error");
377 goto URB_ERROR;
378 }
379
380 /* Check transfer interval validity */
381 if ((dde_urb->interval <= (int)HCD_HIGHEST_INTERVAL) &&
382 (dde_urb->interval >= (int)HCD_LOWEST_INTERVAL))
383 urb->interval = (hcd_reg1)dde_urb->interval;
384 else {
385 USB_MSG("URB interval error");
386 goto URB_ERROR;
387 }
388
389 /* TODO: Alignment of setup packet. Can DDE client guarantee that? */
390 /* Transfer data assignment */
391 urb->inout_data = (hcd_reg1 *)dde_urb->data;
392 urb->in_setup = (hcd_ctrlrequest *)dde_urb->setup_packet;
393
394 /* TODO: Sane size check? */
395 urb->in_size = (hcd_reg4)dde_urb->size;
396
397 /* Buffer validity check */
398 if ((NULL == urb->inout_data) && (NULL == urb->in_setup)) {
399 USB_MSG("URB buffer error");
400 goto URB_ERROR;
401 }
402
403 /* Remember device and check for NULL */
404 if (NULL == (urb->target_device = (hcd_device_state *)dde_urb->dev)) {
405 USB_MSG("URB device pointer error");
406 goto URB_ERROR;
407 }
408
409 /* Decoding completed */
410 return;
411
412 URB_ERROR:
413 urb->inout_status = EXIT_FAILURE;
414 }
415
416
417 /*===========================================================================*
418 * hcd_encode_urb *
419 *===========================================================================*/
420 static void
hcd_encode_urb(hcd_urb * urb,struct ddekit_usb_urb * dde_urb)421 hcd_encode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb)
422 {
423 DEBUG_DUMP;
424
425 /* Data buffers are the same, no need to copy */
426 /* Rewrite output for DDEKit part */
427 dde_urb->actual_length = urb->out_size;
428 dde_urb->status = urb->inout_status;
429 }
430
431
432 /*===========================================================================*
433 * hcd_new_urb *
434 *===========================================================================*/
435 static hcd_urb *
hcd_new_urb(void)436 hcd_new_urb(void)
437 {
438 DEBUG_DUMP;
439 return malloc(sizeof(hcd_urb));
440 }
441
442
443 /*===========================================================================*
444 * hcd_free_urb *
445 *===========================================================================*/
446 static void
hcd_free_urb(hcd_urb * urb)447 hcd_free_urb(hcd_urb * urb)
448 {
449 DEBUG_DUMP;
450 free(urb);
451 }
452
453
454 /*===========================================================================*
455 * hcd_decode_info *
456 *===========================================================================*/
457 static void
hcd_decode_info(long type,long invalue,hcd_event * event,hcd_reg1 * outvalue)458 hcd_decode_info(long type, long invalue, hcd_event * event, hcd_reg1 * outvalue)
459 {
460 DEBUG_DUMP;
461
462 USB_ASSERT((invalue >= 0) && (invalue <= 0xFF),
463 "Illegal USB info value received");
464
465 switch ((ddekit_msg_type_t)type) {
466 case DDEKIT_HUB_PORT_LS_CONN:
467 *event = HCD_EVENT_PORT_LS_CONNECTED;
468 break;
469 case DDEKIT_HUB_PORT_FS_CONN:
470 *event = HCD_EVENT_PORT_FS_CONNECTED;
471 break;
472 case DDEKIT_HUB_PORT_HS_CONN:
473 *event = HCD_EVENT_PORT_HS_CONNECTED;
474 break;
475 case DDEKIT_HUB_PORT_DISCONN:
476 *event = HCD_EVENT_PORT_DISCONNECTED;
477 break;
478 default:
479 *event = HCD_EVENT_INVALID;
480 break;
481 }
482
483 *outvalue = (hcd_reg1)invalue;
484 }
485