diff options
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r-- | drivers/usb/serial/cypress_m8.c | 579 |
1 files changed, 257 insertions, 322 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 779d07851a4d..32121794808d 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -122,6 +122,11 @@ static struct usb_driver cypress_driver = { | |||
122 | .no_dynamic_id = 1, | 122 | .no_dynamic_id = 1, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | enum packet_format { | ||
126 | packet_format_1, /* b0:status, b1:payload count */ | ||
127 | packet_format_2 /* b0[7:3]:status, b0[2:0]:payload count */ | ||
128 | }; | ||
129 | |||
125 | struct cypress_private { | 130 | struct cypress_private { |
126 | spinlock_t lock; /* private lock */ | 131 | spinlock_t lock; /* private lock */ |
127 | int chiptype; /* identifier of device, for quirks/etc */ | 132 | int chiptype; /* identifier of device, for quirks/etc */ |
@@ -139,8 +144,9 @@ struct cypress_private { | |||
139 | __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ | 144 | __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ |
140 | __u8 current_config; /* stores the current configuration byte */ | 145 | __u8 current_config; /* stores the current configuration byte */ |
141 | __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ | 146 | __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ |
147 | enum packet_format pkt_fmt; /* format to use for packet send / receive */ | ||
148 | int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ | ||
142 | int baud_rate; /* stores current baud rate in integer form */ | 149 | int baud_rate; /* stores current baud rate in integer form */ |
143 | int cbr_mask; /* stores current baud rate in masked form */ | ||
144 | int isthrottled; /* if throttled, discard reads */ | 150 | int isthrottled; /* if throttled, discard reads */ |
145 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ | 151 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ |
146 | char prev_status, diff_status; /* used for TIOCMIWAIT */ | 152 | char prev_status, diff_status; /* used for TIOCMIWAIT */ |
@@ -176,9 +182,6 @@ static void cypress_unthrottle (struct usb_serial_port *port); | |||
176 | static void cypress_set_dead (struct usb_serial_port *port); | 182 | static void cypress_set_dead (struct usb_serial_port *port); |
177 | static void cypress_read_int_callback (struct urb *urb); | 183 | static void cypress_read_int_callback (struct urb *urb); |
178 | static void cypress_write_int_callback (struct urb *urb); | 184 | static void cypress_write_int_callback (struct urb *urb); |
179 | /* baud helper functions */ | ||
180 | static int mask_to_rate (unsigned mask); | ||
181 | static unsigned rate_to_mask (int rate); | ||
182 | /* write buffer functions */ | 185 | /* write buffer functions */ |
183 | static struct cypress_buf *cypress_buf_alloc(unsigned int size); | 186 | static struct cypress_buf *cypress_buf_alloc(unsigned int size); |
184 | static void cypress_buf_free(struct cypress_buf *cb); | 187 | static void cypress_buf_free(struct cypress_buf *cb); |
@@ -197,10 +200,6 @@ static struct usb_serial_driver cypress_earthmate_device = { | |||
197 | .description = "DeLorme Earthmate USB", | 200 | .description = "DeLorme Earthmate USB", |
198 | .usb_driver = &cypress_driver, | 201 | .usb_driver = &cypress_driver, |
199 | .id_table = id_table_earthmate, | 202 | .id_table = id_table_earthmate, |
200 | .num_interrupt_in = 1, | ||
201 | .num_interrupt_out = 1, | ||
202 | .num_bulk_in = NUM_DONT_CARE, | ||
203 | .num_bulk_out = NUM_DONT_CARE, | ||
204 | .num_ports = 1, | 203 | .num_ports = 1, |
205 | .attach = cypress_earthmate_startup, | 204 | .attach = cypress_earthmate_startup, |
206 | .shutdown = cypress_shutdown, | 205 | .shutdown = cypress_shutdown, |
@@ -227,10 +226,6 @@ static struct usb_serial_driver cypress_hidcom_device = { | |||
227 | .description = "HID->COM RS232 Adapter", | 226 | .description = "HID->COM RS232 Adapter", |
228 | .usb_driver = &cypress_driver, | 227 | .usb_driver = &cypress_driver, |
229 | .id_table = id_table_cyphidcomrs232, | 228 | .id_table = id_table_cyphidcomrs232, |
230 | .num_interrupt_in = 1, | ||
231 | .num_interrupt_out = 1, | ||
232 | .num_bulk_in = NUM_DONT_CARE, | ||
233 | .num_bulk_out = NUM_DONT_CARE, | ||
234 | .num_ports = 1, | 229 | .num_ports = 1, |
235 | .attach = cypress_hidcom_startup, | 230 | .attach = cypress_hidcom_startup, |
236 | .shutdown = cypress_shutdown, | 231 | .shutdown = cypress_shutdown, |
@@ -257,10 +252,6 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
257 | .description = "Nokia CA-42 V2 Adapter", | 252 | .description = "Nokia CA-42 V2 Adapter", |
258 | .usb_driver = &cypress_driver, | 253 | .usb_driver = &cypress_driver, |
259 | .id_table = id_table_nokiaca42v2, | 254 | .id_table = id_table_nokiaca42v2, |
260 | .num_interrupt_in = 1, | ||
261 | .num_interrupt_out = 1, | ||
262 | .num_bulk_in = NUM_DONT_CARE, | ||
263 | .num_bulk_out = NUM_DONT_CARE, | ||
264 | .num_ports = 1, | 255 | .num_ports = 1, |
265 | .attach = cypress_ca42v2_startup, | 256 | .attach = cypress_ca42v2_startup, |
266 | .shutdown = cypress_shutdown, | 257 | .shutdown = cypress_shutdown, |
@@ -284,16 +275,62 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
284 | *****************************************************************************/ | 275 | *****************************************************************************/ |
285 | 276 | ||
286 | 277 | ||
278 | static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) | ||
279 | { | ||
280 | struct cypress_private *priv; | ||
281 | priv = usb_get_serial_port_data(port); | ||
282 | |||
283 | /* | ||
284 | * The general purpose firmware for the Cypress M8 allows for | ||
285 | * a maximum speed of 57600bps (I have no idea whether DeLorme | ||
286 | * chose to use the general purpose firmware or not), if you | ||
287 | * need to modify this speed setting for your own project | ||
288 | * please add your own chiptype and modify the code likewise. | ||
289 | * The Cypress HID->COM device will work successfully up to | ||
290 | * 115200bps (but the actual throughput is around 3kBps). | ||
291 | */ | ||
292 | if (port->serial->dev->speed == USB_SPEED_LOW) { | ||
293 | /* | ||
294 | * Mike Isely <isely@pobox.com> 2-Feb-2008: The | ||
295 | * Cypress app note that describes this mechanism | ||
296 | * states the the low-speed part can't handle more | ||
297 | * than 800 bytes/sec, in which case 4800 baud is the | ||
298 | * safest speed for a part like that. | ||
299 | */ | ||
300 | if (new_rate > 4800) { | ||
301 | dbg("%s - failed setting baud rate, device incapable " | ||
302 | "speed %d", __func__, new_rate); | ||
303 | return -1; | ||
304 | } | ||
305 | } | ||
306 | switch (priv->chiptype) { | ||
307 | case CT_EARTHMATE: | ||
308 | if (new_rate <= 600) { | ||
309 | /* 300 and 600 baud rates are supported under | ||
310 | * the generic firmware, but are not used with | ||
311 | * NMEA and SiRF protocols */ | ||
312 | dbg("%s - failed setting baud rate, unsupported speed " | ||
313 | "of %d on Earthmate GPS", __func__, new_rate); | ||
314 | return -1; | ||
315 | } | ||
316 | break; | ||
317 | default: | ||
318 | break; | ||
319 | } | ||
320 | return new_rate; | ||
321 | } | ||
322 | |||
323 | |||
287 | /* This function can either set or retrieve the current serial line settings */ | 324 | /* This function can either set or retrieve the current serial line settings */ |
288 | static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits, | 325 | static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_rate, int data_bits, int stop_bits, |
289 | int parity_enable, int parity_type, int reset, int cypress_request_type) | 326 | int parity_enable, int parity_type, int reset, int cypress_request_type) |
290 | { | 327 | { |
291 | int new_baudrate = 0, retval = 0, tries = 0; | 328 | int new_baudrate = 0, retval = 0, tries = 0; |
292 | struct cypress_private *priv; | 329 | struct cypress_private *priv; |
293 | __u8 feature_buffer[8]; | 330 | __u8 feature_buffer[5]; |
294 | unsigned long flags; | 331 | unsigned long flags; |
295 | 332 | ||
296 | dbg("%s", __FUNCTION__); | 333 | dbg("%s", __func__); |
297 | 334 | ||
298 | priv = usb_get_serial_port_data(port); | 335 | priv = usb_get_serial_port_data(port); |
299 | 336 | ||
@@ -302,58 +339,23 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m | |||
302 | 339 | ||
303 | switch(cypress_request_type) { | 340 | switch(cypress_request_type) { |
304 | case CYPRESS_SET_CONFIG: | 341 | case CYPRESS_SET_CONFIG: |
305 | 342 | new_baudrate = priv->baud_rate; | |
306 | /* | 343 | /* 0 means 'Hang up' so doesn't change the true bit rate */ |
307 | * The general purpose firmware for the Cypress M8 allows for a maximum speed | 344 | if (baud_rate == 0) |
308 | * of 57600bps (I have no idea whether DeLorme chose to use the general purpose | ||
309 | * firmware or not), if you need to modify this speed setting for your own | ||
310 | * project please add your own chiptype and modify the code likewise. The | ||
311 | * Cypress HID->COM device will work successfully up to 115200bps (but the | ||
312 | * actual throughput is around 3kBps). | ||
313 | */ | ||
314 | if (baud_mask != priv->cbr_mask) { | ||
315 | dbg("%s - baud rate is changing", __FUNCTION__); | ||
316 | if ( priv->chiptype == CT_EARTHMATE ) { | ||
317 | /* 300 and 600 baud rates are supported under the generic firmware, | ||
318 | * but are not used with NMEA and SiRF protocols */ | ||
319 | |||
320 | if ( (baud_mask == B300) || (baud_mask == B600) ) { | ||
321 | err("%s - failed setting baud rate, unsupported speed", | ||
322 | __FUNCTION__); | ||
323 | new_baudrate = priv->baud_rate; | ||
324 | } else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { | ||
325 | err("%s - failed setting baud rate, unsupported speed", | ||
326 | __FUNCTION__); | ||
327 | new_baudrate = priv->baud_rate; | ||
328 | } | ||
329 | } else if (priv->chiptype == CT_CYPHIDCOM) { | ||
330 | if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { | ||
331 | err("%s - failed setting baud rate, unsupported speed", | ||
332 | __FUNCTION__); | ||
333 | new_baudrate = priv->baud_rate; | ||
334 | } | ||
335 | } else if (priv->chiptype == CT_CA42V2) { | ||
336 | if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { | ||
337 | err("%s - failed setting baud rate, unsupported speed", | ||
338 | __FUNCTION__); | ||
339 | new_baudrate = priv->baud_rate; | ||
340 | } | ||
341 | } else if (priv->chiptype == CT_GENERIC) { | ||
342 | if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { | ||
343 | err("%s - failed setting baud rate, unsupported speed", | ||
344 | __FUNCTION__); | ||
345 | new_baudrate = priv->baud_rate; | ||
346 | } | ||
347 | } else { | ||
348 | info("%s - please define your chiptype", __FUNCTION__); | ||
349 | new_baudrate = priv->baud_rate; | ||
350 | } | ||
351 | } else { /* baud rate not changing, keep the old */ | ||
352 | new_baudrate = priv->baud_rate; | 345 | new_baudrate = priv->baud_rate; |
346 | /* Change of speed ? */ | ||
347 | else if (baud_rate != priv->baud_rate) { | ||
348 | dbg("%s - baud rate is changing", __func__); | ||
349 | retval = analyze_baud_rate(port, baud_rate); | ||
350 | if (retval >= 0) { | ||
351 | new_baudrate = retval; | ||
352 | dbg("%s - New baud rate set to %d", | ||
353 | __func__, new_baudrate); | ||
354 | } | ||
353 | } | 355 | } |
354 | dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate); | 356 | dbg("%s - baud rate is being sent as %d", __func__, new_baudrate); |
355 | 357 | ||
356 | memset(feature_buffer, 0, 8); | 358 | memset(feature_buffer, 0, sizeof(feature_buffer)); |
357 | /* fill the feature_buffer with new configuration */ | 359 | /* fill the feature_buffer with new configuration */ |
358 | *((u_int32_t *)feature_buffer) = new_baudrate; | 360 | *((u_int32_t *)feature_buffer) = new_baudrate; |
359 | 361 | ||
@@ -365,48 +367,65 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m | |||
365 | /* 1 bit gap */ | 367 | /* 1 bit gap */ |
366 | feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ | 368 | feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ |
367 | 369 | ||
368 | dbg("%s - device is being sent this feature report:", __FUNCTION__); | 370 | dbg("%s - device is being sent this feature report:", __func__); |
369 | dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1], | 371 | dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, feature_buffer[0], feature_buffer[1], |
370 | feature_buffer[2], feature_buffer[3], feature_buffer[4]); | 372 | feature_buffer[2], feature_buffer[3], feature_buffer[4]); |
371 | 373 | ||
372 | do { | 374 | do { |
373 | retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), | 375 | retval = usb_control_msg(port->serial->dev, |
374 | HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | 376 | usb_sndctrlpipe(port->serial->dev, 0), |
375 | 0x0300, 0, feature_buffer, 8, 500); | 377 | HID_REQ_SET_REPORT, |
378 | USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | ||
379 | 0x0300, 0, feature_buffer, | ||
380 | sizeof(feature_buffer), 500); | ||
376 | 381 | ||
377 | if (tries++ >= 3) | 382 | if (tries++ >= 3) |
378 | break; | 383 | break; |
379 | 384 | ||
380 | } while (retval != 8 && retval != -ENODEV); | 385 | } while (retval != sizeof(feature_buffer) && |
386 | retval != -ENODEV); | ||
381 | 387 | ||
382 | if (retval != 8) { | 388 | if (retval != sizeof(feature_buffer)) { |
383 | err("%s - failed sending serial line settings - %d", __FUNCTION__, retval); | 389 | err("%s - failed sending serial line settings - %d", __func__, retval); |
384 | cypress_set_dead(port); | 390 | cypress_set_dead(port); |
385 | } else { | 391 | } else { |
386 | spin_lock_irqsave(&priv->lock, flags); | 392 | spin_lock_irqsave(&priv->lock, flags); |
387 | priv->baud_rate = new_baudrate; | 393 | priv->baud_rate = new_baudrate; |
388 | priv->cbr_mask = baud_mask; | ||
389 | priv->current_config = feature_buffer[4]; | 394 | priv->current_config = feature_buffer[4]; |
390 | spin_unlock_irqrestore(&priv->lock, flags); | 395 | spin_unlock_irqrestore(&priv->lock, flags); |
396 | /* If we asked for a speed change encode it */ | ||
397 | if (baud_rate) | ||
398 | tty_encode_baud_rate(port->tty, | ||
399 | new_baudrate, new_baudrate); | ||
391 | } | 400 | } |
392 | break; | 401 | break; |
393 | case CYPRESS_GET_CONFIG: | 402 | case CYPRESS_GET_CONFIG: |
394 | dbg("%s - retreiving serial line settings", __FUNCTION__); | 403 | if (priv->get_cfg_unsafe) { |
404 | /* Not implemented for this device, | ||
405 | and if we try to do it we're likely | ||
406 | to crash the hardware. */ | ||
407 | return -ENOTTY; | ||
408 | } | ||
409 | dbg("%s - retreiving serial line settings", __func__); | ||
395 | /* set initial values in feature buffer */ | 410 | /* set initial values in feature buffer */ |
396 | memset(feature_buffer, 0, 8); | 411 | memset(feature_buffer, 0, sizeof(feature_buffer)); |
397 | 412 | ||
398 | do { | 413 | do { |
399 | retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), | 414 | retval = usb_control_msg(port->serial->dev, |
400 | HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | 415 | usb_rcvctrlpipe(port->serial->dev, 0), |
401 | 0x0300, 0, feature_buffer, 8, 500); | 416 | HID_REQ_GET_REPORT, |
402 | 417 | USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, | |
418 | 0x0300, 0, feature_buffer, | ||
419 | sizeof(feature_buffer), 500); | ||
420 | |||
403 | if (tries++ >= 3) | 421 | if (tries++ >= 3) |
404 | break; | 422 | break; |
405 | 423 | ||
406 | } while (retval != 5 && retval != -ENODEV); | 424 | } while (retval != sizeof(feature_buffer) && |
425 | retval != -ENODEV); | ||
407 | 426 | ||
408 | if (retval != 5) { | 427 | if (retval != sizeof(feature_buffer)) { |
409 | err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval); | 428 | err("%s - failed to retrieve serial line settings - %d", __func__, retval); |
410 | cypress_set_dead(port); | 429 | cypress_set_dead(port); |
411 | return retval; | 430 | return retval; |
412 | } else { | 431 | } else { |
@@ -415,9 +434,6 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m | |||
415 | /* store the config in one byte, and later use bit masks to check values */ | 434 | /* store the config in one byte, and later use bit masks to check values */ |
416 | priv->current_config = feature_buffer[4]; | 435 | priv->current_config = feature_buffer[4]; |
417 | priv->baud_rate = *((u_int32_t *)feature_buffer); | 436 | priv->baud_rate = *((u_int32_t *)feature_buffer); |
418 | |||
419 | if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40) | ||
420 | dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__); | ||
421 | spin_unlock_irqrestore(&priv->lock, flags); | 437 | spin_unlock_irqrestore(&priv->lock, flags); |
422 | } | 438 | } |
423 | } | 439 | } |
@@ -447,51 +463,6 @@ static void cypress_set_dead(struct usb_serial_port *port) | |||
447 | } | 463 | } |
448 | 464 | ||
449 | 465 | ||
450 | /* given a baud mask, it will return integer baud on success */ | ||
451 | static int mask_to_rate (unsigned mask) | ||
452 | { | ||
453 | int rate; | ||
454 | |||
455 | switch (mask) { | ||
456 | case B0: rate = 0; break; | ||
457 | case B300: rate = 300; break; | ||
458 | case B600: rate = 600; break; | ||
459 | case B1200: rate = 1200; break; | ||
460 | case B2400: rate = 2400; break; | ||
461 | case B4800: rate = 4800; break; | ||
462 | case B9600: rate = 9600; break; | ||
463 | case B19200: rate = 19200; break; | ||
464 | case B38400: rate = 38400; break; | ||
465 | case B57600: rate = 57600; break; | ||
466 | case B115200: rate = 115200; break; | ||
467 | default: rate = -1; | ||
468 | } | ||
469 | |||
470 | return rate; | ||
471 | } | ||
472 | |||
473 | |||
474 | static unsigned rate_to_mask (int rate) | ||
475 | { | ||
476 | unsigned mask; | ||
477 | |||
478 | switch (rate) { | ||
479 | case 0: mask = B0; break; | ||
480 | case 300: mask = B300; break; | ||
481 | case 600: mask = B600; break; | ||
482 | case 1200: mask = B1200; break; | ||
483 | case 2400: mask = B2400; break; | ||
484 | case 4800: mask = B4800; break; | ||
485 | case 9600: mask = B9600; break; | ||
486 | case 19200: mask = B19200; break; | ||
487 | case 38400: mask = B38400; break; | ||
488 | case 57600: mask = B57600; break; | ||
489 | case 115200: mask = B115200; break; | ||
490 | default: mask = 0x40; | ||
491 | } | ||
492 | |||
493 | return mask; | ||
494 | } | ||
495 | /***************************************************************************** | 466 | /***************************************************************************** |
496 | * Cypress serial driver functions | 467 | * Cypress serial driver functions |
497 | *****************************************************************************/ | 468 | *****************************************************************************/ |
@@ -502,7 +473,7 @@ static int generic_startup (struct usb_serial *serial) | |||
502 | struct cypress_private *priv; | 473 | struct cypress_private *priv; |
503 | struct usb_serial_port *port = serial->port[0]; | 474 | struct usb_serial_port *port = serial->port[0]; |
504 | 475 | ||
505 | dbg("%s - port %d", __FUNCTION__, port->number); | 476 | dbg("%s - port %d", __func__, port->number); |
506 | 477 | ||
507 | priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); | 478 | priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); |
508 | if (!priv) | 479 | if (!priv) |
@@ -523,17 +494,27 @@ static int generic_startup (struct usb_serial *serial) | |||
523 | priv->line_control = 0; | 494 | priv->line_control = 0; |
524 | priv->termios_initialized = 0; | 495 | priv->termios_initialized = 0; |
525 | priv->rx_flags = 0; | 496 | priv->rx_flags = 0; |
526 | priv->cbr_mask = B300; | 497 | /* Default packet format setting is determined by packet size. |
498 | Anything with a size larger then 9 must have a separate | ||
499 | count field since the 3 bit count field is otherwise too | ||
500 | small. Otherwise we can use the slightly more compact | ||
501 | format. This is in accordance with the cypress_m8 serial | ||
502 | converter app note. */ | ||
503 | if (port->interrupt_out_size > 9) { | ||
504 | priv->pkt_fmt = packet_format_1; | ||
505 | } else { | ||
506 | priv->pkt_fmt = packet_format_2; | ||
507 | } | ||
527 | if (interval > 0) { | 508 | if (interval > 0) { |
528 | priv->write_urb_interval = interval; | 509 | priv->write_urb_interval = interval; |
529 | priv->read_urb_interval = interval; | 510 | priv->read_urb_interval = interval; |
530 | dbg("%s - port %d read & write intervals forced to %d", | 511 | dbg("%s - port %d read & write intervals forced to %d", |
531 | __FUNCTION__,port->number,interval); | 512 | __func__,port->number,interval); |
532 | } else { | 513 | } else { |
533 | priv->write_urb_interval = port->interrupt_out_urb->interval; | 514 | priv->write_urb_interval = port->interrupt_out_urb->interval; |
534 | priv->read_urb_interval = port->interrupt_in_urb->interval; | 515 | priv->read_urb_interval = port->interrupt_in_urb->interval; |
535 | dbg("%s - port %d intervals: read=%d write=%d", | 516 | dbg("%s - port %d intervals: read=%d write=%d", |
536 | __FUNCTION__,port->number, | 517 | __func__,port->number, |
537 | priv->read_urb_interval,priv->write_urb_interval); | 518 | priv->read_urb_interval,priv->write_urb_interval); |
538 | } | 519 | } |
539 | usb_set_serial_port_data(port, priv); | 520 | usb_set_serial_port_data(port, priv); |
@@ -545,17 +526,30 @@ static int generic_startup (struct usb_serial *serial) | |||
545 | static int cypress_earthmate_startup (struct usb_serial *serial) | 526 | static int cypress_earthmate_startup (struct usb_serial *serial) |
546 | { | 527 | { |
547 | struct cypress_private *priv; | 528 | struct cypress_private *priv; |
529 | struct usb_serial_port *port = serial->port[0]; | ||
548 | 530 | ||
549 | dbg("%s", __FUNCTION__); | 531 | dbg("%s", __func__); |
550 | 532 | ||
551 | if (generic_startup(serial)) { | 533 | if (generic_startup(serial)) { |
552 | dbg("%s - Failed setting up port %d", __FUNCTION__, | 534 | dbg("%s - Failed setting up port %d", __func__, |
553 | serial->port[0]->number); | 535 | port->number); |
554 | return 1; | 536 | return 1; |
555 | } | 537 | } |
556 | 538 | ||
557 | priv = usb_get_serial_port_data(serial->port[0]); | 539 | priv = usb_get_serial_port_data(port); |
558 | priv->chiptype = CT_EARTHMATE; | 540 | priv->chiptype = CT_EARTHMATE; |
541 | /* All Earthmate devices use the separated-count packet | ||
542 | format! Idiotic. */ | ||
543 | priv->pkt_fmt = packet_format_1; | ||
544 | if (serial->dev->descriptor.idProduct != PRODUCT_ID_EARTHMATEUSB) { | ||
545 | /* The old original USB Earthmate seemed able to | ||
546 | handle GET_CONFIG requests; everything they've | ||
547 | produced since that time crashes if this command is | ||
548 | attempted :-( */ | ||
549 | dbg("%s - Marking this device as unsafe for GET_CONFIG " | ||
550 | "commands", __func__); | ||
551 | priv->get_cfg_unsafe = !0; | ||
552 | } | ||
559 | 553 | ||
560 | return 0; | 554 | return 0; |
561 | } /* cypress_earthmate_startup */ | 555 | } /* cypress_earthmate_startup */ |
@@ -565,10 +559,10 @@ static int cypress_hidcom_startup (struct usb_serial *serial) | |||
565 | { | 559 | { |
566 | struct cypress_private *priv; | 560 | struct cypress_private *priv; |
567 | 561 | ||
568 | dbg("%s", __FUNCTION__); | 562 | dbg("%s", __func__); |
569 | 563 | ||
570 | if (generic_startup(serial)) { | 564 | if (generic_startup(serial)) { |
571 | dbg("%s - Failed setting up port %d", __FUNCTION__, | 565 | dbg("%s - Failed setting up port %d", __func__, |
572 | serial->port[0]->number); | 566 | serial->port[0]->number); |
573 | return 1; | 567 | return 1; |
574 | } | 568 | } |
@@ -584,10 +578,10 @@ static int cypress_ca42v2_startup (struct usb_serial *serial) | |||
584 | { | 578 | { |
585 | struct cypress_private *priv; | 579 | struct cypress_private *priv; |
586 | 580 | ||
587 | dbg("%s", __FUNCTION__); | 581 | dbg("%s", __func__); |
588 | 582 | ||
589 | if (generic_startup(serial)) { | 583 | if (generic_startup(serial)) { |
590 | dbg("%s - Failed setting up port %d", __FUNCTION__, | 584 | dbg("%s - Failed setting up port %d", __func__, |
591 | serial->port[0]->number); | 585 | serial->port[0]->number); |
592 | return 1; | 586 | return 1; |
593 | } | 587 | } |
@@ -603,7 +597,7 @@ static void cypress_shutdown (struct usb_serial *serial) | |||
603 | { | 597 | { |
604 | struct cypress_private *priv; | 598 | struct cypress_private *priv; |
605 | 599 | ||
606 | dbg ("%s - port %d", __FUNCTION__, serial->port[0]->number); | 600 | dbg ("%s - port %d", __func__, serial->port[0]->number); |
607 | 601 | ||
608 | /* all open ports are closed at this point */ | 602 | /* all open ports are closed at this point */ |
609 | 603 | ||
@@ -624,7 +618,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) | |||
624 | unsigned long flags; | 618 | unsigned long flags; |
625 | int result = 0; | 619 | int result = 0; |
626 | 620 | ||
627 | dbg("%s - port %d", __FUNCTION__, port->number); | 621 | dbg("%s - port %d", __func__, port->number); |
628 | 622 | ||
629 | if (!priv->comm_is_ok) | 623 | if (!priv->comm_is_ok) |
630 | return -EIO; | 624 | return -EIO; |
@@ -652,16 +646,16 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) | |||
652 | result = cypress_write(port, NULL, 0); | 646 | result = cypress_write(port, NULL, 0); |
653 | 647 | ||
654 | if (result) { | 648 | if (result) { |
655 | dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result); | 649 | dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result); |
656 | return result; | 650 | return result; |
657 | } else | 651 | } else |
658 | dbg("%s - success setting the control lines", __FUNCTION__); | 652 | dbg("%s - success setting the control lines", __func__); |
659 | 653 | ||
660 | cypress_set_termios(port, &priv->tmp_termios); | 654 | cypress_set_termios(port, &priv->tmp_termios); |
661 | 655 | ||
662 | /* setup the port and start reading from the device */ | 656 | /* setup the port and start reading from the device */ |
663 | if(!port->interrupt_in_urb){ | 657 | if(!port->interrupt_in_urb){ |
664 | err("%s - interrupt_in_urb is empty!", __FUNCTION__); | 658 | err("%s - interrupt_in_urb is empty!", __func__); |
665 | return(-1); | 659 | return(-1); |
666 | } | 660 | } |
667 | 661 | ||
@@ -672,7 +666,7 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp) | |||
672 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 666 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
673 | 667 | ||
674 | if (result){ | 668 | if (result){ |
675 | dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); | 669 | dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result); |
676 | cypress_set_dead(port); | 670 | cypress_set_dead(port); |
677 | } | 671 | } |
678 | 672 | ||
@@ -688,7 +682,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
688 | long timeout; | 682 | long timeout; |
689 | wait_queue_t wait; | 683 | wait_queue_t wait; |
690 | 684 | ||
691 | dbg("%s - port %d", __FUNCTION__, port->number); | 685 | dbg("%s - port %d", __func__, port->number); |
692 | 686 | ||
693 | /* wait for data to drain from buffer */ | 687 | /* wait for data to drain from buffer */ |
694 | spin_lock_irq(&priv->lock); | 688 | spin_lock_irq(&priv->lock); |
@@ -726,7 +720,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) | |||
726 | timeout = 2*HZ; | 720 | timeout = 2*HZ; |
727 | schedule_timeout_interruptible(timeout); | 721 | schedule_timeout_interruptible(timeout); |
728 | 722 | ||
729 | dbg("%s - stopping urbs", __FUNCTION__); | 723 | dbg("%s - stopping urbs", __func__); |
730 | usb_kill_urb (port->interrupt_in_urb); | 724 | usb_kill_urb (port->interrupt_in_urb); |
731 | usb_kill_urb (port->interrupt_out_urb); | 725 | usb_kill_urb (port->interrupt_out_urb); |
732 | 726 | ||
@@ -755,7 +749,7 @@ static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, | |||
755 | struct cypress_private *priv = usb_get_serial_port_data(port); | 749 | struct cypress_private *priv = usb_get_serial_port_data(port); |
756 | unsigned long flags; | 750 | unsigned long flags; |
757 | 751 | ||
758 | dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count); | 752 | dbg("%s - port %d, %d bytes", __func__, port->number, count); |
759 | 753 | ||
760 | /* line control commands, which need to be executed immediately, | 754 | /* line control commands, which need to be executed immediately, |
761 | are not put into the buffer for obvious reasons. | 755 | are not put into the buffer for obvious reasons. |
@@ -788,12 +782,12 @@ static void cypress_send(struct usb_serial_port *port) | |||
788 | if (!priv->comm_is_ok) | 782 | if (!priv->comm_is_ok) |
789 | return; | 783 | return; |
790 | 784 | ||
791 | dbg("%s - port %d", __FUNCTION__, port->number); | 785 | dbg("%s - port %d", __func__, port->number); |
792 | dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size); | 786 | dbg("%s - interrupt out size is %d", __func__, port->interrupt_out_size); |
793 | 787 | ||
794 | spin_lock_irqsave(&priv->lock, flags); | 788 | spin_lock_irqsave(&priv->lock, flags); |
795 | if (priv->write_urb_in_use) { | 789 | if (priv->write_urb_in_use) { |
796 | dbg("%s - can't write, urb in use", __FUNCTION__); | 790 | dbg("%s - can't write, urb in use", __func__); |
797 | spin_unlock_irqrestore(&priv->lock, flags); | 791 | spin_unlock_irqrestore(&priv->lock, flags); |
798 | return; | 792 | return; |
799 | } | 793 | } |
@@ -803,21 +797,18 @@ static void cypress_send(struct usb_serial_port *port) | |||
803 | memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size); | 797 | memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size); |
804 | 798 | ||
805 | spin_lock_irqsave(&priv->lock, flags); | 799 | spin_lock_irqsave(&priv->lock, flags); |
806 | switch (port->interrupt_out_size) { | 800 | switch (priv->pkt_fmt) { |
807 | case 32: | 801 | default: |
808 | /* this is for the CY7C64013... */ | 802 | case packet_format_1: |
809 | offset = 2; | 803 | /* this is for the CY7C64013... */ |
810 | port->interrupt_out_buffer[0] = priv->line_control; | 804 | offset = 2; |
811 | break; | 805 | port->interrupt_out_buffer[0] = priv->line_control; |
812 | case 8: | 806 | break; |
813 | /* this is for the CY7C63743... */ | 807 | case packet_format_2: |
814 | offset = 1; | 808 | /* this is for the CY7C63743... */ |
815 | port->interrupt_out_buffer[0] = priv->line_control; | 809 | offset = 1; |
816 | break; | 810 | port->interrupt_out_buffer[0] = priv->line_control; |
817 | default: | 811 | break; |
818 | dbg("%s - wrong packet size", __FUNCTION__); | ||
819 | spin_unlock_irqrestore(&priv->lock, flags); | ||
820 | return; | ||
821 | } | 812 | } |
822 | 813 | ||
823 | if (priv->line_control & CONTROL_RESET) | 814 | if (priv->line_control & CONTROL_RESET) |
@@ -825,7 +816,7 @@ static void cypress_send(struct usb_serial_port *port) | |||
825 | 816 | ||
826 | if (priv->cmd_ctrl) { | 817 | if (priv->cmd_ctrl) { |
827 | priv->cmd_count++; | 818 | priv->cmd_count++; |
828 | dbg("%s - line control command being issued", __FUNCTION__); | 819 | dbg("%s - line control command being issued", __func__); |
829 | spin_unlock_irqrestore(&priv->lock, flags); | 820 | spin_unlock_irqrestore(&priv->lock, flags); |
830 | goto send; | 821 | goto send; |
831 | } else | 822 | } else |
@@ -838,15 +829,16 @@ static void cypress_send(struct usb_serial_port *port) | |||
838 | return; | 829 | return; |
839 | } | 830 | } |
840 | 831 | ||
841 | switch (port->interrupt_out_size) { | 832 | switch (priv->pkt_fmt) { |
842 | case 32: | 833 | default: |
843 | port->interrupt_out_buffer[1] = count; | 834 | case packet_format_1: |
844 | break; | 835 | port->interrupt_out_buffer[1] = count; |
845 | case 8: | 836 | break; |
846 | port->interrupt_out_buffer[0] |= count; | 837 | case packet_format_2: |
838 | port->interrupt_out_buffer[0] |= count; | ||
847 | } | 839 | } |
848 | 840 | ||
849 | dbg("%s - count is %d", __FUNCTION__, count); | 841 | dbg("%s - count is %d", __func__, count); |
850 | 842 | ||
851 | send: | 843 | send: |
852 | spin_lock_irqsave(&priv->lock, flags); | 844 | spin_lock_irqsave(&priv->lock, flags); |
@@ -856,9 +848,10 @@ send: | |||
856 | if (priv->cmd_ctrl) | 848 | if (priv->cmd_ctrl) |
857 | actual_size = 1; | 849 | actual_size = 1; |
858 | else | 850 | else |
859 | actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1); | 851 | actual_size = count + |
860 | 852 | (priv->pkt_fmt == packet_format_1 ? 2 : 1); | |
861 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size, | 853 | |
854 | usb_serial_debug_data(debug, &port->dev, __func__, port->interrupt_out_size, | ||
862 | port->interrupt_out_urb->transfer_buffer); | 855 | port->interrupt_out_urb->transfer_buffer); |
863 | 856 | ||
864 | usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, | 857 | usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, |
@@ -867,7 +860,7 @@ send: | |||
867 | cypress_write_int_callback, port, priv->write_urb_interval); | 860 | cypress_write_int_callback, port, priv->write_urb_interval); |
868 | result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); | 861 | result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC); |
869 | if (result) { | 862 | if (result) { |
870 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, | 863 | dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, |
871 | result); | 864 | result); |
872 | priv->write_urb_in_use = 0; | 865 | priv->write_urb_in_use = 0; |
873 | cypress_set_dead(port); | 866 | cypress_set_dead(port); |
@@ -891,13 +884,13 @@ static int cypress_write_room(struct usb_serial_port *port) | |||
891 | int room = 0; | 884 | int room = 0; |
892 | unsigned long flags; | 885 | unsigned long flags; |
893 | 886 | ||
894 | dbg("%s - port %d", __FUNCTION__, port->number); | 887 | dbg("%s - port %d", __func__, port->number); |
895 | 888 | ||
896 | spin_lock_irqsave(&priv->lock, flags); | 889 | spin_lock_irqsave(&priv->lock, flags); |
897 | room = cypress_buf_space_avail(priv->buf); | 890 | room = cypress_buf_space_avail(priv->buf); |
898 | spin_unlock_irqrestore(&priv->lock, flags); | 891 | spin_unlock_irqrestore(&priv->lock, flags); |
899 | 892 | ||
900 | dbg("%s - returns %d", __FUNCTION__, room); | 893 | dbg("%s - returns %d", __func__, room); |
901 | return room; | 894 | return room; |
902 | } | 895 | } |
903 | 896 | ||
@@ -909,7 +902,7 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) | |||
909 | unsigned int result = 0; | 902 | unsigned int result = 0; |
910 | unsigned long flags; | 903 | unsigned long flags; |
911 | 904 | ||
912 | dbg("%s - port %d", __FUNCTION__, port->number); | 905 | dbg("%s - port %d", __func__, port->number); |
913 | 906 | ||
914 | spin_lock_irqsave(&priv->lock, flags); | 907 | spin_lock_irqsave(&priv->lock, flags); |
915 | control = priv->line_control; | 908 | control = priv->line_control; |
@@ -923,7 +916,7 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file) | |||
923 | | ((status & UART_RI) ? TIOCM_RI : 0) | 916 | | ((status & UART_RI) ? TIOCM_RI : 0) |
924 | | ((status & UART_CD) ? TIOCM_CD : 0); | 917 | | ((status & UART_CD) ? TIOCM_CD : 0); |
925 | 918 | ||
926 | dbg("%s - result = %x", __FUNCTION__, result); | 919 | dbg("%s - result = %x", __func__, result); |
927 | 920 | ||
928 | return result; | 921 | return result; |
929 | } | 922 | } |
@@ -935,7 +928,7 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, | |||
935 | struct cypress_private *priv = usb_get_serial_port_data(port); | 928 | struct cypress_private *priv = usb_get_serial_port_data(port); |
936 | unsigned long flags; | 929 | unsigned long flags; |
937 | 930 | ||
938 | dbg("%s - port %d", __FUNCTION__, port->number); | 931 | dbg("%s - port %d", __func__, port->number); |
939 | 932 | ||
940 | spin_lock_irqsave(&priv->lock, flags); | 933 | spin_lock_irqsave(&priv->lock, flags); |
941 | if (set & TIOCM_RTS) | 934 | if (set & TIOCM_RTS) |
@@ -946,9 +939,9 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, | |||
946 | priv->line_control &= ~CONTROL_RTS; | 939 | priv->line_control &= ~CONTROL_RTS; |
947 | if (clear & TIOCM_DTR) | 940 | if (clear & TIOCM_DTR) |
948 | priv->line_control &= ~CONTROL_DTR; | 941 | priv->line_control &= ~CONTROL_DTR; |
942 | priv->cmd_ctrl = 1; | ||
949 | spin_unlock_irqrestore(&priv->lock, flags); | 943 | spin_unlock_irqrestore(&priv->lock, flags); |
950 | 944 | ||
951 | priv->cmd_ctrl = 1; | ||
952 | return cypress_write(port, NULL, 0); | 945 | return cypress_write(port, NULL, 0); |
953 | } | 946 | } |
954 | 947 | ||
@@ -957,23 +950,9 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi | |||
957 | { | 950 | { |
958 | struct cypress_private *priv = usb_get_serial_port_data(port); | 951 | struct cypress_private *priv = usb_get_serial_port_data(port); |
959 | 952 | ||
960 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); | 953 | dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); |
961 | 954 | ||
962 | switch (cmd) { | 955 | switch (cmd) { |
963 | case TIOCGSERIAL: | ||
964 | if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) { | ||
965 | return -EFAULT; | ||
966 | } | ||
967 | return (0); | ||
968 | break; | ||
969 | case TIOCSSERIAL: | ||
970 | if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) { | ||
971 | return -EFAULT; | ||
972 | } | ||
973 | /* here we need to call cypress_set_termios to invoke the new settings */ | ||
974 | cypress_set_termios(port, &priv->tmp_termios); | ||
975 | return (0); | ||
976 | break; | ||
977 | /* This code comes from drivers/char/serial.c and ftdi_sio.c */ | 956 | /* This code comes from drivers/char/serial.c and ftdi_sio.c */ |
978 | case TIOCMIWAIT: | 957 | case TIOCMIWAIT: |
979 | while (priv != NULL) { | 958 | while (priv != NULL) { |
@@ -1009,7 +988,7 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi | |||
1009 | break; | 988 | break; |
1010 | } | 989 | } |
1011 | 990 | ||
1012 | dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__, cmd); | 991 | dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); |
1013 | 992 | ||
1014 | return -ENOIOCTLCMD; | 993 | return -ENOIOCTLCMD; |
1015 | } /* cypress_ioctl */ | 994 | } /* cypress_ioctl */ |
@@ -1021,18 +1000,14 @@ static void cypress_set_termios (struct usb_serial_port *port, | |||
1021 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1000 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1022 | struct tty_struct *tty; | 1001 | struct tty_struct *tty; |
1023 | int data_bits, stop_bits, parity_type, parity_enable; | 1002 | int data_bits, stop_bits, parity_type, parity_enable; |
1024 | unsigned cflag, iflag, baud_mask; | 1003 | unsigned cflag, iflag; |
1025 | unsigned long flags; | 1004 | unsigned long flags; |
1026 | __u8 oldlines; | 1005 | __u8 oldlines; |
1027 | int linechange = 0; | 1006 | int linechange = 0; |
1028 | 1007 | ||
1029 | dbg("%s - port %d", __FUNCTION__, port->number); | 1008 | dbg("%s - port %d", __func__, port->number); |
1030 | 1009 | ||
1031 | tty = port->tty; | 1010 | tty = port->tty; |
1032 | if ((!tty) || (!tty->termios)) { | ||
1033 | dbg("%s - no tty structures", __FUNCTION__); | ||
1034 | return; | ||
1035 | } | ||
1036 | 1011 | ||
1037 | spin_lock_irqsave(&priv->lock, flags); | 1012 | spin_lock_irqsave(&priv->lock, flags); |
1038 | if (!priv->termios_initialized) { | 1013 | if (!priv->termios_initialized) { |
@@ -1040,40 +1015,37 @@ static void cypress_set_termios (struct usb_serial_port *port, | |||
1040 | *(tty->termios) = tty_std_termios; | 1015 | *(tty->termios) = tty_std_termios; |
1041 | tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | | 1016 | tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | |
1042 | CLOCAL; | 1017 | CLOCAL; |
1018 | tty->termios->c_ispeed = 4800; | ||
1019 | tty->termios->c_ospeed = 4800; | ||
1043 | } else if (priv->chiptype == CT_CYPHIDCOM) { | 1020 | } else if (priv->chiptype == CT_CYPHIDCOM) { |
1044 | *(tty->termios) = tty_std_termios; | 1021 | *(tty->termios) = tty_std_termios; |
1045 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 1022 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | |
1046 | CLOCAL; | 1023 | CLOCAL; |
1024 | tty->termios->c_ispeed = 9600; | ||
1025 | tty->termios->c_ospeed = 9600; | ||
1047 | } else if (priv->chiptype == CT_CA42V2) { | 1026 | } else if (priv->chiptype == CT_CA42V2) { |
1048 | *(tty->termios) = tty_std_termios; | 1027 | *(tty->termios) = tty_std_termios; |
1049 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 1028 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | |
1050 | CLOCAL; | 1029 | CLOCAL; |
1030 | tty->termios->c_ispeed = 9600; | ||
1031 | tty->termios->c_ospeed = 9600; | ||
1051 | } | 1032 | } |
1052 | priv->termios_initialized = 1; | 1033 | priv->termios_initialized = 1; |
1053 | } | 1034 | } |
1054 | spin_unlock_irqrestore(&priv->lock, flags); | 1035 | spin_unlock_irqrestore(&priv->lock, flags); |
1055 | 1036 | ||
1037 | /* Unsupported features need clearing */ | ||
1038 | tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); | ||
1039 | |||
1056 | cflag = tty->termios->c_cflag; | 1040 | cflag = tty->termios->c_cflag; |
1057 | iflag = tty->termios->c_iflag; | 1041 | iflag = tty->termios->c_iflag; |
1058 | 1042 | ||
1059 | /* check if there are new settings */ | 1043 | /* check if there are new settings */ |
1060 | if (old_termios) { | 1044 | if (old_termios) { |
1061 | if ((cflag != old_termios->c_cflag) || | 1045 | spin_lock_irqsave(&priv->lock, flags); |
1062 | (RELEVANT_IFLAG(iflag) != | 1046 | priv->tmp_termios = *(tty->termios); |
1063 | RELEVANT_IFLAG(old_termios->c_iflag))) { | 1047 | spin_unlock_irqrestore(&priv->lock, flags); |
1064 | dbg("%s - attempting to set new termios settings", | 1048 | } |
1065 | __FUNCTION__); | ||
1066 | /* should make a copy of this in case something goes | ||
1067 | * wrong in the function, we can restore it */ | ||
1068 | spin_lock_irqsave(&priv->lock, flags); | ||
1069 | priv->tmp_termios = *(tty->termios); | ||
1070 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1071 | } else { | ||
1072 | dbg("%s - nothing to do, exiting", __FUNCTION__); | ||
1073 | return; | ||
1074 | } | ||
1075 | } else | ||
1076 | return; | ||
1077 | 1049 | ||
1078 | /* set number of data bits, parity, stop bits */ | 1050 | /* set number of data bits, parity, stop bits */ |
1079 | /* when parity is disabled the parity type bit is ignored */ | 1051 | /* when parity is disabled the parity type bit is ignored */ |
@@ -1104,7 +1076,7 @@ static void cypress_set_termios (struct usb_serial_port *port, | |||
1104 | break; | 1076 | break; |
1105 | default: | 1077 | default: |
1106 | err("%s - CSIZE was set, but not CS5-CS8", | 1078 | err("%s - CSIZE was set, but not CS5-CS8", |
1107 | __FUNCTION__); | 1079 | __func__); |
1108 | data_bits = 3; | 1080 | data_bits = 3; |
1109 | } | 1081 | } |
1110 | } else | 1082 | } else |
@@ -1114,54 +1086,17 @@ static void cypress_set_termios (struct usb_serial_port *port, | |||
1114 | oldlines = priv->line_control; | 1086 | oldlines = priv->line_control; |
1115 | if ((cflag & CBAUD) == B0) { | 1087 | if ((cflag & CBAUD) == B0) { |
1116 | /* drop dtr and rts */ | 1088 | /* drop dtr and rts */ |
1117 | dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__); | 1089 | dbg("%s - dropping the lines, baud rate 0bps", __func__); |
1118 | baud_mask = B0; | ||
1119 | priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); | 1090 | priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); |
1120 | } else { | 1091 | } else |
1121 | baud_mask = (cflag & CBAUD); | ||
1122 | switch(baud_mask) { | ||
1123 | case B300: | ||
1124 | dbg("%s - setting baud 300bps", __FUNCTION__); | ||
1125 | break; | ||
1126 | case B600: | ||
1127 | dbg("%s - setting baud 600bps", __FUNCTION__); | ||
1128 | break; | ||
1129 | case B1200: | ||
1130 | dbg("%s - setting baud 1200bps", __FUNCTION__); | ||
1131 | break; | ||
1132 | case B2400: | ||
1133 | dbg("%s - setting baud 2400bps", __FUNCTION__); | ||
1134 | break; | ||
1135 | case B4800: | ||
1136 | dbg("%s - setting baud 4800bps", __FUNCTION__); | ||
1137 | break; | ||
1138 | case B9600: | ||
1139 | dbg("%s - setting baud 9600bps", __FUNCTION__); | ||
1140 | break; | ||
1141 | case B19200: | ||
1142 | dbg("%s - setting baud 19200bps", __FUNCTION__); | ||
1143 | break; | ||
1144 | case B38400: | ||
1145 | dbg("%s - setting baud 38400bps", __FUNCTION__); | ||
1146 | break; | ||
1147 | case B57600: | ||
1148 | dbg("%s - setting baud 57600bps", __FUNCTION__); | ||
1149 | break; | ||
1150 | case B115200: | ||
1151 | dbg("%s - setting baud 115200bps", __FUNCTION__); | ||
1152 | break; | ||
1153 | default: | ||
1154 | dbg("%s - unknown masked baud rate", __FUNCTION__); | ||
1155 | } | ||
1156 | priv->line_control = (CONTROL_DTR | CONTROL_RTS); | 1092 | priv->line_control = (CONTROL_DTR | CONTROL_RTS); |
1157 | } | ||
1158 | spin_unlock_irqrestore(&priv->lock, flags); | 1093 | spin_unlock_irqrestore(&priv->lock, flags); |
1159 | 1094 | ||
1160 | dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " | 1095 | dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " |
1161 | "%d data_bits (+5)", __FUNCTION__, stop_bits, | 1096 | "%d data_bits (+5)", __func__, stop_bits, |
1162 | parity_enable, parity_type, data_bits); | 1097 | parity_enable, parity_type, data_bits); |
1163 | 1098 | ||
1164 | cypress_serial_control(port, baud_mask, data_bits, stop_bits, | 1099 | cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits, |
1165 | parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); | 1100 | parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); |
1166 | 1101 | ||
1167 | /* we perform a CYPRESS_GET_CONFIG so that the current settings are | 1102 | /* we perform a CYPRESS_GET_CONFIG so that the current settings are |
@@ -1219,13 +1154,13 @@ static int cypress_chars_in_buffer(struct usb_serial_port *port) | |||
1219 | int chars = 0; | 1154 | int chars = 0; |
1220 | unsigned long flags; | 1155 | unsigned long flags; |
1221 | 1156 | ||
1222 | dbg("%s - port %d", __FUNCTION__, port->number); | 1157 | dbg("%s - port %d", __func__, port->number); |
1223 | 1158 | ||
1224 | spin_lock_irqsave(&priv->lock, flags); | 1159 | spin_lock_irqsave(&priv->lock, flags); |
1225 | chars = cypress_buf_data_avail(priv->buf); | 1160 | chars = cypress_buf_data_avail(priv->buf); |
1226 | spin_unlock_irqrestore(&priv->lock, flags); | 1161 | spin_unlock_irqrestore(&priv->lock, flags); |
1227 | 1162 | ||
1228 | dbg("%s - returns %d", __FUNCTION__, chars); | 1163 | dbg("%s - returns %d", __func__, chars); |
1229 | return chars; | 1164 | return chars; |
1230 | } | 1165 | } |
1231 | 1166 | ||
@@ -1235,7 +1170,7 @@ static void cypress_throttle (struct usb_serial_port *port) | |||
1235 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1170 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1236 | unsigned long flags; | 1171 | unsigned long flags; |
1237 | 1172 | ||
1238 | dbg("%s - port %d", __FUNCTION__, port->number); | 1173 | dbg("%s - port %d", __func__, port->number); |
1239 | 1174 | ||
1240 | spin_lock_irqsave(&priv->lock, flags); | 1175 | spin_lock_irqsave(&priv->lock, flags); |
1241 | priv->rx_flags = THROTTLED; | 1176 | priv->rx_flags = THROTTLED; |
@@ -1249,7 +1184,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) | |||
1249 | int actually_throttled, result; | 1184 | int actually_throttled, result; |
1250 | unsigned long flags; | 1185 | unsigned long flags; |
1251 | 1186 | ||
1252 | dbg("%s - port %d", __FUNCTION__, port->number); | 1187 | dbg("%s - port %d", __func__, port->number); |
1253 | 1188 | ||
1254 | spin_lock_irqsave(&priv->lock, flags); | 1189 | spin_lock_irqsave(&priv->lock, flags); |
1255 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | 1190 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; |
@@ -1265,7 +1200,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) | |||
1265 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1200 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
1266 | if (result) { | 1201 | if (result) { |
1267 | dev_err(&port->dev, "%s - failed submitting read urb, " | 1202 | dev_err(&port->dev, "%s - failed submitting read urb, " |
1268 | "error %d\n", __FUNCTION__, result); | 1203 | "error %d\n", __func__, result); |
1269 | cypress_set_dead(port); | 1204 | cypress_set_dead(port); |
1270 | } | 1205 | } |
1271 | } | 1206 | } |
@@ -1274,7 +1209,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) | |||
1274 | 1209 | ||
1275 | static void cypress_read_int_callback(struct urb *urb) | 1210 | static void cypress_read_int_callback(struct urb *urb) |
1276 | { | 1211 | { |
1277 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1212 | struct usb_serial_port *port = urb->context; |
1278 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1213 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1279 | struct tty_struct *tty; | 1214 | struct tty_struct *tty; |
1280 | unsigned char *data = urb->transfer_buffer; | 1215 | unsigned char *data = urb->transfer_buffer; |
@@ -1286,7 +1221,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1286 | int i = 0; | 1221 | int i = 0; |
1287 | int status = urb->status; | 1222 | int status = urb->status; |
1288 | 1223 | ||
1289 | dbg("%s - port %d", __FUNCTION__, port->number); | 1224 | dbg("%s - port %d", __func__, port->number); |
1290 | 1225 | ||
1291 | switch (status) { | 1226 | switch (status) { |
1292 | case 0: /* success */ | 1227 | case 0: /* success */ |
@@ -1302,14 +1237,14 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1302 | default: | 1237 | default: |
1303 | /* something ugly is going on... */ | 1238 | /* something ugly is going on... */ |
1304 | dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", | 1239 | dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", |
1305 | __FUNCTION__, status); | 1240 | __func__, status); |
1306 | cypress_set_dead(port); | 1241 | cypress_set_dead(port); |
1307 | return; | 1242 | return; |
1308 | } | 1243 | } |
1309 | 1244 | ||
1310 | spin_lock_irqsave(&priv->lock, flags); | 1245 | spin_lock_irqsave(&priv->lock, flags); |
1311 | if (priv->rx_flags & THROTTLED) { | 1246 | if (priv->rx_flags & THROTTLED) { |
1312 | dbg("%s - now throttling", __FUNCTION__); | 1247 | dbg("%s - now throttling", __func__); |
1313 | priv->rx_flags |= ACTUALLY_THROTTLED; | 1248 | priv->rx_flags |= ACTUALLY_THROTTLED; |
1314 | spin_unlock_irqrestore(&priv->lock, flags); | 1249 | spin_unlock_irqrestore(&priv->lock, flags); |
1315 | return; | 1250 | return; |
@@ -1318,48 +1253,48 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1318 | 1253 | ||
1319 | tty = port->tty; | 1254 | tty = port->tty; |
1320 | if (!tty) { | 1255 | if (!tty) { |
1321 | dbg("%s - bad tty pointer - exiting", __FUNCTION__); | 1256 | dbg("%s - bad tty pointer - exiting", __func__); |
1322 | return; | 1257 | return; |
1323 | } | 1258 | } |
1324 | 1259 | ||
1325 | spin_lock_irqsave(&priv->lock, flags); | 1260 | spin_lock_irqsave(&priv->lock, flags); |
1326 | switch(urb->actual_length) { | 1261 | result = urb->actual_length; |
1327 | case 32: | 1262 | switch (priv->pkt_fmt) { |
1328 | /* This is for the CY7C64013... */ | 1263 | default: |
1329 | priv->current_status = data[0] & 0xF8; | 1264 | case packet_format_1: |
1330 | bytes = data[1] + 2; | 1265 | /* This is for the CY7C64013... */ |
1331 | i = 2; | 1266 | priv->current_status = data[0] & 0xF8; |
1332 | if (bytes > 2) | 1267 | bytes = data[1] + 2; |
1333 | havedata = 1; | 1268 | i = 2; |
1334 | break; | 1269 | if (bytes > 2) |
1335 | case 8: | 1270 | havedata = 1; |
1336 | /* This is for the CY7C63743... */ | 1271 | break; |
1337 | priv->current_status = data[0] & 0xF8; | 1272 | case packet_format_2: |
1338 | bytes = (data[0] & 0x07) + 1; | 1273 | /* This is for the CY7C63743... */ |
1339 | i = 1; | 1274 | priv->current_status = data[0] & 0xF8; |
1340 | if (bytes > 1) | 1275 | bytes = (data[0] & 0x07) + 1; |
1341 | havedata = 1; | 1276 | i = 1; |
1342 | break; | 1277 | if (bytes > 1) |
1343 | default: | 1278 | havedata = 1; |
1344 | dbg("%s - wrong packet size - received %d bytes", | 1279 | break; |
1345 | __FUNCTION__, urb->actual_length); | ||
1346 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1347 | goto continue_read; | ||
1348 | } | 1280 | } |
1349 | spin_unlock_irqrestore(&priv->lock, flags); | 1281 | spin_unlock_irqrestore(&priv->lock, flags); |
1282 | if (result < bytes) { | ||
1283 | dbg("%s - wrong packet size - received %d bytes but packet " | ||
1284 | "said %d bytes", __func__, result, bytes); | ||
1285 | goto continue_read; | ||
1286 | } | ||
1350 | 1287 | ||
1351 | usb_serial_debug_data (debug, &port->dev, __FUNCTION__, | 1288 | usb_serial_debug_data (debug, &port->dev, __func__, |
1352 | urb->actual_length, data); | 1289 | urb->actual_length, data); |
1353 | 1290 | ||
1354 | spin_lock_irqsave(&priv->lock, flags); | 1291 | spin_lock_irqsave(&priv->lock, flags); |
1355 | /* check to see if status has changed */ | 1292 | /* check to see if status has changed */ |
1356 | if (priv != NULL) { | 1293 | if (priv->current_status != priv->prev_status) { |
1357 | if (priv->current_status != priv->prev_status) { | 1294 | priv->diff_status |= priv->current_status ^ |
1358 | priv->diff_status |= priv->current_status ^ | 1295 | priv->prev_status; |
1359 | priv->prev_status; | 1296 | wake_up_interruptible(&priv->delta_msr_wait); |
1360 | wake_up_interruptible(&priv->delta_msr_wait); | 1297 | priv->prev_status = priv->current_status; |
1361 | priv->prev_status = priv->current_status; | ||
1362 | } | ||
1363 | } | 1298 | } |
1364 | spin_unlock_irqrestore(&priv->lock, flags); | 1299 | spin_unlock_irqrestore(&priv->lock, flags); |
1365 | 1300 | ||
@@ -1367,7 +1302,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1367 | * though */ | 1302 | * though */ |
1368 | if (tty && !(tty->termios->c_cflag & CLOCAL) && | 1303 | if (tty && !(tty->termios->c_cflag & CLOCAL) && |
1369 | !(priv->current_status & UART_CD)) { | 1304 | !(priv->current_status & UART_CD)) { |
1370 | dbg("%s - calling hangup", __FUNCTION__); | 1305 | dbg("%s - calling hangup", __func__); |
1371 | tty_hangup(tty); | 1306 | tty_hangup(tty); |
1372 | goto continue_read; | 1307 | goto continue_read; |
1373 | } | 1308 | } |
@@ -1380,7 +1315,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1380 | if (priv->current_status & CYP_ERROR) { | 1315 | if (priv->current_status & CYP_ERROR) { |
1381 | spin_unlock_irqrestore(&priv->lock, flags); | 1316 | spin_unlock_irqrestore(&priv->lock, flags); |
1382 | tty_flag = TTY_PARITY; | 1317 | tty_flag = TTY_PARITY; |
1383 | dbg("%s - Parity Error detected", __FUNCTION__); | 1318 | dbg("%s - Parity Error detected", __func__); |
1384 | } else | 1319 | } else |
1385 | spin_unlock_irqrestore(&priv->lock, flags); | 1320 | spin_unlock_irqrestore(&priv->lock, flags); |
1386 | 1321 | ||
@@ -1414,7 +1349,7 @@ continue_read: | |||
1414 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1349 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
1415 | if (result) { | 1350 | if (result) { |
1416 | dev_err(&urb->dev->dev, "%s - failed resubmitting " | 1351 | dev_err(&urb->dev->dev, "%s - failed resubmitting " |
1417 | "read urb, error %d\n", __FUNCTION__, | 1352 | "read urb, error %d\n", __func__, |
1418 | result); | 1353 | result); |
1419 | cypress_set_dead(port); | 1354 | cypress_set_dead(port); |
1420 | } | 1355 | } |
@@ -1426,12 +1361,12 @@ continue_read: | |||
1426 | 1361 | ||
1427 | static void cypress_write_int_callback(struct urb *urb) | 1362 | static void cypress_write_int_callback(struct urb *urb) |
1428 | { | 1363 | { |
1429 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1364 | struct usb_serial_port *port = urb->context; |
1430 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1365 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1431 | int result; | 1366 | int result; |
1432 | int status = urb->status; | 1367 | int status = urb->status; |
1433 | 1368 | ||
1434 | dbg("%s - port %d", __FUNCTION__, port->number); | 1369 | dbg("%s - port %d", __func__, port->number); |
1435 | 1370 | ||
1436 | switch (status) { | 1371 | switch (status) { |
1437 | case 0: | 1372 | case 0: |
@@ -1442,7 +1377,7 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1442 | case -ESHUTDOWN: | 1377 | case -ESHUTDOWN: |
1443 | /* this urb is terminated, clean up */ | 1378 | /* this urb is terminated, clean up */ |
1444 | dbg("%s - urb shutting down with status: %d", | 1379 | dbg("%s - urb shutting down with status: %d", |
1445 | __FUNCTION__, status); | 1380 | __func__, status); |
1446 | priv->write_urb_in_use = 0; | 1381 | priv->write_urb_in_use = 0; |
1447 | return; | 1382 | return; |
1448 | case -EPIPE: /* no break needed; clear halt and resubmit */ | 1383 | case -EPIPE: /* no break needed; clear halt and resubmit */ |
@@ -1451,19 +1386,19 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1451 | usb_clear_halt(port->serial->dev, 0x02); | 1386 | usb_clear_halt(port->serial->dev, 0x02); |
1452 | /* error in the urb, so we have to resubmit it */ | 1387 | /* error in the urb, so we have to resubmit it */ |
1453 | dbg("%s - nonzero write bulk status received: %d", | 1388 | dbg("%s - nonzero write bulk status received: %d", |
1454 | __FUNCTION__, status); | 1389 | __func__, status); |
1455 | port->interrupt_out_urb->transfer_buffer_length = 1; | 1390 | port->interrupt_out_urb->transfer_buffer_length = 1; |
1456 | port->interrupt_out_urb->dev = port->serial->dev; | 1391 | port->interrupt_out_urb->dev = port->serial->dev; |
1457 | result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); | 1392 | result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); |
1458 | if (!result) | 1393 | if (!result) |
1459 | return; | 1394 | return; |
1460 | dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", | 1395 | dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", |
1461 | __FUNCTION__, result); | 1396 | __func__, result); |
1462 | cypress_set_dead(port); | 1397 | cypress_set_dead(port); |
1463 | break; | 1398 | break; |
1464 | default: | 1399 | default: |
1465 | dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n", | 1400 | dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n", |
1466 | __FUNCTION__, status); | 1401 | __func__, status); |
1467 | cypress_set_dead(port); | 1402 | cypress_set_dead(port); |
1468 | break; | 1403 | break; |
1469 | } | 1404 | } |
@@ -1668,7 +1603,7 @@ static int __init cypress_init(void) | |||
1668 | { | 1603 | { |
1669 | int retval; | 1604 | int retval; |
1670 | 1605 | ||
1671 | dbg("%s", __FUNCTION__); | 1606 | dbg("%s", __func__); |
1672 | 1607 | ||
1673 | retval = usb_serial_register(&cypress_earthmate_device); | 1608 | retval = usb_serial_register(&cypress_earthmate_device); |
1674 | if (retval) | 1609 | if (retval) |
@@ -1699,7 +1634,7 @@ failed_em_register: | |||
1699 | 1634 | ||
1700 | static void __exit cypress_exit (void) | 1635 | static void __exit cypress_exit (void) |
1701 | { | 1636 | { |
1702 | dbg("%s", __FUNCTION__); | 1637 | dbg("%s", __func__); |
1703 | 1638 | ||
1704 | usb_deregister (&cypress_driver); | 1639 | usb_deregister (&cypress_driver); |
1705 | usb_serial_deregister (&cypress_earthmate_device); | 1640 | usb_serial_deregister (&cypress_earthmate_device); |