xref: /minix/minix/drivers/usb/usbd/hcd/hcd_ddekit.c (revision e3b78ef1)
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 *
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 *
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 *
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 *
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 *
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
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 *
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
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
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
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
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
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
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
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
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
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 *
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
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
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