Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e8cf775 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman Committed by Greg Kroah-Hartman
Browse files

USB: add EPIC support to the io_edgeport driver



This patch adds EPiC support to the io_edgeport driver which adds
support for a number of NCR printers:
	- NCR (Axiohm) 7401-K580 printer
	- NCR (TEC) 7401-K590 printer, 7402-K592
	- NCR (TEC) 7167, 7168 printers
	- NCR (TEC) 7197, 7198, F306, F307, F309 printers
	- NCR (Axiohm) 7194 printer
	- NCR (Axiohm) 7158 printer
and a few more.

It is based on the 2.6.19 kernel.

Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 20b2e28f
Loading
Loading
Loading
Loading
+327 −82
Original line number Diff line number Diff line
@@ -146,6 +146,8 @@ struct edgeport_serial {
	struct edge_manuf_descriptor	manuf_descriptor;	/* the manufacturer descriptor */
	struct edge_boot_descriptor	boot_descriptor;	/* the boot firmware descriptor */
	struct edgeport_product_info	product_info;		/* Product Info */
	struct edge_compatibility_descriptor epic_descriptor;	/* Edgeport compatible descriptor */
	int			is_epic;			/* flag if EPiC device or not */

	__u8			interrupt_in_endpoint;		/* the interrupt endpoint handle */
	unsigned char *		interrupt_in_buffer;		/* the buffer we use for the interrupt endpoint */
@@ -397,6 +399,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen)
	unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2);

	kfree(pStringDesc);
	dbg("%s - USB String %s", __FUNCTION__, string);
	return strlen(string);
}

@@ -434,6 +437,34 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de
}
#endif

static void dump_product_info(struct edgeport_product_info *product_info)
{
	// 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);
	dbg("  EpicVer               %d", product_info->EpicVer);
}

static void get_product_info(struct edgeport_serial *edge_serial)
{
	struct edgeport_product_info *product_info = &edge_serial->product_info;
@@ -495,30 +526,60 @@ static void get_product_info(struct edgeport_serial *edge_serial)
			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);
	dump_product_info(product_info);
}

static int get_epic_descriptor(struct edgeport_serial *ep)
{
	int result;
	struct usb_serial *serial = ep->serial;
	struct edgeport_product_info *product_info = &ep->product_info;
	struct edge_compatibility_descriptor *epic = &ep->epic_descriptor;
	struct edge_compatibility_bits *bits;

	ep->is_epic = 0;
	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
				 USB_REQUEST_ION_GET_EPIC_DESC,
				 0xC0, 0x00, 0x00,
				 &ep->epic_descriptor,
				 sizeof(struct edge_compatibility_descriptor),
				 300);

	dbg("%s result = %d", __FUNCTION__, result);

	if (result > 0) {
		ep->is_epic = 1;
		memset(product_info, 0, sizeof(struct edgeport_product_info));

		product_info->NumPorts			= epic->NumPorts;
		product_info->ProdInfoVer		= 0;
		product_info->FirmwareMajorVersion	= epic->MajorVersion;
		product_info->FirmwareMinorVersion	= epic->MinorVersion;
		product_info->FirmwareBuildNumber	= epic->BuildNumber;
		product_info->iDownloadFile		= epic->iDownloadFile;
		product_info->EpicVer			= epic->EpicVer;
		product_info->Epic			= epic->Supports;
		product_info->ProductId			= ION_DEVICE_ID_EDGEPORT_COMPATIBLE;
		dump_product_info(product_info);

		bits = &ep->epic_descriptor.Supports;
		dbg("**EPIC descriptor:");
		dbg("  VendEnableSuspend: %s", bits->VendEnableSuspend	? "TRUE": "FALSE");
		dbg("  IOSPOpen         : %s", bits->IOSPOpen		? "TRUE": "FALSE" );
		dbg("  IOSPClose        : %s", bits->IOSPClose		? "TRUE": "FALSE" );
		dbg("  IOSPChase        : %s", bits->IOSPChase		? "TRUE": "FALSE" );
		dbg("  IOSPSetRxFlow    : %s", bits->IOSPSetRxFlow	? "TRUE": "FALSE" );
		dbg("  IOSPSetTxFlow    : %s", bits->IOSPSetTxFlow	? "TRUE": "FALSE" );
		dbg("  IOSPSetXChar     : %s", bits->IOSPSetXChar	? "TRUE": "FALSE" );
		dbg("  IOSPRxCheck      : %s", bits->IOSPRxCheck	? "TRUE": "FALSE" );
		dbg("  IOSPSetClrBreak  : %s", bits->IOSPSetClrBreak	? "TRUE": "FALSE" );
		dbg("  IOSPWriteMCR     : %s", bits->IOSPWriteMCR	? "TRUE": "FALSE" );
		dbg("  IOSPWriteLCR     : %s", bits->IOSPWriteLCR	? "TRUE": "FALSE" );
		dbg("  IOSPSetBaudRate  : %s", bits->IOSPSetBaudRate	? "TRUE": "FALSE" );
		dbg("  TrueEdgeport     : %s", bits->TrueEdgeport	? "TRUE": "FALSE" );
	}

	return result;
}


@@ -1017,6 +1078,9 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)

	edge_port->closePending = TRUE;

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPChase))) {
		/* flush and chase */
		edge_port->chaseResponsePending = TRUE;

@@ -1028,10 +1092,15 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
		} else {
			edge_port->chaseResponsePending = FALSE;
		}
	}

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPClose))) {
	       /* close the port */
		dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__);
		send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
	}

	//port->close = TRUE;
	edge_port->closePending = FALSE;
@@ -1694,8 +1763,12 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
static void edge_break (struct usb_serial_port *port, int break_state)
{
	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
	struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial);
	int status;

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPChase))) {
		/* flush and chase */
		edge_port->chaseResponsePending = TRUE;

@@ -1707,7 +1780,11 @@ static void edge_break (struct usb_serial_port *port, int break_state)
		} else {
			edge_port->chaseResponsePending = FALSE;
		}
	}

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) {
		if (break_state == -1) {
			dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__);
			status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0);
@@ -1718,6 +1795,7 @@ static void edge_break (struct usb_serial_port *port, int break_state)
		if (status) {
			dbg("%s - error sending break set/clear command.", __FUNCTION__);
		}
	}

	return;
}
@@ -2288,6 +2366,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer
 *****************************************************************************/
static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
	unsigned char *cmdBuffer;
	unsigned char *currCmd;
	int cmdLen = 0;
@@ -2295,6 +2374,14 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
	int status;
	unsigned char number = edge_port->port->number - edge_port->port->serial->minor;

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) {
		dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d",
		    edge_port->port->number, baudRate);
		return 0;
	}

	dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate);

	status = calc_baud_rate_divisor (baudRate, &divisor);
@@ -2374,6 +2461,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor)
 *****************************************************************************/
static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
	unsigned char *cmdBuffer;
	unsigned char *currCmd;
	unsigned long cmdLen = 0;
@@ -2381,6 +2469,22 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r

	dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue);

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) &&
	     (regNum == MCR))) {
		dbg("SendCmdWriteUartReg - Not writting to MCR Register");
		return 0;
	}

	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) &&
	     (regNum == LCR))) {
		dbg ("SendCmdWriteUartReg - Not writting to LCR Register");
		return 0;
	}

	// Alloc memory for the string of commands.
	cmdBuffer = kmalloc (0x10, GFP_ATOMIC);
	if (cmdBuffer == NULL ) {
@@ -2414,6 +2518,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
#endif
static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
	struct tty_struct *tty;
	int baud;
	unsigned cflag;
@@ -2494,8 +2599,12 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
		unsigned char stop_char  = STOP_CHAR(tty);
		unsigned char start_char = START_CHAR(tty);

		if ((!edge_serial->is_epic) ||
		    ((edge_serial->is_epic) &&
		     (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) {
			send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char);
			send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char);
		}

		/* if we are implementing INBOUND XON/XOFF */
		if (I_IXOFF(tty)) {
@@ -2515,7 +2624,13 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
	}

	/* Set flow control to the configured value */
	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow)))
		send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow);
	if ((!edge_serial->is_epic) ||
	    ((edge_serial->is_epic) &&
	     (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow)))
		send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow);


@@ -2728,6 +2843,13 @@ static int edge_startup (struct usb_serial *serial)
	struct edgeport_port *edge_port;
	struct usb_device *dev;
	int i, j;
	int response;
	int interrupt_in_found;
	int bulk_in_found;
	int bulk_out_found;
	static __u32 descriptor[3] = {	EDGE_COMPATIBILITY_MASK0,
					EDGE_COMPATIBILITY_MASK1,
					EDGE_COMPATIBILITY_MASK2 };

	dev = serial->dev;

@@ -2750,6 +2872,12 @@ static int edge_startup (struct usb_serial *serial)

	dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);

	/* Read the epic descriptor */
	if (get_epic_descriptor(edge_serial) <= 0) {
		/* memcpy descriptor to Supports structures */
		memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
		       sizeof(struct edge_compatibility_bits));

		/* get the manufacturing descriptor for this device */
		get_manufacturing_desc (edge_serial);

@@ -2757,18 +2885,23 @@ static int edge_startup (struct usb_serial *serial)
		get_boot_desc (edge_serial);

		get_product_info(edge_serial);
	}

	/* set the number of ports from the manufacturing description */
	/* serial->num_ports = serial->product_info.NumPorts; */
	if (edge_serial->product_info.NumPorts != serial->num_ports) {
		warn("%s - Device Reported %d serial ports vs core "
		     "thinking we have %d ports, email greg@kroah.com this info.",
		     __FUNCTION__, edge_serial->product_info.NumPorts, 
	if ((!edge_serial->is_epic) &&
	    (edge_serial->product_info.NumPorts != serial->num_ports)) {
		dev_warn(&serial->dev->dev, "Device Reported %d serial ports "
			 "vs. core thinking we have %d ports, email "
			 "greg@kroah.com this information.",
			 edge_serial->product_info.NumPorts,
			 serial->num_ports);
	}

	dbg("%s - time 1 %ld", __FUNCTION__, jiffies);

	/* If not an EPiC device */
	if (!edge_serial->is_epic) {
		/* now load the application firmware into this device */
		load_application_firmware (edge_serial);

@@ -2782,6 +2915,7 @@ static int edge_startup (struct usb_serial *serial)
		/* set the configuration to use #1 */
//		dbg("set_configuration 1");
//		usb_set_configuration (dev, 1);
	}

	/* we set up the pointers to the endpoints in the edge_open function, 
	 * as the structures aren't created yet. */
@@ -2805,7 +2939,100 @@ static int edge_startup (struct usb_serial *serial)
		usb_set_serial_port_data(serial->port[i], edge_port);
	}

	return 0;
	response = 0;

	if (edge_serial->is_epic) {
		/* EPIC thing, set up our interrupt polling now and our read urb, so
		 * that the device knows it really is connected. */
		interrupt_in_found = bulk_in_found = bulk_out_found = FALSE;
		for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) {
			struct usb_endpoint_descriptor *endpoint;
			int buffer_size;

			endpoint = &serial->interface->altsetting[0].endpoint[i].desc;
			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
			if ((!interrupt_in_found) &&
			    (usb_endpoint_is_int_in(endpoint))) {
				/* we found a interrupt in endpoint */
				dbg("found interrupt in");

				/* not set up yet, so do it now */
				edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL);
				if (!edge_serial->interrupt_read_urb) {
					err("out of memory");
					return -ENOMEM;
				}
				edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
				if (!edge_serial->interrupt_in_buffer) {
					err("out of memory");
					usb_free_urb(edge_serial->interrupt_read_urb);
					return -ENOMEM;
				}
				edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress;

				/* set up our interrupt urb */
				usb_fill_int_urb(edge_serial->interrupt_read_urb,
						 dev,
						 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
						 edge_serial->interrupt_in_buffer,
						 buffer_size,
						 edge_interrupt_callback,
						 edge_serial,
						 endpoint->bInterval);

				interrupt_in_found = TRUE;
			}

			if ((!bulk_in_found) &&
			    (usb_endpoint_is_bulk_in(endpoint))) {
				/* we found a bulk in endpoint */
				dbg("found bulk in");

				/* not set up yet, so do it now */
				edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL);
				if (!edge_serial->read_urb) {
					err("out of memory");
					return -ENOMEM;
				}
				edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
				if (!edge_serial->bulk_in_buffer) {
					err ("out of memory");
					usb_free_urb(edge_serial->read_urb);
					return -ENOMEM;
				}
				edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress;

				/* set up our bulk in urb */
				usb_fill_bulk_urb(edge_serial->read_urb, dev,
						  usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
						  edge_serial->bulk_in_buffer,
						  endpoint->wMaxPacketSize,
						  edge_bulk_in_callback,
						  edge_serial);
				bulk_in_found = TRUE;
			}

			if ((!bulk_out_found) &&
			    (usb_endpoint_is_bulk_out(endpoint))) {
				/* we found a bulk out endpoint */
				dbg("found bulk out");
				edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress;
				bulk_out_found = TRUE;
			}
		}

		if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) {
			err ("Error - the proper endpoints were not found!");
			return -ENODEV;
		}

		/* start interrupt read for this edgeport this interrupt will
		 * continue as long as the edgeport is connected */
		response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL);
		if (response)
			err("%s - Error %d submitting control urb", __FUNCTION__, response);
	}
	return response;
}


@@ -2815,6 +3042,7 @@ static int edge_startup (struct usb_serial *serial)
 ****************************************************************************/
static void edge_shutdown (struct usb_serial *serial)
{
	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
	int i;

	dbg("%s", __FUNCTION__);
@@ -2824,7 +3052,18 @@ static void edge_shutdown (struct usb_serial *serial)
		kfree (usb_get_serial_port_data(serial->port[i]));
		usb_set_serial_port_data(serial->port[i],  NULL);
	}
	kfree (usb_get_serial_data(serial));
	/* free up our endpoint stuff */
	if (edge_serial->is_epic) {
		usb_unlink_urb(edge_serial->interrupt_read_urb);
		usb_free_urb(edge_serial->interrupt_read_urb);
		kfree(edge_serial->interrupt_in_buffer);

		usb_unlink_urb(edge_serial->read_urb);
		usb_free_urb(edge_serial->read_urb);
		kfree(edge_serial->bulk_in_buffer);
	}

	kfree(edge_serial);
	usb_set_serial_data(serial, NULL);
}

@@ -2846,6 +3085,9 @@ static int __init edgeport_init(void)
	retval = usb_serial_register(&edgeport_8port_device);
	if (retval)
		goto failed_8port_device_register;
	retval = usb_serial_register(&epic_device);
	if (retval)
		goto failed_epic_device_register;
	retval = usb_register(&io_driver);
	if (retval) 
		goto failed_usb_register;
@@ -2853,6 +3095,8 @@ static int __init edgeport_init(void)
	return 0;

failed_usb_register:
	usb_serial_deregister(&epic_device);
failed_epic_device_register:
	usb_serial_deregister(&edgeport_8port_device);
failed_8port_device_register:
	usb_serial_deregister(&edgeport_4port_device);
@@ -2873,6 +3117,7 @@ static void __exit edgeport_exit (void)
	usb_serial_deregister (&edgeport_2port_device);
	usb_serial_deregister (&edgeport_4port_device);
	usb_serial_deregister (&edgeport_8port_device);
	usb_serial_deregister (&epic_device);
}

module_init(edgeport_init);
+4 −2
Original line number Diff line number Diff line
@@ -111,10 +111,12 @@ struct edgeport_product_info {
	__le16	FirmwareBuildNumber;		/*				zzzz (LE format) */

	__u8	ManufactureDescDate[3];		/* MM/DD/YY when descriptor template was compiled */
	__u8	Unused1[1];			/* Available */
	__u8	HardwareType;

	__u8	iDownloadFile;			/* What to download to EPiC device */
	__u8	Unused2[2];			/* Available */
	__u8	EpicVer;			/* What version of EPiC spec this device supports */

	struct edge_compatibility_bits Epic;
};

/*
+50 −0
Original line number Diff line number Diff line
@@ -47,6 +47,18 @@ static struct usb_device_id edgeport_8port_id_table [] = {
	{ }
};

static struct usb_device_id Epic_port_id_table [] = {
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) },
	{ }
};

/* Devices that this driver supports */
static struct usb_device_id id_table_combined [] = {
	{ USB_DEVICE(USB_VENDOR_ID_ION,	ION_DEVICE_ID_EDGEPORT_4) },
@@ -70,6 +82,14 @@ static struct usb_device_id id_table_combined [] = {
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) },
	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) },
	{ USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) },
	{ USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) },
	{ }							/* Terminating entry */
};

@@ -165,5 +185,35 @@ static struct usb_serial_driver edgeport_8port_device = {
	.write_bulk_callback	= edge_bulk_out_data_callback,
};

static struct usb_serial_driver epic_device = {
	.driver = {
		.owner		= THIS_MODULE,
		.name		= "epic",
	},
	.description		= "EPiC device",
	.id_table		= Epic_port_id_table,
	.num_interrupt_in	= 1,
	.num_bulk_in		= 1,
	.num_bulk_out		= 1,
	.num_ports		= 1,
	.open			= edge_open,
	.close			= edge_close,
	.throttle		= edge_throttle,
	.unthrottle		= edge_unthrottle,
	.attach			= edge_startup,
	.shutdown		= edge_shutdown,
	.ioctl			= edge_ioctl,
	.set_termios		= edge_set_termios,
	.tiocmget		= edge_tiocmget,
	.tiocmset		= edge_tiocmset,
	.write			= edge_write,
	.write_room		= edge_write_room,
	.chars_in_buffer	= edge_chars_in_buffer,
	.break_ctl		= edge_break,
	.read_int_callback	= edge_interrupt_callback,
	.read_bulk_callback	= edge_bulk_in_callback,
	.write_bulk_callback	= edge_bulk_out_data_callback,
};

#endif
+5 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#define	USB_VENDOR_ID_ION	0x1608		// Our VID
#define	USB_VENDOR_ID_TI	0x0451		// TI VID
#define USB_VENDOR_ID_AXIOHM	0x05D9		/* Axiohm VID */

//
// Definitions of USB product IDs (PID)
@@ -334,6 +335,10 @@ struct edge_compatibility_bits

};

#define EDGE_COMPATIBILITY_MASK0	0x0001
#define EDGE_COMPATIBILITY_MASK1	0x3FFF
#define EDGE_COMPATIBILITY_MASK2	0x0001

struct edge_compatibility_descriptor
{
	__u8	Length;				// Descriptor Length (per USB spec)