tools/llvm: Do not build with symbols
[minix3.git] / minix / drivers / usb / usbd / hcd / hcd_ddekit.c
blobc9862c8651a59f7fcec43f8f110a08c5119d9cee
1 /*
2 * Implementation of DDEkit related calls/data
3 */
5 #include <string.h> /* memset */
7 #include <ddekit/usb.h>
9 #include <usbd/hcd_ddekit.h>
10 #include <usbd/hcd_interface.h>
11 #include <usbd/hcd_schedule.h>
12 #include <usbd/usbd_common.h>
15 /*===========================================================================*
16 * Local declarations *
17 *===========================================================================*/
19 * In this file "struct ddekit_usb_dev" equals "hcd_device_state"
21 struct ddekit_usb_device_id;
22 struct ddekit_usb_urb;
23 struct ddekit_usb_dev;
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 *);
29 /* HCD's URB create/destroy */
30 static hcd_urb * hcd_new_urb(void);
31 static void hcd_free_urb(hcd_urb *);
33 /* Decodes event from received info */
34 static void hcd_decode_info(long, long, hcd_event *, hcd_reg1 *);
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;
45 /*===========================================================================*
46 * Implementation for usb_server.c *
47 *===========================================================================*/
49 /*===========================================================================*
50 * _ddekit_usb_get_manufacturer *
51 *===========================================================================*/
52 char *
53 _ddekit_usb_get_manufacturer(struct ddekit_usb_dev * ddev)
55 static const char mfg[] = "UNKNOWN";
56 DEBUG_DUMP;
57 /* TODO: UNUSED for argument won't work */
58 ((void)ddev);
59 return (char *)mfg;
63 /*===========================================================================*
64 * _ddekit_usb_get_product *
65 *===========================================================================*/
66 char *
67 _ddekit_usb_get_product(struct ddekit_usb_dev * ddev)
69 static const char prod[] = "UNKNOWN";
70 DEBUG_DUMP;
71 /* TODO: UNUSED for argument won't work */
72 ((void)ddev);
73 return (char *)prod;
77 /*===========================================================================*
78 * _ddekit_usb_get_serial *
79 *===========================================================================*/
80 char *
81 _ddekit_usb_get_serial(struct ddekit_usb_dev * ddev)
83 static const char serial[] = "UNKNOWN";
84 DEBUG_DUMP;
85 /* TODO: UNUSED for argument won't work */
86 ((void)ddev);
87 return (char *)serial;
91 /*===========================================================================*
92 * _ddekit_usb_get_device_desc *
93 *===========================================================================*/
94 struct usb_device_descriptor *
95 _ddekit_usb_get_device_desc(struct ddekit_usb_dev * ddev)
97 hcd_device_state * dev;
99 DEBUG_DUMP;
101 dev = (hcd_device_state *)ddev;
103 return (struct usb_device_descriptor *)
104 (&(dev->config_tree.descriptor));
108 /*===========================================================================*
109 * _ddekit_usb_get_interface_desc *
110 *===========================================================================*/
111 struct usb_interface_descriptor *
112 _ddekit_usb_get_interface_desc(struct ddekit_usb_dev * ddev, int inum)
114 hcd_device_state * dev;
116 DEBUG_DUMP;
118 dev = (hcd_device_state *)ddev;
120 return (struct usb_interface_descriptor *)
121 (&(dev->config_tree.interface[inum].descriptor));
125 /*===========================================================================*
126 * Implementation for <ddekit/usb.h> *
127 *===========================================================================*/
129 /*===========================================================================*
130 * ddekit_usb_dev_set_data *
131 *===========================================================================*/
133 ddekit_usb_dev_set_data(struct ddekit_usb_dev * dev, void * data)
135 hcd_device_state * hcd_dev;
137 DEBUG_DUMP;
139 hcd_dev = (hcd_device_state *)dev;
141 hcd_dev->data = data;
143 return EXIT_SUCCESS;
147 /*===========================================================================*
148 * ddekit_usb_dev_get_data *
149 *===========================================================================*/
150 void *
151 ddekit_usb_dev_get_data(struct ddekit_usb_dev * dev)
153 hcd_device_state * hcd_dev;
155 DEBUG_DUMP;
157 hcd_dev = (hcd_device_state *)dev;
159 return hcd_dev->data;
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)
172 DEBUG_DUMP;
173 /* TODO: UNUSED for argument won't work */
174 ((void)dev);
175 ((void)id);
176 return;
178 #endif
181 /*===========================================================================*
182 * ddekit_usb_submit_urb *
183 *===========================================================================*/
185 ddekit_usb_submit_urb(struct ddekit_usb_urb * d_urb)
187 hcd_urb * urb;
189 DEBUG_DUMP;
191 /* Get new URB */
192 urb = hcd_new_urb();
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);
198 /* Add URB to scheduler */
199 return hcd_schedule_external_urb(urb);
203 /*===========================================================================*
204 * ddekit_usb_cancle_urb *
205 *===========================================================================*/
207 ddekit_usb_cancle_urb(struct ddekit_usb_urb * d_urb)
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;
218 /*===========================================================================*
219 * ddekit_usb_info *
220 *===========================================================================*/
221 long
222 ddekit_usb_info(struct ddekit_usb_dev * dev, long type, long value)
224 hcd_event event;
225 hcd_reg1 val;
227 DEBUG_DUMP;
229 /* Decode event */
230 hcd_decode_info(type, value, &event, &val);
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;
243 /*===========================================================================*
244 * ddekit_usb_init *
245 *===========================================================================*/
247 ddekit_usb_init(struct ddekit_usb_driver * drv,
248 ddekit_usb_malloc_fn * _m,
249 ddekit_usb_free_fn * _f)
251 DEBUG_DUMP;
253 completion_cb = drv->completion;
254 connect_cb = drv->connect;
255 disconnect_cb = drv->disconnect;
257 *_m = malloc;
258 *_f = free;
260 return EXIT_SUCCESS;
264 /*===========================================================================*
265 * hcd_connect_cb *
266 *===========================================================================*/
267 void
268 hcd_connect_cb(hcd_device_state * dev)
270 unsigned int if_bitmask;
272 DEBUG_DUMP;
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);
278 USB_DBG("Interfaces %d, mask %08X",
279 dev->config_tree.num_interfaces,
280 if_bitmask);
282 connect_cb((struct ddekit_usb_dev *)dev, (int)if_bitmask);
286 /*===========================================================================*
287 * hcd_disconnect_cb *
288 *===========================================================================*/
289 void
290 hcd_disconnect_cb(hcd_device_state * dev)
292 DEBUG_DUMP;
294 disconnect_cb((struct ddekit_usb_dev *)dev);
298 /*===========================================================================*
299 * hcd_completion_cb *
300 *===========================================================================*/
301 void
302 hcd_completion_cb(hcd_urb * urb)
304 struct ddekit_usb_urb * d_urb;
306 DEBUG_DUMP;
308 /* Recollect original URB */
309 d_urb = (struct ddekit_usb_urb *)urb->original_urb;
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);
317 /* No need for this URB anymore */
318 hcd_free_urb(urb);
320 completion_cb(d_urb->priv);
325 /*===========================================================================*
326 * hcd_decode_urb *
327 *===========================================================================*/
328 static void
329 hcd_decode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb)
331 DEBUG_DUMP;
333 /* Remember original */
334 urb->original_urb = (void *)dde_urb;
336 /* No UBR error initially */
337 urb->inout_status = EXIT_SUCCESS;
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;
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;
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;
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;
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;
394 /* TODO: Sane size check? */
395 urb->in_size = (hcd_reg4)dde_urb->size;
397 /* Buffer validity check */
398 if ((NULL == urb->inout_data) && (NULL == urb->in_setup)) {
399 USB_MSG("URB buffer error");
400 goto URB_ERROR;
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;
409 /* Decoding completed */
410 return;
412 URB_ERROR:
413 urb->inout_status = EXIT_FAILURE;
417 /*===========================================================================*
418 * hcd_encode_urb *
419 *===========================================================================*/
420 static void
421 hcd_encode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb)
423 DEBUG_DUMP;
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;
432 /*===========================================================================*
433 * hcd_new_urb *
434 *===========================================================================*/
435 static hcd_urb *
436 hcd_new_urb(void)
438 DEBUG_DUMP;
439 return malloc(sizeof(hcd_urb));
443 /*===========================================================================*
444 * hcd_free_urb *
445 *===========================================================================*/
446 static void
447 hcd_free_urb(hcd_urb * urb)
449 DEBUG_DUMP;
450 free(urb);
454 /*===========================================================================*
455 * hcd_decode_info *
456 *===========================================================================*/
457 static void
458 hcd_decode_info(long type, long invalue, hcd_event * event, hcd_reg1 * outvalue)
460 DEBUG_DUMP;
462 USB_ASSERT((invalue >= 0) && (invalue <= 0xFF),
463 "Illegal USB info value received");
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;
483 *outvalue = (hcd_reg1)invalue;