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

📄 option.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	return;}static void option_outdat_callback(struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port;	dbg("%s", __FUNCTION__);	port = (struct usb_serial_port *) urb->context;	if (port->open_count)		schedule_work(&port->work);}static void option_instat_callback(struct urb *urb, struct pt_regs *regs){	int err;	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;	struct option_port_private *portdata = usb_get_serial_port_data(port);	struct usb_serial *serial = port->serial;	dbg("%s", __FUNCTION__);	dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);	if (urb->status == 0) {		struct usb_ctrlrequest *req_pkt =				(struct usb_ctrlrequest *)urb->transfer_buffer;		if (!req_pkt) {			dbg("%s: NULL req_pkt\n", __FUNCTION__);			return;		}		if ((req_pkt->bRequestType == 0xA1) &&				(req_pkt->bRequest == 0x20)) {			int old_dcd_state;			unsigned char signals = *((unsigned char *)					urb->transfer_buffer +					sizeof(struct usb_ctrlrequest));			dbg("%s: signal x%x", __FUNCTION__, signals);			old_dcd_state = portdata->dcd_state;			portdata->cts_state = 1;			portdata->dcd_state = ((signals & 0x01) ? 1 : 0);			portdata->dsr_state = ((signals & 0x02) ? 1 : 0);			portdata->ri_state = ((signals & 0x08) ? 1 : 0);			if (port->tty && !C_CLOCAL(port->tty) &&					old_dcd_state && !portdata->dcd_state)				tty_hangup(port->tty);		} else {			dbg("%s: type %x req %x", __FUNCTION__,				req_pkt->bRequestType,req_pkt->bRequest);		}	} else		dbg("%s: error %d", __FUNCTION__, urb->status);	/* Resubmit urb so we continue receiving IRQ data */	if (urb->status != -ESHUTDOWN) {		urb->dev = serial->dev;		err = usb_submit_urb(urb, GFP_ATOMIC);		if (err)			dbg("%s: resubmit intr urb failed. (%d)",				__FUNCTION__, err);	}}static int option_write_room(struct usb_serial_port *port){	struct option_port_private *portdata;	int i;	int data_len = 0;	struct urb *this_urb;	portdata = usb_get_serial_port_data(port);	for (i=0; i < N_OUT_URB; i++) {		this_urb = portdata->out_urbs[i];		if (this_urb && this_urb->status != -EINPROGRESS)			data_len += OUT_BUFLEN;	}	dbg("%s: %d", __FUNCTION__, data_len);	return data_len;}static int option_chars_in_buffer(struct usb_serial_port *port){	struct option_port_private *portdata;	int i;	int data_len = 0;	struct urb *this_urb;	portdata = usb_get_serial_port_data(port);	for (i=0; i < N_OUT_URB; i++) {		this_urb = portdata->out_urbs[i];		if (this_urb && this_urb->status == -EINPROGRESS)			data_len += this_urb->transfer_buffer_length;	}	dbg("%s: %d", __FUNCTION__, data_len);	return data_len;}static int option_open(struct usb_serial_port *port, struct file *filp){	struct option_port_private *portdata;	struct usb_serial *serial = port->serial;	int i, err;	struct urb *urb;	portdata = usb_get_serial_port_data(port);	dbg("%s", __FUNCTION__);	/* Set some sane defaults */	portdata->rts_state = 1;	portdata->dtr_state = 1;	/* Reset low level data toggle and start reading from endpoints */	for (i = 0; i < N_IN_URB; i++) {		urb = portdata->in_urbs[i];		if (! urb)			continue;		if (urb->dev != serial->dev) {			dbg("%s: dev %p != %p", __FUNCTION__,				urb->dev, serial->dev);			continue;		}		/*		 * make sure endpoint data toggle is synchronized with the		 * device		 */		usb_clear_halt(urb->dev, urb->pipe);		err = usb_submit_urb(urb, GFP_KERNEL);		if (err) {			dbg("%s: submit urb %d failed (%d) %d",				__FUNCTION__, i, err,				urb->transfer_buffer_length);		}	}	/* Reset low level data toggle on out endpoints */	for (i = 0; i < N_OUT_URB; i++) {		urb = portdata->out_urbs[i];		if (! urb)			continue;		urb->dev = serial->dev;		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),				usb_pipeout(urb->pipe), 0); */	}	port->tty->low_latency = 1;	option_send_setup(port);	return (0);}static inline void stop_urb(struct urb *urb){	if (urb && urb->status == -EINPROGRESS)		usb_kill_urb(urb);}static void option_close(struct usb_serial_port *port, struct file *filp){	int i;	struct usb_serial *serial = port->serial;	struct option_port_private *portdata;	dbg("%s", __FUNCTION__);	portdata = usb_get_serial_port_data(port);	portdata->rts_state = 0;	portdata->dtr_state = 0;	if (serial->dev) {		option_send_setup(port);		/* Stop reading/writing urbs */		for (i = 0; i < N_IN_URB; i++)			stop_urb(portdata->in_urbs[i]);		for (i = 0; i < N_OUT_URB; i++)			stop_urb(portdata->out_urbs[i]);	}	port->tty = NULL;}/* Helper functions used by option_setup_urbs */static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,		int dir, void *ctx, char *buf, int len,		void (*callback)(struct urb *, struct pt_regs *regs)){	struct urb *urb;	if (endpoint == -1)		return NULL;		/* endpoint not needed */	urb = usb_alloc_urb(0, GFP_KERNEL);		/* No ISO */	if (urb == NULL) {		dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);		return NULL;	}		/* Fill URB using supplied data. */	usb_fill_bulk_urb(urb, serial->dev,		      usb_sndbulkpipe(serial->dev, endpoint) | dir,		      buf, len, callback, ctx);	return urb;}/* Setup urbs */static void option_setup_urbs(struct usb_serial *serial){	int j;	struct usb_serial_port *port;	struct option_port_private *portdata;	dbg("%s", __FUNCTION__);	port = serial->port[0];	portdata = usb_get_serial_port_data(port);	/* Do indat endpoints first */	for (j = 0; j <= N_IN_URB; ++j) {		portdata->in_urbs[j] = option_setup_urb (serial,                  port->bulk_in_endpointAddress, USB_DIR_IN, port,                  portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);	}	/* outdat endpoints */	for (j = 0; j <= N_OUT_URB; ++j) {		portdata->out_urbs[j] = option_setup_urb (serial,                  port->bulk_out_endpointAddress, USB_DIR_OUT, port,                  portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);	}}static int option_send_setup(struct usb_serial_port *port){	struct usb_serial *serial = port->serial;	struct option_port_private *portdata;	dbg("%s", __FUNCTION__);	portdata = usb_get_serial_port_data(port);	if (port->tty) {		int val = 0;		if (portdata->dtr_state)			val |= 0x01;		if (portdata->rts_state)			val |= 0x02;		return usb_control_msg(serial->dev,				usb_rcvctrlpipe(serial->dev, 0),				0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);	}	return 0;}static int option_startup(struct usb_serial *serial){	int i, err;	struct usb_serial_port *port;	struct option_port_private *portdata;	dbg("%s", __FUNCTION__);	/* Now setup per port private data */	for (i = 0; i < serial->num_ports; i++) {		port = serial->port[i];		portdata = kmalloc(sizeof(*portdata), GFP_KERNEL);		if (!portdata) {			dbg("%s: kmalloc for option_port_private (%d) failed!.",					__FUNCTION__, i);			return (1);		}		memset(portdata, 0, sizeof(struct option_port_private));		usb_set_serial_port_data(port, portdata);		if (! port->interrupt_in_urb)			continue;		err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);		if (err)			dbg("%s: submit irq_in urb failed %d",				__FUNCTION__, err);	}	option_setup_urbs(serial);	return (0);}static void option_shutdown(struct usb_serial *serial){	int i, j;	struct usb_serial_port *port;	struct option_port_private *portdata;	dbg("%s", __FUNCTION__);	/* Stop reading/writing urbs */	for (i = 0; i < serial->num_ports; ++i) {		port = serial->port[i];		portdata = usb_get_serial_port_data(port);		for (j = 0; j < N_IN_URB; j++)			stop_urb(portdata->in_urbs[j]);		for (j = 0; j < N_OUT_URB; j++)			stop_urb(portdata->out_urbs[j]);	}	/* Now free them */	for (i = 0; i < serial->num_ports; ++i) {		port = serial->port[i];		portdata = usb_get_serial_port_data(port);		for (j = 0; j < N_IN_URB; j++) {			if (portdata->in_urbs[j]) {				usb_free_urb(portdata->in_urbs[j]);				portdata->in_urbs[j] = NULL;			}		}		for (j = 0; j < N_OUT_URB; j++) {			if (portdata->out_urbs[j]) {				usb_free_urb(portdata->out_urbs[j]);				portdata->out_urbs[j] = NULL;			}		}	}	/* Now free per port private data */	for (i = 0; i < serial->num_ports; i++) {		port = serial->port[i];		kfree(usb_get_serial_port_data(port));	}}MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_VERSION(DRIVER_VERSION);MODULE_LICENSE("GPL");#ifdef CONFIG_USB_DEBUGmodule_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug messages");#endif

⌨️ 快捷键说明

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