操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    作為工程師,通常我們在開發板上開發usb device驅動比較多。比如說我們開發板通過usb連接一個usb攝像頭。在這種情況下,我們的開發板中有一個usb host controller,簡稱UHC。開發板充當了usb host角色。這個時候我們在開發板中開發的usb 攝像頭等usb設備驅動,稱之為usb device驅動。

    那么有沒有可能使得我們的開發板作為一個usb設備呢?比如在實際應用場景中,開發板A沒有網卡,開發板B有網卡。開發板A想上網,只能通過usb連接開發板B,讓開發板B共享自己的網卡資源.這個時候開發板A是host角色。開發板B是device角色,它里面有usb device controller,簡稱UDC。這個時候很明顯我們需要在開發板B開發一個驅動,使得它自己可以作為一個usb網卡設備被A識別并使用。那么,開發板B中的驅動,我們稱之為usb gadget驅動。常見的usb gadget驅動有RNDIS(usb 網卡),file_storage(比如安卓手機插到電腦可以當u盤),adb(開發過安卓的應該都知道是啥)

    相信大家已經明白了usb device驅動及usb gadget驅動的區別了。那么,我們平時把手機通過usb線接到電腦上面當u盤使用,我們的手機中需要usb gadget驅動還是usb device驅動呢?歡迎大家將你們的答案寫在留言區。

    /* USB_DT_ENDPOINT: Endpoint descriptor */
    struct usb_endpoint_descriptor {
    	__u8  bLength;
    	__u8  bDescriptorType;
    
    	__u8  bEndpointAddress;
    	__u8  bmAttributes;
    	__le16 wMaxPacketSize;
    	__u8  bInterval;
    
    	/* NOTE:  these two are _only_ in audio endpoints. */
    	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
    	__u8  bRefresh;
    	__u8  bSynchAddress;
    } __attribute__ ((packed));
    
    #define USB_DT_ENDPOINT_SIZE		7
    
    struct usb_ep {
    	void			*driver_data;
    
    	const char		*name;
    	const struct usb_ep_ops	*ops;
    	struct list_head	ep_list;
    	struct usb_ep_caps	caps;
    	bool			claimed;
    	bool			enabled;
    	unsigned		maxpacket:16;
    	unsigned		maxpacket_limit:16;
    	unsigned		max_streams:16;
    	unsigned		mult:2;
    	unsigned		maxburst:5;
    	u8			address;
    	const struct usb_endpoint_descriptor	*desc;
    	const struct usb_ss_ep_comp_descriptor	*comp_desc;
    };
    
    struct s3c2410_ep {
    	struct list_head		queue;
    	unsigned long			last_io;	/* jiffies timestamp */
    	struct usb_gadget		*gadget;
    	struct s3c2410_udc		*dev;
    	struct usb_ep			ep;
    	u8				num;
    
    	unsigned short			fifo_size;
    	u8				bEndpointAddress;
    	u8				bmAttributes;
    
    	unsigned			halted : 1;
    	unsigned			already_seen : 1;
    	unsigned			setup_stage : 1;
    };
    
    
    static const struct usb_ep_ops s3c2410_ep_ops={
    	.enable=s3c2410_udc_ep_enable,
    	.disable=s3c2410_udc_ep_disable,
         
    };
    *
     *	s3c2410_udc_ep_enable
     */
    static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
    				 const struct usb_endpoint_descriptor *desc)
    {
    	struct s3c2410_udc	*dev;
    	struct s3c2410_ep	*ep;
    	u32			max, tmp;
    	unsigned long		flags;
    	u32			csr1, csr2;
    	u32			int_en_reg;
    
    	ep=to_s3c2410_ep(_ep);
    
    	if (!_ep || !desc
    			|| _ep->name==ep0name
    			|| desc->bDescriptorType !=USB_DT_ENDPOINT)
    		return -EINVAL;
    
    	dev=ep->dev;
    	if (!dev->driver || dev->gadget.speed==USB_SPEED_UNKNOWN)
    		return -ESHUTDOWN;
    
    	max=usb_endpoint_maxp(desc) & 0x1fff;   ////根據endpoint 描述符設置 udc reg 
    
    	local_irq_save(flags);
    	_ep->maxpacket=max & 0x7ff;
    	ep->ep.desc=desc;
    	ep->halted=0;
    	ep->bEndpointAddress=desc->bEndpointAddress;
    
    	/* set max packet */
    	udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    	udc_write(max >> 3, S3C2410_UDC_MAXP_REG);
    
    	/* set type, direction, address; reset fifo counters */
    	if (desc->bEndpointAddress & USB_DIR_IN) {
    		csr1=S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT;
    		csr2=S3C2410_UDC_ICSR2_MODEIN|S3C2410_UDC_ICSR2_DMAIEN;
    
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
    	} else {
    		/* don't flush in fifo or it will cause endpoint interrupt */
    		csr1=S3C2410_UDC_ICSR1_CLRDT;
    		csr2=S3C2410_UDC_ICSR2_DMAIEN;
    
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
    
    		csr1=S3C2410_UDC_OCSR1_FFLUSH | S3C2410_UDC_OCSR1_CLRDT;
    		csr2=S3C2410_UDC_OCSR2_DMAIEN;
    
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr1, S3C2410_UDC_OUT_CSR1_REG);
    		udc_write(ep->num, S3C2410_UDC_INDEX_REG);
    		udc_write(csr2, S3C2410_UDC_OUT_CSR2_REG);
    	}
    
    	/* enable irqs */
    	int_en_reg=udc_read(S3C2410_UDC_EP_INT_EN_REG);
    	udc_write(int_en_reg | (1 << ep->num), S3C2410_UDC_EP_INT_EN_REG);
    
    	/* print some debug message */
    	tmp=desc->bEndpointAddress;
    	dprintk(DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n",
    		 _ep->name, ep->num, tmp,
    		 desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max);
    
    	local_irq_restore(flags);
    	s3c2410_udc_set_halt(_ep, 0);
    
    	return 0;
    }
    
    /*
     * s3c2410_udc_ep_disable
     */
    static int s3c2410_udc_ep_disable(struct usb_ep *_ep)
    {
    	struct s3c2410_ep *ep=to_s3c2410_ep(_ep);
    	unsigned long flags;
    	u32 int_en_reg;
    
    	if (!_ep || !ep->ep.desc) {
    		dprintk(DEBUG_NORMAL, "%s not enabled\n",
    			_ep ? ep->ep.name : NULL);
    		return -EINVAL;
    	}
    
    	local_irq_save(flags);
    
    	dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
    
    	ep->ep.desc=NULL;
    	ep->halted=1;
    
    	s3c2410_udc_nuke(ep->dev, ep, -ESHUTDOWN);
    
    	/* disable irqs */
    	int_en_reg=udc_read(S3C2410_UDC_EP_INT_EN_REG);
    	udc_write(int_en_reg & ~(1<<ep->num), S3C2410_UDC_EP_INT_EN_REG);
    
    	local_irq_restore(flags);
    
    	dprintk(DEBUG_NORMAL, "%s disabled\n", _ep->name);
    
    	return 0;
    }
    
網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有