lkml.org 
[lkml]   [2020]   [May]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 3/8] usb: mausb_host: HCD initialization
    Date
    Implemented HCD initialization/deinitialization functionality.

    Signed-off-by: Vladimir Stankovic <vladimir.stankovic@displaylink.com>
    ---
    drivers/usb/host/mausb/Makefile | 1 +
    drivers/usb/host/mausb/hcd.c | 120 ++++++++++++++++++++++++++++
    drivers/usb/host/mausb/hcd.h | 65 +++++++++++++++
    drivers/usb/host/mausb/mausb_core.c | 18 ++++-
    4 files changed, 203 insertions(+), 1 deletion(-)
    create mode 100644 drivers/usb/host/mausb/hcd.c
    create mode 100644 drivers/usb/host/mausb/hcd.h

    diff --git a/drivers/usb/host/mausb/Makefile b/drivers/usb/host/mausb/Makefile
    index acc8ad3f0eff..4d655cb7fab4 100644
    --- a/drivers/usb/host/mausb/Makefile
    +++ b/drivers/usb/host/mausb/Makefile
    @@ -9,3 +9,4 @@ obj-$(CONFIG_USB_HOST_MAUSB) += mausb_host.o
    mausb_host-y := mausb_core.o
    mausb_host-y += utils.o
    mausb_host-y += ip_link.o
    +mausb_host-y += hcd.o
    diff --git a/drivers/usb/host/mausb/hcd.c b/drivers/usb/host/mausb/hcd.c
    new file mode 100644
    index 000000000000..3a6ef9313dcb
    --- /dev/null
    +++ b/drivers/usb/host/mausb/hcd.c
    @@ -0,0 +1,120 @@
    +// SPDX-License-Identifier: GPL-2.0
    +/*
    + * Copyright (c) 2019 - 2020 DisplayLink (UK) Ltd.
    + */
    +#include "hcd.h"
    +
    +#include "utils.h"
    +
    +static int mausb_bus_match(struct device *dev, struct device_driver *drv);
    +
    +static const struct file_operations mausb_fops;
    +
    +static unsigned int major;
    +static unsigned int minor = 1;
    +static dev_t devt;
    +static struct device *device;
    +
    +struct mausb_hcd *mhcd;
    +static struct class *mausb_class;
    +static struct bus_type mausb_bus_type = {
    + .name = DEVICE_NAME,
    + .match = mausb_bus_match,
    +};
    +
    +static struct device_driver mausb_driver = {
    + .name = DEVICE_NAME,
    + .bus = &mausb_bus_type,
    + .owner = THIS_MODULE,
    +};
    +
    +static void mausb_remove(void)
    +{
    + struct usb_hcd *hcd, *shared_hcd;
    +
    + hcd = mhcd->hcd_hs_ctx->hcd;
    + shared_hcd = mhcd->hcd_ss_ctx->hcd;
    +
    + if (shared_hcd) {
    + usb_remove_hcd(shared_hcd);
    + usb_put_hcd(shared_hcd);
    + mhcd->hcd_ss_ctx = NULL;
    + }
    +
    + usb_remove_hcd(hcd);
    + usb_put_hcd(hcd);
    + mhcd->hcd_hs_ctx = NULL;
    +}
    +
    +static int mausb_bus_match(struct device *dev, struct device_driver *drv)
    +{
    + if (strncmp(dev->bus->name, drv->name, strlen(drv->name)))
    + return 0;
    + else
    + return 1;
    +}
    +
    +int mausb_init_hcd(void)
    +{
    + int retval = register_chrdev(0, DEVICE_NAME, &mausb_fops);
    +
    + if (retval < 0)
    + return retval;
    +
    + major = (unsigned int)retval;
    + retval = bus_register(&mausb_bus_type);
    + if (retval)
    + goto bus_register_error;
    +
    + mausb_class = class_create(THIS_MODULE, CLASS_NAME);
    + if (IS_ERR(mausb_class)) {
    + retval = (int)PTR_ERR(mausb_class);
    + goto class_error;
    + }
    +
    + retval = driver_register(&mausb_driver);
    + if (retval)
    + goto driver_register_error;
    +
    + mhcd = kzalloc(sizeof(*mhcd), GFP_ATOMIC);
    + if (!mhcd) {
    + retval = -ENOMEM;
    + goto mausb_hcd_alloc_failed;
    + }
    +
    + devt = MKDEV(major, minor);
    + device = device_create(mausb_class, NULL, devt, mhcd, DEVICE_NAME);
    + if (IS_ERR(device)) {
    + retval = (int)IS_ERR(device);
    + goto device_create_error;
    + }
    +
    + device->driver = &mausb_driver;
    +
    + return retval;
    +device_create_error:
    + kfree(mhcd);
    + mhcd = NULL;
    +mausb_hcd_alloc_failed:
    + driver_unregister(&mausb_driver);
    +driver_register_error:
    + class_destroy(mausb_class);
    +class_error:
    + bus_unregister(&mausb_bus_type);
    +bus_register_error:
    + unregister_chrdev(major, DEVICE_NAME);
    +
    + return retval;
    +}
    +
    +void mausb_deinit_hcd(void)
    +{
    + if (mhcd) {
    + mausb_remove();
    + device_destroy(mausb_class, devt);
    + driver_unregister(&mausb_driver);
    + class_destroy(mausb_class);
    + bus_unregister(&mausb_bus_type);
    + unregister_chrdev(major, DEVICE_NAME);
    + }
    +}
    diff --git a/drivers/usb/host/mausb/hcd.h b/drivers/usb/host/mausb/hcd.h
    new file mode 100644
    index 000000000000..e2374af67663
    --- /dev/null
    +++ b/drivers/usb/host/mausb/hcd.h
    @@ -0,0 +1,65 @@
    +/* SPDX-License-Identifier: GPL-2.0 */
    +/*
    + * Copyright (c) 2019 - 2020 DisplayLink (UK) Ltd.
    + */
    +#ifndef __MAUSB_HCD_H__
    +#define __MAUSB_HCD_H__
    +
    +#include <linux/slab.h>
    +#include <linux/usb.h>
    +#include <linux/usb/hcd.h>
    +
    +#define DEVICE_NAME "mausb_host_hcd"
    +#define CLASS_NAME "mausb"
    +
    +#define NUMBER_OF_PORTS 15
    +
    +#define MAX_USB_DEVICE_DEPTH 6
    +
    +#define RESPONSE_TIMEOUT 5000
    +
    +#define MAUSB_PORT_20_STATUS_LOW_SPEED 0x0200
    +#define MAUSB_PORT_20_STATUS_HIGH_SPEED 0x0400
    +
    +enum mausb_device_type {
    + USBDEVICE = 0,
    + USB20HUB = 1,
    + USB30HUB = 2
    +};
    +
    +enum mausb_device_speed {
    + LOW_SPEED = 0,
    + FULL_SPEED = 1,
    + HIGH_SPEED = 2,
    + SUPER_SPEED = 3,
    + SUPER_SPEED_PLUS = 4
    +};
    +
    +struct mausb_hcd {
    + spinlock_t lock; /* Protect HCD during URB processing */
    + struct device *pdev;
    + u16 connected_ports;
    +
    + struct rb_root mausb_urbs;
    + struct hub_ctx *hcd_ss_ctx;
    + struct hub_ctx *hcd_hs_ctx;
    + struct notifier_block power_state_listener;
    +};
    +
    +struct mausb_dev {
    + u32 port_status;
    + struct rb_root usb_devices;
    + u8 dev_speed;
    + void *ma_dev;
    +};
    +
    +struct hub_ctx {
    + struct mausb_hcd *mhcd;
    + struct usb_hcd *hcd;
    + struct mausb_dev ma_devs[NUMBER_OF_PORTS];
    +};
    +
    +int mausb_init_hcd(void);
    +void mausb_deinit_hcd(void);
    +
    +#endif /* __MAUSB_HCD_H__ */
    diff --git a/drivers/usb/host/mausb/mausb_core.c b/drivers/usb/host/mausb/mausb_core.c
    index 44f76a1b74de..485f241d2b4c 100644
    --- a/drivers/usb/host/mausb/mausb_core.c
    +++ b/drivers/usb/host/mausb/mausb_core.c
    @@ -4,6 +4,7 @@
    */
    #include <linux/module.h>

    +#include "hcd.h"
    #include "utils.h"

    MODULE_LICENSE("GPL");
    @@ -11,12 +12,27 @@ MODULE_AUTHOR("DisplayLink (UK) Ltd.");

    static int mausb_host_init(void)
    {
    - return mausb_host_dev_register();
    + int status = mausb_host_dev_register();
    +
    + if (status < 0)
    + goto exit;
    +
    + status = mausb_init_hcd();
    + if (status < 0)
    + goto cleanup_dev;
    +
    + return 0;
    +
    +cleanup_dev:
    + mausb_host_dev_deregister();
    +exit:
    + return status;
    }

    static void mausb_host_exit(void)
    {
    dev_info(mausb_host_dev.this_device, "Module unloading started...");
    + mausb_deinit_hcd();
    mausb_host_dev_deregister();
    }

    --
    2.17.1
    \
     
     \ /
      Last update: 2020-05-15 14:36    [W:2.244 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site