三、Linux input 子系統學習之register_input_handler 分析__Linux

來源:互聯網
上載者:User
這一篇,我們來分析input_register_handler 這個非常重要的函數。就像之前說過的一樣,這是註冊一個驅動。

  我們去input目錄下看看那些檔案調用的這個函數,分別有:evdev.c(evdev驅動)、joydev.c(joydev驅動)、keychord.c(按鍵驅動)、mousedev.c(滑鼠驅動)。
  也即是每個檔案,對於一種驅動,並在裡面進行註冊驅動。

 好的,那麼我們以evdev.c為例子分析就好了。因為,觸控螢幕裝置也是對應這個驅動。
 
 1、看看入口函數

點擊(此處)摺疊或開啟 static const struct input_device_id evdev_ids[] = {
    { .driver_info = 1 },    /* Matches all devices */
    { },            /* Terminating zero entry */
};

MODULE_DEVICE_TABLE(input, evdev_ids);

static struct input_handler evdev_handler = {
    .event        = evdev_event,
    .connect    = evdev_connect,
    .disconnect    = evdev_disconnect,
    .fops        = &evdev_fops,
    .minor        = EVDEV_MINOR_BASE,
    .name        = "evdev",
    .id_table    = evdev_ids,
};

static int __init evdev_init(void)
{
    return input_register_handler(&evdev_handler);
}

    入口函數裡面,啥都沒幹,就直接註冊了一個evdev_handler,夠直接把。哈哈!
   struct input_handler   evdev_handler 這幾個機構體裡面的幾個元素都比較重要,後面都會用到,現在先來個大概的瞭解。

    .event = evdev_event,                       : 當時間上報的時候,會調用到此函數。
    .connect = evdev_connect,                 :當驅動和裝置匹配的時候會調用到
    .disconnect = evdev_disconnect,         :這個還沒研究
    .fops = &evdev_fops,                         :這個handler的操作函數
    .minor = EVDEV_MINOR_BASE,           :EVDEV 此裝置號的基值
    .name = "evdev",                               : 名字啦
    .id_table = evdev_ids,                         :驅動和裝置是否匹配,需要通過id_table來驗證。這裡的evdev_ids 看到上面的注釋沒“match all devices ”,就是匹配所有設
                                                                備。

2、詳細分析下input_register_handler 這個函數

點擊(此處)摺疊或開啟 /**
 * input_register_handler - register a new input handler
 * @handler: handler to be registered
 *
 * This function registers a new input handler (interface) for input
 * devices in the system and attaches it to all input devices that
 * are compatible with the handler.
 */
int input_register_handler(struct input_handler *handler)
{
    struct input_dev *dev;
    int retval;

    retval = mutex_lock_interruptible(&input_mutex);
    if (retval)
        return retval;
       INIT_LIST_HEAD(&handler->h_list);    //初始化h_list頭部
    if (handler->fops != NULL) {
        if (input_table[handler->minor >> 5]) {
            retval = -EBUSY;
            goto out;
        }
        input_table[handler->minor >> 5] = handler;  //將handler插入數組,其位置是handler->minor >> 5,也就是除以32     }
          list_add_tail(&handler->node, &input_handler_list); // 將handler->node插入到input_handler_list鏈表,深入程式碼分析可知,是插在input_handler_list頭部的後面

    list_for_each_entry(dev, &input_dev_list, node) //遍曆input_dev_list鏈表,對每一個dev調用input_attach_handler函數,看是否匹配。
        input_attach_handler(dev, handler);

    input_wakeup_procfs_readers();

 out:
    mutex_unlock(&input_mutex);
    return retval;
}
EXPORT_SYMBOL(input_register_handler);    上面的注釋也說的很清楚,就是註冊一個input_handler。函數的分析,代碼旁邊的注釋也說了。

2.1 我們將重點集中下面這句代碼。     list_for_each_entry ( dev ,   & input_dev_list ,  node ) 
        input_attach_handler ( dev ,  handler ) ;

   先看看list_for_each_entry是怎麼定義的
 

點擊(此處)摺疊或開啟 /**
 * list_for_each_entry    -    iterate over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */
#define list_for_each_entry(pos, head, member)                \
    for (pos = list_entry((head)->next, typeof(*pos), member);    \
     &pos->member != (head);     \
     pos = list_entry(pos->member.next, typeof(*pos), member))    注釋說得很清楚,就是對於給定的某種類型的鏈表進行遍曆,其實就是一個for 迴圈。我們帶入就是下面這樣
   

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.