xref: /minix3/minix/lib/libddekit/src/usb_server.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 #include "common.h"
2 
3 #include <ddekit/minix/msg_queue.h>
4 #include <ddekit/panic.h>
5 #include <ddekit/printf.h>
6 #include <ddekit/usb.h>
7 #include <minix/safecopies.h>
8 #include <minix/usb.h>
9 #include <minix/usb_ch9.h>
10 #include <minix/devman.h>
11 
12 #define MAX_URBS    10
13 
14 #define DRIVER_UNUSED 0
15 #define DRIVER_ACTIVE 1
16 #define DRIVER_BOUND  2
17 
18 #if 0
19 #define DEBUG_MSG(fmt, ...) ddekit_printf("%s : "fmt"\n", __func__, ##__VA_ARGS__ )
20 #else
21 #define DEBUG_MSG(fmt, ...)
22 #endif
23 
24 #undef DDEBUG
25 #define DDEBUG 0
26 #include "debug.h"
27 
28 #define MAX_DEVS 256
29 #define MAX_DRIVERS 256
30 #define OK 0
31 
32 #define INVAL_DEV (-1)
33 
34 struct my_context {
35 	unsigned urb_id;
36 	struct ddekit_usb_urb *d_urb;
37 	struct usb_urb *mx_urb;
38 	struct minix_usb_driver *drv;
39 	gid_t gid;
40 };
41 
42 struct minix_usb_driver {
43 	endpoint_t ep;                       /* address of the client */
44 
45 	int status;                          /* In what state is the client? */
46 
47 	int dev;                          /* which device is this driver handling */
48 	unsigned interfaces;                 /* which interfaces of the device the
49 	                                        driver is handling */
50 
51 	struct ddekit_usb_urb *urbs[MAX_URBS]; /* pending urbs */
52 
53 	unsigned long urb_id;			     /* generation of driver_local urb_ids */
54 };
55 
56 struct minix_usb_device {
57 	struct ddekit_usb_dev *dev;
58 	unsigned int interfaces;
59 };
60 
61 static struct minix_usb_driver *find_driver(endpoint_t ep);
62 static struct minix_usb_driver *find_unused_driver(void);
63 static int add_to_pending_urbs(struct minix_usb_driver *drv, struct
64 	ddekit_usb_urb *urb);
65 static int remove_from_pending_urbs(struct minix_usb_driver *drv,
66 	struct ddekit_usb_urb *urb);
67 static struct ddekit_usb_urb * find_pending_urb(struct minix_usb_driver
68 	*drv, unsigned urb_id);
69 static void register_driver(message *msg);
70 static struct ddekit_usb_urb *ddekit_usb_urb_from_mx_urb(struct usb_urb
71 	*mx_urb);
72 static void submit_urb(message *msg);
73 static void cancle_urb(message *msg);
74 static void get_info(message *msg);
75 static void completion_callback(void *priv);
76 
77 static void prepare_devman_usbdev(struct ddekit_usb_dev * dev, int
78 	dev_id, unsigned int interfaces, struct devman_usb_dev *dudev);
79 static void device_disconnect_callback(struct ddekit_usb_dev * dev);
80 static int add_acl(int dev_id, unsigned interfaces, endpoint_t ep);
81 static int del_acl(int dev_id, unsigned interaces, endpoint_t ep);
82 static int handle_msg(message *msg);
83 static void _ddekit_usb_thread();
84 static void device_connect_callback(struct ddekit_usb_dev * dev,
85 	unsigned int interfaces);
86 
87 char *_ddekit_usb_get_manufacturer(struct ddekit_usb_dev *ddev);
88 char *_ddekit_usb_get_product(struct ddekit_usb_dev *ddev);
89 char *_ddekit_usb_get_serial(struct ddekit_usb_dev *ddev);
90 usb_device_descriptor_t *_ddekit_usb_get_device_desc(struct
91 	ddekit_usb_dev *ddev);
92 usb_interface_descriptor_t *_ddekit_usb_get_interface_desc(struct
93 	ddekit_usb_dev *ddev, int inum);
94 
95 
96 static ddekit_usb_malloc_fn my_malloc;
97 static ddekit_usb_free_fn my_free;
98 static struct minix_usb_driver gbl_drivers[MAX_DRIVERS];
99 static struct minix_usb_device _devices[MAX_DEVS];
100 
101 static struct ddekit_usb_driver my_driver = {
102 	.completion = completion_callback,
103 	.connect    = device_connect_callback,
104 	.disconnect = device_disconnect_callback,
105 };
106 
107 
108 /*****************************************************************************
109  *         find_driver                                                       *
110  ****************************************************************************/
find_driver(endpoint_t ep)111 static struct minix_usb_driver *find_driver(endpoint_t ep)
112 {
113 	int i;
114 	for (i = 0; i < MAX_DRIVERS; i++ ){
115 		if (gbl_drivers[i].ep == ep) {
116 			return &gbl_drivers[i];
117 		}
118 	}
119 	return NULL;
120 }
121 
122 /*****************************************************************************
123  *         find_unused_driver                                                *
124  ****************************************************************************/
find_unused_driver()125 static struct minix_usb_driver *find_unused_driver()
126 {
127 	int i;
128 	for (i = 0; i < MAX_DRIVERS; i++ ){
129 		if (gbl_drivers[i].status == DRIVER_UNUSED) {
130 			return &gbl_drivers[i];
131 		}
132 	}
133 	return NULL;
134 }
135 
136 /*****************************************************************************
137  *         add_to_pending_urbs                                               *
138  ****************************************************************************/
add_to_pending_urbs(struct minix_usb_driver * drv,struct ddekit_usb_urb * urb)139 static int add_to_pending_urbs(struct minix_usb_driver *drv,
140                                struct ddekit_usb_urb *urb)
141 {
142 	int i;
143 
144 	for (i = 0; i < MAX_URBS; i++) {
145 		if (drv->urbs[i] == NULL) {
146 			drv->urbs[i] = urb;
147 			return 0;
148 		}
149 	}
150 
151 	return -1;
152 }
153 
154 /*****************************************************************************
155  *         remove_from_pending_urbs                                          *
156  ****************************************************************************/
remove_from_pending_urbs(struct minix_usb_driver * drv,struct ddekit_usb_urb * urb)157 static int remove_from_pending_urbs(struct minix_usb_driver *drv,
158                                struct ddekit_usb_urb *urb)
159 {
160 	int i;
161 
162 	for (i = 0; i < MAX_URBS; i++) {
163 		if (drv->urbs[i] == urb) {
164 			drv->urbs[i] = NULL;
165 			return 0;
166 		}
167 	}
168 
169 	return -1;
170 }
171 
172 /*****************************************************************************
173  *         find_pending_urb                                                  *
174  ****************************************************************************/
find_pending_urb(struct minix_usb_driver * drv,unsigned urb_id)175 static struct ddekit_usb_urb * find_pending_urb(struct minix_usb_driver *drv,
176                                                 unsigned urb_id)
177 {
178 	int i;
179 
180 	for (i = 0; i < MAX_URBS; i++) {
181 		if (((struct my_context*)drv->urbs[i]->priv)->urb_id == urb_id) {
182 				return drv->urbs[i];
183 		}
184 	}
185 
186 	return NULL;
187 }
188 
189 /*****************************************************************************
190  *         register_driver                                                   *
191  ****************************************************************************/
register_driver(message * msg)192 static void register_driver(message *msg)
193 {
194 	endpoint_t ep = msg->m_source;
195 	struct minix_usb_driver *drv;
196 
197 	msg->m_type=USB_REPLY;
198 
199 	if ( (drv = find_driver(ep)) != NULL) {
200 		msg->m_type = USB_REPLY;
201 		msg->USB_RESULT = OK;
202 		ipc_send(ep,msg);
203 	} else {
204 		msg->m_type = USB_REPLY;
205 		msg->USB_RESULT = EPERM;
206 		ipc_send(ep,msg);
207 		return;
208 	}
209 
210 	DEBUG_MSG("DRIVER %d registered \n"
211 	              "Announcing device %d, interfaces 0x%x\n",
212 				  ep,
213 				  drv->dev,
214 				  drv->interfaces);
215 
216 	/* hand out the device */
217 	msg->m_type = USB_ANNOUCE_DEV;
218 	msg->USB_DEV_ID     = drv->dev;
219 	msg->USB_INTERFACES = drv->interfaces;
220 	ipc_send(ep, msg);
221 }
222 
223 /*****************************************************************************
224  *         deregister_driver                                                 *
225  ****************************************************************************/
deregister_driver(message * msg)226 static void deregister_driver(message *msg)
227 {
228 	endpoint_t ep = msg->m_source;
229 
230 	struct minix_usb_driver *drv;
231 
232 	msg->m_type=USB_REPLY;
233 
234 	if ( (drv = find_driver(ep)) == NULL) {
235 		DEBUG_MSG("Non-registered driver tries to unregister.");
236 		return;
237 	} else {
238 		/* do not accept requests for this client anymore! */
239 		drv->status = DRIVER_UNUSED;
240 
241 		msg->USB_RESULT = 0;
242 		asynsend3(ep, msg, AMF_NOREPLY);
243 	}
244 }
245 
246 /*****************************************************************************
247  *         ddekit_usb_urb_from_mx_urb                                        *
248  ****************************************************************************/
ddekit_usb_urb_from_mx_urb(struct usb_urb * mx_urb)249 static struct ddekit_usb_urb *ddekit_usb_urb_from_mx_urb(struct usb_urb *mx_urb)
250 {
251 	/*
252 	 * A helper function that generates (allocates and initializes)
253 	 * a ddekit_usb_urb.
254 	 */
255 
256 	struct ddekit_usb_urb *d_urb = (struct ddekit_usb_urb *)
257 		my_malloc(sizeof(struct ddekit_usb_urb));
258 
259 	if (d_urb == NULL) {
260 		return NULL;
261 	}
262 
263 	d_urb->type           = mx_urb->type;
264 	d_urb->direction      = mx_urb->direction;
265 	d_urb->transfer_flags = mx_urb->transfer_flags;
266 	d_urb->size           = mx_urb->size;
267 	d_urb->data           = mx_urb->buffer;
268 	d_urb->interval       = mx_urb->interval;
269 	d_urb->endpoint       = mx_urb->endpoint;
270 
271 	if (d_urb->type == USB_TRANSFER_CTL) {
272 		d_urb->setup_packet = mx_urb->setup_packet;
273 	}
274 	DEBUG_MSG("setup_package at %p", d_urb->setup_packet);
275 
276 	if (d_urb->type == USB_TRANSFER_ISO) {
277 		d_urb->iso_desc  = (struct ddekit_usb_iso_packet_desc *)
278 		    mx_urb->buffer + mx_urb->iso_desc_offset;
279 		d_urb->number_of_packets = mx_urb->number_of_packets;
280 	}
281 
282 	return d_urb;
283 }
284 
285 /*****************************************************************************
286  *         submit_urb                                                        *
287  ****************************************************************************/
submit_urb(message * msg)288 static void submit_urb(message *msg)
289 {
290 	/*
291 	 * submit_urb
292 	 *
293 	 * Handles a submit_urb from a minix USB device driver. It copies the
294 	 * usb_urb structure containing the buffers and generates and tries to
295 	 * submit a ddekit_usb_urb. The reference to the ddekit_usb_urb is stored
296 	 * in the driver structure in order to be able to cancle the URB on the
297 	 * clients request.
298 	 */
299 	endpoint_t ep = msg->m_source;
300 	struct minix_usb_driver *drv;
301 
302 	/* find driver */
303 	if ( (drv = find_driver(ep)) == NULL) {
304 		DEBUG_MSG("Non-registered driver tries to send URB.");
305 		return;
306 	} else {
307 
308 		int res;
309 		struct my_context *ctx = NULL;
310 		struct ddekit_usb_urb *d_urb = NULL;
311 
312 		struct usb_urb *mx_urb  = (struct usb_urb*)
313 		    my_malloc(msg->USB_GRANT_SIZE+sizeof(void *));
314 
315 		if (mx_urb == NULL) {
316 			DEBUG_MSG("Can't allocat mem for mx_urb.");
317 			res = ENOMEM;
318 			goto out;
319 		}
320 
321 		/* copy in URB */
322 		res = sys_safecopyfrom(ep, msg->USB_GRANT_ID, 0,
323 		    (vir_bytes) &mx_urb->dev_id, msg->USB_GRANT_SIZE);
324 
325 		if (res != 0) {
326 			DEBUG_MSG("sys_safecopyfrom failed ");
327 			my_free(mx_urb);
328 			res = EINVAL;
329 			goto out;
330 		}
331 
332 		DEBUG_MSG("URB type: %d", mx_urb->type);
333 		/* check if urb is valid */
334 		if (mx_urb->dev_id >= MAX_DEVS || mx_urb->dev_id < 0) {
335 			DEBUG_MSG("Bogus device ID.");
336 			res = EINVAL;
337 			goto out;
338 		}
339 
340 		/* create ddekit_usb_urb */
341 		d_urb = ddekit_usb_urb_from_mx_urb(mx_urb);
342 		d_urb->dev = _devices[drv->dev].dev;
343 		/* submit urb */
344 
345 		if (!d_urb) {
346 			res = ENOMEM;
347 			goto out;
348 		}
349 
350 		ctx = my_malloc(sizeof(struct my_context));
351 
352 		if(!ctx) {
353 			res = ENOMEM;
354 			goto out;
355 		}
356 
357 		ctx->drv       = drv;
358 		ctx->urb_id    = drv->urb_id++;
359 		mx_urb->urb_id = ctx->urb_id;
360 		ctx->mx_urb    = mx_urb;
361 		ctx->d_urb     = d_urb;
362 		ctx->gid       = msg->USB_GRANT_ID;
363 
364 		DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ",
365 		    ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid);
366 
367 		d_urb->priv = ctx;
368 
369 		res = add_to_pending_urbs(drv, d_urb);
370 
371 		if (res == 0) {
372 			DEBUG_MSG("submitting urb...");
373 			res = ddekit_usb_submit_urb(d_urb);
374 			if(res) {
375 				DEBUG_MSG("submitting urb failed (err: %d)", res);
376 				remove_from_pending_urbs(drv, d_urb);
377 			}
378 		}
379 
380 out:
381 		/* reply */
382 		msg->m_type     = USB_REPLY;
383 		msg->USB_URB_ID = mx_urb->urb_id;
384 		msg->USB_RESULT = res;
385 
386 		if(res != 0) {
387 
388 			if (mx_urb != NULL) {
389 				my_free(mx_urb);
390 			}
391 			if (ctx != NULL) {
392 				my_free(ctx);
393 			}
394 
395 			if (d_urb != NULL) {
396 				my_free(d_urb);
397 			}
398 
399 		}
400 
401 		/* send reply */
402 		ipc_send(ep, msg);
403 	}
404 }
405 
406 
407 /*
408  * cancle_urb
409  *
410  * Cancels the submission of an URB identified by a URB_id
411  */
412 /*****************************************************************************
413  *         cancle_urb                                                        *
414  ****************************************************************************/
cancle_urb(message * msg)415 static void cancle_urb(message *msg)
416 {
417 	endpoint_t ep = msg->m_source;
418 
419 	struct minix_usb_driver *drv;
420 
421 	msg->USB_RESULT = -1;
422 	msg->m_type = USB_REPLY;
423 
424 	/* find driver */
425 	if ( (drv = find_driver(ep)) == NULL) {
426 		DEBUG_MSG("Non-registered driver tries to cancel URB.");
427 		return;
428 	} else {
429 		struct ddekit_usb_urb *d_urb = NULL;
430 
431 		d_urb = find_pending_urb(drv, msg->USB_URB_ID);
432 
433 		if (d_urb != NULL) {
434 			ddekit_usb_cancle_urb(d_urb);
435 			msg->USB_RESULT = 0;
436 		} else {
437 			DEBUG_MSG("No URB to cancle");
438 			msg->USB_RESULT = ENODEV;
439 		}
440 	}
441 
442 	ipc_send(ep, msg);
443 }
444 
445 
446 /*****************************************************************************
447  *         get_info                                                          *
448  *****************************************************************************/
449 static void
get_info(message * msg)450 get_info(message * msg)
451 {
452 	struct minix_usb_driver * drv;
453 	endpoint_t ep;
454 	long info_type;
455 	long info_value;
456 
457 	/* Read */
458 	ep		= msg->m_source;
459 	info_type	= msg->USB_INFO_TYPE;
460 	info_value	= msg->USB_INFO_VALUE;
461 
462 	/* Reuse as reply */
463 	msg->m_type	= USB_REPLY;
464 	msg->USB_RESULT	= -1;
465 
466 	/* Try and find driver first */
467 	if (NULL == (drv = find_driver(ep)))
468 		ddekit_printf("Non-registered driver tries to send info");
469 	else
470 		/* Route info to device */
471 		msg->USB_RESULT = ddekit_usb_info(_devices[drv->dev].dev,
472 						info_type, info_value);
473 
474 	/* Reply */
475 	ipc_send(ep, msg);
476 }
477 
478 
479 /*****************************************************************************
480  *         completion_callback                                               *
481  ****************************************************************************/
completion_callback(void * priv)482 static void completion_callback(void *priv)
483 {
484 	/*
485 	 * completion_callback
486 	 *
487 	 * This is called by the DDE side. Here the data is copied back to
488 	 * the driver and a message is send to inform the driver about the
489 	 * completion.
490 	 */
491 	message msg;
492 	int res;
493 	struct my_context *ctx       = (struct my_context *)priv;
494 	struct usb_urb *mx_urb       = ctx->mx_urb;
495 	struct ddekit_usb_urb *d_urb = ctx->d_urb;
496 	struct minix_usb_driver *drv = ctx->drv;
497 
498 	DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ",
499 		    ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid);
500 
501 	/* update data in minix URB */
502 	mx_urb->status          = d_urb->status;
503 	mx_urb->actual_length   = d_urb->actual_length;
504 	mx_urb->error_count     = d_urb->error_count;
505 	mx_urb->transfer_flags  = d_urb->transfer_flags;
506 
507 	remove_from_pending_urbs(drv, d_urb);
508 
509 	/* copy out URB */
510 	res = sys_safecopyto(drv->ep, ctx->gid, 0,
511 	    (vir_bytes) ((char*)mx_urb) + sizeof(void*),
512 		mx_urb->urb_size - sizeof(void*));
513 
514 	if (res != 0) {
515 		DEBUG_MSG("Copy out failed: %d", res);
516 		DEBUG_MSG(" URB ID: %d, Grant-ID: %d, Grant-size: %d", ctx->urb_id,
517 		            ctx->gid, mx_urb->urb_size);
518 	}
519 
520 	/* send message to client */
521 	msg.m_type     = USB_COMPLETE_URB;
522 	msg.USB_URB_ID = ctx->urb_id;
523 	asynsend3(drv->ep, &msg, AMF_NOREPLY);
524 
525 	/* free stuff */
526 	my_free(ctx);
527 	my_free(mx_urb);
528 	my_free(d_urb);
529 }
530 
531 
532 /*****************************************************************************
533  *         prepare_devman_usbdev                                             *
534  ****************************************************************************/
prepare_devman_usbdev(struct ddekit_usb_dev * dev,int dev_id,unsigned int interfaces,struct devman_usb_dev * dudev)535 static void prepare_devman_usbdev
536 (struct ddekit_usb_dev * dev, int dev_id, unsigned int interfaces,
537  struct devman_usb_dev *dudev)
538 {
539 	int j;
540 	int intf_count;
541 	/*
542 	 * currently this is only implemented by stub driver
543 	 */
544 
545 	usb_device_descriptor_t *desc = _ddekit_usb_get_device_desc(dev);
546 
547 	dudev->manufacturer = _ddekit_usb_get_manufacturer(dev);
548 	dudev->product = _ddekit_usb_get_product(dev);
549 	dudev->serial = _ddekit_usb_get_serial(dev);
550 
551 	dudev->desc = desc;
552 
553 	intf_count = 0;
554 
555 	for (j=0; j < 32; j++) {
556 		if (interfaces & (1 << j)) {
557 				dudev->interfaces[intf_count++].desc =
558 				   _ddekit_usb_get_interface_desc(dev, j);
559 		}
560 	}
561 
562 	dudev->intf_count = intf_count;
563 	dudev->dev_id     = dev_id;
564 }
565 
566 /*****************************************************************************
567  *         device_connect_callback                                           *
568  ****************************************************************************/
569 static void
device_connect_callback(struct ddekit_usb_dev * dev,unsigned int interfaces)570 device_connect_callback
571 (struct ddekit_usb_dev * dev, unsigned int interfaces) {
572 
573 	int i, res;
574 
575 	/* add to device list */
576 	for (i=0; i < MAX_DEVS; i++) {
577 		if (_devices[i].dev == NULL)
578 			break;
579 	}
580 
581 	if (i >= MAX_DEVS) {
582 		DEBUG_MSG("Too much devices...");
583 	} else {
584 		_devices[i].dev = dev;
585 		_devices[i].interfaces = (1 << interfaces);
586 	}
587 
588 	struct devman_usb_dev *dudev;
589 
590 	dudev = devman_usb_device_new(i);
591 
592 	prepare_devman_usbdev(dev, i, interfaces, dudev);
593 
594 	if (dudev == NULL) {
595 		/* TODO: ERROR */
596 		printf("ERROR: !");
597 	}
598 
599 	ddekit_usb_dev_set_data(dev, dudev);
600 
601 	res = devman_usb_device_add(dudev);
602 
603 	if (res != 0) {
604 		/* TODO: Error*/
605 		printf("ERROR!");
606 	}
607 }
608 
609 /*****************************************************************************
610  *         device_disconnect_callback                                        *
611  ****************************************************************************/
device_disconnect_callback(struct ddekit_usb_dev * dev)612 static void device_disconnect_callback(struct ddekit_usb_dev * dev)
613 {
614 	int i;
615 
616 	/* remove ACL entry */
617 	for (i = 0; i< MAX_DRIVERS; i++) {
618 		if (gbl_drivers[i].dev != INVAL_DEV
619 			&& _devices[gbl_drivers[i].dev].dev == dev) {
620 			struct minix_usb_driver *drv = &gbl_drivers[i];
621 			drv->ep     = 0;
622 			drv->status = DRIVER_UNUSED;
623 			drv->dev    = INVAL_DEV;
624 		}
625 	}
626 
627 	for (i=0; i < MAX_DEVS; i++) {
628 		if (_devices[i].dev == dev) {
629 			_devices[i].dev = NULL;
630 			_devices[i].interfaces = 0;
631 		}
632 	}
633 
634 
635 	/* get the devman device */
636 	struct devman_usb_dev * dudev = NULL;
637 
638 	dudev = ddekit_usb_dev_get_data(dev);
639 
640 	if (dudev == NULL) {
641 		/* TODO: error */
642 	}
643 
644 	devman_usb_device_remove(dudev);
645 
646 	/* free the devman dev */
647 	devman_usb_device_delete(dudev);
648 }
649 
650 
651 /*****************************************************************************
652  *         add_acl                                                           *
653  ****************************************************************************/
add_acl(int dev_id,unsigned interfaces,endpoint_t ep)654 static int add_acl(int dev_id, unsigned interfaces, endpoint_t ep)
655 {
656 	/*
657 	 * This functions binds a specific USB interface to a client.
658 	 */
659 	int i;
660 	struct minix_usb_driver *drv;
661 
662 	if (_devices[dev_id].dev == NULL) {
663 		/* if no device with that ID */
664 		return  ENODEV;
665 	}
666 
667 	/* is the device allready given to a client*/
668 	for (i = 0; i< MAX_DRIVERS; i++) {
669 		if (gbl_drivers[i].status != DRIVER_UNUSED &&
670 			gbl_drivers[i].dev == dev_id) {
671 			printf("devid: %d\n", dev_id);
672 			return EBUSY;
673 		}
674 	}
675 
676 	/* bind device to client */
677 	drv = find_unused_driver();
678 
679 	if (drv == NULL) {
680 		return ENOMEM;
681 	}
682 
683 	drv->status     = DRIVER_BOUND;
684 	drv->dev        = dev_id;
685 	drv->interfaces = 1 << interfaces;
686 	drv->ep         = ep;
687 	drv->urb_id     = 0;
688 
689 	return OK;
690 }
691 
692 /*****************************************************************************
693  *         del_acl                                                           *
694  ****************************************************************************/
del_acl(int dev_id,unsigned interfaces,endpoint_t ep)695 static int del_acl(int dev_id, unsigned interfaces, endpoint_t ep)
696 {
697 	struct minix_usb_driver *drv;
698 	int dev, withdraw = 0;
699 	message msg;
700 
701 	/* find driver */
702 	drv = find_driver(ep);
703 
704 	if (drv == NULL) {
705 		return  ENOENT;
706 	}
707 
708 	dev = drv->dev;
709 
710 	if (drv->status == DRIVER_ACTIVE) {
711 		withdraw = 1;
712 	}
713 
714 	drv->ep    = 0;
715 	drv->status = DRIVER_UNUSED;
716 	drv->dev   = INVAL_DEV;
717 
718 	if (withdraw) {
719 		msg.m_type     = USB_WITHDRAW_DEV;
720 		msg.USB_DEV_ID = dev;
721 		asynsend3(ep, &msg, AMF_NOREPLY);
722 	}
723 
724 	return 0;
725 }
726 
727 /*****************************************************************************
728  *         handle_msg                                                        *
729  ****************************************************************************/
handle_msg(message * msg)730 static int handle_msg(message *msg)
731 {
732 	/*
733 	 * handle_msg
734 	 *
735 	 * The dispatcher for USB related messages.
736 	 */
737 
738 	switch(msg->m_type) {
739 		case USB_RQ_INIT:
740 			register_driver(msg);
741 			return 1;
742 		case USB_RQ_DEINIT:
743 			deregister_driver(msg);
744 			return 1;
745 		case USB_RQ_SEND_URB:
746 			submit_urb(msg);
747 			return 1;
748 		case USB_RQ_CANCEL_URB:
749 			cancle_urb(msg);
750 			return 1;
751 		case USB_RQ_SEND_INFO:
752 			get_info(msg);
753 			return 1;
754 		default:
755 			return 0;
756 	}
757 }
758 
759 /*****************************************************************************
760  *         devman_tread                                                      *
761  ****************************************************************************/
devman_thread(void * unused)762 static void devman_thread(void *unused)
763 {
764 	struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(DEVMAN_BASE,
765 	    DEVMAN_BASE + 0xff);
766 	int ipc_status;
767 	message m;
768 	while (1) {
769 		ddekit_minix_rcv(mq, &m, &ipc_status);
770 		devman_handle_msg(&m);
771 	}
772 }
773 
774 /*****************************************************************************
775  *         _ddekit_usb_thread                                                *
776  ****************************************************************************/
_ddekit_usb_thread(void * unused)777 static void _ddekit_usb_thread(void * unused)
778 {
779 	struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE,
780 	    USB_BASE + 0xff);
781 
782 	message m;
783 	int ipc_status;
784 
785 	/* create devman thread */
786 	ddekit_thread_t * __unused dmth;
787 
788 	dmth = ddekit_thread_create(devman_thread, NULL, "devman_thread");
789 
790 	while (1) {
791 		ddekit_minix_rcv(mq, &m, &ipc_status);
792 		handle_msg(&m);
793 	}
794 }
795 
796 
797 /*****************************************************************************
798  *         bind_cb                                                           *
799  ****************************************************************************/
bind_cb(struct devman_usb_bind_cb_data * data,endpoint_t ep)800 static int bind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep)
801 {
802 	if(data) {
803 		return add_acl(data->dev_id, data->interface, ep);
804 	} else {
805 		printf("warning: missing cb_data!\n");
806 		return EINVAL;
807 	}
808 }
809 
810 /*****************************************************************************
811  *         unbind_cb                                                         *
812  ****************************************************************************/
unbind_cb(struct devman_usb_bind_cb_data * data,endpoint_t ep)813 static int unbind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep)
814 {
815 	if(data) {
816 		return del_acl(data->dev_id, data->interface, ep);
817 	} else {
818 		printf("warning: missing cb_data!\n");
819 		return EINVAL;
820 	}
821 }
822 
823 /*****************************************************************************
824  *         ddekit_usb_server_init                                            *
825  ****************************************************************************/
ddekit_usb_server_init()826 void ddekit_usb_server_init()
827 {
828 	int i;
829 	/*
830 	 * this function has to be called inside the context of an dedicated
831 	 * DDELinux thread
832 	 */
833 	devman_usb_init(bind_cb, unbind_cb);
834 	ddekit_usb_init(&my_driver, &my_malloc, &my_free);
835 	for (i = 0; i< MAX_DRIVERS; i++) {
836 		gbl_drivers[i].dev = DRIVER_UNUSED;
837 		gbl_drivers[i].dev = INVAL_DEV;
838 	}
839 	_ddekit_usb_thread(NULL);
840 
841 }
842