usb: dwc2: avoid out of bounds access
[platform/kernel/u-boot.git] / drivers / usb / host / ehci-generic.c
1 /*
2  * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include "ehci.h"
10
11 /*
12  * Even though here we don't explicitly use "struct ehci_ctrl"
13  * ehci_register() expects it to be the first thing that resides in
14  * device's private data.
15  */
16 struct generic_ehci {
17         struct ehci_ctrl ctrl;
18 };
19
20 static int ehci_usb_probe(struct udevice *dev)
21 {
22         struct ehci_hccr *hccr = (struct ehci_hccr *)dev_get_addr(dev);
23         struct ehci_hcor *hcor;
24
25         hcor = (struct ehci_hcor *)((uintptr_t)hccr +
26                                     HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
27
28         return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
29 }
30
31 static int ehci_usb_remove(struct udevice *dev)
32 {
33         return ehci_deregister(dev);
34 }
35
36 static const struct udevice_id ehci_usb_ids[] = {
37         { .compatible = "generic-ehci" },
38         { }
39 };
40
41 U_BOOT_DRIVER(ehci_generic) = {
42         .name   = "ehci_generic",
43         .id     = UCLASS_USB,
44         .of_match = ehci_usb_ids,
45         .probe = ehci_usb_probe,
46         .remove = ehci_usb_remove,
47         .ops    = &ehci_usb_ops,
48         .priv_auto_alloc_size = sizeof(struct generic_ehci),
49         .flags  = DM_FLAG_ALLOC_PRIV_DMA,
50 };