From: Johan Hovold <jhovold@gmail.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: "Tobias Winter" <tobias@linuxdingsda.de>,
"Bjørn Mork" <bjorn@mork.no>, "Rob Landley" <rob@landley.net>,
"Johan Hovold" <jhovold@gmail.com>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 2/3] USB: serial: make minor allocation dynamic
Date: Sat, 8 Jun 2013 12:03:47 +0200 [thread overview]
Message-ID: <20130608100347.GO2566@localhost> (raw)
In-Reply-To: <20130607180428.GB4204@kroah.com>
On Fri, Jun 07, 2013 at 11:04:28AM -0700, Greg KH wrote:
> From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Changes v2 - v3:
> - fixed up comments about usb_serial_get_by_minor()
> - fixed error case in usb_serial_get_by_minor()
> - folded get_free_port() into get_free_serial()
> - renamed get_free_serial() to allocate_minors()
> - fixed console.c build breakage
> - properly pass in minor port number to usb_serial_console_init()
> --- a/drivers/usb/serial/usb-serial.c
> +++ b/drivers/usb/serial/usb-serial.c
> @@ -37,6 +37,7 @@
> #include <linux/usb.h>
> #include <linux/usb/serial.h>
> #include <linux/kfifo.h>
> +#include <linux/idr.h>
> #include "pl2303.h"
>
> #define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
> @@ -49,72 +50,64 @@
> drivers depend on it.
> */
>
> -static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
> +static DEFINE_IDR(serial_minors);
> static DEFINE_MUTEX(table_lock);
> static LIST_HEAD(usb_serial_driver_list);
>
> /*
> - * Look up the serial structure. If it is found and it hasn't been
> - * disconnected, return with its disc_mutex held and its refcount
> - * incremented. Otherwise return NULL.
> + * Look up the serial port structure. If it is found and it hasn't been
> + * disconnected, return with the parent usb_serial structure's disc_mutex held
> + * and its refcount incremented. Otherwise return NULL.
> */
> -struct usb_serial *usb_serial_get_by_index(unsigned index)
> +struct usb_serial_port *usb_serial_port_get_by_minor(unsigned minor)
> {
> - struct usb_serial *serial;
> + struct usb_serial *serial = NULL;
This isn't necessary anymore.
> + struct usb_serial_port *port;
>
> mutex_lock(&table_lock);
> - serial = serial_table[index];
> + port = idr_find(&serial_minors, minor);
> + if (!port)
> + goto exit;
>
> - if (serial) {
> - mutex_lock(&serial->disc_mutex);
> - if (serial->disconnected) {
> - mutex_unlock(&serial->disc_mutex);
> - serial = NULL;
> - } else {
> - kref_get(&serial->kref);
> - }
> + serial = port->serial;
> + mutex_lock(&serial->disc_mutex);
> + if (serial->disconnected) {
> + mutex_unlock(&serial->disc_mutex);
> + port = NULL;
> + } else {
> + kref_get(&serial->kref);
> }
> +exit:
> mutex_unlock(&table_lock);
> - return serial;
> + return port;
> }
>
> -static struct usb_serial *get_free_serial(struct usb_serial *serial,
> - int num_ports, unsigned int *minor)
> +static int allocate_minors(struct usb_serial *serial, int num_ports)
> {
> + struct usb_serial_port *port;
> unsigned int i, j;
> - int good_spot;
> + int minor;
>
> dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports);
>
> - *minor = 0;
> mutex_lock(&table_lock);
> - for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
> - if (serial_table[i])
> - continue;
> -
> - good_spot = 1;
> - for (j = 1; j <= num_ports-1; ++j)
> - if ((i+j >= SERIAL_TTY_MINORS) || (serial_table[i+j])) {
> - good_spot = 0;
> - i += j;
> - break;
> - }
> - if (good_spot == 0)
> - continue;
> -
> - *minor = i;
> - j = 0;
> - dev_dbg(&serial->interface->dev, "%s - minor base = %d\n", __func__, *minor);
> - for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i, ++j) {
> - serial_table[i] = serial;
> - serial->port[j]->minor = i;
> - serial->port[j]->port_number = i - *minor;
> - }
> - mutex_unlock(&table_lock);
> - return serial;
> + for (i = 0; i < num_ports; ++i) {
> + port = serial->port[i];
> + minor = idr_alloc(&serial_minors, port, 0, 0, GFP_KERNEL);
> + if (minor < 0)
> + goto error;
> + port->minor = minor;
> + port->port_number = i;
> }
> + serial->minors_reserved = 1;
> mutex_unlock(&table_lock);
> - return NULL;
> + return 0;
> +error:
> + /* unwind the already allocated minors */
> + for (j = 0; j < i; ++j)
> + idr_remove(&serial_minors, serial->port[j]->minor);
> + mutex_unlock(&table_lock);
> + return minor;
> }
>
> static void return_serial(struct usb_serial *serial)
Perhaps rename this one release_minors to match allocate_minors (much
better name btw)?
> @@ -123,8 +116,9 @@ static void return_serial(struct usb_ser
>
> mutex_lock(&table_lock);
> for (i = 0; i < serial->num_ports; ++i)
> - serial_table[serial->minor + i] = NULL;
> + idr_remove(&serial_minors, serial->port[i]->minor);
> mutex_unlock(&table_lock);
> + serial->minors_reserved = 0;
This isn't strictly needed as the serial struct release_serial is only
called once when the struct is about to be freed.
> }
>
> static void destroy_serial(struct kref *kref)
> @@ -136,7 +130,7 @@ static void destroy_serial(struct kref *
> serial = to_usb_serial(kref);
>
> /* return the minor range that this device had */
> - if (serial->minor != SERIAL_TTY_NO_MINOR)
> + if (serial->minors_reserved)
> return_serial(serial);
>
> if (serial->attached && serial->type->release)
All three patches look good otherwise. The port-number disambiguation
was indeed long overdue. Feel free to add
Reviewed-by: Johan Hovold <jhovold@gmail.com>
Thanks,
Johan
next prev parent reply other threads:[~2013-06-08 10:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-06 17:31 [PATCH v2 0/3] Increase the number of USB to serial devices we can support at once Greg KH
2013-06-06 17:31 ` [PATCH v2 2/3] USB: serial: make minor allocation dynamic Greg KH
2013-06-07 9:40 ` Johan Hovold
2013-06-07 9:50 ` Johan Hovold
2013-06-07 17:58 ` Greg KH
2013-06-07 10:00 ` Johan Hovold
2013-06-07 17:24 ` Greg KH
2013-06-07 18:04 ` [PATCH v3 " Greg KH
2013-06-08 10:03 ` Johan Hovold [this message]
2013-06-17 20:16 ` Greg KH
2013-06-18 10:23 ` Johan Hovold
2013-06-06 17:31 ` [PATCH v2 3/3] USB: serial: increase the number of devices we support Greg KH
2013-06-06 17:32 ` [PATCH v2 1/3] USB: serial: ports: add minor and port number Greg KH
2013-06-07 6:00 ` [PATCH v2 0/3] Increase the number of USB to serial devices we can support at once Tobias Winter
2013-06-07 9:55 ` Tobias Winter
2013-06-07 17:25 ` Greg KH
2013-06-08 9:14 ` Tobias Winter
2013-06-08 14:26 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130608100347.GO2566@localhost \
--to=jhovold@gmail.com \
--cc=bjorn@mork.no \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=rob@landley.net \
--cc=tobias@linuxdingsda.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.