日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

platform 设备驱动实验

發(fā)布時間:2023/12/10 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 platform 设备驱动实验 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • Linux 驅動的分離與分層
    • 驅動的分隔與分離
    • 驅動的分層
  • platform 平臺驅動模型簡介
    • platform 總線
    • platform 驅動
    • platform 設備
  • 硬件原理圖分析
  • 試驗程序編寫
    • platform 設備與驅動程序編寫
    • 測試APP 編寫
  • 54.5 運行測試
    • 編譯驅動程序和測試APP
    • 運行測試

我們在前面幾章編寫的設備驅動都非常的簡單,都是對IO 進行最簡單的讀寫操作。像I2C、SPI、LCD 等這些復雜外設的驅動就不能這么去寫了,Linux 系統(tǒng)要考慮到驅動的可重用性,因此提出了驅動的分離與分層這樣的軟件思路,在這個思路下誕生了我們將來最常打交道的platform 設備驅動,也叫做平臺設備驅動。本章我們就來學習一下Linux 下的驅動分離與分層,以及platform 框架下的設備驅動該如何編寫。

Linux 驅動的分離與分層

驅動的分隔與分離

對于Linux 這樣一個成熟、龐大、復雜的操作系統(tǒng),代碼的重用性非常重要,否則的話就會在Linux 內(nèi)核中存在大量無意義的重復代碼。尤其是驅動程序,因為驅動程序占用了Linux內(nèi)核代碼量的大頭,如果不對驅動程序加以管理,任由重復的代碼肆意增加,那么用不了多久Linux 內(nèi)核的文件數(shù)量就龐大到無法接受的地步。

假如現(xiàn)在有三個平臺A、B 和C,這三個平臺(這里的平臺說的是SOC)上都有MPU6050 這個I2C 接口的六軸傳感器,按照我們寫裸機I2C 驅動的時候的思路,每個平臺都有一個MPU6050的驅動,因此編寫出來的最簡單的驅動框架如圖54.1.1 所示:

從圖54.1.1.1 可以看出,每種平臺下都有一個主機驅動和設備驅動,主機驅動肯定是必須要的,畢竟不同的平臺其I2C 控制器不同。但是右側的設備驅動就沒必要每個平臺都寫一個,因為不管對于那個SOC 來說,MPU6050 都是一樣,通過I2C 接口讀寫數(shù)據(jù)就行了,只需要一個MPU6050 的驅動程序即可。如果再來幾個I2C 設備,比如AT24C02、FT5206(電容觸摸屏)
等,如果按照圖54.1.1 中的寫法,那么設備端的驅動將會重復的編寫好幾次。顯然在Linux 驅動程序中這種寫法是不推薦的,最好的做法就是每個平臺的I2C 控制器都提供一個統(tǒng)一的接口(也叫做主機驅動),每個設備的話也只提供一個驅動程序(設備驅動),每個設備通過統(tǒng)一的I2C接口驅動來訪問,這樣就可以大大簡化驅動文件,比如54.1.1 中三種平臺下的MPU6050 驅動
框架就可以簡化為圖54.1.1.2 所示:

實際的I2C 驅動設備肯定有很多種,不止MPU6050 這一個,那么實際的驅動架構如圖54.1.1.3 所示:

這個就是驅動的分隔,也就是將主機驅動和設備驅動分隔開來,比如I2C、SPI 等等都會采用驅動分隔的方式來簡化驅動的開發(fā)。在實際的驅動開發(fā)中,一般I2C 主機控制器驅動已經(jīng)由半導體廠家編寫好了,而設備驅動一般也由設備器件的廠家編寫好了,我們只需要提供設備信息即可,比如I2C 設備的話提供設備連接到了哪個I2C 接口上,I2C 的速度是多少等等。相當
于將設備信息從設備驅動中剝離開來,驅動使用標準方法去獲取到設備信息(比如從設備樹中獲取到設備信息),然后根據(jù)獲取到的設備信息來初始化設備。這樣就相當于驅動只負責驅動,設備只負責設備,想辦法將兩者進行匹配即可。這個就是Linux 中的總線(bus)、驅動(driver)和設備(device)模型,也就是常說的驅動分離。總線就是驅動和設備信息的月老,負責給兩者牽線
搭橋,如圖54.1.1.4 所示:

當我們向系統(tǒng)注冊一個驅動的時候,總線就會在右側的設備中查找,看看有沒有與之匹配的設備,如果有的話就將兩者聯(lián)系起來。同樣的,當向系統(tǒng)中注冊一個設備的時候,總線就會在左側的驅動中查找看有沒有與之匹配的設備,有的話也聯(lián)系起來。Linux 內(nèi)核中大量的驅動程序都采用總線、驅動和設備模式,我們一會要重點講解的platform 驅動就是這一思想下的產(chǎn)
物。

驅動的分層

上一小節(jié)講了驅動的分隔與分離,本節(jié)我們來簡單看一下驅動的分層,大家應該聽說過網(wǎng)絡的7 層模型,不同的層負責不同的內(nèi)容。同樣的,Linux 下的驅動往往也是分層的,分層的目的也是為了在不同的層處理不同的內(nèi)容。以其他書籍或者資料常常使用到的input(輸入子系統(tǒng),后面會有專門的章節(jié)詳細的講解)為例,簡單介紹一下驅動的分層。input 子系統(tǒng)負責管理所有跟輸入有關的驅動,包括鍵盤、鼠標、觸摸等,最底層的就是設備原始驅動,負責獲取輸入設備的原始值,獲取到的輸入事件上報給input 核心層。input 核心層會處理各種IO 模型,并且提供file_operations 操作集合。我們在編寫輸入設備驅動的時候只需要處理好輸入事件的上報即可,至于如何處理這些上報的輸入事件那是上層去考慮的,我們不用管。可以看出借助分層模型可以極大的簡化我們的驅動編寫,對于驅動編寫來說非常的友好。

platform 平臺驅動模型簡介

前面我們講了設備驅動的分離,并且引出了總線(bus)、驅動(driver)和設備(device)模型,比如I2C、SPI、USB 等總線。但是在SOC 中有些外設是沒有總線這個概念的,但是又要使用總線、驅動和設備模型該怎么辦呢?為了解決此問題,Linux 提出了platform 這個虛擬總線,相應的就有platform_driver 和platform_device。

platform 總線

Linux 系統(tǒng)內(nèi)核使用bus_type 結構體表示總線,此結構體定義在文件include/linux/device.h,bus_type 結構體內(nèi)容如下:

1 struct bus_type { 2 const char *name; /* 總線名字*/ 3 const char *dev_name; 4 struct device *dev_root; 5 struct device_attribute *dev_attrs; 6 const struct attribute_group **bus_groups; /* 總線屬性*/ 7 const struct attribute_group **dev_groups; /* 設備屬性*/ 8 const struct attribute_group **drv_groups; /* 驅動屬性*/ 9 10 int (*match)(struct device *dev, struct device_driver *drv); 11 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 12 int (*probe)(struct device *dev); 13 int (*remove)(struct device *dev); 14 void (*shutdown)(struct device *dev); 15 16 int (*online)(struct device *dev); 17 int (*offline)(struct device *dev); 18 int (*suspend)(struct device *dev, pm_message_t state); 19 int (*resume)(struct device *dev); 20 const struct dev_pm_ops *pm; 21 const struct iommu_ops *iommu_ops; 22 struct subsys_private *p; 23 struct lock_class_key lock_key; 24 };

第10 行,match 函數(shù),此函數(shù)很重要,單詞match 的意思就是“匹配、相配”,因此此函數(shù)就是完成設備和驅動之間匹配的,總線就是使用match 函數(shù)來根據(jù)注冊的設備來查找對應的驅動,或者根據(jù)注冊的驅動來查找相應的設備,因此每一條總線都必須實現(xiàn)此函數(shù)。match 函數(shù)有兩個參數(shù):dev 和drv,這兩個參數(shù)分別為device 和device_driver 類型,也就是設備和驅動。

platform 總線是bus_type 的一個具體實例,定義在文件drivers/base/platform.c,platform 總線定義如下:

1 struct bus_type platform_bus_type = { 2 .name = "platform", 3 .dev_groups = platform_dev_groups, 4 .match = platform_match, 5 .uevent = platform_uevent, 6 .pm = &platform_dev_pm_ops, 7 };

platform_bus_type 就是platform 平臺總線,其中platform_match 就是匹配函數(shù)。我們來看一下驅動和設備是如何匹配的,platform_match 函數(shù)定義在文件drivers/base/platform.c 中,函數(shù)內(nèi)容如下所示:

1 static int platform_match(struct device *dev, struct device_driver *drv) 2 { 3 struct platform_device *pdev = to_platform_device(dev); 4 struct platform_driver *pdrv = to_platform_driver(drv); 5 6 /*When driver_override is set,only bind to the matching driver*/ 7 if (pdev->driver_override) 8 return !strcmp(pdev->driver_override, drv->name); 9 10 /* Attempt an OF style match first */ 11 if (of_driver_match_device(dev, drv)) 12 return 1; 13 14 /* Then try ACPI style match */ 15 if (acpi_driver_match_device(dev, drv)) 16 return 1; 17 18 int (*suspend)(struct device *dev, pm_message_t state); 19 int (*resume)(struct device *dev); 20 const struct dev_pm_ops *pm; 21 const struct iommu_ops *iommu_ops; 22 struct subsys_private *p; 23 struct lock_class_key lock_key; 24 };

第10 行,match 函數(shù),此函數(shù)很重要,單詞match 的意思就是“匹配、相配”,因此此函數(shù)就是完成設備和驅動之間匹配的,總線就是使用match 函數(shù)來根據(jù)注冊的設備來查找對應的驅動,或者根據(jù)注冊的驅動來查找相應的設備,因此每一條總線都必須實現(xiàn)此函數(shù)。match 函數(shù)有兩個參數(shù):dev 和drv,這兩個參數(shù)分別為device 和device_driver 類型,也就是設備和驅動。

platform 總線是bus_type 的一個具體實例,定義在文件drivers/base/platform.c,platform 總線定義如下:

1 struct bus_type platform_bus_type = { 2 .name = "platform", 3 .dev_groups = platform_dev_groups, 4 .match = platform_match, 5 .uevent = platform_uevent, 6 .pm = &platform_dev_pm_ops, 7 };

platform_bus_type 就是platform 平臺總線,其中platform_match 就是匹配函數(shù)。我們來看一下驅動和設備是如何匹配的,platform_match 函數(shù)定義在文件drivers/base/platform.c 中,函數(shù)內(nèi)容如下所示:

1 static int platform_match(struct device *dev, struct device_driver *drv) 2 { 3 struct platform_device *pdev = to_platform_device(dev); 4 struct platform_driver *pdrv = to_platform_driver(drv); 5 6 /*When driver_override is set,only bind to the matching driver*/ 7 if (pdev->driver_override) 8 return !strcmp(pdev->driver_override, drv->name); 9 10 /* Attempt an OF style match first */ 11 if (of_driver_match_device(dev, drv)) 12 return 1; 13 14 /* Then try ACPI style match */ 15 if (acpi_driver_match_device(dev, drv)) 16 return 1; 17 18 /* Then try to match against the id table */ 19 if (pdrv->id_table) 20 return platform_match_id(pdrv->id_table, pdev) != NULL; 21 22 /* fall-back to driver name match */ 23 return (strcmp(pdev->name, drv->name) == 0); 24 }

驅動和設備的匹配有四種方法,我們依次來看一下:
第11~12 行,第一種匹配方式,OF 類型的匹配,也就是設備樹采用的匹配方式,of_driver_match_device 函數(shù)定義在文件include/linux/of_device.h 中。device_driver 結構體(表示設備驅動)中有個名為of_match_table 的成員變量,此成員變量保存著驅動的compatible 匹配表,設備樹中的每個設備節(jié)點的compatible 屬性會和of_match_table 表中的所有成員比較,查看是否有相同的條目,如果有的話就表示設備和此驅動匹配,設備和驅動匹配成功以后probe 函數(shù)就會執(zhí)行。
第15~16 行,第二種匹配方式,ACPI 匹配方式。
第19~20 行,第三種匹配方式,id_table 匹配,每個platform_driver 結構體有一個id_table成員變量,顧名思義,保存了很多id 信息。這些id 信息存放著這個platformd 驅動所支持的驅動類型。
第23 行,第四種匹配方式,如果第三種匹配方式的id_table 不存在的話就直接比較驅動和設備的name 字段,看看是不是相等,如果相等的話就匹配成功。
對于支持設備樹的Linux 版本號,一般設備驅動為了兼容性都支持設備樹和無設備樹兩種匹配方式。也就是第一種匹配方式一般都會存在,第三種和第四種只要存在一種就可以,一般用的最多的還是第四種,也就是直接比較驅動和設備的name 字段,畢竟這種方式最簡單了。

platform 驅動

platform_driver 結構體表示platform 驅動,此結構體定義在文件
include/linux/platform_device.h 中,內(nèi)容如下:

1 struct platform_driver { 2 int (*probe)(struct platform_device *); 3 int (*remove)(struct platform_device *); 4 void (*shutdown)(struct platform_device *); 5 int (*suspend)(struct platform_device *, pm_message_t state); 6 int (*resume)(struct platform_device *); 7 struct device_driver driver; 8 const struct platform_device_id *id_table; 9 bool prevent_deferred_probe; 10 };

第2 行,probe 函數(shù),當驅動與設備匹配成功以后probe 函數(shù)就會執(zhí)行,非常重要的函數(shù)!!一般驅動的提供者會編寫,如果自己要編寫一個全新的驅動,那么probe 就需要自行實現(xiàn)。
第7 行,driver 成員,為device_driver 結構體變量,Linux 內(nèi)核里面大量使用到了面向對象的思維,device_driver 相當于基類,提供了最基礎的驅動框架。plaform_driver 繼承了這個基類,然后在此基礎上又添加了一些特有的成員變量。

第8 行,id_table 表,也就是我們上一小節(jié)講解platform 總線匹配驅動和設備的時候采用的第三種方法,id_table 是個表( 也就是數(shù)組) ,每個元素的類型為platform_device_id ,platform_device_id 結構體內(nèi)容如下:

1 struct platform_device_id { 2 char name[PLATFORM_NAME_SIZE]; 3 kernel_ulong_t driver_data; 4 };

device_driver 結構體定義在include/linux/device.h,device_driver 結構體內(nèi)容如下:

1 struct device_driver { 2 const char *name; 3 struct bus_type *bus; 4 5 struct module *owner; 6 const char *mod_name; /* used for built-in modules */ 7 8 bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ 9 10 const struct of_device_id *of_match_table; 11 const struct acpi_device_id *acpi_match_table; 12 13 int (*probe) (struct device *dev); 14 int (*remove) (struct device *dev); 15 void (*shutdown) (struct device *dev); 16 int (*suspend) (struct device *dev, pm_message_t state); 17 int (*resume) (struct device *dev); 18 const struct attribute_group **groups; 19 20 const struct dev_pm_ops *pm; 21 22 struct driver_private *p; 23 };

第10 行,of_match_table 就是采用設備樹的時候驅動使用的匹配表,同樣是數(shù)組,每個匹配項都為of_device_id 結構體類型,此結構體定義在文件include/linux/mod_devicetable.h 中,內(nèi)容如下:

1 struct of_device_id { 2 char name[32]; 3 char type[32]; 4 char compatible[128]; 5 const void *data; 6 };

第4 行的compatible 非常重要,因為對于設備樹而言,就是通過設備節(jié)點的compatible 屬性值和of_match_table 中每個項目的compatible 成員變量進行比較,如果有相等的就表示設備和此驅動匹配成功。

在編寫platform 驅動的時候,首先定義一個platform_driver 結構體變量,然后實現(xiàn)結構體中的各個成員變量,重點是實現(xiàn)匹配方法以及probe 函數(shù)。當驅動和設備匹配成功以后probe函數(shù)就會執(zhí)行,具體的驅動程序在probe 函數(shù)里面編寫,比如字符設備驅動等等。

當我們定義并初始化好platform_driver 結構體變量以后,需要在驅動入口函數(shù)里面調(diào)用platform_driver_register 函數(shù)向Linux 內(nèi)核注冊一個platform 驅動,platform_driver_register 函數(shù)原型如下所示:

int platform_driver_register (struct platform_driver *driver)

函數(shù)參數(shù)和返回值含義如下:
driver:要注冊的platform 驅動。
返回值:負數(shù),失敗;0,成功。
還需要在驅動卸載函數(shù)中通過platform_driver_unregister 函數(shù)卸載platform 驅動,platform_driver_unregister 函數(shù)原型如下:

void platform_driver_unregister(struct platform_driver *drv)

函數(shù)參數(shù)和返回值含義如下:
drv:要卸載的platform 驅動。
返回值:無。
platform 驅動框架如下所示:

/* 設備結構體*/ 1 struct xxx_dev{ 2 struct cdev cdev; 3 /* 設備結構體其他具體內(nèi)容*/ 4 }; 5 6 struct xxx_dev xxxdev; /* 定義個設備結構體變量*/ 7 8 static int xxx_open(struct inode *inode, struct file *filp) 9 { 10 /* 函數(shù)具體內(nèi)容*/ 11 return 0; 12 } 13 14 static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) 15 { 16 /* 函數(shù)具體內(nèi)容*/ 17 return 0; 18 } 19 20 /* 21 * 字符設備驅動操作集 22 */ 23 static struct file_operations xxx_fops = { 24 .owner = THIS_MODULE, 25 .open = xxx_open, 26 .write = xxx_write, 27 }; 28 29 /* 30 * platform驅動的probe函數(shù) 31 * 驅動與設備匹配成功以后此函數(shù)就會執(zhí)行 32 */ 33 static int xxx_probe(struct platform_device *dev) 34 { 35 ...... 36 cdev_init(&xxxdev.cdev, &xxx_fops); /* 注冊字符設備驅動*/ 37 /* 函數(shù)具體內(nèi)容*/ 38 return 0; 39 } 40 41 static int xxx_remove(struct platform_device *dev) 42 { 43 ...... 44 cdev_del(&xxxdev.cdev);/* 刪除cdev */ 45 /* 函數(shù)具體內(nèi)容*/ 46 return 0; 47 } 48 49 /* 匹配列表*/ 50 static const struct of_device_id xxx_of_match[] = { 51 { .compatible = "xxx-gpio" }, 52 { /* Sentinel */ } 53 }; 54 55 /* 56 * platform平臺驅動結構體 57 */ 58 static struct platform_driver xxx_driver = { 59 .driver = { 60 .name = "xxx", 61 .of_match_table = xxx_of_match, 62 }, 63 .probe = xxx_probe, 64 .remove = xxx_remove, 65 }; 66 67 /* 驅動模塊加載*/ 68 static int __init xxxdriver_init(void) 69 { 70 return platform_driver_register(&xxx_driver); 71 } 72 73 /* 驅動模塊卸載*/ 74 static void __exit xxxdriver_exit(void) 75 { 76 platform_driver_unregister(&xxx_driver); 77 } 78 79 module_init(xxxdriver_init); 80 module_exit(xxxdriver_exit); 81 MODULE_LICENSE("GPL"); 82 MODULE_AUTHOR("zuozhongkai");

第1~27 行,傳統(tǒng)的字符設備驅動,所謂的platform 驅動并不是獨立于字符設備驅動、塊設備驅動和網(wǎng)絡設備驅動之外的其他種類的驅動。platform 只是為了驅動的分離與分層而提出來的一種框架,其驅動的具體實現(xiàn)還是需要字符設備驅動、塊設備驅動或網(wǎng)絡設備驅動。

第33~39 行,xxx_probe 函數(shù),當驅動和設備匹配成功以后此函數(shù)就會執(zhí)行,以前在驅動入口init 函數(shù)里面編寫的字符設備驅動程序就全部放到此probe 函數(shù)里面。比如注冊字符設備驅動、添加cdev、創(chuàng)建類等等。

第41~47 行,xxx_remove 函數(shù),platform_driver 結構體中的remove 成員變量,當關閉platfor備驅動的時候此函數(shù)就會執(zhí)行,以前在驅動卸載exit 函數(shù)里面要做的事情就放到此函數(shù)中來。比如,使用iounmap 釋放內(nèi)存、刪除cdev,注銷設備號等等。

第50~53 行,xxx_of_match 匹配表,如果使用設備樹的話將通過此匹配表進行驅動和設備的匹配。第51 行設置了一個匹配項,此匹配項的compatible 值為“xxx-gpio”,因此當設備樹中設備節(jié)點的compatible 屬性值為“xxx-gpio”的時候此設備就會與此驅動匹配。

第52 行是一個標記,of_device_id 表最后一個匹配項必須是空的。

第58~ 65 行,定義一個platform_driver 結構體變量xxx_driver,表示platform 驅動,

第59~62行設置paltform_driver 中的device_driver 成員變量的name 和of_match_table 這兩個屬性。其中name 屬性用于傳統(tǒng)的驅動與設備匹配,也就是檢查驅動和設備的name 字段是不是相同。of_match_table 屬性就是用于設備樹下的驅動與設備檢查。對于一個完整的驅動程序,必須提供
有設備樹和無設備樹兩種匹配方法。最后63 和64 這兩行設置probe 和remove 這兩成員變量。

第68~71 行,驅動入口函數(shù),調(diào)用platform_driver_register 函數(shù)向Linux 內(nèi)核注冊一個platform驅動,也就是上面定義的xxx_driver 結構體變量。

第74~77 行,驅動出口函數(shù),調(diào)用platform_driver_unregister 函數(shù)卸載前面注冊的platform驅動。

總體來說,platform 驅動還是傳統(tǒng)的字符設備驅動、塊設備驅動或網(wǎng)絡設備驅動,只是套上了一張“platform”的皮,目的是為了使用總線、驅動和設備這個驅動模型來實現(xiàn)驅動的分離與分層。

platform 設備

platform 驅動已經(jīng)準備好了,我們還需要platform 設備,否則的話單單一個驅動也做不了什么。platform_device 這個結構體表示platform 設備,這里我們要注意,如果內(nèi)核支持設備樹的話就不要再使用platform_device 來描述設備了,因為改用設備樹去描述了。當然了,你如果一定要用platform_device 來描述設備信息的話也是可以的。platform_device 結構體定義在文件
include/linux/platform_device.h 中,結構體內(nèi)容如下:

22 struct platform_device { 23 const char *name; 24 int id; 25 bool id_auto; 26 struct device dev; 27 u32 num_resources; 28 struct resource *resource; 29 30 const struct platform_device_id *id_entry; 31 char *driver_override; /* Driver name to force a match */ 32 33 /* MFD cell pointer */ 34 struct mfd_cell *mfd_cell; 35 36 /* arch specific additions */ 37 struct pdev_archdata archdata; 38 };

第23 行,name 表示設備名字,要和所使用的platform 驅動的name 字段相同,否則的話設備就無法匹配到對應的驅動。比如對應的platform 驅動的name 字段為“xxx-gpio”,那么此name字段也要設置為“xxx-gpio”。

第27 行,num_resources 表示資源數(shù)量,一般為第28 行resource 資源的大小。

第28 行,resource 表示資源,也就是設備信息,比如外設寄存器等。Linux 內(nèi)核使用resource結構體表示資源,resource 結構體內(nèi)容如下:

18 struct resource { 19 resource_size_t start; 20 resource_size_t end; 21 const char *name; 22 unsigned long flags; 23 struct resource *parent, *sibling, *child; 24 };

start 和end 分別表示資源的起始和終止信息,對于內(nèi)存類的資源,就表示內(nèi)存起始和終止地址,name 表示資源名字,flags 表示資源類型,可選的資源類型都定義在了文件include/linux/ioport.h 里面,如下所示:

29 #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ 30 31 #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */ 32 #define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */ 33 #define IORESOURCE_MEM 0x00000200 34 #define IORESOURCE_REG 0x00000300 /* Register offsets */ 35 #define IORESOURCE_IRQ 0x00000400 36 #define IORESOURCE_DMA 0x00000800 37 #define IORESOURCE_BUS 0x00001000 ...... 104 /* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */ 105 #define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */

在以前不支持設備樹的Linux 版本中,用戶需要編寫platform_device 變量來描述設備信息,然后使用platform_device_register 函數(shù)將設備信息注冊到Linux 內(nèi)核中,此函數(shù)原型如下所示:

int platform_device_register(struct platform_device *pdev)

函數(shù)參數(shù)和返回值含義如下:
pdev:要注冊的platform 設備。
返回值:負數(shù),失敗;0,成功。
如果不再使用platform 的話可以通過platform_device_unregister 函數(shù)注銷掉相應的platform設備,platform_device_unregister 函數(shù)原型如下:

void platform_device_unregister(struct platform_device *pdev)

函數(shù)參數(shù)和返回值含義如下:
pdev:要注銷的platform 設備。
返回值:無。
platform 設備信息框架如下所示:

1 /* 寄存器地址定義*/ 2 #define PERIPH1_REGISTER_BASE (0X20000000) /* 外設1寄存器首地址*/ 3 #define PERIPH2_REGISTER_BASE (0X020E0068) /* 外設2寄存器首地址*/ 4 #define REGISTER_LENGTH 4 5 6 /* 資源*/ 7 static struct resource xxx_resources[] = { 8 [0] = { 9 .start = PERIPH1_REGISTER_BASE, 10 .end = (PERIPH1_REGISTER_BASE + REGISTER_LENGTH - 1), 11 .flags = IORESOURCE_MEM, 12 }, 13 [1] = { 14 .start = PERIPH2_REGISTER_BASE, 15 .end = (PERIPH2_REGISTER_BASE + REGISTER_LENGTH - 1), 16 .flags = IORESOURCE_MEM, 17 }, 18 }; 19 20 /* platform設備結構體*/ 21 static struct platform_device xxxdevice = { 22 .name = "xxx-gpio", 23 .id = -1, 24 .num_resources = ARRAY_SIZE(xxx_resources), 25 .resource = xxx_resources, 26 }; 27 28 /* 設備模塊加載*/ 29 static int __init xxxdevice_init(void) 30 { 31 return platform_device_register(&xxxdevice); 32 } 33 34 /* 設備模塊注銷*/ 35 static void __exit xxx_resourcesdevice_exit(void) 36 { 37 platform_device_unregister(&xxxdevice); 38 } 39 40 module_init(xxxdevice_init); 41 module_exit(xxxdevice_exit); 42 MODULE_LICENSE("GPL"); 43 MODULE_AUTHOR("zuozhongkai");

第7~18 行,數(shù)組xxx_resources 表示設備資源,一共有兩個資源,分別為設備外設1 和外設2 的寄存器信息。因此flags 都為IORESOURCE_MEM,表示資源為內(nèi)存類型的。
第21~26 行,platform 設備結構體變量,注意name 字段要和所使用的驅動中的name 字段一致,否則驅動和設備無法匹配成功。num_resources 表示資源大小,其實就是數(shù)組xxx_resources的元素數(shù)量,這里用ARRAY_SIZE 來測量一個數(shù)組的元素個數(shù)。
第29~32 行,設備模塊加載函數(shù),在此函數(shù)中調(diào)用platform_device_register 向Linux 內(nèi)核注冊platform 設備。
第35~38 行,設備模塊卸載函數(shù),在此函數(shù)中調(diào)用platform_device_unregister 從Linux 內(nèi)核中卸載platform 設備。

示例代碼54.2.3.4 主要是在不支持設備樹的Linux 版本中使用的,當Linux 內(nèi)核支持了設備樹以后就不需要用戶手動去注冊platform 設備了。因為設備信息都放到了設備樹中去描述,Linux 內(nèi)核啟動的時候會從設備樹中讀取設備信息,然后將其組織成platform_device 形式,至于設備樹到platform_device 的具體過程就不去詳細的追究了,感興趣的可以去看一下,網(wǎng)上也有很多博客詳細的講解了整個過程。

關于platform 下的總線、驅動和設備就講解到這里,我們接下來就使用platform 驅動框架來編寫一個LED 燈驅動,本章我們不使用設備樹來描述設備信息,我們采用自定義platform_device 這種“古老”方式來編寫LED 的設備信息。下一章我們來編寫設備樹下的platform驅動,這樣我們就掌握了無設備樹和有設備樹這兩種platform 驅動的開發(fā)方式。

硬件原理圖分析

本章實驗我們只使用到IMX6U-ALPHA 開發(fā)板上的LED 燈,因此實驗硬件原理圖參考8.3小節(jié)即可。

試驗程序編寫

本實驗對應的例程路徑為:開發(fā)板光盤-> 2、Linux 驅動例程-> 17_platform。
本章實驗我們需要編寫一個驅動模塊和一個設備模塊,其中驅動模塊是platform 驅動程序,設備模塊是platform 的設備信息。當這兩個模塊都加載成功以后就會匹配成功,然后platform驅動模塊中的probe 函數(shù)就會執(zhí)行,probe 函數(shù)中就是傳統(tǒng)的字符設備驅動那一套。

platform 設備與驅動程序編寫

新建名為“17_platform”的文件夾,然后在17_platform 文件夾里面創(chuàng)建vscode 工程,工作區(qū)命名為“platform”。新建名為leddevice.c 和leddriver.c 這兩個文件,這兩個文件分別為LED燈的platform 設備文件和LED 燈的platform 的驅動文件。在leddevice.c 中輸入如下所示內(nèi)容:

#include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/ide.h> #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/gpio.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/of_gpio.h> #include <linux/semaphore.h> #include <linux/timer.h> #include <linux/irq.h> #include <linux/wait.h> #include <linux/poll.h> #include <linux/fs.h> #include <linux/fcntl.h> #include <linux/platform_device.h> #include <asm/mach/map.h> #include <asm/uaccess.h> #include <asm/io.h> /*************************************************************** Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : leddevice.c 作者 : 左忠凱 版本 : V1.0 描述 : platform設備 其他 : 無 論壇 : www.openedv.com 日志 : 初版V1.0 2019/8/13 左忠凱創(chuàng)建 ***************************************************************//* * 寄存器地址定義*/ #define CCM_CCGR1_BASE (0X020C406C) #define SW_MUX_GPIO1_IO03_BASE (0X020E0068) #define SW_PAD_GPIO1_IO03_BASE (0X020E02F4) #define GPIO1_DR_BASE (0X0209C000) #define GPIO1_GDIR_BASE (0X0209C004) #define REGISTER_LENGTH 4/* @description : 釋放flatform設備模塊的時候此函數(shù)會執(zhí)行 * @param - dev : 要釋放的設備 * @return : 無*/ static void led_release(struct device *dev) {printk("led device released!\r\n"); }/* * 設備資源信息,也就是LED0所使用的所有寄存器*/ static struct resource led_resources[] = {[0] = {.start = CCM_CCGR1_BASE,.end = (CCM_CCGR1_BASE + REGISTER_LENGTH - 1),.flags = IORESOURCE_MEM,}, [1] = {.start = SW_MUX_GPIO1_IO03_BASE,.end = (SW_MUX_GPIO1_IO03_BASE + REGISTER_LENGTH - 1),.flags = IORESOURCE_MEM,},[2] = {.start = SW_PAD_GPIO1_IO03_BASE,.end = (SW_PAD_GPIO1_IO03_BASE + REGISTER_LENGTH - 1),.flags = IORESOURCE_MEM,},[3] = {.start = GPIO1_DR_BASE,.end = (GPIO1_DR_BASE + REGISTER_LENGTH - 1),.flags = IORESOURCE_MEM,},[4] = {.start = GPIO1_GDIR_BASE,.end = (GPIO1_GDIR_BASE + REGISTER_LENGTH - 1),.flags = IORESOURCE_MEM,}, };/** platform設備結構體 */ static struct platform_device leddevice = {.name = "imx6ul-led",.id = -1,.dev = {.release = &led_release,},.num_resources = ARRAY_SIZE(led_resources),.resource = led_resources, };/** @description : 設備模塊加載 * @param : 無* @return : 無*/ static int __init leddevice_init(void) {return platform_device_register(&leddevice); }/** @description : 設備模塊注銷* @param : 無* @return : 無*/ static void __exit leddevice_exit(void) {platform_device_unregister(&leddevice); }module_init(leddevice_init); module_exit(leddevice_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("zuozhongkai");

leddevice.c 文件內(nèi)容就是按照示例代碼54.2.3.4 的platform 設備模板編寫的。
第56~82 行,led_resources 數(shù)組,也就是設備資源,描述了LED 所要使用到的寄存器信息,也就是IORESOURCE_MEM 資源。
第88~96,platform 設備結構體變量leddevice,這里要注意name 字段為“imx6ul-led”,所以稍后編寫platform 驅動中的name 字段也要為“imx6ul-led”,否則設備和驅動匹配失敗。
第103~106 行,設備模塊加載函數(shù),在此函數(shù)里面通過platform_device_register 向Linux 內(nèi)核注冊leddevice 這個platform 設備。
第113~116 行,設備模塊卸載函數(shù),在此函數(shù)里面通過platform_device_unregister 從Linux內(nèi)核中刪除掉leddevice 這個platform 設備。
leddevice.c 文件編寫完成以后就編寫leddriver.c 這個platform 驅動文件,在leddriver.c 里面輸入如下內(nèi)容:

#include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/ide.h> #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/gpio.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/of_gpio.h> #include <linux/semaphore.h> #include <linux/timer.h> #include <linux/irq.h> #include <linux/wait.h> #include <linux/poll.h> #include <linux/fs.h> #include <linux/fcntl.h> #include <linux/platform_device.h> #include <asm/mach/map.h> #include <asm/uaccess.h> #include <asm/io.h> /*************************************************************** Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : leddriver.c 作者 : 左忠凱 版本 : V1.0 描述 : platform驅動 其他 : 無 論壇 : www.openedv.com 日志 : 初版V1.0 2019/8/13 左忠凱創(chuàng)建 ***************************************************************/#define LEDDEV_CNT 1 /* 設備號長度 */ #define LEDDEV_NAME "platled" /* 設備名字 */ #define LEDOFF 0 #define LEDON 1/* 寄存器名 */ static void __iomem *IMX6U_CCM_CCGR1; static void __iomem *SW_MUX_GPIO1_IO03; static void __iomem *SW_PAD_GPIO1_IO03; static void __iomem *GPIO1_DR; static void __iomem *GPIO1_GDIR;/* leddev設備結構體 */ struct leddev_dev{dev_t devid; /* 設備號 */struct cdev cdev; /* cdev */struct class *class; /* 類 */struct device *device; /* 設備 */int major; /* 主設備號 */ };struct leddev_dev leddev; /* led設備 *//** @description : LED打開/關閉* @param - sta : LEDON(0) 打開LED,LEDOFF(1) 關閉LED* @return : 無*/ void led0_switch(u8 sta) {u32 val = 0;if(sta == LEDON){val = readl(GPIO1_DR);val &= ~(1 << 3); writel(val, GPIO1_DR);}else if(sta == LEDOFF){val = readl(GPIO1_DR);val|= (1 << 3); writel(val, GPIO1_DR);} }/** @description : 打開設備* @param - inode : 傳遞給驅動的inode* @param - filp : 設備文件,file結構體有個叫做private_data的成員變量* 一般在open的時候將private_data指向設備結構體。* @return : 0 成功;其他 失敗*/ static int led_open(struct inode *inode, struct file *filp) {filp->private_data = &leddev; /* 設置私有數(shù)據(jù) */return 0; }/** @description : 向設備寫數(shù)據(jù) * @param - filp : 設備文件,表示打開的文件描述符* @param - buf : 要寫給設備寫入的數(shù)據(jù)* @param - cnt : 要寫入的數(shù)據(jù)長度* @param - offt : 相對于文件首地址的偏移* @return : 寫入的字節(jié)數(shù),如果為負值,表示寫入失敗*/ static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt) {int retvalue;unsigned char databuf[1];unsigned char ledstat;retvalue = copy_from_user(databuf, buf, cnt);if(retvalue < 0) {return -EFAULT;}ledstat = databuf[0]; /* 獲取狀態(tài)值 */if(ledstat == LEDON) {led0_switch(LEDON); /* 打開LED燈 */}else if(ledstat == LEDOFF) {led0_switch(LEDOFF); /* 關閉LED燈 */}return 0; }/* 設備操作函數(shù) */ static struct file_operations led_fops = {.owner = THIS_MODULE,.open = led_open,.write = led_write, };/** @description : flatform驅動的probe函數(shù),當驅動與設備匹配以后此函數(shù)就會執(zhí)行* @param - dev : platform設備* @return : 0,成功;其他負值,失敗*/ static int led_probe(struct platform_device *dev) { int i = 0;int ressize[5];u32 val = 0;struct resource *ledsource[5];printk("led driver and device has matched!\r\n");/* 1、獲取資源 */for (i = 0; i < 5; i++) {ledsource[i] = platform_get_resource(dev, IORESOURCE_MEM, i); /* 依次MEM類型資源 */if (!ledsource[i]) {dev_err(&dev->dev, "No MEM resource for always on\n");return -ENXIO;}ressize[i] = resource_size(ledsource[i]); } /* 2、初始化LED *//* 寄存器地址映射 */IMX6U_CCM_CCGR1 = ioremap(ledsource[0]->start, ressize[0]);SW_MUX_GPIO1_IO03 = ioremap(ledsource[1]->start, ressize[1]);SW_PAD_GPIO1_IO03 = ioremap(ledsource[2]->start, ressize[2]);GPIO1_DR = ioremap(ledsource[3]->start, ressize[3]);GPIO1_GDIR = ioremap(ledsource[4]->start, ressize[4]);val = readl(IMX6U_CCM_CCGR1);val &= ~(3 << 26); /* 清除以前的設置 */val |= (3 << 26); /* 設置新值 */writel(val, IMX6U_CCM_CCGR1);/* 設置GPIO1_IO03復用功能,將其復用為GPIO1_IO03 */writel(5, SW_MUX_GPIO1_IO03);writel(0x10B0, SW_PAD_GPIO1_IO03);/* 設置GPIO1_IO03為輸出功能 */val = readl(GPIO1_GDIR);val &= ~(1 << 3); /* 清除以前的設置 */val |= (1 << 3); /* 設置為輸出 */writel(val, GPIO1_GDIR);/* 默認關閉LED1 */val = readl(GPIO1_DR);val |= (1 << 3) ; writel(val, GPIO1_DR);/* 注冊字符設備驅動 *//*1、創(chuàng)建設備號 */if (leddev.major) { /* 定義了設備號 */leddev.devid = MKDEV(leddev.major, 0);register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME);} else { /* 沒有定義設備號 */alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME); /* 申請設備號 */leddev.major = MAJOR(leddev.devid); /* 獲取分配號的主設備號 */}/* 2、初始化cdev */leddev.cdev.owner = THIS_MODULE;cdev_init(&leddev.cdev, &led_fops);/* 3、添加一個cdev */cdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT);/* 4、創(chuàng)建類 */leddev.class = class_create(THIS_MODULE, LEDDEV_NAME);if (IS_ERR(leddev.class)) {return PTR_ERR(leddev.class);}/* 5、創(chuàng)建設備 */leddev.device = device_create(leddev.class, NULL, leddev.devid, NULL, LEDDEV_NAME);if (IS_ERR(leddev.device)) {return PTR_ERR(leddev.device);}return 0; }/** @description : platform驅動的remove函數(shù),移除platform驅動的時候此函數(shù)會執(zhí)行* @param - dev : platform設備* @return : 0,成功;其他負值,失敗*/ static int led_remove(struct platform_device *dev) {iounmap(IMX6U_CCM_CCGR1);iounmap(SW_MUX_GPIO1_IO03);iounmap(SW_PAD_GPIO1_IO03);iounmap(GPIO1_DR);iounmap(GPIO1_GDIR);cdev_del(&leddev.cdev);/* 刪除cdev */unregister_chrdev_region(leddev.devid, LEDDEV_CNT); /* 注銷設備號 */device_destroy(leddev.class, leddev.devid);class_destroy(leddev.class);return 0; }/* platform驅動結構體 */ static struct platform_driver led_driver = {.driver = {.name = "imx6ul-led", /* 驅動名字,用于和設備匹配 */},.probe = led_probe,.remove = led_remove, };/** @description : 驅動模塊加載函數(shù)* @param : 無* @return : 無*/ static int __init leddriver_init(void) {return platform_driver_register(&led_driver); }/** @description : 驅動模塊卸載函數(shù)* @param : 無* @return : 無*/ static void __exit leddriver_exit(void) {platform_driver_unregister(&led_driver); }module_init(leddriver_init); module_exit(leddriver_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("zuozhongkai");

leddriver.c 文件內(nèi)容就是按照示例代碼54.2.2.5 的platform 驅動模板編寫的。

第34~122 行,傳統(tǒng)的字符設備驅動。
第130~206 行,probe 函數(shù),當設備和驅動匹配以后此函數(shù)就會執(zhí)行,當匹配成功以后會在終端上輸出“l(fā)ed driver and device has matched!”這樣語句。在probe 函數(shù)里面初始化LED、注冊字符設備驅動。也就是將原來在驅動加載函數(shù)里面做的工作全部放到probe 函數(shù)里面完成。
第213~226 行,remobe 函數(shù),當卸載platform 驅動的時候此函數(shù)就會執(zhí)行。在此函數(shù)里面釋放內(nèi)存、注銷字符設備等。也就是將原來驅動卸載函數(shù)里面的工作全部都放到remove 函數(shù)中完成。
第229~235 行,platform_driver 驅動結構體,注意name 字段為"imx6ul-led",和我們在leddevice.c 文件里面設置的設備name 字段一致。

第242~245 行,驅動模塊加載函數(shù),在此函數(shù)里面通過platform_driver_register 向Linux 內(nèi)核注冊led_driver 驅動。

第252~255 行,驅動模塊卸載函數(shù),在此函數(shù)里面通過platform_driver_unregister 從Linux內(nèi)核卸載led_driver 驅動。

測試APP 編寫

測試APP 的內(nèi)容很簡單,就是打開和關閉LED 燈,新建ledApp.c 這個文件,然后在里面輸入如下內(nèi)容:

#include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/stat.h" #include "fcntl.h" #include "stdlib.h" #include "string.h" /*************************************************************** Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : ledApp.c 作者 : 左忠凱 版本 : V1.0 描述 : platform驅動驅測試APP。 其他 : 無 使用方法 :./ledApp /dev/platled 0 關閉LED./ledApp /dev/platled 1 打開LED 論壇 : www.openedv.com 日志 : 初版V1.0 2019/8/16 左忠凱創(chuàng)建 ***************************************************************/ #define LEDOFF 0 #define LEDON 1/** @description : main主程序* @param - argc : argv數(shù)組元素個數(shù)* @param - argv : 具體參數(shù)* @return : 0 成功;其他 失敗*/ int main(int argc, char *argv[]) {int fd, retvalue;char *filename;unsigned char databuf[2];if(argc != 3){printf("Error Usage!\r\n");return -1;}filename = argv[1];/* 打開led驅動 */fd = open(filename, O_RDWR);if(fd < 0){printf("file %s open failed!\r\n", argv[1]);return -1;}databuf[0] = atoi(argv[2]); /* 要執(zhí)行的操作:打開或關閉 */retvalue = write(fd, databuf, sizeof(databuf));if(retvalue < 0){printf("LED Control Failed!\r\n");close(fd);return -1;}retvalue = close(fd); /* 關閉文件 */if(retvalue < 0){printf("file %s close failed!\r\n", argv[1]);return -1;}return 0; }

ledApp.c 文件內(nèi)容很簡單,就是控制LED 燈的亮滅,和第四十一章的測試APP 基本一致,這里就不重復講解了。

54.5 運行測試

編譯驅動程序和測試APP

1、編譯驅動程序
編寫Makefile 文件,本章實驗的Makefile 文件和第四十章實驗基本一樣,只是將obj-m 變量的值改為“l(fā)eddevice.o leddriver.o”,Makefile 內(nèi)容如下所示:

KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek CURRENT_PATH := $(shell pwd)obj-m := leddevice.o obj-m += leddriver.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modulesclean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

第4 行,設置obj-m 變量的值為“l(fā)eddevice.o leddriver.o”。
輸入如下命令編譯出驅動模塊文件:

make -j32

編譯成功以后就會生成一個名為“l(fā)eddevice.ko leddriver.ko”的驅動模塊文件。

2、編譯測試APP
輸入如下命令編譯測試ledApp.c 這個測試程序:

arm-linux-gnueabihf-gcc ledApp.c -o ledApp

編譯成功以后就會生成ledApp 這個應用程序。

運行測試

將上一小節(jié)編譯出來leddevice.ko 、leddriver.ko 和ledApp 這兩個文件拷貝到
rootfs/lib/modules/4.1.15 目錄中,重啟開發(fā)板,進入到目錄lib/modules/4.1.15 中,輸入如下命令加載leddevice.ko 設備模塊和leddriver.ko 這個驅動模塊。

depmod //第一次加載驅動的時候需要運行此命令 modprobe leddevice.ko //加載設備模塊 modprobe leddriver.ko //加載驅動模塊

根文件系統(tǒng)中/sys/bus/platform/目錄下保存著當前板子platform 總線下的設備和驅動,其中devices 子目錄為platform 設備,drivers 子目錄為plartofm 驅動。查看/sys/bus/platform/devices/目錄,看看我們的設備是否存在,我們在leddevice.c 中設置leddevice(platform_device 類型)的
name 字段為“imx6ul-led”,也就是設備名字為imx6ul-led,因此肯定在/sys/bus/platform/devices/目錄下存在一個名字“imx6ul-led”的文件,否則說明我們的設備模塊加載失敗,結果如圖54.4.2.1所示:

同理,查看/sys/bus/platform/drivers/目錄,看一下驅動是否存在,我們在leddriver.c 中設置led_driver (platform_driver 類型)的name 字段為“imx6ul-led”,因此會在/sys/bus/platform/drivers/目錄下存在名為“imx6ul-led”這個文件,結果如圖54.4.2.2 所示:

驅動模塊和設備模塊加載成功以后platform 總線就會進行匹配,當驅動和設備匹配成功以后就會輸出如圖54.4.2.3 所示一行語句:

驅動和設備匹配成功以后就可以測試LED 燈驅動了,輸入如下命令打開LED 燈:

./ledApp /dev/platled 1 //打開LED 燈

在輸入如下命令關閉LED 燈:

./ledApp /dev/platled 0 //關閉LED 燈

觀察一下LED 燈能否打開和關閉,如果可以的話就說明驅動工作正常,如果要卸載驅動的話輸入如下命令即可:

rmmod leddevice.ko rmmod leddriver.ko

總結

以上是生活随笔為你收集整理的platform 设备驱动实验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

欧美日韩99 | 永久av免费在线观看 | 久久精品亚洲国产 | 91精品对白一区国产伦 | 欧美日韩高清在线一区 | 九九免费观看全部免费视频 | 亚洲永久av | 久草在线视频看看 | 97超碰资源 | 狠狠狠干狠狠 | 精品在线观看免费 | 91aaa在线观看| 国内精品久久久久影院一蜜桃 | 亚洲精品乱码久久久一二三 | 婷婷久久婷婷 | 日日操操操 | 国产精品青草综合久久久久99 | 精品久久久久久久久久久久久久久久 | 成人免费观看网站 | 日韩av成人在线观看 | 亚洲精品视频在线免费播放 | 国产69精品久久久久99 | 成人午夜在线电影 | 亚洲成a人片77777潘金莲 | 日韩久久精品一区二区三区下载 | 最近高清中文字幕在线国语5 | 国产精品免费在线播放 | 国产成人综合精品 | 精品国产一区二区三区日日嗨 | 日韩在线观看a | 蜜臀久久99精品久久久无需会员 | 免费看片亚洲 | 中文字幕精品一区二区三区电影 | 中文字幕欧美日韩va免费视频 | 国产美女视频 | 色www.| 色诱亚洲精品久久久久久 | 日韩免费电影 | 国产精品欧美激情在线观看 | 久久福利精品 | 欧美激情视频一区二区三区免费 | 欧美先锋影音 | 婷婷天天色 | 午夜在线资源 | 国产一级二级在线播放 | 国产精品久久久网站 | 国产在线最新 | 色噜噜噜噜 | 亚洲乱码在线观看 | 99视频免费看 | www.干| 懂色av一区二区三区蜜臀 | 日韩午夜视频在线观看 | 色视频网站在线观看一=区 a视频免费在线观看 | 欧美三级免费 | 亚洲精品动漫久久久久 | 国产精品久久久影视 | 亚洲视频在线免费看 | 精品一区二区在线免费观看 | 欧美日韩综合在线 | 色网站免费在线观看 | 精品麻豆入口免费 | 亚洲aⅴ在线 | 96久久精品| 日韩电影在线视频 | 国产中文字幕网 | 性色av免费看 | 成人小视频免费在线观看 | 在线成人性视频 | 免费在线观看毛片网站 | 亚洲春色综合另类校园电影 | 又爽又黄又刺激的视频 | 国产三级精品在线 | 干天天| 亚洲国产999| 亚洲综合成人在线 | 欧美精品小视频 | 国产精品视屏 | 蜜臀久久99精品久久久酒店新书 | 欧美亚洲国产一卡 | 久久人人爽人人爽人人片av免费 | 日韩色综合网 | 色综合久久天天 | 久久人人添人人爽添人人88v | 在线天堂中文www视软件 | 免费麻豆网站 | 91精品国产91热久久久做人人 | 久久国产精品二国产精品中国洋人 | 天天综合在线观看 | 午夜精品一区二区国产 | 激情综合五月天 | 国产成人精品a | 日韩综合精品 | 国产成人一区二区三区久久精品 | 一区二区 不卡 | 欧美日韩性生活 | 黄色小说免费观看 | 狠狠操91 | 久久久久夜色 | 久久不见久久见免费影院 | 天天爱天天干天天爽 | 久草电影在线观看 | 国产一区二区视频在线播放 | 久久久久久国产精品 | 久久精品福利视频 | 五月天中文在线 | 国产亚洲精品日韩在线tv黄 | 久久久视屏 | 最近最新中文字幕 | 夜夜躁天天躁很躁波 | 91av电影在线 | 国产中文字幕精品 | 国产精品久久久电影 | 在线视频久 | 91av影视 | 久久99国产精品久久99 | 久久综合九色综合欧美狠狠 | av在线专区 | 国产这里只有精品 | 国模精品在线 | 国产亚洲在 | 成人免费观看网址 | 一二三四精品 | 精品uu| 国产又粗又猛又爽又黄的视频免费 | 超碰97久久 | 国产免费视频一区二区裸体 | 国产精品粉嫩 | 99久久999久久久精玫瑰 | 一区二区三区视频网站 | 欧美日韩一区二区久久 | 天天色图| 亚洲精品玖玖玖av在线看 | 国产成人精品久久亚洲高清不卡 | 国产区免费 | 91香蕉久久 | 久草视频免费观 | 亚洲一区二区麻豆 | 国产精品99久久久久久久久久久久 | 中文字幕91视频 | 久久综合色8888 | 中文字幕免 | 五月婷婷另类国产 | 最新亚洲视频 | 国产一级二级在线观看 | 在线观看视频h | 91在线91拍拍在线91 | 麻豆免费视频 | 亚洲色综合| 欧美精品一区二区三区一线天视频 | av一级一片 | 欧美日本在线观看视频 | 亚洲成人av在线 | 国产成人精品国内自产拍免费看 | 午夜10000| 国产手机在线视频 | 欧美日韩1区2区 | 91看片一区二区三区 | 黄色小说免费观看 | 天天视频色 | 久久超碰97 | 2023亚洲精品国偷拍自产在线 | 天天综合天天综合 | 99久久精品久久久久久动态片 | 麻豆免费视频网站 | 欧美一级片免费在线观看 | 成人一区二区在线观看 | 久色 网 | 国产另类av | 亚洲天堂自拍视频 | 亚洲精品成人网 | 四虎8848免费高清在线观看 | 色婷婷国产精品一区在线观看 | 久久精品一二区 | 天天干,狠狠干 | 日韩高清激情 | 天天操天天弄 | 在线a视频 | 久久成人在线视频 | 在线观看你懂的网址 | 国产999精品久久久 免费a网站 | 在线视频 区 | 又大又硬又黄又爽视频在线观看 | 欧美一级专区免费大片 | 超碰av在线免费观看 | 国产1区2区| 麻豆免费看片 | 日本在线视频一区二区三区 | 99亚洲国产 | 992tv在线观看 | 免费看污片 | 久久综合影院 | 91成人在线视频观看 | 国产一级黄色免费看 | www.日本色 | 最近的中文字幕大全免费版 | 999久久国精品免费观看网站 | 亚洲乱码精品久久久久 | 外国av网 | 亚洲手机av | 婷婷丁香狠狠爱 | 亚洲天堂网站视频 | 丁香五月网久久综合 | 亚洲最大成人免费网站 | 精品久久久久久一区二区里番 | 免费亚洲精品视频 | 中字幕视频在线永久在线观看免费 | 欧美美女视频在线观看 | 最新av电影网站 | 成人h动漫在线看 | 公与妇乱理三级xxx 在线观看视频在线观看 | 久久99国产精品久久99 | 伊人狠狠色| av看片在线观看 | 亚洲电影毛片 | 久久久污| 亚洲欧美日韩国产一区二区三区 | 亚洲精品免费观看视频 | 久久精品99国产精品亚洲最刺激 | 日韩免费视频一区二区 | 在线高清 | av电影免费在线 | 激情久久婷婷 | av福利资源 | 亚州性色 | 夜夜夜夜爽 | 久久免费播放 | 91九色蝌蚪在线 | 视频一区二区国产 | 国产一区二区三区免费视频 | 91热| 亚洲91精品在线观看 | 国产精品久久精品国产 | 一本之道乱码区 | 国产午夜精品在线 | 婷婷伊人综合亚洲综合网 | 在线国产日韩 | 在线影视 一区 二区 三区 | 狠狠色噜噜狠狠 | 免费观看国产精品视频 | 少妇精品久久久一区二区免费 | 国产韩国精品一区二区三区 | 久久艹在线观看 | 久久看片网站 | 午夜在线看 | 中文字幕一区二区三区精华液 | 91精品视频在线观看免费 | 免费在线观看一级片 | 国产成人精品一区二区 | 4438全国亚洲精品观看视频 | 久久人人做| 日韩美女久久 | 日韩av成人在线观看 | 久久人91精品久久久久久不卡 | 国产一二三区在线观看 | 波多野结衣视频一区二区 | 一区二区三区动漫 | 最新动作电影 | 国产91精品看黄网站在线观看动漫 | 日韩精品观看 | 久久国产精品99久久久久久老狼 | 夜色资源站国产www在线视频 | 在线观看免费黄视频 | 一本色道久久精品 | 最新日韩视频 | 成人av资源网| 天天操夜夜拍 | 欧美精品国产综合久久 | 91精品毛片 | 成人动态视频 | 探花国产在线 | 日韩欧美电影在线 | 黄色毛片大全 | 日韩高清免费在线观看 | 日本中文字幕在线 | 丁香六月天婷婷 | 国产精品一区在线观看你懂的 | 国产精品欧美久久久久久 | 精品国产精品一区二区夜夜嗨 | 亚洲涩涩涩 | 国产高清免费在线观看 | 日本免费久久高清视频 | 波多野结衣一区 | 欧美日韩免费一区二区三区 | 成人av在线亚洲 | 国产拍在线 | 亚洲精品1234区 | 日本精品中文字幕 | 久久在线一区 | 网站在线观看你们懂的 | 亚洲成人欧美 | 99精品免费视频 | 视频一区二区视频 | 在线观看免费黄视频 | 欧美一区二区三区四区夜夜大片 | 欧洲黄色片 | 97超碰人人澡 | 午夜视频在线观看网站 | 日韩久久精品一区二区 | 在线网站黄 | 免费观看一级一片 | av资源在线看 | 91污视频在线观看 | 伊人久久在线观看 | 99视频在线精品国自产拍免费观看 | 日韩精品一区二区三区丰满 | 色国产精品一区在线观看 | 天堂视频一区 | 超碰97免费 | 天堂网一区二区三区 | 久久一级片 | 国产乱视频 | 麻豆 91 在线| 久久成年人视频 | 亚洲欧美一区二区三区孕妇写真 | 中文视频一区二区 | 日韩一区二区三区免费电影 | 欧美国产亚洲精品久久久8v | 亚洲精品国偷拍自产在线观看蜜桃 | 在线电影 一区 | 丰满少妇在线 | 99精品福利 | 免费久久网 | 欧美另类一二三四区 | 欧美在线视频一区二区 | 久久精品久久精品 | 91精品国产网站 | 国产香蕉久久精品综合网 | 视频精品一区二区三区 | 91成人看片| av直接看| 成人在线一区二区三区 | 亚洲资源视频 | 91一区二区三区久久久久国产乱 | 日韩黄色中文字幕 | 99视频在线免费观看 | 久久天天躁狠狠躁亚洲综合公司 | 久久久久久久免费看 | 国内精品毛片 | 香蕉久久国产 | 四虎成人精品在永久免费 | 狠狠色狠狠色终合网 | 在线观看亚洲专区 | 亚洲人人射 | 少妇视频在线播放 | 欧美一二三区播放 | 日韩大片免费观看 | 久久人人爽人人爽人人片 | 国产精品久久av | 91在线播放国产 | 99精品欧美一区二区三区 | 午夜黄网| 日韩av网站在线播放 | 色中色资源站 | 天天干夜夜想 | 91精品国产99久久久久 | 欧美视频日韩 | 蜜臀av.com| 久久精品香蕉视频 | 久草在线视频首页 | 亚洲 欧洲 国产 精品 | 青青草国产免费 | 亚洲国产精品成人av | 亚洲一区美女视频在线观看免费 | 伊人狠狠色 | 99视频在线免费看 | 国产福利不卡视频 | 中文资源在线观看 | 中文字幕在线网 | 中文字幕第一页在线播放 | 日本精品二区 | 日韩国产高清在线 | 久久久久久久久影视 | 国产视频久 | 精品国产aⅴ麻豆 | 在线免费色视频 | 国产最新在线观看 | 在线观看国产日韩欧美 | 349k.cc看片app | 欧美ⅹxxxxxx| 91av电影在线 | 免费在线观看国产精品 | 99久久www| 久久天堂精品视频 | www.五月天激情 | 亚洲成a人片77777kkkk1在线观看 | 91成人亚洲| 成人久久18免费网站图片 | 中文字幕在线视频一区 | 色香com.| 岛国av在线免费 | 久久av中文字幕片 | 久久久伊人网 | 欧美精品国产精品 | 久久精品中文字幕免费mv | 欧美日韩国语 | 激情网色 | 日韩欧美一区二区三区视频 | 国产精品免费一区二区三区在线观看 | 国产精品入口a级 | 国产成人免费高清 | 久久精品站 | 国产精品视频99 | 国产区网址 | 日日碰狠狠躁久久躁综合网 | 中文字幕一区三区 | 久久九九国产视频 | 成人在线观看日韩 | 日韩天天综合 | 麻豆视频在线免费 | 久久在草| 天天干天天操天天操 | 色欧美88888久久久久久影院 | 91精品国产自产91精品 | 久久香蕉一区 | 国产午夜免费视频 | 天天av天天 | 黄色免费网站下载 | 999久久久久久久久6666 | 国产精品久久人 | 亚洲久久视频 | 五月色婷 | 久久夜色电影 | 亚洲天天干| 日韩城人在线 | 在线a视频 | 亚洲aⅴ免费在线观看 | 日日干日日 | 精品国产免费久久 | 久久99精品久久久久久清纯直播 | 激情丁香5月 | 国产一区二区高清不卡 | 欧美日韩国内在线 | 天天做日日做天天爽视频免费 | 国产精品观看在线亚洲人成网 | 在线91播放 | 中文字幕在线观看完整版 | 91精品久久香蕉国产线看观看 | 99精品视频免费观看视频 | 日韩视频一 | 欧美日韩午夜在线 | 亚洲乱码中文字幕综合 | 手机在线看永久av片免费 | 国产精品久久久久免费 | 男女视频国产 | 免费视频一区 | 人人爽人人爽人人爽学生一级 | 亚洲黄色在线观看 | www.五月天色 | 成人黄色电影免费观看 | 日韩欧美精品一区 | 一区二区三区久久精品 | 久久精品一区二区三区国产主播 | 国产精品不卡在线观看 | 亚洲欧美视频在线播放 | 黄污视频网站 | 青草视频在线看 | 日日干夜夜骑 | 米奇影视7777 | av在线永久免费观看 | 欧美日韩一区二区在线 | 一本一本久久a久久精品综合小说 | 亚洲精品在线观看的 | 在线观看国产高清视频 | 日韩电影精品一区 | 99高清视频有精品视频 | 精品国产乱码久久久久久天美 | 操久在线 | 成人午夜剧场在线观看 | 日韩欧美电影在线 | 91av手机在线 | 91九色九色 | 青青草视频精品 | 精品欧美小视频在线观看 | 日韩| 一区二区三区动漫 | 色婷婷精品大在线视频 | 精品国产自 | 国产精品com | 九九九毛片 | 国产一级在线视频 | 久久免费在线视频 | 色综合在 | 香蕉一区 | 黄色三级免费看 | 精品一区中文字幕 | 视频在线国产 | 免费av在线网站 | 亚洲综合日韩在线 | 777奇米四色 | 久久久人 | 精品1区二区 | 一区二区三区四区精品 | 亚洲色图色 | 久久精品黄 | 2020天天干天天操 | 国产精品视频最多的网站 | 日本特黄一级片 | 国产美女在线精品免费观看 | 精品美女久久久久久免费 | 中国一级特黄毛片大片久久 | 成人a级大片| 天堂中文在线视频 | 久久婷亚洲五月一区天天躁 | 亚洲精品日韩一区二区电影 | 免费的黄色av | 91丨九色丨首页 | 91精品婷婷国产综合久久蝌蚪 | 探花视频在线观看+在线播放 | www久久com | 在线小视频 | av888av.com| 亚洲h在线播放在线观看h | 成人av电影免费在线观看 | 午夜精品久久久久 | 黄色成人免费电影 | 日本激情中文字幕 | 人人网av | 久久精品五月 | 91视频在线免费看 | 国产视频在线观看一区 | 国产日产精品久久久久快鸭 | 人人干网站 | 久99久精品视频免费观看 | 国产美女免费视频 | 在线观看亚洲视频 | 国产免费av一区二区三区 | 97人人看 | 欧美一区视频 | 久久蜜臀一区二区三区av | 日韩电影在线一区二区 | 91视频免费观看 | 欧美三级在线播放 | 三级黄色免费 | 国产精品麻豆果冻传媒在线播放 | 最近中文字幕免费大全 | 在线免费看片 | 国产成人一级 | 激情伊人 | 国产视频九色蝌蚪 | 久久综合九色综合97婷婷女人 | 91天天操 | 高清美女视频 | 天堂av免费 | 九九热精品在线 | 黄污视频网站 | 日本公妇色中文字幕 | www国产亚洲精品久久麻豆 | 在线观看mv的中文字幕网站 | 天天射夜夜爽 | 久久久久久久久久久久久国产精品 | 欧美激情视频一二三区 | 五月天激情视频在线观看 | 午夜精品一区二区三区视频免费看 | 天天操天天舔天天爽 | 国产一二区在线观看 | 天天操天天色天天射 | 国产色女人| 欧美在线观看视频一区二区 | 手机av网站 | 911久久香蕉国产线看观看 | 日韩一级片大全 | 日韩高清 一区 | 精品国产伦一区二区三区免费 | 激情欧美在线观看 | 欧美色图88| 伊人网综合在线观看 | 国产91精品看黄网站在线观看动漫 | 国产99久久久国产 | 国产91精品欧美 | 黄色特一级片 | 在线小视频你懂得 | 免费在线观看日韩欧美 | 91在线视频网址 | 久久综合精品一区 | av成人动漫 | 黄在线免费看 | 精产嫩模国品一二三区 | 色成人亚洲网 | 国产香蕉视频在线观看 | 久久婷婷久久 | 国产精品初高中精品久久 | 九草在线观看 | av片子在线观看 | 日韩一级成人av | 免费高清在线观看成人 | 成人91在线 | 久久久精品在线观看 | 国产精品2018 | 亚洲无吗av | 日韩免费中文字幕 | 色综合天天视频在线观看 | 亚洲一级特黄 | 国产人在线成免费视频 | 天天射网 | 九九爱免费视频在线观看 | 永久免费观看视频 | 久久99久久99免费视频 | 99爱视频 | 91c网站色版视频 | 麻豆国产视频 | 午夜视频免费 | 亚洲成人精品久久 | 91大神精品视频在线观看 | 色婷婷电影 | av+在线播放在线播放 | 天天草网站 | 日韩精品一区二区三区外面 | 国产成人一区二区在线观看 | 国产91精品久久久久 | 五月综合激情婷婷 | 国产在线播放不卡 | 日本中文乱码卡一卡二新区 | 久久国产美女视频 | 天天天色| 在线观看国产永久免费视频 | 婷婷深爱 | 91av网址| 日韩精品一区二区三区高清免费 | 欧美日韩国产在线 | 亚洲精品免费观看 | 99久久国产免费看 | 成人午夜电影网 | 久久综合成人网 | 日日干综合 | 久久黄色免费视频 | 日本精品视频在线观看 | 久久久国产精品网站 | 日韩三级视频在线观看 | 天天曰天天射 | 网站在线观看日韩 | 亚洲精品97 | 成年人免费在线观看网站 | 欧美91精品国产自产 | 夜夜干天天操 | 美女视频网站久久 | 色狠狠婷婷 | 欧美久久久久久久久久 | 免费h视频| 国产精品门事件 | 美女久久视频 | 激情av一区二区 | 91av在线精品| 亚洲综合激情小说 | 97av免费视频 | 99久久精品国产一区二区成人 | 久久视频国产精品免费视频在线 | 精品日韩av | 国内久久精品视频 | 亚洲三区在线 | 成人免费xxx在线观看 | 国产九九九九九 | 91精品国产高清自在线观看 | 最新国产在线 | 色噜噜在线观看 | 天天夜操 | 五月丁色 | 色综合久久综合中文综合网 | 99精品一级欧美片免费播放 | 亚洲激情中文 | 亚洲精品高清视频 | 久久高清视频免费 | 中国精品一区二区 | 成+人+色综合 | 91亚洲精 | 国产精品婷婷 | 国产一区二区不卡视频 | 欧美一区二区精美视频 | 丰满少妇麻豆av | 久久综合婷婷国产二区高清 | 国产精品自产拍在线观看桃花 | 欧美激情视频在线免费观看 | 久久精品牌麻豆国产大山 | 亚洲成人二区 | 麻豆你懂的 | 麻豆一级视频 | 国产国产人免费人成免费视频 | 成年在线观看 | 国产精品免费视频久久久 | 97人人澡人人添人人爽超碰 | 国产精品视频免费在线观看 | 欧美一级在线观看视频 | 干干干操操操 | 成人一区电影 | 久久久亚洲网站 | 国产精品一区二区久久 | 国产视频黄 | 中字幕视频在线永久在线观看免费 | 黄网站免费大全入口 | 国产精品v欧美精品v日韩 | 国产人成一区二区三区影院 | 国产一级免费在线观看 | 丝袜美腿亚洲 | 久久最新视频 | 国产专区一 | 久久成人国产精品入口 | 永久免费的啪啪网站免费观看浪潮 | 国产成人三级一区二区在线观看一 | 亚洲专区一二三 | 日韩在线中文字幕视频 | 97人人模人人爽人人喊中文字 | 久久久久久久久久久高潮一区二区 | 中文免费观看 | 国产中文字幕视频在线观看 | 婷婷5月色 | 国产在线2020 | a天堂最新版中文在线地址 久久99久久精品国产 | 久久人人爽爽 | 国产打女人屁股调教97 | 久久久精品 一区二区三区 国产99视频在线观看 | 丁香六月婷婷激情 | 日韩动漫免费观看高清完整版在线观看 | 亚洲综合在线观看视频 | 天天干天天做 | 欧美日韩1区2区 | 国产 在线 高清 精品 | 久久久久综合精品福利啪啪 | 天天综合色网 | 久久国产精品一区二区三区四区 | 成人av教育 | 久草香蕉在线 | 精品av网站 | 欧美精品在线观看 | 九九久久国产精品 | 国产黄色在线 | 午夜美女影院 | 亚洲日本国产精品 | 亚洲精品国产第一综合99久久 | 久av在线 | 日本精品久久久一区二区三区 | 成人一级片在线观看 | 热99在线视频 | 国产精品不卡在线观看 | 国产中文字幕一区二区三区 | 欧美不卡视频在线 | 亚洲激情六月 | 伊人婷婷综合 | 欧美日韩啪啪 | 欧美精品免费视频 | 综合精品久久久 | 波多野结衣视频一区二区三区 | 黄色app网站在线观看 | 日韩一三区 | 蜜臀精品久久久久久蜜臀 | 欧美另类色图 | 五月婷婷av | 国产精品久久久久永久免费观看 | 开心激情网五月天 | 超碰在线cao | 狠狠综合久久 | 久久久综合香蕉尹人综合网 | 国产在线永久 | 国产韩国精品一区二区三区 | 国产一级精品绿帽视频 | 久草在线99 | 亚洲精品久久久久999中文字幕 | 国产在线观看国语版免费 | 国产一区在线视频播放 | 色综合久久久久久中文网 | 黄色三几片 | 欧美久久久久久久久久久 | 欧美日韩久久不卡 | 西西444www大胆高清图片 | 久久久久久久久久网站 | 亚洲国产日韩一区 | 丁香花中文字幕 | 午夜电影久久久 | 99久久国产免费,99久久国产免费大片 | 欧美日韩免费一区二区 | 99精品视频在线免费观看 | 亚洲精品午夜久久久久久久 | 久久久久中文 | 欧美精品乱码久久久久久按摩 | 999久久久久久 | 深爱五月激情五月 | 一区二区中文字幕在线观看 | 狠狠狠色 | 国产女人18毛片水真多18精品 | 久久爱综合| 天天操天天干天天综合网 | 精品国产黄色片 | 在线电影日韩 | 国产精品久久久久久久久岛 | 97视频免费观看2区 亚洲视屏 | 亚洲国产美女久久久久 | 91精品国产高清自在线观看 | 香蕉在线观看视频 | 激情婷婷久久 | 日本久久久久久久久 | 色五月色开心色婷婷色丁香 | 亚洲国产字幕 | 久久精品国产99国产 | 最新av网址在线观看 | 婷婷在线资源 | 亚洲永久精品在线 | 麻豆一区在线观看 | 国产成人精品av在线观 | 午夜精品久久一牛影视 | 在线视频免费观看 | 亚洲国产电影在线观看 | 99久久www免费 | 在线草| 精品久久久久久综合日本 | 97精品国产97久久久久久免费 | 91女人18片女毛片60分钟 | 成人在线视频在线观看 | 99久久超碰中文字幕伊人 | 亚洲精区二区三区四区麻豆 | 成人av在线播放网站 | 天天干天天干天天干天天干天天干天天干 | 欧美一级淫片videoshd | 日韩中文幕 | 国产精品综合久久久久久 | 最新中文在线视频 | av免费网| 97碰碰精品嫩模在线播放 | 日本久久久精品视频 | 99久久免费看 | 精品96久久久久久中文字幕无 | 成人理论电影 | 999久久久久久久久久久 | 91成人在线看 | av福利网址导航大全 | 精品一区二区三区四区在线 | 在线观看中文字幕一区二区 | 蜜桃视频在线视频 | 91大神免费视频 | 国产激情久久久 | 亚洲国产伊人 | av片中文 | 一区二区三区免费在线播放 | www婷婷 | 欧美日韩高清 | 国产一区网 | 国产传媒一区在线 | 丁香久久五月 | 国产中文在线视频 | 亚洲人成在线电影 | 91最新地址永久入口 | 色偷偷888欧美精品久久久 | 亚洲激情综合网 | 激情久久久久久久久久久久久久久久 | 在线免费91 | 久久综合日 | 91九色在线视频观看 | 精品国产理论片 | 免费在线观看成人小视频 | 久久国产精品99久久久久 | 在线观看涩涩 | 久久一区二区三区日韩 | 亚洲午夜在线视频 | 免费在线观看视频一区 | 亚洲综合欧美激情 | 91中文字幕永久在线 | 日韩中文字幕免费视频 | 亚洲aaa级| 97国产大学生情侣白嫩酒店 | 一区二区三区视频网站 | 在线观看免费一区 | 97超碰人人网| 亚州欧美视频 | 一区二区精品视频 | 狠狠狠色丁香婷婷综合久久五月 | 欧美日韩在线播放 | 丁香婷婷激情国产高清秒播 | 天天操天天操天天操天天 | 亚洲综合视频在线 | 国产精品免费久久久久影院仙踪林 | 日韩高清成人在线 | 免费在线观看中文字幕 | 久久久久久久久久福利 | 国产99re| 日韩欧美一区二区三区免费观看 | av福利第一导航 | 婷婷www| 亚洲欧洲精品一区二区精品久久久 | 日韩理论 | 少妇激情久久 | 日韩av在线一区二区 | 91av原创| 丁香九月婷婷综合 | 天天看天天干 | 麻豆91在线| 免费av网站观看 | 超碰在线cao| 亚洲国产精品资源 | 成人免费毛片aaaaaa片 | 久久中文网 | 97在线视频免费看 | 日韩精品久久久久久久电影99爱 | 美女网站在线 | 中文字幕av在线不卡 | 国产精品无av码在线观看 | 999成人网 | 热99久久精品 | 国产视频一区在线 | 日韩一区在线播放 | 午夜.dj高清免费观看视频 | 免费激情网 | 亚洲乱亚洲乱亚洲 | 日日夜夜免费精品视频 | 亚洲伦理精品 | 精品中文字幕在线观看 | 91系列在线 | 国产不卡av在线播放 | 国产精品在线看 | 菠萝菠萝蜜在线播放 | 国产一区私人高清影院 | 国产区在线看 | 一区二区三区中文字幕在线观看 | 91中文字幕在线播放 | 国产精品免费久久久 | 看国产黄色大片 | 91在线小视频 | 婷婷av综合 | a久久久久久 | 九九九九九精品 | 欧美a视频 | 91精品国自产在线观看 | 国产高清在线看 | 欧美性久久久久久 | 免费在线一区二区 | 成人黄色电影在线 | 国产香蕉97碰碰碰视频在线观看 | 91精品久久久久久久久久久久久 | 黄色免费在线视频 | 91网在线| av网站免费线看精品 | 亚洲精品综合久久 | 国产精品av在线 | 中文国产在线观看 | 国产91亚洲精品 | 日韩一区二区三区观看 | 黄色免费视频在线观看 | 激情小说久久 | 免费精品人在线二线三线 | 久久综合久色欧美综合狠狠 | 一级黄色视屏 | 国产精品免费观看在线 | 亚洲欧美综合精品久久成人 | 日韩精品一区二区在线视频 | 亚洲精品国偷拍自产在线观看蜜桃 | 99视频免费看 | 天堂av影院 | 色综合久久久久久久 | 丁香六月婷婷 | 天天视频色 | 日韩精品一区二区在线观看 | 国产精品国产三级国产专区53 | 久久久久久欧美二区电影网 | 久久综合欧美精品亚洲一区 | 激情综合色播五月 | 五月婷婷,六月丁香 | 日韩理论片在线观看 | 99久久精品免费视频 | 免费看成人片 | 中文资源在线官网 | 日韩理论电影网 | 日韩视频免费 | 日本超碰在线 | 成人a免费看 | 国产精品麻豆91 | bayu135国产精品视频 | 一区二区三区在线免费 | 青青草国产免费 | 国产精品黄色影片导航在线观看 | 欧美在线观看禁18 | 天天操天天干天天综合网 | av免费高清观看 | 国产美女久久久 | 国产成人亚洲在线电影 | 婷婷色吧 | av7777777| 国产毛片久久久 | 亚洲一区精品人人爽人人躁 | 中文字幕一区二区三区在线视频 | 欧美日韩一区二区三区在线观看视频 | 麻花天美星空视频 | 波多野结衣电影一区二区三区 | 美女视频黄频大全免费 | 丁香六月色 | 蜜桃麻豆www久久囤产精品 | 日韩欧美在线观看一区 | 三级av网站 | 久久久久亚洲精品国产 | 亚洲 欧美 精品 | 精品亚洲成a人在线观看 | 日韩精品一区二区三区免费观看 | 免费看片网页 | 国产精品久久久久9999 | 国产美女主播精品一区二区三区 | 亚洲激情一区二区三区 | 国内视频 | 欧美日韩国产色综合一二三四 | 97超碰在线久草超碰在线观看 | av免费观看高清 | 亚洲精品久久久久久久不卡四虎 | 娇妻呻吟一区二区三区 |