부상입다.

오늘은.../InLine Skate 2005. 6. 20. 12:04 posted by tolkien
MT를 못간 사람들끼리 비정기로드중
여의도에서 잠실로 가다가 앞사람에게 걸려서 넘어졌다. 하필이며 보호대를 하지않은 팔꿈치를 확 갈아버렸다는. T.T


결론. 보호대를 하고 탑시다.
2005년 6월 16일 23시 40분 돌아가시다.

sleep/wakeup 문제

Personal Computer/Linux 2005. 6. 16. 14:36 posted by tolkien
총 5개 문제중...

1. kernel쪽 wm9705_ts.c에서 pm_callback에서 처리를 제대로 못해서 발생한 문제 2건
2. skywalker가 먹통이 되서 발생한 듯한 문제 1건
3. h/w쪽으로 의심되는 문제가 1건
4. kernel이 아닐까 막연하게 의심되는 문제 1건

중에서 이제 1.번 항목 하나 처리했다. 나머지는 어떻게 원인을 밝혀내지? @.@

mz_test Implementation Specification

Personal Computer/misc 2005. 6. 15. 17:27 posted by tolkien
1. mz_tst_t ("입력"을 저장하는 buffer)
a. id : key_input? ts_input?
b. buf[] : 실제 data를 저장 (key는 scancode, pressed. ts는 x,y,pressed)
c. jiffies : 각 "입력"이 발생한 시각

2. 기록
a. key는 handle_scancode, ts는 wm9705_ts_put_xy에서 "입력"을 가로챈다
b. mzt_put_queue(id, buf) or mzt_put_queue(mz_tst_t)
c. read()는 한번에 한 "입력"씩 application에 보내자.
d. poll()은 buffer가 채워지면 바로 return, 그렇다면 mzt_put_queue에서 wake_up(wait_queue)
e. 별도의 ioctl()을 쓰지말고, open(..., O_RDONLY)하는 순간 recoding start!!!

3. 재현
a. open(..., O_WRONLY)하고나서 처음 write()할때 "재현"시작
b. 그러면 한번에 여러번 data를 받게 해야하나... @.@
c. mod_timer(&mzt_timer, jiffies + 현재_입력.jiffies - 이전_입력.jiffies)
d. key는 handle_scancode()를 이용해서 강제로 넣고,
e. ts는 wm9705_ts_put_buffer()랑 비슷한 놈을 만들어야하나...

mz_test Function Specification

Personal Computer/misc 2005. 6. 15. 17:26 posted by tolkien
다른 곳에 작성한 건데... 이곳으로 옮깁니다. (그곳을 지울거라서...)

1. 목적
a. 사용자로부터 입력받은대로 똑같이 재현한다.
b. 사용자 입력은 KeyButton, TouchScreen 두가지 device를 통해서 입력됨.

2. 사용자 입력을 기록
open("/dev/misc/test", O_RDONLY)
read("/dev/misc/test", buf, len);

3. 저장된 사용자 입력을 재현
open("/dev/misc/test", O_WRONLY)
write("/dev/misc/test", buf, len);

4. 한번에 한명의 사용자만 device를 open할 수 있슴. (독점적)
open(..., O_RDWR)은 -EINVAL을 return.

아바 6주년 기념로드.

오늘은.../InLine Skate 2005. 6. 14. 09:25 posted by tolkien
2005년 6월 2번째 일요일이 아바가 한강에서 로드런 한지 6년째 되는 날이었다.
(언제냐구? 달력보고 확인해봐요.)


일에 찌든...

오늘은.../살아가는 이야기 2005. 6. 14. 09:12 posted by tolkien
때를 말끔히 벗기고 싶네.
귀찮아서 안 쓰다가 다시 쓰니 내용이 순 일하는 얘기...

음. 지난주 일요일이 아바정기로드한지 6년째 되는 날이었고, (본인은 4년차 회원이다. 처음 1년간은 유령...)
이번주 토요일에 아바MT니 그전에 재필이 녀석 결혼한다는데 만나서 축하해줘야 할텐데...
담주는 승빈이가 MT가자고 하는데 갈 수 있을까? (문제는 호응...)
다담주는 정선이 얘기 돐!

주말만 바쁘군!!!
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...

PM_STATE_UNKNOWN!!!

Personal Computer/Linux 2005. 6. 14. 08:40 posted by tolkien
drivers/char/serial.c에서 pm관련 code...

pm_rs_callback(...) {
int i = 0;

while (i < NR_PORTS) {
struct async_struct * info = rs_table[i].info;
if (req == PM_LAST_SLEEP_CHECK && info ) {
blah... blah...
} else if (req == PM_FIRST_WAKEUP_CHECK && info) {
blah... blah...
} else
return ENOENT;
i++;
}
return 0;
}

이렇게 하니까, 나중에 wakeup한 다음에 pm->state가 PM_FIRST_WAKEUP_CHECK가 아닌
PM_STATE_UNKNOWN으로 나온다. ???
이해를 못함. 그래서 이렇게 바꾸어봤다.

pm_rs_callback(...) {
int i;

if (req == PM_LAST_SLEEP_CHECK) {
for(i=0; i < NR_PORTS; i++) {
struct async_struct * info = rs_table[i].info;
if (info) {
blah... blah...
}
}
} else if (req == PM_FIRST_WAKEUP_CHECK) {
for(i=0; i < NR_PORTS; i++) {
struct async_struct * info = rs_table[i].info;
if (info) {
blah... blah...
}
}
} else {
return ENOENT;
}
return 0;
}

그랬더니 pm->state가 변한다. PM_FIRST_WAKEUP_CHECK로 기억... (아니면 PM_HID_RESUME이었던가... 이런 확인해봐야겠네.)

그 이유가 뭔지 확인해야하겠지?