Several problems prevented USB HIDs to be opened, closed and reopened:
* The first problem was introduced by myself, when I added deleting the transfer semaphore in HIDDevice::Close(). Obviously, I should (re)create it in Open() then, or it won't work another time. (Open() is now the only place where it's created.) * The second problem was when transfers have already been scheduled the last time the device was open, but never triggered yet. We need to reset the fTransferUnprocessed flag, or we won't schedule another transfer but wait on the transfer semaphore anyways in Control(). I also added canceling the usb transfers with the stack in Close(). * The remaining problems were specific to the KeyboardDevice, the repeat key stuff needs to be reset in Open(). I also added unsetting the repeat key when the key release is detected, but this should have already worked, because the semaphore timeout was reset to B_INFINITE_TIMEOUT. One can now "/system/servers/input_server -q" and everything will be back in working order. There may be some remaining problems in the Wacom driver which I have not yet looked at. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28368 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -39,12 +39,6 @@ HIDDevice::HIDDevice(usb_device device, usb_pipe interruptPipe,
|
||||
if (ringBufferSize > 0)
|
||||
fRingBuffer = create_ring_buffer(ringBufferSize);
|
||||
|
||||
fTransferNotifySem = create_sem(0, "hid device transfer notify sem");
|
||||
if (fTransferNotifySem < B_OK) {
|
||||
fStatus = fTransferNotifySem;
|
||||
return;
|
||||
}
|
||||
|
||||
fTransferBuffer = (uint8 *)malloc(fTotalReportSize);
|
||||
if (fTransferBuffer == NULL) {
|
||||
fStatus = B_NO_MEMORY;
|
||||
@@ -231,7 +225,17 @@ HIDDevice::SetParentCookie(int32 cookie)
|
||||
status_t
|
||||
HIDDevice::Open(uint32 flags)
|
||||
{
|
||||
if (fOpen)
|
||||
return B_BUSY;
|
||||
|
||||
if (fTransferNotifySem < 0) {
|
||||
fTransferNotifySem = create_sem(0, "hid device transfer notify sem");
|
||||
if (fTransferNotifySem < 0)
|
||||
return (status_t)fTransferNotifySem;
|
||||
}
|
||||
|
||||
fOpen = true;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -242,8 +246,10 @@ HIDDevice::Close()
|
||||
fOpen = false;
|
||||
// make threads waiting for a transfer bail out
|
||||
if (fTransferNotifySem >= 0) {
|
||||
gUSBModule->cancel_queued_transfers(fInterruptPipe);
|
||||
delete_sem(fTransferNotifySem);
|
||||
fTransferNotifySem = -1;
|
||||
_SetTransferProcessed();
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
@@ -307,6 +313,8 @@ HIDDevice::_IsTransferUnprocessed()
|
||||
status_t
|
||||
HIDDevice::_ScheduleTransfer()
|
||||
{
|
||||
if (fTransferNotifySem < 0)
|
||||
return B_ERROR;
|
||||
if (fTransferUnprocessed)
|
||||
return B_BUSY;
|
||||
if (fRemoved)
|
||||
|
||||
@@ -43,6 +43,23 @@ KeyboardDevice::~KeyboardDevice()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::Open(uint32 flags)
|
||||
{
|
||||
status_t status = HIDDevice::Open(flags);
|
||||
if (status != B_OK) {
|
||||
TRACE_ALWAYS("keyboard device failed to open: %s\n",
|
||||
strerror(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
fCurrentRepeatDelay = B_INFINITE_TIMEOUT;
|
||||
fCurrentRepeatKey = 0;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
@@ -71,6 +88,7 @@ KeyboardDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
_WriteKey(fCurrentRepeatKey, true);
|
||||
// the next timeout is reduced to the repeat_rate
|
||||
fCurrentRepeatDelay = fRepeatRate;
|
||||
break;
|
||||
} else if (result == B_INTERRUPTED && IsOpen()) {
|
||||
continue;
|
||||
} else
|
||||
@@ -346,8 +364,10 @@ KeyboardDevice::_InterpretBuffer()
|
||||
fCurrentRepeatDelay = fRepeatDelay;
|
||||
} else {
|
||||
// cancel the repeats if they are for this key
|
||||
if (fCurrentRepeatKey == key)
|
||||
if (fCurrentRepeatKey == key) {
|
||||
fCurrentRepeatDelay = B_INFINITE_TIMEOUT;
|
||||
fCurrentRepeatKey = 0;
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
size_t totalReportSize);
|
||||
virtual ~KeyboardDevice();
|
||||
|
||||
virtual status_t Open(uint32 flags);
|
||||
virtual status_t Control(uint32 op, void *buffer, size_t length);
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user