精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux中tty框架與uart框架之間的調用關系剖析

開發 架構
在這期間有一個問題困擾著我,那就是來自用戶空間的針對uart設備的操作意圖是如何通過tty框架逐層調用到uart層的core驅動,進而又是如何調用到真實對應于設備的設備驅動的,本文中的對應設備驅動就是8250驅動,最近我想將這方面的內容搞清楚。

之前本人在"從串口驅動的移植看linux2.6內核中的驅動模型 platform device & platform driver"一文中已經寫到了移植的設備是如何通過platform總線來與對應的驅動掛載。

在這期間有一個問題困擾著我,那就是來自用戶空間的針對uart設備的操作意圖是如何通過tty框架逐層調用到uart層的core驅動,進而又是如何調用到真實對應于設備的設備驅動的,本文中的對應設備驅動就是8250驅動,最近我想將這方面的內容搞清楚。

在說明這一方面問題之前我們先要大致了解兩個基本的框架結構,tty框架和uart框架。

首先看看tty框架:

在linux系統中,tty表示各種終端。終端通常都跟硬件相對應。比如對應于輸入設備鍵盤鼠標,輸出設備顯示器的控制終端和串口終端。

下面這張圖是一張很經典的圖了,很清楚的展現了tty框架的層次結構,大家先看圖,下面給大家解釋。

最上面的用戶空間會有很多對底層硬件(在本文中就是8250uart設備)的操作,像read,write等。用戶空間主要是通過設備文件同tty_core交互,tty_core根據用空間操作的類型再選擇跟line discipline和tty_driver也就是serial_core交互,例如設置硬件的ioctl指令就直接交給serial_core處理。Read和write操作就會交給line discipline處理。Line discipline是線路規程的意思。正如它的名字一樣,它表示的是這條終端”線程”的輸入與輸出規范設置,主要用來進行輸入/輸出數據的預處理。處理之后,就會將數據交給serial_core,最后serial_core會調用8250.c的操作。

下圖是同一樣一副經典的uart框架圖,將uart重要的結構封裝的很清楚,大家且看。

一個uart_driver通常會注冊一段設備號.即在用戶空間會看到uart_driver對應有多個設備節點。例如:

/dev/ttyS0  /dev/ttyS1 每個設備節點是對應一個具體硬件的,這樣就可做到對多個硬件設備的統一管理,而每個設備文件應該對應一個uart_port,也就是說:uart_device要和多個uart_port關系起來。并且每個uart_port對應一個circ_buf(用來接收數據),所以 uart_port必須要和這個緩存區關系起來。

#p#

1 自底向上

接下來我們就來看看對設備的操作是怎樣進行起來的,不過在此之前我們有必要從底層的uart驅動注冊時開始說起,這樣到后面才能更清晰。

這里我們討論的是8250驅動,在驅動起來的時候調用了uart_register_driver(&serial8250_reg);函數將參數serial8250_reg注冊進了tty層。具體代碼如下所示:

  1. int uart_register_driver(struct uart_driver *drv) 
  1. {  
  2.     struct tty_driver *normal = NULL;  
  3.     int i, retval;  
  4.  
  5.     BUG_ON(drv->state);  
  6.  
  7.     /*  
  8.      * Maybe we should be using a slab cache for this, especially if   
  9.      * we have a large number of ports to handle.  
  10.      */ 
  11.     drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);  
  12.     retval = -ENOMEM;  
  13.     if (!drv->state)  
  14.         goto out;  
  15.  
  16.     normal  = alloc_tty_driver(drv->nr);  
  17.     if (!normal)  
  18.         goto out;  
  19.  
  20.     drv->tty_driver = normal;  
  21.  
  22.     normal->owner       = drv->owner;  
  23.     normal->driver_name = drv->driver_name;  
  24.     normal->name        = drv->dev_name;  
  25.     normal->major       = drv->major;  
  26.     normal->minor_start = drv->minor;  
  27.     normal->type        = TTY_DRIVER_TYPE_SERIAL;  
  28.     normal->subtype     = SERIAL_TYPE_NORMAL;  
  29.     normal->init_termios    = tty_std_termios;  
  30.     normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;  
  31.     normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;  
  32.     normal->flags       = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;  
  33.     normal->driver_state    = drv;  // here is important for me, ref uart_open function in this file   
  34.     tty_set_operations(normal, &uart_ops);  
  35.  
  36.     /*  
  37.      * Initialise the UART state(s).   
  38.      */ 
  39.     for (i = 0; i < drv->nr; i++) {  
  40.         struct uart_state *state = drv->state + i;  
  41.  
  42.         state->close_delay     = 500;   /* .5 seconds */ 
  43.         state->closing_wait    = 30000/* 30 seconds */ 
  44.         mutex_init(&state->mutex);  
  45.  
  46.         tty_port_init(&state->info.port);  
  47.         init_waitqueue_head(&state->info.delta_msr_wait);  
  48.         tasklet_init(&state->info.tlet, uart_tasklet_action,  
  49.                  (unsigned long)state);  
  50.     }  
  51.  
  52.     retval = tty_register_driver(normal);  
  53.  out:  
  54.     if (retval < 0) {  
  55.         put_tty_driver(normal);  
  56.         kfree(drv->state);  
  57.     }  
  58.     return retval;  

從上面代碼可以看出,uart_driver中很多數據結構其實就是tty_driver中的,將數據轉換為tty_driver之后,注冊tty_driver。然后初始化uart_driver->state的存儲空間。
這里有兩個地方我們需要特別關注:

第一個是

  1. normal->driver_state    = drv;  

為什么說重要呢,因為真實這一句將參數的ops關系都賦給了serial_core層。也就是說在后面serial_core會根據uart_ops關系找到我們的8250.c中所對應的操作,而我們參數中的ops是在哪被賦值的呢?這個一定是會在8250.c中不會錯,所以我定位到了8250.c中的serial8250_ops結構體,初始化如下:

  1. static struct uart_ops serial8250_pops = {  
  2.     .tx_empty   = serial8250_tx_empty,  
  3.     .set_mctrl  = serial8250_set_mctrl,  
  4.     .get_mctrl  = serial8250_get_mctrl,  
  5.     .stop_tx    = serial8250_stop_tx,  
  6.     .start_tx   = serial8250_start_tx,  
  7.     .stop_rx    = serial8250_stop_rx,  
  8.     .enable_ms  = serial8250_enable_ms,  
  9.     .break_ctl  = serial8250_break_ctl,  
  10.     .startup    = serial8250_startup,  
  11.     .shutdown   = serial8250_shutdown,  
  12.     .set_termios    = serial8250_set_termios,  
  13.     .pm     = serial8250_pm,  
  14.     .type       = serial8250_type,  
  15.     .release_port   = serial8250_release_port,  
  16.     .request_port   = serial8250_request_port,  
  17.     .config_port    = serial8250_config_port,  
  18.     .verify_port    = serial8250_verify_port,  
  19. #ifdef CONFIG_CONSOLE_POLL  
  20.     .poll_get_char = serial8250_get_poll_char,  
  21.     .poll_put_char = serial8250_put_poll_char,  
  22. #endif  
  23. }; 

這樣一來只要將serial8250_ops結構體成員的值賦給我們uart_dirver就可以了,那么這個過程在哪呢?就是在uart_add_one_port()函數中,這個函數是從serial8250_init->serial8250_register_ports()->uart_add_one_port()逐步調用過來的,這一步就將port和uart_driver聯系起來了。

第二個需要關注的地方:

  1. tty_set_operations(normal, &uart_ops); 

此句之所以值得關注是因為.在這里將tty_driver的操作集統一設為了uart_ops.這樣就使得從用戶空間下來的操作可以找到正確的serial_core的操作函數,uart_ops是在serial_core.c中的:

  1. static const struct tty_operations uart_ops = {  
  2.     .open       = uart_open,  
  3.     .close      = uart_close,  
  4.     .write      = uart_write,  
  5.     .put_char   = uart_put_char,  
  6.     .flush_chars    = uart_flush_chars,  
  7.     .write_room = uart_write_room,  
  8.     .chars_in_buffer= uart_chars_in_buffer,  
  9.     .flush_buffer   = uart_flush_buffer,  
  10.     .ioctl      = uart_ioctl,  
  11.     .throttle   = uart_throttle,  
  12.     .unthrottle = uart_unthrottle,  
  13.     .send_xchar = uart_send_xchar,  
  14.     .set_termios    = uart_set_termios,  
  15.     .set_ldisc  = uart_set_ldisc,  
  16.     .stop       = uart_stop,  
  17.     .start      = uart_start,  
  18.     .hangup     = uart_hangup,  
  19.     .break_ctl  = uart_break_ctl,  
  20.     .wait_until_sent= uart_wait_until_sent,  
  21. #ifdef CONFIG_PROC_FS  
  22.     .read_proc  = uart_read_proc,  
  23. #endif  
  24.     .tiocmget   = uart_tiocmget,  
  25.     .tiocmset   = uart_tiocmset,  
  26. #ifdef CONFIG_CONSOLE_POLL  
  27.     .poll_init  = uart_poll_init,  
  28.     .poll_get_char  = uart_poll_get_char,  
  29.     .poll_put_char  = uart_poll_put_char,  
  30. #endif  
  31. }; 

這樣就保證了調用關系的通暢。

#p#

2 自頂向下

說完了從底層注冊時所需要注意的地方,現在我們來看看正常的從上到下的調用關系。tty_core是所有tty類型的驅動的頂層構架,向用戶應用層提供了統一的接口,應用層的read/write等調用首先會到達這里。此層由內核實現,代碼主要分布在drivers/char目錄下的n_tty.c,tty_io.c等文件中,下面的代碼:

  1. static const struct file_operations tty_fops = {  
  2.     .llseek        = no_llseek,  
  3.     .read        = tty_read,  
  4.     .write        = tty_write,  
  5.     .poll        = tty_poll,  
  6.     .unlocked_ioctl    = tty_ioctl,  
  7.     .compat_ioctl    = tty_compat_ioctl,  
  8.     .open        = tty_open,  
  9.     .release    = tty_release,  
  10.     .fasync        = tty_fasync,  
  11. }; 

就是定義了此層調用函數的結構體,在uart_register_driver()函數中我們調用了每個tty類型的驅動注冊時都會調用的tty_register_driver函數,代碼如下:

  1. int tty_register_driver(struct tty_driver * driver)  
  2. {  
  3.     ...  
  4.     cdev_init(&driver->cdev, &tty_fops);  
  5.     ...  

我們可以看到,此句就已經將指針調用關系賦給了cdev,以用于完成調用。在前面我們已經說過了,Read和write操作就會交給line discipline處理,我們在下面的代碼可以看出調用的就是線路規程的函數:

  1. static ssize_t tty_read(struct file *file, char __user *buf, size_t count,  
  2.             loff_t *ppos)  
  3. {  
  4.     ...  
  5.     ld = tty_ldisc_ref_wait(tty);  
  6.     if (ld->ops->read)  
  7.         i = (ld->ops->read)(tty, file, buf, count);  
  8.         //調用到了ldisc層(線路規程)的read函數  
  9.     else 
  10.         i = -EIO;  
  11.     tty_ldisc_deref(ld);  
  12.     ...  
  13. }  
  14. static ssize_t tty_write(struct file *file, const char __user *buf,  
  15.                         size_t count, loff_t *ppos)  
  16. {  
  17.     ...  
  18.     ld = tty_ldisc_ref_wait(tty);  
  19.     if (!ld->ops->write)  
  20.         ret = -EIO;  
  21.     else 
  22.         ret = do_tty_write(ld->ops->write, tty, file, buf, count);  
  23.     tty_ldisc_deref(ld);  
  24.     return ret;  
  25. }  
  26. static inline ssize_t do_tty_write(  
  27.     ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),  
  28.     struct tty_struct *tty,  
  29.     struct file *file,  
  30.     const char __user *buf,  
  31.     size_t count)  
  32. {  
  33.     ...  
  34.     for (;;) {  
  35.         size_t size = count;  
  36.         if (size > chunk)  
  37.             size = chunk;  
  38.         ret = -EFAULT;  
  39.         if (copy_from_user(tty->write_buf, buf, size))  
  40.             break;  
  41.         ret = write(tty, file, tty->write_buf, size);  
  42.         //調用到了ldisc層的write函數  
  43.         if (ret <= 0)  
  44.             break;  
  45.     ...  

那我們就去看看線路規程調用的是又是誰,代碼目錄在drivers/char/n_tty.c文件中,下面的代碼是線路規程中的write函數:

  1. static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,  
  2.                const unsigned char *buf, size_t nr)  
  3. {  
  4.     ...  
  5.     add_wait_queue(&tty->write_wait, &wait);//將當前進程放到等待隊列中  
  6.     while (1) {  
  7.         set_current_state(TASK_INTERRUPTIBLE);  
  8.         if (signal_pending(current)) {  
  9.             retval = -ERESTARTSYS;  
  10.             break;  
  11.         }  
  12.         //進入此處繼續執行的原因可能是被信號打斷,而不是條件得到了滿足。  
  13.         //只有條件得到了滿足,我們才會繼續,否則,直接返回!  
  14.         if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {  
  15.             retval = -EIO;  
  16.             break;  
  17.         }  
  18.         if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {  
  19.             while (nr > 0) {  
  20.                 ssize_t num = process_output_block(tty, b, nr);  
  21.                 if (num < 0) {  
  22.                     if (num == -EAGAIN)  
  23.                         break;  
  24.                     retval = num;  
  25.                     goto break_out;  
  26.                 }  
  27.                 b += num;  
  28.                 nr -= num;  
  29.                 if (nr == 0)  
  30.                     break;  
  31.                 c = *b;  
  32.                 if (process_output(c, tty) < 0)  
  33.                     break;  
  34.                 b++; nr--;  
  35.             }  
  36.             if (tty->ops->flush_chars)  
  37.                 tty->ops->flush_chars(tty);  
  38.         } else {  
  39.             while (nr > 0) {  
  40.                 c = tty->ops->write(tty, b, nr);  
  41.                 //調用到具體的驅動中的write函數  
  42.                 if (c < 0) {  
  43.                     retval = c;  
  44.                     goto break_out;  
  45.                 }  
  46.                 if (!c)  
  47.                     break;  
  48.                 b += c;  
  49.                 nr -= c;  
  50.             }  
  51.         }  
  52.         if (!nr)  
  53.             break;  
  54.         //全部寫入,返回  
  55.         if (file->f_flags & O_NONBLOCK) {  
  56.             retval = -EAGAIN;  
  57.             break;  
  58.         }  
  59.         /*   
  60.         假如是以非阻塞的方式打開的,那么也直接返回。否則,讓出cpu,等條件滿足以后再繼續執行。  
  61.         */          
  62.  
  63.         schedule();//執行到這里,當前進程才會真正讓出cpu!!!  
  64.     }  
  65. break_out:  
  66.     __set_current_state(TASK_RUNNING);  
  67.     remove_wait_queue(&tty->write_wait, &wait);  
  68.     ...  

在上面我們可以看到此句:

  1. c = tty->ops->write(tty, b, nr); 

此句很明顯告訴我們這是調用了serial_core的write()函數,可是這些調用關系指針是在哪賦值的,剛開始我也是郁悶了一段時間,不過好在我最后還是找到了一些蛛絲馬跡。其實就是在tty_core進行open的時候悄悄把tty->ops指針給賦值了。具體的代碼就在driver/char/tty_io.c中,調用關系如下所示:

tty_open -> tty_init_dev -> initialize_tty_struct,initialize_tty_struct()函數的代碼在下面:

  1. void initialize_tty_struct(struct tty_struct *tty,  
  2.         struct tty_driver *driver, int idx)  
  3. {  
  4.     ...  
  5.     tty->ops = driver->ops;  
  6.     ...  

可以看到啦,這里就將serial_core層的操作調用關系指針值付給了tty_core層,這樣tty->ops->write()其實調用到了具體的驅動的write函數,在這里就是我們前面說到的8250驅動中的write函數沒問題了。從這就可以看出其實在操作指針值得層層傳遞上open操作還是功不可沒的,這么講不僅僅是因為上面的賦值過程,還有下面這個,在open操作調用到serial_core層的時候有下面的代碼:

  1. static int uart_open(struct tty_struct *tty, struct file *filp)  
  2. {  
  3.     struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; // here just tell me why uart_open can call 8250  
  4.     struct uart_state *state;  
  5.     int retval, line = tty->index;  
  6.  
  7.     ……  
  8.  
  9.         uart_update_termios(state);  
  10.     }  
  11.  
  12.  fail:  
  13.     return retval;  

在此函數的第一句我們就看到了似曾相識的東西了,沒錯就是我們在uart_register_driver()的時候所做的一些事情,那時我們是放進去,現在是拿出來而已。

這樣一來,我們先從底層向上層分析上來后,又由頂層向底層分析下去,兩頭總算是接上頭了,我很高興,不是因為我花了近兩個小時的時間終于寫完了這篇博客,而是我是第一次通過這篇博客的寫作過程弄清楚了這個有點小復雜的環節,當然有謬誤的地方還是希望大家能慷慨指出。

分享知識,共同進步~

 

原文鏈接:http://blog.csdn.net/bonnshore/article/details/7996730

責任編輯:林師授 來源: bonnshore的博客
相關推薦

2021-02-05 12:04:45

LinuxUARTLinux系統

2009-06-22 16:34:30

框架架構設計模式

2011-08-08 09:51:52

Cocoa 框架

2019-08-23 11:58:07

Java框架架構

2009-12-29 14:55:31

ADO.NET Dat

2010-08-03 16:21:54

FlexFlash

2020-05-12 16:58:05

LinuxUnix技術

2011-02-15 14:30:24

PowerShell.NET框架

2013-04-23 09:31:12

Winform開發框架

2021-10-11 08:51:05

Linux console Linux 系統

2009-09-29 10:00:40

Spring AOP框

2009-08-21 17:16:19

.NET框架與COM

2010-02-05 15:33:29

Android JDK

2022-09-22 12:04:22

.NET開發框架

2009-12-07 18:43:29

WCF框架

2010-02-26 17:44:40

Python測試框架

2010-08-16 10:25:23

DIVSPAN

2018-09-08 08:20:05

LinuxUnixTTY

2012-05-31 14:54:59

Hadoop大數據

2010-02-23 10:50:11

Python 測試框架
點贊
收藏

51CTO技術棧公眾號

国产一区二区三区免费视频| 91视频精品在这里| 日韩黄色在线免费观看| 99久re热视频精品98| 国产不卡av在线播放| 9久re热视频在线精品| 夜夜嗨av一区二区三区四区| 黄色三级视频在线播放| 妞干网免费在线视频| 国产乱子伦视频一区二区三区| 久久久久亚洲精品| 久草福利在线观看| 秋霞国产精品| 婷婷亚洲久悠悠色悠在线播放| 日本精品二区| 亚洲AV午夜精品| 日韩精品乱码免费| 色中色综合影院手机版在线观看| 91精品视频国产| 国产777精品精品热热热一区二区| 国产高清精品网站| 国产精品99久久久久久白浆小说| 欧美做爰爽爽爽爽爽爽| 亚洲+小说+欧美+激情+另类 | 红桃av在线播放| 亚洲欧洲精品视频| 国产乱码精品一区二区三区忘忧草 | 欧美爱爱免费视频| 91国产一区| 亚洲精品国产a久久久久久 | 国产免费av高清在线| 国产精品一品二品| 国产69精品久久久久99| av2014天堂网| 国产一区二区精品调教| 国产精品美女久久久久久| 国产精品一区二区久久国产| 日韩欧美三级在线观看| 综合激情一区| 日韩在线播放一区| 激情av中文字幕| 欧洲亚洲精品久久久久| 一区二区三区在线免费视频| 亚洲7777| 成人欧美一区| 久久精品免费在线观看| 成人欧美在线视频| 国产九色91回来了| 国内综合精品午夜久久资源| 久久精品男人天堂| 男人天堂资源网| 欧洲激情视频| 亚洲国产精品va在线| 日韩av播放器| 羞羞视频在线观看不卡| 亚洲欧美一区二区久久| 精品免费一区二区三区蜜桃| 亚洲天堂视频在线| 免费视频最近日韩| 国产欧美中文字幕| 91精品国产综合久| 亚洲欧美成人| 欧美国产乱视频| 九九热只有精品| 亚洲国产影院| 日本在线观看天堂男亚洲| youjizz在线视频| 日韩国产在线观看| 清纯唯美亚洲综合| 欧美日韩人妻精品一区二区三区 | 无码 制服 丝袜 国产 另类| 性开放的欧美大片| 91在线你懂得| 97久久夜色精品国产九色 | 国产尤物一区二区在线| 51精品国产人成在线观看| 无码人妻一区二区三区线| 久久先锋影音| 成人精品久久一区二区三区| 国产99免费视频| 另类的小说在线视频另类成人小视频在线 | 另类专区亚洲| 欧美日韩国产在线播放网站| www激情五月| 国产福利资源一区| 国产亚洲欧美视频| 懂色av懂色av粉嫩av| 欧美日韩爆操| 国产精品久久久久av| 国产精品无码一区二区桃花视频| 成人成人成人在线视频| 日韩欧美在线一区二区| 欧美aaaaaaa| 色综合夜色一区| 加勒比av中文字幕| 成人久久网站| 精品久久久久久亚洲综合网| 精品少妇一区二区三区免费观| 欧美自拍一区| 日韩av有码在线| 亚洲不卡的av| 欧美成人自拍| 国内偷自视频区视频综合| 亚洲精品国产精品国自产网站按摩| 韩国v欧美v亚洲v日本v| 免费国产在线精品一区二区三区| 男人天堂久久久| 精品欧美一区二区三区| 久久久久久久久久久99| 午夜不卡一区| 日韩一区二区三区免费看| 真人bbbbbbbbb毛片| 五月激情综合| 欧美激情日韩图片| 日批视频免费观看| 九色综合国产一区二区三区| 九色91在线视频| 黄色在线网站| 亚洲午夜电影网| 亚洲无在线观看| 亚洲一区二区三区在线免费| 日韩久久免费视频| 色欲狠狠躁天天躁无码中文字幕 | 亚洲国产精品欧美久久 | 国产性70yerg老太| 亚洲人成久久| 91亚洲精品久久久| 国产小视频一区| 91丝袜国产在线播放| 日本精品二区| 超碰在线观看免费版| 欧美性生交片4| 给我看免费高清在线观看| 精品久久一区| 欧美精品在线免费观看| 亚洲激情视频一区| 国产精品一品视频| 中国老女人av| 亚洲国产精选| 日韩av一区二区在线| 一级特黄曰皮片视频| 久久久五月天| 国产一区深夜福利| av在线1区2区| 香蕉成人啪国产精品视频综合网 | 久久综合一区二区| 黄色国产一级视频| 精品精品国产三级a∨在线| 亚洲天堂网在线观看| 久久艹免费视频| 激情综合色播激情啊| 国产丝袜不卡| 国产在线xxx| 亚洲成人av在线| 日本系列第一页| 99re成人在线| 日韩video| 亚洲乱码一区| 午夜免费日韩视频| 亚洲aaa在线观看| 一本色道久久综合亚洲91| 超碰在线超碰在线| 欧美在线91| 国产日本一区二区三区| 国产精品原创| 国产亚洲欧洲在线| 在线免费看毛片| 亚洲精品日日夜夜| 成人欧美精品一区二区| 激情欧美丁香| 91麻豆桃色免费看| 欧洲成人综合网| 91精品国产综合久久久久久漫画 | 91最新在线免费观看| 性欧美高清come| 日韩av在线免费观看一区| 中文字幕另类日韩欧美亚洲嫩草| 国产成人精品一区二| 亚洲人精品午夜射精日韩| 97久久精品一区二区三区的观看方式| 超碰精品一区二区三区乱码| 亚洲国产一二三区| 色婷婷精品久久二区二区蜜臀av | 欧美日韩在线免费| 欧美一级片在线免费观看| 亚洲人成免费| 国产一区再线| 先锋成人av| 欧美一级免费大片| 毛片基地在线观看| 99精品欧美一区二区蜜桃免费| 国产极品美女高潮无套久久久| 成人系列视频| 国产欧美日韩91| 国产小视频免费在线网址| 欧美精品九九99久久| 五月天免费网站| 成人av在线播放网址| 中文字幕av专区| 亚洲毛片av| 久久久福利视频| 高清久久精品| 国产不卡视频在线| 青草在线视频| 日韩中文字幕亚洲| 国产精品主播一区二区| 欧美日韩黄色大片| 国产va在线播放| 国产视频一区二区在线观看| 亚洲av无码一区东京热久久| 欧美aaaaa成人免费观看视频| 亚洲欧美日本国产有色| 北条麻妃在线一区二区免费播放| 国语对白做受69| 黄色av网站在线播放| 亚洲无av在线中文字幕| 中文字幕一区二区三区四区免费看| 国产精品丝袜一区| www.日本高清| 三级精品在线观看| 在线观看精品视频| 亚洲1区在线| 国产玖玖精品视频| 免费欧美电影| 日本国产高清不卡| 日本视频在线播放| 欧美成人video| 99久久精品免费看国产交换| 欧美日韩一级片网站| 欧美成人黄色网| 91在线高清观看| 亚洲xxxx2d动漫1| 亚洲欧美bt| 国产午夜大地久久| 亚洲国产精品一区制服丝袜| 国产免费内射又粗又爽密桃视频| 免费成人蒂法| 国产欧美日韩一区| 国产精品成人国产| 久久久亚洲福利精品午夜| 免费动漫网站在线观看| 欧美狂野另类xxxxoooo| 久久精品国产亚洲av无码娇色 | 日本一级黄色大片| 久久久www免费人成精品| 中文字幕a在线观看| 丁香婷婷深情五月亚洲| 日本美女久久久| 丁香六月久久综合狠狠色| 欧美日韩在线中文| 先锋影音久久久| 欧美美女黄色网| 国产在线不卡| 国产原创popny丨九色| 91久久综合| 三级在线免费观看| 不卡视频在线| 久久66热这里只有精品| 精品视频在线一区| 99视频在线| 99视频有精品高清视频| 欧美中文在线免费| 欧美日韩不卡| 欧美在线一区二区三区四| 性感美女一区二区在线观看| 国产精品久久久久久久久久| 日韩三级成人| 成人综合av网| 欧美禁忌电影网| 国内精品二区| 欧美日韩精品一区二区视频| 手机成人av在线| 亚洲午夜伦理| 黄色高清无遮挡| 国产专区综合网| 欧美又黄又嫩大片a级| 国产91精品久久久久久久网曝门| 亚洲国产果冻传媒av在线观看| 岛国av在线一区| 蜜桃精品一区二区| 国产精品久久久久久久久久免费看 | 91视频福利网| 99久久免费视频.com| 日本午夜精品视频| 国产精品水嫩水嫩| 欧美日韩成人免费观看| 一区二区三区四区在线播放 | 黑人玩欧美人三根一起进| 日韩av电影中文字幕| 中文成人激情娱乐网| 国内一区在线| 亚洲激情久久| 欧美精品一区二区性色a+v| 精品福利av| 欧美婷婷精品激情| 蜜桃免费网站一区二区三区| 无套内谢丰满少妇中文字幕| 国产一区二区三区精品欧美日韩一区二区三区 | 欧美日韩不卡一区| 亚洲天堂视频网| 91精选在线观看| 麻豆国产在线播放| 夜夜躁日日躁狠狠久久88av| 国产蜜臀在线| 欧美亚洲一级片| 日本精品国产| 国产乱码精品一区二区三区日韩精品 | 国产成人精品一区二区三区视频| 国产福利精品在线| 99精品中文字幕在线不卡| 亚洲欧美日韩综合一区| 亚洲国产网站| 精品久久久久久久无码| 成人听书哪个软件好| 殴美一级黄色片| 日本乱人伦一区| 香蕉av一区二区三区| 欧美高清性猛交| 最新中文字幕在线播放| 91亚洲精品一区| 久久国产精品免费精品3p| 欧美一级免费在线观看| 日本在线不卡视频| 国产黄色网址在线观看| 亚洲午夜在线观看视频在线| 在线观看日本视频| 欧美裸体bbwbbwbbw| 亚洲xxx在线| 亚洲欧美成人网| 91www在线| 国产精品二区三区四区| 蜜桃国内精品久久久久软件9| 日韩黄色片在线| 国产一区二区三区在线观看精品| 水蜜桃av无码| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 国产精品69久久久| 国产精品影视在线观看| 天天看天天摸天天操| 欧美日韩人人澡狠狠躁视频| 中文无码精品一区二区三区| 亚洲视频777| 国产盗摄一区二区| 国产精品啪视频| 国产一区在线电影| 亚洲一区尤物| 青青草伊人久久| 在线观看天堂av| 日韩欧美高清在线视频| 日韩一二三四| 国产成人精品999| 成人自拍在线| 人妻少妇精品久久| 国产一区二三区好的| 中文字幕av网址| 欧美性淫爽ww久久久久无| 无码国产伦一区二区三区视频| 日韩在线不卡视频| 粉嫩一区二区三区| 国产91亚洲精品一区二区三区| 成人网18免费网站| 中文字幕乱码人妻综合二区三区 | 日本中文不卡| 免费成人在线网站| www.av欧美| 婷婷综合另类小说色区| www.我爱av| 性欧美视频videos6一9| 亚洲婷婷影院| 国产原创精品在线| 久久一区二区三区国产精品| 久久久久无码精品国产| 欧美电影在线免费观看| 香蕉久久aⅴ一区二区三区| 国产精品一区二区三区免费视频| 国产精品福利在线观看播放| 巨乳女教师的诱惑| 亚洲天堂成人网| 蜜桃在线一区二区| 国产成人精品av在线| 久久久久电影| 久久久久久久高清| 中文字幕精品三区| a天堂视频在线| 欧美有码在线视频| 97国产精品| 国产国语性生话播放| 午夜精品福利一区二区三区蜜桃| 麻豆av电影在线观看| 91精品国产高清久久久久久91裸体| 国产精品久久久久9999赢消| 五月天av在线播放| 国产精品麻豆网站| 欧洲成人一区二区三区| 国产精品99久久久久久久久久久久| 精品中文字幕一区二区三区av| 国产黄色一级网站| 亚洲欧美怡红院| 日韩精品视频无播放器在线看| 日本韩国欧美精品大片卡二|