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

📄 sierra.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static void sierra_indat_callback(struct urb *urb){	int err;	int endpoint;	struct usb_serial_port *port;	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int status = urb->status;	dbg("%s: %p", __FUNCTION__, urb);	endpoint = usb_pipeendpoint(urb->pipe);	port = (struct usb_serial_port *) urb->context;	if (status) {		dbg("%s: nonzero status: %d on endpoint %02x.",		    __FUNCTION__, status, endpoint);	} else {		tty = port->tty;		if (urb->actual_length) {			tty_buffer_request_room(tty, urb->actual_length);			tty_insert_flip_string(tty, data, urb->actual_length);			tty_flip_buffer_push(tty);		} else {			dbg("%s: empty read urb received", __FUNCTION__);		}		/* Resubmit urb so we continue receiving */		if (port->open_count && status != -ESHUTDOWN) {			err = usb_submit_urb(urb, GFP_ATOMIC);			if (err)				dev_err(&port->dev, "resubmit read urb failed."					"(%d)\n", err);		}	}	return;}static void sierra_instat_callback(struct urb *urb){	int err;	int status = urb->status;	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;	struct sierra_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 (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__, status);	/* Resubmit urb so we continue receiving IRQ data */	if (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 sierra_write_room(struct usb_serial_port *port){	struct sierra_port_private *portdata = usb_get_serial_port_data(port);	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	/* try to give a good number back based on if we have any free urbs at	 * this point in time */	spin_lock_irqsave(&portdata->lock, flags);	if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {		spin_unlock_irqrestore(&portdata->lock, flags);		dbg("%s - write limit hit\n", __FUNCTION__);		return 0;	}	spin_unlock_irqrestore(&portdata->lock, flags);	return 2048;}static int sierra_chars_in_buffer(struct usb_serial_port *port){	dbg("%s - port %d", __FUNCTION__, port->number);	/*	 * We can't really account for how much data we	 * have sent out, but hasn't made it through to the	 * device as we can't see the backend here, so just	 * tell the tty layer that everything is flushed.	 */	return 0;}static int sierra_open(struct usb_serial_port *port, struct file *filp){	struct sierra_port_private *portdata;	struct usb_serial *serial = port->serial;	int i;	struct urb *urb;	int result;	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);		result = usb_submit_urb(urb, GFP_KERNEL);		if (result) {			dev_err(&port->dev, "submit urb %d failed (%d) %d\n",				i, result, urb->transfer_buffer_length);		}	}	port->tty->low_latency = 1;	sierra_send_setup(port);	/* start up the interrupt endpoint if we have one */	if (port->interrupt_in_urb) {		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);		if (result)			dev_err(&port->dev, "submit irq_in urb failed %d\n",				result);	}	return 0;}static void sierra_close(struct usb_serial_port *port, struct file *filp){	int i;	struct usb_serial *serial = port->serial;	struct sierra_port_private *portdata;	dbg("%s", __FUNCTION__);	portdata = usb_get_serial_port_data(port);	portdata->rts_state = 0;	portdata->dtr_state = 0;	if (serial->dev) {		sierra_send_setup(port);		/* Stop reading/writing urbs */		for (i = 0; i < N_IN_URB; i++)			usb_kill_urb(portdata->in_urbs[i]);	}	usb_kill_urb(port->interrupt_in_urb);	port->tty = NULL;}static int sierra_startup(struct usb_serial *serial){	struct usb_serial_port *port;	struct sierra_port_private *portdata;	struct urb *urb;	int i;	int j;	dbg("%s", __FUNCTION__);	/*Set Device mode to D0 */	sierra_set_power_state(serial->dev, 0x0000);	/* Now setup per port private data */	for (i = 0; i < serial->num_ports; i++) {		port = serial->port[i];		portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);		if (!portdata) {			dbg("%s: kmalloc for sierra_port_private (%d) failed!.",					__FUNCTION__, i);			return -ENOMEM;		}		spin_lock_init(&portdata->lock);		usb_set_serial_port_data(port, portdata);		/* initialize the in urbs */		for (j = 0; j < N_IN_URB; ++j) {			urb = usb_alloc_urb(0, GFP_KERNEL);			if (urb == NULL) {				dbg("%s: alloc for in port failed.",				    __FUNCTION__);				continue;			}			/* Fill URB using supplied data. */			usb_fill_bulk_urb(urb, serial->dev,					  usb_rcvbulkpipe(serial->dev,						port->bulk_in_endpointAddress),					  portdata->in_buffer[j], IN_BUFLEN,					  sierra_indat_callback, port);			portdata->in_urbs[j] = urb;		}	}	return 0;}static void sierra_shutdown(struct usb_serial *serial){	int i, j;	struct usb_serial_port *port;	struct sierra_port_private *portdata;	dbg("%s", __FUNCTION__);	for (i = 0; i < serial->num_ports; ++i) {		port = serial->port[i];		if (!port)			continue;		portdata = usb_get_serial_port_data(port);		if (!portdata)			continue;		for (j = 0; j < N_IN_URB; j++) {			usb_kill_urb(portdata->in_urbs[j]);			usb_free_urb(portdata->in_urbs[j]);			portdata->in_urbs[j] = NULL;		}		kfree(portdata);		usb_set_serial_port_data(port, NULL);	}}static struct usb_serial_driver sierra_1port_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"sierra1",	},	.description       = "Sierra USB modem (1 port)",	.id_table          = id_table_1port,	.usb_driver        = &sierra_driver,	.num_interrupt_in  = NUM_DONT_CARE,	.num_bulk_in       = 1,	.num_bulk_out      = 1,	.num_ports         = 1,	.open              = sierra_open,	.close             = sierra_close,	.write             = sierra_write,	.write_room        = sierra_write_room,	.chars_in_buffer   = sierra_chars_in_buffer,	.throttle          = sierra_rx_throttle,	.unthrottle        = sierra_rx_unthrottle,	.ioctl             = sierra_ioctl,	.set_termios       = sierra_set_termios,	.break_ctl         = sierra_break_ctl,	.tiocmget          = sierra_tiocmget,	.tiocmset          = sierra_tiocmset,	.attach            = sierra_startup,	.shutdown          = sierra_shutdown,	.read_int_callback = sierra_instat_callback,};static struct usb_serial_driver sierra_3port_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"sierra3",	},	.description       = "Sierra USB modem (3 port)",	.id_table          = id_table_3port,	.usb_driver        = &sierra_driver,	.num_interrupt_in  = NUM_DONT_CARE,	.num_bulk_in       = 3,	.num_bulk_out      = 3,	.num_ports         = 3,	.open              = sierra_open,	.close             = sierra_close,	.write             = sierra_write,	.write_room        = sierra_write_room,	.chars_in_buffer   = sierra_chars_in_buffer,	.throttle          = sierra_rx_throttle,	.unthrottle        = sierra_rx_unthrottle,	.ioctl             = sierra_ioctl,	.set_termios       = sierra_set_termios,	.break_ctl         = sierra_break_ctl,	.tiocmget          = sierra_tiocmget,	.tiocmset          = sierra_tiocmset,	.attach            = sierra_startup,	.shutdown          = sierra_shutdown,	.read_int_callback = sierra_instat_callback,};/* Functions used by new usb-serial code. */static int __init sierra_init(void){	int retval;	retval = usb_serial_register(&sierra_1port_device);	if (retval)		goto failed_1port_device_register;	retval = usb_serial_register(&sierra_3port_device);	if (retval)		goto failed_3port_device_register;	retval = usb_register(&sierra_driver);	if (retval)		goto failed_driver_register;	info(DRIVER_DESC ": " DRIVER_VERSION);	return 0;failed_driver_register:	usb_serial_deregister(&sierra_3port_device);failed_3port_device_register:	usb_serial_deregister(&sierra_1port_device);failed_1port_device_register:	return retval;}static void __exit sierra_exit(void){	usb_deregister (&sierra_driver);	usb_serial_deregister(&sierra_1port_device);	usb_serial_deregister(&sierra_3port_device);}module_init(sierra_init);module_exit(sierra_exit);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 + -