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

📄 whiteheat.c

📁 linux2.4.20下的针对三星公司的s3c2410的usb模块驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static void whiteheat_close(struct usb_serial_port *port, struct file * filp){	struct whiteheat_min_set	close_command;		dbg("%s - port %d", __FUNCTION__, port->number);		/* send a close command to the port */	/* firmware uses 1 based port numbering */	close_command.port = port->number - port->serial->minor + 1;	whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));	/* Need to change the control lines here */	/* FIXME */		/* shutdown our bulk reads and writes */	usb_unlink_urb (port->write_urb);	usb_unlink_urb (port->read_urb);}static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg){	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);	return -ENOIOCTLCMD;}static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios){	unsigned int cflag;	struct whiteheat_port_settings port_settings;	dbg("%s -port %d", __FUNCTION__, port->number);	if ((!port->tty) || (!port->tty->termios)) {		dbg("%s - no tty structures", __FUNCTION__);		goto exit;	}		cflag = port->tty->termios->c_cflag;	/* check that they really want us to change something */	if (old_termios) {		if ((cflag == old_termios->c_cflag) &&		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {			dbg("%s - nothing to change...", __FUNCTION__);			goto exit;		}	}	/* set the port number */	/* firmware uses 1 based port numbering */	port_settings.port = port->number + 1;	/* get the byte size */	switch (cflag & CSIZE) {		case CS5:	port_settings.bits = 5;   break;		case CS6:	port_settings.bits = 6;   break;		case CS7:	port_settings.bits = 7;   break;		default:		case CS8:	port_settings.bits = 8;   break;	}	dbg("%s - data bits = %d", __FUNCTION__, port_settings.bits);		/* determine the parity */	if (cflag & PARENB)		if (cflag & PARODD)			port_settings.parity = 'o';		else			port_settings.parity = 'e';	else		port_settings.parity = 'n';	dbg("%s - parity = %c", __FUNCTION__, port_settings.parity);	/* figure out the stop bits requested */	if (cflag & CSTOPB)		port_settings.stop = 2;	else		port_settings.stop = 1;	dbg("%s - stop bits = %d", __FUNCTION__, port_settings.stop);		/* figure out the flow control settings */	if (cflag & CRTSCTS)		port_settings.hflow = (WHITEHEAT_CTS_FLOW | WHITEHEAT_RTS_FLOW);	else		port_settings.hflow = 0;	dbg("%s - hardware flow control = %s %s %s %s", __FUNCTION__,	    (port_settings.hflow & WHITEHEAT_CTS_FLOW) ? "CTS" : "",	    (port_settings.hflow & WHITEHEAT_RTS_FLOW) ? "RTS" : "",	    (port_settings.hflow & WHITEHEAT_DSR_FLOW) ? "DSR" : "",	    (port_settings.hflow & WHITEHEAT_DTR_FLOW) ? "DTR" : "");		/* determine software flow control */	if (I_IXOFF(port->tty))		port_settings.sflow = 'b';	else		port_settings.sflow = 'n';	dbg("%s - software flow control = %c", __FUNCTION__, port_settings.sflow);		port_settings.xon = START_CHAR(port->tty);	port_settings.xoff = STOP_CHAR(port->tty);	dbg("%s - XON = %2x, XOFF = %2x", __FUNCTION__, port_settings.xon, port_settings.xoff);	/* get the baud rate wanted */	port_settings.baud = tty_get_baud_rate(port->tty);	dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);	/* handle any settings that aren't specified in the tty structure */	port_settings.lloop = 0;		/* now send the message to the device */	whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));	exit:	return;}static void whiteheat_throttle (struct usb_serial_port *port){	dbg("%s - port %d", __FUNCTION__, port->number);	/* Change the control signals */	/* FIXME!!! */	return;}static void whiteheat_unthrottle (struct usb_serial_port *port){	dbg("%s - port %d", __FUNCTION__, port->number);	/* Change the control signals */	/* FIXME!!! */	return;}/* steps to download the firmware to the WhiteHEAT device: - hold the reset (by writing to the reset bit of the CPUCS register) - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD - release the reset (by writing to the CPUCS register) - download the WH.HEX file for all addresses greater than 0x1b3f using   VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD - hold the reset - download the WH.HEX file for all addresses less than 0x1b40 using   VENDOR_REQUEST_ANCHOR_LOAD - release the reset - device renumerated itself and comes up as new device id with all   firmware download completed.*/static int whiteheat_fake_startup (struct usb_serial *serial){	int response;	const struct whiteheat_hex_record *record;		dbg("%s", __FUNCTION__);		response = ezusb_set_reset (serial, 1);	record = &whiteheat_loader[0];	while (record->address != 0xffff) {		response = ezusb_writememory (serial, record->address, 				(unsigned char *)record->data, record->data_size, 0xa0);		if (response < 0) {			err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",				__FUNCTION__, response, record->address, record->data, record->data_size);			break;		}		++record;	}	response = ezusb_set_reset (serial, 0);	record = &whiteheat_firmware[0];	while (record->address < 0x1b40) {		++record;	}	while (record->address != 0xffff) {		response = ezusb_writememory (serial, record->address, 				(unsigned char *)record->data, record->data_size, 0xa3);		if (response < 0) {			err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 				__FUNCTION__, response, record->address, record->data, record->data_size);			break;		}		++record;	}		response = ezusb_set_reset (serial, 1);	record = &whiteheat_firmware[0];	while (record->address < 0x1b40) {		response = ezusb_writememory (serial, record->address, 				(unsigned char *)record->data, record->data_size, 0xa0);		if (response < 0) {			err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 				__FUNCTION__, response, record->address, record->data, record->data_size);			break;		}		++record;	}	response = ezusb_set_reset (serial, 0);	/* we want this device to fail to have a driver assigned to it. */	return 1;}static int  whiteheat_real_startup (struct usb_serial *serial){	struct whiteheat_hw_info *hw_info;	int pipe;	int ret;	int alen;	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };	__u8 result[sizeof(*hw_info) + 1];	pipe = usb_rcvbulkpipe (serial->dev, 7);	usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);	/*	 * We ignore the return code. In the case where rmmod/insmod is	 * performed with a WhiteHEAT connected, the above times out	 * because the endpoint is already prepped, meaning the below succeeds	 * regardless. All other cases the above succeeds.	 */	pipe = usb_sndbulkpipe (serial->dev, 7);	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);	if (ret) {		err("%s: Couldn't send command [%d]", serial->type->name, ret);		goto error_out;	} else if (alen != sizeof(command)) {		err("%s: Send command incomplete [%d]", serial->type->name, alen);		goto error_out;	}	pipe = usb_rcvbulkpipe (serial->dev, 7);	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);	if (ret) {		err("%s: Couldn't get results [%d]", serial->type->name, ret);		goto error_out;	} else if (alen != sizeof(result)) {		err("%s: Get results incomplete [%d]", serial->type->name, alen);		goto error_out;	} else if (result[0] != command[0]) {		err("%s: Command failed [%d]", serial->type->name, result[0]);		goto error_out;	}	hw_info = (struct whiteheat_hw_info *)&result[1];	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);	return 0;error_out:	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);	/*	 * Return that we've claimed the interface. A failure here may be	 * due to interception by the command_callback routine or other	 * causes that don't mean that the firmware isn't running. This may	 * change in the future. Probably should actually.	 */	return 0;}static void whiteheat_real_shutdown (struct usb_serial *serial){	struct usb_serial_port *command_port;	dbg("%s", __FUNCTION__);	/* free up our private data for our command port */	command_port = &serial->port[COMMAND_PORT];	if (command_port->private != NULL) {		kfree (command_port->private);		command_port->private = NULL;	}	return;}static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command){	struct whiteheat_rdb_set rdb_command;		/* send a set rts command to the port */	/* firmware uses 1 based port numbering */	rdb_command.port = port->number - port->serial->minor + 1;	rdb_command.state = state;	whiteheat_send_cmd (port->serial, command, (__u8 *)&rdb_command, sizeof(rdb_command));}static inline void set_rts (struct usb_serial_port *port, unsigned char rts){	set_command (port, rts, WHITEHEAT_SET_RTS);}static inline void set_dtr (struct usb_serial_port *port, unsigned char dtr){	set_command (port, dtr, WHITEHEAT_SET_DTR);}static inline void set_break (struct usb_serial_port *port, unsigned char brk){	set_command (port, brk, WHITEHEAT_SET_BREAK);}static int __init whiteheat_init (void){	usb_serial_register (&whiteheat_fake_device);	usb_serial_register (&whiteheat_device);	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;}static void __exit whiteheat_exit (void){	usb_serial_deregister (&whiteheat_fake_device);	usb_serial_deregister (&whiteheat_device);}module_init(whiteheat_init);module_exit(whiteheat_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");

⌨️ 快捷键说明

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