Esempio n. 1
0
/**
 * This function is called by the Gadget Driver for each EP to be
 * configured for the current configuration (SET_CONFIGURATION).  
 * 
 * This function initializes the dwc_otg_ep_t data structure, and then
 * calls dwc_otg_ep_activate.
 */
static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep, 
								 const struct usb_endpoint_descriptor *_desc)
{
	dwc_otg_pcd_ep_t *ep = 0;
	dwc_otg_pcd_t *pcd = 0;
	unsigned long flags;
	
	DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, _ep, _desc );

	ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
	if (!_ep || !_desc || ep->desc || 
			_desc->bDescriptorType != USB_DT_ENDPOINT) 
	{
		DWC_WARN( "%s, bad ep or descriptor\n", __func__);
		return -EINVAL;
	}
	if (ep == &ep->pcd->ep0)
	{
		DWC_WARN("%s, bad ep(0)\n", __func__);
		return -EINVAL;
	}
		
	/* Check FIFO size? */
	if (!_desc->wMaxPacketSize) 
	{
		DWC_WARN("%s, bad %s maxpacket\n", __func__, _ep->name);
		return -ERANGE;
	}

	pcd = ep->pcd;
	if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) 
	{
		if (!pcd->driver) {
			bh_otg_dbg2("[%s:%d] gadget[%s] !pcd->driver\n", __FUNCTION__, __LINE__, pcd->gadget.name);
		}
		if (pcd->gadget.speed == USB_SPEED_UNKNOWN) {
			bh_otg_dbg2("[%s:%d] gadget[%s] USB_SPEED_UNKNOWN\n", __FUNCTION__, __LINE__, pcd->gadget.name);
		}

	
		DWC_WARN("%s, bogus device state\n", __func__);
		return -ESHUTDOWN;
	}

	SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
		
	ep->desc = _desc;
	ep->ep.maxpacket = le16_to_cpu (_desc->wMaxPacketSize);
		
	/*
	 * Activate the EP
	 */
	ep->stopped = 0;
		
	ep->dwc_ep.is_in = (USB_DIR_IN & _desc->bEndpointAddress) != 0;
	ep->dwc_ep.maxpacket = ep->ep.maxpacket;
	
	ep->dwc_ep.type = _desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;

	if(ep->dwc_ep.is_in)
	{
		if(!pcd->otg_dev->core_if->en_multiple_tx_fifo)
		{
			ep->dwc_ep.tx_fifo_num = 0;
		
			if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
//cathy				USB_ENDPOINT_XFER_ISOC ) 
				USB_ENDPOINT_XFER_INT ) 	//assign interrupt in ep (ep3) to periodic tx fifo
			{
				/* 
				 * if ISOC EP then assign a Periodic Tx FIFO.
				 */
				ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
			 }
		}
		else
		{
			/* 
			 * if Dedicated FIFOs mode is on then assign a Tx FIFO.
			 */
                        ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
	        }		 
	}		 
	/* Set initial data PID. */
	if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
			USB_ENDPOINT_XFER_BULK ) 
	{
		ep->dwc_ep.data_pid_start = 0;	
	}
		
	DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n", 
					ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
					ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc );
		
	dwc_otg_ep_activate( GET_CORE_IF(pcd), &ep->dwc_ep );
	SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
	return 0;
}
Esempio n. 2
0
/**
 * This function is called by the Gadget Driver for each EP to be
 * configured for the current configuration (SET_CONFIGURATION).
 *
 * This function initializes the dwc_otg_ep_t data structure, and then
 * calls dwc_otg_ep_activate.
 */
static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep,
                                 const struct usb_endpoint_descriptor *_desc)
{
        dwc_otg_pcd_ep_t *ep = 0;
        dwc_otg_pcd_t *pcd = 0;
        unsigned long flags;

        DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, _ep, _desc );

        ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
	if (!_ep || !_desc || ep->desc ||
            _desc->bDescriptorType != USB_DT_ENDPOINT) {
		DWC_WARN( "%s, bad ep or descriptor\n", __func__);
		return -EINVAL;
        }
	if (ep == &ep->pcd->ep[0]){
		DWC_WARN("%s, bad ep(0)\n", __func__);
		return -EINVAL;
        }

        /* Check FIFO size? */
	if (!_desc->wMaxPacketSize) {
		DWC_WARN("%s, bad %s maxpacket\n", __func__, _ep->name);
		return -ERANGE;
	}

        pcd = ep->pcd;
	if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) {
		DWC_WARN("%s, bogus device state\n", __func__);
		return -ESHUTDOWN;
	}

        spin_lock_irqsave(&pcd->lock, flags);

	ep->desc = _desc;
	ep->ep.maxpacket = le16_to_cpu (_desc->wMaxPacketSize);

        /*
         * Activate the EP
         */
        ep->stopped = 0;
        ep->dwc_ep.is_in = (USB_DIR_IN & _desc->bEndpointAddress) != 0;
        ep->dwc_ep.maxpacket = ep->ep.maxpacket;
        ep->dwc_ep.tx_fifo_num = 0;
        ep->dwc_ep.type = _desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
        if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
            USB_ENDPOINT_XFER_ISOC ) {
                /*
                 * if ISOC EP then assign a Periodic Tx FIFO.
                 */
                /** @todo NGS Determine Tx FIFO for periodic EP.
                 *  Currently using 1.
                 */
                ep->dwc_ep.tx_fifo_num = 1;
        }
        /* Set initial data PID. */
        if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
            USB_ENDPOINT_XFER_BULK ) {
                ep->dwc_ep.data_pid_start = 0;
        }

        DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n",
                    ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
                    ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc );

        dwc_otg_ep_activate( GET_CORE_IF(pcd), &ep->dwc_ep );
        spin_unlock_irqrestore(&pcd->lock, flags);
        return 0;
}