diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 31d51346786a..830f3894a037 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -629,6 +629,35 @@ static int get_free_serial_index(void) return -1; } +static int obtain_minor(struct hso_serial *serial) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&serial_table_lock, flags); + for (i = 0; i < HSO_SERIAL_TTY_MINORS; ++i) { + if (serial_table[i] == NULL) { + serial_table[i] = serial->parent; + serial->minor = i; + spin_unlock_irqrestore(&serial_table_lock, flags); + return 0; + } + } + spin_unlock_irqrestore(&serial_table_lock, flags); + + pr_err("%s: no free serial devices in table\n", __func__); + return -1; +} + +static void release_minor(struct hso_serial *serial) +{ + unsigned long flags; + + spin_lock_irqsave(&serial_table_lock, flags); + serial_table[serial->minor] = NULL; + spin_unlock_irqrestore(&serial_table_lock, flags); +} + static void set_serial_by_index(unsigned index, struct hso_serial *serial) { unsigned long flags; @@ -2229,7 +2258,9 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) static void hso_serial_tty_unregister(struct hso_serial *serial) { + pr_info("hso_serial_tty_unregister 0x%p %d\n", serial, serial->minor); tty_unregister_device(tty_drv, serial->minor); + release_minor(serial); } static void hso_serial_common_free(struct hso_serial *serial) @@ -2262,15 +2293,22 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, if (minor < 0) goto exit2; + if (obtain_minor(serial)) + goto exit2; + /* register our minor number */ + pr_info("hso_serial_common_create: registering 0x%p, %d\n", serial, + minor); serial->parent->dev = tty_port_register_device_attr(&serial->port, - tty_drv, minor, &serial->parent->interface->dev, + tty_drv, serial->minor, &serial->parent->interface->dev, serial->parent, hso_serial_dev_groups); - if (IS_ERR(serial->parent->dev)) + if (IS_ERR(serial->parent->dev)) { + release_minor(serial); goto exit2; + } /* fill in specific data for later use */ - serial->minor = minor; + // serial->minor = minor; serial->magic = HSO_SERIAL_MAGIC; spin_lock_init(&serial->serial_lock); serial->num_rx_urbs = num_urbs; @@ -2654,7 +2692,9 @@ static struct hso_device *hso_create_bulk_serial_device( serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_IN); if (!serial->in_endp) { - dev_err(&interface->dev, "Failed to find BULK IN ep\n"); + dev_err(&interface->dev, + "Failed to find BULK IN ep 0x%p, 0x%p\n", + interface, serial); goto exit2; } @@ -2668,7 +2708,7 @@ static struct hso_device *hso_create_bulk_serial_device( serial->write_data = hso_std_serial_write_data; /* and record this serial */ - set_serial_by_index(serial->minor, serial); + // set_serial_by_index(serial->minor, serial); /* setup the proc dirs and files if needed */ hso_log_port(hso_dev); @@ -2727,7 +2767,7 @@ struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface, mutex_unlock(&serial->shared_int->shared_int_lock); /* and record this serial */ - set_serial_by_index(serial->minor, serial); + // set_serial_by_index(serial->minor, serial); /* setup the proc dirs and files if needed */ hso_log_port(hso_dev); @@ -2877,6 +2917,8 @@ static int hso_probe(struct usb_interface *interface, return -ENODEV; } + pr_info("hso_probe interface 0x%p\n", interface); + if_num = interface->cur_altsetting->desc.bInterfaceNumber; /* Get the interface/port specification from either driver_info or from @@ -3101,6 +3143,8 @@ static void hso_free_interface(struct usb_interface *interface) struct hso_serial *serial; int i; + pr_info("hso_free_interface 0x%p\n", interface); + for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { if (serial_table[i] && (serial_table[i]->interface == interface)) { @@ -3113,7 +3157,7 @@ static void hso_free_interface(struct usb_interface *interface) cancel_work_sync(&serial_table[i]->async_get_intf); hso_serial_tty_unregister(serial); kref_put(&serial_table[i]->ref, hso_serial_ref_free); - set_serial_by_index(i, NULL); + // set_serial_by_index(i, NULL); } } @@ -3233,7 +3277,7 @@ static int __init hso_init(void) int result; /* put it in the log */ - pr_info("%s\n", version); + pr_info("hso_init: %s\n", version); /* Initialise the serial table semaphore and table */ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) @@ -3280,6 +3324,7 @@ static int __init hso_init(void) err_unreg_tty: tty_unregister_driver(tty_drv); err_free_tty: + pr_info("freeing tty_drv 0x%p\n", tty_drv); put_tty_driver(tty_drv); return result; } @@ -3291,6 +3336,7 @@ static void __exit hso_exit(void) tty_unregister_driver(tty_drv); /* deregister the usb driver */ usb_deregister(&hso_driver); + pr_info("freeing tty_drv 0x%p\n", tty_drv); put_tty_driver(tty_drv); } diff --git a/fs/char_dev.c b/fs/char_dev.c index ba0ded7842a7..919e224c5f7c 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -593,6 +593,7 @@ static void cdev_unmap(dev_t dev, unsigned count) */ void cdev_del(struct cdev *p) { + pr_info("anirudh: cdev_del 0x%p\n", p); cdev_unmap(p->dev, p->count); kobject_put(&p->kobj); }