📄 usb-serial.c
字号:
} if (!serial->type) { dbg("serial->type == NULL!"); return (-ENODEV); } /* make the tty driver remember our serial object, and us it */ tty->driver_data = serial; serial->tty = tty; /* pass on to the driver specific version of this function */ if (serial->type->open) { return (serial->type->open(tty, filp)); } return (0);}static void serial_close(struct tty_struct *tty, struct file * filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("serial_close"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return; } if (!serial->type) { dbg("serial->type == NULL!"); return; } if (!serial->present) { dbg("no device registered"); return; } if (!serial->active) { dbg ("device already open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->close) { serial->type->close(tty, filp); }} static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("serial_write"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return (-ENODEV); } if (!serial->type) { dbg("serial->type == NULL!"); return (-ENODEV); } if (!serial->present) { dbg("device not registered"); return (-EINVAL); } if (!serial->active) { dbg ("device not opened"); return (-EINVAL); } /* pass on to the driver specific version of this function */ if (serial->type->write) { return (serial->type->write(tty, from_user, buf, count)); } /* no specific driver, so return that we didn't write anything */ return (0);}static void serial_put_char (struct tty_struct *tty, unsigned char ch){ struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; dbg("serial_put_char"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return; } if (!serial->type) { dbg("serial->type == NULL!"); return; } if (!serial->present) { dbg("no device registered"); return; } if (!serial->active) { dbg ("device not open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->put_char) { serial->type->put_char(tty, ch); } return;} static int serial_write_room (struct tty_struct *tty) { struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; dbg("serial_write_room"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return (-ENODEV); } if (!serial->type) { dbg("serial->type == NULL!"); return (-ENODEV); } if (!serial->present) { dbg("no device registered"); return (-EINVAL); } if (!serial->active) { dbg ("device not open"); return (-EINVAL); } /* pass on to the driver specific version of this function */ if (serial->type->write_room) { return (serial->type->write_room(tty)); } return (0);}static int serial_chars_in_buffer (struct tty_struct *tty) { struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; dbg("serial_chars_in_buffer"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return (-ENODEV); } if (!serial->type) { dbg("serial->type == NULL!"); return (-ENODEV); } if (!serial->present) { dbg("no device registered"); return (-EINVAL); } if (!serial->active) { dbg ("device not open"); return (-EINVAL); } /* pass on to the driver specific version of this function */ if (serial->type->chars_in_buffer) { return (serial->type->chars_in_buffer(tty)); } return (0);}static void serial_throttle (struct tty_struct * tty){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("serial_throttle"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return; } if (!serial->type) { dbg("serial->type == NULL!"); return; } if (!serial->present) { dbg("no device registered"); return; } if (!serial->active) { dbg ("device not open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->throttle) { serial->type->throttle(tty); } return;}static void serial_unthrottle (struct tty_struct * tty){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("serial_unthrottle"); /* do some sanity checking that we really have a device present */ if (!serial) { dbg("serial == NULL!"); return; } if (!serial->type) { dbg("serial->type == NULL!"); return; } if (!serial->present) { dbg("no device registered"); return; } if (!serial->active) { dbg ("device not open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->unthrottle) { serial->type->unthrottle(tty); } return;}#if defined(CONFIG_USB_SERIAL_BELKIN) || defined(CONFIG_USB_SERIAL_PERACOM)/***************************************************************************** * eTek specific driver functions *****************************************************************************/static int etek_serial_open (struct tty_struct *tty, struct file *filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("etek_serial_open"); if (!serial->present) { dbg("no device registered"); return -EINVAL; } if (serial->active) { dbg ("device already open"); return -EINVAL; } serial->active = 1; /*Start reading from the device*/ if (usb_submit_urb(&serial->read_urb)) dbg("usb_submit_urb(read bulk) failed"); /* Need to do device specific setup here (control lines, baud rate, etc.) */ /* FIXME!!! */ return (0);}static void etek_serial_close(struct tty_struct *tty, struct file * filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("etek_serial_close"); /* Need to change the control lines here */ /* FIXME */ /* shutdown our bulk reads and writes */ usb_unlink_urb (&serial->write_urb); usb_unlink_urb (&serial->read_urb); serial->active = 0;}#endif /* defined(CONFIG_USB_SERIAL_BELKIN) || defined(CONFIG_USB_SERIAL_PERACOM) */#ifdef CONFIG_USB_SERIAL_WHITEHEAT/***************************************************************************** * Connect Tech's White Heat specific driver functions *****************************************************************************/static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("whiteheat_serial_open"); if (!serial->present) { dbg("no device registered"); return -EINVAL; } if (serial->active) { dbg ("device already open"); return -EINVAL; } serial->active = 1; /*Start reading from the device*/ if (usb_submit_urb(&serial->read_urb)) dbg("usb_submit_urb(read bulk) failed"); /* Need to do device specific setup here (control lines, baud rate, etc.) */ /* FIXME!!! */ return (0);}static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("whiteheat_serial_close"); /* Need to change the control lines here */ /* FIXME */ /* shutdown our bulk reads and writes */ usb_unlink_urb (&serial->write_urb); usb_unlink_urb (&serial->read_urb); serial->active = 0;}static void whiteheat_throttle (struct tty_struct * tty){ dbg("whiteheat_throttle"); /* Change the control signals */ /* FIXME!!! */ return;}static void whiteheat_unthrottle (struct tty_struct * tty){ dbg("whiteheat_unthrottle"); /* Change the control signals */ /* FIXME!!! */ return;}static int whiteheat_writememory (struct usb_serial_state *serial, int address, unsigned char *data, int length, __u8 bRequest){ int result; unsigned char *transfer_buffer = kmalloc (length, GFP_KERNEL); if (!transfer_buffer) { err("whiteheat_writememory: kmalloc(%d) failed.\n", length); return -ENOMEM; } memcpy (transfer_buffer, data, length); result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 300); kfree (transfer_buffer); return result;}/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */#define CPUCS_REG 0x7F92static int whiteheat_set_reset (struct usb_serial_state *serial, unsigned char reset_bit){ dbg("whiteheat_set_reset: %d", reset_bit); return (whiteheat_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0));}/* 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_state *serial){ int response; const struct whiteheat_hex_record *record; dbg("whiteheat_startup\n"); response = whiteheat_set_reset (serial, 1); record = &whiteheat_loader[0]; while (record->address != 0xffff) { response = whiteheat_writememory (serial, record->address, (unsigned char *)record->data, record->data_size, 0xa0); if (response < 0) { err("whiteheat_writememory failed for loader (%d %04X %p %d)", response, record->address, record->data, record->data_size); break; } ++record; } response = whiteheat_set_reset (serial, 0); record = &whiteheat_firmware[0]; while (record->address < 0x8000) { ++record; } while (record->address != 0xffff) { response = whiteheat_writememory (serial, record->address, (unsigned char *)record->data, record->data_size, 0xa3); if (response < 0) { err("whiteheat_writememory failed for first firmware step (%d %04X %p %d)", response, record->address, record->data, record->data_size); break; } ++record; } response = whiteheat_set_reset (serial, 1); record = &whiteheat_firmware[0]; while (record->address < 0x8000) { response = whiteheat_writememory (serial, record->address, (unsigned char *)record->data, record->data_size, 0xa0); if (response < 0) { err("whiteheat_writememory failed for first firmware step (%d %04X %p %d)\n", response, record->address, record->data, record->data_size); break; } ++record; } response = whiteheat_set_reset (serial, 0); /* we want this device to fail to have a driver assigned to it. */ return (1);}#endif /* CONFIG_USB_SERIAL_WHITEHEAT */#ifdef CONFIG_USB_SERIAL_VISOR/****************************************************************************** * Handspring Visor specific driver functions ******************************************************************************/static int visor_serial_open (struct tty_struct *tty, struct file *filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("visor_serial_open"); if (!serial->present) { dbg("no device registered"); return -EINVAL; } if (serial->active) { dbg ("device already open"); return -EINVAL; } serial->active = 1; /*Start reading from the device*/ if (usb_submit_urb(&serial->read_urb)) dbg("usb_submit_urb(read bulk) failed"); return (0);}static void visor_serial_close(struct tty_struct *tty, struct file * filp){ struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; dbg("USB: visor_serial_close"); /* shutdown our bulk reads and writes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -