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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 ****************************************************************************/ 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 310 struct usb_urb *mx_urb = (struct usb_urb*) 311 my_malloc(msg->USB_GRANT_SIZE+sizeof(void *)); 312 313 if (mx_urb == NULL) { 314 DEBUG_MSG("Can't allocat mem for mx_urb."); 315 res = ENOMEM; 316 goto out; 317 } 318 319 /* copy in URB */ 320 res = sys_safecopyfrom(ep, msg->USB_GRANT_ID, 0, 321 (vir_bytes) &mx_urb->dev_id, msg->USB_GRANT_SIZE); 322 323 if (res != 0) { 324 DEBUG_MSG("sys_safecopyfrom failed "); 325 my_free(mx_urb); 326 res = EINVAL; 327 goto out; 328 } 329 330 DEBUG_MSG("URB type: %d", mx_urb->type); 331 /* check if urb is valid */ 332 if (mx_urb->dev_id >= MAX_DEVS || mx_urb->dev_id < 0) { 333 DEBUG_MSG("Bogus device ID."); 334 res = EINVAL; 335 goto out; 336 } 337 338 /* create ddekit_usb_urb */ 339 struct ddekit_usb_urb *d_urb = ddekit_usb_urb_from_mx_urb(mx_urb); 340 d_urb->dev = _devices[drv->dev].dev; 341 /* submit urb */ 342 343 if (!d_urb) { 344 res = ENOMEM; 345 goto out; 346 } 347 348 struct my_context *ctx = (struct my_context *) 349 my_malloc(sizeof(struct my_context)); 350 351 if(!ctx) { 352 res = ENOMEM; 353 goto out; 354 } 355 356 ctx->drv = drv; 357 ctx->urb_id = drv->urb_id++; 358 mx_urb->urb_id = ctx->urb_id; 359 ctx->mx_urb = mx_urb; 360 ctx->d_urb = d_urb; 361 ctx->gid = msg->USB_GRANT_ID; 362 363 DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ", 364 ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid); 365 366 d_urb->priv = ctx; 367 368 res = add_to_pending_urbs(drv, d_urb); 369 370 if (res == 0) { 371 DEBUG_MSG("submitting urb..."); 372 res = ddekit_usb_submit_urb(d_urb); 373 if(res) { 374 DEBUG_MSG("submitting urb failed (err: %d)", res); 375 remove_from_pending_urbs(drv, d_urb); 376 } 377 } 378 379 out: 380 /* reply */ 381 msg->m_type = USB_REPLY; 382 msg->USB_URB_ID = mx_urb->urb_id; 383 msg->USB_RESULT = res; 384 385 if(res != 0) { 386 387 if (mx_urb != NULL) { 388 my_free(mx_urb); 389 } 390 if (ctx != NULL) { 391 my_free(ctx); 392 } 393 394 if (d_urb != NULL) { 395 my_free(d_urb); 396 } 397 398 } 399 400 /* send reply */ 401 ipc_send(ep, msg); 402 } 403 } 404 405 406 /* 407 * cancle_urb 408 * 409 * Cancels the submission of an URB identified by a URB_id 410 */ 411 /***************************************************************************** 412 * cancle_urb * 413 ****************************************************************************/ 414 static void cancle_urb(message *msg) 415 { 416 endpoint_t ep = msg->m_source; 417 418 struct minix_usb_driver *drv; 419 420 msg->USB_RESULT = -1; 421 msg->m_type = USB_REPLY; 422 423 /* find driver */ 424 if ( (drv = find_driver(ep)) == NULL) { 425 DEBUG_MSG("Non-registered driver tries to cancel URB."); 426 return; 427 } else { 428 struct ddekit_usb_urb *d_urb = NULL; 429 430 d_urb = find_pending_urb(drv, msg->USB_URB_ID); 431 432 if (d_urb != NULL) { 433 ddekit_usb_cancle_urb(d_urb); 434 msg->USB_RESULT = 0; 435 } else { 436 DEBUG_MSG("No URB to cancle"); 437 msg->USB_RESULT = ENODEV; 438 } 439 } 440 441 ipc_send(ep, msg); 442 } 443 444 445 /***************************************************************************** 446 * get_info * 447 *****************************************************************************/ 448 static void 449 get_info(message * msg) 450 { 451 struct minix_usb_driver * drv; 452 endpoint_t ep; 453 long info_type; 454 long info_value; 455 456 /* Read */ 457 ep = msg->m_source; 458 info_type = msg->USB_INFO_TYPE; 459 info_value = msg->USB_INFO_VALUE; 460 461 /* Reuse as reply */ 462 msg->m_type = USB_REPLY; 463 msg->USB_RESULT = -1; 464 465 /* Try and find driver first */ 466 if (NULL == (drv = find_driver(ep))) 467 ddekit_printf("Non-registered driver tries to send info"); 468 else 469 /* Route info to device */ 470 msg->USB_RESULT = ddekit_usb_info(_devices[drv->dev].dev, 471 info_type, info_value); 472 473 /* Reply */ 474 ipc_send(ep, msg); 475 } 476 477 478 /***************************************************************************** 479 * completion_callback * 480 ****************************************************************************/ 481 static void completion_callback(void *priv) 482 { 483 /* 484 * completion_callback 485 * 486 * This is called by the DDE side. Here the data is copied back to 487 * the driver and a message is send to inform the driver about the 488 * completion. 489 */ 490 message msg; 491 int res; 492 struct my_context *ctx = (struct my_context *)priv; 493 struct usb_urb *mx_urb = ctx->mx_urb; 494 struct ddekit_usb_urb *d_urb = ctx->d_urb; 495 struct minix_usb_driver *drv = ctx->drv; 496 497 DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ", 498 ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid); 499 500 /* update data in minix URB */ 501 mx_urb->status = d_urb->status; 502 mx_urb->actual_length = d_urb->actual_length; 503 mx_urb->error_count = d_urb->error_count; 504 mx_urb->transfer_flags = d_urb->transfer_flags; 505 506 remove_from_pending_urbs(drv, d_urb); 507 508 /* copy out URB */ 509 res = sys_safecopyto(drv->ep, ctx->gid, 0, 510 (vir_bytes) ((char*)mx_urb) + sizeof(void*), 511 mx_urb->urb_size - sizeof(void*)); 512 513 if (res != 0) { 514 DEBUG_MSG("Copy out failed: %d", res); 515 DEBUG_MSG(" URB ID: %d, Grant-ID: %d, Grant-size: %d", ctx->urb_id, 516 ctx->gid, mx_urb->urb_size); 517 } 518 519 /* send message to client */ 520 msg.m_type = USB_COMPLETE_URB; 521 msg.USB_URB_ID = ctx->urb_id; 522 asynsend3(drv->ep, &msg, AMF_NOREPLY); 523 524 /* free stuff */ 525 my_free(ctx); 526 my_free(mx_urb); 527 my_free(d_urb); 528 } 529 530 531 /***************************************************************************** 532 * prepare_devman_usbdev * 533 ****************************************************************************/ 534 static void prepare_devman_usbdev 535 (struct ddekit_usb_dev * dev, int dev_id, unsigned int interfaces, 536 struct devman_usb_dev *dudev) 537 { 538 int j; 539 int intf_count; 540 /* 541 * currently this is only implemented by stub driver 542 */ 543 544 usb_device_descriptor_t *desc = _ddekit_usb_get_device_desc(dev); 545 546 dudev->manufacturer = _ddekit_usb_get_manufacturer(dev); 547 dudev->product = _ddekit_usb_get_product(dev); 548 dudev->serial = _ddekit_usb_get_serial(dev); 549 550 dudev->desc = desc; 551 552 intf_count = 0; 553 554 for (j=0; j < 32; j++) { 555 if (interfaces & (1 << j)) { 556 dudev->interfaces[intf_count++].desc = 557 _ddekit_usb_get_interface_desc(dev, j); 558 } 559 } 560 561 dudev->intf_count = intf_count; 562 dudev->dev_id = dev_id; 563 } 564 565 /***************************************************************************** 566 * device_connect_callback * 567 ****************************************************************************/ 568 static void 569 device_connect_callback 570 (struct ddekit_usb_dev * dev, unsigned int interfaces) { 571 572 int i, res; 573 574 /* add to device list */ 575 for (i=0; i < MAX_DEVS; i++) { 576 if (_devices[i].dev == NULL) 577 break; 578 } 579 580 if (i >= MAX_DEVS) { 581 DEBUG_MSG("Too much devices..."); 582 } else { 583 _devices[i].dev = dev; 584 _devices[i].interfaces = (1 << interfaces); 585 } 586 587 struct devman_usb_dev *dudev; 588 589 dudev = devman_usb_device_new(i); 590 591 prepare_devman_usbdev(dev, i, interfaces, dudev); 592 593 if (dudev == NULL) { 594 /* TODO: ERROR */ 595 printf("ERROR: !"); 596 } 597 598 ddekit_usb_dev_set_data(dev, dudev); 599 600 res = devman_usb_device_add(dudev); 601 602 if (res != 0) { 603 /* TODO: Error*/ 604 printf("ERROR!"); 605 } 606 } 607 608 /***************************************************************************** 609 * device_disconnect_callback * 610 ****************************************************************************/ 611 static void device_disconnect_callback(struct ddekit_usb_dev * dev) 612 { 613 int i; 614 615 /* remove ACL entry */ 616 for (i = 0; i< MAX_DRIVERS; i++) { 617 if (gbl_drivers[i].dev != INVAL_DEV 618 && _devices[gbl_drivers[i].dev].dev == dev) { 619 struct minix_usb_driver *drv = &gbl_drivers[i]; 620 drv->ep = 0; 621 drv->status = DRIVER_UNUSED; 622 drv->dev = INVAL_DEV; 623 } 624 } 625 626 for (i=0; i < MAX_DEVS; i++) { 627 if (_devices[i].dev == dev) { 628 _devices[i].dev = NULL; 629 _devices[i].interfaces = 0; 630 } 631 } 632 633 634 /* get the devman device */ 635 struct devman_usb_dev * dudev = NULL; 636 637 dudev = ddekit_usb_dev_get_data(dev); 638 639 if (dudev == NULL) { 640 /* TODO: error */ 641 } 642 643 devman_usb_device_remove(dudev); 644 645 /* free the devman dev */ 646 devman_usb_device_delete(dudev); 647 } 648 649 650 /***************************************************************************** 651 * add_acl * 652 ****************************************************************************/ 653 static int add_acl(int dev_id, unsigned interfaces, endpoint_t ep) 654 { 655 /* 656 * This functions binds a specific USB interface to a client. 657 */ 658 int i; 659 struct minix_usb_driver *drv; 660 661 if (_devices[dev_id].dev == NULL) { 662 /* if no device with that ID */ 663 return ENODEV; 664 } 665 666 /* is the device allready given to a client*/ 667 for (i = 0; i< MAX_DRIVERS; i++) { 668 if (gbl_drivers[i].status != DRIVER_UNUSED && 669 gbl_drivers[i].dev == dev_id) { 670 printf("devid: %d\n", dev_id); 671 return EBUSY; 672 } 673 } 674 675 /* bind device to client */ 676 drv = find_unused_driver(); 677 678 if (drv == NULL) { 679 return ENOMEM; 680 } 681 682 drv->status = DRIVER_BOUND; 683 drv->dev = dev_id; 684 drv->interfaces = 1 << interfaces; 685 drv->ep = ep; 686 drv->urb_id = 0; 687 688 return OK; 689 } 690 691 /***************************************************************************** 692 * del_acl * 693 ****************************************************************************/ 694 static int del_acl(int dev_id, unsigned interfaces, endpoint_t ep) 695 { 696 struct minix_usb_driver *drv; 697 int dev, withdraw = 0; 698 message msg; 699 700 /* find driver */ 701 drv = find_driver(ep); 702 703 if (drv == NULL) { 704 return ENOENT; 705 } 706 707 dev = drv->dev; 708 709 if (drv->status == DRIVER_ACTIVE) { 710 withdraw = 1; 711 } 712 713 drv->ep = 0; 714 drv->status = DRIVER_UNUSED; 715 drv->dev = INVAL_DEV; 716 717 if (withdraw) { 718 msg.m_type = USB_WITHDRAW_DEV; 719 msg.USB_DEV_ID = dev; 720 asynsend3(ep, &msg, AMF_NOREPLY); 721 } 722 723 return 0; 724 } 725 726 /***************************************************************************** 727 * handle_msg * 728 ****************************************************************************/ 729 static int handle_msg(message *msg) 730 { 731 /* 732 * handle_msg 733 * 734 * The dispatcher for USB related messages. 735 */ 736 737 switch(msg->m_type) { 738 case USB_RQ_INIT: 739 register_driver(msg); 740 return 1; 741 case USB_RQ_DEINIT: 742 deregister_driver(msg); 743 return 1; 744 case USB_RQ_SEND_URB: 745 submit_urb(msg); 746 return 1; 747 case USB_RQ_CANCEL_URB: 748 cancle_urb(msg); 749 return 1; 750 case USB_RQ_SEND_INFO: 751 get_info(msg); 752 return 1; 753 default: 754 return 0; 755 } 756 } 757 758 /***************************************************************************** 759 * devman_tread * 760 ****************************************************************************/ 761 static void devman_thread(void *unused) 762 { 763 struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(DEVMAN_BASE, 764 DEVMAN_BASE + 0xff); 765 int ipc_status; 766 message m; 767 while (1) { 768 ddekit_minix_rcv(mq, &m, &ipc_status); 769 devman_handle_msg(&m); 770 } 771 } 772 773 /***************************************************************************** 774 * _ddekit_usb_thread * 775 ****************************************************************************/ 776 static void _ddekit_usb_thread(void * unused) 777 { 778 struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE, 779 USB_BASE + 0xff); 780 781 message m; 782 int ipc_status; 783 784 /* create devman thread */ 785 ddekit_thread_t * dmth; 786 787 dmth = ddekit_thread_create(devman_thread, NULL, "devman_thread"); 788 789 while (1) { 790 ddekit_minix_rcv(mq, &m, &ipc_status); 791 handle_msg(&m); 792 } 793 } 794 795 796 /***************************************************************************** 797 * bind_cb * 798 ****************************************************************************/ 799 static int bind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep) 800 { 801 if(data) { 802 return add_acl(data->dev_id, data->interface, ep); 803 } else { 804 printf("warning: missing cb_data!\n"); 805 return EINVAL; 806 } 807 } 808 809 /***************************************************************************** 810 * unbind_cb * 811 ****************************************************************************/ 812 static int unbind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep) 813 { 814 if(data) { 815 return del_acl(data->dev_id, data->interface, ep); 816 } else { 817 printf("warning: missing cb_data!\n"); 818 return EINVAL; 819 } 820 } 821 822 /***************************************************************************** 823 * ddekit_usb_server_init * 824 ****************************************************************************/ 825 void ddekit_usb_server_init() 826 { 827 int i; 828 /* 829 * this function has to be called inside the context of an dedicated 830 * DDELinux thread 831 */ 832 devman_usb_init(bind_cb, unbind_cb); 833 ddekit_usb_init(&my_driver, &my_malloc, &my_free); 834 for (i = 0; i< MAX_DRIVERS; i++) { 835 gbl_drivers[i].dev = DRIVER_UNUSED; 836 gbl_drivers[i].dev = INVAL_DEV; 837 } 838 _ddekit_usb_thread(NULL); 839 840 } 841