コード例 #1
0
int hub_port_resume( struct rt_urb *p_urb, __u16 port_nr)
{
  int tries = 100;
  int us_delay = 10000;
  portstat_t pstat;

  if( hub_get_portstat( p_urb, port_nr, &pstat) ){
    return -1;
  }

  if( !pstat.stat.port_suspend ){
    return 0;
  }

  if( hub_clear_port_feature( p_urb, port_nr, PORT_SUSPEND) ){
    return -1;
  }

  do{
    udelay(us_delay);
    if( hub_get_portstat( p_urb, port_nr, &pstat) ){
      return -1;
    }
  } while( tries-- && !pstat.change.c_port_suspend );

  if(!tries){
    return(-1);
  }

  hub_clear_port_feature( p_urb, port_nr, C_PORT_SUSPEND);
  return 0;
}
コード例 #2
0
struct usb_device *usb_poll_hub_port( struct rt_urb *p_urb, __u8 hub_port_nr )
{
  struct usb_device *p_new_dev  = NULL;
  portstat_t p_pstat;
  struct rt_urb *p_urb_save     = NULL;
  struct usb_device *p_usbdev_save = NULL;

  if(! p_urb || !p_urb->p_usbdev || !p_urb->p_usbdev->p_hcd){
    if (!p_urb)                           ERR("[ERROR] %s - Invalid URB-Pointer \n", __FUNCTION__);
    if (!p_urb->p_usbdev)                 ERR("[ERROR] %s - Invalid USB-Device-Pointer \n", __FUNCTION__);
    if (!p_urb->p_usbdev->p_hcd)          ERR("[ERROR] %s - Invalid Host-Controller-Pointer \n", __FUNCTION__);
    return NULL;
  }

  if (hub_get_portstat( p_urb, hub_port_nr, &p_pstat)){
    ERR_MSG2(p_urb->p_hcd,p_urb->p_usbdev," %s - Get Portstat for Port[%d] failed \n",__FUNCTION__, hub_port_nr);
    return NULL;
  }

  dump_portstatus( p_urb->p_usbdev, hub_port_nr, &p_pstat);

  if( p_pstat.change.c_port_connection ) {  /* Connection detect */
    if( hub_clear_port_feature( p_urb , hub_port_nr, C_PORT_CONNECTION) ){
      return NULL;
    }
    if( p_pstat.stat.port_connection){

      hub_port_resume( p_urb ,hub_port_nr);
      hub_port_reset( p_urb ,hub_port_nr);
      udelay(10);

      // unregister hub_urb
      p_urb_save    = p_urb;
      p_usbdev_save = p_urb->p_usbdev;
      nrt_usb_unregister_urb(p_urb);

      p_new_dev = nrt_usb_config_dev( p_urb->p_hcd, p_urb->p_usbdev->rh_port, p_pstat.stat.port_lowspeed);

      // re-register hub_urb
      p_urb = p_urb_save;
      p_urb->p_usbdev = p_usbdev_save;
      p_urb->p_hcd = p_usbdev_save->p_hcd;
      nrt_usb_register_urb(p_urb);

      return p_new_dev;

    }

    hub_set_port_feature(   p_urb, hub_port_nr, PORT_SUSPEND );
    hub_clear_port_feature( p_urb, hub_port_nr, PORT_ENABLE  );

  }

  return NULL;
}
コード例 #3
0
int hub_port_reset( struct rt_urb *p_urb, __u16 port_nr)
{
  int tries = 100;
  int us_delay = 10000;
  portstat_t pstat;

  if( hub_set_port_feature( p_urb, port_nr, PORT_RESET) ){
    return -1;
  }

  do{
    udelay(us_delay);
    if( hub_get_portstat( p_urb, port_nr, &pstat) ){
      return -1;
    }
  } while( tries-- && !pstat.change.c_port_reset );

  if(!tries){
    return(-1);
  }

  hub_clear_port_feature( p_urb, port_nr, C_PORT_RESET);
  return 0;
}
コード例 #4
0
ファイル: vsfusbh_HUB.c プロジェクト: hank-fan/vsf
static vsf_err_t hub_reset_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data;
	struct vsfusbh_urb_t *vsfurb = hub->vsfurb;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	hub->retry = 0;

	do
	{
		/* send command to reset port */
		vsfurb->transfer_buffer = NULL;
		vsfurb->transfer_length = 0;
		err = hub_set_port_feature(hub->usbh, vsfurb, hub->counter,
				USB_PORT_FEAT_RESET);
		if (err != VSFERR_NONE)
			return err;
		vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
		if (vsfurb->status != URB_OK)
			return VSFERR_FAIL;

		/* delay 100ms after port reset*/
		vsfsm_pt_delay(pt, 100);

		// clear reset
		vsfurb->transfer_buffer = NULL;
		vsfurb->transfer_length = 0;
		err = hub_clear_port_feature(hub->usbh, vsfurb,
				hub->counter, USB_PORT_FEAT_C_RESET);
		if (err != VSFERR_NONE)
			return err;
		vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
		if (vsfurb->status != URB_OK)
			return VSFERR_FAIL;

		/* delay 100ms after port reset*/
		vsfsm_pt_delay(pt, 50);

		/* get port status for check */
		vsfurb->transfer_buffer = &hub->hub_portsts;
		vsfurb->transfer_length = sizeof(hub->hub_portsts);
		err = hub_get_port_status(hub->usbh, vsfurb, hub->counter);
		if (err != VSFERR_NONE)
			return err;
		vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
		if (vsfurb->status != URB_OK)
			return VSFERR_FAIL;

		/* check port status after reset */
		if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_ENABLE)
		{
			return VSFERR_NONE;
		}
		else
		{
			/* delay 200ms for next reset*/
			vsfsm_pt_delay(pt, 200);
		}

	} while (hub->retry++ <= 3);

	vsfsm_pt_end(pt);
	return VSFERR_FAIL;
}
コード例 #5
0
ファイル: vsfusbh_HUB.c プロジェクト: hank-fan/vsf
static vsf_err_t hub_scan_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	vsf_err_t err;
	struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data;
	struct vsfusbh_urb_t *vsfurb = hub->vsfurb;

	vsfsm_pt_begin(pt);

	do
	{
		hub->counter = 1;
		do
		{
			// get port status
			vsfurb->transfer_buffer = &hub->hub_portsts;
			vsfurb->transfer_length = sizeof(hub->hub_portsts);
			err = hub_get_port_status(hub->usbh, vsfurb, hub->counter);
			if (err != VSFERR_NONE)
				return err;
			vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
			if (vsfurb->status != URB_OK)
				return VSFERR_FAIL;

			if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_CONNECTION)
			{
				// try to connect
				vsfsm_pt_wfpt(pt, &hub->drv_connect_pt);
			}
			else if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_ENABLE)
			{
				vsfurb->transfer_buffer = NULL;
				vsfurb->transfer_length = 0;
				err = hub_clear_port_feature(hub->usbh, vsfurb,
						hub->counter, USB_PORT_FEAT_C_ENABLE);
				if (err != VSFERR_NONE)
					return err;
				vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
				if (vsfurb->status != URB_OK)
					return VSFERR_FAIL;

				hub->hub_portsts.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
			}

			if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_SUSPEND)
			{
				vsfurb->transfer_buffer = NULL;
				vsfurb->transfer_length = 0;
				err = hub_clear_port_feature(hub->usbh, vsfurb,
						hub->counter, USB_PORT_FEAT_C_SUSPEND);
				if (err != VSFERR_NONE)
					return err;
				vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
				if (vsfurb->status != URB_OK)
					return VSFERR_FAIL;

				hub->hub_portsts.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
			}
			if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_OVERCURRENT)
			{
				vsfurb->transfer_buffer = NULL;
				vsfurb->transfer_length = 0;
				err = hub_clear_port_feature(hub->usbh, vsfurb,
						hub->counter, USB_PORT_FEAT_C_OVER_CURRENT);
				if (err != VSFERR_NONE)
					return err;
				vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
				if (vsfurb->status != URB_OK)
					return VSFERR_FAIL;

				hub->hub_portsts.wPortChange &= ~USB_PORT_FEAT_C_OVER_CURRENT;

				// TODO : power every port
			}
			if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_RESET)
			{
				vsfurb->transfer_buffer = NULL;
				vsfurb->transfer_length = 0;
				err = hub_clear_port_feature(hub->usbh, vsfurb,
						hub->counter, USB_PORT_FEAT_C_RESET);
				if (err != VSFERR_NONE)
					return err;
				vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
				if (vsfurb->status != URB_OK)
					return VSFERR_FAIL;

				hub->hub_portsts.wPortChange &= ~USB_PORT_FEAT_C_RESET;
			}
		} while (hub->counter++ < hub->dev->maxchild);

		// TODO : poll hub status

		vsfsm_pt_delay(pt, 500);
	} while (1);
	vsfsm_pt_end(pt);

	return VSFERR_NONE;
}
コード例 #6
0
ファイル: vsfusbh_HUB.c プロジェクト: hank-fan/vsf
static vsf_err_t hub_connect_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	vsf_err_t err;
	struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data;
	struct vsfusbh_urb_t *vsfurb = hub->vsfurb;
	struct vsfusbh_device_t *dev;

	vsfsm_pt_begin(pt);

	/* clear the cnnection change state */
	vsfurb->transfer_buffer = NULL;
	vsfurb->transfer_length = 0;
	err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter,
			USB_PORT_FEAT_C_CONNECTION);
	if (err != VSFERR_NONE)
		return err;
	vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
	if (vsfurb->status != URB_OK)
		return VSFERR_FAIL;

	if (hub->dev->children[hub->counter - 1] != NULL)
	{
		vsfusbh_disconnect_device(hub->usbh,
				&hub->dev->children[hub->counter - 1]);
	}

	if (!(hub->hub_portsts.wPortStatus & USB_PORT_STAT_CONNECTION))
	{
		if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_ENABLE)
		{
			vsfurb->transfer_buffer = NULL;
			vsfurb->transfer_length = 0;
			err = hub_clear_port_feature(hub->usbh, vsfurb,
					hub->counter, USB_PORT_FEAT_ENABLE);
			if (err != VSFERR_NONE)
				return err;
			vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE);
			if (vsfurb->status != URB_OK)
				return VSFERR_FAIL;
		}

		return VSFERR_NONE;
	}

	if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED)
	{
		vsfsm_pt_delay(pt, 200);
	}

	vsfsm_pt_wfpt(pt, &hub->drv_reset_pt);

	vsfsm_pt_delay(pt, 200);

	// wait for new_dev free
	while (hub->usbh->new_dev != NULL)
	{
		vsfsm_pt_delay(pt, 200);
	}

	dev = vsfusbh_alloc_device(hub->usbh);
	if (NULL == dev)
		return VSFERR_FAIL;

	if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED)
	{
		dev->speed = USB_SPEED_LOW;
		dev->slow = 1;
	}
	else if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_HIGH_SPEED)
		dev->speed = USB_SPEED_HIGH;
	else
		dev->speed = USB_SPEED_FULL;

	hub->dev->children[hub->counter - 1] = dev;
	dev->parent = hub->dev;

	hub->usbh->new_dev = dev;
	vsfsm_post_evt_pending(&hub->usbh->sm, VSFSM_EVT_NEW_DEVICE);

	vsfsm_pt_end(pt);

	return VSFERR_NONE;
}