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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Linux那些事儿 之 戏说USB(25)设备的生命线(八)

發(fā)布時間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux那些事儿 之 戏说USB(25)设备的生命线(八) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
回到struct usb_hcd,繼續(xù)努力的往下看。

7行,又見kref,usb主機控制器的引用計數(shù)。struct usb_hcd也有自己專用的引用計數(shù)函數(shù),看drivers/usb/core/hcd.c文件
static void hcd_release(struct kref *kref)
{struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);mutex_lock(&usb_port_peer_mutex);if (usb_hcd_is_primary_hcd(hcd))kfree(hcd->bandwidth_mutex);if (hcd->shared_hcd) {struct usb_hcd *peer = hcd->shared_hcd;peer->shared_hcd = NULL;if (peer->primary_hcd == hcd)peer->primary_hcd = NULL;}mutex_unlock(&usb_port_peer_mutex);kfree(hcd);
}struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd)
{if (hcd)kref_get (&hcd->kref);return hcd;
}
EXPORT_SYMBOL_GPL(usb_get_hcd);void usb_put_hcd (struct usb_hcd *hcd)
{if (hcd)kref_put (&hcd->kref, hcd_release);
}
EXPORT_SYMBOL_GPL(usb_put_hcd);

和struct urb的那幾個長的也忒像了,像的俺都不好意思多介紹它們了,如果不明白就回去看看聊struct urb的時候怎么說的吧。
9行,product_desc,主機控制器的產(chǎn)品描述字符串,對于UHCI,它為“UHCI Host Controller”,對于EHCI,它為“EHCI Host Controller”。
14行,irq_descr[24],這里邊兒保存的是“ehci-hcd:usb1”之類的字符串,也就是驅(qū)動的大名再加上總線編號。
18~20行,電源管理的,飄過。
25行,driver,每個男人心中都有一個狐貍精,每個女人心里都有一個洛麗塔,每個主機控制器驅(qū)動都有一個struct hc_driver結構體。看看它在hcd.h里的定義
struct hc_driver {const char	*description;	/* "ehci-hcd" etc */const char	*product_desc;	/* product/vendor string */size_t		hcd_priv_size;	/* size of private data *//* irq handler */irqreturn_t	(*irq) (struct usb_hcd *hcd);int	flags;
#define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
#define	HCD_LOCAL_MEM	0x0002		/* HC needs local memory */
#define	HCD_SHARED	0x0004		/* Two (or more) usb_hcds share HW */
#define	HCD_USB11	0x0010		/* USB 1.1 */
#define	HCD_USB2	0x0020		/* USB 2.0 */
#define	HCD_USB25	0x0030		/* Wireless USB 1.0 (USB 2.5)*/
#define	HCD_USB3	0x0040		/* USB 3.0 */
#define	HCD_MASK	0x0070
#define	HCD_BH		0x0100		/* URB complete in BH context *//* called to init HCD and root hub */int	(*reset) (struct usb_hcd *hcd);int	(*start) (struct usb_hcd *hcd);/* NOTE:  these suspend/resume calls relate to the HC as* a whole, not just the root hub; they're for PCI bus glue.*//* called after suspending the hub, before entering D3 etc */int	(*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);/* called after entering D0 (etc), before resuming the hub */int	(*pci_resume)(struct usb_hcd *hcd, bool hibernated);/* cleanly make HCD stop writing memory and doing I/O */void	(*stop) (struct usb_hcd *hcd);/* shutdown HCD */void	(*shutdown) (struct usb_hcd *hcd);/* return current frame number */int	(*get_frame_number) (struct usb_hcd *hcd);/* manage i/o requests, device state */int	(*urb_enqueue)(struct usb_hcd *hcd,struct urb *urb, gfp_t mem_flags);int	(*urb_dequeue)(struct usb_hcd *hcd,struct urb *urb, int status);/** (optional) these hooks allow an HCD to override the default DMA* mapping and unmapping routines.  In general, they shouldn't be* necessary unless the host controller has special DMA requirements,* such as alignment contraints.  If these are not specified, the* general usb_hcd_(un)?map_urb_for_dma functions will be used instead* (and it may be a good idea to call these functions in your HCD* implementation)*/int	(*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,gfp_t mem_flags);void    (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);/* hw synch, freeing endpoint resources that urb_dequeue can't */void	(*endpoint_disable)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);/* (optional) reset any endpoint state such as sequence numberand current window */void	(*endpoint_reset)(struct usb_hcd *hcd,struct usb_host_endpoint *ep);/* root hub support */int	(*hub_status_data) (struct usb_hcd *hcd, char *buf);int	(*hub_control) (struct usb_hcd *hcd,u16 typeReq, u16 wValue, u16 wIndex,char *buf, u16 wLength);int	(*bus_suspend)(struct usb_hcd *);int	(*bus_resume)(struct usb_hcd *);int	(*start_port_reset)(struct usb_hcd *, unsigned port_num);/* force handover of high-speed port to full-speed companion */void	(*relinquish_port)(struct usb_hcd *, int);/* has a port been handed over to a companion? */int	(*port_handed_over)(struct usb_hcd *, int);/* CLEAR_TT_BUFFER completion callback */void	(*clear_tt_buffer_complete)(struct usb_hcd *,struct usb_host_endpoint *);/* xHCI specific functions *//* Called by usb_alloc_dev to alloc HC device structures */int	(*alloc_dev)(struct usb_hcd *, struct usb_device *);/* Called by usb_disconnect to free HC device structures */void	(*free_dev)(struct usb_hcd *, struct usb_device *);/* Change a group of bulk endpoints to support multiple stream IDs */int	(*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, unsigned int num_eps,unsigned int num_streams, gfp_t mem_flags);/* Reverts a group of bulk endpoints back to not using stream IDs.* Can fail if we run out of memory.*/int	(*free_streams)(struct usb_hcd *hcd, struct usb_device *udev,struct usb_host_endpoint **eps, unsigned int num_eps,gfp_t mem_flags);/* Bandwidth computation functions *//* Note that add_endpoint() can only be called once per endpoint before* check_bandwidth() or reset_bandwidth() must be called.* drop_endpoint() can only be called once per endpoint also.* A call to xhci_drop_endpoint() followed by a call to* xhci_add_endpoint() will add the endpoint to the schedule with* possibly new parameters denoted by a different endpoint descriptor* in usb_host_endpoint.  A call to xhci_add_endpoint() followed by a* call to xhci_drop_endpoint() is not allowed.*//* Allocate endpoint resources and add them to a new schedule */int	(*add_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);/* Drop an endpoint from a new schedule */int	(*drop_endpoint)(struct usb_hcd *, struct usb_device *,struct usb_host_endpoint *);/* Check that a new hardware configuration, set using* endpoint_enable and endpoint_disable, does not exceed bus* bandwidth.  This must be called before any set configuration* or set interface requests are sent to the device.*/int	(*check_bandwidth)(struct usb_hcd *, struct usb_device *);/* Reset the device schedule to the last known good schedule,* which was set from a previous successful call to* check_bandwidth().  This reverts any add_endpoint() and* drop_endpoint() calls since that last successful call.* Used for when a check_bandwidth() call fails due to resource* or bandwidth constraints.*/void	(*reset_bandwidth)(struct usb_hcd *, struct usb_device *);/* Returns the hardware-chosen device address */int	(*address_device)(struct usb_hcd *, struct usb_device *udev);/* prepares the hardware to send commands to the device */int	(*enable_device)(struct usb_hcd *, struct usb_device *udev);/* Notifies the HCD after a hub descriptor is fetched.* Will block.*/int	(*update_hub_device)(struct usb_hcd *, struct usb_device *hdev,struct usb_tt *tt, gfp_t mem_flags);int	(*reset_device)(struct usb_hcd *, struct usb_device *);/* Notifies the HCD after a device is connected and its* address is set*/int	(*update_device)(struct usb_hcd *, struct usb_device *);int	(*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int);/* USB 3.0 Link Power Management *//* Returns the USB3 hub-encoded value for the U1/U2 timeout. */int	(*enable_usb3_lpm_timeout)(struct usb_hcd *,struct usb_device *, enum usb3_link_state state);/* The xHCI host controller can still fail the command to* disable the LPM timeouts, so this can return an error code.*/int	(*disable_usb3_lpm_timeout)(struct usb_hcd *,struct usb_device *, enum usb3_link_state state);int	(*find_raw_port_number)(struct usb_hcd *, int);
};
和usb_driver一樣,和pci_driver也一樣,所有的xxx_driver都有一堆函數(shù)指針,具體的主機控制器驅(qū)動就靠它們來活的,不多說了,太深入了,做人要懂得適可而止,這里只說下函數(shù)指針之外的東西,也就是開頭兒的那三個。description直白點說就是驅(qū)動的大名,比如對于UHCI,它是“uhci_hcd”,對于EHCI,它就是“ehci_hcd”。product_desc和struct usb_hcd里的那個是一個樣兒。hcd_priv_size還是有點兒意思的,前面喝那杯茶的時候提到過,每個主機控制器驅(qū)動都會有一個私有結構體,藏在struct usb_hcd最后的那個變長數(shù)組里,這個變也是相對的,在創(chuàng)建usb_hcd的時候也得知道它能變多長,不然誰知道要申請多少內(nèi)存啊,這個長度就hcd_priv_size。

38行,flags,屬于HCD的一些標志,可用值就在39~44行。它們什么意思?書到用時方恨少,flags到用時才可知。

16,17,57~64,這幾行都是專為root hub服務的。佛說,一花一世界,一葉一如來。一個host controller對應一個root hub,即使某些嵌入式系統(tǒng)里,硬件上host controller沒有集成root hub,軟件上也需要虛擬一個出來,也就是所謂的virtual root hub。它位置是特殊的,但需要提供的功能和其它hub是沒有什么差別的,僅僅是在和host controller的軟硬件接口上有一些特別的規(guī)定。root hub再怎么特別也始終是一個hub,是一個usb設備,也不能脫離usb這個大家庭,也要向組織注冊,也要有自己的設備生命線,既然這里遇到了,就說說它的這條線。

/*------------------------------------------root hub的生命線-------------------------------------------------

還是要先聲明一下,root hub的生命線只是咱們的主線里的一個岔路口,不會沿著它去仔細的走,只會盡量的使用快鏡頭去展示一下。如果有哪里不明白,等走完了那條主線,你再回過頭來看看,很多事情都是在我們驀然回首的時候才明白的。

基于root hub和host controller這種極為曖昧極為特殊的關系,UHCI、EHCI等主機控制器驅(qū)動程序在自己的初始化代碼里都有大量的篇幅大量的心思花在root hub上面。不管是UHCI,還是EHCI,一般來說都是PCI設備,是PCI設備都應該有個struct pci_driver結構體,都應該有一個屬于自己的probe。在這個probe里,也都會調(diào)用usb_create_hcd()來創(chuàng)建一個屬于自己的usb_hcd,也都會調(diào)用usb_add_hcd()將這個剛剛創(chuàng)建的usb_hcd注冊到usb組織里。于是root hub便披著皇帝的新裝,走著貓步登場了。這里只貼與root hub相關的一些主要代碼

drivers/usb/core/hcd.c

	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {dev_err(hcd->self.controller, "unable to allocate root hub\n");retval = -ENOMEM;goto err_allocate_root_hub;}mutex_lock(&usb_port_peer_mutex);hcd->self.root_hub = rhdev;mutex_unlock(&usb_port_peer_mutex);switch (hcd->speed) {case HCD_USB11:rhdev->speed = USB_SPEED_FULL;break;case HCD_USB2:rhdev->speed = USB_SPEED_HIGH;break;case HCD_USB25:rhdev->speed = USB_SPEED_WIRELESS;break;case HCD_USB3:rhdev->speed = USB_SPEED_SUPER;break;default:retval = -EINVAL;goto err_set_rh_speed;}

在usb_add_hcd函數(shù)里,首先會調(diào)用咱們已經(jīng)親密接觸過的usb_alloc_dev()來為root hub準備一個struct usb_device結構體,我唯一想再提一下的是這時root hub的設備類型被賦值為usb_device_type,所屬總線類型賦值為usb_bus_type。然后根據(jù)各個host controller的實際情況,設定它的速度。struct usb_device結構體準備妥當之后,就要賦給struct usb_bus的root_hub元素。這些都只不過是準備工作,重頭戲都在usb_add_hcd()最后調(diào)用的register_root_hub()里面。

register_root_hub()非常肯定的將root hub的設備號devnum設置為1,于是就少了選擇地址設置地址的過程,root hub直接跳躍式發(fā)展進入了Address狀態(tài),咱們耗費幾代人,期待數(shù)十年才能完成的壯舉,root hub輕而易舉的就實現(xiàn)了。當然,是個人都知道在Address狀態(tài)是好處多多便利多多的,不然房地產(chǎn)就支柱不起來了。起碼這時可以很方便的獲得root hub的設備描述符,可以調(diào)用usb_new_device將root hub送給無所不能的設備模型,去尋找它命中的驅(qū)動。

drivers/usb/core/hcd.c

	retval = usb_new_device (usb_dev);if (retval) {dev_err (parent_dev, "can't register root hub for %s, %d\n",dev_name(&usb_dev->dev), retval);} else {spin_lock_irq (&hcd_root_hub_lock);hcd->rh_registered = 1;spin_unlock_irq (&hcd_root_hub_lock);/* Did the HC die before the root hub was registered? */if (HCD_DEAD(hcd))usb_hc_died (hcd);	/* This time clean up */}
如果這些都一切順利的話,register_root_hub()在最后就會將struct usb_hcd的rh_registered設置為1,表示root hub已經(jīng)找到組織并加入到革命隊伍里了。

Linux設備模型根據(jù)root hub所屬的總線類型usb_bus_type將它添加到usb總線的那條有名的設備鏈表里,然后會輪詢usb總線的另外一條有名的驅(qū)動鏈表,針對每個找到的驅(qū)動去調(diào)用usb總線的match函數(shù),也就是咱們以前一再遇到以后不斷遇到的usb_device_match(),為root hub牽線搭橋?qū)ふ伊硪粋€匹配的半圓。要注意,root hub的設備類型是usb_device_type,所以在usb_device_match()里走的設備那條路,匹配成功的是那個對所有usb_device_type類型的設備都來者不拒的花心大蘿卜——usb世界里唯一的那個usb設備驅(qū)動(不是usb接口驅(qū)動)struct device_driver結構體對象usb_generic_driver。所以接下來要調(diào)用的就是usb_generic_driver的probe函數(shù)generic_probe(),去配置root hub,然后root hub就大步邁進了Configured狀態(tài)。因為root hub只有一個配置,所以generic_probe()配置root hub時并沒有多少選擇的煩惱,如果有所疑問,可以look下hcd.c的開頭就已經(jīng)設定好的root hub設備描述符
/* usb 2.0 root hub device descriptor */
static const u8 usb2_rh_dev_descriptor[18] = {0x12,       /*  __u8  bLength; */0x01,       /*  __u8  bDescriptorType; Device */0x00, 0x02, /*  __le16 bcdUSB; v2.0 */0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */0x00,	    /*  __u8  bDeviceSubClass; */0x00,       /*  __u8  bDeviceProtocol; [ usb 2.0 no TT ] */0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */0x02, 0x00, /*  __le16 idProduct; device 0x0002 */KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */0x03,       /*  __u8  iManufacturer; */0x02,       /*  __u8  iProduct; */0x01,       /*  __u8  iSerialNumber; */0x01        /*  __u8  bNumConfigurations; */
};
這張表是const的,也就是說在整個usb的世界里它都是只能去讀不能去修改的,要用嚴謹科學的態(tài)度去對待root hub。明眼人一眼就能看到躲在它最后的那個0x01,這就是root hub支持的配置數(shù)量。在它下邊兒還有針對usb 1.1的root hub設備描述符,大同小異就不貼了。

既然進入了Configured狀態(tài),就可以無拘無束的使用root hub提供的所有功能了,不過,對于咱們使用usb的勞苦大眾來說,實際在起作用的還是設備里的接口,所以generic_probe()接下來就會根據(jù)root hub使用的配置,為它所有的接口準備struct usb_interface結構體對象,這時接口所屬的總線類型仍然為usb_bus_type,設備類型就不一樣了,為usb_if_device_type,早先說過的那句總線有總線的類型,設備有設備的類型到這里就應該再加上一句,接口有接口的類型。usb_if_device_type在message.c里定義
struct device_type usb_if_device_type = {.name =		"usb_interface",.release =	usb_release_interface,.uevent =	usb_if_uevent,
};

為root hub的接口準備struct usb_interface結構體也沒費太大功夫,因為spec里規(guī)定了hub上除了端點0,就只有一個中斷的IN端點,并不用準備太多的東西。root hub的配置描述符也已經(jīng)在hcd.c的開頭兒指定好了,確實只有一個接口,一個設置,一個端點,去look一下

drivers/usb/core/hcd.c

/* Configuration descriptors for our root hubs */static const u8 fs_rh_config_descriptor[] = {/* one configuration */0x09,       /*  __u8  bLength; */0x02,       /*  __u8  bDescriptorType; Configuration */0x19, 0x00, /*  __le16 wTotalLength; */0x01,       /*  __u8  bNumInterfaces; (1) */0x01,       /*  __u8  bConfigurationValue; */0x00,       /*  __u8  iConfiguration; */0xc0,       /*  __u8  bmAttributes;Bit 7: must be set,6: Self-powered,5: Remote wakeup,4..0: resvd */0x00,       /*  __u8  MaxPower; *//* USB 1.1:* USB 2.0, single TT organization (mandatory):*	one interface, protocol 0** USB 2.0, multiple TT organization (optional):*	two interfaces, protocols 1 (like single TT)*	and 2 (multiple TT mode) ... config is*	sometimes settable*	NOT IMPLEMENTED*//* one interface */0x09,       /*  __u8  if_bLength; */0x04,       /*  __u8  if_bDescriptorType; Interface */0x00,       /*  __u8  if_bInterfaceNumber; */0x00,       /*  __u8  if_bAlternateSetting; */0x01,       /*  __u8  if_bNumEndpoints; */0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */0x00,       /*  __u8  if_bInterfaceSubClass; */0x00,       /*  __u8  if_bInterfaceProtocol; [usb1.1 or single tt] */0x00,       /*  __u8  if_iInterface; *//* one endpoint (status change endpoint) */0x07,       /*  __u8  ep_bLength; */0x05,       /*  __u8  ep_bDescriptorType; Endpoint */0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */0x03,       /*  __u8  ep_bmAttributes; Interrupt */0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */0xff        /*  __u8  ep_bInterval; (255ms -- usb 2.0 spec) */
};

9行的0x01,34行0x00,35行的0x01,分別指定了接口數(shù)量,使用的設置,端點的數(shù)目。也就是說,如果加上端點0,root hub只有兩個端點,而另外一個端點為IN端點,端點號為1,中斷類型,每次可以處理的最大字節(jié)數(shù)為2,期望host controller訪問自己的時間間隔為256ms。這里打個岔問個問題,為什么說這個中斷端點的wMaxPacketSize為2,46行不是明確寫著0x02,0x00么?呵呵,協(xié)議里說了,usb設備的各種描述符都是按照little-endian方式的字節(jié)序存儲的,先是低字節(jié)然后是高字節(jié)。

為root hub的那個獨苗兒接口準備好struct usb_interface結構體之后應該怎么做?佛又說了,一個接口一個驅(qū)動,接下來顯然是應該將它送給設備模型去尋找它命中注定的驅(qū)動了。然后此處省略2008字,又到了usb_device_match()。不過你說這個時候設備和接口兩條路它應該走哪條?它的類型已經(jīng)設置成usb_if_device_type了,設備那條路把門兒的根本就不會讓它進,所以它必須得去走接口那條路。

有關在接口這條路上它怎么去尋找另一半兒,咱現(xiàn)在不多說,日后在主線里說,現(xiàn)在只天馬行空的扯一下。首先回頭瞧下root hub的設備描述符,它的bDeviceClass 被指定為0x09,在include/linux/usb/ch9.h里,它對應的是USB_CLASS_HUB,再回頭看看root hub配置描述符的36行,bInterfaceClass也被指定成0x09,也就是說同樣為USB_CLASS_HUB。你再去hub驅(qū)動對應的hub.c文件里看看那里的hub_id_table,是不是應該明白點什么了?對頭,root hub里的那個接口所對應的驅(qū)動就是hub驅(qū)動,雖然它很特殊,可它也是個hub啊。root hub一邊和host controller相生相依,一邊和hub驅(qū)動眉來眼去花前月下,多么巨大的諷刺。

接下來要做的就是調(diào)用hub驅(qū)動里的hub_probe()。不管是root hub還是一般的hub,走到這一步都是必然的,不同的是對于root hub在host controller初始化的過程中就會去調(diào)用hub_probe()。再省略2008字后,hub_probe()通過hub_configure()創(chuàng)建并初始化了一個中斷的urb,然后在hub_activate()里調(diào)用usb_submit_urb()將它提交給core,接著就又回到了HCD。如果覺得省略了這么多讓你很不爽,那就再去看看《我是hub》吧。

每個hub都要需要進行中斷傳輸來獲得hub的狀態(tài)變化,不然hub驅(qū)動里那個著名的hub_events就活不下去了,你連在hub上的usb設備系統(tǒng)也就察覺不到了,你也就不能用usb攝像頭來泡mm了,都走到了21世紀了,都應該知道中斷傳輸不會提交一次就完事兒了,這么一次就完事兒hub不會滿意,每個男人女人都不會滿意。你需要在你的結束處理函數(shù)里提交再提交,host controller都不嫌煩,你煩什么啊。中斷傳輸都是有個間隔時間的,這個時間不由你決定,也不由我決定,咱們只能期待,決定權在host controller那里。host controller就決定了,對于root hub要每隔250ms去訪問一次,你再看上面root hub的描述符,里面顯示它期待的時間為0xff,也就是256ms,250與256也差不了多少,root hub也應該滿意了。這個固定的訪問頻率host controller是怎么實現(xiàn)的?就是通過struct usb_hcd里的那個定時器rh_timer,定時器就是專門干這種事兒的,root hub每提交一次urb,在HCD里都會對它初始化一次,指定250ms之后去獲得root hub的狀態(tài),然后就讓urb返回給root hub,于是root hub再提交,再250ms后返回,……。

但是這種對root hub的輪詢機制是早先版本里的,現(xiàn)在就不一樣了。struct usb_hcd里出現(xiàn)了uses_new_polling,看名字就知道是一種新機制出現(xiàn)了。這也是Alan Stern在2005年的陽春三月春心萌動孕育出來的,舊機制主要靠輪詢,新機制主要靠中斷。在新的機制里,root hub仍然是要提交一個中斷urb的,不同的是這時它可以不用再請定時器來幫忙,在有設備插入時,host controller會在自己的中斷處理函數(shù)里調(diào)用一個名叫usb_hcd_poll_rh_status的函數(shù)去獲得root hub的狀態(tài)并將urb的所有權歸還給hub驅(qū)動。

那是不是就可以不需要定時器rh_timer了?事情沒這么簡單,也不能就這么過河拆橋,由于某些不可言狀的原因,原來的機制還必須得保留著,給不同的host controller選擇使用。為了讓新舊機制和諧的運作,usb_hcd_poll_rh_status多了一個職務,就是作為rh_timer的定時器函數(shù),而且struct usb_hcd里除了uses_new_polling之外就又多了poll_rh等幾個元素。如果uses_new_polling沒有被設置,則一定會采用舊的輪詢機制,如果uses_new_polling已經(jīng)被設置了,但同時又設置了poll_rh,也是要采用舊機制,否則采用的就是新機制。至于status_urb,其實就是root hub提交的那個urb。

root hub的生命線就還是說到這里吧,適可而止適可而止。
-------------------------------------------------------------------------------------------------------------*/

回到struct usb_hcd,看92行,wireless,是不是無線usb。

72~75這幾行都是與主機控制器的娘家PCI有關的,說到PCI就不得不說到那張著名的表。PCI spec說了,要想在我這兒混,誰都必須不能少了那張表。

不過強制的也不一定都是壞事兒,起碼這張表不是,中斷號啊等很多有用的東西都在里面準備好了。72行的irq就躲在上面表兒里的倒數(shù)第四個byte,HCD可以直接拿來用,根本就不用再去申請,一提到申請個什么,誰都知道那是多么一個艱辛的過程。接下來的regs,rsrc_start,rsrc_len就與中間的那幾個Base Address0~5脫不開關系了,牽涉到所謂的I/O內(nèi)存和I/O端口,簡單說一下。

大家都知道CPU牛X,是眾人矚目的焦點,但是它再牛也不可能一個人戰(zhàn)斗,電腦運轉是個集體項目,有很多千奇百怪的外設。CPU也需要跟各種外設配合交流,它需要訪問外設里的那些寄存器或者內(nèi)存。現(xiàn)在差別就出來了,主要是空間的差別,一些CPU芯片有兩個空間,即I/O空間和內(nèi)存空間,提供有專門訪問外設I/O端口的指令,而另外一些只有一個空間,即內(nèi)存空間。外設的I/O端口可以映射在I/O空間也可以映射到內(nèi)存空間,CPU通過訪問這兩個空間來訪問外設,I/O空間有I/O空間訪問的接口,內(nèi)存空間有內(nèi)存空間訪問的接口。當然某些外設不但有寄存器,還有內(nèi)存,也就是I/O內(nèi)存,比如EHCI/OHCI,它們需要映射到內(nèi)存空間。但是不管映射到哪個空間,訪問I/O端口還是I/O內(nèi)存,CPU必須知道它們映射后的地址,不然沒有辦法配合交流。

上面表里中間的那些Base Address保存的就是PCI設備里I/O內(nèi)存或I/O端口的首尾位置還有長度,驅(qū)動里使用時要首先把它們給讀出來,如果要映射到I/O空間,則要根據(jù)讀到的值向系統(tǒng)申請I/O端口資源,如果要映射到內(nèi)存空間,除了要申請內(nèi)存資源,還要使用ioremap等進行映射。

74行的rsrc_start和75行的rsrc_len保存的就是從表里讀出來的host controller的I/O端口或內(nèi)存的首地址和長度,73行的regs保存的是調(diào)用ioremap_nocache映射后的內(nèi)存地址。

76行,power_budget,能夠提供的電流。

98行,*pool [HCD_BUFFER_POOLS],幾個dma池。因為HCD_BUFFER_POOLS在97行定義為4,所以這里就表示每個主機控制器可以有4個dma池。

我們知道主機控制器是可以進行DMA傳輸?shù)?#xff0c;鏡頭再回到前面的struct urb,那里有兩個成員transfer_dma和setup_dma,當時只是說你可以使用usb_buffer_alloc分配好dma緩沖區(qū)給它們,然后再告訴HCD你的urb已經(jīng)有了,HCD就可以不用再進行復雜的DMA映射了,并沒有提到你這個獲取的dma緩沖區(qū)是從哪里來的。俺都暗示到這種地步了,你用屁股也能猜出來是從這里所說的dma池子里來的了。

混了這么久,俺對池子還是有比較美好的回憶的,還親手搭建過線程池、數(shù)據(jù)庫連接池等等池子,像線程啊數(shù)據(jù)庫連接啊什么的創(chuàng)建銷毀的時候不是比較的耗資源么,就先建個池子預先創(chuàng)建好一批線程什么的放里邊兒,用的時候就從里面取出來,不用的時候就再放里面,用的越多就越劃的來,號稱將負擔均分了。所以說,池子是多么的重要啊。

當然,dma池沒這么幼稚,它還有其它的內(nèi)涵。一般來說DMA映射獲得的都是以頁為單位的內(nèi)存,urb需要不了這么大,如果需要比較小的DMA緩沖區(qū),就離不開DMA池了。還是看看主機控制器的這幾個池子是怎么創(chuàng)建的,在drivers/usb/core/buffer.c 文件里
int hcd_buffer_create(struct usb_hcd *hcd)
{char		name[16];int		i, size;if (!hcd->self.controller->dma_mask &&!(hcd->driver->flags & HCD_LOCAL_MEM))return 0;for (i = 0; i < HCD_BUFFER_POOLS; i++) {size = pool_max[i];if (!size)continue;snprintf(name, sizeof name, "buffer-%d", size);hcd->pool[i] = dma_pool_create(name, hcd->self.controller,size, size, 0);if (!hcd->pool[i]) {hcd_buffer_destroy(hcd);return -ENOMEM;}}return 0;
}
這里首先要判斷下這個主機控制器支持不支持DMA,如果不支持的話再創(chuàng)建什么DMA池就是純粹無稽之談了。如果支持DMA,就逐個適用dma_pool_alloc來創(chuàng)建DMA池,如果創(chuàng)建失敗了,就調(diào)用同一個文件里的hcd_buffer_destroy來將已經(jīng)創(chuàng)建成功的池子給銷毀掉。
void hcd_buffer_destroy(struct usb_hcd *hcd)
{int i;for (i = 0; i < HCD_BUFFER_POOLS; i++) {struct dma_pool *pool = hcd->pool[i];if (pool) {dma_pool_destroy(pool);hcd->pool[i] = NULL;}}
}
這里調(diào)用的dma_pool_destroy和上面的dma_pool_alloc也是相映成趣,都是DMA池子領域的小白領。帶翅膀的丘比特說了,每個人的人生都要找到四個人,第一個是自己,第二個是你最愛的人,第三個是最愛你的人,第四個是共度一生的人。他還說了,每個DMA池子都要找到四個函數(shù),一個用來創(chuàng)建,一個用來銷毀,一個用來取內(nèi)存,一個用來放內(nèi)存。上邊兒只遇到了創(chuàng)建和銷毀的,還少兩個取和放的,再去同一個文件里找找
void *hcd_buffer_alloc(struct usb_bus		*bus,size_t			size,gfp_t			mem_flags,dma_addr_t		*dma
)
{struct usb_hcd		*hcd = bus_to_hcd(bus);int			i;/* some USB hosts just use PIO */if (!bus->controller->dma_mask &&!(hcd->driver->flags & HCD_LOCAL_MEM)) {*dma = ~(dma_addr_t) 0;return kmalloc(size, mem_flags);}for (i = 0; i < HCD_BUFFER_POOLS; i++) {if (size <= pool_max[i])return dma_pool_alloc(hcd->pool[i], mem_flags, dma);}return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
}void hcd_buffer_free(struct usb_bus		*bus,size_t			size,void			*addr,dma_addr_t		dma
)
{struct usb_hcd		*hcd = bus_to_hcd(bus);int			i;if (!addr)return;if (!bus->controller->dma_mask &&!(hcd->driver->flags & HCD_LOCAL_MEM)) {kfree(addr);return;}for (i = 0; i < HCD_BUFFER_POOLS; i++) {if (size <= pool_max[i]) {dma_pool_free(hcd->pool[i], addr, dma);return;}}dma_free_coherent(hcd->self.controller, size, addr, dma);
}
又可以找到兩個dma_pool_alloc和dma_pool_free,現(xiàn)在可以湊齊四個了。不過咱們不用管它們四個到底什么長相,只要它們能夠干活兒就成了,這里要注意的是幾個問題。第一個是即使你的主機控制器不支持DMA,這幾個函數(shù)也是可以用的,只不過創(chuàng)建的不是DMA池子,取的也不是DMA緩沖區(qū),此時,DMA池子不存在,hcd_buffer_alloc獲取的只是適用kmalloc申請的普通內(nèi)存,當然相應的,你必須在它沒有利用價值的時候使用hcd_buffer_free將它釋放掉。

第二個問題是size的問題,也是每個男人女人的問題。看到它們里面都有個pool_max吧,這是個同一個文件里定義的數(shù)組
static const size_t	pool_max[HCD_BUFFER_POOLS] = {/* platforms without dma-friendly caches might need to* prevent cacheline sharing...*/32,128,512,PAGE_SIZE / 2/* bigger --> allocate pages */
};
這個數(shù)組里定義的就是四個池子中每個池子里保存的DMA緩沖區(qū)的size。注意這里雖說只定義了四種size,但是并不說明你使用hcd_buffer_alloc獲取DMA緩沖區(qū)的時候不能指定更大的size,如果誰誰太貪心了,欲望太強烈了,這幾個池子都滿足不了她的要求,那就會使用dma_alloc_coherent為她建立一個新的DMA映射。還有,每個人的情況都不一樣,不可能都會完全恰好和上面定義的四種size一致,那也不用怕,這不是病,使用這個size獲取DMA緩沖區(qū)的時候,池子會選擇一個略大一些的回饋過去。

還是讓咱們拋開size,回到struct usb_hcd中來,100行,state,主機控制器的狀態(tài),緊挨著它的下面那些行就是相關的可用值和宏定義。咱們自己的狀態(tài)還都稀里糊涂的,就先不說它們了。

123行,如果不是有短暫失憶癥或選擇性失憶癥的話,是會知道這是什么意思用來干嗎的。

總結

以上是生活随笔為你收集整理的Linux那些事儿 之 戏说USB(25)设备的生命线(八)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

日韩av视屏在线观看 | 日韩av在线高清 | 欧美激情视频在线观看免费 | 欧美精品久久久久久久免费 | 狠狠狠狠狠干 | 国产精品电影在线 | 日韩精品一区二区三区水蜜桃 | 99在线视频免费观看 | 亚洲一区美女视频在线观看免费 | 国产99久久久欧美黑人 | 国产 日韩 欧美 中文 在线播放 | 久久五月天色综合 | 色婷婷综合久久久中文字幕 | 亚洲成人av在线 | 高清在线观看av | 久久午夜免费视频 | 亚洲成人动漫在线观看 | 日韩一二三区不卡 | 最新日韩视频在线观看 | 国产一区自拍视频 | 欧美电影在线观看 | 久久久久综合网 | 在线97| 91视频在线看 | 日韩影视在线 | 国产色视频一区 | 日日碰夜夜爽 | 久久99精品国产99久久6尤 | 午夜久久久久 | 91最新网址在线观看 | 天天操天天操天天爽 | ww亚洲ww亚在线观看 | 亚洲经典中文字幕 | 色wwww| 欧美一区免费在线观看 | 97精品国自产拍在线观看 | 欧美国产一区二区 | 国产又粗又猛又黄又爽的视频 | 中文字幕一区二区三区四区久久 | 中文字幕国产一区 | 色九九影院| 在线观看日本高清mv视频 | 天天色综合久久 | 亚洲国产欧美在线人成大黄瓜 | 中国美女一级看片 | 日本精品视频在线观看 | av电影一区二区三区 | www.色就是色 | 久久久亚洲麻豆日韩精品一区三区 | 久久久这里有精品 | 97在线精品视频 | 久草视频免费观 | 欧美另类亚洲 | 2021国产在线 | 天天操天天操天天干 | 在线高清av | 久久久免费 | 天天射综合网站 | 欧美另类z0zx | 久久尤物电影视频在线观看 | 日韩欧美在线观看一区二区三区 | 有码视频在线观看 | 亚洲精品视频免费在线 | 一级片免费观看 | 日韩欧美极品 | 久久久久久久久久久电影 | 欧美一二三视频 | 天天看天天干天天操 | www.99久久.com | 毛片一区二区 | 夜夜嗨av色一区二区不卡 | 日韩视频在线一区 | 伊人久久在线观看 | 国产区精品区 | 国产人成在线视频 | 欧美人zozo| 欧美日韩在线视频一区二区 | 欧美色综合久久 | 91超在线| 久草在线免费色站 | 精品久久久久久亚洲综合网站 | 亚洲高清视频一区二区三区 | 蜜臀久久99精品久久久酒店新书 | 久久精品国产亚洲精品2020 | 婷婷香蕉 | 天天性天天草 | 中文字幕国产视频 | 亚洲自拍偷拍色图 | 亚洲视频电影在线 | 国产精品毛片一区视频播不卡 | av官网 | 东方av免费在线观看 | 在线播放日韩av | 久久综合色婷婷 | 久久精品2| 在线国产99 | 在线岛国av | 成人黄色毛片 | 日韩国产精品久久久久久亚洲 | 久久久国产精品麻豆 | 国产精品视频内 | 国产小视频在线免费观看 | av免费线看 | 在线免费日韩 | av在线影视| 国产淫片 | 日本中文字幕免费观看 | 91九色视频国产 | 91丝袜美腿 | 久久综合久色欧美综合狠狠 | 久久另类小说 | 日日日爽爽爽 | 精品成人a区在线观看 | 精品视频123区在线观看 | 久久久久久久久久久精 | 成人影片免费 | 亚洲日本中文字幕在线观看 | 亚洲伦理一区 | 色综合色综合色综合 | 国产69精品久久99的直播节目 | 毛片一区二区 | 在线播放你懂 | 国产一级视频 | 国产精品久久久久久久久久久久午夜片 | 四虎在线免费观看 | 国产一区二区高清视频 | 一区二区视频电影在线观看 | 91尤物国产尤物福利在线播放 | 亚洲一区免费在线 | 中文字幕亚洲字幕 | 日日操夜夜操狠狠操 | 国产一区二区免费在线观看 | 精品视频123区在线观看 | 在线高清 | 久久精品麻豆 | 亚洲欧美日韩国产 | 在线免费试看 | 亚洲成av人片一区二区梦乃 | 免费视频三区 | 国产中年夫妇高潮精品视频 | 欧美一区二区三区特黄 | 日韩av片免费在线观看 | 中文字幕亚洲综合久久五月天色无吗'' | 人人精品 | 伊人色**天天综合婷婷 | 亚洲免费av在线 | 一区二区三区在线观看中文字幕 | 欧美日本啪啪无遮挡网站 | 亚洲国产伊人 | 99久久一区| 91看成人 | 国产午夜精品福利视频 | 欧美一区二区精品在线 | 国产精品毛片一区视频播 | 五月激情丁香婷婷 | 久久a级片| 91色吧 | 91在线精品播放 | 免费福利在线 | 久草视频在线观 | 91av大全| 91久久在线观看 | 日韩精品免费在线播放 | 国产在线欧美在线 | 久久久久久久久久免费视频 | 美女视频黄,久久 | av片在线观看免费 | 免费看一级黄色 | 爱射综合| 久久亚洲精品电影 | 超碰97免费在线 | 最新av网址大全 | 国产精品久久久久久麻豆一区 | 国产一区在线看 | 粉嫩aⅴ一区二区三区 | 在线亚洲激情 | 国产aaa免费视频 | 九色精品在线 | 日韩美女黄色片 | 精品国产一区二区三区噜噜噜 | 欧美精品久久久久性色 | 国产码电影| 欧美91成人网 | 国产免费av一区二区三区 | 伊人五月婷 | 狠狠干夜夜 | 久久高清毛片 | 日韩欧美精品在线观看 | 成人一级在线观看 | 国产精品免费观看久久 | 日本性高潮视频 | 成人黄色电影视频 | www.夜夜| 国产精品免费久久久久影院仙踪林 | 成人国产精品 | 天天色欧美 | 丁香六月婷婷激情 | 久久精品国产亚洲精品 | 亚洲综合色婷婷 | 最新亚洲视频 | 91在线观看视频 | 欧美日韩国产综合一区二区 | 国产一区国产二区在线观看 | 国产精品一区二区三区视频免费 | 国产91av视频在线观看 | 国产亚州精品视频 | 久久精品第一页 | 国产色婷婷在线 | 夜夜操狠狠操 | 99精品国产免费久久久久久下载 | 99精品视频在线观看视频 | 精品国产亚洲一区二区麻豆 | 精品久久久久久国产91 | 天天干天天操天天操 | 日韩在线观看不卡 | 成 人 黄 色 视频 免费观看 | 激情欧美网 | av在线a| 国产一区福利在线 | 六月激情久久 | 国产成人不卡 | 久久人人爽人人 | 国产一二区在线观看 | 色av色av色av | 久久久精品 一区二区三区 国产99视频在线观看 | 亚洲永久在线 | 奇米影视777影音先锋 | 玖玖在线看 | 波多野结衣一区三区 | 久久成年人视频 | 97精品国产97久久久久久久久久久久 | 欧美激情在线网站 | 99热这里是精品 | 中文字幕在线视频国产 | 欧美a级一区二区 | 久久久私人影院 | www.久久久| 亚洲国产资源 | 中文字幕在线观看不卡 | 日韩在线观看你懂的 | 99精品国产99久久久久久97 | 久久国产综合视频 | 成人午夜网址 | 手机在线看a | 亚洲精品国产精品国自产 | 色婷婷a | 久久婷婷五月综合色丁香 | 欧美日韩aaaa| 91成人免费视频 | 免费观看国产精品 | 天天做天天爽 | 免费av网址在线观看 | 天天草天天操 | 国产黄在线播放 | 亚洲最新av| 不卡视频在线 | 国产成人在线免费观看 | 美女视频黄免费的久久 | 又大又硬又黄又爽视频在线观看 | 综合影视 | 色婷婷成人网 | 在线观看av免费 | 国产性天天综合网 | 在线视频一区观看 | 97国产超碰 | 色五月激情五月 | 日韩城人在线 | 99在线热播精品免费99热 | 久久久久五月 | 免费观看成人 | 免费网站看v片在线a | 久久久九色精品国产一区二区三区 | 五月开心六月婷婷 | 国产一级大片免费看 | 91中文字幕在线视频 | 免费视频一区 | 超碰在线人 | 五月天国产精品 | 懂色av一区二区三区蜜臀 | 欧美国产日韩在线观看 | 黄色的网站在线 | 欧美男女爱爱视频 | 午夜影视剧场 | 国产精品99久久久久久宅男 | 欧美日韩国产网站 | 波多野结衣电影一区 | 综合精品在线 | 国产精品视频资源 | 色在线免费视频 | 亚洲精品视频在线观看网站 | 97天天干 | 日韩欧美视频在线观看免费 | 亚洲国内精品在线 | 国产精品一区电影 | 亚洲 欧美 成人 | 国产经典 欧美精品 | 97视频一区 | 手机av观看| 国产精品乱码久久久 | 国产字幕av| 黄色片网站 | 欧美大片aaa | 色99网| 涩涩伊人 | 四虎最新域名 | 久久再线视频 | 亚洲高清网站 | 亚洲天堂网视频 | 日日夜夜精品网站 | 日韩精品一区二区三区第95 | av在线看片 | 久久国产精品久久久 | 国产精品美女www爽爽爽视频 | 国产.精品.日韩.另类.中文.在线.播放 | 欧美狠狠操 | 欧美亚洲成人xxx | 狠狠狠狠狠狠狠狠干 | 中文字幕日韩有码 | 国内精品视频在线 | 亚洲电影第一页av | 天天色中文 | 国产精品久久久久久久7电影 | 91成人精品国产刺激国语对白 | 在线免费观看麻豆视频 | 国产网红在线观看 | 久久综合久久88 | 美女视频黄免费 | 色婷婷狠狠五月综合天色拍 | 91精品国产成人www | 精品国产一区二 | 激情欧美一区二区三区免费看 | 国产不卡在线视频 | a视频在线观看免费 | 国产成人99av超碰超爽 | 日韩中文字幕在线看 | 国产精品自产拍在线观看桃花 | 日韩欧美视频在线免费观看 | 亚洲精品在线二区 | 天天干夜夜干 | 色香蕉网| 六月色婷婷 | 999久久 | 成人黄色免费在线观看 | 亚洲国产小视频在线观看 | 九九久久免费 | 天天天综合 | 成人精品999 | 国产精品h在线观看 | 三级小视频在线观看 | 久久视频99 | 欧美综合在线观看 | 狠狠干夜夜 | 亚洲精品男人天堂 | 久久精品二区 | 精品国产亚洲在线 | 国产综合婷婷 | zzijzzij亚洲日本少妇熟睡 | 亚洲国产精品久久久 | 国产精品伦一区二区三区视频 | 免费高清男女打扑克视频 | 中文字幕在线观看不卡 | 色婷婷99| 国产精久久久久久久 | 欧美成年性 | 国产精品福利无圣光在线一区 | 99色在线观看视频 | 欧美另类成人 | 日韩免费一级a毛片在线播放一级 | 免费视频色 | 97人人澡人人添人人爽超碰 | 极品嫩模被强到高潮呻吟91 | 韩国一区二区三区在线观看 | 精品久久一区二区三区 | 国际精品久久久久 | 国产亚洲情侣一区二区无 | 人人射人人爱 | 精品国产一区二区三区日日嗨 | 伊人久久婷婷 | 日日夜夜精品网站 | 黄色一级大片在线免费看国产一 | 天天操天天射天天添 | 精品久久久久久亚洲综合网 | 五月天六月婷 | 欧美日韩免费观看一区二区三区 | 欧美精选一区二区三区 | 最近免费在线观看 | 九九热只有精品 | 成人观看 | 91精品婷婷国产综合久久蝌蚪 | 国产成人av一区二区三区在线观看 | 亚州黄色一级 | 人人爱天天操 | 国产黄网站在线观看 | 日本中文在线观看 | 91在线中字 | 在线观看亚洲精品视频 | 免费日韩一区二区三区 | 国产最新在线观看 | 婷婷激情网站 | 欧洲亚洲国产视频 | 欧美成人在线网站 | 久久久伊人网 | 黄污网站在线 | 久久国产精品精品国产色婷婷 | 欧美日韩精品在线视频 | 2023天天干 | 尤物九九久久国产精品的分类 | 就要色综合 | 91精品免费视频 | 99综合视频 | 天天干天天碰 | 91chinesexxx| 亚洲国产成人精品久久 | 日本久久综合视频 | 天天色影院 | 国内久久精品 | 日韩 在线a | av一级片 | 国产做aⅴ在线视频播放 | 婷婷中文字幕 | 欧美亚洲一级片 | 国产精品日韩 | 久久噜噜少妇网站 | 激情五月婷婷激情 | 91久久人澡人人添人人爽欧美 | 最新的av网站 | 999视频网| 国产色婷婷精品综合在线手机播放 | 狠狠干五月天 | 91成人在线观看高潮 | 在线你懂 | 久久一视频 | 开心婷婷色 | 天天射天天干天天插 | 最近中文字幕完整高清 | 亚洲成人av片在线观看 | 国内三级在线观看 | 丁香婷婷色综合亚洲电影 | 亚洲精品美女在线观看播放 | 超碰成人av | 亚洲五月婷婷 | 色噜噜噜 | 欧美网址在线观看 | 天堂久色| 91精品婷婷国产综合久久蝌蚪 | 日韩欧美在线影院 | 久久综合加勒比 | www.天天成人国产电影 | 久久久国产精品视频 | 久久久穴 | 黄色一级在线免费观看 | 毛片永久新网址首页 | 日韩网页 | 日b视频在线观看网址 | 免费视频一级片 | 亚洲精品久久久久久中文传媒 | 天堂av在线免费观看 | 亚洲精品一区中文字幕乱码 | 国产午夜三级 | 人人舔人人干 | 一区二区三区四区五区六区 | 久久99精品国产麻豆宅宅 | 国产午夜激情视频 | 久久免费观看少妇a级毛片 久久久久成人免费 | 在线观看91| 国产在线成人 | 亚洲精品 在线视频 | 99久久精品免费看 | 午夜精品一区二区三区免费 | 97色婷婷| 天堂av色婷婷一区二区三区 | 精品女同一区二区三区在线观看 | 久久久久久久久久影视 | 欧美一级激情 | 亚洲欧美视频 | 丁香影院在线 | 亚洲免费视频在线观看 | 男女激情麻豆 | 偷拍福利视频一区二区三区 | 狠狠干中文字幕 | 在线成人高清电影 | 狠狠的操你 | 欧美一级免费高清 | 国产午夜亚洲精品 | 中文字幕国产亚洲 | 免费久久久久久 | 人人插人人草 | 日韩中字在线观看 | 国产一级做a | 国产精品理论片 | 韩国av一区二区 | 91精品国产福利 | 色综合久久久久久中文网 | 久久国产午夜精品理论片最新版本 | 久久午夜国产 | 涩涩伊人 | 国产精品麻豆视频 | 婷婷免费在线视频 | 久久精品视频网站 | 欧美99精品 | 999精品网| 欧美日韩一区二区三区不卡 | 黄色小说免费在线观看 | 久久精品激情 | 中文字幕中文字幕在线一区 | 久久涩涩网站 | 欧美激情第一页xxx 午夜性福利 | 91尤物国产尤物福利在线播放 | 91丨porny丨九色 | 97视频亚洲 | 久久精品站 | 国产69久久| 欧美日本不卡高清 | 欧美国产不卡 | 一级黄色片在线免费看 | a级国产片 | 国产精品av一区二区 | 91成人精品一区在线播放69 | 六月色| 精品在线99 | 玖操| 中文字幕av网站 | 狠狠色丁香久久婷婷综合丁香 | 人人草在线视频 | 字幕网在线观看 | 国产成人一区二区三区在线观看 | 视频1区2区| 97电影网手机版 | 午夜91视频| 99re8这里有精品热视频免费 | 美女网站色在线观看 | 精品在线视频观看 | 久色婷婷 | 午夜精品福利一区二区 | av免费看电影 | 日韩av成人免费看 | 69av免费视频 | 91看片一区二区三区 | 麻豆激情电影 | 性色av一区二区 | 国产视频一区二区三区在线 | 在线午夜av | 超碰97免费 | 在线观看av大片 | 国产97视频在线 | 久久夜色精品国产欧美一区麻豆 | 超碰97国产 | 国产特级毛片aaaaaa | 亚洲国产精品一区二区久久hs | 久久成人午夜视频 | 在线观看免费黄视频 | 区一区二区三区中文字幕 | 午夜美女av | 欧美日韩成人一区 | 成人一区二区三区在线观看 | 国产99色 | 24小时日本在线www免费的 | 99一区二区三区 | 国产精品videoxxxx | 亚洲视频在线看 | 91免费在线视频 | 日韩成人在线免费观看 | 精品一区 精品二区 | 亚洲国产手机在线 | 999视频在线播放 | 国产一级一片免费播放放 | 欧美二区在线播放 | 久久久69| 久久午夜影视 | 久久成人国产精品免费软件 | 麻豆视频大全 | 天天色综合天天 | 69久久99精品久久久久婷婷 | 欧美色图一区 | 国产不卡免费视频 | 亚洲片在线观看 | www.五月天激情 | 亚洲午夜久久久久久久久电影网 | 亚洲成人精品av | 中文字幕日韩国产 | 久草久草久草久草 | 激情网综合 | 93久久精品日日躁夜夜躁欧美 | 99精品久久久 | 亚洲三级黄 | 91喷水| 92国产精品久久久久首页 | 久久综合综合久久综合 | 久久国产精品免费 | av成人在线播放 | 国产精品久久久久久久久久久久久久 | 国产在线美女 | 91亚洲精品国偷拍自产在线观看 | 天天操天天能 | 一二区电影 | 亚洲九九影院 | 国内精品久久久久影院优 | 婷婷丁香激情综合 | 精品国产一区二区三区久久久蜜月 | 国产亚洲aⅴaaaaaa毛片 | 日本久久91 | 欧美日韩中文国产一区发布 | 亚洲国产网站 | 992tv人人网tv亚洲精品 | 97免费视频在线 | 九九九九热精品免费视频点播观看 | a v在线观看 | 久久最新 | 久久视频免费观看 | 久久99亚洲网美利坚合众国 | 黄色小说免费在线观看 | 成人毛片久久 | 天堂av网在线 | 国产福利一区在线观看 | 九九视频一区 | 福利视频入口 | 久久综合精品一区 | 日本久久久精品视频 | 久久久综合九色合综国产精品 | 五月激情丁香图片 | 欧美激情在线网站 | 在线中文字母电影观看 | 欧美国产日韩在线观看 | 精品国精品自拍自在线 | 黄色一级大片在线观看 | 97精品超碰一区二区三区 | 久久深夜福利免费观看 | 久久久福利视频 | 久久免费视频在线观看30 | 免费aa大片 | 婷婷激情影院 | 国产精品 国产精品 | 一区二区三区四区久久 | 久久论理 | 97碰在线视频 | 精品亚洲欧美无人区乱码 | 这里只有精彩视频 | 91在线免费播放视频 | 亚洲免费av一区二区 | 色妞久久福利网 | 丁香网五月天 | 免费网站在线观看人 | 亚洲精品自拍视频在线观看 | 午夜精品久久久久久久99水蜜桃 | 美女一二三区 | 日韩欧美精品在线观看 | 日本精品在线 | 一区二区三区在线看 | 天天干天天操天天入 | 91在线看视频 | 国产一级a毛片视频爆浆 | 亚洲成人av片 | 日韩在线电影一区二区 | 成人在线视频论坛 | 成人久久久精品国产乱码一区二区 | 国产精品美女视频网站 | 久久国语露脸国产精品电影 | 精品五月天 | 国产精品不卡视频 | 中文字幕欧美日韩va免费视频 | 日韩在观看线 | 成人在线观看免费视频 | 中文字幕在线观看不卡 | 97热久久免费频精品99 | 91精品国产福利在线观看 | 美女网站在线观看 | 成年人黄色免费视频 | 亚洲在线视频网站 | 激情综合网婷婷 | 欧美va天堂va视频va在线 | 国产精品短视频 | 日本公妇在线观看高清 | 欧美大香线蕉线伊人久久 | 国产成人久久av免费高清密臂 | 黄色1级毛片 | 日韩免费在线观看网站 | 97久久精品午夜一区二区 | 麻豆视频免费在线 | 人人爽人人av | 欧美一区二区三区激情视频 | 久久免费国产视频 | 久久国产精品免费一区二区三区 | 亚洲性少妇性猛交wwww乱大交 | 69国产成人综合久久精品欧美 | 日韩激情免费视频 | 一级黄色片在线观看 | 日本丰满少妇免费一区 | 国产一区二区精品久久 | 欧美另类巨大 | 天堂va在线高清一区 | 九九九热精品免费视频观看 | 丁香九月激情 | 国产精品午夜久久久久久99热 | 久草综合在线 | 国产一区二区在线免费观看 | 日本性xxxxx 亚洲精品午夜久久久 | 国产中文字幕在线免费观看 | 久久精品高清 | 久久久久国产视频 | 超碰在线cao| 成人在线视频在线观看 | 午夜久久久久久久久久影院 | 免费黄a | 午夜色站| 97免费| 香蕉97视频观看在线观看 | 亚洲国产中文在线观看 | 超碰在线人人爱 | 99久久精品免费看国产一区二区三区 | 不卡国产视频 | 精品福利在线观看 | 亚洲资源在线网 | 成人av在线资源 | 久草在线综合网 | 亚洲最新视频在线 | 91视频免费视频 | 亚洲精品国产精品乱码不99热 | 亚洲综合色播 | 成年人在线观看网站 | 日韩精品视频久久 | 精品美女久久久久久免费 | 天天射天天拍 | 午夜资源站 | 日韩高清黄色 | 久草在线视频免费资源观看 | 欧美日韩有码 | 国产91丝袜在线播放动漫 | 亚洲国产精品免费 | 免费亚洲黄色 | 成全在线视频免费观看 | 久久美女免费视频 | 91麻豆精品国产 | 一区二区三区四区不卡 | 性色av免费观看 | 91网在线观看 | 国产成人精品一区二三区 | 96亚洲精品久久久蜜桃 | 国产露脸91国语对白 | 成人av在线电影 | 亚洲国产网站 | 亚洲精品在线免费播放 | 久久久久免费精品国产 | 在线观看黄色免费视频 | 在线看不卡av | 天天曰天天干 | 欧美精品中文 | 在线观看网站你懂的 | 在线观看av免费 | 久久欧美精品 | 亚洲精品在线视频观看 | 欧美一级免费片 | 一级免费av | 久久久人人爽 | 三级动图 | 日韩免费在线看 | 超碰人人在线观看 | 国产成人精品日本亚洲999 | 亚洲国产精品第一区二区 | 一区二区三区观看 | 日韩手机视频 | a黄色片 | 91免费黄视频 | 91久久精 | 久久电影日韩 | 91精品国产入口 | 日韩天天干 | 久久99国产精品久久99 | 亚洲成人av片 | 青青河边草免费直播 | 久久97久久 | 乱男乱女www7788 | 国产第一页福利影院 | 午夜视频一区二区三区 | 亚洲精品在线资源 | 久综合网 | 一二三区视频在线 | 国内精品在线观看视频 | 男女男视频 | 一区免费观看 | 亚洲天天综合 | 国内精品福利视频 | 97看片 | 国产片免费在线观看视频 | 成年人在线看片 | 欧美成天堂网地址 | 日韩字幕| 国产麻豆电影在线观看 | 久久激情五月丁香伊人 | 国产理论影院 | 人人爱夜夜操 | 最新色站 | 久久99精品一区二区三区三区 | 一区二区毛片 | 人人舔人人爽 | 97碰碰碰| 天天综合久久综合 | 六月丁香婷婷网 | 伊人久久五月天 | 国产精品理论视频 | 一性一交视频 | 91精品国产91久久久久 | 久久在线免费观看 | 精品伊人久久久 | 精品一二三四五区 | 狠狠色婷婷丁香六月 | 草久久久久久 | 欧美成人播放 | 97超碰在线资源 | 亚洲午夜久久久影院 | 久久久久久久久久久久久影院 | 9色在线视频 | 麻豆91在线 | 国产成人精品三级 | 五月天久久狠狠 | 久久av免费 | 精品成人久久 | 97色综合 | 成人av直播| av黄网站 | 日韩一级电影在线观看 | 免费看的黄色的网站 | 中文国产字幕在线观看 | 国产一区二区高清视频 | 91精品国产92久久久久 | 亚洲精品久久久久中文字幕二区 | 久久99精品热在线观看 | 深爱婷婷激情 | 97国产大学生情侣白嫩酒店 | 亚洲理论片 | 久久久久国产精品厨房 | 国内一区二区视频 | 国产aaa免费视频 | 久草干 | 亚洲免费在线看 | 亚洲电影黄色 | 免费成人在线网站 | 黄色在线观看网站 | 国产一区二区三区网站 | 一区二区三区视频在线 | 欧美日韩国产精品一区二区三区 | 中日韩欧美精彩视频 | 国产精品高清一区二区三区 | a黄在线观看| 久草视频手机在线 | 天天插天天爱 | 久久国产精品二国产精品中国洋人 | 国产精品大片免费观看 | 在线不卡的av | 91久草视频 | 国产黄在线看 | 丁香亚洲| av中文字幕在线播放 | 日本福利视频在线 | 精品成人a区在线观看 | 激情五月婷婷激情 | 国产老妇av| 日韩天天干| 国产福利一区二区三区在线观看 | 在线观看中文字幕视频 | 热re99久久精品国产66热 | 五月婷婷激情五月 | 欧美激精品 | 波多野结衣一区二区三区中文字幕 | 国产护士av | 国产亚洲成人精品 | 超碰在线97观看 | 欧美日韩在线播放 | 超碰在线1| 美女视频黄频大全免费 | 久久久免费av | 伊人导航 | 日韩久久影院 | av中文字幕网 | 婷婷国产在线观看 | wwwwwww黄| 一区二区三区日韩精品 | www日韩在线观看 | www欧美日韩 | 奇米影视8888在线观看大全免费 | 一级黄色片在线观看 | 蜜桃av久久久亚洲精品 | 狠狠躁18三区二区一区ai明星 | 免费av影视 | 欧美日韩三级 | 日韩欧美精品一区二区 | 黄色大片免费网站 | 一级a毛片高清视频 | 激情视频免费在线 | 伊人五月在线 | 男女激情网址 | 久久一线 | 91在线中文| 午夜10000 | 国产在线观看91 | 97在线影视 | 天天操夜夜叫 | 免费精品在线观看 | 在线免费看黄色 | 色夜视频| 亚洲一区视频免费观看 | 热久久99这里有精品 | 欧美性生爱 | 国产91精品久久久久 | 97在线免费 | 公与妇乱理三级xxx 在线观看视频在线观看 | 九九精品毛片 | 四虎免费在线观看视频 | 最新av观看 | 久久精品麻豆 | 在线观看黄色 | 国产精品视频线看 | 中文字幕乱视频 | 久久久久久久国产精品 | 99电影456麻豆 | 最近最新mv字幕免费观看 | 激情五月婷婷综合 | 国产麻豆成人传媒免费观看 | 91成人免费视频 | 麻豆精品传媒视频 | 高清av中文字幕 | 国产精品一区二区久久 | 九七在线视频 | 天天做天天看 | 美女网站视频色 | 亚洲黄色成人 | 日韩簧片在线观看 | 国产精品露脸在线 | 五月导航 | 精品亚洲一区二区三区 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 天天搞天天干天天色 | 日韩三级在线观看 | 夜夜夜夜夜夜操 | 人人射人人澡 | 日韩免费成人 | 99精品福利视频 | 精品少妇一区二区三区在线 | 91热精品| 亚洲欧美日本一区二区三区 | 成人免费一区二区三区在线观看 | 激情五月婷婷网 | 中文字幕在线播放视频 | 中文字幕九九 | 日本久久免费视频 | 国产夫妻性生活自拍 | 免费视频在线观看网站 | 91成人精品国产刺激国语对白 | 一级片免费观看 | www免费视频com━ | 成人免费观看完整版电影 | 99热最新在线| 欧美一区视频 | 丝袜美女视频网站 | 国产一区二区影院 | 91日韩在线 | 蜜桃视频日本 | 久久伊人综合 | 激情欧美日韩一区二区 | 欧美激情视频免费看 | 91日韩在线播放 | 久久夜色精品国产欧美乱 | 69国产精品视频免费观看 | 国产老熟 | 日韩精品无码一区二区三区 | 久久极品| 三上悠亚一区二区在线观看 | 国产成人精品一区二区在线观看 | 成人在线免费看视频 | 国产精品99久久久久久久久久久久 | 在线观看免费成人 | 日韩专区在线观看 | 久久精品国产精品亚洲 | 久久这里只有精品首页 | 天天射天天做 | 最新中文字幕视频 | 亚洲在线网址 | 亚洲欧美激情精品一区二区 | 丁香婷婷色综合亚洲电影 | 天天激情天天干 | 欧美久久久久久久 | 国内精品视频久久 | av免费在线播放 | 97国产小视频 | 免费观看日韩 | 天天在线免费视频 | 91综合久久一区二区 | 99综合视频 | 亚洲精品字幕在线 | 亚洲天天综合 | 亚洲黄色激情小说 | 久草网站在线 | 久久综合久久88 | 日韩www在线 | 四虎5151久久欧美毛片 | 不卡的av中文字幕 | 91九色蝌蚪视频网站 | 欧美一级淫片videoshd | 波多野结衣亚洲一区二区 |