📄 pl2303.c
字号:
} 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 + -