[PATCH 2/4] cdc-acm: Convert acm_minors to XArray

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxx>
---
 drivers/usb/class/cdc-acm.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 739f8960811a..28eb9a898b4a 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -47,7 +47,7 @@
 static struct usb_driver acm_driver;
 static struct tty_driver *acm_tty_driver;
 
-static DEFINE_IDR(acm_minors);
+static DEFINE_XARRAY_ALLOC(acm_minors);
 static DEFINE_MUTEX(acm_minors_lock);
 
 static void acm_tty_set_termios(struct tty_struct *tty,
@@ -66,7 +66,7 @@ static struct acm *acm_get_by_minor(unsigned int minor)
 	struct acm *acm;
 
 	mutex_lock(&acm_minors_lock);
-	acm = idr_find(&acm_minors, minor);
+	acm = xa_load(&acm_minors, minor);
 	if (acm) {
 		mutex_lock(&acm->mutex);
 		if (acm->disconnected) {
@@ -86,20 +86,15 @@ static struct acm *acm_get_by_minor(unsigned int minor)
  */
 static int acm_alloc_minor(struct acm *acm)
 {
-	int minor;
-
-	mutex_lock(&acm_minors_lock);
-	minor = idr_alloc(&acm_minors, acm, 0, ACM_TTY_MINORS, GFP_KERNEL);
-	mutex_unlock(&acm_minors_lock);
-
-	return minor;
+	return xa_alloc(&acm_minors, &acm->minor, acm,
+			XA_LIMIT(0, ACM_TTY_MINORS - 1), GFP_KERNEL);
 }
 
 /* Release the minor number associated with 'acm'.  */
 static void acm_release_minor(struct acm *acm)
 {
 	mutex_lock(&acm_minors_lock);
-	idr_remove(&acm_minors, acm->minor);
+	xa_erase(&acm_minors, acm->minor);
 	mutex_unlock(&acm_minors_lock);
 }
 
@@ -1130,7 +1125,6 @@ static int acm_probe(struct usb_interface *intf,
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	struct usb_cdc_parsed_header h;
 	struct acm *acm;
-	int minor;
 	int ctrlsize, readsize;
 	u8 *buf;
 	int call_intf_num = -1;
@@ -1302,9 +1296,10 @@ static int acm_probe(struct usb_interface *intf,
 	tty_port_init(&acm->port);
 	acm->port.ops = &acm_port_ops;
 
-	minor = acm_alloc_minor(acm);
-	if (minor < 0)
-		goto alloc_fail1;
+	rv = acm_alloc_minor(acm);
+	if (rv < 0)
+		goto alloc_fail0;
+	rv = -ENOMEM;
 
 	ctrlsize = usb_endpoint_maxp(epctrl);
 	readsize = usb_endpoint_maxp(epread) *
@@ -1313,7 +1308,6 @@ static int acm_probe(struct usb_interface *intf,
 	acm->writesize = usb_endpoint_maxp(epwrite) * 20;
 	acm->control = control_interface;
 	acm->data = data_interface;
-	acm->minor = minor;
 	acm->dev = usb_dev;
 	if (h.usb_cdc_acm_descriptor)
 		acm->ctrl_caps = h.usb_cdc_acm_descriptor->bmCapabilities;
@@ -1450,7 +1444,7 @@ static int acm_probe(struct usb_interface *intf,
 	acm->nb_index = 0;
 	acm->nb_size = 0;
 
-	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
+	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", acm->minor);
 
 	acm->line.dwDTERate = cpu_to_le32(9600);
 	acm->line.bDataBits = 8;
@@ -1460,8 +1454,8 @@ static int acm_probe(struct usb_interface *intf,
 	usb_set_intfdata(data_interface, acm);
 
 	usb_get_intf(control_interface);
-	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
-			&control_interface->dev);
+	tty_dev = tty_port_register_device(&acm->port, acm_tty_driver,
+			acm->minor, &control_interface->dev);
 	if (IS_ERR(tty_dev)) {
 		rv = PTR_ERR(tty_dev);
 		goto alloc_fail6;
@@ -1496,6 +1490,8 @@ static int acm_probe(struct usb_interface *intf,
 alloc_fail2:
 	usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
 alloc_fail1:
+	acm_release_minor(acm);
+alloc_fail0:
 	tty_port_put(&acm->port);
 alloc_fail:
 	return rv;
@@ -1986,7 +1982,6 @@ static void __exit acm_exit(void)
 	usb_deregister(&acm_driver);
 	tty_unregister_driver(acm_tty_driver);
 	put_tty_driver(acm_tty_driver);
-	idr_destroy(&acm_minors);
 }
 
 module_init(acm_init);
-- 
2.20.1




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux