'Personal Computer/debug, iom_v2'에 해당되는 글 12건

  1. 2005.06.14 간헐적으로 sleep/wakeup시 먹통이 되는 현상... 2
  2. 2005.06.14 한번에 한놈만 open?
BUG중에서 잡기 힘든 유형이다.
항상 발생하는게 아니고 여러번 반복해야 발견이 되니 몸이 아주 귀찮다. (그렇다고 log를 남길 검증자들이 아니다. 현상만 보고한다.)

그렇다고 저 현상을 찾기 위해 몸이 수고할 tolkien이 아니지. 자동화 tool 만든다고 mz_test 만들다가 급한 것같아서 일단 자동 wakeup한다고 rtcwakeup code 손보다가 삽질을 했지만, 결국 자동화 code 돌린지 1시간만에 원인 발견.

돌린지 17번째 횟수에서 한번 발견, touch interrupt가 들어오지 않는 것을 확인하고 다시 한번 돌려서 31번째 다시 현상 재확인.
registers.o를 올려서 이것저것 확인해보니...

# cat /proc/cpu/registers/GAFR2_U
0x01000002
# cat /proc/cpu/registers/GPDR2
0x0ec1ffff
# cat /proc/cpu/registers/GPLR2
0x7501cf5c

# cat 76-AC97_WM9705_TS1
0xe020
0b.1110.0000.0010.0000
15 - POLL
14:12 - ADC_SEL (BMON)
7: 4 - DEL (83.8us)
# cat 78-AC97_WM9705_TS2
0xe281
0b.1110.0010.1000.0001
15:14 - RPR (running)
13 - RPR (AC-line & wm9712 auto-wake-up)
9 - WAIT (until old data has been read)
8 - PIL (400uA)
1 - RPU (64k-Ohm)

이런... battery 값을 안 가져갔네? 0x78 register에 WAIT이 setting되 어있으니 이전 값을 가져가기 전까지는 새로운 값을 가져올 수 없다.라는 것이다. (그전에는 h/w팀의 인 줄 알았다.)

이런이런... 부랴부랴 code patch를 했다.
sleep/wakeup 구간에 진입했을때 ADC-request가 들어오면 그냥 빠져나오게 하고 혹시나 해서...

ret = ts_reg_read(AC97_WM9705_DAT);

로 강제적으로 값을 읽어버리게 하고 등등... 해서 다시 test를 돌리니까 잘 되는 것같아 기분이 좋았다. ^^

근데, 지금 생각해보니...

clear_bit(WM9705OTH_RUNNING, &wm9705bat.flag);
clear_bit(WM9705OTH_RUNNING, &wm9705bat_type.flag);

같은 code는 두번 register되는 문제가 있지 않을까? 응?

wake_up_interruptible(&info->wq);
wake_up_interruptible(&info->type_wq);

이렇게 해서 깨어나면 error 처리해야 iom_v2란 놈이 제대로 처리할텐데 왠지 불안하다. --;;;
에구에구, 출근해서 고쳐야겠네. (흑... 그리고 다시 test... T.T 밤새 걸어놓은게 무의미해짐.)

좌우간 자동화 test tool은 필요하다. 게으른 자에게는...

한번에 한놈만 open?

Personal Computer/debug, iom_v2 2005. 6. 14. 08:41 posted by tolkien
drivers/char/sa1100-rtc.c에서 open()쪽을 보면...

if (test_and_set_bit (1, &rtc_status))
return -EBUSY;
rtc_irq_data = 0;

짜잔~ 다른 놈이 open하고 있으면 다시는 안 열린다.
RTC 동작방식을 생각하면 일견 이해가 되지만, 문제는 debugging...
sleep/wakeup에 문제가 있어 debugging하려니 영~불편하군.

임시로 return -EBUSY를 skip하게 만들어서 kernel을 올려서 test하다가 자주 이런 일이 발생할 것같기도 해서...
내친김에 run-time debugging feature를 만들어버렸다.

static __inline__ int mz_debug_on_p(void) {
return (mz_ops.stat & MZ_DEBUG_ON);
}

echo 1 > /proc/sys/debug/enable 이면 debugging-on
0이면 off하게...
가볍게 생각하고 다음과 같이 code를 고치고 룰루랄라했는데...

if (test_and_set_bit (1, &rtc_status))
+#ifdef CONFIG_MIZI
+ if (!mz_debug_on_p())
+#endif
return -EBUSY;
rtc_irq_data = 0;

이런... 한번 debugging feature를 on 시켜서 강제로 열면 계속 열리는 것이 아닌가!!! 헐헐헐... 가볍게 끝날 것같던 code가 결국 5시간이나 debugging을 해야했다. (중간에 점심시간을 생각해도 T.T)

close()쪽에서 rtc_status를 clear하는 것을 미쳐 생각 못한 것.
더하기 변수 하나 (open된 횟수 세는 놈) 추가하기 싫어서 rtc_status의 상위 16bit가지고 끄적거린다고 버린 시간이 5시간 된 것이다. --;;;

결국 변수하나 추가하고 (처음부터 그럴 것이지...) 해결봤다.

open()...
#ifdef CONFIG_MIZI
if (mz_debug_on_p()) {
rtc_open_cnt++;
if (!test_and_set_bit (1, &rtc_status))
rtc_irq_data = 0;
return 0;
}
#endif
if (test_and_set_bit (1, &rtc_status))
return -EBUSY;
#ifdef CONFIG_MIZI
rtc_open_cnt++;
#endif
rtc_irq_data = 0;
return 0;

close()...
#ifdef CONFIG_MIZI
rtc_open_cnt--;
if (mz_debug_on_p()) {
if (rtc_open_cnt > 0)
return 0;
}
#endif
spin_lock_irq (&rtc_lock);
RTSR = 0;
blah... blah...