Ejemplo n.º 1
0
void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
		  struct usb_endpoint_instance *endpoint)
{
	if (0 == id) {
		/* EP0 */
		ep0_endpoint = endpoint;
		ep0_endpoint->endpoint_address = 0xff;
		ep0_urb = usbd_alloc_urb(device, endpoint);
	} else if (MAX_ENDPOINT >= id) {
		int ep_addr;

		/* Check the direction */
		ep_addr = endpoint->endpoint_address;
		if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
			/* IN */
			epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
		} else {
			/* OUT */
			epinfo[id * 2].epsize = endpoint->rcv_packetSize;
		}

		musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo));
	} else {
		if (debug_level > 0)
			serial_printf("ERROR : %s endpoint request %d "
				      "exceeds maximum %d\n",
				      __PRETTY_FUNCTION__, id, MAX_ENDPOINT);
	}
}
Ejemplo n.º 2
0
int blan_start_recv_endpoint(struct usbd_function_instance *function_instance,
                int endpoint_index, otg_atomic_t *recv_urbs_started, char *msg)
{
        struct usb_network_private *npd = function_instance->privdata;
        int i;
        int hs = usbd_high_speed(function_instance);
        int alloc_length = usbd_endpoint_transferSize(function_instance, endpoint_index, hs);

        if (TRACE_VERBOSE)
                TRACE_MSG4(NTT, "endpoint_index: %d recv_urbs_started: %d alloc_length: %d %s",
                                endpoint_index, otg_atomic_read(recv_urbs_started), alloc_length, msg);

        while (otg_atomic_read(recv_urbs_started) < npd->max_recv_urbs ) {
                u8 *os_buffer = NULL;
                void *os_data = NULL;
                struct usbd_urb *urb;

                #ifdef DEBUG_CRC_SEEN
                if (npd->seen_crc_error) {
                        TRACE_MSG0(NTT, "CRC ERROR NOT RESTARTING");
                        break;
                }
                #endif /* DEBUG_CRC_SEEN */

                /* get os buffer - os_buffer is data, os_data is the os data structure */
                os_data = net_os_alloc_buffer(function_instance, &os_buffer, alloc_length);

                /* allocate urb with no buffer */
                /*allocate urb without buffer */
                urb = usbd_alloc_urb(function_instance, endpoint_index, 0, net_fd_recv_urb2);

                /* start urb with buffer pointing at the os_buffer in os_data structure */
                if (os_buffer && urb) {

                        urb->function_privdata = os_data;
                        urb->buffer = os_buffer;
                        urb->flags |= npd->recv_urb_flags;
                        urb->alloc_length = urb->buffer_length = alloc_length;
                        if (usbd_start_out_urb(urb)) {
                                net_os_dealloc_buffer(function_instance, os_data, os_buffer);
                                urb->function_privdata = NULL;
                                urb->buffer = NULL;
                                usbd_free_urb(urb);
                        }
                        otg_atomic_inc(recv_urbs_started);
                        continue;
                }
                TRACE_MSG1(NTT, "recv_urbs_started: %d FAILED EARLY", otg_atomic_read(recv_urbs_started));

                if (os_buffer || os_data)
                        net_os_dealloc_buffer(function_instance, os_data, os_buffer);
                if (urb)
                        urb->buffer = NULL;
                        usbd_free_urb(urb);
                break;
        }
        if (TRACE_VERBOSE)
                TRACE_MSG1(NTT, "recv_urbs_started: %d", otg_atomic_read(recv_urbs_started));
        return 0;
}
Ejemplo n.º 3
0
/* Switch on the UDC */
void udc_enable(struct usb_device_instance *device)
{

	ep0state = EP0_IDLE;

	/* enable endpoint 0, A, B's Packet Complete Interrupt. */
	writel(0xffffffff, UDCICR0);
	writel(0xa8000000, UDCICR1);

	/* clear the interrupt status/control registers */
	writel(0xffffffff, UDCISR0);
	writel(0xffffffff, UDCISR1);

	/* set UDC-enable */
	udc_set_mask_UDCCR(UDCCR_UDE);

	udc_device = device;
	if (!ep0_urb)
		ep0_urb = usbd_alloc_urb(udc_device,
				udc_device->bus->endpoint_array);
	else
		usbinfo("ep0_urb %p already allocated", ep0_urb);

	usbdbg("UDC Enabled\n");
}
Ejemplo n.º 4
0
/*! net_fd_start_recv_ecm - start recv urb(s)
 *
 * @param function_instance - pointer to this function instance
 * @return none
 */
int net_fd_start_recv_ecm(struct usbd_function_instance *function_instance)
{
        struct usb_network_private *npd = function_instance->privdata;
        int i;
        int network_start_urbs = NETWORK_START_URBS;
        int hs = usbd_high_speed(function_instance);
        int endpoint_index = BULK_OUT_A;

        if (hs)
                network_start_urbs = NETWORK_START_URBS * 3;


        for (i = 0; i < network_start_urbs; i++) {
                struct usbd_urb *urb;
                BREAK_IF(!(urb = usbd_alloc_urb(function_instance, endpoint_index,
                                                usbd_endpoint_transferSize(function_instance, endpoint_index, hs),
                                                net_fd_recv_urb)));
                TRACE_MSG5(NTT,"i: %d urb: %p priv: %p npd: %p function: %p",
                                i, urb, urb->function_privdata, npd, function_instance);

                //urb->function_privdata = npd;
                if (usbd_start_out_urb(urb)) {
                        urb->function_privdata = NULL;
                        usbd_free_urb(urb);
                }
        }
        return 0;
}
Ejemplo n.º 5
0
/*! net_fd_start_xmit_nocrc
 * @brief - start sending a buffer
 *
 * @param function_instance - pointer to this function instance
 * @param buffer buffer containing data to send
 * @param len  - length of data to send
 * @param data instance data
 * @return: 0 if all OK
 *         -EINVAL, -EUNATCH, -ENOMEM
 *         rc from usbd_start_in_urb() if that fails (is != 0, may be one of err values above)
 *         Note: -ECOMM is interpreted by calling routine as signal to leave IF stopped.
 */
int net_fd_start_xmit_nocrc (struct usbd_function_instance *function_instance, u8 *buffer, int len, void *data)
{
        struct usb_network_private *npd = function_instance->privdata;
        struct usbd_urb *urb = NULL;
        int rc;
        int in_pkt_sz;
        u8 *cp;
        u32 crc;
        #ifndef CONFIG_OTG_NETWORK_DOUBLE_IN
        int xmit_index = 0;
        int endpoint_index = BULK_IN_A;
        #else /* CONFIG_OTG_NETWORK_DOUBLE_IN */
        int xmit_index = (otg_atomic_read(&npd->xmit_urbs_started[0]) <= otg_atomic_read(&npd->xmit_urbs_started[1]))
                ? 0 : 1;
        int endpoint_index = (xmit_index) ? BULK_IN_B : BULK_IN_A;
        #endif /* CONFIG_OTG_NETWORK_DOUBLE_IN */

        TRACE_MSG7(NTT,"npd: %p function: %p flags: %04x len: %d endpoint_index: %d xmit_started: %d %d",
                        npd, function_instance, npd->flags, len, endpoint_index,
                        otg_atomic_read(&npd->xmit_urbs_started[0]), otg_atomic_read(&npd->xmit_urbs_started[1]));

        in_pkt_sz = usbd_endpoint_wMaxPacketSize(function_instance, endpoint_index, usbd_high_speed(function_instance));

        /* allocate urb 5 bytes larger than required */
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + in_pkt_sz, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                printk(KERN_ERR"%s: urb alloc failed len: %d endpoint: %02x\n", __FUNCTION__, len, epa);
                return -ENOMEM;
        }

        urb->actual_length = len;

        memcpy (urb->buffer, buffer, len);
        urb->function_privdata = data;
        urb->actual_length = len;
        otg_atomic_add(urb->actual_length, &npd->queued_bytes);
        otg_atomic_inc(&npd->xmit_urbs_started[xmit_index]);
        if ((rc = usbd_start_in_urb (urb))) {
                TRACE_MSG1(NTT,"FAILED: %d", rc);
                printk(KERN_ERR"%s: FAILED: %d\n", __FUNCTION__, rc);
                urb->function_privdata = NULL;
                otg_atomic_sub(urb->actual_length, &npd->queued_bytes);
                otg_atomic_dec(&npd->xmit_urbs_started[xmit_index]);
                usbd_free_urb (urb);
                return rc;
        }
        return 0;
}
Ejemplo n.º 6
0
/* Switch on the UDC */
void udc_enable (struct usb_device_instance *device)
{
	debug("enable device %p, status %d\n", device, device->status);

	/* Save the device structure pointer */
	udc_device = device;

	/* Setup ep0 urb */
	if (!ep0_urb)
		ep0_urb = usbd_alloc_urb(udc_device,
					 udc_device->bus->endpoint_array);
	else
		serial_printf("udc_enable: ep0_urb already allocated %p\n",
			       ep0_urb);

	s3c24x0_configure_device(device);
}
/* udc_enable
 *
 * Grab an EP0 URB, register interest in a subset of USB events
 */
void udc_enable (struct usb_device_instance *device)
{
	if (udc_state == STATE_ERROR) {
		return;
	}

	udc_device = device;

	if (!ep_ref[0].urb) {
		ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
	}

	/* Register interest in all events except SOF, enable transceiver */
	usbp->usber = 0x03FF;
	usbp->usbmr = 0x02F7;

	return;
}
Ejemplo n.º 8
0
/* Return     : EOK if ok, error code on error                                      */
int devi_output_control(void * pHandle, pControlRequest pRequest, void * data, int nLen)
{
   int rc = EOK;
   struct usbd_urb * pUrb;
   void * pLocalData = NULL;
   pModule_data_t pModule = (pModule_data_t)pHandle;

   if(NULL == pModule -> ep_cntl)
      return EINVAL;

   if((pRequest -> dir & URB_DIR_OUT) && (nLen > pModule -> ep_cnt_size)) // Too big buffer
      return EINVAL;
   
   if( pUrb = usbd_alloc_urb( NULL ) ) // Allocate request block
      {
      if((pRequest -> dir & URB_DIR_OUT) && (NULL != data) && (nLen > 0) )
	 memcpy(pModule -> ep_cnt_buf, data, nLen); // Take data to USB -allocated buffer
      // Setup vendor request block
      usbd_setup_vendor( 
	      pUrb, 
	      pRequest -> dir, // Direction
	      pRequest -> req, // Device specific request
	      pRequest -> type | 
	      pRequest -> rec, // Type | recipient
	      pRequest -> value, // Request specific
	      pRequest -> index, // Request specific 
	      pModule -> ep_cnt_buf,
	      nLen );
      rc = usbd_io( pUrb, pModule -> ep_cntl, NULL, pModule, USBD_TIME_INFINITY ) ;
      // Delete request block
      usbd_free_urb( pUrb );

      if((pRequest -> dir & URB_DIR_IN) && (EOK == rc))  // Take data from USB -allocated buffer
	    memcpy(data, pLocalData, min(nLen, pModule -> ep_cnt_size));
      }
   else 
      rc = ENOMEM;

   return( rc );
   
}
/* mpc8xx_udc_assign_urb
 *
 * Associate a given urb to an endpoint TX or RX transmit/receive buffers
 */
static int mpc8xx_udc_assign_urb (int ep, char direction)
{
	struct usb_endpoint_instance *epi = 0;

	if (ep >= MAX_ENDPOINTS) {
		goto err;
	}
	epi = &udc_device->bus->endpoint_array[ep];
	if (!epi) {
		goto err;
	}

	if (!ep_ref[ep].urb) {
		ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
		if (!ep_ref[ep].urb) {
			goto err;
		}
	} else {
		ep_ref[ep].urb->actual_length = 0;
	}

	switch (direction) {
	case USB_DIR_IN:
		epi->tx_urb = ep_ref[ep].urb;
		break;
	case USB_DIR_OUT:
		epi->rcv_urb = ep_ref[ep].urb;
		break;
	default:
		goto err;
	}
	return 0;

      err:
	udc_state = STATE_ERROR;
	return -1;
}
Ejemplo n.º 10
0
/*! net_fd_start_xmit_mdlm
 * @brief - start sending a buffer
 *
 * @param function_instance - function instance pointer
 * @param buffer
 * @param len
 * @param data
 *
 * @return: 0 if all OK
 *         -EINVAL, -EUNATCH, -ENOMEM
 *         rc from usbd_start_in_urb() if that fails (is != 0, may be one of err values above)
 *         Note: -ECOMM is interpreted by calling routine as signal to leave IF stopped.
 */
int net_fd_start_xmit_mdlm (struct usbd_function_instance *function_instance, u8 *buffer, int len, void *data)
{
        struct usb_network_private *npd = function_instance->privdata;
        struct usbd_urb *urb = NULL;
        int rc;
        u32 crc;

        #ifndef CONFIG_OTG_NETWORK_DOUBLE_IN
        int xmit_index = 0;
        int endpoint_index = BULK_IN_A;
        #else /* CONFIG_OTG_NETWORK_DOUBLE_IN */
        int xmit_index = (otg_atomic_read(&npd->xmit_urbs_started[0]) <= otg_atomic_read(&npd->xmit_urbs_started[1]))
                ? 0 : 1;
        int endpoint_index = (xmit_index) ? BULK_IN_B : BULK_IN_A;
        #endif /* CONFIG_OTG_NETWORK_DOUBLE_IN */

        int in_pkt_sz = usbd_endpoint_wMaxPacketSize(function_instance, xmit_index, usbd_high_speed(function_instance));

        if (TRACE_VERBOSE)
                TRACE_MSG8(NTT,"npd: %p flags: %04x len: %d endpoint_index: %d "
                                "xmit_index: %d xmit_started: %d %d in_pkt_sz: %d",
                                npd, npd->flags, len, endpoint_index, xmit_index, otg_atomic_read(&npd->xmit_urbs_started[0]),
                                otg_atomic_read(&npd->xmit_urbs_started[1]), in_pkt_sz);

        #if defined(CONFIG_OTG_NETWORK_BLAN_CRC) || defined(CONFIG_OTG_NETWORK_SAFE_CRC)
        /* allocate urb 5 bytes larger than required */
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + 4 + in_pkt_sz, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                return -ENOMEM;
        }

        urb->actual_length = len;

        /* copy and crc len bytes */
        crc = crc32_copy(urb->buffer, buffer, len, CRC32_INIT);

        if ((urb->actual_length % in_pkt_sz) == (in_pkt_sz - 4)) {
                /* no longer in Kconfig - change undef to define to active padbyte */
                #undef CONFIG_OTG_NETWORK_PADBYTE
                #ifdef CONFIG_OTG_NETWORK_PADBYTE
                // add a pad byte if required to ensure a short packet, usbdnet driver
                // will correctly handle pad byte before or after CRC, but the MCCI driver
                // wants it before the CRC.
                crc = crc32_pad(urb->buffer + urb->actual_length, 1, crc);
                urb->actual_length++;
                #else /* CONFIG_OTG_NETWORK_PADBYTE */
                urb->flags |= USBD_URB_SENDZLP;
                TRACE_MSG2(NTT,"setting ZLP: urb: %p flags: %x", urb, urb->flags);
                #endif /* CONFIG_OTG_NETWORK_PADBYTE */
        }
        crc = ~crc;
        urb->buffer[urb->actual_length++] = crc & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 8) & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 16) & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 24) & 0xff;

        #if defined(CONFIG_OTG_NETWORK_BLAN_FERMAT)
        if (npd->fermat) fermat_encode(urb->buffer, urb->actual_length);
        #endif

        #else /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/

        /* allocate urb with no buffer */
        #ifdef CONFIG_OTG_NETWORK_XMIT_OS
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, 0, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                return -ENOMEM;
        }
        urb->actual_length = len;
        urb->buffer = buffer;
        #else /* CONFIG_OTG_NETWORK_XMIT_OS */
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + 4 + in_pkt_sz, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                printk(KERN_ERR"%s: urb alloc failed len: %d endpoint: %02x\n", __FUNCTION__, len, epa);
                return -ENOMEM;
        }
        urb->actual_length = len;
        memcpy (urb->buffer, buffer, len);
        #endif /* CONFIG_OTG_NETWORK_XMIT_OS */

        urb->flags |= ((urb->actual_length % in_pkt_sz) == 0) ? USBD_URB_SENDZLP : 0;

        #endif /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/

        if (TRACE_VERBOSE)
                TRACE_MSG3(NTT,"urb: %p buf: %p priv: %p", urb, data, urb->function_privdata);
        urb->function_privdata = data;

        otg_atomic_add(urb->actual_length, &npd->queued_bytes);
        otg_atomic_inc(&npd->xmit_urbs_started[xmit_index]);
        if ((rc = usbd_start_in_urb (urb))) {

                TRACE_MSG1(NTT,"FAILED: %d", rc);
                printk(KERN_ERR"%s: FAILED: %d\n", __FUNCTION__, rc);
                urb->function_privdata = NULL;
                otg_atomic_sub(urb->actual_length, &npd->queued_bytes);
                otg_atomic_dec(&npd->xmit_urbs_started[xmit_index]);
                usbd_free_urb (urb);

                return rc;
        }
        return 0;
}
Ejemplo n.º 11
0
/**
 * usbd_device_event - called to respond to various usb events
 * @device: pointer to struct device
 * @event: event to respond to
 *
 * Used by a Bus driver to indicate an event.
 */
void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
{
	struct urb *urb;

	usb_device_state_t state;

	if (!device || !device->bus) {
		dbg_usbe (1, "(%p,%d) NULL device or device->bus", device, event);
		return;
	}

	state = device->device_state;

	dbg_usbe (3, "-------------------------------------------------------------------------------------");


        dbg_usbe (1,"%s", USBD_DEVICE_EVENTS(event));

	switch (event) {
	case DEVICE_UNKNOWN:
		break;
	case DEVICE_INIT:
		device->device_state = STATE_INIT;
		break;

	case DEVICE_CREATE:
		device->device_state = STATE_ATTACHED;
		break;

	case DEVICE_HUB_CONFIGURED:
		device->device_state = STATE_POWERED;
		break;

	case DEVICE_RESET:
		device->device_state = STATE_DEFAULT;
		device->address = 0;
		break;

	case DEVICE_ADDRESS_ASSIGNED:
		device->device_state = STATE_ADDRESSED;
		break;

	case DEVICE_CONFIGURED:
		device->device_state = STATE_CONFIGURED;
		break;

	case DEVICE_DE_CONFIGURED:
		device->device_state = STATE_ADDRESSED;
		break;

	case DEVICE_BUS_INACTIVE:
		if (device->status != USBD_CLOSING) {
			device->status = USBD_SUSPENDED;
		}
		break;
	case DEVICE_BUS_ACTIVITY:
		if (device->status != USBD_CLOSING) {
			device->status = USBD_OK;
		}
		break;

	case DEVICE_SET_INTERFACE:
		break;
	case DEVICE_SET_FEATURE:
		break;
	case DEVICE_CLEAR_FEATURE:
		break;

	case DEVICE_POWER_INTERRUPTION:
		device->device_state = STATE_POWERED;
		break;
	case DEVICE_HUB_RESET:
		device->device_state = STATE_ATTACHED;
		break;
	case DEVICE_DESTROY:
		device->device_state = STATE_UNKNOWN;
		break;
	case DEVICE_FUNCTION_PRIVATE:
		break;
	}
	dbg_usbe (3, "%s event: %d oldstate: %d newstate: %d status: %d address: %d", device->name, event, state, device->device_state, device->status, device->address);;

	// tell the bus interface driver
	if (device->bus && device->bus->driver->ops->device_event) {
		dbg_usbe (3, "calling bus->event");
		device->bus->driver->ops->device_event (device, event, data);
	}
#if 0
	if (device->function_instance_array && (device->function_instance_array + port)->function_driver->ops->event) {
		dbg_usbe (3, "calling function->event");
		(device->function_instance_array + port)->function_driver->ops->event (device, event);
	}
#endif

	if (device->ep0 && device->ep0->function_driver->ops->event) {
		dbg_usbe (3, "calling ep0->event");
		device->ep0->function_driver->ops->event (device, event, data);
	}
#if 0
	// tell the bus interface driver
	if (device->bus && device->bus->driver->ops->device_event) {
		dbg_usbe (3, "calling bus->event");
		device->bus->driver->ops->device_event (device, event);
	}
#endif

	// dbg_usbe(0, "FINISHED - NO FUNCTION BH");
	// return;

	// XXX
	// queue an urb to endpoint zero 

        dbg_usbe(1,"queueing event urb");
	if ((urb = usbd_alloc_urb (device, device->function_instance_array, 0, 0))) {
		urb->event = event;
		urb->data = data;
		urb_append_irq (&(urb->endpoint->events), urb);
		usbd_schedule_function_bh (device);
	}
	dbg_usbe (5, "FINISHED");
	return;
}
Ejemplo n.º 12
0
/* Return     : None                                                                */
void insertion( struct usbd_connection *pConnection, usbd_device_instance_t *pInstance )
{
   int rc;
   struct usbd_device * pDevice;
   pModule_data_t pModule, * ppModule;
   
   if(verbosity)
     printf("Try to inser device\n");
   if( EOK != (rc = usbd_attach( pConnection, pInstance, sizeof(module_data_t **), &pDevice ) ))
     {
     char * pMsgTxt = "Error: cannot attach USB device #%i (error code is %i)\n";
     fprintf(stderr, pMsgTxt, (int)(pInstance -> devno), rc);
     slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt, (int)(pInstance -> devno), rc);
     return;
     }
   ppModule = (pModule_data_t *)usbd_device_extra(pDevice);
	
	
   // Try to find if somebody cares about keyboard reports
   for(pModule = LIST_FIRST_ITEM(&modList); NULL != pModule; pModule = LIST_NEXT_ITEM(pModule, lst_conn))
        {
	// Check device number if specified
        if( (USBD_CONNECT_WILDCARD != pModule -> nDev) && (pModule -> nDev != pInstance -> devno))
	     continue;

        if( (USBD_CONNECT_WILDCARD != pModule -> nVendor) && (pModule -> nVendor != pInstance -> ident.vendor))
             continue; // Wrong vendor - ignore
	   
        if((USBD_CONNECT_WILDCARD != pModule -> nClass) && (pModule -> nClass != pInstance -> ident.dclass))
             continue;
   
        if((USBD_CONNECT_WILDCARD != pModule -> nSubClass) && (pModule -> nSubClass != pInstance -> ident.subclass))
             continue;

	pModule -> pInstance = pInstance;
	pModule -> pDevice   = pDevice;
        if( EOK == parse_descriptors( pModule) )
	   {
	   if( pModule -> ep_int_buf = usbd_alloc( pModule -> ep_int_size ) )
	      {
	      if( pModule -> urb = usbd_alloc_urb( NULL ) )
		 {
		 // Initialize request block
		 usbd_setup_interrupt( pModule -> urb,  
				      URB_DIR_IN, 
				      pModule -> ep_int_buf, 
				      pModule->ep_int_size );
		 // Initialize Interrupt callback function
		 if( EOK == usbd_io( pModule -> urb, 
				   pModule -> ep_int, 
				   usb_dev_int, 
				   pModule, USBD_TIME_INFINITY ) ) 
		      {
		      pModule -> flags |= USB_DEVICE_ON |  USB_DEVICE_PRESENT;
		      *ppModule = pModule;
                      if(verbosity)
                         printf("Attach device\n");
		      return;
		      }
		 else
		      {
                      if(verbosity)
                         printf("Cannot attach device\n");
		      }
		 }
               usbd_free( pModule -> ep_int_buf );
	       }
	   usbd_detach( pDevice );
	   }
         }
}