⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 usb to rs232 converter source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file is a part of BeOS USB Serial driver project. * Copyright (c) 2003 by Siarzuk Zharski <imker@gmx.li> * * This file may be used under the terms of the BSD License * See the file "License" for details. *  * $Source: /cvsroot/sis4be/usb_serial/driver.c,v $ * $Author: zharik $ * $Revision: 1.8 $ * $Date: 2003/10/05 17:44:52 $ * */ #include <KernelExport.h>#include <Drivers.h>#include <USB.h>#include <ttylayer.h>#include <malloc.h>#include <string.h> /* strerror */#include <stdlib.h> /* strtol */#include <stdio.h>  /* sprintf */#include "driver.h"#include "acm.h"#include "prolific.h"#include "ftdi.h" /* driver callbacks forward declarations */static status_t usb_serial_open (const char *name, uint32 flags, void** cookie);static status_t usb_serial_read (void* cookie,                                 off_t position, void *buf, size_t* num_bytes);static status_t usb_serial_write (void* cookie, off_t position,                                  const void* buffer, size_t* num_bytes);static status_t usb_serial_control (void* cookie, uint32 op, void* arg, size_t len);static status_t usb_serial_close (void* cookie);static status_t usb_serial_free (void* cookie);/* USB notify callbacks forward declarations */status_t usb_serial_device_added(const usb_device *dev, void **cookie);status_t usb_serial_device_removed(void *cookie);/* The base name of drivers created in /dev/ports/ directory */#define BASENAME_LEN 0x09 /*must be synchronized with below !!!*/static const char *basename = "ports/usb%u";/* function pointers for the device hooks entry points */device_hooks usb_serial_hooks = {  usb_serial_open,            /* -> open entry point */  usb_serial_close,           /* -> close entry point */  usb_serial_free,            /* -> free cookie */  usb_serial_control,         /* -> control entry point */  usb_serial_read,            /* -> read entry point */  usb_serial_write            /* -> write entry point */};/* USB notify hooks */static usb_notify_hooks notify_hooks = {    &usb_serial_device_added,    &usb_serial_device_removed}; /* kernel modules */usb_module_info *usb_m; /* usb layer */tty_module_info *tty_m; /* tty layer */struct tty usb_serial_tty[DEVICES_COUNT]; struct ddomain usb_serial_dd;/* hardware devices, supported by this driver.   See description field for human readable names */usb_serial_hw usb_serial_hw_devices[] = {  {0, 0, add_acm_device, reset_acm_device,         set_line_coding_acm, set_control_line_state_acm,         on_read_acm, on_write_acm, on_close_acm,         "CDC ACM compatible device"},           {VND_PROLIFIC, PROD_PROLIFIC_RSAQ2,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,           on_read_acm, on_write_acm, on_close_acm,           "PL2303 Serial adapter (IODATA USB-RSAQ2)"},  {VND_IODATA,   PROD_IODATA_USBRSAQ,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "I/O Data USB serial adapter USB-RSAQ1"},  {VND_ATEN,     PROD_ATEN_UC232A,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "Aten Serial adapter"},  {VND_TDK,      PROD_TDK_UHA6400,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "TDK USB-PHS Adapter UHA6400"},  {VND_RATOC,    PROD_RATOC_REXUSB60,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "Ratoc USB serial adapter REX-USB60"},  {VND_PROLIFIC, PROD_PROLIFIC_PL2303,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "PL2303 Serial adapter (ATEN/IOGEAR UC232A)"},  {VND_ELECOM,   PROD_ELECOM_UCSGT,           add_prolific_device, reset_prolific_device,           set_line_coding_acm, set_control_line_state_acm,            on_read_acm, on_write_acm, on_close_acm,           "Elecom UC-SGT"},   {VND_FTDI,   PROD_8U100AX,           add_ftdi_device, reset_ftdi_device,           set_line_coding_ftdi, set_control_line_state_ftdi,            on_read_ftdi, on_write_ftdi, on_close_ftdi,           "FTDI 8U100AX serial converter"},   {VND_FTDI,   PROD_8U232AM,           add_ftdi_device, reset_ftdi_device,           set_line_coding_ftdi, set_control_line_state_ftdi,           on_read_ftdi, on_write_ftdi, on_close_ftdi,           "FTDI 8U232AM serial converter"}, };/* supported devices*/usb_support_descriptor supported_devices[] = {  {USB_DEV_CLASS_COMM, 0, 0, 0, 0},  {0, 0, 0, VND_PROLIFIC, PROD_PROLIFIC_RSAQ2 },  {0, 0, 0, VND_IODATA,   PROD_IODATA_USBRSAQ },  {0, 0, 0, VND_ATEN,     PROD_ATEN_UC232A },  {0, 0, 0, VND_TDK,      PROD_TDK_UHA6400 },  {0, 0, 0, VND_RATOC,    PROD_RATOC_REXUSB60 },  {0, 0, 0, VND_PROLIFIC, PROD_PROLIFIC_PL2303 },  {0, 0, 0, VND_ELECOM,   PROD_ELECOM_UCSGT },    {0, 0, 0, VND_FTDI, PROD_8U100AX },  {0, 0, 0, VND_FTDI, PROD_8U232AM },};/* main devices table locking semaphore */sem_id usb_serial_lock = -1;/* array of pointers to device objects */usb_serial_device *usb_serial_devices[DEVICES_COUNT];/* the names of "ports" */char * usb_serial_names[DEVICES_COUNT + 1];/* speed constants, supported by this driver. */const uint32 serial_tty_speed[] = {    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};/* init_hardware - called once the first time the driver is loaded */status_t init_hardware (void){  TRACE("init_hardware\n"); /*special case - no file-logging activated now*/  return B_OK;}/* init_driver - optional function - called every time the driver   is loaded. */status_t init_driver (void){  int i;  status_t status = B_OK;  load_setting();  create_log();  TRACE_FUNCALLS("init_driver\n");    if((status = get_module(B_TTY_MODULE_NAME, (module_info **)&tty_m)) == B_OK){    if((status = get_module(B_USB_MODULE_NAME, (module_info **)&usb_m)) == B_OK){      if(tty_m && usb_m){        for(i = 0; i < DEVICES_COUNT; i++)          usb_serial_devices[i] = 0;                  usb_serial_names[0] = NULL;          load_driver_symbols(DRIVER_NAME);        (*usb_m->register_driver)(DRIVER_NAME, supported_devices,                                        SIZEOF(supported_devices), DRIVER_NAME);        (*usb_m->install_notify)(DRIVER_NAME, &notify_hooks);          usb_serial_lock = create_sem(1, DRIVER_NAME"_devices_table_lock");      }else{        status = B_ERROR;        TRACE_ALWAYS("init_driver failed: tty_m:%08x usb_m:%08x", tty_m, usb_m);      }     }else      TRACE_ALWAYS("init_driver failed:%lx cannot get a module %s", status,                                                               B_USB_MODULE_NAME);  }else    TRACE_ALWAYS("init_driver failed:%lx cannot get a module %s", status,                                                               B_TTY_MODULE_NAME);    TRACE_FUNCRET("init_driver returns:%08x\n", status);  return status;}/* uninit_driver - optional function - called every time the driver   is unloaded */void uninit_driver (void){  int i;  TRACE_FUNCALLS("uninit_driver\n");  (*usb_m->uninstall_notify)(DRIVER_NAME);  acquire_sem(usb_serial_lock);    for(i = 0; i < DEVICES_COUNT; i++)    if(usb_serial_devices[i]){      delete_area(usb_serial_devices[i]->buffers_area);      delete_sem(usb_serial_devices[i]->done_read);      delete_sem(usb_serial_devices[i]->done_write);      free(usb_serial_devices[i]);      usb_serial_devices[i] = 0;    }    release_sem_etc(usb_serial_lock, 1, B_DO_NOT_RESCHEDULE);  delete_sem(usb_serial_lock);    for(i = 0; usb_serial_names[i]; i++)    free(usb_serial_names[i]);  put_module(B_USB_MODULE_NAME);  put_module(B_TTY_MODULE_NAME);}void usb_serial_device_notify_in(void *cookie,                                 uint32 status, void *data, uint32 actual_len){  TRACE_FUNCALLS("usb_serial_device_notify_in:cookie:%08x status:%08x data:%08x len:%d\n", cookie, status, data, actual_len);  if(cookie){    usb_serial_device *usd = ((usb_serial_device_info *)cookie)->device;    usd->actual_len_read = actual_len;    usd->dev_status_read = status;    release_sem(usd->done_read);  }} void usb_serial_device_notify_out(void *cookie, uint32 status,                                  void *data, uint32 actual_len){  TRACE_FUNCALLS("usb_serial_device_notify_out:cookie:%08x status:%08x "                 "data:%08x len:%d\n", cookie, status, data, actual_len);  if(cookie){    usb_serial_device *usd = ((usb_serial_device_info *)cookie)->device;    usd->actual_len_write = actual_len;    usd->dev_status_write = status;    release_sem(usd->done_write);  }} status_t usb_serial_device_thread(void *param){  status_t status = B_ERROR;  usb_serial_device_info *usdi = (usb_serial_device_info *)param;  usb_serial_device *usd = usdi->device;  TRACE_FUNCALLS("usb_serial_device_thread:%08x\n", param);  while(true){    size_t i, to_read;    char *buf;    struct ddrover *ddr;    usd->actual_len_read = 0;    usd->dev_status_read = 0;    status = (*usb_m->queue_bulk)(usd->pipe_read, usd->read_buffer,                        usd->read_buffer_size, usb_serial_device_notify_in, usdi);    if(status != B_OK){      TRACE_ALWAYS("usb_serial_device_thread : queue_bulk error : %lx\n", status);      break;    }    status = acquire_sem_etc(usd->done_read, 1, B_CAN_INTERRUPT, 0);    if(status != B_OK){      TRACE_ALWAYS("usb_serial_device_thread : acquire_sem_etc : "                     "error %08lx (%s)\n", status, strerror(status));      break;    }    if(usd->dev_status_read){      TRACE_ALWAYS("usb_serial_device_thread : dev_status error !!!\n");      break;    }        buf = usd->read_buffer;    to_read = usd->actual_len_read;    (*usd->hw->on_read)(usd, &buf, &to_read);    if(!to_read)      continue;    ddr = (*tty_m->ddrstart)(NULL);    if(!ddr){      TRACE_ALWAYS("usb_serial_device_thread : ddrstart problem !!!\n");      status = B_NO_MEMORY;      break;    }    (*tty_m->ttyilock)(usd->tty, ddr, true);    for(i = 0; i < to_read; i++){      (*tty_m->ttyin)(usd->tty, ddr, buf[i]);    }    (*tty_m->ttyilock)(usd->tty, ddr, false);    (*tty_m->ddrdone)(ddr);  }  TRACE_FUNCRET("usb_serial_device_thread returns %08x\n", status);  return status;}void usb_serial_setmodes(usb_serial_device *usd){  usb_serial_line_coding line_coding;  struct termios tios;  int newctrl, baud_index;  TRACE_FUNCALLS("usb_serial_setmodes:%08x\n", usd);  memcpy(&tios, &usd->tty->t, sizeof(struct termios));   newctrl = usd->ctrlout;  TRACE_FUNCRES(trace_termios, &tios);  TRACE("newctrl:%08x\n", newctrl);  baud_index = tios.c_cflag & CBAUD;  if(baud_index > SIZEOF(serial_tty_speed))    baud_index = SIZEOF(serial_tty_speed) - 1;      line_coding.speed = serial_tty_speed[baud_index];  line_coding.stopbits = ( tios.c_cflag & CSTOPB ) ? LC_STOP_BIT_2 : LC_STOP_BIT_1;  if(PARENB & tios.c_cflag){    line_coding.parity = LC_PARITY_EVEN;    if(PARODD & tios.c_cflag){      line_coding.parity = LC_PARITY_ODD;    }  }else    line_coding.parity = LC_PARITY_NONE;  line_coding.databits = (tios.c_cflag & CS8) ? 8 : 7;  if(line_coding.speed == 0){    newctrl &= 0xfffffffe;    line_coding.speed = usd->line_coding.speed;  }else    newctrl = CLS_LINE_DTR;  if(usd->ctrlout != newctrl ){    usd->ctrlout = newctrl;    TRACE("newctrl send to modem:%08x\n", newctrl);    (*usd->hw->set_control_line_state)(usd, newctrl);  }    if(memcmp (&line_coding, &usd->line_coding, sizeof(usb_serial_line_coding))){    usd->line_coding.speed = line_coding.speed;    usd->line_coding.stopbits = line_coding.stopbits;    usd->line_coding.databits = line_coding.databits;    usd->line_coding.parity = line_coding.parity;    TRACE("send to modem:speed %d sb:%08x db:%08x parity:%08x\n",                                usd->line_coding.speed, usd->line_coding.stopbits,                                usd->line_coding.databits, usd->line_coding.parity);    (*usd->hw->set_line_coding)(usd, &usd->line_coding);  }}bool usb_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags){  int i;  bool bret = false;  usb_serial_device *usd;  TRACE_FUNCALLS("usb_serial_service:%08x ddr:%08x flags:%08x\n", ptty, ddr, flags);    for(i = 0; i < DEVICES_COUNT; i++){    if(usb_serial_devices[i]){      if(ptty == usb_serial_devices[i]->tty){        usd = usb_serial_devices[i];        break;      }    }  }  if(usd){    if(flags <= TTYGETSIGNALS){       switch(flags){      case TTYENABLE:          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWDCD, false);          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWCTS, true);                    usd->ctrlout = CLS_LINE_DTR | CLS_LINE_RTS;          (*usd->hw->set_control_line_state)(usd, usd->ctrlout);          break;                case TTYDISABLE:                    (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWDCD, false);                    usd->ctrlout = 0x0;          (*usd->hw->set_control_line_state)(usd, usd->ctrlout);          break;                case TTYISTOP:          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWCTS, false);          break;                case TTYIRESUME:          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWCTS, true);          break;                case TTYGETSIGNALS:          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWDCD, true);          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWCTS, true);          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWDSR, false);          (*tty_m->ttyhwsignal)(ptty, ddr, TTYHWRI, false);          break;                case TTYSETMODES:          usb_serial_setmodes(usd);          break;      case TTYOSTART:      case TTYOSYNC:      case TTYSETBREAK:      case TTYCLRBREAK:      case TTYSETDTR:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -