diff options
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 104 |
1 files changed, 44 insertions, 60 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4066a468118a..7b1673a44077 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -271,26 +271,58 @@ static int debug; | |||
271 | static __u16 vendor = FTDI_VID; | 271 | static __u16 vendor = FTDI_VID; |
272 | static __u16 product; | 272 | static __u16 product; |
273 | 273 | ||
274 | struct ftdi_private { | ||
275 | ftdi_chip_type_t chip_type; | ||
276 | /* type of the device, either SIO or FT8U232AM */ | ||
277 | int baud_base; /* baud base clock for divisor setting */ | ||
278 | int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ | ||
279 | __u16 last_set_data_urb_value ; | ||
280 | /* the last data state set - needed for doing a break */ | ||
281 | int write_offset; /* This is the offset in the usb data block to write the serial data - | ||
282 | * it is different between devices | ||
283 | */ | ||
284 | int flags; /* some ASYNC_xxxx flags are supported */ | ||
285 | unsigned long last_dtr_rts; /* saved modem control outputs */ | ||
286 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | ||
287 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | ||
288 | __u8 rx_flags; /* receive state flags (throttling) */ | ||
289 | spinlock_t rx_lock; /* spinlock for receive state */ | ||
290 | struct delayed_work rx_work; | ||
291 | struct usb_serial_port *port; | ||
292 | int rx_processed; | ||
293 | unsigned long rx_bytes; | ||
294 | |||
295 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | ||
296 | |||
297 | int force_baud; /* if non-zero, force the baud rate to this value */ | ||
298 | int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ | ||
299 | |||
300 | spinlock_t tx_lock; /* spinlock for transmit state */ | ||
301 | unsigned long tx_bytes; | ||
302 | unsigned long tx_outstanding_bytes; | ||
303 | unsigned long tx_outstanding_urbs; | ||
304 | }; | ||
305 | |||
274 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 306 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
275 | struct ftdi_sio_quirk { | 307 | struct ftdi_sio_quirk { |
276 | int (*probe)(struct usb_serial *); | 308 | int (*probe)(struct usb_serial *); |
277 | void (*setup)(struct usb_serial *); /* Special settings during startup. */ | 309 | void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */ |
278 | }; | 310 | }; |
279 | 311 | ||
280 | static int ftdi_olimex_probe (struct usb_serial *serial); | 312 | static int ftdi_olimex_probe (struct usb_serial *serial); |
281 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial); | 313 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); |
282 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); | 314 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); |
283 | 315 | ||
284 | static struct ftdi_sio_quirk ftdi_olimex_quirk = { | 316 | static struct ftdi_sio_quirk ftdi_olimex_quirk = { |
285 | .probe = ftdi_olimex_probe, | 317 | .probe = ftdi_olimex_probe, |
286 | }; | 318 | }; |
287 | 319 | ||
288 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 320 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
289 | .setup = ftdi_USB_UIRT_setup, | 321 | .port_probe = ftdi_USB_UIRT_setup, |
290 | }; | 322 | }; |
291 | 323 | ||
292 | static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | 324 | static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { |
293 | .setup = ftdi_HE_TIRA1_setup, | 325 | .port_probe = ftdi_HE_TIRA1_setup, |
294 | }; | 326 | }; |
295 | 327 | ||
296 | /* | 328 | /* |
@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = { | |||
567 | #define THROTTLED 0x01 | 599 | #define THROTTLED 0x01 |
568 | #define ACTUALLY_THROTTLED 0x02 | 600 | #define ACTUALLY_THROTTLED 0x02 |
569 | 601 | ||
570 | struct ftdi_private { | ||
571 | ftdi_chip_type_t chip_type; | ||
572 | /* type of the device, either SIO or FT8U232AM */ | ||
573 | int baud_base; /* baud base clock for divisor setting */ | ||
574 | int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ | ||
575 | __u16 last_set_data_urb_value ; | ||
576 | /* the last data state set - needed for doing a break */ | ||
577 | int write_offset; /* This is the offset in the usb data block to write the serial data - | ||
578 | * it is different between devices | ||
579 | */ | ||
580 | int flags; /* some ASYNC_xxxx flags are supported */ | ||
581 | unsigned long last_dtr_rts; /* saved modem control outputs */ | ||
582 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | ||
583 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | ||
584 | __u8 rx_flags; /* receive state flags (throttling) */ | ||
585 | spinlock_t rx_lock; /* spinlock for receive state */ | ||
586 | struct delayed_work rx_work; | ||
587 | struct usb_serial_port *port; | ||
588 | int rx_processed; | ||
589 | unsigned long rx_bytes; | ||
590 | |||
591 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | ||
592 | |||
593 | int force_baud; /* if non-zero, force the baud rate to this value */ | ||
594 | int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ | ||
595 | |||
596 | spinlock_t tx_lock; /* spinlock for transmit state */ | ||
597 | unsigned long tx_bytes; | ||
598 | unsigned long tx_outstanding_bytes; | ||
599 | unsigned long tx_outstanding_urbs; | ||
600 | }; | ||
601 | |||
602 | /* Used for TIOCMIWAIT */ | 602 | /* Used for TIOCMIWAIT */ |
603 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) | 603 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) |
604 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) | 604 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) |
@@ -609,7 +609,6 @@ struct ftdi_private { | |||
609 | 609 | ||
610 | /* function prototypes for a FTDI serial converter */ | 610 | /* function prototypes for a FTDI serial converter */ |
611 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); | 611 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); |
612 | static int ftdi_sio_attach (struct usb_serial *serial); | ||
613 | static void ftdi_shutdown (struct usb_serial *serial); | 612 | static void ftdi_shutdown (struct usb_serial *serial); |
614 | static int ftdi_sio_port_probe (struct usb_serial_port *port); | 613 | static int ftdi_sio_port_probe (struct usb_serial_port *port); |
615 | static int ftdi_sio_port_remove (struct usb_serial_port *port); | 614 | static int ftdi_sio_port_remove (struct usb_serial_port *port); |
@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
663 | .ioctl = ftdi_ioctl, | 662 | .ioctl = ftdi_ioctl, |
664 | .set_termios = ftdi_set_termios, | 663 | .set_termios = ftdi_set_termios, |
665 | .break_ctl = ftdi_break_ctl, | 664 | .break_ctl = ftdi_break_ctl, |
666 | .attach = ftdi_sio_attach, | ||
667 | .shutdown = ftdi_shutdown, | 665 | .shutdown = ftdi_shutdown, |
668 | }; | 666 | }; |
669 | 667 | ||
@@ -1200,6 +1198,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id | |||
1200 | static int ftdi_sio_port_probe(struct usb_serial_port *port) | 1198 | static int ftdi_sio_port_probe(struct usb_serial_port *port) |
1201 | { | 1199 | { |
1202 | struct ftdi_private *priv; | 1200 | struct ftdi_private *priv; |
1201 | struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); | ||
1202 | |||
1203 | 1203 | ||
1204 | dbg("%s",__FUNCTION__); | 1204 | dbg("%s",__FUNCTION__); |
1205 | 1205 | ||
@@ -1216,6 +1216,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1216 | than queue a task to deliver them */ | 1216 | than queue a task to deliver them */ |
1217 | priv->flags = ASYNC_LOW_LATENCY; | 1217 | priv->flags = ASYNC_LOW_LATENCY; |
1218 | 1218 | ||
1219 | if (quirk && quirk->port_probe) | ||
1220 | quirk->port_probe(priv); | ||
1221 | |||
1219 | /* Increase the size of read buffers */ | 1222 | /* Increase the size of read buffers */ |
1220 | kfree(port->bulk_in_buffer); | 1223 | kfree(port->bulk_in_buffer); |
1221 | port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL); | 1224 | port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL); |
@@ -1246,29 +1249,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1246 | return 0; | 1249 | return 0; |
1247 | } | 1250 | } |
1248 | 1251 | ||
1249 | /* attach subroutine */ | ||
1250 | static int ftdi_sio_attach (struct usb_serial *serial) | ||
1251 | { | ||
1252 | /* Check for device requiring special set up. */ | ||
1253 | struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial); | ||
1254 | |||
1255 | if (quirk && quirk->setup) | ||
1256 | quirk->setup(serial); | ||
1257 | |||
1258 | return 0; | ||
1259 | } /* ftdi_sio_attach */ | ||
1260 | |||
1261 | |||
1262 | /* Setup for the USB-UIRT device, which requires hardwired | 1252 | /* Setup for the USB-UIRT device, which requires hardwired |
1263 | * baudrate (38400 gets mapped to 312500) */ | 1253 | * baudrate (38400 gets mapped to 312500) */ |
1264 | /* Called from usbserial:serial_probe */ | 1254 | /* Called from usbserial:serial_probe */ |
1265 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial) | 1255 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) |
1266 | { | 1256 | { |
1267 | struct ftdi_private *priv; | ||
1268 | |||
1269 | dbg("%s",__FUNCTION__); | 1257 | dbg("%s",__FUNCTION__); |
1270 | 1258 | ||
1271 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1272 | priv->flags |= ASYNC_SPD_CUST; | 1259 | priv->flags |= ASYNC_SPD_CUST; |
1273 | priv->custom_divisor = 77; | 1260 | priv->custom_divisor = 77; |
1274 | priv->force_baud = B38400; | 1261 | priv->force_baud = B38400; |
@@ -1276,13 +1263,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial *serial) | |||
1276 | 1263 | ||
1277 | /* Setup for the HE-TIRA1 device, which requires hardwired | 1264 | /* Setup for the HE-TIRA1 device, which requires hardwired |
1278 | * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ | 1265 | * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ |
1279 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | 1266 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) |
1280 | { | 1267 | { |
1281 | struct ftdi_private *priv; | ||
1282 | |||
1283 | dbg("%s",__FUNCTION__); | 1268 | dbg("%s",__FUNCTION__); |
1284 | 1269 | ||
1285 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1286 | priv->flags |= ASYNC_SPD_CUST; | 1270 | priv->flags |= ASYNC_SPD_CUST; |
1287 | priv->custom_divisor = 240; | 1271 | priv->custom_divisor = 240; |
1288 | priv->force_baud = B38400; | 1272 | priv->force_baud = B38400; |