aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorDuncan Sands <duncan.sands@math.u-psud.fr>2005-06-23 03:37:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-07-12 14:52:55 -0400
commit1a7aad15ff93be104c8e0851a43b94f8ccd92225 (patch)
tree943d64e19c20871b20637e4e51dfdb950e28cad0 /drivers/usb
parentcd5c08fb7b0d960b7cd48bc977feee7b3bd8b046 (diff)
[PATCH] USB ATM: fix line resync logic
We map states 0x00 and 0x10 to the ATM_PHY_SIG_LOST flag. The current logic fails to resync the line if we get state 0x10 followed by 0x00, since we only resync the line when the state is 0x00 and the flag changed. Doubly fixed by (1) always resyncing the line when the state is 0x00 even if the state didn't change, and (2) keeping track of the last state, not just the flag. We do (2) as well as (1) in order to get better log messages. This is a tweaked version of the original patch by Aurelio Arroyo. Signed-off-by: Duncan Sands <baldrick@free.fr> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/atm/speedtch.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 03a0e99a4267..d0cbbb7f0385 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -100,6 +100,8 @@ struct speedtch_instance_data {
100 100
101 struct work_struct status_checker; 101 struct work_struct status_checker;
102 102
103 unsigned char last_status;
104
103 int poll_delay; /* milliseconds */ 105 int poll_delay; /* milliseconds */
104 106
105 struct timer_list resubmit_timer; 107 struct timer_list resubmit_timer;
@@ -423,7 +425,8 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
423 struct usbatm_data *usbatm = instance->usbatm; 425 struct usbatm_data *usbatm = instance->usbatm;
424 struct atm_dev *atm_dev = usbatm->atm_dev; 426 struct atm_dev *atm_dev = usbatm->atm_dev;
425 unsigned char *buf = instance->scratch_buffer; 427 unsigned char *buf = instance->scratch_buffer;
426 int ret; 428 int down_speed, up_speed, ret;
429 unsigned char status;
427 430
428 atm_dbg(usbatm, "%s entered\n", __func__); 431 atm_dbg(usbatm, "%s entered\n", __func__);
429 432
@@ -436,37 +439,34 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
436 439
437 instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY); 440 instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY);
438 441
439 atm_dbg(usbatm, "%s: line state %02x\n", __func__, buf[OFFSET_7]); 442 status = buf[OFFSET_7];
440 443
441 switch (buf[OFFSET_7]) { 444 atm_dbg(usbatm, "%s: line state %02x\n", __func__, status);
442 case 0: 445
443 if (atm_dev->signal != ATM_PHY_SIG_LOST) { 446 if ((status != instance->last_status) || !status) {
447 switch (status) {
448 case 0:
444 atm_dev->signal = ATM_PHY_SIG_LOST; 449 atm_dev->signal = ATM_PHY_SIG_LOST;
445 atm_info(usbatm, "ADSL line is down\n"); 450 if (instance->last_status)
446 /* It'll never resync again unless we ask it to... */ 451 atm_info(usbatm, "ADSL line is down\n");
452 /* It may never resync again unless we ask it to... */
447 ret = speedtch_start_synchro(instance); 453 ret = speedtch_start_synchro(instance);
448 } 454 break;
449 break;
450 455
451 case 0x08: 456 case 0x08:
452 if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
453 atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 457 atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
454 atm_info(usbatm, "ADSL line is blocked?\n"); 458 atm_info(usbatm, "ADSL line is blocked?\n");
455 } 459 break;
456 break;
457 460
458 case 0x10: 461 case 0x10:
459 if (atm_dev->signal != ATM_PHY_SIG_LOST) {
460 atm_dev->signal = ATM_PHY_SIG_LOST; 462 atm_dev->signal = ATM_PHY_SIG_LOST;
461 atm_info(usbatm, "ADSL line is synchronising\n"); 463 atm_info(usbatm, "ADSL line is synchronising\n");
462 } 464 break;
463 break;
464 465
465 case 0x20: 466 case 0x20:
466 if (atm_dev->signal != ATM_PHY_SIG_FOUND) { 467 down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
467 int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
468 | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); 468 | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
469 int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) 469 up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
470 | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); 470 | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24);
471 471
472 if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) { 472 if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) {
@@ -480,15 +480,15 @@ static void speedtch_check_status(struct speedtch_instance_data *instance)
480 atm_info(usbatm, 480 atm_info(usbatm,
481 "ADSL line is up (%d kb/s down | %d kb/s up)\n", 481 "ADSL line is up (%d kb/s down | %d kb/s up)\n",
482 down_speed, up_speed); 482 down_speed, up_speed);
483 } 483 break;
484 break;
485 484
486 default: 485 default:
487 if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
488 atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 486 atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
489 atm_info(usbatm, "Unknown line state %02x\n", buf[OFFSET_7]); 487 atm_info(usbatm, "Unknown line state %02x\n", status);
488 break;
490 } 489 }
491 break; 490
491 instance->last_status = status;
492 } 492 }
493} 493}
494 494
@@ -728,6 +728,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
728 728
729 instance->status_checker.timer.function = speedtch_status_poll; 729 instance->status_checker.timer.function = speedtch_status_poll;
730 instance->status_checker.timer.data = (unsigned long)instance; 730 instance->status_checker.timer.data = (unsigned long)instance;
731 instance->last_status = 0xff;
731 instance->poll_delay = MIN_POLL_DELAY; 732 instance->poll_delay = MIN_POLL_DELAY;
732 733
733 init_timer(&instance->resubmit_timer); 734 init_timer(&instance->resubmit_timer);