📄 serial.c
字号:
return count;
exit:
spin_unlock_irqrestore(&port->port_lock, flags);
return ret;
}
/*
* gs_put_char
*/
static void gs_put_char(struct tty_struct *tty, unsigned char ch)
{
unsigned long flags;
struct gs_port *port = tty->driver_data;
if (port == NULL) {
printk(KERN_ERR "gs_put_char: NULL port pointer\n");
return;
}
gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2));
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev == NULL) {
printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n",
port->port_num, tty);
goto exit;
}
if (port->port_open_count == 0) {
printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n",
port->port_num, tty);
goto exit;
}
gs_buf_put(port->port_write_buf, &ch, 1);
exit:
spin_unlock_irqrestore(&port->port_lock, flags);
}
/*
* gs_flush_chars
*/
static void gs_flush_chars(struct tty_struct *tty)
{
unsigned long flags;
struct gs_port *port = tty->driver_data;
if (port == NULL) {
printk(KERN_ERR "gs_flush_chars: NULL port pointer\n");
return;
}
gs_debug("gs_flush_chars: (%d,%p)\n", port->port_num, tty);
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev == NULL) {
printk(KERN_ERR
"gs_flush_chars: (%d,%p) port is not connected\n",
port->port_num, tty);
goto exit;
}
if (port->port_open_count == 0) {
printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n",
port->port_num, tty);
goto exit;
}
spin_unlock_irqrestore(&port->port_lock, flags);
gs_send(gs_device);
return;
exit:
spin_unlock_irqrestore(&port->port_lock, flags);
}
/*
* gs_write_room
*/
static int gs_write_room(struct tty_struct *tty)
{
int room = 0;
unsigned long flags;
struct gs_port *port = tty->driver_data;
if (port == NULL)
return 0;
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev != NULL && port->port_open_count > 0
&& port->port_write_buf != NULL)
room = gs_buf_space_avail(port->port_write_buf);
spin_unlock_irqrestore(&port->port_lock, flags);
gs_debug("gs_write_room: (%d,%p) room=%d\n",
port->port_num, tty, room);
return room;
}
/*
* gs_chars_in_buffer
*/
static int gs_chars_in_buffer(struct tty_struct *tty)
{
int chars = 0;
unsigned long flags;
struct gs_port *port = tty->driver_data;
if (port == NULL)
return 0;
spin_lock_irqsave(&port->port_lock, flags);
if (port->port_dev != NULL && port->port_open_count > 0
&& port->port_write_buf != NULL)
chars = gs_buf_data_avail(port->port_write_buf);
spin_unlock_irqrestore(&port->port_lock, flags);
gs_debug("gs_chars_in_buffer: (%d,%p) chars=%d\n",
port->port_num, tty, chars);
return chars;
}
/*
* gs_throttle
*/
static void gs_throttle(struct tty_struct *tty)
{
}
/*
* gs_unthrottle
*/
static void gs_unthrottle(struct tty_struct *tty)
{
}
/*
* gs_break
*/
static void gs_break(struct tty_struct *tty, int break_state)
{
}
/*
* gs_ioctl
*/
static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
{
struct gs_port *port = tty->driver_data;
if (port == NULL) {
printk(KERN_ERR "gs_ioctl: NULL port pointer\n");
return -EIO;
}
gs_debug("gs_ioctl: (%d,%p,%p) cmd=0x%4.4x, arg=%lu\n",
port->port_num, tty, file, cmd, arg);
/* handle ioctls */
/* could not handle ioctl */
return -ENOIOCTLCMD;
}
/*
* gs_set_termios
*/
static void gs_set_termios(struct tty_struct *tty, struct termios *old)
{
}
/*
* gs_send
*
* This function finds available write requests, calls
* gs_send_packet to fill these packets with data, and
* continues until either there are no more write requests
* available or no more data to send. This function is
* run whenever data arrives or write requests are available.
*/
static int gs_send(struct gs_dev *dev)
{
int ret,len;
unsigned long flags;
struct usb_ep *ep;
struct usb_request *req;
struct gs_req_entry *req_entry;
if (dev == NULL) {
printk(KERN_ERR "gs_send: NULL device pointer\n");
return -ENODEV;
}
spin_lock_irqsave(&dev->dev_lock, flags);
ep = dev->dev_in_ep;
while(!list_empty(&dev->dev_req_list)) {
req_entry = list_entry(dev->dev_req_list.next,
struct gs_req_entry, re_entry);
req = req_entry->re_req;
len = gs_send_packet(dev, req->buf, ep->maxpacket);
if (len > 0) {
gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2));
list_del(&req_entry->re_entry);
req->length = len;
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
printk(KERN_ERR
"gs_send: cannot queue read request, ret=%d\n",
ret);
break;
}
} else {
break;
}
}
spin_unlock_irqrestore(&dev->dev_lock, flags);
return 0;
}
/*
* gs_send_packet
*
* If there is data to send, a packet is built in the given
* buffer and the size is returned. If there is no data to
* send, 0 is returned. If there is any error a negative
* error number is returned.
*
* Called during USB completion routine, on interrupt time.
*
* We assume that disconnect will not happen until all completion
* routines have completed, so we can assume that the dev_port
* array does not change during the lifetime of this function.
*/
static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size)
{
unsigned int len;
struct gs_port *port;
/* TEMPORARY -- only port 0 is supported right now */
port = dev->dev_port[0];
if (port == NULL) {
printk(KERN_ERR
"gs_send_packet: port=%d, NULL port pointer\n",
0);
return -EIO;
}
spin_lock(&port->port_lock);
len = gs_buf_data_avail(port->port_write_buf);
if (len < size)
size = len;
if (size == 0)
goto exit;
size = gs_buf_get(port->port_write_buf, packet, size);
if (port->port_tty)
wake_up_interruptible(&port->port_tty->write_wait);
exit:
spin_unlock(&port->port_lock);
return size;
}
/*
* gs_recv_packet
*
* Called for each USB packet received. Reads the packet
* header and stuffs the data in the appropriate tty buffer.
* Returns 0 if successful, or a negative error number.
*
* Called during USB completion routine, on interrupt time.
*
* We assume that disconnect will not happen until all completion
* routines have completed, so we can assume that the dev_port
* array does not change during the lifetime of this function.
*/
static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
{
unsigned int len;
struct gs_port *port;
int ret;
/* TEMPORARY -- only port 0 is supported right now */
port = dev->dev_port[0];
if (port == NULL) {
printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n",
port->port_num);
return -EIO;
}
spin_lock(&port->port_lock);
if (port->port_open_count == 0) {
printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n",
port->port_num);
ret = -EIO;
goto exit;
}
if (port->port_tty == NULL) {
printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n",
port->port_num);
ret = -EIO;
goto exit;
}
if (port->port_tty->magic != TTY_MAGIC) {
printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n",
port->port_num);
ret = -EIO;
goto exit;
}
len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count);
if (len < size)
size = len;
if (size > 0) {
memcpy(port->port_tty->flip.char_buf_ptr, packet, size);
port->port_tty->flip.char_buf_ptr += size;
port->port_tty->flip.count += size;
tty_flip_buffer_push(port->port_tty);
wake_up_interruptible(&port->port_tty->read_wait);
}
ret = 0;
exit:
spin_unlock(&port->port_lock);
return ret;
}
/*
* gs_read_complete
*/
static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
{
int ret;
struct gs_dev *dev = ep->driver_data;
if (dev == NULL) {
printk(KERN_ERR "gs_read_complete: NULL device pointer\n");
return;
}
switch(req->status) {
case 0:
/* normal completion */
gs_recv_packet(dev, req->buf, req->actual);
requeue:
req->length = ep->maxpacket;
if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
printk(KERN_ERR
"gs_read_complete: cannot queue read request, ret=%d\n",
ret);
}
break;
case -ESHUTDOWN:
/* disconnect */
gs_debug("gs_read_complete: shutdown\n");
gs_free_req(ep, req);
break;
default:
/* unexpected */
printk(KERN_ERR
"gs_read_complete: unexpected status error, status=%d\n",
req->status);
goto requeue;
break;
}
}
/*
* gs_write_complete
*/
static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
{
struct gs_dev *dev = ep->driver_data;
struct gs_req_entry *gs_req = req->context;
if (dev == NULL) {
printk(KERN_ERR "gs_write_complete: NULL device pointer\n");
return;
}
switch(req->status) {
case 0:
/* normal completion */
requeue:
if (gs_req == NULL) {
printk(KERN_ERR
"gs_write_complete: NULL request pointer\n");
return;
}
spin_lock(&dev->dev_lock);
list_add(&gs_req->re_entry, &dev->dev_req_list);
spin_unlock(&dev->dev_lock);
gs_send(dev);
break;
case -ESHUTDOWN:
/* disconnect */
gs_debug("gs_write_complete: shutdown\n");
gs_free_req(ep, req);
break;
default:
printk(KERN_ERR
"gs_write_complete: unexpected status error, status=%d\n",
req->status);
goto requeue;
break;
}
}
/* Gadget Driver */
/*
* gs_bind
*
* Called on module load. Allocates and initializes the device
* structure and a control request.
*/
static int gs_bind(struct usb_gadget *gadget)
{
int ret;
struct usb_ep *ep;
struct gs_dev *dev;
int gcnum;
/* Some controllers can't support CDC ACM:
* - sh doesn't support multiple interfaces or configs;
* - sa1100 doesn't have a third interrupt endpoint
*/
if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
use_acm = 0;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
gs_device_desc.bcdDevice =
cpu_to_le16(GS_VERSION_NUM | gcnum);
else {
printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
gs_device_desc.bcdDevice =
__constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
}
usb_ep_autoconfig_reset(gadget);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -