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

📄 visor.c

📁 usb driver for 2.6.17
💻 C
📖 第 1 页 / 共 3 页
字号:
	dbg("%s - port %d", __FUNCTION__, port->number);			 	/* shutdown our urbs */	usb_kill_urb(port->read_urb);	if (port->interrupt_in_urb)		usb_kill_urb(port->interrupt_in_urb);	/* Try to send shutdown message, if the device is gone, this will just fail. */	transfer_buffer =  kmalloc (0x12, GFP_KERNEL);	if (transfer_buffer) {		usb_control_msg (port->serial->dev,				 usb_rcvctrlpipe(port->serial->dev, 0),				 VISOR_CLOSE_NOTIFICATION, 0xc2,				 0x0000, 0x0000, 				 transfer_buffer, 0x12, 300);		kfree (transfer_buffer);	}	if (stats)		dev_info(&port->dev, "Bytes In = %d  Bytes Out = %d\n",			 priv->bytes_in, priv->bytes_out);}static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count){	struct visor_private *priv = usb_get_serial_port_data(port);	struct usb_serial *serial = port->serial;	struct urb *urb;	unsigned char *buffer;	unsigned long flags;	int status;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {		spin_unlock_irqrestore(&priv->lock, flags);		dbg("%s - write limit hit\n", __FUNCTION__);		return 0;	}	spin_unlock_irqrestore(&priv->lock, flags);	buffer = kmalloc (count, GFP_ATOMIC);	if (!buffer) {		dev_err(&port->dev, "out of memory\n");		return -ENOMEM;	}	urb = usb_alloc_urb(0, GFP_ATOMIC);	if (!urb) {		dev_err(&port->dev, "no more free urbs\n");		kfree (buffer);		return -ENOMEM;	}	memcpy (buffer, buf, count);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);	usb_fill_bulk_urb (urb, serial->dev,			   usb_sndbulkpipe (serial->dev,					    port->bulk_out_endpointAddress),			   buffer, count, 			   visor_write_bulk_callback, port);	/* send it down the pipe */	status = usb_submit_urb(urb, GFP_ATOMIC);	if (status) {		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",			__FUNCTION__, status);		count = status;		kfree (buffer);	} else {		spin_lock_irqsave(&priv->lock, flags);		++priv->outstanding_urbs;		priv->bytes_out += count;		spin_unlock_irqrestore(&priv->lock, flags);	}	/* we are done with this urb, so let the host driver	 * really free it when it is finished with it */	usb_free_urb (urb);	return count;}static int visor_write_room (struct usb_serial_port *port){	dbg("%s - port %d", __FUNCTION__, port->number);	/*	 * We really can take anything the user throws at us	 * but let's pick a nice big number to tell the tty	 * layer that we have lots of free space	 */	return 2048;}static int visor_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, so just tell the tty layer that everything	 * is flushed.	 */	return 0;}static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned long flags;	/* free up the transfer buffer, as usb_free_urb() does not do this */	kfree (urb->transfer_buffer);	dbg("%s - port %d", __FUNCTION__, port->number);		if (urb->status)		dbg("%s - nonzero write bulk status received: %d",		    __FUNCTION__, urb->status);	spin_lock_irqsave(&priv->lock, flags);	--priv->outstanding_urbs;	spin_unlock_irqrestore(&priv->lock, flags);	schedule_work(&port->work);}static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned char *data = urb->transfer_buffer;	struct tty_struct *tty;	unsigned long flags;	int throttled;	int result;	dbg("%s - port %d", __FUNCTION__, port->number);	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);		return;	}	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);	tty = port->tty;	if (tty && 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);	}	spin_lock_irqsave(&priv->lock, flags);	priv->bytes_in += urb->actual_length;	throttled = priv->throttled;	spin_unlock_irqrestore(&priv->lock, flags);	/* Continue trying to always read if we should */	if (!throttled) {		usb_fill_bulk_urb (port->read_urb, port->serial->dev,				   usb_rcvbulkpipe(port->serial->dev,						   port->bulk_in_endpointAddress),				   port->read_urb->transfer_buffer,				   port->read_urb->transfer_buffer_length,				   visor_read_bulk_callback, port);		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);		if (result)			dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);	}	return;}static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	int result;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d",		    __FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d",		    __FUNCTION__, urb->status);		goto exit;	}	/*	 * This information is still unknown what it can be used for.	 * If anyone has an idea, please let the author know...	 *	 * Rumor has it this endpoint is used to notify when data	 * is ready to be read from the bulk ones.	 */	usb_serial_debug_data(debug, &port->dev, __FUNCTION__,			      urb->actual_length, urb->transfer_buffer);exit:	result = usb_submit_urb (urb, GFP_ATOMIC);	if (result)		dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n",			__FUNCTION__, result);}static void visor_throttle (struct usb_serial_port *port){	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	priv->throttled = 1;	spin_unlock_irqrestore(&priv->lock, flags);}static void visor_unthrottle (struct usb_serial_port *port){	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned long flags;	int result;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&priv->lock, flags);	priv->throttled = 0;	spin_unlock_irqrestore(&priv->lock, flags);	port->read_urb->dev = port->serial->dev;	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);	if (result)		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);}static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id){	struct device *dev = &serial->dev->dev;	struct visor_connection_info *connection_info;	unsigned char *transfer_buffer;	char *string;	int retval = 0;	int i;	int num_ports = 0;	dbg("%s", __FUNCTION__);	transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);	if (!transfer_buffer) {		dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__,			sizeof(*connection_info));		return -ENOMEM;	}	/* send a get connection info request */	retval = usb_control_msg (serial->dev,				  usb_rcvctrlpipe(serial->dev, 0),				  VISOR_GET_CONNECTION_INFORMATION,				  0xc2, 0x0000, 0x0000, transfer_buffer,				  sizeof(*connection_info), 300);	if (retval < 0) {		dev_err(dev, "%s - error %d getting connection information\n",			__FUNCTION__, retval);		goto exit;	}	if (retval == sizeof(*connection_info)) {	        connection_info = (struct visor_connection_info *)transfer_buffer;		num_ports = le16_to_cpu(connection_info->num_ports);		for (i = 0; i < num_ports; ++i) {			switch (connection_info->connections[i].port_function_id) {				case VISOR_FUNCTION_GENERIC:					string = "Generic";					break;				case VISOR_FUNCTION_DEBUGGER:					string = "Debugger";					break;				case VISOR_FUNCTION_HOTSYNC:					string = "HotSync";					break;				case VISOR_FUNCTION_CONSOLE:					string = "Console";					break;				case VISOR_FUNCTION_REMOTE_FILE_SYS:					string = "Remote File System";					break;				default:					string = "unknown";					break;			}			dev_info(dev, "%s: port %d, is for %s use\n",				serial->type->description,				connection_info->connections[i].port, string);		}	}	/*	* Handle devices that report invalid stuff here.	*/	if (num_ports == 0 || num_ports > 2) {		dev_warn (dev, "%s: No valid connect info available\n",			serial->type->description);		num_ports = 2;	}  	dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,		num_ports);	/*	 * save off our num_ports info so that we can use it in the	 * calc_num_ports callback	 */	usb_set_serial_data(serial, (void *)(long)num_ports);	/* ask for the number of bytes available, but ignore the response as it is broken */	retval = usb_control_msg (serial->dev,				  usb_rcvctrlpipe(serial->dev, 0),				  VISOR_REQUEST_BYTES_AVAILABLE,				  0xc2, 0x0000, 0x0005, transfer_buffer,				  0x02, 300);	if (retval < 0)		dev_err(dev, "%s - error %d getting bytes available request\n",			__FUNCTION__, retval);	retval = 0;exit:	kfree (transfer_buffer);	return retval;}

⌨️ 快捷键说明

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