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

📄 pl2303.c

📁 PL2303 Linux驱动源码 drivers/usb/serial/usb-serial
💻 C
📖 第 1 页 / 共 2 页
字号:
    }  return;}       static intpl2303_open (struct usb_serial_port *port, struct file *filp){                               /* pl2303_open */  struct termios tmp_termios;  struct usb_serial *serial = port->serial;  unsigned char buf[10];  int i;  dbg ("pl2303_open port %d", port->number);  port->active++;#define FISH(a,b,c,d) \	i=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \		    b, a,c  , d, buf, 1, 100); \	printk("0x%x:0x%x:0x%x:0x%x  %d - %x\n",a,b,c,d,i,buf[0]);#define SOUP(a,b,c,d) \	i=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \		    b, a,c  , d, NULL, 0, 100); \	printk("0x%x:0x%x:0x%x:0x%x  %d\n",a,b,c,d,i);  FISH (0xc0, 1, 0x8484, 0);  SOUP (0x40, 1, 0x0404, 0);  FISH (0xc0, 1, 0x8484, 0);  FISH (0xc0, 1, 0x8383, 0);  FISH (0xc0, 1, 0x8484, 0);  SOUP (0x40, 1, 0x0404, 1);  FISH (0xc0, 1, 0x8484, 0);  FISH (0xc0, 1, 0x8383, 0);  SOUP (0x40, 1, 0, 1);  SOUP (0x40, 1, 1, 0xc0);  SOUP (0x40, 1, 2, 4);  /* Setup termios */  if (port->active == 1)    {      *(port->tty->termios) = tty_std_termios;      port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;    }  pl2303_set_termios (port, &tmp_termios);  //FIXME: need to assert RTS and DTR if CRTSCTS off  if (port->active == 1)    {	unsigned long flags,page;      int i;			page = get_free_page(GFP_KERNEL);	if (!page)		 {          pl2303_close (port, NULL);	    return -ENOMEM;	}			PL2303_LOCK(port,flags);		port->xmit_cnt=port->xmit_head=port->xmit_tail=0;	if (tmp_buf)	    free_page(page);	else	    tmp_buf = (unsigned char *) page;		PL2303_UNLOCK(port,flags);	page = get_free_page(GFP_KERNEL);	if (!page)		 {          pl2303_close (port, NULL);	    return -ENOMEM;	}	PL2303_LOCK(port,flags);	if (port->xmit_buf)		free_page(page);	else		port->xmit_buf=(unsigned char *) page;	PL2303_UNLOCK(port,flags);      if ((i = usb_submit_urb (port->read_urb)))        {          err ("usb_submit_urb(read bulk 1) failed");          printk ("i=%d\n", i);          pl2303_close (port, NULL);          return -EPROTO;        }      if ((i = usb_submit_urb (port->interrupt_in_urb)))        {          err ("usb_submit_urb(interrupt ink) failed");          printk ("i=%d\n", i);          pl2303_close (port, NULL);          return -EPROTO;        }    }  return (0);}                               /* pl2303_open */static voidpl2303_close (struct usb_serial_port *port, struct file *filp){                               /* pl2303_close */  unsigned int c_cflag = port->tty->termios->c_cflag;  unsigned long flags;  dbg ("pl2303_close port %d", port->number);  /* shutdown our bulk reads and writes */  if (port->active == 1)    {  if (c_cflag & HUPCL)    {      //FIXME: Do drop DTR      //FIXME: Do drop RTS    }      usb_unlink_urb (port->write_urb);      usb_unlink_urb (port->read_urb);      usb_unlink_urb (port->interrupt_in_urb);	PL2303_LOCK(port,flags);	    if (port->xmit_buf){		unsigned char * temp;		temp = port->xmit_buf;		port->xmit_buf = 0;		free_page((unsigned long) temp);	    }	PL2303_UNLOCK(port,flags);	//FIXME: tmp_buf memory leak    }  port->active--;}                               /* pl2303_close *//* do some startup allocations not currently performed by usb_serial_probe() */static intpl2303_startup (struct usb_serial *serial){  spin_lock_init(&serial->ports[0].lock);  return (0);}static intpl2303_ioctl (struct usb_serial_port *port, struct file *file,              unsigned int cmd, unsigned long arg){// struct usb_serial *serial = port->serial;// __u16 urb_value=0; /* Will hold the new flags */// char buf[1];// int  ret, mask;  printk ("pl2303_sio ioctl 0x%04x\n", cmd);  /* Based on code from acm.c and others */  switch (cmd)    {    case TIOCMGET:      dbg ("TIOCMGET");      return put_user (0, (unsigned long *) arg);      break;    case TIOCMBIS:    case TIOCMBIC:    case TIOCMSET:      return 0;    default:      /* This is not an error - turns out the higher layers will do        *  some ioctls itself (see comment above)       */      dbg ("pl2303_sio ioctl arg not supported - it was 0x%04x", cmd);      return (-ENOIOCTLCMD);      break;    }  dbg ("pl2303_ioctl returning 0");  return 0;}                               /* pl2303_ioctl */static void pl2303_break_ctl(struct usb_serial_port *port,int break_state){//FIXME}static voidpl2303_read_int_callback (struct urb *urb){  struct usb_serial_port *port = (struct usb_serial_port *) urb->context;  struct usb_serial *serial = get_usb_serial (port, "pl2303_read_int_callback");  //unsigned char *data = urb->transfer_buffer;  //int i;//ints auto restart...  if (!serial)    {      return;    }  if (urb->status)    {      urb->status = 0;      return;    }#if 0//FIXME need to update state of terminal lines variable  if (urb->actual_length)    {      printk (KERN_DEBUG __FILE__ ": INT data read - length = %d, data = ",              urb->actual_length);      for (i = 0; i < urb->actual_length; ++i)        {          printk ("%.2x ", data[i]);        }      printk ("\n");    }#endif  return;}static voidpl2303_read_bulk_callback (struct urb *urb){  struct usb_serial_port *port = (struct usb_serial_port *) urb->context;  struct usb_serial *serial = get_usb_serial (port, "pl2303_read_bulk_callback");  struct tty_struct *tty;  unsigned char *data = urb->transfer_buffer;  int i;  if (!serial)    {      return;    }// PL2303 mysteriously fails with -EPROTO reschedule the read  if (urb->status)    {      urb->status = 0;      if (usb_submit_urb (urb))        dbg ("failed resubmitting read bulk urb");      return;    }#ifdef DEBUG  if (urb->actual_length)    {      printk (KERN_DEBUG __FILE__ ": BULK data read - length = %d, data = ",              urb->actual_length);      for (i = 0; i < urb->actual_length; ++i)        {          printk ("%.2x ", data[i]);        }      printk ("\n");    }#endif  tty = port->tty;  if (urb->actual_length)    {      for (i = 0; i < urb->actual_length; ++i)        {          if (tty->flip.count >= TTY_FLIPBUF_SIZE)            {              printk ("ARGH ------------ Flip buffer overrun...\n");              break;            }          tty_insert_flip_char (tty, data[i], 0);        }      tty_flip_buffer_push (tty);    }  /* Schedule the next read*/  if (usb_submit_urb (urb))    dbg ("failed submitting read bulk urb");  return;}static voidpl2303_write_bulk_callback (struct urb *urb){  struct usb_serial_port *port = (struct usb_serial_port *) urb->context;  struct usb_serial *serial;  struct tty_struct *tty = port->tty;  dbg ("pl2303_write_bulk_callback");  if (port_paranoia_check (port, "pl2303_write_bulk_callback"))    {      return;    }  serial = port->serial;  if (serial_paranoia_check (serial, "pl2303_write_bulk_callback"))    {      return;    }  if (urb->status)    {      printk ("Overflow in write\n");      dbg ("nonzero write bulk status received: %d", urb->status);      //need to resubmit frame;      port->write_urb->transfer_buffer_length = 1;      //Resubmit ourselves      if (usb_submit_urb (port->write_urb))        err ("usb_submit_urb(write bulk) failed");      return;    }  wake_up_interruptible (&port->write_wait);  if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)    (tty->ldisc.write_wakeup) (tty);  wake_up_interruptible (&tty->write_wait);        start_xmit(port);  return;}static voidstart_xmit (struct usb_serial_port *port){  struct usb_serial *serial;  unsigned long flags;  serial = port->serial;  PL2303_LOCK(port,flags);      if (port->write_urb->status != -EINPROGRESS)        {          if (port->xmit_tail!=port->xmit_head)            {              memcpy (port->write_urb->transfer_buffer, &port->xmit_buf[port->xmit_tail],1);            port->xmit_cnt--;            port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);	                    port->write_urb->transfer_buffer_length = 1;              if (usb_submit_urb (port->write_urb))                err ("usb_submit_urb(write bulk) failed");            }        }PL2303_UNLOCK(port,flags);}

⌨️ 快捷键说明

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