On 15.5.20. 15:07, Greg KH wrote: > On Fri, May 15, 2020 at 02:34:57PM +0200, Vladimir Stankovic wrote: >> --- /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, >> +}; > > A static bus type??? For a single driver? > >> + >> +static struct device_driver mausb_driver = { >> + .name = DEVICE_NAME, >> + .bus = &mausb_bus_type, >> + .owner = THIS_MODULE, >> +}; > > Wait, what??? A static "raw" struct device_driver? Why??? This was our initial driver setup that was "inherited" from some in-tree drivers. We are currently revising driver setup. In general, device driver will not work properly w/o bus being setup and the only way to avoid explicit bus and simplify driver setup is to use platform driver; however, we are not aware of any explicit dependency on the platform, so not sure whether it's acceptable to switch to platform device driver setup. > >> + >> +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; > > Why? What is this device going to do? What do you need it for? Yeah, this one is not needed at all. Will be removed. > >> + >> + 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); > > I thought you were using the misc device, what are you doing with a > class and chardev? Why is that still here? > We're currently revising driver setup logic - this part should be much cleaner in new patch version. > > > >> + >> + 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 > > Why this max? Related to USB_SS_MAXPORTS - a worst case scenario. > >> + >> +#define MAX_USB_DEVICE_DEPTH 6 > > Where does this max come from? Unknown origin and unused - will be removed. > >> + >> +#define RESPONSE_TIMEOUT 5000 > > Units? ms - will be renamed to reflect the same. > >> + >> +#define MAUSB_PORT_20_STATUS_LOW_SPEED 0x0200 >> +#define MAUSB_PORT_20_STATUS_HIGH_SPEED 0x0400 > > Device ids? Something else? > > If something else, use BIT()? > >> + >> +enum mausb_device_type { >> + USBDEVICE = 0, >> + USB20HUB = 1, >> + USB30HUB = 2 > > Trailing , please > >> +}; >> + >> +enum mausb_device_speed { >> + LOW_SPEED = 0, >> + FULL_SPEED = 1, >> + HIGH_SPEED = 2, >> + SUPER_SPEED = 3, >> + SUPER_SPEED_PLUS = 4 > > , please. > >> +}; > > Where do these values come from? > >> + >> +struct mausb_hcd { >> + spinlock_t lock; /* Protect HCD during URB processing */ >> + struct device *pdev; >> + u16 connected_ports; > > Why u16? Seems odd, since max number of ports is much less. Should be corrected. > >> + >> + 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..."); > > This is debugging statements, please remove. If a driver works > properly, it does not print anything out. > > Especially as you never give the user the chance to see if module > unloading ever finished :) Agree :) > > thanks, > > greg k-h > -- Regards, Vladimir.