Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://www.arcetri.astro.it/irlab/doc/library/linux/khg/HyperNews/get/devices/basics/1.html
Дата изменения: Thu Mar 23 12:37:13 2000 Дата индексирования: Wed Sep 15 04:18:54 2010 Кодировка: Поисковые слова: п п п п п п п п п п п п п п п п п п |
Hello; I have need for a select() entry point in my driver but my device is not using interrupts so I'm not sure how to have the os call my select() to let me poll the device. I think I must use a timer, with select_wait(), so the system will call my select() until my device becomes active. The trouble is I can not seem to get the timer work. The entire system hangs _solid_ whenever it gets activated. Below is my select() code. I use wake_up_interruptible() as the function the timer will call in the future to just make this process runnable again, in lieu of calling it from an interrupt service routine. A few specific questions: 1) my driver permits several processes to have the device open at once. Am I correct in assuming that if this general approach works I will need a separate timer_list and wait_queue for each open process instance? 2) In no examples do I ever see the wait_queue pointer ever _set_ to point at an actual wait_queue instance. Is this correct? Any comments would be greatly appreciated. Rememeber, the only real goal here is some way to get the os to call us occasionally to let us poll the device, but the device is not using interrupts. Thank you in advance; Elwood Downey static int pc39_select (struct inode *inode, struct file *file, int sel_type, select_table *wait) { static struct timer_list pc39_tl; static struct wait_queue *pc39_wq; switch (sel_type) { case SEL_EX: return (0); /* never any exceptions */ case SEL_IN: if (IBF()) return (1); break; case SEL_OUT: if (TBE()) return (1); break; } /* nothing ready -- set timer to try again later if necessary */ if (wait) { init_timer (&pc39_tl); pc39_tl.expires = PC39_SELTO; pc39_tl.function = (void(*)(unsigned long))wake_up_interruptible; pc39_tl.data = (unsigned long) &pc39_wq; add_timer (&pc39_tl); select_wait (&pc39_wq, wait); } return (0); } |