/* * For each usb hub device in the system check to see if it is in the * peer domain of the given port_dev, and if it is check to see if it * has a port that matches the given port by location */ static int match_location(struct usb_device *peer_hdev, void *p) { int port1; struct usb_hcd *hcd, *peer_hcd; struct usb_port *port_dev = p, *peer; struct usb_hub *peer_hub = usb_hub_to_struct_hub(peer_hdev); struct usb_device *hdev = to_usb_device(port_dev->dev.parent->parent); if (!peer_hub) return 0; hcd = bus_to_hcd(hdev->bus); peer_hcd = bus_to_hcd(peer_hdev->bus); /* peer_hcd is provisional until we verify it against the known peer */ if (peer_hcd != hcd->shared_hcd) return 0; for (port1 = 1; port1 <= peer_hdev->maxchild; port1++) { peer = peer_hub->ports[port1 - 1]; if (peer && peer->location == port_dev->location) { link_peers_report(port_dev, peer); return 1; /* done */ } } return 0; }
void usb_poll(struct usb_bus *bus) { #ifdef CONFIG_USB_OTG_HOST_RTL8672 unsigned long flags; struct usb_hcd *hcd=bus_to_hcd(bus); dwc_otg_hcd_t *otg_hcd = (struct dwc_otg_hcd_t *)hcd->hcd_priv; spin_lock_irqsave (&otg_hcd->lock, flags); dwc_otg_async(otg_hcd, 0); dwc_otg_hcd_handle_sof_intr (otg_hcd); spin_unlock_irqrestore (&otg_hcd->lock, flags); return; #else #ifdef __LINUX_2_6__ unsigned long flags=0; struct usb_hcd *hcd=bus_to_hcd(bus); struct ehci_hcd *ehci=(struct ehci_hcd *)hcd->hcd_priv; spin_lock_irqsave (&ehci->lock, flags); ehci_irq(hcd); spin_unlock_irqrestore (&ehci->lock, flags); #else struct usb_hcd *hcd=bus_to_hcd(priv->udev->bus); ehci_irq(hcd, NULL); #endif return; #endif }
static ssize_t bcmpmu_otg_xceiv_vbus_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_hcd *hcd; ssize_t result = 0; unsigned int val; struct bcmpmu_otg_xceiv_data *xceiv_data = dev_get_drvdata(dev); int error; hcd = bus_to_hcd(xceiv_data->otg_xceiver.xceiver.host); result = sscanf(buf, "%02x\n", &val); if (result != 1) { result = -EINVAL; } else if (val == 0) { dev_info(xceiv_data->dev, "Clearing PORT_POWER feature\n"); error = hcd->driver->hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, NULL, 0); if (error) dev_err(xceiv_data->dev, "Failed to clear PORT_POWER feature\n"); } else { dev_info(xceiv_data->dev, "Setting PORT_POWER feature\n"); error = hcd->driver->hub_control(hcd, SetPortFeature, USB_PORT_FEAT_POWER, 1, NULL, 0); if (error) dev_err(xceiv_data->dev, "Failed to set PORT_POWER feature\n"); } return result < 0 ? result : count; }
static int ehci_zynq_otg_stop_host(struct usb_phy *otg) { struct usb_hcd *hcd = bus_to_hcd(otg->otg->host); usb_remove_hcd(hcd); return 0; }
void hcd_buffer_free( struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); int i; if (!addr) return; if (!bus->controller->dma_mask && !(hcd->driver->flags & HCD_LOCAL_MEM)) { kfree(addr); return; } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) { dma_pool_free(hcd->pool [i], addr, dma); return; } } dma_free_coherent(hcd->self.controller, size, addr, dma); }
static int ehci_xusbps_otg_stop_host(struct otg_transceiver *otg) { struct usb_hcd *hcd = bus_to_hcd(otg->host); usb_remove_hcd(hcd); return 0; }
static void msm_hsusb_start_host(struct usb_bus *bus, int start) { struct usb_hcd *hcd = bus_to_hcd(bus); struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd); mhcd->flags = start ? REQUEST_START : REQUEST_STOP; schedule_work(&mhcd->otg_work); }
static int ehci_zynq_otg_start_host(struct usb_phy *otg) { struct usb_hcd *hcd = bus_to_hcd(otg->otg->host); struct zynq_otg *xotg = xceiv_to_xotg(hcd->usb_phy); usb_add_hcd(hcd, xotg->irq, IRQF_SHARED); return 0; }
static int ehci_xusbps_otg_start_host(struct otg_transceiver *otg) { struct usb_hcd *hcd = bus_to_hcd(otg->host); struct xusbps_otg *xotg = xceiv_to_xotg(hcd_to_ehci(hcd)->transceiver); usb_add_hcd(hcd, xotg->irq, IRQF_SHARED | IRQF_DISABLED); return 0; }
/** * exynos_drd_switch_start_host - helper function for starting/stoping the host * controller driver. * * @otg: Pointer to the usb_otg structure. * @on: start / stop the host controller driver. * * Returns 0 on success otherwise negative errno. */ static int exynos_drd_switch_start_host(struct usb_otg *otg, int on) { struct exynos_drd_switch *drd_switch = container_of(otg, struct exynos_drd_switch, otg); struct usb_hcd *hcd; struct device *xhci_dev; int ret = 0; if (!otg->host) return -EINVAL; dev_dbg(otg->phy->dev, "Turn %s host %s\n", on ? "on" : "off", otg->host->bus_name); hcd = bus_to_hcd(otg->host); xhci_dev = hcd->self.controller; if (on) { #if !defined(CONFIG_USB_HOST_NOTIFY) wake_lock(&drd_switch->wakelock); #endif /* * Clear runtime_error flag. The flag could be * set when user space accessed the host while DRD * was in B-Dev mode. */ pm_runtime_disable(xhci_dev); if (pm_runtime_status_suspended(xhci_dev)) pm_runtime_set_suspended(xhci_dev); else pm_runtime_set_active(xhci_dev); pm_runtime_enable(xhci_dev); ret = pm_runtime_get_sync(xhci_dev); if (ret < 0 && ret != -EINPROGRESS) { pm_runtime_put_noidle(xhci_dev); goto err; } exynos_drd_switch_ases_vbus_ctrl(drd_switch, 1); } else { exynos_drd_switch_ases_vbus_ctrl(drd_switch, 0); ret = pm_runtime_put_sync(xhci_dev); if (ret == -EAGAIN) pm_runtime_get_noresume(xhci_dev); #if !defined(CONFIG_USB_HOST_NOTIFY) else wake_unlock(&drd_switch->wakelock); #endif } err: /* ret can be 1 after pm_runtime_get_sync */ return (ret < 0) ? ret : 0; }
void usb_receive_all_pkts(struct rtl8190_priv *priv) { #ifdef CONFIG_USB_OTG_HOST_RTL8672 usb_scan_async(priv->udev->bus, 1); #else #ifdef __LINUX_2_6__ unsigned long flags=0; struct usb_hcd *hcd=bus_to_hcd(priv->udev->bus); struct ehci_hcd *ehci=(struct ehci_hcd *)hcd->hcd_priv; spin_lock_irqsave (&ehci->lock, flags); ehci_irq(hcd); spin_unlock_irqrestore (&ehci->lock, flags); #else struct usb_hcd *hcd=bus_to_hcd(priv->udev->bus); ehci_irq(hcd, NULL); #endif #endif }
void usb_scan_async(struct usb_bus *bus, unsigned wlan_close) { unsigned long flags; struct usb_hcd *hcd=bus_to_hcd(bus); dwc_otg_hcd_t *otg_hcd = (struct dwc_otg_hcd_t *)hcd->hcd_priv; spin_lock_irqsave (&otg_hcd->lock, flags); dwc_otg_async(otg_hcd, wlan_close); spin_unlock_irqrestore (&otg_hcd->lock, flags); }
static int usb_amd_resume_quirk(struct usb_device *udev) { struct usb_hcd *hcd; hcd = bus_to_hcd(udev->bus); /* The device should be attached directly to root hub */ if (udev->level == 1 && hcd->amd_resume_bug == 1) return 1; return 0; }
static ssize_t store_ehci_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_hcd *hcd = bus_to_hcd(dev_get_drvdata(dev)); int power_on; int retval; if (sscanf(buf, "%d", &power_on) != 1) return -EINVAL; device_lock(dev); if (power_on == 0 && s5pv210_hcd != NULL) { printk(KERN_DEBUG "%s: EHCI turns off\n", __func__); usb_remove_hcd(hcd); s5pv210_stop_ehc(); s5pv210_hcd = NULL; /*HSIC IPC control the ACTIVE_STATE*/ #ifdef CONFIG_SAMSUNG_PHONE_SVNET mc_control_active_state(0); #endif } else if (power_on == 1) { printk(KERN_DEBUG "%s: EHCI turns on\n", __func__); if (s5pv210_hcd != NULL) { usb_remove_hcd(hcd); /*HSIC IPC control the ACTIVE_STATE*/ #ifdef CONFIG_SAMSUNG_PHONE_SVNET mc_control_active_state(0); #endif } s5pv210_start_ehc(); #if defined(CONFIG_ARCH_S5PV310) writel(0x03C00000, hcd->regs + 0x90); #endif retval = usb_add_hcd(hcd, IRQ_UHOST, IRQF_DISABLED | IRQF_SHARED); if (retval < 0) { dev_err(dev, "Power On Fail\n"); goto exit; } /*HSIC IPC control the ACTIVE_STATE*/ #ifdef CONFIG_SAMSUNG_PHONE_SVNET mc_control_active_state(1); #endif s5pv210_hcd = hcd; } exit: device_unlock(dev); return count; }
static void msm_hsusb_start_host(struct usb_bus *bus, int start) { struct usb_hcd *hcd = bus_to_hcd(bus); struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd); mhcd->flags = start; if (in_interrupt()) schedule_work(&mhcd->otg_work); else msm_hsusb_request_host((void *)mhcd, mhcd->flags); }
/* * Find the peer port either via explicit platform firmware "location" * data, the peer hcd for root hubs, or the upstream peer relationship * for all other hubs. */ static void find_and_link_peer(struct usb_hub *hub, int port1) { struct usb_port *port_dev = hub->ports[port1 - 1], *peer; struct usb_device *hdev = hub->hdev; struct usb_device *peer_hdev; struct usb_hub *peer_hub; /* * If location data is available then we can only peer this port * by a location match, not the default peer (lest we create a * situation where we need to go back and undo a default peering * when the port is later peered by location data) */ if (port_dev->location) { /* we link the peer in match_location() if found */ usb_for_each_dev(port_dev, match_location); return; } else if (!hdev->parent) { struct usb_hcd *hcd = bus_to_hcd(hdev->bus); struct usb_hcd *peer_hcd = hcd->shared_hcd; if (!peer_hcd) return; peer_hdev = peer_hcd->self.root_hub; } else { struct usb_port *upstream; struct usb_device *parent = hdev->parent; struct usb_hub *parent_hub = usb_hub_to_struct_hub(parent); if (!parent_hub) return; upstream = parent_hub->ports[hdev->portnum - 1]; if (!upstream || !upstream->peer) return; peer_hdev = upstream->peer->child; } peer_hub = usb_hub_to_struct_hub(peer_hdev); if (!peer_hub || port1 > peer_hdev->maxchild) return; /* * we found a valid default peer, last check is to make sure it * does not have location data */ peer = peer_hub->ports[port1 - 1]; if (peer && peer->location == 0) link_peers_report(port_dev, peer); }
/** * usb_release_dev - free a usb device structure when all users of it are finished. * @dev: device that's been disconnected * * Will be called only by the device core when all users of this usb device are * done. */ static void usb_release_dev(struct device *dev) { struct usb_device *udev; udev = to_usb_device(dev); usb_destroy_configuration(udev); usb_put_hcd(bus_to_hcd(udev->bus)); kfree(udev->product); kfree(udev->manufacturer); kfree(udev->serial); kfree(udev); }
/** * exynos_drd_switch_is_host_off - check host's PM status. * * @otg: Pointer to the usb_otg structure. * * Before peripheral can start two conditions must be met: * 1. Host's completely resumed after system sleep. * 2. Host is runtime suspended. */ static bool exynos_drd_switch_is_host_off(struct usb_otg *otg) { struct usb_hcd *hcd; struct device *dev; if (!otg->host) /* REVISIT: what should we return here? */ return true; hcd = bus_to_hcd(otg->host); dev = hcd->self.controller; return pm_runtime_suspended(dev); }
/** * dwc3_otg_start_host - helper function for starting/stoping the host controller driver. * * @otg: Pointer to the otg_transceiver structure. * @on: start / stop the host controller driver. * * Returns 0 on success otherwise negative errno. */ static int dwc3_otg_start_host(struct usb_otg *otg, int on) { struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct usb_hcd *hcd; struct xhci_hcd *xhci; int ret = 0; if (!otg->host) return -EINVAL; hcd = bus_to_hcd(otg->host); xhci = hcd_to_xhci(hcd); if (on) { dev_dbg(otg->phy->dev, "%s: turn on host %s\n", __func__, otg->host->bus_name); dwc3_otg_set_host_regs(dotg); /* * This should be revisited for more testing post-silicon. * In worst case we may need to disconnect the root hub * before stopping the controller so that it does not * interfere with runtime pm/system pm. * We can also consider registering and unregistering xhci * platform device. It is almost similar to add_hcd and * remove_hcd, But we may not use standard set_host method * anymore. */ ret = hcd->driver->start(hcd); if (ret) { dev_err(otg->phy->dev, "%s: failed to start primary hcd, ret=%d\n", __func__, ret); return ret; } ret = xhci->shared_hcd->driver->start(xhci->shared_hcd); if (ret) { dev_err(otg->phy->dev, "%s: failed to start secondary hcd, ret=%d\n", __func__, ret); return ret; } } else { dev_dbg(otg->phy->dev, "%s: turn off host %s\n", __func__, otg->host->bus_name); hcd->driver->stop(hcd); } return 0; }
/** * usb_release_dev - free a usb device structure when all users of it are finished. * @dev: device that's been disconnected * * Will be called only by the device core when all users of this usb device are * done. */ static void usb_release_dev(struct device *dev) { struct usb_device *udev; struct usb_hcd *hcd; udev = to_usb_device(dev); hcd = bus_to_hcd(udev->bus); usb_destroy_configuration(udev); usb_release_bos_descriptor(udev); usb_put_hcd(hcd); kfree(udev->product); kfree(udev->manufacturer); kfree(udev->serial); kfree(udev); }
static void mv_otg_start_host(struct mv_otg *mvotg, int on) { struct otg_transceiver *otg = &mvotg->otg; struct usb_hcd *hcd; if (!otg->host) return; hcd = bus_to_hcd(otg->host); dev_info(&mvotg->dev->dev, "%s host\n", on ? "start" : "stop"); if (on) usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); else usb_remove_hcd(hcd); }
static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) { struct msm_otg *motg = container_of(otg->usb_phy, struct msm_otg, phy); struct usb_hcd *hcd; /* * Fail host registration if this board can support * only peripheral configuration. */ if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) { dev_info(otg->usb_phy->dev, "Host mode is not supported\n"); return -ENODEV; } if (!host) { if (otg->state == OTG_STATE_A_HOST) { pm_runtime_get_sync(otg->usb_phy->dev); msm_otg_start_host(otg->usb_phy, 0); otg->host = NULL; otg->state = OTG_STATE_UNDEFINED; schedule_work(&motg->sm_work); } else { otg->host = NULL; } return 0; } hcd = bus_to_hcd(host); hcd->power_budget = motg->pdata->power_budget; otg->host = host; dev_dbg(otg->usb_phy->dev, "host driver registered w/ tranceiver\n"); /* * Kick the state machine work, if peripheral is not supported * or peripheral is already registered with us. */ if (motg->pdata->mode == USB_DR_MODE_HOST || motg->pdata->mode == USB_DR_MODE_OTG || otg->gadget) { pm_runtime_get_sync(otg->usb_phy->dev); schedule_work(&motg->sm_work); } return 0; }
static int xhci_slot_context_show(struct seq_file *s, void *unused) { struct xhci_hcd *xhci; struct xhci_slot_ctx *slot_ctx; struct xhci_slot_priv *priv = s->private; struct xhci_virt_device *dev = priv->dev; xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, xhci_decode_slot_context(slot_ctx->dev_info, slot_ctx->dev_info2, slot_ctx->tt_info, slot_ctx->dev_state)); return 0; }
/** * usb_release_dev - free a usb device structure when all users of it are finished. * @dev: device that's been disconnected * * Will be called only by the device core when all users of this usb device are * done. */ static void usb_release_dev(struct device *dev) { struct usb_device *udev; struct usb_hcd *hcd; udev = to_usb_device(dev); hcd = bus_to_hcd(udev->bus); usb_destroy_configuration(udev); /* Root hubs aren't real devices, so don't free HCD resources */ if (hcd->driver->free_dev && udev->parent) hcd->driver->free_dev(hcd, udev); usb_put_hcd(hcd); kfree(udev->product); kfree(udev->manufacturer); kfree(udev->serial); kfree(udev); }
static void usb_release_dev(struct device *dev) { struct usb_device *udev; struct usb_hcd *hcd; udev = to_usb_device(dev); hcd = bus_to_hcd(udev->bus); usb_destroy_configuration(udev); if (hcd->driver->free_dev && udev->parent) hcd->driver->free_dev(hcd, udev); usb_put_hcd(hcd); kfree(udev->product); kfree(udev->manufacturer); kfree(udev->serial); kfree(udev); }
/** * usb_alloc_dev - usb device constructor (usbcore-internal) * @parent: hub to which device is connected; null to allocate a root hub * @bus: bus used to access the device * @port1: one-based index of port; ignored for root hubs * Context: !in_interrupt() * * Only hub drivers (including virtual root hub drivers for host * controllers) should ever call this. * * This call may not be used in a non-sleeping context. */ struct usb_device *mtk_usb_alloc_rhdev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) { struct usb_device *dev; struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); unsigned root_hub = 0; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; if (!usb_get_hcd(bus_to_hcd(bus))) { kfree(dev); return NULL; } device_initialize(&dev->dev); dev->children = kzalloc(31 * sizeof(struct usb_device *), GFP_KERNEL); dev->dev.dma_mask = bus->controller->dma_mask; atomic_set(&dev->urbnum, 0); dev->can_submit = 1; /* Save readable and stable topology id, distinguishing devices * by location for diagnostics, tools, driver model, etc. The * string is a path along hub ports, from the root. Each device's * dev->devpath will be stable until USB is re-cabled, and hubs * are often labeled with these port numbers. The name isn't * as stable: bus->busnum changes easily from modprobe order, * cardbus or pci hotplugging, and so on. */ if (unlikely(!parent)) { dev->devpath[0] = '0'; dev->route = 0; dev->dev.parent = bus->controller; dev_set_name(&dev->dev, "usb%d", bus->busnum); root_hub = 1; } dev->portnum = port1; dev->bus = bus; dev->parent = parent; dev->authorized = 1; return dev; }
static void mv_otg_start_host(struct mv_otg *mvotg, int on) { #ifdef CONFIG_USB struct usb_otg *otg = mvotg->phy.otg; struct usb_hcd *hcd; if (!otg->host) return; dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop"); hcd = bus_to_hcd(otg->host); if (on) usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); else usb_remove_hcd(hcd); #endif /* CONFIG_USB */ }
/* * Allocate a URB and initialize the various fields of it. * This API is used by the single_step_set_feature test of * EHSET where IN packet of the GetDescriptor request is * sent 15secs after the SETUP packet. * Return NULL if failed. */ static struct urb *xhci_request_single_step_set_feature_urb( struct usb_device *udev, void *dr, void *buf, struct completion *done) { struct urb *urb; struct usb_hcd *hcd = bus_to_hcd(udev->bus); struct usb_host_endpoint *ep; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return NULL; urb->pipe = usb_rcvctrlpipe(udev, 0); ep = udev->ep_in[usb_pipeendpoint(urb->pipe)]; if (!ep) { usb_free_urb(urb); return NULL; } /* * Initialize the various URB fields as these are used by the HCD * driver to queue it and as well as when completion happens. */ urb->ep = ep; urb->dev = udev; urb->setup_packet = dr; urb->transfer_buffer = buf; urb->transfer_buffer_length = USB_DT_DEVICE_SIZE; urb->complete = xhci_single_step_completion; urb->status = -EINPROGRESS; urb->actual_length = 0; urb->transfer_flags = URB_DIR_IN; usb_get_urb(urb); atomic_inc(&urb->use_count); atomic_inc(&urb->dev->urbnum); usb_hcd_map_urb_for_dma(hcd, urb, GFP_KERNEL); urb->context = done; return urb; }
static void msm_otg_start_host(struct usb_phy *phy, int on) { struct msm_otg *motg = container_of(phy, struct msm_otg, phy); struct msm_otg_platform_data *pdata = motg->pdata; struct usb_hcd *hcd; if (!phy->otg->host) return; hcd = bus_to_hcd(phy->otg->host); if (on) { dev_dbg(phy->dev, "host on\n"); if (pdata->vbus_power) pdata->vbus_power(1); /* * Some boards have a switch cotrolled by gpio * to enable/disable internal HUB. Enable internal * HUB before kicking the host. */ if (pdata->setup_gpio) pdata->setup_gpio(OTG_STATE_A_HOST); #ifdef CONFIG_USB usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); device_wakeup_enable(hcd->self.controller); #endif } else { dev_dbg(phy->dev, "host off\n"); #ifdef CONFIG_USB usb_remove_hcd(hcd); #endif if (pdata->setup_gpio) pdata->setup_gpio(OTG_STATE_UNDEFINED); if (pdata->vbus_power) pdata->vbus_power(0); } }
void *hcd_buffer_alloc( struct usb_bus *bus, size_t size, gfp_t mem_flags, dma_addr_t *dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); int i; /* some USB hosts just use PIO */ if (!bus->controller->dma_mask) { *dma = ~(dma_addr_t) 0; return kmalloc(size, mem_flags); } for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) return dma_pool_alloc(hcd->pool [i], mem_flags, dma); } return dma_alloc_coherent(hcd->self.controller, size, dma, 0); }