📄 whiteheat.c
字号:
retval = usb_submit_urb(port->read_urb); if (retval) { err(__FUNCTION__ " - failed submitting read urb, error %d", retval); goto error_exit; } /* send an open port command */ /* firmware uses 1 based port numbering */ open_command.port = port->number - port->serial->minor + 1; retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command)); if (retval) goto error_exit; /* Need to do device specific setup here (control lines, baud rate, etc.) */ /* FIXME!!! */ } dbg(__FUNCTION__ " - exit"); up (&port->sem); return retval;error_exit: --port->open_count; MOD_DEC_USE_COUNT; dbg(__FUNCTION__ " - error_exit"); up (&port->sem); return retval;}static void whiteheat_close(struct usb_serial_port *port, struct file * filp){ struct whiteheat_min_set close_command; dbg(__FUNCTION__ " - port %d", port->number); down (&port->sem); --port->open_count; if (port->open_count <= 0) { /* 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); port->active = 0; } MOD_DEC_USE_COUNT; up (&port->sem);}static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg){ dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", 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(__FUNCTION__ " -port %d", port->number); down (&port->sem); if ((!port->tty) || (!port->tty->termios)) { dbg(__FUNCTION__" - no tty structures"); 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(__FUNCTION__ " - nothing to change..."); 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(__FUNCTION__ " - data bits = %d", 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(__FUNCTION__ " - parity = %c", port_settings.parity); /* figure out the stop bits requested */ if (cflag & CSTOPB) port_settings.stop = 2; else port_settings.stop = 1; dbg(__FUNCTION__ " - stop bits = %d", 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(__FUNCTION__ " - hardware flow control = %s %s %s %s", (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(__FUNCTION__ " - software flow control = %c", port_settings.sflow); port_settings.xon = START_CHAR(port->tty); port_settings.xoff = STOP_CHAR(port->tty); dbg(__FUNCTION__ " - XON = %2x, XOFF = %2x", port_settings.xon, port_settings.xoff); /* get the baud rate wanted */ port_settings.baud = tty_get_baud_rate(port->tty); dbg(__FUNCTION__ " - baud rate = %d", 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: up (&port->sem); return;}static void whiteheat_throttle (struct usb_serial_port *port){ dbg(__FUNCTION__" - port %d", port->number); /* Change the control signals */ /* FIXME!!! */ return;}static void whiteheat_unthrottle (struct usb_serial_port *port){ dbg(__FUNCTION__" - port %d", 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_startup (struct usb_serial *serial){ int response; const struct whiteheat_hex_record *record; dbg(__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(__FUNCTION__ " - ezusb_writememory failed for loader (%d %04X %p %d)", 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(__FUNCTION__ " - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 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(__FUNCTION__" - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 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 void whiteheat_shutdown (struct usb_serial *serial){ struct usb_serial_port *command_port; int i; dbg(__FUNCTION__); /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { while (serial->port[i].open_count > 0) { whiteheat_close (&serial->port[i], NULL); } } /* 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_VERSION ":" DRIVER_DESC); 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 + -