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

📄 keyspan.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	urb->dev = port->serial->dev;	if ((err = usb_submit_urb(urb)) != 0) {		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);	}	return;}	/* Outdat handling is common for usa26, usa28 and usa49 messages */static void	usa2x_outdat_callback(struct urb *urb){	struct usb_serial_port *port;	struct keyspan_port_private *p_priv;	port = (struct usb_serial_port *) urb->context;	p_priv = (struct keyspan_port_private *)(port->private);	dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); 	if (port->active) {		queue_task(&port->tqueue, &tq_immediate);		mark_bh(IMMEDIATE_BH);	}}static void	usa26_inack_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__); 	}static void	usa26_outcont_callback(struct urb *urb){	struct usb_serial_port *port;	struct keyspan_port_private *p_priv;	port = (struct usb_serial_port *) urb->context;	p_priv = (struct keyspan_port_private *)(port->private);	if (p_priv->resend_cont) {		dbg (__FUNCTION__ " sending setup\n"); 		keyspan_usa26_send_setup(port->serial, port, 0);	}}static void	usa26_instat_callback(struct urb *urb){	unsigned char 				*data = urb->transfer_buffer;	keyspan_usa26_portStatusMessage		*msg;	struct usb_serial			*serial;	struct usb_serial_port			*port;	struct keyspan_port_private	 	*p_priv;	int old_dcd_state, err;	serial = (struct usb_serial *) urb->context;	if (urb->status) {		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);		return;	}	if (urb->actual_length != 9) {		dbg(__FUNCTION__ " %d byte report??\n", urb->actual_length);		goto exit;	}	msg = (keyspan_usa26_portStatusMessage *)data;#if 0	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d\n",	    msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff,	    msg->_txXoff, msg->rxEnabled, msg->controlResponse);#endif	/* Now do something useful with the data */	/* Check port number from message and retrieve private data */		if (msg->port >= serial->num_ports) {		dbg ("Unexpected port number %d\n", msg->port);		goto exit;	}	port = &serial->port[msg->port];	p_priv = (struct keyspan_port_private *)(port->private);		/* Update handshaking pin state information */	old_dcd_state = p_priv->dcd_state;	p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);	p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);	p_priv->ri_state = ((msg->ri) ? 1 : 0);	if (port->tty && !C_CLOCAL(port->tty)	    && old_dcd_state != p_priv->dcd_state) {		if (old_dcd_state)			tty_hangup(port->tty);		/*  else */		/*	wake_up_interruptible(&p_priv->open_wait); */	}	exit:	/* Resubmit urb so we continue receiving */	urb->dev = serial->dev;	if ((err = usb_submit_urb(urb)) != 0) {		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);	}}static void	usa26_glocont_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__);	}static void     usa28_indat_callback(struct urb *urb){	int                     i, err;	struct usb_serial_port  *port;	struct tty_struct       *tty;	unsigned char           *data;	struct keyspan_port_private             *p_priv;	dbg ("%s\n", __FUNCTION__);	port = (struct usb_serial_port *) urb->context;	p_priv = (struct keyspan_port_private *)(port->private);	data = urb->transfer_buffer;	if (urb != p_priv->in_urbs[p_priv->in_flip])		return;	do {		if (urb->status) {			dbg(__FUNCTION__ "nonzero status: %x on endpoint%d.\n",			    urb->status, usb_pipeendpoint(urb->pipe));			return;		}		port = (struct usb_serial_port *) urb->context;		p_priv = (struct keyspan_port_private *)(port->private);		data = urb->transfer_buffer;		tty = port->tty;		if (urb->actual_length) {			for (i = 0; i < urb->actual_length ; ++i) {				tty_insert_flip_char(tty, data[i], 0);			}			tty_flip_buffer_push(tty);		}		/* Resubmit urb so we continue receiving */		urb->dev = port->serial->dev;		if ((err = usb_submit_urb(urb)) != 0) {			dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n",err);		}		p_priv->in_flip ^= 1;		urb = p_priv->in_urbs[p_priv->in_flip];	} while (urb->status != -EINPROGRESS);}static void	usa28_inack_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__);}static void	usa28_outcont_callback(struct urb *urb){	struct usb_serial_port *port;	struct keyspan_port_private *p_priv;	port = (struct usb_serial_port *) urb->context;	p_priv = (struct keyspan_port_private *)(port->private);	if (p_priv->resend_cont) {		dbg (__FUNCTION__ " sending setup\n");		keyspan_usa28_send_setup(port->serial, port, 0);	}}static void	usa28_instat_callback(struct urb *urb){	int					err;	unsigned char 				*data = urb->transfer_buffer;	keyspan_usa28_portStatusMessage		*msg;	struct usb_serial			*serial;	struct usb_serial_port			*port;	struct keyspan_port_private	 	*p_priv;	int old_dcd_state;	serial = (struct usb_serial *) urb->context;	if (urb->status) {		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);		return;	}	if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) {		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);		goto exit;	}	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x\n",	    data[0], data[1], data[2], data[3], data[4], data[5],	    data[6], data[7], data[8], data[9], data[10], data[11]);*/			/* Now do something useful with the data */	msg = (keyspan_usa28_portStatusMessage *)data;		/* Check port number from message and retrieve private data */		if (msg->port >= serial->num_ports) {		dbg ("Unexpected port number %d\n", msg->port);		goto exit;	}	port = &serial->port[msg->port];	p_priv = (struct keyspan_port_private *)(port->private);		/* Update handshaking pin state information */	old_dcd_state = p_priv->dcd_state;	p_priv->cts_state = ((msg->cts) ? 1 : 0);	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);	p_priv->ri_state = ((msg->ri) ? 1 : 0);	if (port->tty && !C_CLOCAL(port->tty)	    && old_dcd_state != p_priv->dcd_state) {		if (old_dcd_state)			tty_hangup(port->tty);		/*  else */		/*	wake_up_interruptible(&p_priv->open_wait); */	}exit:			/* Resubmit urb so we continue receiving */	urb->dev = serial->dev;	if ((err = usb_submit_urb(urb)) != 0) {		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);	}}static void	usa28_glocont_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__);}static void	usa49_glocont_callback(struct urb *urb){	struct usb_serial *serial;	struct usb_serial_port *port;	struct keyspan_port_private *p_priv;	int i;	dbg ("%s\n", __FUNCTION__);	serial = (struct usb_serial *) urb->context;	for (i = 0; i < serial->num_ports; ++i) {		port = &serial->port[i];		p_priv = (struct keyspan_port_private *)(port->private);		if (p_priv->resend_cont) {			dbg (__FUNCTION__ " sending setup\n"); 			keyspan_usa49_send_setup(serial, port, 0);			break;		}	}}	/* This is actually called glostat in the Keyspan	   doco */static void	usa49_instat_callback(struct urb *urb){	int					err;	unsigned char 				*data = urb->transfer_buffer;	keyspan_usa49_portStatusMessage		*msg;	struct usb_serial			*serial;	struct usb_serial_port			*port;	struct keyspan_port_private	 	*p_priv;	int old_dcd_state;	dbg ("%s\n", __FUNCTION__);	serial = (struct usb_serial *) urb->context;	if (urb->status) {		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);		return;	}	if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);		goto exit;	}	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x\n",	    data[0], data[1], data[2], data[3], data[4], data[5],	    data[6], data[7], data[8], data[9], data[10]);*/			/* Now do something useful with the data */	msg = (keyspan_usa49_portStatusMessage *)data;		/* Check port number from message and retrieve private data */		if (msg->portNumber >= serial->num_ports) {		dbg ("Unexpected port number %d\n", msg->portNumber);		goto exit;	}	port = &serial->port[msg->portNumber];	p_priv = (struct keyspan_port_private *)(port->private);		/* Update handshaking pin state information */	old_dcd_state = p_priv->dcd_state;	p_priv->cts_state = ((msg->cts) ? 1 : 0);	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);	p_priv->ri_state = ((msg->ri) ? 1 : 0);	if (port->tty && !C_CLOCAL(port->tty)	    && old_dcd_state != p_priv->dcd_state) {		if (old_dcd_state)			tty_hangup(port->tty);		/*  else */		/*	wake_up_interruptible(&p_priv->open_wait); */	}exit:			/* Resubmit urb so we continue receiving */	urb->dev = serial->dev;	if ((err = usb_submit_urb(urb)) != 0) {		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);	}}static void	usa49_inack_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__);}static void	usa49_indat_callback(struct urb *urb){	int			i, err;	int			endpoint;	struct usb_serial_port	*port;	struct tty_struct	*tty;	unsigned char 		*data = urb->transfer_buffer;	dbg ("%s\n", __FUNCTION__);	endpoint = usb_pipeendpoint(urb->pipe);	if (urb->status) {		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",			      		urb->status, endpoint);		return;	}	port = (struct usb_serial_port *) urb->context;	tty = port->tty;	if (urb->actual_length) {		if (data[0] == 0) {			/* no error on any byte */			for (i = 1; i < urb->actual_length ; ++i) {				tty_insert_flip_char(tty, data[i], 0);			}		} else {			/* some bytes had errors, every byte has status */			for (i = 0; i + 1 < urb->actual_length; i += 2) {				int stat = data[i], flag = 0;				if (stat & RXERROR_OVERRUN)					flag |= TTY_OVERRUN;				if (stat & RXERROR_FRAMING)					flag |= TTY_FRAME;				if (stat & RXERROR_PARITY)					flag |= TTY_PARITY;				/* XXX should handle break (0x10) */				tty_insert_flip_char(tty, data[i+1], flag);			}		}		tty_flip_buffer_push(tty);	}						/* Resubmit urb so we continue receiving */	urb->dev = port->serial->dev;	if ((err = usb_submit_urb(urb)) != 0) {		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);	}}/* not used, usa-49 doesn't have per-port control endpoints */static void	usa49_outcont_callback(struct urb *urb){	dbg ("%s\n", __FUNCTION__);}static int keyspan_write_room (struct usb_serial_port *port){	dbg("keyspan_write_room called\n");	return (32);}static int keyspan_chars_in_buffer (struct usb_serial_port *port){	return (0);}static int keyspan_open (struct usb_serial_port *port, struct file *filp){	struct keyspan_port_private 	*p_priv;	struct keyspan_serial_private 	*s_priv;	struct usb_serial 		*serial = port->serial;	const keyspan_device_details	*d_details;	int				i, already_active, err;	urb_t *urb;	s_priv = (struct keyspan_serial_private *)(serial->private);	p_priv = (struct keyspan_port_private *)(port->private);	d_details = s_priv->device_details;		dbg("keyspan_open called for port%d.\n", port->number); 	MOD_INC_USE_COUNT;	down (&port->sem);	++port->open_count;	already_active = port->active;	port->active = 1;	up (&port->sem);	if (already_active)		return 0;	p_priv = (struct keyspan_port_private *)(port->private);		/* Set some sane defaults */	p_priv->rts_state = 1;	p_priv->dtr_state = 1;	/* Start reading from endpoints */	for (i = 0; i < 2; i++) {		if ((urb = p_priv->in_urbs[i]) == NULL)			continue;		urb->dev = serial->dev;		if ((err = usb_submit_urb(urb)) != 0) {			dbg(__FUNCTION__ " submit urb %d failed (%d)\n", i, err);		}	}

⌨️ 快捷键说明

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