Beispiel #1
0
/*!
    \brief      the handle function of HOST_DEV_ATTACHED state
    \param[in]  pudev: pointer to usb device
    \param[in]  puhost: pointer to usb host
    \param[in]  pustate: pointer to usb state driver
    \param[out] none
    \retval     none
*/
static void host_dev_attached_handle (usb_core_handle_struct *pudev, 
                                      usbh_host_struct *puhost, 
                                      usbh_state_handle_struct *pustate)
{
    puhost->usr_cb->device_connected();
    puhost->control.hc_out_num = usbh_channel_alloc(pudev, 0x00U);
    puhost->control.hc_in_num = usbh_channel_alloc(pudev, 0x80U);

    /* reset usb device */
    if (0U == usb_port_reset(pudev)) {
        puhost->usr_cb->device_reset();

        /* wait for USB USBH_ISR_PrtEnDisableChange()
         * host is now ready to start the enumeration
         */
        puhost->device.speed = (uint8_t)USB_CURRENT_SPEED_GET();
        puhost->usr_cb->device_speed_detected(puhost->device.speed);

        /* open IN control pipes */
        usbh_channel_open (pudev,
                           puhost->control.hc_in_num,
                           puhost->device.address,
                           puhost->device.speed,
                           USB_EPTYPE_CTRL,
                           (uint16_t)puhost->control.ep0_size);

        /* open OUT control pipes */
        usbh_channel_open (pudev,
                           puhost->control.hc_out_num,
                           puhost->device.address,
                           puhost->device.speed,
                           USB_EPTYPE_CTRL,
                           (uint16_t)puhost->control.ep0_size);

        scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ENUM, pustate->usbh_current_state);
    }
}
Beispiel #2
0
static int fhci_hub_control(struct usb_hcd *hcd,
			    u16 typeReq,
			    u16 wValue, u16 wIndex, char *buf, u16 wLength)
{
	struct fhci_hcd *fhci = hcd_to_fhci(hcd);
	int retval = 0;
	int len = 0;
	struct usb_hub_status *hub_status;
	struct usb_port_status *port_status;
	unsigned long flags;

	local_irq_save(flags);
	_raw_spin_lock(&fhci->lock);

	fhci_dbg(fhci, "-> %s\n", __func__);

	switch (typeReq) {
	case ClearHubFeature:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
		case C_HUB_OVER_CURRENT:
			break;
		default:
			goto error;
		}
		break;
	case ClearPortFeature:
		fhci->vroot_hub->feature &= (1 << wValue);

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_ENABLE;
			usb_port_disable(fhci);
			break;
		case USB_PORT_FEAT_C_ENABLE:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_ENABLE;
			break;
		case USB_PORT_FEAT_SUSPEND:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_SUSPEND;
			fhci_stop_sof_timer(fhci);
			break;
		case USB_PORT_FEAT_C_SUSPEND:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_SUSPEND;
			break;
		case USB_PORT_FEAT_POWER:
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_POWER;
			config_transceiver(fhci, FHCI_OP_POWER_OFF);
			break;
		case USB_PORT_FEAT_C_CONNECTION:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_CONNECTION;
			break;
		case USB_PORT_FEAT_C_OVER_CURRENT:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_OVERCURRENT;
			break;
		case USB_PORT_FEAT_C_RESET:
			fhci->vroot_hub->port.wPortChange &=
			    ~USB_PORT_STAT_C_RESET;
		default:
			goto error;
		}
		break;
	case GetHubDescriptor:
		memcpy(buf, root_hub_des, sizeof(root_hub_des));
		buf[3] = 0x11; /* per-port power, no ovrcrnt */
		len = (buf[0] < wLength) ? buf[0] : wLength;
		break;
	case GetHubStatus:
		hub_status = (struct usb_hub_status *)buf;
		hub_status->wHubStatus =
		    cpu_to_le16(fhci->vroot_hub->hub.wHubStatus);
		hub_status->wHubChange =
		    cpu_to_le16(fhci->vroot_hub->hub.wHubChange);
		len = 4;
		break;
	case GetPortStatus:
		port_status = (struct usb_port_status *)buf;
		port_status->wPortStatus =
		    cpu_to_le16(fhci->vroot_hub->port.wPortStatus);
		port_status->wPortChange =
		    cpu_to_le16(fhci->vroot_hub->port.wPortChange);
		len = 4;
		break;
	case SetHubFeature:
		switch (wValue) {
		case C_HUB_OVER_CURRENT:
		case C_HUB_LOCAL_POWER:
			break;
		default:
			goto error;
		}
		break;
	case SetPortFeature:
		fhci->vroot_hub->feature |= (1 << wValue);

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_ENABLE;
			usb_port_enable(fhci->usb_lld);
			break;
		case USB_PORT_FEAT_SUSPEND:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_SUSPEND;
			fhci_stop_sof_timer(fhci);
			break;
		case USB_PORT_FEAT_RESET:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_RESET;
			usb_port_reset(fhci->usb_lld);
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_ENABLE;
			fhci->vroot_hub->port.wPortStatus &=
			    ~USB_PORT_STAT_RESET;
			break;
		case USB_PORT_FEAT_POWER:
			fhci->vroot_hub->port.wPortStatus |=
			    USB_PORT_STAT_POWER;
			config_transceiver(fhci, FHCI_OP_POWER_ON);
			break;
		default:
			goto error;
		}
		break;
	default:
error:
		retval = -EPIPE;
	}

	fhci_dbg(fhci, "<- %s\n", __func__);

	_raw_spin_unlock(&fhci->lock);
	local_irq_restore(flags);

	return retval;
}