From 36986acbbd67c4866976aeb4a6a3e98d953b69c3 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Fri, 10 Jun 2011 17:35:46 +0000 Subject: [PATCH] * Finish the port to the new tty module. Back when I left off last time it was only halfway finished. The way it is supposed to work is that there are two tty cookies, representing the system and the device side. Reads and writes coming from the system and going to the device are using the system cookie while reads and writes coming from the device use the device cookie. * Move writing to the device into an output thread, similar to how reading from the device works. This isn't necessarily a good idea and might be moved back into the write hook again to ensure that writes can be made blocking. Right now if you just write and then close, the writes will most likely be canceled before every going out to the device. * Removed the read and write lock mutex. They aren't necessary as the tty layer will serialize the reads and writes anyway. * Made simply copying the data to the write buffer the default implementation of the OnWrite callback and removed the OnWrite in ACMDevice. The ProlificDevice didn't provide an OnWrite hook before, so it would've never written anything. * Break out the baud index to speed mapping into an inline function. Since the defines might change in termios.h just adding an array is a bit fragile (it already missed one entry and would've been broken for certain speeds). This should make usb_serial usable for some (most?) cases. I've tested this with an Arduino board that uses an FTDI interface. As mentioned above, since writes currently just write into the tty layer and don't wait for the data to be flushed, and since close doesn't wait for the output buffers to be drained either, a simple write and close (as in "echo a > /dev/ports/usb0") will in most cases cancel the output before it is written to the device. I'm looking into a few ways to fix that next. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42089 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/ports/usb_serial/ACM.cpp | 7 - .../kernel/drivers/ports/usb_serial/ACM.h | 3 - .../drivers/ports/usb_serial/SerialDevice.cpp | 349 ++++++++++-------- .../drivers/ports/usb_serial/SerialDevice.h | 28 +- 4 files changed, 215 insertions(+), 172 deletions(-) diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/ACM.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/ACM.cpp index e5ee99c5b5..0114e52c20 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/ACM.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/ACM.cpp @@ -134,10 +134,3 @@ ACMDevice::SetControlLineState(uint16 state) TRACE_FUNCRET("< ACMDevice::SetControlLineState() returns: 0x%08x\n", status); return status; } - - -void -ACMDevice::OnWrite(const char *buffer, size_t *numBytes, size_t *packetBytes) -{ - memcpy(WriteBuffer(), buffer, *numBytes); -} diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/ACM.h b/src/add-ons/kernel/drivers/ports/usb_serial/ACM.h index 025ce5ad88..459b945392 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/ACM.h +++ b/src/add-ons/kernel/drivers/ports/usb_serial/ACM.h @@ -19,9 +19,6 @@ virtual status_t AddDevice(const usb_configuration_info *config); virtual status_t SetLineCoding(usb_cdc_line_coding *coding); virtual status_t SetControlLineState(uint16 state); - -virtual void OnWrite(const char *buffer, size_t *numBytes, - size_t *packetBytes); }; #endif //_USB_ACM_H_ diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp index 98f9caf54d..5c12841c78 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp @@ -29,6 +29,8 @@ SerialDevice::SerialDevice(usb_device device, uint16 vendorID, fBufferArea(-1), fReadBuffer(NULL), fReadBufferSize(ROUNDUP(DEF_BUFFER_SIZE, 16)), + fOutputBuffer(NULL), + fOutputBufferSize(ROUNDUP(DEF_BUFFER_SIZE, 16)), fWriteBuffer(NULL), fWriteBufferSize(ROUNDUP(DEF_BUFFER_SIZE, 16)), fInterruptBuffer(NULL), @@ -39,12 +41,12 @@ SerialDevice::SerialDevice(usb_device device, uint16 vendorID, fInputStopped(false), fMasterTTY(NULL), fSlaveTTY(NULL), - fTTYCookie(NULL), - fDeviceThread(-1), - fStopDeviceThread(false) + fSystemTTYCookie(NULL), + fDeviceTTYCookie(NULL), + fInputThread(-1), + fOutputThread(-1), + fStopThreads(false) { - mutex_init(&fReadLock, "usb_serial read lock"); - mutex_init(&fWriteLock, "usb_serial write lock"); } @@ -59,9 +61,6 @@ SerialDevice::~SerialDevice() if (fBufferArea >= B_OK) delete_area(fBufferArea); - - mutex_destroy(&fReadLock); - mutex_destroy(&fWriteLock); } @@ -70,16 +69,15 @@ SerialDevice::Init() { fDoneRead = create_sem(0, "usb_serial:done_read"); fDoneWrite = create_sem(0, "usb_serial:done_write"); - mutex_init(&fReadLock, "usb_serial:read_lock"); - mutex_init(&fWriteLock, "usb_serial:write_lock"); - size_t totalBuffers = fReadBufferSize + fWriteBufferSize + size_t totalBuffers = fReadBufferSize + fOutputBufferSize + fWriteBufferSize + fInterruptBufferSize; fBufferArea = create_area("usb_serial:buffers_area", (void **)&fReadBuffer, B_ANY_KERNEL_ADDRESS, ROUNDUP(totalBuffers, B_PAGE_SIZE), B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); - fWriteBuffer = fReadBuffer + fReadBufferSize; + fOutputBuffer = fReadBuffer + fReadBufferSize; + fWriteBuffer = fOutputBuffer + fOutputBufferSize; fInterruptBuffer = fWriteBuffer + fWriteBufferSize; return B_OK; } @@ -106,47 +104,53 @@ SerialDevice::SetWritePipe(usb_pipe handle) } +inline int32 +baud_index_to_speed(int index) +{ + switch (index) { + case B0: return 0; + case B50: return 50; + case B75: return 75; + case B110: return 110; + case B134: return 134; + case B150: return 150; + case B200: return 200; + case B300: return 300; + case B600: return 600; + case B1200: return 1200; + case B1800: return 1800; + case B2400: return 2400; + case B4800: return 4800; + case B9600: return 9600; + case B19200: return 19200; + case B31250: return 31250; + case B38400: return 38400; + case B57600: return 57600; + case B115200: return 115200; + case B230400: return 230400; + } + + TRACE_ALWAYS("invalid baud index %d\n", index); + return -1; +} + + void SerialDevice::SetModes(struct termios *tios) { uint16 newControl = fControlOut; TRACE_FUNCRES(trace_termios, tios); - static uint32 baudRates[] = { - 0x00000000, //B0 - 0x00000032, //B50 - 0x0000004B, //B75 - 0x0000006E, //B110 - 0x00000086, //B134 - 0x00000096, //B150 - 0x000000C8, //B200 - 0x0000012C, //B300 - 0x00000258, //B600 - 0x000004B0, //B1200 - 0x00000708, //B1800 - 0x00000960, //B2400 - 0x000012C0, //B4800 - 0x00002580, //B9600 - 0x00004B00, //B19200 - 0x00009600, //B38400 - 0x0000E100, //B57600 - 0x0001C200, //B115200 - 0x00038400, //B230400 - 0x00070800, //460800 - 0x000E1000, //921600 - }; - - uint32 baudCount = sizeof(baudRates) / sizeof(baudRates[0]); - uint32 baudIndex = tios->c_cflag & CBAUD; - if (baudIndex == 0) - baudIndex = tios->c_ispeed; - if (baudIndex == 0) - baudIndex = tios->c_ospeed; - if (baudIndex > baudCount) - baudIndex = baudCount - 1; + int32 speed = baud_index_to_speed(tios->c_cflag & CBAUD); + if (speed < 0) + speed = baud_index_to_speed(tios->c_ispeed); + if (speed < 0) + speed = baud_index_to_speed(tios->c_ospeed); + if (speed < 0) + speed = 19200; usb_cdc_line_coding lineCoding; - lineCoding.speed = baudRates[baudIndex]; + lineCoding.speed = speed; lineCoding.stopbits = (tios->c_cflag & CSTOPB) ? USB_CDC_LINE_CODING_2_STOPBITS : USB_CDC_LINE_CODING_1_STOPBIT; @@ -190,8 +194,8 @@ SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length) bool enable = *(bool *)buffer; TRACE("TTYENABLE: %sable\n", enable ? "en" : "dis"); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDCD, enable); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, enable); + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWDCD, enable); + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWCTS, enable); fControlOut = enable ? USB_CDC_CONTROL_SIGNAL_STATE_DTR | USB_CDC_CONTROL_SIGNAL_STATE_RTS : 0; @@ -202,19 +206,19 @@ SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length) case TTYISTOP: fInputStopped = *(bool *)buffer; TRACE("TTYISTOP: %sstopped\n", fInputStopped ? "" : "not "); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWCTS, !fInputStopped); return true; case TTYGETSIGNALS: TRACE("TTYGETSIGNALS\n"); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDCD, + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWDCD, (fControlOut & (USB_CDC_CONTROL_SIGNAL_STATE_DTR | USB_CDC_CONTROL_SIGNAL_STATE_RTS)) != 0); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWCTS, !fInputStopped); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDSR, false); - gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWRI, false); + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWDSR, false); + gTTYModule->tty_hardware_signal(fSystemTTYCookie, TTYHWRI, false); return true; case TTYSETMODES: @@ -263,16 +267,27 @@ SerialDevice::Open(uint32 flags) return B_NO_MEMORY; } - fSlaveTTY = gTTYModule->tty_create(NULL, false); + fSlaveTTY = gTTYModule->tty_create(usb_serial_service, false); if (fSlaveTTY == NULL) { TRACE_ALWAYS("open: failed to init slave tty\n"); gTTYModule->tty_destroy(fMasterTTY); return B_NO_MEMORY; } - fTTYCookie = gTTYModule->tty_create_cookie(fMasterTTY, fSlaveTTY, flags); - if (fTTYCookie == NULL) { - TRACE_ALWAYS("open: failed to init tty cookie\n"); + fSystemTTYCookie = gTTYModule->tty_create_cookie(fMasterTTY, fSlaveTTY, + flags); + if (fSystemTTYCookie == NULL) { + TRACE_ALWAYS("open: failed to init system tty cookie\n"); + gTTYModule->tty_destroy(fMasterTTY); + gTTYModule->tty_destroy(fSlaveTTY); + return B_NO_MEMORY; + } + + fDeviceTTYCookie = gTTYModule->tty_create_cookie(fSlaveTTY, fMasterTTY, + flags); + if (fDeviceTTYCookie == NULL) { + TRACE_ALWAYS("open: failed to init device tty cookie\n"); + gTTYModule->tty_destroy_cookie(fSystemTTYCookie); gTTYModule->tty_destroy(fMasterTTY); gTTYModule->tty_destroy(fSlaveTTY); return B_NO_MEMORY; @@ -280,22 +295,32 @@ SerialDevice::Open(uint32 flags) ResetDevice(); - fDeviceThread = spawn_kernel_thread(DeviceThread, - "usb_serial device thread", B_NORMAL_PRIORITY, this); + fStopThreads = false; - if (fDeviceThread < B_OK) { - TRACE_ALWAYS("open: failed to spawn kernel thread\n"); - return fDeviceThread; + fInputThread = spawn_kernel_thread(_InputThread, + "usb_serial input thread", B_NORMAL_PRIORITY, this); + if (fInputThread < 0) { + TRACE_ALWAYS("open: failed to spawn input thread\n"); + return fInputThread; } - resume_thread(fDeviceThread); + resume_thread(fInputThread); + + fOutputThread = spawn_kernel_thread(_OutputThread, + "usb_serial output thread", B_NORMAL_PRIORITY, this); + if (fOutputThread < 0) { + TRACE_ALWAYS("open: failed to spawn output thread\n"); + return fOutputThread; + } + + resume_thread(fOutputThread); fControlOut = USB_CDC_CONTROL_SIGNAL_STATE_DTR | USB_CDC_CONTROL_SIGNAL_STATE_RTS; SetControlLineState(fControlOut); status_t status = gUSBModule->queue_interrupt(fControlPipe, - fInterruptBuffer, fInterruptBufferSize, InterruptCallbackFunction, + fInterruptBuffer, fInterruptBufferSize, _InterruptCallbackFunction, this); if (status < B_OK) TRACE_ALWAYS("failed to queue initial interrupt\n"); @@ -313,75 +338,19 @@ SerialDevice::Read(char *buffer, size_t *numBytes) return B_DEV_NOT_READY; } - status_t status = mutex_lock(&fReadLock); - if (status != B_OK) { - TRACE_ALWAYS("read: failed to get read lock\n"); - *numBytes = 0; - return status; - } - - status = gTTYModule->tty_read(fTTYCookie, buffer, numBytes); - - mutex_unlock(&fReadLock); - return status; + return gTTYModule->tty_read(fSystemTTYCookie, buffer, numBytes); } status_t SerialDevice::Write(const char *buffer, size_t *numBytes) { - size_t bytesLeft = *numBytes; - *numBytes = 0; - - status_t status = mutex_lock(&fWriteLock); - if (status != B_OK) { - TRACE_ALWAYS("write: failed to get write lock\n"); - return status; - } - if (fDeviceRemoved) { - mutex_unlock(&fWriteLock); + *numBytes = 0; return B_DEV_NOT_READY; } - while (bytesLeft > 0) { - size_t length = MIN(bytesLeft, fWriteBufferSize); - size_t packetLength = length; - OnWrite(buffer, &length, &packetLength); - - status = gUSBModule->queue_bulk(fWritePipe, fWriteBuffer, - packetLength, WriteCallbackFunction, this); - if (status < B_OK) { - TRACE_ALWAYS("write: queueing failed with status 0x%08x\n", status); - break; - } - - status = acquire_sem_etc(fDoneWrite, 1, B_CAN_INTERRUPT, 0); - if (status < B_OK) { - TRACE_ALWAYS("write: failed to get write done sem 0x%08x\n", - status); - break; - } - - if (fStatusWrite != B_OK) { - TRACE("write: device status error 0x%08x\n", fStatusWrite); - status = gUSBModule->clear_feature(fWritePipe, - USB_FEATURE_ENDPOINT_HALT); - if (status < B_OK) { - TRACE_ALWAYS("write: failed to clear device halt\n"); - status = B_ERROR; - break; - } - continue; - } - - buffer += length; - *numBytes += length; - bytesLeft -= length; - } - - mutex_unlock(&fWriteLock); - return status; + return gTTYModule->tty_write(fSystemTTYCookie, buffer, numBytes); } @@ -391,7 +360,9 @@ SerialDevice::Control(uint32 op, void *arg, size_t length) if (fDeviceRemoved) return B_DEV_NOT_READY; - return gTTYModule->tty_control(fTTYCookie, op, arg, length); + gTTYModule->tty_control(fSystemTTYCookie, op, arg, length); + gTTYModule->tty_control(fDeviceTTYCookie, op, arg, length); + return B_OK; } @@ -401,7 +372,7 @@ SerialDevice::Select(uint8 event, uint32 ref, selectsync *sync) if (fDeviceRemoved) return B_DEV_NOT_READY; - return gTTYModule->tty_select(fTTYCookie, event, ref, sync); + return gTTYModule->tty_select(fSystemTTYCookie, event, ref, sync); } @@ -411,7 +382,7 @@ SerialDevice::DeSelect(uint8 event, selectsync *sync) if (fDeviceRemoved) return B_DEV_NOT_READY; - return gTTYModule->tty_deselect(fTTYCookie, event, sync); + return gTTYModule->tty_deselect(fSystemTTYCookie, event, sync); } @@ -420,13 +391,29 @@ SerialDevice::Close() { OnClose(); + // TODO: wait for the output buffer to be flushed? + + fStopThreads = true; + fInputStopped = false; + if (!fDeviceRemoved) { gUSBModule->cancel_queued_transfers(fReadPipe); gUSBModule->cancel_queued_transfers(fWritePipe); gUSBModule->cancel_queued_transfers(fControlPipe); } - gTTYModule->tty_destroy_cookie(fTTYCookie); + int32 result = B_OK; + wait_for_thread(fInputThread, &result); + fInputThread = -1; + + wait_for_thread(fOutputThread, &result); + fOutputThread = -1; + + gTTYModule->tty_destroy_cookie(fSystemTTYCookie); + gTTYModule->tty_destroy_cookie(fDeviceTTYCookie); + + gTTYModule->tty_destroy(fMasterTTY); + gTTYModule->tty_destroy(fSlaveTTY); fDeviceOpen = false; return B_OK; @@ -436,8 +423,6 @@ SerialDevice::Close() status_t SerialDevice::Free() { - gTTYModule->tty_destroy(fMasterTTY); - gTTYModule->tty_destroy(fSlaveTTY); return B_OK; } @@ -452,18 +437,18 @@ SerialDevice::Removed() fDeviceRemoved = true; // we need to ensure that we do not use the device anymore - fStopDeviceThread = true; + fStopThreads = true; fInputStopped = false; gUSBModule->cancel_queued_transfers(fReadPipe); gUSBModule->cancel_queued_transfers(fWritePipe); gUSBModule->cancel_queued_transfers(fControlPipe); int32 result = B_OK; - wait_for_thread(fDeviceThread, &result); - fDeviceThread = -1; + wait_for_thread(fInputThread, &result); + fInputThread = -1; - mutex_lock(&fWriteLock); - mutex_unlock(&fWriteLock); + wait_for_thread(fOutputThread, &result); + fOutputThread = -1; } @@ -509,7 +494,7 @@ SerialDevice::OnRead(char **buffer, size_t *numBytes) void SerialDevice::OnWrite(const char *buffer, size_t *numBytes, size_t *packetBytes) { - // default implementation - does nothing + memcpy(fWriteBuffer, buffer, *numBytes); } @@ -521,35 +506,37 @@ SerialDevice::OnClose() int32 -SerialDevice::DeviceThread(void *data) +SerialDevice::_InputThread(void *data) { SerialDevice *device = (SerialDevice *)data; - while (!device->fStopDeviceThread) { + while (!device->fStopThreads) { status_t status = gUSBModule->queue_bulk(device->fReadPipe, device->fReadBuffer, device->fReadBufferSize, - device->ReadCallbackFunction, data); + device->_ReadCallbackFunction, data); if (status < B_OK) { - TRACE_ALWAYS("device thread: queueing failed with error: 0x%08x\n", + TRACE_ALWAYS("input thread: queueing failed with error: 0x%08x\n", status); - break; + return status; } status = acquire_sem_etc(device->fDoneRead, 1, B_CAN_INTERRUPT, 0); if (status < B_OK) { - TRACE_ALWAYS("device thread: failed to get read done sem 0x%08x\n", + TRACE_ALWAYS("input thread: failed to get read done sem 0x%08x\n", status); - break; + return status; } if (device->fStatusRead != B_OK) { - TRACE("device thread: device status error 0x%08x\n", + TRACE("input thread: device status error 0x%08x\n", device->fStatusRead); if (gUSBModule->clear_feature(device->fReadPipe, USB_FEATURE_ENDPOINT_HALT) != B_OK) { - TRACE_ALWAYS("device thread: failed to clear halt feature\n"); - break; + TRACE_ALWAYS("input thread: failed to clear halt feature\n"); + return B_ERROR; } + + continue; } char *buffer = device->fReadBuffer; @@ -561,7 +548,71 @@ SerialDevice::DeviceThread(void *data) while (device->fInputStopped) snooze(100); - gTTYModule->tty_write(device->fTTYCookie, buffer, &readLength); + status = gTTYModule->tty_write(device->fDeviceTTYCookie, buffer, + &readLength); + if (status != B_OK) { + TRACE_ALWAYS("input thread: failed to write into TTY\n"); + return status; + } + } + + return B_OK; +} + + +int32 +SerialDevice::_OutputThread(void *data) +{ + SerialDevice *device = (SerialDevice *)data; + + while (!device->fStopThreads) { + char *buffer = device->fOutputBuffer; + size_t bytesLeft = device->fOutputBufferSize; + status_t status = gTTYModule->tty_read(device->fDeviceTTYCookie, buffer, + &bytesLeft); + if (status != B_OK) { + TRACE_ALWAYS("output thread: failed to read from TTY\n"); + return status; + } + + while (bytesLeft > 0) { + size_t length = MIN(bytesLeft, device->fWriteBufferSize); + size_t packetLength = length; + device->OnWrite(buffer, &length, &packetLength); + + status = gUSBModule->queue_bulk(device->fWritePipe, + device->fWriteBuffer, packetLength, _WriteCallbackFunction, + device); + if (status < B_OK) { + TRACE_ALWAYS("output thread: queueing failed with status " + "0x%08x\n", status); + return status; + } + + status = acquire_sem_etc(device->fDoneWrite, 1, B_CAN_INTERRUPT, 0); + if (status != B_OK) { + TRACE_ALWAYS("output thread: failed to get write done sem " + "0x%08x\n", status); + return status; + } + + if (device->fStatusWrite != B_OK) { + TRACE("output thread: device status error 0x%08x\n", + device->fStatusWrite); + status = gUSBModule->clear_feature(device->fWritePipe, + USB_FEATURE_ENDPOINT_HALT); + if (status < B_OK) { + TRACE_ALWAYS("output thread: failed to clear device " + "halt\n"); + return B_ERROR; + } + + continue; + } + + buffer += length; + bytesLeft -= length; + } } return B_OK; @@ -569,7 +620,7 @@ SerialDevice::DeviceThread(void *data) void -SerialDevice::ReadCallbackFunction(void *cookie, int32 status, void *data, +SerialDevice::_ReadCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength) { TRACE_FUNCALLS("read callback: cookie: 0x%08x status: 0x%08x data: 0x%08x " @@ -583,7 +634,7 @@ SerialDevice::ReadCallbackFunction(void *cookie, int32 status, void *data, void -SerialDevice::WriteCallbackFunction(void *cookie, int32 status, void *data, +SerialDevice::_WriteCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength) { TRACE_FUNCALLS("write callback: cookie: 0x%08x status: 0x%08x data: 0x%08x " @@ -597,7 +648,7 @@ SerialDevice::WriteCallbackFunction(void *cookie, int32 status, void *data, void -SerialDevice::InterruptCallbackFunction(void *cookie, int32 status, +SerialDevice::_InterruptCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength) { TRACE_FUNCALLS("interrupt callback: cookie: 0x%08x status: 0x%08x data: " @@ -612,7 +663,7 @@ SerialDevice::InterruptCallbackFunction(void *cookie, int32 status, if (status == B_OK && !device->fDeviceRemoved) { status = gUSBModule->queue_interrupt(device->fControlPipe, device->fInterruptBuffer, device->fInterruptBufferSize, - device->InterruptCallbackFunction, device); + device->_InterruptCallbackFunction, device); } } diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h index a7b5b72c49..c88e01c6d9 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h @@ -76,16 +76,18 @@ protected: void SetReadBufferSize(size_t size) { fReadBufferSize = size; }; void SetWriteBufferSize(size_t size) { fWriteBufferSize = size; }; void SetInterruptBufferSize(size_t size) { fInterruptBufferSize = size; }; -private: -static int32 DeviceThread(void *data); -static void ReadCallbackFunction(void *cookie, +private: +static int32 _InputThread(void *data); +static int32 _OutputThread(void *data); + +static void _ReadCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength); -static void WriteCallbackFunction(void *cookie, +static void _WriteCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength); -static void InterruptCallbackFunction(void *cookie, +static void _InterruptCallbackFunction(void *cookie, int32 status, void *data, uint32 actualLength); @@ -108,6 +110,8 @@ static void InterruptCallbackFunction(void *cookie, area_id fBufferArea; char * fReadBuffer; size_t fReadBufferSize; + char * fOutputBuffer; + size_t fOutputBufferSize; char * fWriteBuffer; size_t fWriteBufferSize; char * fInterruptBuffer; @@ -129,15 +133,13 @@ static void InterruptCallbackFunction(void *cookie, bool fInputStopped; struct tty * fMasterTTY; struct tty * fSlaveTTY; - struct tty_cookie * fTTYCookie; + struct tty_cookie * fSystemTTYCookie; + struct tty_cookie * fDeviceTTYCookie; - /* device thread management */ - thread_id fDeviceThread; - bool fStopDeviceThread; - - /* device locks to ensure no concurent reads/writes */ - mutex fReadLock; - mutex fWriteLock; + /* input/output thread management */ + thread_id fInputThread; + thread_id fOutputThread; + bool fStopThreads; }; #endif // _USB_DEVICE_H_