日韩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)容還不錯,歡迎將生活随笔推薦給好友。

97综合视频 | 玖玖视频在线 | jizzjizzjizz亚洲 | 国产99久久99热这里精品5 | 中文字幕日本在线观看 | 欧美日韩另类视频 | 日韩av一区二区三区四区 | 午夜精品久久久久久久99婷婷 | 日韩av电影一区 | 五月天婷婷狠狠 | 日日干日日操 | 亚洲成a人片综合在线 | 国产精品久久久久久久久久白浆 | 亚洲精品视频网站在线观看 | 黄色tv视频| 最近免费观看的电影完整版 | 久久免费毛片 | 天天操天天干天天玩 | 深爱激情综合 | 久久精品视频网 | 欧美91成人网| 91九色在线视频 | av一本久道久久波多野结衣 | 日本精品一区二区在线观看 | 日韩在线视频二区 | 四季av综合网站 | 亚洲国产免费看 | www..com毛片| av免费线看 | 天天爱天天草 | 91麻豆精品国产午夜天堂 | 少妇高潮冒白浆 | 亚洲午夜精品福利 | 国产精品大片在线观看 | 国产成年人av | 天天操天天插 | 亚洲综合丁香 | 久久乐九色婷婷综合色狠狠182 | 成人免费观看视频大全 | 欧美 日韩 国产 成人 在线 | 成人国产精品 | 手机av在线免费观看 | 一区二区三区在线播放 | 国产激情电影综合在线看 | av黄色免费网站 | 97在线视频免费 | 久久久久久久久影视 | 天天干,天天射,天天操,天天摸 | 黄色日本片 | 午夜在线资源 | 超碰久热 | www亚洲一区 | 在线色亚洲 | 久久久久久久99 | 深爱激情久久 | 精品在线观看免费 | 日韩欧美国产免费播放 | 国产高清专区 | 一区二区 精品 | 免费精品视频在线 | 欧美日韩国产一区二区三区在线观看 | 国产精品99久久久久 | 亚洲电影成人 | 精品久久久免费视频 | 69久久夜色精品国产69 | 国产精品专区在线 | 操久| 狠狠操天天操 | 国产视频在线观看一区二区 | 日韩理论电影在线观看 | 中文字幕资源站 | 在线观看视频三级 | 色a资源在线 | 97色综合| 一区二区视频在线观看免费 | 女人18毛片90分钟 | 黄色亚洲大片免费在线观看 | 最近中文字幕免费视频 | 亚洲精品中文在线资源 | 成年人黄色免费看 | 中文字幕在线观看第一区 | 久久精品www人人爽人人 | 99久久精品日本一区二区免费 | 午夜少妇 | 亚洲一级黄色片 | 日本久久精品 | 中文字幕综合在线 | 国产在线一区二区三区播放 | 中文字幕中文字幕在线中文字幕三区 | 亚洲成人精品在线观看 | 久青草视频在线观看 | 国产成人一区三区 | 久久久不卡影院 | 色婷婷综合久久久 | 国产免费xvideos视频入口 | 日本中出在线观看 | 欧美永久视频 | 日本精品一区二区三区在线播放视频 | 日本黄色黄网站 | 国产精品手机在线 | 亚洲专区欧美 | 国产精品毛片一区二区在线看 | 亚洲欧美在线观看视频 | av成人在线电影 | 亚洲一区二区三区精品在线观看 | 日韩av中文 | 制服丝袜欧美 | 97国产一区 | 91在线看网站 | 婷婷福利影院 | 日韩电影中文 | 精品在线免费视频 | 免费黄在线观看 | 在线影院av | 久久香蕉电影 | 亚洲精品自在在线观看 | 激情导航| 成人动漫一区二区三区 | 欧美一级xxxx| 天天综合精品 | 九色精品在线 | 久久久亚洲影院 | 久久论理 | 国产精品99久久久精品免费观看 | 97电影手机版| 欧美一级片在线播放 | 最新午夜| 午夜av不卡 | 国产成人精品免高潮在线观看 | 国产黄色片免费观看 | 97国产一区| 精品毛片在线 | 亚洲黄色成人av | 中文字幕免费在线 | 亚洲一区二区三区91 | 久久人人爽人人 | 国产人成一区二区三区影院 | 成人在线播放免费观看 | 日韩av中文 | 欧美a级成人淫片免费看 | 久久久久久久久久久久亚洲 | 在线av资源| 国产亚洲婷婷免费 | 日韩综合第一页 | 亚洲aⅴ在线观看 | 日本亚洲国产 | 免费成人黄色片 | 97超碰国产精品 | 欧美日韩国产综合网 | av一二三区 | 国产成人精品一区二区在线观看 | 欧美精品国产精品 | 欧美另类巨大 | 天天干天天插伊人网 | 亚洲国产精品人久久电影 | 国产精品久久嫩一区二区免费 | 久久久国产影院 | 精品国产日本 | 免费观看91视频大全 | 色人久久| 亚洲激情五月 | 日韩精品免费在线播放 | 日日夜夜免费精品视频 | 77国产精品 | 精品久久久久久综合 | 国产亚洲欧美精品久久久久久 | 欧美吞精 | 亚洲aⅴ乱码精品成人区 | 国产不卡精品视频 | 国产色婷婷精品综合在线手机播放 | 日本二区三区在线 | 亚洲经典中文字幕 | 日批视频国产 | 久久99久久99精品免观看粉嫩 | japanesexxxhd奶水| 久久国内精品视频 | 狠狠色噜噜狠狠狠狠 | av成年人电影 | 久久久国产一区二区三区 | 在线观看免费观看在线91 | 免费久久网 | 色婷婷激婷婷情综天天 | 久久久久欠精品国产毛片国产毛生 | 亚洲国产精彩中文乱码av | 91精品国产电影 | 国产高清成人av | 久久久精品亚洲 | 91久久国产露脸精品国产闺蜜 | av免费成人 | 成人黄色在线看 | 91麻豆精品国产91久久久久久 | 热久久电影 | 色偷偷av男人天堂 | 中文乱幕日产无线码1区 | av福利第一导航 | 91成品视频 | 久久午夜精品影院一区 | 免费观看91| 久久午夜影院 | 国产精品网站一区二区三区 | 中文字幕精品三区 | 国产精品99久久久久 | 国产精品男女视频 | 国产在线最新 | 国产精品免费久久久 | 久久观看最新视频 | 久久黄色精品视频 | 国产婷婷精品av在线 | 中文字幕有码在线观看 | 美女精品国产 | 久久免费成人 | 91大神精品视频在线观看 | 中国一区二区视频 | 97视频在线免费观看 | 欧美日韩大片在线观看 | 日韩色一区二区三区 | 国产精品久久久久久高潮 | 欧美日韩另类在线 | 久久综合偷偷噜噜噜色 | 久草久热 | 日韩欧美高清视频在线观看 | 草免费视频 | 99精品国产一区二区 | 最新三级在线 | 国产一级免费片 | 9在线观看免费高清完整版在线观看明 | 美女中文字幕 | 99精品热视频只有精品10 | 国产无套精品久久久久久 | 成人在线观看免费视频 | h文在线观看免费 | 国产精品美女久久久久aⅴ 干干夜夜 | 国产一级片毛片 | 成人黄色在线看 | 国产精品资源网 | 国产精品久久久久久久久久妇女 | 99久久精品免费一区 | 在线精品视频免费播放 | 91麻豆产精品久久久久久 | 奇米导航 | 日本精品在线视频 | 五月激情久久久 | 91人人爽人人爽人人精88v | 激情视频一区二区三区 | 日本中文字幕视频 | av中文字幕网站 | 国产精品久久久久久久午夜 | 免费在线观看毛片网站 | 亚洲精品综合欧美二区变态 | 激情婷婷久久 | 在线观看国产永久免费视频 | 欧美精品午夜 | 亚洲国产97在线精品一区 | 999视频网| 国产拍在线 | 五月婷网站 | www.大网伊人 | 欧美色就是色 | 99精品视频99| 在线欧美小视频 | 久久人人爽av | 日韩中文字幕免费看 | 四虎永久免费在线观看 | 久久精品网站视频 | 免费aa大片 | 国产精品欧美激情在线观看 | 国产一区二区三区高清播放 | 亚洲午夜精品在线观看 | 欧美最猛性xxx | 亚洲国产手机在线 | 日韩精品一区不卡 | 日韩亚洲在线视频 | 日韩精品中文字幕在线观看 | 欧美另类69| 五月婷婷综合在线视频 | 在线视频在线观看 | 99久久婷婷国产综合亚洲 | 国产午夜精品一区二区三区欧美 | 92精品国产成人观看免费 | 人人爽人人爽人人片 | 美女网站在线免费观看 | 免费黄色网址网站 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 亚洲成av人片 | 色www精品视频在线观看 | 六月丁香色婷婷 | 色夜视频 | 91日韩精品| 国产视频2区 | 久久国产精品免费 | 日韩中文字幕视频在线观看 | 午夜私人影院久久久久 | 黄色特级毛片 | 亚洲久草在线视频 | 亚洲成人资源在线 | 色中色综合 | 日韩在线观看一区二区三区 | 日韩xxxxxxxxx | 亚洲国产精品成人女人久久 | 国产在线国产 | 最新高清无码专区 | 一区二区电影在线观看 | 国产精品成人在线 | 三级午夜片 | 福利视频一二区 | 国产亚洲一区二区在线观看 | 91网页版免费观看 | 久久久久久久久久电影 | 日韩在线欧美在线 | 国产高清精 | 国产精品一区二区久久久 | 最新日韩视频在线观看 | 国产在线色视频 | 人人干干人人 | 亚洲播放一区 | 亚洲午夜久久久久久久久 | 国产真实精品久久二三区 | 91av国产视频 | 欧美成人xxxx| 美女福利视频在线 | 久久久www成人免费精品 | 久亚洲| 超碰在线最新网址 | 久久电影国产免费久久电影 | 亚洲精品videossex少妇 | 国产高清在线a视频大全 | 天天射网站 | 超碰在线最新网址 | 久草久草视频 | 中文字幕亚洲高清 | 日日干美女 | 国产成人精品电影久久久 | 国产精品一区二区吃奶在线观看 | 亚洲黄色成人 | 韩日精品在线 | 在线观看第一页 | 九九热视频在线免费观看 | 狠狠狠色丁香婷婷综合久久五月 | www五月天com| 精品国产免费av | 97在线视频免费播放 | 综合久久精品 | 成人宗合网 | 久久99热久久99精品 | 国产精品亚洲人在线观看 | 国产资源精品 | 免费在线观看一区 | 最近最新最好看中文视频 | 欧美在线视频不卡 | av网站大全免费 | 在线观看中文字幕一区二区 | 亚洲精品欧洲精品 | 黄色一区二区在线观看 | 亚洲码国产日韩欧美高潮在线播放 | 婷婷深爱五月 | 国产精品美女久久久久久久 | 中文字幕在线人 | 97精品国产97久久久久久久久久久久 | 欧美精品999 | 成人网色| av免费看网站 | 在线观看91久久久久久 | 在线视频 亚洲 | 午夜久久成人 | 91在线影视 | 特级aaa毛片 | 日韩欧美在线视频一区二区 | 狠狠久久综合 | 欧美激情第一区 | 色婷婷www| 欧美调教网站 | 亚洲国产精品99久久久久久久久 | av黄网站| 日韩在线视频免费播放 | 精品国产人成亚洲区 | 久久精品一 | 久久久免费高清视频 | 日韩精品欧美一区 | www.夜夜干.com | 99爱视频在线观看 | 亚洲色视频 | 亚洲欧美视频在线播放 | 婷婷激情在线 | 99免费国产 | 99激情网| 欧美色操 | 99热最新网址 | 精品久久国产精品 | 日韩欧美91| 国产成人精品av在线 | 国产一区二区在线免费播放 | 日韩一区二区在线免费观看 | 国产精品99免费看 | 国产综合精品久久 | 日韩精品一区在线观看 | 久久 精品一区 | 日韩综合一区二区 | 国产日韩欧美在线一区 | 日本久久久影视 | 久久综合色一综合色88 | 天天操狠狠操 | 99久久夜色精品国产亚洲96 | 久久久久久久久久久成人 | 在线99热 | 色吊丝在线永久观看最新版本 | 黄色高清视频在线观看 | 三上悠亚一区二区在线观看 | 色婷婷综合成人av | 在线不卡中文字幕播放 | 成 人 黄 色 免费播放 | 亚洲一级二级三级 | www.亚洲激情.com | 香蕉色综合 | 婷婷激情五月综合 | 97在线观 | 免费看一级黄色 | 三级在线国产 | 亚洲精品视频在线观看网站 | 91中文字幕在线播放 | 久久久久国产一区二区三区四区 | 亚洲欧美日韩一区二区三区在线观看 | 奇米7777狠狠狠琪琪视频 | 午夜视频99 | 国产亚洲欧美一区 | 日韩xxxx视频 | 午夜10000| 黄色片免费看 | 久久99精品久久久久久久久久久久 | 久久久男人的天堂 | 在线看黄网站 | 精品久久久久久亚洲综合网站 | a级国产乱理伦片在线观看 亚洲3级 | 黄色三几片 | 人人澡人人添人人爽一区二区 | 久久久午夜精品福利内容 | 国产一区二区高清视频 | 久草在线视频免赞 | 久久中文字幕导航 | 一本大道久久精品懂色aⅴ 五月婷社区 | 日韩欧美一区二区三区在线 | 免费福利小视频 | 国产无套精品久久久久久 | 国产又粗又猛又色又黄视频 | 欧美淫aaa免费观看 日韩激情免费视频 | 日韩高清www | 日韩毛片精品 | 99视频免费播放 | 九九久久在线看 | 成人亚洲免费 | 日本3级在线观看 | 91精品麻豆 | 国产香蕉97碰碰久久人人 | 黄免费在线观看 | 欧美午夜精品久久久久久浪潮 | 国产一区二区综合 | 久久久久亚洲精品男人的天堂 | 蜜臀av性久久久久av蜜臀妖精 | 午夜久久福利视频 | 在线免费观看av网站 | 日韩高清二区 | 亚洲精品自拍视频在线观看 | 国产手机在线观看视频 | 日韩久久精品 | 天天射天天干天天 | 免费观看成人av | 国产一线二线三线性视频 | 99久久国产免费,99久久国产免费大片 | 黄色www在线观看 | 国产女v资源在线观看 | 国产 成人 久久 | 国产欧美精品一区二区三区 | 久久久999精品视频 国产美女免费观看 | 国产精品乱码久久久久 | 色综合中文综合网 | 成人一区二区三区在线 | 国产视频亚洲 | 啪啪肉肉污av国网站 | 一区三区在线欧 | 欧美日韩一区二区久久 | 波多野结衣在线视频一区 | 国产精品破处视频 | 久久久久日本精品一区二区三区 | 免费看一级黄色 | 国产综合精品一区二区三区 | 色老板在线 | av黄色在线观看 | 免费日韩av电影 | 日韩成人邪恶影片 | 久久99国产精品视频 | 91av播放| 精品欧美在线视频 | 日本少妇高清做爰视频 | 国产精品扒开做爽爽的视频 | 亚洲一级国产 | 麻豆传媒一区二区 | 日韩欧美高清一区二区三区 | 精品自拍网 | 欧美一区影院 | 五月婷婷爱 | 97影视 | 97电影在线 | 色综合久久久久久久 | 福利二区视频 | 成人黄色免费在线观看 | 三级黄色理论片 | 黄色大片日本免费大片 | 91女神的呻吟细腰翘臀美女 | 国产精品免费视频网站 | 超碰人人舔 | 美女视频一区 | 日日干夜夜草 | 综合国产在线 | 成人在线观看影院 | 国产91国语对白在线 | 51久久成人国产精品麻豆 | 在线观看日韩视频 | 国产网红在线 | 久久国产视频网 | 亚州精品国产 | 成人a在线观看高清电影 | 久久久久亚洲精品成人网小说 | 国产中文 | 欧美精品在线观看一区 | 亚洲黄色成人网 | 亚洲精品美女 | 91原创在线观看 | 国产精品久久久久av免费 | 十八岁以下禁止观看的1000个网站 | 在线视频观看亚洲 | 亚洲va韩国va欧美va精四季 | 欧美久久久久久久久 | a成人v | 国产精品久久嫩一区二区免费 | 亚洲国产精品第一区二区 | 天天人人 | 2019中文最近的2019中文在线 | 亚洲黄色av网址 | 亚洲2019精品 | 岛国av在线 | 久久99婷婷| 日韩三级视频在线观看 | 中文字幕在线观看一区 | 日本精品久久久久 | 国产精品成人一区二区三区吃奶 | 国产精品视频内 | 久久你懂的| 国产午夜免费视频 | 国产精品女人久久久久久 | 欧美日韩高清一区二区 国产亚洲免费看 | 日韩天天干| 国产精品成人久久久久久久 | av网站免费看 | 欧美一区二区三区四区夜夜大片 | 亚洲精品自拍视频在线观看 | 欧美在线a视频 | 日韩欧美在线不卡 | 黄色资源在线观看 | 国产91勾搭技师精品 | 又黄又刺激视频 | 日本精品久久久久久 | 91九色视频在线观看 | 中文字幕在线播放视频 | 91视频电影 | 国产一级h | 97电影网手机版 | 一二三区视频在线 | 欧美 日韩 成人 | 一本一本久久a久久精品综合 | 久久av高清| 黄av免费 | 中文字幕视频一区二区 | 日本精品视频免费观看 | 一级片色播影院 | 亚洲精品美女免费 | jizz999| 亚洲精品在线免费看 | 久日视频| 2023天天干 | 亚洲国产成人精品电影在线观看 | 精品国产黄色片 | 日本韩国欧美在线观看 | 青春草国产视频 | 中文字幕在线看视频国产中文版 | 高清不卡一区二区在线 | 91经典在线 | 免费看黄视频 | 中文字幕在线视频一区二区 | 美女精品在线观看 | 8x8x在线观看视频 | 久久免费一 | 美女视频免费精品 | 九九免费观看全部免费视频 | 超碰免费在线公开 | 992tv在线成人免费观看 | 国产精品免费在线观看视频 | 美女网站视频久久 | va视频在线| 欧美日韩在线精品 | 国产黄色精品视频 | 欧美黄色成人 | 久久久久久久影视 | 国产一区观看 | 国产一卡在线 | 欧美一级片免费播放 | 香蕉久久久久久av成人 | 久久精品爱爱视频 | 天天干天天拍 | 欧美成人中文字幕 | 免费电影一区二区三区 | a视频在线观看 | 免费av成人在线 | 日韩理论| 96精品高清视频在线观看软件特色 | 人人澡澡人人 | 色天天天| 日韩中文在线视频 | 九九久久电影 | 久久夜色精品国产欧美一区麻豆 | 国产精品video爽爽爽爽 | 91av网站在线观看 | 免费av小说| 狠狠躁夜夜躁人人爽超碰97香蕉 | 天天干天天操人体 | 毛片网站在线观看 | 亚洲九九爱 | 国产专区视频 | av网站免费线看精品 | 欧美国产日韩一区二区三区 | 懂色av一区二区在线播放 | 丁香婷婷网 | 日韩视频在线不卡 | 一级成人网 | 免费观看完整版无人区 | 91中文字幕在线播放 | 精品亚洲欧美一区 | 视频一区二区精品 | 911国产在线观看 | 成人97人人超碰人人99 | 国产经典 欧美精品 | 特级黄色片免费看 | 不卡av在线免费观看 | 国产精品日韩精品 | 九九综合九九综合 | japanesexxxxfreehd乱熟 | 国产精品手机播放 | 国产亚洲免费的视频看 | 日韩肉感妇bbwbbwbbw | www色com | 午夜av免费在线观看 | 欧美黑吊大战白妞欧美 | av线上看| 黄色毛片视频免费观看中文 | 一区三区视频在线观看 | 国产黄色在线 | 一本到在线 | 中文字幕一区二区三区乱码在线 | 国产经典 欧美精品 | 91电影福利| 免费看av片网站 | 激情五月亚洲 | 激情五月五月婷婷 | 视色网站| 91丝袜美腿 | 操碰av| 亚洲成人资源在线观看 | 精品福利片 | 国产精品一区二区三区观看 | 五月婷婷导航 | 亚洲成人国产精品 | 国产成人在线免费观看 | 999男人的天堂 | 网址你懂的在线观看 | 国产亚洲精品久 | 久久久久久久久久久久国产精品 | 成人a视频片观看免费 | 中文字幕中文字幕在线中文字幕三区 | 97色婷婷成人综合在线观看 | 久久精品国产v日韩v亚洲 | 国产污视频在线观看 | 欧美中文字幕第一页 | av电影在线观看完整版一区二区 | 欧美日韩免费在线观看视频 | 久草免费色站 | 国产亚洲精品久久久久秋 | 97在线视| 91精品国产高清自在线观看 | 日韩精品一区二区三区水蜜桃 | 菠萝菠萝在线精品视频 | 国产成人精品福利 | 免费看黄色大全 | 视频一区二区精品 | 久久视频免费观看 | 外国av网| 成人国产电影在线观看 | 久久情爱 | 一区二区三区免费网站 | 99在线观看免费视频精品观看 | 中文字幕资源网 国产 | 美女黄频网站 | 久久久一本精品99久久精品 | 久久免费公开视频 | 亚洲国内精品在线 | 婷婷丁香在线视频 | 中文伊人 | 国产视频91在线 | 免费国产一区二区视频 | 欧美色图狠狠干 | 国产美女被啪进深处喷白浆视频 | 欧美久久久 | 国语黄色片 | 精品国产成人av在线免 | 三级黄色欧美 | 日韩激情视频在线 | 在线观看播放av | 色婷婷精品大在线视频 | 国产精品福利在线 | 久久久久久久久影院 | 成人免费在线播放 | 在线高清一区 | 成人午夜电影在线 | 久久久久亚洲国产精品 | 99国产情侣在线播放 | 欧美午夜精品久久久久久浪潮 | 人人插人人干 | 久久99精品国产99久久 | 黄色免费观看视频 | 免费在线观看国产精品 | 午夜av电影 | 激情视频综合网 | 日本公妇在线观看 | av综合av| 一区二区三区免费在线观看 | 一区二区欧美在线观看 | 成人av电影免费 | 国产你懂的在线 | 亚洲欧美视频在线播放 | 天天精品视频 | 欧美国产日韩激情 | a资源在线 | 日本成人中文字幕在线观看 | 免费看的黄色小视频 | 久久爽久久爽久久av东京爽 | www.久久色| 黄色三级网站在线观看 | 国产精品丝袜在线 | www.超碰| 中文字幕欧美三区 | 国内揄拍国产精品 | 精品国产日本 | 日本不卡一区二区三区在线观看 | 亚洲人成免费 | 国产123区在线观看 国产精品麻豆91 | 日本成人免费在线观看 | 国产精品久久久久四虎 | 国产精品久久久久永久免费 | 九九久久免费 | 不卡精品 | 香蕉视频导航 | 黄www在线观看 | 日日爽天天爽 | 日韩高清在线一区 | 日韩在线网址 | 91污污| 九九综合九九 | 婷婷丁香色 | 99人成在线观看视频 | 中文字幕a∨在线乱码免费看 | 欧美日韩国产成人 | 久久成人国产精品一区二区 | 久久精品成人欧美大片古装 | 欧美日韩免费一区 | 黄色毛片一级 | 在线观看黄污 | 久草视频精品 | 日本在线观看中文字幕无线观看 | 激情小说网站亚洲综合网 | 亚洲精品18p| 午夜视频在线观看一区 | 色婷婷色 | 亚洲国产精品va在线看黑人动漫 | 日韩高清www | 色偷偷888欧美精品久久久 | 精品国产一区二区三区男人吃奶 | 亚洲黄色在线播放 | 色婷婷啪啪免费在线电影观看 | 欧洲精品码一区二区三区免费看 | 色香蕉网 | 亚洲国产美女久久久久 | 日韩精品中文字幕在线不卡尤物 | 五月婷久久 | 天堂av在线网站 | 在线视频手机国产 | 中文字幕在线视频一区二区三区 | 久久久久久久网 | 一级欧美日韩 | 成年人免费看 | 伊人五月| 国产精品毛片一区二区三区 | 免费观看www7722午夜电影 | 免费在线观看视频一区 | 中文字幕在线观看不卡 | 二区三区在线 | 国产美女免费视频 | 99久久精品免费看国产 | av网站在线观看免费 | 成人av影视观看 | 国产免费久久久久 | 天天干天天操天天入 | 天天色天天射天天操 | 国产精品美乳一区二区免费 | 九九热精品视频在线观看 | 日韩av一区二区三区四区 | 天天做日日做天天爽视频免费 | 日本中文字幕久久 | 九九三级毛片 | 欧美久久久久久久久久 | 日本狠狠干 | 久久视频国产 | 久久久久久久久黄色 | 夜夜澡人模人人添人人看 | 在线视频18在线视频4k | 久久久久国产精品免费 | 91av小视频 | 字幕网av| 久久69精品久久久久久久电影好 | 中文字幕av在线播放 | 69av视频在线观看 | 国产精品精品国产婷婷这里av | 亚洲天堂网视频 | 五月婷婷开心中文字幕 | 国产精品免费视频观看 | 97成人资源站 | 日韩美女久久 | 国产精品专区h在线观看 | 在线国产黄色 | 美女国产免费 | 国产一级在线看 | 在线岛国av | 九9热这里真品2 | 免费看黄色大全 | 一区二区三区免费播放 | 日韩xxxbbb| 97超碰人人澡人人爱学生 | h文在线观看免费 | 久久久综合色 | 亚洲天天综合网 | 久久天天拍 | 亚洲色图27p| 九九九视频精品 | 免费福利在线播放 | 久久久一本精品99久久精品66 | 国产精品一区二区三区在线看 | 麻豆视频在线播放 | 中文字幕在线不卡国产视频 | 黄视频色网站 | 亚洲精品网站 | 久久精品99久久久久久2456 | 日韩视频图片 | 欧美精品一区二区免费 | 视频在线99 | 国产美女精品久久久 | 日韩三级在线 | 国产精品99久久免费黑人 | 亚洲一区免费在线 | 国产高清在线永久 | 美女免费黄网站 | 日韩理论在线播放 | 99免费在线播放99久久免费 | 国产九九九精品视频 | 国产成人精品999在线观看 | 啪啪动态视频 | 最近中文国产在线视频 | 欧美日韩不卡在线视频 | 蜜臀av免费一区二区三区 | 亚洲一级片免费观看 | 中文字幕一区二区三区久久 | 美女av电影 | 久久er99热精品一区二区三区 | 久久久久久久影视 | 九九av| 中文字幕在线观看完整 | 国产精品一区在线播放 | 久久免费视频这里只有精品 | 国产资源网 | 中文字幕日韩伦理 | 国产精品久久久久国产精品日日 | 欧美孕妇视频 | 精品美女视频 | 午夜国产一区二区 | 一区二区久久 | 日韩午夜精品福利 | 国产精品免费一区二区三区 | 欧美另类一二三四区 | 日日干夜夜草 | 国产精品中文字幕在线 | 黄色的视频| 黄色视屏av | 亚洲国产av精品毛片鲁大师 | 91九色视频在线 | 免费手机黄色网址 | 一本一本久久a久久精品综合妖精 | 日日夜夜免费精品视频 | 中文字幕一二 | 成人黄色电影视频 | 中文字幕在线观看视频免费 | 久久久精品网 | 亚洲国产精品一区二区久久,亚洲午夜 | 久久国产精品99久久久久 | 一级久久久 | 国产丝袜网站 | 日韩免费在线看 | 久久国内精品99久久6app | 久久久国产99久久国产一 | 丝袜av一区 | 中文在线www| 国产免费又黄又爽 | 五月天婷亚洲天综合网鲁鲁鲁 | 久香蕉 | 国产精品久久久久久久久软件 | 免费a视频在线观看 | 播五月综合| 日本久久99 | 激情综合婷婷 | 久久尤物电影视频在线观看 | 黄av在线 | 五月天综合激情 | 久久久久国产精品一区 | 国产高清视频在线免费观看 | 日韩影视大全 | a精品视频 | 亚洲免费av片| 日韩欧美精品在线观看 | 伊人黄 | 最新在线你懂的 | 亚洲第一区在线播放 | 在线色资源 | 碰天天操天天 | 在线亚洲播放 | 国产蜜臀av | 丰满少妇在线观看 | 精品久久久久_ | 久久久久久国产精品美女 | 国产精品一区在线观看 | 在线国产视频观看 | 国产精品久久久一区二区三区网站 | 国产精品久久久久久久久久久久冷 | 日本夜夜草视频网站 | 波多野结衣在线观看视频 | 亚洲激情视频在线 | 夜夜操网| 中文字幕第 | 嫩小bbbb摸bbb摸bbb | 免费欧美高清视频 | 日韩午夜av | 午夜久久美女 | 久久久久久久久久久久国产精品 | 久久精品屋 | 亚洲欧美日本一区二区三区 | 91av免费看| 国产一级在线 | 欧美 国产 视频 | 亚洲四虎 | 国产99久久99热这里精品5 | 天天干,天天操,天天射 | 精品女同一区二区三区在线观看 | 99久高清在线观看视频99精品热在线观看视频 | 国产午夜精品一区二区三区 | 玖草在线观看 | 成人看片| 国产精品九九久久99视频 | 久久男女视频 | 国产一区二区三区免费观看视频 | 四虎影视成人精品 | 欧美日韩国产高清视频 | 日本高清免费中文字幕 | 国产亚洲午夜高清国产拍精品 | 国产福利91精品张津瑜 | 久久国产精品久久久 | 国产精品av在线 | 午夜性盈盈 | 久久久精品网站 | 久久久免费 | 2024av | 久久国产系列 | av黄色免费网站 | 免费三级黄 | 黄色av电影免费观看 | 超碰在线公开免费 | 日韩精品不卡在线观看 | 久久久久久久久久久免费av | 欧洲精品视频一区二区 | 99精品国产成人一区二区 | 欧美网址在线观看 | 亚洲国产精品久久久久婷婷884 | 福利视频午夜 | 免费看的av片 | 久精品一区 | www.xxxx欧美|