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

📄 pl2303.c

📁 linux下利用usb转换为串口的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
      priv->control_state |= (TIOCM_DTR | TIOCM_RTS);      if(BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState |= 0x0001) < 0)        err("Set DTR error");      /* don't set RTS if using hardware flow control */      if(!(old_cflag & CRTSCTS))        if(BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState |= 0x0002) < 0)          err("Set RTS error");    }    switch(cflag & CBAUD)    {      case B150:    rate = 150; break;      case B300:    rate = 300; break;      case B600:    rate = 600; break;      case B1200:   rate = 1200; break;      case B2400:   rate = 2400; break;      case B4800:   rate = 4800; break;      case B9600:   rate = 9600; break;      case B19200:  rate = 19200; break;      case B38400:  rate = 38400; break;      case B115200: rate = 115200; break;      case B230400: rate = 230400; break;      case B460800: rate = 460800; break;    }    if((cflag & CBAUD) == B0) {      /* Drop RTS and DTR */      priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);      if(BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState &= 0xFFFE) < 0)        err("DTR LOW error");      if(BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState &= 0xFFFD) < 0)        err("RTS LOW error");    }  }  /* set the parity */  if((cflag & (PARENB | PARODD)) != (old_cflag & (PARENB | PARODD))) {    if(cflag & PARENB)      parity = (cflag & PARODD) ? 0x01 : 0x02;    else      parity = 0;  }  /* set the number of data bits */  if((cflag & CSIZE) != (old_cflag & CSIZE)) {    switch(cflag & CSIZE)    {      case CS5: size = 5; break;      case CS6: size = 6; break;      case CS7: size = 7; break;      case CS8: size = 8; break;    }  }  /* set the number of stop bits */  if((cflag & CSTOPB) != (old_cflag & CSTOPB))    format = (cflag & CSTOPB) ? 0x02 : 0x00;  /* Set flow control */  if((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {    if(cflag & CRTSCTS)      prolific_set_dcr_state(port, TRUE);    else      prolific_set_dcr_state(port, FALSE);  }  priv->lineCoding.dwDTERate = rate;  priv->lineCoding.bCharFormat = format;  priv->lineCoding.bParityType = parity;  priv->lineCoding.bDatabits = size;  dbg(__FUNCTION__ "==> dwDTERate: %ld - bCharFormat: %d - bParityType: %d - bDatabits: %d", rate, format, parity, size);  if(BSA_USB_CMD_SET_DATA_LEN(PROLIFIC_SA_SET_LINECODING_REQUEST, 0, &priv->lineCoding, 7) < 0)    err("Set_line_coding request error");} /* prolific_sa_set_termios */static void prolific_sa_break_ctl(struct usb_serial_port *port, int break_state){  struct usb_serial *serial = port->serial;  if(break_state) {    if(BSA_USB_CMD(PROLIFIC_SA_SET_BREAK_REQUEST, 0xFFFF) < 0)      err("Set break_ctl %d fail", break_state);  }  else {    if(BSA_USB_CMD(PROLIFIC_SA_SET_BREAK_REQUEST, 0) < 0)      err("Set break_ctl %d fail", break_state);  }}static int prolific_sa_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg){  struct usb_serial           *serial = port->serial;  __u16                       urb_value;  /* Will hold the new flags */  struct prolific_sa_private  *priv = (struct prolific_sa_private *)port->private;  int                         ret, mask;  info(__FUNCTION__ " cmd: %04x", cmd);  /* Based on code from acm.c and others */  switch(cmd)  {    case TIOCMGET:      dbg("TIOCMGET: control_state - 0x%04x", (unsigned int)priv->control_state);      return put_user(priv->control_state, (unsigned long *)arg);      break;    case TIOCMSET:  /* Turns on and off the lines as specified by the mask */    case TIOCMBIS:  /* turns on (Sets) the lines as specified by the mask */    case TIOCMBIC:  /* turns off (Clears) the lines as specified by the mask */      if((ret = get_user(mask, (unsigned long *)arg)))        return ret;      dbg("cmd: 0x%04X mask: 0x%04X", cmd, mask);      if((cmd == TIOCMSET) || (mask & TIOCM_RTS)) {        /* RTS needs set */        urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || (cmd == TIOCMBIS) ? 1 : 0;        if(urb_value)          priv->control_state |= TIOCM_RTS;        else          priv->control_state &= ~TIOCM_RTS;        if(urb_value) {          if((ret = BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState |= 0x0002)) < 0) {            err("Set RTS error %d", ret);            return(ret);          }        }        else {          if((ret = BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState &= 0xFFFD)) < 0) {            err("Clear RTS error %d", ret);            return(ret);          }        }        if((cmd == TIOCMSET) || (mask & TIOCM_DTR)) {          /* DTR needs set */          urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) || (cmd == TIOCMBIS) ? 1 : 0;          if(urb_value)            priv->control_state |= TIOCM_DTR;          else            priv->control_state &= ~TIOCM_DTR;          if(urb_value) {            if((ret = BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState |= 0x0001)) < 0) {              err("Set DTR error %d", ret);              return(ret);            }          }          else {            if((ret = BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState &= 0xFFFE)) < 0) {              err("Clear DTR error %d", ret);              return(ret);            }          }        }      }      break;    case TIOCMIWAIT:      /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/      /* TODO */      return(0);    case TIOCGICOUNT:      /* return count of modemline transitions */      /* TODO */      return 0;    default:      dbg("prolific_sa_ioctl arg not supported - 0x%04x", cmd);      return(-ENOIOCTLCMD);      break;  }  return 0;} /* prolific_sa_ioctl */static void prolific_set_dcr_state(struct usb_serial_port *port, int set){  struct usb_serial           *serial = port->serial;  unsigned short              code = 0;  unsigned char               old_value = 0;  unsigned short              new_value;  int                         ret;  struct prolific_sa_private  *priv = (struct prolific_sa_private *)port->private;  info(__FUNCTION__ " - set: %d", set);  if(BSA_USB_CMD_GET_VENDOR_DATA(PROLIFIC_SA_VENDOR_REQUEST, code, &old_value, sizeof(old_value)) < 0)    err("Get DCR request error");  if(set)    new_value = old_value | 0x40;  else    new_value = old_value & 0x3F;  if(BSA_USB_CMD_SET_VENDOR(PROLIFIC_SA_VENDOR_REQUEST, code, new_value) < 0)    err("Set DCR request error");  if(set) {    if((ret = BSA_USB_CMD(PROLIFIC_SA_SET_CTRL_LINE_REQUEST, priv->RTSDTRState |= 0x0002)) < 0) {      err("Set RTS error %d", ret);      return;    }  }}static int prolific_sa_write(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count){  struct usb_serial *serial = port->serial;  unsigned long     flags;  int               result;  dbg(__FUNCTION__ " - port %d", port->number);  if(count == 0) {    dbg(__FUNCTION__ " - write request of 0 bytes");    return(0);  }  /* only do something if we have a bulk out endpoint */  if(serial->num_bulk_out) {/*    if(port->write_urb->status == -EINPROGRESS) {      dbg(__FUNCTION__ " - already writing");      return(0);    }*/    while(port->write_urb->status == -EINPROGRESS)      schedule();    spin_lock_irqsave(&port->port_lock, flags);    count = (count > port->bulk_out_size) ? port->bulk_out_size : count;    usb_serial_debug_data(__FILE__, __FUNCTION__, count, buf);    if(from_user) {      copy_from_user(port->write_urb->transfer_buffer, buf, count);    }    else {      memcpy(port->write_urb->transfer_buffer, buf, count);    }    /* set up our urb */    FILL_BULK_URB(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),                  port->write_urb->transfer_buffer, count,                  prolific_sa_write_bulk_callback,                  port);    /* send the data out the bulk port */    result = usb_submit_urb(port->write_urb);    if(result) {      err(__FUNCTION__ " - failed submitting write urb, error %d", result);      spin_unlock_irqrestore(&port->port_lock, flags);      return 0;    }    spin_unlock_irqrestore(&port->port_lock, flags);    return(count);  }  /* no bulk out, so return 0 bytes written */  return(0);}static void prolific_sa_write_bulk_callback(struct urb *urb){  struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;  struct usb_serial       *serial = get_usb_serial(port, __FUNCTION__);  dbg(__FUNCTION__ " - port %d", port->number);  if(!serial) {    dbg(__FUNCTION__ " - bad serial pointer, exiting");    return;  }  if(urb->status) {    dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);    return;  }  queue_task(&port->tqueue, &tq_immediate);  mark_bh(IMMEDIATE_BH);  return;}static int __init prolific_sa_init(void){  usb_serial_register(&prolific_sa_device);  return 0;}static void __exit prolific_sa_exit(void){  usb_serial_deregister(&prolific_sa_device);}module_init(prolific_sa_init);module_exit(prolific_sa_exit);MODULE_AUTHOR("Sam Kuo");MODULE_DESCRIPTION("Prolific USB-Serial converter driver");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");

⌨️ 快捷键说明

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