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

📄 io_edgeport.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	unicode_to_ascii(string,  pStringDesc->wData,     pStringDesc->bLength/2-1);	kfree(pStringDesc);	return strlen(string);}#if 0/************************************************************************ * *  Get string descriptor from device * ************************************************************************/static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc){	struct usb_string_descriptor StringDesc;	struct usb_string_descriptor *pStringDesc;	dbg("%s - USB String ID = %d", __FUNCTION__, Id );	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {		return 0;	}	pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);	if (!pStringDesc) {		return -1;	}	if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {		kfree(pStringDesc);		return -1;	}	*pRetDesc = pStringDesc;	return 0;}#endifstatic void get_product_info(struct edgeport_serial *edge_serial){	struct edgeport_product_info *product_info = &edge_serial->product_info;	memset (product_info, 0, sizeof(struct edgeport_product_info));	product_info->ProductId		= (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);	product_info->NumPorts		= edge_serial->manuf_descriptor.NumPorts;	product_info->ProdInfoVer	= 0;	product_info->RomSize		= edge_serial->manuf_descriptor.RomSize;	product_info->RamSize		= edge_serial->manuf_descriptor.RamSize;	product_info->CpuRev		= edge_serial->manuf_descriptor.CpuRev;	product_info->BoardRev		= edge_serial->manuf_descriptor.BoardRev;	product_info->BootMajorVersion	= edge_serial->boot_descriptor.MajorVersion;	product_info->BootMinorVersion	= edge_serial->boot_descriptor.MinorVersion;	product_info->BootBuildNumber	= edge_serial->boot_descriptor.BuildNumber;	memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));	// check if this is 2nd generation hardware	if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {		product_info->FirmwareMajorVersion	= OperationalCodeImageVersion_GEN2.MajorVersion;		product_info->FirmwareMinorVersion	= OperationalCodeImageVersion_GEN2.MinorVersion;		product_info->FirmwareBuildNumber	= cpu_to_le16(OperationalCodeImageVersion_GEN2.BuildNumber);		product_info->iDownloadFile		= EDGE_DOWNLOAD_FILE_80251;	} else {		product_info->FirmwareMajorVersion	= OperationalCodeImageVersion_GEN1.MajorVersion;		product_info->FirmwareMinorVersion	= OperationalCodeImageVersion_GEN1.MinorVersion;		product_info->FirmwareBuildNumber	= cpu_to_le16(OperationalCodeImageVersion_GEN1.BuildNumber);		product_info->iDownloadFile		= EDGE_DOWNLOAD_FILE_I930;	}	// Determine Product type and set appropriate flags	switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) {		case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:		case ION_DEVICE_ID_EDGEPORT_4T:		case ION_DEVICE_ID_EDGEPORT_4:		case ION_DEVICE_ID_EDGEPORT_2:		case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:		case ION_DEVICE_ID_EDGEPORT_8:		case ION_DEVICE_ID_EDGEPORT_421:		case ION_DEVICE_ID_EDGEPORT_21:		case ION_DEVICE_ID_EDGEPORT_2_DIN:		case ION_DEVICE_ID_EDGEPORT_4_DIN:		case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:			product_info->IsRS232 = 1;			break;		case ION_DEVICE_ID_EDGEPORT_2I:				   // Edgeport/2 RS422/RS485			product_info->IsRS422 = 1;			product_info->IsRS485 = 1;			break;		case ION_DEVICE_ID_EDGEPORT_8I:				   // Edgeport/4 RS422		case ION_DEVICE_ID_EDGEPORT_4I:				   // Edgeport/4 RS422			product_info->IsRS422 = 1;			break;	}	// Dump Product Info structure	dbg("**Product Information:");	dbg("  ProductId             %x", product_info->ProductId );	dbg("  NumPorts              %d", product_info->NumPorts );	dbg("  ProdInfoVer           %d", product_info->ProdInfoVer );	dbg("  IsServer              %d", product_info->IsServer);	dbg("  IsRS232               %d", product_info->IsRS232 );	dbg("  IsRS422               %d", product_info->IsRS422 );	dbg("  IsRS485               %d", product_info->IsRS485 );	dbg("  RomSize               %d", product_info->RomSize );	dbg("  RamSize               %d", product_info->RamSize );	dbg("  CpuRev                %x", product_info->CpuRev  );	dbg("  BoardRev              %x", product_info->BoardRev);	dbg("  BootMajorVersion      %d.%d.%d", product_info->BootMajorVersion,	    product_info->BootMinorVersion,	    le16_to_cpu(product_info->BootBuildNumber));	dbg("  FirmwareMajorVersion  %d.%d.%d", product_info->FirmwareMajorVersion,	    product_info->FirmwareMinorVersion,	    le16_to_cpu(product_info->FirmwareBuildNumber));	dbg("  ManufactureDescDate   %d/%d/%d", product_info->ManufactureDescDate[0],	    product_info->ManufactureDescDate[1],	    product_info->ManufactureDescDate[2]+1900);	dbg("  iDownloadFile         0x%x",     product_info->iDownloadFile);}/************************************************************************//************************************************************************//*            U S B  C A L L B A C K   F U N C T I O N S                *//*            U S B  C A L L B A C K   F U N C T I O N S                *//************************************************************************//************************************************************************//***************************************************************************** * edge_interrupt_callback *	this is the callback function for when we have received data on the  *	interrupt endpoint. *****************************************************************************/static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;	struct edgeport_port *edge_port;	struct usb_serial_port *port;	unsigned char *data = urb->transfer_buffer;	int length = urb->actual_length;	int bytes_avail;	int position;	int txCredits;	int portNumber;	int result;	dbg("%s", __FUNCTION__);	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;	}	// process this interrupt-read even if there are no ports open	if (length) {		usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, length, data);		if (length > 1) {			bytes_avail = data[0] | (data[1] << 8);			if (bytes_avail) {				spin_lock(&edge_serial->es_lock);				edge_serial->rxBytesAvail += bytes_avail;				dbg("%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d", __FUNCTION__, bytes_avail, edge_serial->rxBytesAvail, edge_serial->read_in_progress);				if (edge_serial->rxBytesAvail > 0 &&				    !edge_serial->read_in_progress) {					dbg("%s - posting a read", __FUNCTION__);					edge_serial->read_in_progress = TRUE;					/* we have pending bytes on the bulk in pipe, send a request */					edge_serial->read_urb->dev = edge_serial->serial->dev;					result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);					if (result) {						dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __FUNCTION__, result);						edge_serial->read_in_progress = FALSE;					}				}				spin_unlock(&edge_serial->es_lock);			}		}		/* grab the txcredits for the ports if available */		position = 2;		portNumber = 0;		while ((position < length) && (portNumber < edge_serial->serial->num_ports)) {			txCredits = data[position] | (data[position+1] << 8);			if (txCredits) {				port = edge_serial->serial->port[portNumber];				edge_port = usb_get_serial_port_data(port);				if (edge_port->open) {					spin_lock(&edge_port->ep_lock);					edge_port->txCredits += txCredits;					spin_unlock(&edge_port->ep_lock);					dbg("%s - txcredits for port%d = %d", __FUNCTION__, portNumber, edge_port->txCredits);					/* tell the tty driver that something has changed */					if (edge_port->port->tty)						tty_wakeup(edge_port->port->tty);					// Since we have more credit, check if more data can be sent					send_more_port_data(edge_serial, edge_port);				}			}			position += 2;			++portNumber;		}	}exit:	result = usb_submit_urb (urb, GFP_ATOMIC);	if (result) {		dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __FUNCTION__, result);	}}/***************************************************************************** * edge_bulk_in_callback *	this is the callback function for when we have received data on the  *	bulk in endpoint. *****************************************************************************/static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;	unsigned char		*data = urb->transfer_buffer;	int			status;	__u16			raw_data_length;	dbg("%s", __FUNCTION__);	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);		edge_serial->read_in_progress = FALSE;		return;	}	if (urb->actual_length == 0) {		dbg("%s - read bulk callback with no data", __FUNCTION__);		edge_serial->read_in_progress = FALSE;		return;	}	raw_data_length = urb->actual_length;	usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __FUNCTION__, raw_data_length, data);	spin_lock(&edge_serial->es_lock);	/* decrement our rxBytes available by the number that we just got */	edge_serial->rxBytesAvail -= raw_data_length;	dbg("%s - Received = %d, rxBytesAvail %d", __FUNCTION__, raw_data_length, edge_serial->rxBytesAvail);	process_rcvd_data (edge_serial, data, urb->actual_length);	/* check to see if there's any more data for us to read */	if (edge_serial->rxBytesAvail > 0) {		dbg("%s - posting a read", __FUNCTION__);		edge_serial->read_urb->dev = edge_serial->serial->dev;		status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);		if (status) {			dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status);			edge_serial->read_in_progress = FALSE;		}	} else {		edge_serial->read_in_progress = FALSE;	}	spin_unlock(&edge_serial->es_lock);}/***************************************************************************** * edge_bulk_out_data_callback *	this is the callback function for when we have finished sending serial data *	on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	struct tty_struct *tty;	dbg("%s", __FUNCTION__);	if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);	}	tty = edge_port->port->tty;	if (tty && edge_port->open) {		/* let the tty driver wakeup if it has a special write_wakeup function */		tty_wakeup(tty);	}	// Release the Write URB	edge_port->write_in_progress = FALSE;	// Check if more data needs to be sent	send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port);}/***************************************************************************** * BulkOutCmdCallback *	this is the callback function for when we have finished sending a command *	on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	struct tty_struct *tty;	int status = urb->status;	dbg("%s", __FUNCTION__);	CmdUrbs--;	dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs);	/* clean up the transfer buffer */	kfree(urb->transfer_buffer);	/* Free the command urb */	usb_free_urb (urb);	if (status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, status);		return;	}	/* Get pointer to tty */	tty = edge_port->port->tty;	/* tell the tty driver that something has changed */	if (tty && edge_port->open)		tty_wakeup(tty);	/* we have completed the command */	edge_port->commandPending = FALSE;	wake_up(&edge_port->wait_command);}/***************************************************************************** * Driver tty interface functions *****************************************************************************//***************************************************************************** * SerialOpen *	this function is called by the tty driver when a port is opened *	If successful, we return 0 *	Otherwise we return a negative error number. *****************************************************************************/static int edge_open (struct usb_serial_port *port, struct file * filp){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	struct usb_serial *serial;	struct edgeport_serial *edge_serial;	int response;	dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return -ENODEV;	if (port->tty)		port->tty->low_latency = low_latency;	/* see if we've set up our endpoint info yet (can't set it up in edge_startup	   as the structures were not set up at that time.) */	serial = port->serial;	edge_serial = usb_get_serial_data(serial);	if (edge_serial == NULL) {		return -ENODEV;	}	if (edge_serial->interrupt_in_buffer == NULL) {

⌨️ 快捷键说明

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