《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 測(cè)試測(cè)量 > 設(shè)計(jì)應(yīng)用 > 基于Linux系統(tǒng)的PCI設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)
基于Linux系統(tǒng)的PCI設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)
崔 莉, 趙大政
摘要: 以一個(gè)具體的PCI設(shè)備的驅(qū)動(dòng)開(kāi)發(fā)過(guò)程為基礎(chǔ),總結(jié)了與PCI設(shè)備驅(qū)動(dòng)開(kāi)發(fā)的相關(guān)問(wèn)題,詳細(xì)闡述了基本開(kāi)發(fā)步驟、具體實(shí)現(xiàn)、驅(qū)動(dòng)程序內(nèi)核塊的加載以及用戶進(jìn)程和驅(qū)動(dòng)程序的協(xié)同工作問(wèn)題。
Abstract:
Key words :

  摘  要: 以一個(gè)具體的PCI設(shè)備的驅(qū)動(dòng)開(kāi)發(fā)過(guò)程為基礎(chǔ),總結(jié)了與PCI設(shè)備驅(qū)動(dòng)開(kāi)發(fā)的相關(guān)問(wèn)題,詳細(xì)闡述了基本開(kāi)發(fā)步驟、具體實(shí)現(xiàn)、驅(qū)動(dòng)程序內(nèi)核塊的加載以及用戶進(jìn)程和驅(qū)動(dòng)程序的協(xié)同工作問(wèn)題。
  關(guān)鍵詞: PCI設(shè)備  設(shè)備驅(qū)動(dòng)  中斷

1 Linux 系統(tǒng)下設(shè)備驅(qū)動(dòng)的概念
  在Linux操作系統(tǒng)下,系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口[2]。設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié)。這樣在應(yīng)用程序看來(lái),硬件設(shè)備只是一個(gè)文件,即特殊的設(shè)備文件。因此應(yīng)用程序通過(guò)特定的設(shè)備驅(qū)動(dòng)程序可以像操作普通文件一樣對(duì)具體的硬件設(shè)備進(jìn)行操作。應(yīng)用程序和設(shè)備驅(qū)動(dòng)的關(guān)系如圖1所示。

 


  在Linux操作系統(tǒng)下有二種主要的設(shè)備文件類型,一種是字符設(shè)備,另一種是塊設(shè)備。每種設(shè)備文件和實(shí)際的硬件相聯(lián)系。字符設(shè)備和塊設(shè)備的主要區(qū)別是:字符設(shè)備在寫請(qǐng)求的同時(shí),實(shí)際的硬件I/O操作便發(fā)生了。塊設(shè)備則不然,它利用一塊系統(tǒng)內(nèi)存作緩沖區(qū),當(dāng)用戶進(jìn)程對(duì)設(shè)備請(qǐng)求讀/寫時(shí),它首先察看緩沖區(qū)的內(nèi)容。如果緩沖區(qū)的數(shù)據(jù)能滿足用戶的要求,就返回請(qǐng)求的數(shù)據(jù),如果不能,就調(diào)用請(qǐng)求函數(shù)來(lái)進(jìn)行實(shí)際的I/O操作。塊設(shè)備主要是針對(duì)磁盤等慢速設(shè)備設(shè)計(jì)的,以免等待時(shí)耗費(fèi)過(guò)多的CPU時(shí)間。
  就特定的PCI卡,用戶可根據(jù)用途來(lái)確定是將其作為塊設(shè)備,還是字符設(shè)備來(lái)處理。本文根據(jù)實(shí)際工作中所用到的PCI采集卡的特點(diǎn),簡(jiǎn)要闡述了其驅(qū)動(dòng)程序開(kāi)發(fā)過(guò)程中需要注意的問(wèn)題和基本步驟。
2  Linux系統(tǒng)PCI設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)
2.1 基本需求分析
 
  根據(jù)設(shè)備不同的用途,可以區(qū)分不同的PCI設(shè)備類型。基于這一設(shè)備類型,又可以分析出其他一些基本需求。從本文所使用的數(shù)據(jù)采集卡可知,其主要用途是用于采集和控制。根據(jù)工控過(guò)程的特點(diǎn),需要PCI采集卡在每采樣一個(gè)數(shù)據(jù)點(diǎn)時(shí),就以中斷的方式交給內(nèi)核緩沖,再由用戶程序適時(shí)取出使用。因此,將PCI采集卡作為一個(gè)字符設(shè)備來(lái)處理,并選擇觸發(fā)模式為內(nèi)觸發(fā),數(shù)據(jù)傳送模式為中斷傳送。本文就是基于這樣的需求,按如下所述的步驟和具體實(shí)現(xiàn)過(guò)程,開(kāi)發(fā)了其驅(qū)動(dòng)程序。
2.2 基本步驟
  (1)PCI設(shè)備文件的建立
  既然PCI設(shè)備被操作系統(tǒng)當(dāng)作特殊的文件來(lái)看,就要有個(gè)文件名。因此,建立一設(shè)備文件的名字來(lái)代表硬件設(shè)備是開(kāi)發(fā)驅(qū)動(dòng)的第一步。按照習(xí)慣,設(shè)備文件都放在系統(tǒng)目錄/dev下。一般在開(kāi)發(fā)過(guò)程中,由于要經(jīng)常查看設(shè)備文件的狀態(tài),而在這一目錄下已經(jīng)有很多設(shè)備文件,查看起來(lái)特別不方便,因此,可以自己在某個(gè)地方建立一個(gè)文件夾,將該設(shè)備文件放在該文件夾下。使用mknod命令可以建立設(shè)備特殊文件(注意:只有root賬號(hào)的超級(jí)用戶才能使用些命令),其格式示例為:
  $mknod  /subfolders/mydev/PCIdrv   c  254  0
  也就是用主設(shè)備號(hào)254(一般在Linux操作系統(tǒng)下設(shè)備文件的主設(shè)備號(hào)不會(huì)超過(guò)254,所以選用254,以確保該設(shè)備號(hào)是惟一的)和輔助設(shè)備號(hào)0在目錄/subfolders/mydev下建立特殊設(shè)備文件PCIdrv。
  (2)file_operation數(shù)據(jù)結(jié)構(gòu)
  設(shè)備驅(qū)動(dòng)程序就是一組能完成特定任務(wù)的、在內(nèi)核態(tài)下運(yùn)行的子函數(shù)的集合。每個(gè)設(shè)備驅(qū)動(dòng)程序都有一個(gè)被稱作file_operation的數(shù)據(jù)結(jié)構(gòu)來(lái)管理、組織這些子函數(shù)。該結(jié)構(gòu)包含了指向驅(qū)動(dòng)程序內(nèi)部這些子函數(shù)的指針。當(dāng)系統(tǒng)引導(dǎo)時(shí),內(nèi)核會(huì)調(diào)用每個(gè)驅(qū)動(dòng)程序的初始化函數(shù)。它有二個(gè)任務(wù)要完成:(1)將設(shè)備驅(qū)動(dòng)程序使用的主設(shè)備號(hào)通知內(nèi)核;(2)初始化函數(shù)將file_operation指針傳送給內(nèi)核。基本結(jié)構(gòu)為:
  struct file_operations PCI_fops={NULL,PCIread,
  PCIwrite,NULL,NULL,NULL,NULL,
  PCIopen,PCIrelease,NULL,NULL};
  結(jié)構(gòu)中的每一個(gè)非NULL成員的名字都對(duì)應(yīng)著一個(gè)系統(tǒng)調(diào)用。用戶進(jìn)程利用系統(tǒng)調(diào)用在對(duì)設(shè)備文件進(jìn)行諸如讀/寫操作時(shí),系統(tǒng)調(diào)用通過(guò)設(shè)備文件的主設(shè)備號(hào)找到相應(yīng)的設(shè)備驅(qū)動(dòng)程序,然后讀取這個(gè)數(shù)據(jù)結(jié)構(gòu)相應(yīng)的函數(shù)指針,接著把控制權(quán)交給該函數(shù)。這是Linux的設(shè)備驅(qū)動(dòng)程序工作的基本流程。例如:當(dāng)用戶進(jìn)程執(zhí)行open( )調(diào)用時(shí),open( )執(zhí)行體將根據(jù)open所帶的參數(shù)找到PCI設(shè)備驅(qū)動(dòng)程序,并根據(jù)其相關(guān)聯(lián)的PCI_fops數(shù)據(jù)結(jié)構(gòu),找到PCIopen子函數(shù)的入口點(diǎn),接著就執(zhí)行PCIopen函數(shù)體。
  (3)編寫驅(qū)動(dòng)程序子函數(shù)
  file_operation的數(shù)據(jù)結(jié)構(gòu)中所定義的子函數(shù)的集合構(gòu)成了具體的設(shè)備驅(qū)動(dòng)的執(zhí)行體。因此編寫驅(qū)動(dòng)程序子函數(shù)是開(kāi)發(fā)過(guò)程中最為重要的一步,這些子函數(shù)要根據(jù)具體的需求來(lái)設(shè)計(jì)。工作中用到的PCI采集卡的主要功能函數(shù)有:A/D轉(zhuǎn)換函數(shù)AD_INT_Start、AD_INT_Stop、AD_INT_Data,數(shù)字量采集與輸出函數(shù)DI_Data、DO_Data,D/A轉(zhuǎn)換函數(shù)AO_Data等。這里不予贅述。
2.3 PCI采集卡驅(qū)動(dòng)程序的具體實(shí)現(xiàn)
  (1)獲取PCI采集卡的基本配置信息
  PCI采集卡的驅(qū)動(dòng)程序主要是完成對(duì)采集卡的寄存器和PCI總線控制器的PCI配置空間的設(shè)置和讀取,用以啟動(dòng)采集卡,并按照一定的方式進(jìn)行采集、傳送、停止等。若要對(duì)這些寄存器進(jìn)行設(shè)置和讀取,就要知道這些寄存器的BaseAddress和偏移值、中斷號(hào)等相關(guān)配置信息。這是對(duì)硬件操作的第一步。Linux操作系統(tǒng)對(duì)PCI設(shè)備提供了大量的初始化函數(shù)(這一點(diǎn)不同于Dos和Windows)。因此,在系統(tǒng)啟動(dòng)時(shí),這特定的初始化函數(shù)會(huì)被調(diào)用,用來(lái)檢測(cè)系統(tǒng)中存在的所有的PCI設(shè)備,并填充PCI設(shè)備的配置空間。因此,在開(kāi)發(fā)PCI設(shè)備驅(qū)動(dòng)時(shí),只要執(zhí)行相關(guān)的系統(tǒng)調(diào)用(由系統(tǒng)提供),就可獲得所需要的PCI設(shè)備信息。
下面是幾個(gè)常用的內(nèi)核函數(shù):
  ①pcibios_present( )
  ②int pcibios_find_device(int device_id,int vendor_id,
int index,int*bus_number,int*device_function)
    ③read_config_byte,read_config_word,read_config_dword
    ④write_config_byte,write_config_word,write_config_dword
    函數(shù)①的功能是:返回一個(gè)布爾值表明所運(yùn)行的計(jì)算機(jī)是否具有支持PCI設(shè)備的能力;函數(shù)②的功能是:返回設(shè)備在總線上的位置及函數(shù)指針bus_number、device_function;函數(shù)③、④的功能是:通過(guò)調(diào)用該類函數(shù),設(shè)備驅(qū)動(dòng)程序?qū)崿F(xiàn)寄存器空間的訪問(wèn),包括讀和寫。
  (2)內(nèi)存操作
  設(shè)備驅(qū)動(dòng)的子函數(shù)運(yùn)行在內(nèi)核態(tài),在設(shè)備驅(qū)動(dòng)程序中動(dòng)態(tài)開(kāi)辟和釋放內(nèi)存。用kmalloc或get_free_pages直接申請(qǐng)頁(yè)而不是用malloc和free;釋放內(nèi)存用的是kfree或free_pages。kmalloc等函數(shù)返回的是物理地址,而malloc等返回的是線性地址,且kmalloc最大只能開(kāi)辟128KB。
  很多硬件需要一塊比較大的連續(xù)內(nèi)存用作DMA傳送,并且需要一直駐留在內(nèi)存,不能被交換到磁盤文件中去。但是kmalloc最多只能開(kāi)辟128KB的內(nèi)存,這可以通過(guò)犧牲一些系統(tǒng)內(nèi)存的方法來(lái)解決。具體做法是:若機(jī)器是32MB的內(nèi)存,在lilo.conf的啟動(dòng)參數(shù)中加上mem=30MB,這樣Linux就認(rèn)為此機(jī)器只有30MB的內(nèi)存,剩下的2MB內(nèi)存在vremap之后就可以為DMA所用。
  (3)Linux下的中斷及中斷處理
  Linux中的中斷處理程序很有特色。它的一個(gè)中斷處理程序可分為上半部(top half)和下半部(bottom half)二個(gè)部分。之所以會(huì)有上半部和下半部之分,完全是考慮到中斷處理的效率。上半部的功能是“登記中斷”,當(dāng)一個(gè)中斷發(fā)生時(shí),它就把設(shè)備驅(qū)動(dòng)程序中中斷例程的下半部掛到該設(shè)備的下半部執(zhí)行隊(duì)列中去,然后就等待新的中斷的到來(lái)。這樣一來(lái),上半部執(zhí)行的速度就會(huì)很快,它就可以接受更多設(shè)備產(chǎn)生的中斷。上半部之所以要快,是因?yàn)樗峭耆帘沃袛嗟模绻粓?zhí)行完,其他的中斷就不能被及時(shí)處理,只能等到這個(gè)中斷處理程序執(zhí)行完畢以后。所以,要盡可能多地對(duì)設(shè)備產(chǎn)生的中斷進(jìn)行服務(wù)和處理,確保中斷處理程序的速度。
要使用一個(gè)中斷,必須先向系統(tǒng)登記。實(shí)現(xiàn)系統(tǒng)中斷登記的系統(tǒng)調(diào)用形式如下:
  int request_irq(unsigned int irq,void(*handle)(int,void*,struct pt_regs*),unsigned int long flags,const char*device);
  其中:irq是要申請(qǐng)的中斷號(hào),handle是中斷處理函數(shù)指針,flags是中斷標(biāo)識(shí),device是設(shè)備名。
  如果登記成功,則返回0。這時(shí)在/proc/interrupts文件中可以看到自己請(qǐng)求的中斷。
  (4)內(nèi)核態(tài)和用戶態(tài)下數(shù)據(jù)交換問(wèn)題
  用戶進(jìn)程在執(zhí)行特定系統(tǒng)調(diào)用使用設(shè)備時(shí),系統(tǒng)就從用戶態(tài)進(jìn)入內(nèi)核態(tài)下運(yùn)行,這時(shí)用戶進(jìn)程的環(huán)境仍然可用。但在內(nèi)核緩沖區(qū)和用戶進(jìn)程緩沖區(qū)間進(jìn)行數(shù)據(jù)交換時(shí),必須要用內(nèi)核提供的專門函數(shù)。主要有:put_user( ),get_user( ),copy_to_user( ),copy_from_user( )等。
  通過(guò)這些調(diào)用來(lái)使用用戶緩沖時(shí)還要進(jìn)行用戶緩沖讀寫權(quán)限的檢驗(yàn),否則調(diào)用數(shù)據(jù)交換函數(shù)時(shí)會(huì)出錯(cuò)。檢驗(yàn)函數(shù)為:int verify_area(int access,void*u_addr,unsigned long size)。
3 將驅(qū)動(dòng)程序嵌入內(nèi)核
  由于驅(qū)動(dòng)程序是在內(nèi)核下運(yùn)行,因此,要把編寫的驅(qū)動(dòng)程序嵌入內(nèi)核。驅(qū)動(dòng)程序可以按照二種方式編譯,一種是編譯進(jìn)kernel,另一種是編譯成模塊(modules)。如果編譯進(jìn)內(nèi)核的話,會(huì)增加內(nèi)核的大小,還要改動(dòng)內(nèi)核的源文件,而且不能動(dòng)態(tài)卸載,不利于調(diào)試。所以推薦使用模塊方式。這種方式可以用insmod命令來(lái)加載模塊和用rmmod來(lái)卸載模塊。
  在用insmod命令將編譯好的模塊調(diào)入內(nèi)核時(shí),init_module 函數(shù)被調(diào)用。在這里,init_module只做了一件事,就是向系統(tǒng)的字符設(shè)備表登記了一個(gè)字符設(shè)備。register_chrdev需要三個(gè)參數(shù):其一是希望獲得的設(shè)備號(hào),如果為0,系統(tǒng)將選擇一個(gè)沒(méi)有被占用的設(shè)備號(hào)返回;其二是設(shè)備文件名;其三是用來(lái)登記驅(qū)動(dòng)程序?qū)嶋H執(zhí)行操作的函數(shù)指針。如果登記成功,則返回設(shè)備的主設(shè)備號(hào);若不成功,則返回一個(gè)負(fù)值。
  下面是用模塊方法將驅(qū)動(dòng)程序加載進(jìn)內(nèi)核時(shí)用的主要功能函數(shù)體示例,也就是當(dāng)執(zhí)行inmod 命令時(shí)執(zhí)行的函數(shù)體。
  int init_module(void)
  {
       int result;
       result=register_chrdev(254,″PCItest″,&PCI_fops);
       if(result<0) {
    printk(KERN_INFO ″test:can′t get major number\n″);
    return result;
       }
       if(PCItest==0) PCItest=result;/*dynamic*/
       return 0;
  }
  同樣可以用 rmmod 命令卸載模塊:
  void cleanup_module(void)
  {
       unregister_chrdev(254,″PCItest″);
  }
  在用rmmod卸載模塊時(shí),cleanup_module函數(shù)被調(diào)用,它釋放字符設(shè)備PCItest在系統(tǒng)字符設(shè)備表中占有的表項(xiàng)。
4  結(jié)束語(yǔ)
  設(shè)計(jì)Linux設(shè)備驅(qū)動(dòng)程序有一定的模式,遵循這個(gè)模式,將會(huì)大大減輕設(shè)計(jì)程序的工作量。本文總結(jié)了工作中對(duì)一種PCI采集卡的驅(qū)動(dòng)開(kāi)發(fā)過(guò)程。同網(wǎng)卡的驅(qū)動(dòng)相比,PCI采集卡驅(qū)動(dòng)的開(kāi)發(fā)是一件相對(duì)簡(jiǎn)單的工作,但它們同屬于PCI設(shè)備,具有類似之處。所以,PCI采集卡的驅(qū)動(dòng)開(kāi)發(fā)對(duì)設(shè)計(jì)復(fù)雜的網(wǎng)絡(luò)驅(qū)動(dòng)程序是很有幫助的。
參考文獻(xiàn)
1   Rubini A著,LISOLEG譯.Linux設(shè)備驅(qū)動(dòng)程序.北京:中國(guó)電力出版社,2000
2   蔡震.Linux系統(tǒng)下USB設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā).計(jì)算機(jī)測(cè)量與控制,2003;11(2)
3   李善平,劉文蜂.Linux內(nèi)核2.4版源代碼分析大全.北京:機(jī)械工業(yè)出版社,2002
4   王學(xué)龍.嵌入式Linux系統(tǒng)設(shè)計(jì)與應(yīng)用.北京:清華大學(xué)出版社,2001
5   Rusling D A著,朱珂譯.Linux編程白皮書(shū).北京:機(jī)械工業(yè)出版社,2000
 

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
亚洲在线网站| 久久久综合免费视频| 午夜久久久久久| 亚洲乱码国产乱码精品精| 欲色影视综合吧| 国内精品久久久久伊人av| 国产伦精品一区二区三区免费迷| 欧美色道久久88综合亚洲精品| 欧美精品七区| 欧美丰满高潮xxxx喷水动漫| 久久理论片午夜琪琪电影网| 久久av在线看| 久久丁香综合五月国产三级网站| 先锋a资源在线看亚洲| 亚洲免费中文字幕| 亚洲欧美三级伦理| 亚洲影院免费观看| 亚洲在线黄色| 亚洲欧美国产日韩天堂区| 亚洲午夜精品17c| 亚洲一区中文| 午夜精品福利一区二区蜜股av| 亚洲一区二区三区高清| 亚洲天堂网站在线观看视频| 中文欧美在线视频| 亚洲欧美变态国产另类| 亚洲欧美日韩中文视频| 午夜久久久久久| 欧美影院久久久| 久久国产婷婷国产香蕉| 久久精品国产99精品国产亚洲性色 | 欧美日韩免费网站| 国产精品s色| 亚洲欧美日韩视频二区| 一区二区在线不卡| 18成人免费观看视频| 最新国产成人av网站网址麻豆| 亚洲免费观看视频| 亚洲淫片在线视频| 欧美一区亚洲| 亚洲区欧美区| 国产精品99久久不卡二区| 香港久久久电影| 玖玖视频精品| 欧美日韩亚洲激情| 国产欧美亚洲日本| 精品动漫一区| 99国产精品久久久久久久| 亚洲性av在线| 欧美在线视频不卡| 日韩视频免费观看高清在线视频| 正在播放日韩| 欧美一区国产二区| 免费成人你懂的| 欧美视频导航| 国语自产精品视频在线看一大j8| 亚洲福利在线看| 亚洲色在线视频| 久久精品视频网| 亚洲色无码播放| 久久精品亚洲一区二区| 美日韩精品免费| 国产精品护士白丝一区av| 国内精品久久久久久影视8| 亚洲人成在线观看| 香蕉久久夜色| 一区二区三区精品视频| 欧美一区精品| 欧美区高清在线| 国产亚洲成av人在线观看导航| 亚洲国产日韩欧美在线99| 亚洲综合不卡| 亚洲精品少妇30p| 欧美一区视频在线| 欧美日韩精品二区第二页| 国产午夜精品一区理论片飘花| 亚洲欧洲一区二区三区| 欧美诱惑福利视频| 亚洲天堂久久| 欧美1区3d| 国产色爱av资源综合区| 日韩亚洲在线观看| 亚洲第一区色| 午夜免费在线观看精品视频| 欧美福利视频在线观看| 国产亚洲欧美一区在线观看| 一片黄亚洲嫩模| 亚洲精品免费一区二区三区| 欧美在线一级va免费观看| 欧美日韩一区二区三区在线看 | 欧美国产丝袜视频| 欧美mv日韩mv国产网站| 国产精品一区二区你懂的| 亚洲免费精彩视频| 亚洲国产另类久久久精品极度| 午夜精品一区二区三区在线视| 欧美母乳在线| 亚洲国产精品一区二区第四页av | 午夜国产精品视频免费体验区| av成人免费| 欧美va天堂va视频va在线| 国产亚洲精品久久久久久| 一区二区三区 在线观看视频| 亚洲三级电影在线观看| 久久欧美中文字幕| 国产欧美亚洲视频| 亚洲一区高清| 亚洲一区二区三区视频| 欧美激情在线免费观看| 在线成人国产| 亚洲国产精品va在看黑人| 久久激情五月激情| 国产欧美精品日韩精品| 亚洲无人区一区| 亚洲尤物在线| 国产精品久久久久久久7电影 | 国产精品人成在线观看免费 | 久久成人免费网| 欧美在线啊v| 国产精品一区二区女厕厕| 亚洲一区二区三区视频播放| 中文网丁香综合网| 欧美日韩在线视频首页| 日韩一级二级三级| 这里只有视频精品| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 在线免费观看日韩欧美| 亚洲国产精品va在线看黑人| 久久乐国产精品| 精品成人a区在线观看| 亚洲国产cao| 欧美成人69| 91久久精品国产91久久性色| 亚洲美女中出| 欧美精选一区| 99国产麻豆精品| 亚洲在线黄色| 国产精品无码专区在线观看 | 中文日韩在线| 亚洲国产欧美一区二区三区丁香婷| 久久亚洲图片| 在线精品视频免费观看| 亚洲精美视频| 欧美欧美全黄| 制服丝袜激情欧洲亚洲| 亚洲欧美一区二区精品久久久| 国产情侣一区| 亚洲国产1区| 欧美劲爆第一页| 在线一区二区三区四区| 欧美亚洲在线| 精品成人在线| 日韩午夜av在线| 国产精品高潮呻吟久久av无限| 亚洲欧美国产毛片在线| 久久久久久亚洲精品杨幂换脸 | 久久www成人_看片免费不卡| 蜜臀久久99精品久久久画质超高清| 亚洲激情女人| 亚洲欧美日韩成人| 国模套图日韩精品一区二区| 亚洲精品一区二区三区在线观看| 欧美日韩一区二| 亚洲女爱视频在线| 开元免费观看欧美电视剧网站| 亚洲区一区二| 欧美亚洲视频| 在线不卡a资源高清| 亚洲午夜精品| 国语自产精品视频在线看| 夜夜精品视频一区二区| 国产精品揄拍一区二区| 亚洲人成网站777色婷婷| 国产精品扒开腿做爽爽爽视频| 久久狠狠亚洲综合| 欧美日韩成人| 欧美亚洲专区| 欧美黄色成人网| 亚洲专区在线视频| 欧美激情亚洲视频| 午夜精品一区二区三区在线| 久久亚洲欧美国产精品乐播| 99日韩精品| 久久青青草原一区二区| 一本久久青青| 久久综合导航| 亚洲婷婷综合色高清在线| 欧美a一区二区| 午夜亚洲精品| 欧美理论大片| 久久精品亚洲精品国产欧美kt∨| 欧美日韩精品三区| 久久精品视频在线| 国产精品视频自拍| 亚洲美女免费视频| 国产一区二区三区最好精华液| 中文精品视频| 亚洲国产成人久久| 久久gogo国模啪啪人体图| 99re6热只有精品免费观看|