Changeset 23328
- Timestamp:
- 01/09/08 14:46:54 (11 months ago)
- Location:
- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid
- Files:
-
- 2 modified
Legend:
- Unmodified
- Added
- Removed
-
haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/hid.c
r22305 r23328 340 340 device->open_fds = NULL; 341 341 device->active = true; 342 device-> unplugged = false;342 device->transfer_scheduled = false; 343 343 device->insns = NULL; 344 344 device->num_insns = 0; … … 356 356 device->repeat_rate = 35000; 357 357 device->repeat_delay = 300000; 358 device->repeat_timer.device = device;359 358 360 359 return device; … … 366 365 { 367 366 assert(device != NULL); 368 cancel_timer(&device->repeat_timer.timer);369 367 370 368 if (device->rbuf != NULL) { … … 389 387 390 388 ring_buffer_write(device->rbuf, (const uint8*)&raw, sizeof(raw_key_info)); 391 release_sem_etc(device->sem_cb, 1, B_DO_NOT_RESCHEDULE);392 }393 394 395 static int32396 timer_repeat_hook(struct timer *timer)397 {398 hid_device_info *device = ((struct hid_repeat_timer *)timer)->device;399 400 write_key(device, device->repeat_timer.key, true);401 return B_HANDLED_INTERRUPT;402 }403 404 405 static int32406 timer_delay_hook(struct timer *timer)407 {408 hid_device_info *device = ((struct hid_repeat_timer *)timer)->device;409 410 add_timer(&device->repeat_timer.timer, timer_repeat_hook, device->repeat_rate,411 B_PERIODIC_TIMER);412 return B_HANDLED_INTERRUPT;413 389 } 414 390 … … 458 434 459 435 // repeat handling 460 cancel_timer(&device->repeat_timer.timer);461 436 device->repeat_timer.key = key; 462 add_timer(&device->repeat_timer.timer, timer_delay_hook, 463 device->repeat_delay, B_ONE_SHOT_RELATIVE_TIMER); 437 device->repeat_timer.current_delay = device->repeat_delay; 464 438 } 465 439 } else … … 493 467 494 468 write_key(device, key, false); 469 470 // cancel the repeats if they are for this key 495 471 if (device->repeat_timer.key == key) 496 cancel_timer(&device->repeat_timer.timer);472 device->repeat_timer.current_delay = B_INFINITE_TIMEOUT; 497 473 } 498 474 } else … … 591 567 info.timestamp = device->timestamp; 592 568 ring_buffer_write(device->rbuf, (const uint8*)&info, sizeof(info)); 593 release_sem_etc(device->sem_cb, 1, B_DO_NOT_RESCHEDULE); 594 } 569 } 570 571 // #pragma mark - interrupt transfers 595 572 596 573 … … 603 580 { 604 581 hid_device_info *device = cookie; 605 status_t status; 606 607 if (device == NULL || device->unplugged) 608 return; 609 610 acquire_sem(device->sem_lock); 582 611 583 device->actual_length = actualLength; 612 584 device->bus_status = busStatus; /* B_USB_STATUS_* */ 613 if (busStatus != B_OK) { 585 586 // release the notification semaphore so the input_server 587 // thread which is blocking in hid_device_control can continue 588 // to run (see you in handle_interrupt_transfer()) 589 release_sem_etc(device->sem_cb, 1, B_DO_NOT_RESCHEDULE); 590 } 591 592 static status_t 593 schedule_interrupt_transfer(hid_device_info* device) 594 { 595 status_t status = usb->queue_interrupt(device->ept->handle, device->buffer, 596 device->total_report_size, usb_callback, device); 597 if (status != B_OK) { 598 /* XXX probably endpoint stall */ 599 DPRINTF_ERR ((MY_ID "queue_interrupt() error %d\n", (int)status)); 600 } 601 return status; 602 } 603 604 static status_t 605 handle_interrupt_transfer(hid_device_info* device) 606 { 607 status_t status = device->bus_status; 608 609 if (status != B_OK) { 614 610 /* request failed */ 615 release_sem(device->sem_lock); 616 DPRINTF_ERR((MY_ID "bus status %d\n", (int)busStatus)); 617 if (busStatus == B_CANCELED) { 611 DPRINTF_ERR((MY_ID "bus status %d\n", (int)device->bus_status)); 612 if (status == B_CANCELED) { 618 613 /* cancelled: device is unplugged */ 619 return ;614 return status; 620 615 } 621 616 #if 1 … … 642 637 } else 643 638 interpret_mouse_buffer(device); 644 645 release_sem(device->sem_lock); 646 } 647 648 /* issue next request */ 649 650 status = usb->queue_interrupt(device->ept->handle, device->buffer, 651 device->total_report_size, usb_callback, device); 652 if (status != B_OK) { 653 /* XXX probably endpoint stall */ 654 DPRINTF_ERR ((MY_ID "queue_interrupt() error %d\n", (int)status)); 655 } 639 } 640 641 return status; 656 642 } 657 643 … … 842 828 DPRINTF_INFO ((MY_ID "%08lx %08lx %08lx\n", *(((uint32*)device->buffer)), *(((uint32*)device->buffer)+1), *(((uint32*)device->buffer)+2))); 843 829 844 /* issue interrupt transfer */845 846 830 device->ept = &intf->endpoint[0]; /* interrupt IN */ 847 status = usb->queue_interrupt(device->ept->handle, device->buffer,848 device->total_report_size, usb_callback, device);849 if (status != B_OK) {850 DPRINTF_ERR ((MY_ID "queue_interrupt() error %d\n", (int)status));851 return B_ERROR;852 }853 831 854 832 /* create a port */ … … 871 849 DPRINTF_INFO((MY_ID "device_removed(%s)\n", device->name)); 872 850 873 device->unplugged = true;874 851 usb->cancel_queued_transfers (device->ept->handle); 875 852 remove_device_info(device); … … 951 928 switch (op) { 952 929 case KB_READ: 953 err = acquire_sem_etc(device->sem_cb, 1, B_CAN_INTERRUPT, 0LL); 954 if (err != B_OK) 955 return err; 956 acquire_sem(device->sem_lock); 930 while (ring_buffer_readable(device->rbuf) == 0) { 931 if (!device->transfer_scheduled) { 932 err = schedule_interrupt_transfer(device); 933 if (err != B_OK) 934 return err; 935 device->transfer_scheduled = true; 936 // NOTE: this thread is now blocking until 937 // the semaphore will be released from the 938 // call_back function 939 } 940 941 err = acquire_sem_etc(device->sem_cb, 1, 942 B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, 943 device->repeat_timer.current_delay); 944 if (err == B_TIMED_OUT) { 945 // this case is for handling key repeats, it means 946 // no interrupt transfer has happened 947 write_key(device, device->repeat_timer.key, true); 948 // the next timeout is reduced to the repeat_rate 949 device->repeat_timer.current_delay = device->repeat_rate; 950 } else if (err == B_OK) { 951 // this case is for when an actual interrupt transfer 952 // happened, it is the only possible reason to be here 953 device->transfer_scheduled = false; 954 err = handle_interrupt_transfer(device); 955 if (err != B_OK) 956 return err; 957 } else { 958 return err; 959 } 960 } 961 962 // process what is in the ring_buffer, it could be written 963 // there because we handled an interrupt transfer or because 964 // we wrote the current repeat key 957 965 ring_buffer_user_read(device->rbuf, arg, sizeof(raw_key_info)); 958 release_sem(device->sem_lock); 959 return err; 960 break; 966 return B_OK; 961 967 962 968 case KB_SET_LEDS: … … 967 973 switch (op) { 968 974 case MS_READ: 975 err = schedule_interrupt_transfer(device); 976 if (err != B_OK) 977 return err; 978 // NOTE: this thread is now blocking until 979 // the semaphore will be released from the 980 // call_back function 981 969 982 err = acquire_sem_etc(device->sem_cb, 1, B_CAN_INTERRUPT, 0LL); 970 983 if (err != B_OK) 971 984 return err; 985 986 err = handle_interrupt_transfer(device); 987 if (err != B_OK) 988 return err; 989 972 990 acquire_sem(device->sem_lock); 973 991 ring_buffer_user_read(device->rbuf, arg, sizeof(mouse_movement)); -
haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/hid.h
r22305 r23328 46 46 47 47 struct hid_repeat_timer { 48 struct timer timer; 49 struct hid_device_info *device; 48 bigtime_t current_delay; 50 49 uint32 key; 51 50 }; … … 69 68 70 69 bool active; 71 bool unplugged;72 70 int open; 73 71 struct driver_cookie *open_fds; … … 77 75 int actual_length; 78 76 const usb_endpoint_info *ept; 77 bool transfer_scheduled; 79 78 80 79 report_insn *insns;
