From b994a185080e8f2706d5a153496070f7fe7b4d7e Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 8 Dec 2010 00:32:24 +0000 Subject: [PATCH] Port of usb_serial to the generic tty module. I don't remember exactly if or how well this was working, but since it was non-functional on Haiku anyway this shouldn't hurt. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39762 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../drivers/ports/usb_serial/Driver.cpp | 9 +- .../kernel/drivers/ports/usb_serial/Driver.h | 5 +- .../drivers/ports/usb_serial/SerialDevice.cpp | 241 ++++++++---------- .../drivers/ports/usb_serial/SerialDevice.h | 13 +- .../drivers/ports/usb_serial/Tracing.cpp | 83 +----- .../kernel/drivers/ports/usb_serial/Tracing.h | 4 - 6 files changed, 124 insertions(+), 231 deletions(-) diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/Driver.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/Driver.cpp index 662b73bb26..e4c9887b03 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/Driver.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/Driver.cpp @@ -21,7 +21,6 @@ SerialDevice *gSerialDevices[DEVICES_COUNT]; char *gDeviceNames[DEVICES_COUNT + 1]; usb_module_info *gUSBModule = NULL; tty_module_info *gTTYModule = NULL; -struct ddomain gSerialDomain; sem_id gDriverLock = -1; @@ -188,12 +187,14 @@ uninit_driver() bool -usb_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags) +usb_serial_service(struct tty *tty, uint32 op, void *buffer, size_t length) { - TRACE_FUNCALLS("> usb_serial_service(0x%08x, 0x%08x, 0x%08x)\n", ptty, ddr, flags); + TRACE_FUNCALLS("> usb_serial_service(%p, 0x%08lx, %p, %lu)\n", tty, + op, buffer, length); for (int32 i = 0; i < DEVICES_COUNT; i++) { - if (gSerialDevices[i] && gSerialDevices[i]->Service(ptty, ddr, flags)) { + if (gSerialDevices[i] + && gSerialDevices[i]->Service(tty, op, buffer, length)) { TRACE_FUNCRET("< usb_serial_service() returns: true\n"); return true; } diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/Driver.h b/src/add-ons/kernel/drivers/ports/usb_serial/Driver.h index 3abbd7d422..85e124f0de 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/Driver.h +++ b/src/add-ons/kernel/drivers/ports/usb_serial/Driver.h @@ -23,7 +23,7 @@ #include "USB3.h" extern "C" { -#include +#include } #define DRIVER_NAME "usb_serial" // driver name for debug output @@ -90,7 +90,8 @@ status_t usb_serial_device_removed(void *cookie); status_t init_hardware(); void uninit_driver(); -bool usb_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags); +bool usb_serial_service(struct tty *tty, uint32 op, void *buffer, + size_t length); status_t usb_serial_open(const char *name, uint32 flags, void **cookie); status_t usb_serial_read(void *cookie, off_t position, void *buffer, size_t *numBytes); 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 ccd520a465..8fa547db87 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp @@ -35,11 +35,14 @@ SerialDevice::SerialDevice(usb_device device, uint16 vendorID, fDoneWrite(-1), fControlOut(0), fInputStopped(false), + fMasterTTY(NULL), + fSlaveTTY(NULL), + fTTYCookie(NULL), fDeviceThread(-1), fStopDeviceThread(false) { - memset(&fTTYFile, 0, sizeof(ttyfile)); - memset(&fTTY, 0, sizeof(tty)); + mutex_init(&fReadLock, "usb_serial read lock"); + mutex_init(&fWriteLock, "usb_serial write lock"); } @@ -101,12 +104,10 @@ SerialDevice::SetWritePipe(usb_pipe handle) void -SerialDevice::SetModes() +SerialDevice::SetModes(struct termios *tios) { - struct termios tios; - memcpy(&tios, &fTTY.t, sizeof(struct termios)); uint16 newControl = fControlOut; - TRACE_FUNCRES(trace_termios, &tios); + TRACE_FUNCRES(trace_termios, tios); static uint32 baudRates[] = { 0x00000000, //B0 @@ -133,28 +134,26 @@ SerialDevice::SetModes() }; uint32 baudCount = sizeof(baudRates) / sizeof(baudRates[0]); - uint32 baudIndex = tios.c_cflag & CBAUD; + 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; usb_serial_line_coding lineCoding; lineCoding.speed = baudRates[baudIndex]; - lineCoding.stopbits = (tios.c_cflag & CSTOPB) ? LC_STOP_BIT_2 : LC_STOP_BIT_1; + lineCoding.stopbits = (tios->c_cflag & CSTOPB) ? LC_STOP_BIT_2 : LC_STOP_BIT_1; - if (tios.c_cflag & PARENB) { + if (tios->c_cflag & PARENB) { lineCoding.parity = LC_PARITY_EVEN; - if (tios.c_cflag & PARODD) + if (tios->c_cflag & PARODD) lineCoding.parity = LC_PARITY_ODD; } else lineCoding.parity = LC_PARITY_NONE; - lineCoding.databits = (tios.c_cflag & CS8) ? 8 : 7; - - if (lineCoding.speed == 0) { - newControl &= 0xfffffffe; - lineCoding.speed = fLineCoding.speed; - } else - newControl = CLS_LINE_DTR; + lineCoding.databits = (tios->c_cflag & CS8) ? 8 : 7; if (fControlOut != newControl) { fControlOut = newControl; @@ -176,64 +175,64 @@ SerialDevice::SetModes() bool -SerialDevice::Service(struct tty *ptty, struct ddrover *ddr, uint flags) +SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length) { - if (&fTTY != ptty) + if (tty != fMasterTTY) return false; - if (flags <= TTYGETSIGNALS) { - switch (flags) { - case TTYENABLE: - TRACE("TTYENABLE\n"); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, false); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, true); - fControlOut = CLS_LINE_DTR | CLS_LINE_RTS; - SetControlLineState(fControlOut); - break; + switch (op) { + case TTYENABLE: + { + bool enable = *(bool *)buffer; + TRACE("TTYENABLE: %sable\n", enable ? "en" : "dis"); - case TTYDISABLE: - TRACE("TTYDISABLE\n"); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, false); - fControlOut = 0x0; - SetControlLineState(fControlOut); - break; + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDCD, enable); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, enable); - case TTYISTOP: - TRACE("TTYISTOP\n"); - fInputStopped = true; - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, false); - break; - - case TTYIRESUME: - TRACE("TTYIRESUME\n"); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, true); - fInputStopped = false; - break; - - case TTYGETSIGNALS: - TRACE("TTYGETSIGNALS\n"); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, true); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, true); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDSR, false); - gTTYModule->ttyhwsignal(ptty, ddr, TTYHWRI, false); - break; - - case TTYSETMODES: - TRACE("TTYSETMODES\n"); - SetModes(); - break; - - case TTYOSTART: - case TTYOSYNC: - case TTYSETBREAK: - case TTYCLRBREAK: - case TTYSETDTR: - case TTYCLRDTR: - TRACE("TTY other\n"); - break; + fControlOut = enable ? CLS_LINE_DTR | CLS_LINE_RTS : 0; + SetControlLineState(fControlOut); + return true; } - return true; + case TTYISTOP: + fInputStopped = *(bool *)buffer; + TRACE("TTYISTOP: %sstopped\n", fInputStopped ? "" : "not "); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, !fInputStopped); + return true; + + case TTYGETSIGNALS: + TRACE("TTYGETSIGNALS\n"); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDCD, + (fControlOut & (CLS_LINE_DTR | CLS_LINE_RTS)) != 0); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWCTS, !fInputStopped); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWDSR, false); + gTTYModule->tty_hardware_signal(fTTYCookie, TTYHWRI, false); + return true; + + case TTYSETMODES: + TRACE("TTYSETMODES\n"); + SetModes((struct termios *)buffer); + return true; + + case TTYSETDTR: + case TTYSETRTS: + { + bool set = *(bool *)buffer; + uint8 bit = TTYSETDTR ? CLS_LINE_DTR : CLS_LINE_RTS; + if (set) + fControlOut |= bit; + else + fControlOut &= ~bit; + + SetControlLineState(fControlOut); + return true; + } + + case TTYOSTART: + case TTYOSYNC: + case TTYSETBREAK: + TRACE("TTY other\n"); + return true; } return false; @@ -249,24 +248,29 @@ SerialDevice::Open(uint32 flags) if (fDeviceRemoved) return B_DEV_NOT_READY; - gTTYModule->ttyinit(&fTTY, true); - fTTYFile.tty = &fTTY; - fTTYFile.flags = flags; - ResetDevice(); - - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) + fMasterTTY = gTTYModule->tty_create(usb_serial_service, true); + if (fMasterTTY == NULL) { + TRACE_ALWAYS("open: failed to init master tty\n"); return B_NO_MEMORY; - - gTTYModule->ddacquire(ddr, &gSerialDomain); - status_t status = gTTYModule->ttyopen(&fTTYFile, ddr, usb_serial_service); - gTTYModule->ddrdone(ddr); - - if (status < B_OK) { - TRACE_ALWAYS("open: failed to open tty\n"); - return status; } + fSlaveTTY = gTTYModule->tty_create(NULL, 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"); + gTTYModule->tty_destroy(fMasterTTY); + gTTYModule->tty_destroy(fSlaveTTY); + return B_NO_MEMORY; + } + + ResetDevice(); + fDeviceThread = spawn_kernel_thread(DeviceThread, "usb_serial device thread", B_NORMAL_PRIORITY, this); @@ -280,8 +284,9 @@ SerialDevice::Open(uint32 flags) fControlOut = CLS_LINE_DTR | CLS_LINE_RTS; SetControlLineState(fControlOut); - status = gUSBModule->queue_interrupt(fControlPipe, fInterruptBuffer, - fInterruptBufferSize, InterruptCallbackFunction, this); + status_t status = gUSBModule->queue_interrupt(fControlPipe, + fInterruptBuffer, fInterruptBufferSize, InterruptCallbackFunction, + this); if (status < B_OK) TRACE_ALWAYS("failed to queue initial interrupt\n"); @@ -305,15 +310,7 @@ SerialDevice::Read(char *buffer, size_t *numBytes) return status; } - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) { - *numBytes = 0; - mutex_unlock(&fReadLock); - return B_NO_MEMORY; - } - - status = gTTYModule->ttyread(&fTTYFile, ddr, buffer, numBytes); - gTTYModule->ddrdone(ddr); + status = gTTYModule->tty_read(fTTYCookie, buffer, numBytes); mutex_unlock(&fReadLock); return status; @@ -383,13 +380,7 @@ SerialDevice::Control(uint32 op, void *arg, size_t length) if (fDeviceRemoved) return B_DEV_NOT_READY; - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) - return B_NO_MEMORY; - - status_t status = gTTYModule->ttycontrol(&fTTYFile, ddr, op, arg, length); - gTTYModule->ddrdone(ddr); - return status; + return gTTYModule->tty_control(fTTYCookie, op, arg, length); } @@ -399,13 +390,7 @@ SerialDevice::Select(uint8 event, uint32 ref, selectsync *sync) if (fDeviceRemoved) return B_DEV_NOT_READY; - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) - return B_NO_MEMORY; - - status_t status = gTTYModule->ttyselect(&fTTYFile, ddr, event, ref, sync); - gTTYModule->ddrdone(ddr); - return status; + return gTTYModule->tty_select(fTTYCookie, event, ref, sync); } @@ -415,13 +400,7 @@ SerialDevice::DeSelect(uint8 event, selectsync *sync) if (fDeviceRemoved) return B_DEV_NOT_READY; - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) - return B_NO_MEMORY; - - status_t status = gTTYModule->ttydeselect(&fTTYFile, ddr, event, sync); - gTTYModule->ddrdone(ddr); - return status; + return gTTYModule->tty_deselect(fTTYCookie, event, sync); } @@ -436,28 +415,19 @@ SerialDevice::Close() gUSBModule->cancel_queued_transfers(fControlPipe); } - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) - return B_NO_MEMORY; - - status_t status = gTTYModule->ttyclose(&fTTYFile, ddr); - gTTYModule->ddrdone(ddr); + gTTYModule->tty_destroy_cookie(fTTYCookie); fDeviceOpen = false; - return status; + return B_OK; } status_t SerialDevice::Free() { - struct ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) - return B_NO_MEMORY; - - status_t status = gTTYModule->ttyfree(&fTTYFile, ddr); - gTTYModule->ddrdone(ddr); - return status; + gTTYModule->tty_destroy(fMasterTTY); + gTTYModule->tty_destroy(fSlaveTTY); + return B_OK; } @@ -575,21 +545,10 @@ SerialDevice::DeviceThread(void *data) if (readLength == 0) continue; - ddrover *ddr = gTTYModule->ddrstart(NULL); - if (!ddr) { - TRACE_ALWAYS("device thread: ddrstart problem\n"); - return B_NO_MEMORY; - } - while (device->fInputStopped) snooze(100); - gTTYModule->ttyilock(&device->fTTY, ddr, true); - for (size_t i = 0; i < readLength; i++) - gTTYModule->ttyin(&device->fTTY, ddr, buffer[i]); - - gTTYModule->ttyilock(&device->fTTY, ddr, false); - gTTYModule->ddrdone(ddr); + gTTYModule->tty_write(device->fTTYCookie, buffer, &readLength); } return B_OK; 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 6e43c779bd..37e539508d 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.h @@ -42,9 +42,9 @@ static SerialDevice * MakeDevice(usb_device device, uint16 vendorID, char * WriteBuffer() { return fWriteBuffer; }; size_t WriteBufferSize() { return fWriteBufferSize; }; - void SetModes(); - bool Service(struct tty *ptty, struct ddrover *ddr, - uint flags); + void SetModes(struct termios *tios); + bool Service(struct tty *tty, uint32 op, + void *buffer, size_t length); status_t Open(uint32 flags); status_t Read(char *buffer, size_t *numBytes); @@ -68,7 +68,7 @@ virtual status_t SetLineCoding(usb_serial_line_coding *coding); virtual status_t SetControlLineState(uint16 state); virtual void OnRead(char **buffer, size_t *numBytes); -virtual void OnWrite(const char *buffer, size_t *numBytes, +virtual void OnWrite(const char *buffer, size_t *numBytes, size_t *packetBytes); virtual void OnClose(); @@ -127,8 +127,9 @@ static void InterruptCallbackFunction(void *cookie, uint16 fControlOut; bool fInputStopped; - struct ttyfile fTTYFile; - struct tty fTTY; + struct tty * fMasterTTY; + struct tty * fSlaveTTY; + struct tty_cookie * fTTYCookie; /* device thread management */ thread_id fDeviceThread; diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp index 993efb72e7..78a406e908 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp @@ -18,14 +18,14 @@ #if DEBUG bool gLogEnabled = true; #else -bool gLogEnabled = false; +bool gLogEnabled = true; #endif bool gLogToFile = false; bool gLogAppend = false; -bool gLogFunctionCalls = false; -bool gLogFunctionReturns = false; -bool gLogFunctionResults = false; +bool gLogFunctionCalls = true; +bool gLogFunctionReturns = true; +bool gLogFunctionResults = true; static const char *sLogFilePath="/boot/home/"DRIVER_NAME".log"; static sem_id sLogLock; @@ -99,15 +99,6 @@ usb_serial_trace(bool force, char *format, ...) } -void -trace_ddomain(struct ddomain *dd) -{ - TRACE("struct ddomain:\n" - "\tddrover: 0x%08x\n" - "\tbg: %d, locked: %d\n", dd->r, dd->bg, dd->locked); -} - - void trace_termios(struct termios *tios) { @@ -120,66 +111,10 @@ trace_termios(struct termios *tios) // "\tc_ixxxxx: 0x%08x\n" // "\tc_oxxxxx: 0x%08x\n" "\tc_cc[0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x]\n", - tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag, - tios->c_line, -// tios->c_ixxxxx, tios->c_oxxxxx, - tios->c_cc[0], tios->c_cc[1], tios->c_cc[2], tios->c_cc[3], - tios->c_cc[4], tios->c_cc[5], tios->c_cc[6], tios->c_cc[7], + tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag, + tios->c_line, +// tios->c_ixxxxx, tios->c_oxxxxx, + tios->c_cc[0], tios->c_cc[1], tios->c_cc[2], tios->c_cc[3], + tios->c_cc[4], tios->c_cc[5], tios->c_cc[6], tios->c_cc[7], tios->c_cc[8], tios->c_cc[9], tios->c_cc[10]); } - - -void -trace_str(struct str *str) -{ - TRACE("struct str:\n" - "\tbuffer: 0x%08x\n" - "\tbufsize: %d\n" - "\tcount: %d\n" - "\ttail: %d\n" - "\tallocated: %d\n", - str->buffer, str->bufsize, str->count, str->tail, str->allocated); -} - - -void -trace_winsize(struct winsize *ws) -{ - TRACE("struct winsize:\n" - "\tws_row: %d\n" - "\tws_col: %d\n" - "\tws_xpixel: %d\n" - "\tws_ypixel: %d\n", - ws->ws_row, ws->ws_col, ws->ws_xpixel, ws->ws_ypixel); -} - - -void -trace_tty(struct tty *tty) -{ - TRACE("struct tty:\n" - "\tnopen: %d, flags: 0x%08x,\n", tty->nopen, tty->flags); - - TRACE("ddomain dd:\n"); - trace_ddomain(&tty->dd); - TRACE("ddomain ddi:\n"); - trace_ddomain(&tty->ddi); - - TRACE("\tpgid: %08x\n", tty->pgid); - TRACE("termios t:"); - trace_termios(&tty->t); - - TRACE("\tiactivity: %d, ibusy: %d\n", tty->iactivity, tty->ibusy); - - TRACE("str istr:\n"); - trace_str(&tty->istr); - TRACE("str rstr:\n"); - trace_str(&tty->rstr); - TRACE("str ostr:\n"); - trace_str(&tty->ostr); - - TRACE("winsize wsize:\n"); - trace_winsize(&tty->wsize); - - TRACE("\tservice: 0x%08x\n", tty->service); -} diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.h b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.h index 65af5c5525..6b90a7e8e2 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.h +++ b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.h @@ -30,10 +30,6 @@ extern bool gLogFunctionResults; if (gLogFunctionResults) \ func(param); -void trace_ddomain(struct ddomain *dd); void trace_termios(struct termios *tios); -void trace_str(struct str *str); -void trace_winsize(struct winsize *ws); -void trace_tty(struct tty *tty); #endif //_USB_SERIAL_TRACING_H_