2.4.20 디바이스 드라이버 mousedev 에서

quintus의 이미지

마우스 드라이버 모듈이 등록 되면서

473 static int __init mousedev_init(void)
474 {
475         [b]input_register_handler(&mousedev_handler);[/b]
476 
477         memset(&mousedev_mix, 0, sizeof(struct mousedev));
478         init_waitqueue_head(&mousedev_mix.wait);
479         mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
480         mousedev_mix.exist = 1;
481         mousedev_mix.minor = MOUSEDEV_MIX;
482         mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);
483 
484         printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
485 
486         return 0;
487 }

475 줄에서 input_register_handler 가 불리어지고

input.c 파일에서

305 void input_register_handler(struct input_handler *handler)
306 {
307         struct input_dev *dev = [b]input_dev;[/b]
308         struct input_handle *handle;
309 
310 /*
311  * Add minors if needed.
312  */
313 
314         if (handler->fops != NULL)
315                 input_table[handler->minor >> 5] = handler;
316 
317 /*
318  * Add the handler.
319  */
320 
321         handler->next = input_handler;  
322         input_handler = handler;
323         
324 /*
325  * Notify it about all existing devices.
326  */
327 
328         while (dev) {
329                 if ((handle = handler->connect(handler, dev)))
330                         input_link_handle(handle);
331                 dev = dev->next;
332         }
333 }

307 줄에 전역 변수로 선언되어진

56 static struct input_dev *input_dev;
가 사용 되는데 그 변수가 사용 되는 곳은 input.c 파일에서
226 void input_register_device(struct input_dev *dev)
227 {
228         struct input_handler *handler = input_handler;
229         struct input_handle *handle;
230 
231 /*
232  * Initialize repeat timer to default values.
233  */
234 
235         init_timer(&dev->timer);
236         dev->timer.data = (long) dev;
237         dev->timer.function = input_repeat_key;
238         dev->rep[REP_DELAY] = HZ/4;
239         dev->rep[REP_PERIOD] = HZ/33;
240 
241 /*
242  * Add the device.
243  */
244 
245         if (input_number >= INPUT_DEVICES) {
246                 printk(KERN_WARNING "input: ran out of input device numbers!\n");
247                 dev->number = input_number;
248         } else {
249                 dev->number = find_first_zero_bit(input_devices, INPUT_DEVICES);
250                 set_bit(dev->number, input_devices);
251         }
252                 
[b]253         dev->next = input_dev;  
254         input_dev = dev;[/b]255         input_number++;
256 
257 /*
258  * Notify handlers.
259  */
260 
261         while (handler) {
262                 if ((handle = handler->connect(handler, dev)))
263                         input_link_handle(handle);
264                 handler = handler->next;
265         }
266 }
267 

253, 254 줄 밖에 없습니다.

그런데 선언된 후 값이 할당 되지 않은 input_dev 가 저렇게 사용되면 어떤 의미인지 궁금합니다.

253         dev->next = input_dev;  
254         input_dev = dev;

mousedev.c 에서는 input_register_device 라는 함수가 사용되지도 않았는데 어찌 input_register_handler 에서 input_dev 라는 변수를 사용할 수 있는지 궁금합니다.

마지막으로

465 static struct input_handler mousedev_handler = {
466         event:          mousedev_event,
467         connect:        mousedev_connect,
468         disconnect:     mousedev_disconnect,
469         fops:           &mousedev_fops,
470         minor:          MOUSEDEV_MINOR_BASE,
471 };
에서 connect, disconnect, event는 뭘 말하는건가요..
마우스를 연결하면 connect라는 함수가 불리어지는건가요? 책도 찾아보고 검색도 해 봐도 잘 모르겠습니다.
tolkien의 이미지

input subsystem에서 handler하고 device는 별개입니다.
그림으로 그려보면 다음과 같은 구조라고 생각합니다.
(아직 input subsystem을 한번 쳐다보진 않았지만, 다른 system쪽을 보면 대충 짐작은 됩니다.)

[ hw, low, ..., kernel, ..., high, user/sw - ---]
device - input glue - handler -- input device interface - ...

이런 식으로 되어 있고, 위에 예를 든 mouse device driver는
handler하고 device를 둘 다 등록하는 것같은데요.

/* handler 등록 */
input_register_handler(&mousedev_handler);

/* device 등록, 아마 input_register_device의 wrapper일 듯 */
input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);

이럴때 handler가 먼저 등록하는가 device를 먼저 등록하는가 에 따라서
문제가 생길 수 있기 때문에 등록할 때마다 handler->connect()를 호출합니다.
이걸로 미루어 보면 connect()은 device 또는 handler 등록시 호출되는 함수이고,
각각의 handler->connect() 함수는 매번 불리울 때마다 자신이 처리할 수 있는 device인지
확인하는 것이 필요하겠네요.
disconnect()은 device 또는 handler 해제시 불리우는 함수이고,
event()는 device에서 입력이 발생할때 불리우는 함수, 즉 실제 ddata를 처리하는 부분입니다.

brain2012의 이미지

내부적인 구조를 전체다 긁어보진 못했기 때문에

위에분처럼 구조도를 말씀드릴순 없겠군요; (내공부족 ㅠ_ㅠ)

제가 본것은 USB mouse device driver 이었기 때문에 구조가 살짝 다릅니다만은

어쨌든 connect함수의 역할은 이 드라이버가 처리할 디바이스가 있는지 조건의 검색과

조건이 합당하다면 (인터럽트 방식인지 아닌지 Endpoint가 in인지 out인지.. 등등등)

그 디바이스를 처리하기 위한 구조체들(input_dev 등등)을 메모리 할당 및 초기화 하기 시작합니다.

그중 input_dev는 시스템에 input device로서의 등록을 위해 필요한 구조체로 알고있습니다.

kmalloc를 호출하여 이루어질수도 있고 input_allocate_device()라는 함수를 호출하여 이루어 질수도 있습니다.

2.4버전대에서는 아마도 전자가 아닐까 하네요.

어쨌든 input.c의 329 line을 보시면 전역으로 선언된 input_dev의 포인터를 인자로 넘겨주는 것을 보실수 있습니다.

그러면 내부에서 할당된 메모리를 거기에 메달아 주겠지요.

때문에 input_device_register() 에서 input_dev를 사용하는 순간에는 이미 할당 및 초기화가 이루어져있기 때문에

input_dev가 값이 할당되지 않은체로 사용되는 일은 없습니다.

메모리 할당이 어떤 이유에서든 되지 않는다면 connect함수가 도중에 작업을 중단해버릴껍니다.

connect함수의 일은 위에서 설명드린바와 같고

disconnect함수는 connect함수와 반대로 할당되었던 메모리들을 해제시킵니다.

내부에서 참조값에 따라 완전히 해제할것인지 아니면 특정 부분만 해제할것인지 구분해 처리할껍니다.

event함수는 device에서 입력이 발생했을때 그 신호에 대해 처리해주는 부분입니다.

(USB device의 경우 데이터값을 가져올 interval을 설정할 수 있습니다 - 보통 10ms)

아마 input_report_??? (key,rel 등등..) 함수를 이용해서

해당값이 이 디바이스에서 사용하기로 한 값인지 확인하고 그 처리를 시스템에 요청할껍니다.

그 밑으로는 인라인어셈으로 짜여져있는게 많아서 더 따라가보지는 못했습니다; (ㅠ_ㅠ )

도움이 되셨는지..

아참.. 참고로 이건 사짜 정보일 수 있습니다. (틀린게 있을수도.. 먼산;;)

자료를 찾을 수 없어 소스보며 날림 분석한거라 -_-v

그럼 이만..

이상한점이나 틀린것을 가르쳐 주시거나 질문 하시겠다면 - brain2012@naver.com 으로!!

========================================================

너만 보고 달려요!

brain2012의 이미지


오오오.. 그런데 이 글..

글쓴이가 질문을 2005년도 9월달에 하셨군요 -________________________-;

tolkien님은 어떻게 찾아서 덧글다셨다지 -_-a

전 최근글에서 눈의 띄길래 달았;

========================================================

지하에서 땅파던 삽질마왕 지상에 출몰하다! ( ^-_-^)

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.