Exemple #1
0
/*
 * Called from process context when the hub is gone.
 * Detach all devices on active ports.
 */
int
uhub_detach(struct device *self, int flags)
{
	struct uhub_softc *sc = (struct uhub_softc *)self;
	struct usbd_hub *hub = sc->sc_hub->hub;
	struct usbd_port *rup;
	int port;

	if (hub == NULL)		/* Must be partially working */
		return (0);

	usbd_abort_pipe(sc->sc_ipipe);
	usbd_close_pipe(sc->sc_ipipe);

	for (port = 0; port < hub->nports; port++) {
		rup = &hub->ports[port];
		if (rup->device != NULL) {
			usbd_detach(rup->device, self);
			rup->device = NULL;
		}
	}

	if (hub->ports[0].tt)
		free(hub->ports[0].tt, M_USBDEV, 0);
	if (sc->sc_statusbuf)
		free(sc->sc_statusbuf, M_USBDEV, 0);
	if (hub->ports)
		free(hub->ports, M_USBDEV, 0);
	free(hub, M_USBDEV, 0);
	sc->sc_hub->hub = NULL;

	return (0);
}
/* Comment    : Must be called before any other devi_hid... function                */
void devi_unregister_usb_client(void * h)
{
   int rc;
   pModule_data_t pModule = (pModule_data_t)h;
   struct timespec t;
   
   assert(pModule);

   
   if(pModule -> ep_int)
     {
     usbd_reset_pipe(pModule -> ep_int);
     usbd_abort_pipe(pModule -> ep_int);
     }

   if(pModule -> ep_cntl)
     usbd_abort_pipe(pModule -> ep_cntl);

   if(pModule -> urb)
     usbd_free_urb(pModule -> urb);
   
   if(pModule -> ep_int_buf)
     usbd_free(pModule -> ep_int_buf);
   
   if(pModule -> ep_cnt_buf)
     usbd_free(pModule -> ep_cnt_buf);

   sleep(1);
   
   if(EOK != (rc = usbd_detach(pModule -> pDevice)))
     {
     if(verbosity)
	fprintf(stderr, "Detach device: error %i\n", rc);
     }
   
   clock_gettime(CLOCK_REALTIME, &t);
   t.tv_sec += MAX_TIME_WAIT;
   if(EOK !=  pthread_mutex_timedlock(&mod_mutex, &t))
      return ;
   
   LIST_REMOVE(pModule, lst_conn);
  
   pthread_mutex_unlock(&mod_mutex);

   free(pModule);

}
/* Return     : None                                                                */
void removal( struct usbd_connection * pConnection, usbd_device_instance_t * pInstance )
{
   struct usbd_device	* pDevice;
   pModule_data_t pModule;
   int rc;

   if(NULL != ( pDevice = usbd_device_lookup( pConnection, pInstance )))
      {
      pModule = usbd_device_extra( pDevice );
      if( pModule -> ep_int ) 
	   {						// Stop the Interrupt In endpoint
	   usbd_abort_pipe( pModule -> ep_int );        // Abort pipe
	   usbd_free_urb( pModule -> urb );             // Free request block
	   usbd_free( pModule -> ep_int_buf );
	   if( rc = usbd_detach( pModule -> pDevice ) ) 
		fprintf( stderr, "usbd_detach %i\n", rc );
	   }
      }
}
Exemple #4
0
int
uhub_port_connect(struct uhub_softc *sc, int port, int status, int change)
{
	struct usbd_port *up = &sc->sc_hub->hub->ports[port-1];
	int speed;

	/* We have a connect status change, handle it. */
	usbd_clear_port_feature(sc->sc_hub, port, UHF_C_PORT_CONNECTION);

	/*
	 * If there is already a device on the port the change status
	 * must mean that is has disconnected.  Looking at the
	 * current connect status is not enough to figure this out
	 * since a new unit may have been connected before we handle
	 * the disconnect.
	 */
	if (up->device != NULL) {
		/* Disconnected */
		usbd_detach(up->device, &sc->sc_dev);
		up->device = NULL;
	}

	/* Nothing connected, just ignore it. */
	if ((status & UPS_CURRENT_CONNECT_STATUS) == 0)
		return (0);

	/* Connected */
	if ((status & (UPS_PORT_POWER|UPS_PORT_POWER_SS)) == 0) {
		printf("%s: connected port %d has no power\n", DEVNAME(sc),
		    port);
		return (-1);
	}

	/* Wait for maximum device power up time. */
	usbd_delay_ms(sc->sc_hub, USB_PORT_POWERUP_DELAY);

	/* Reset port, which implies enabling it. */
	if (usbd_reset_port(sc->sc_hub, port)) {
		printf("%s: port %d reset failed\n", DEVNAME(sc), port);
		return (-1);
	}
	/* Get port status again, it might have changed during reset */
	if (usbd_get_port_status(sc->sc_hub, port, &up->status))
		return (-1);

	status = UGETW(up->status.wPortStatus);
	change = UGETW(up->status.wPortChange);
	DPRINTF("%s: port %d status=0x%04x change=0x%04x\n", DEVNAME(sc),
	    port, status, change);

	/* Nothing connected, just ignore it. */
	if ((status & UPS_CURRENT_CONNECT_STATUS) == 0) {
		DPRINTF("%s: port %d, device disappeared after reset\n",
		    DEVNAME(sc), port);
		return (-1);
	}

	/*
	 * Figure out device speed.  This is a bit tricky because
	 * UPS_PORT_POWER_SS and UPS_LOW_SPEED share the same bit.
	 */
	if ((status & UPS_PORT_POWER) == 0)
		status &= ~UPS_PORT_POWER_SS;

	if (status & UPS_HIGH_SPEED)
		speed = USB_SPEED_HIGH;
	else if (status & UPS_LOW_SPEED)
		speed = USB_SPEED_LOW;
	else {
		/*
		 * If there is no power bit set, it is certainly
		 * a Super Speed device, so use the speed of its
		 * parent hub.
		 */
		if (status & UPS_PORT_POWER)
			speed = USB_SPEED_FULL;
		else
			speed = sc->sc_hub->speed;
	}

	/*
	 * Reduce the speed, otherwise we won't setup the proper
	 * transfer methods.
	 */
	if (speed > sc->sc_hub->speed)
		speed = sc->sc_hub->speed;

	/* Get device info and set its address. */
	if (usbd_new_device(&sc->sc_dev, sc->sc_hub->bus, sc->sc_hub->depth + 1,
	    speed, port, up)) {
		/*
		 * The unit refused to accept a new address, or had
		 * some other serious problem.  Since we cannot leave
		 * at 0 we have to disable the port instead.
		 */
		printf("%s: device problem, disabling port %d\n", DEVNAME(sc),
		    port);
		usbd_clear_port_feature(sc->sc_hub, port, UHF_PORT_ENABLE);

		return (-1);
	}

	return (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 );
	   }
         }
}