[PATCH 24/77] staging: comedi: usbduxsigma: push usb (*probe) into comedi (*auto_attach)

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

 



The usb_driver (*probe) already calls comedi_usb_auto_config(), which
will call the comedi_driver (*auto_attach). Move the bulk of the (*probe)
to the (*auto_attach).

This allows the comedi_device private data to be kzalloc'ed and the static
array used to pass the private data from the usb_driver to the comedi_driver
can be removed along with the static semaphore that protected it.

We can also drop a couple variables from the private data since they no
longer are used or needed.

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/usbduxsigma.c | 153 +++++++--------------------
 1 file changed, 40 insertions(+), 113 deletions(-)

diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index 56fc95d..24bbda5 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -145,9 +145,6 @@ Status: testing
 /* must have more buffers due to buggy USB ctr */
 #define NUMOFOUTBUFFERSHIGH    10
 
-/* Total number of usbdux devices */
-#define NUMUSBDUX             16
-
 /* Analogue in subdevice */
 #define SUBDEV_AD             0
 
@@ -172,10 +169,6 @@ static const struct comedi_lrange range_usbdux_ai_range = { 1, {
 };
 
 struct usbduxsigma_private {
-	/* attached? */
-	int attached;
-	/* is it associated with a subdevice? */
-	int probed;
 	/* pointer to the usb-device */
 	struct usb_device *usbdev;
 	/* actual number of in-buffers */
@@ -199,8 +192,6 @@ struct usbduxsigma_private {
 	int8_t *insnBuffer;
 	/* output buffer for single DA outputs */
 	int16_t *outBuffer;
-	/* interface number */
-	int ifnum;
 	/* interface structure in 2.6 */
 	struct usb_interface *interface;
 	/* comedi device for the interrupt context */
@@ -233,17 +224,6 @@ struct usbduxsigma_private {
 	struct semaphore sem;
 };
 
-/*
- * The pointer to the private usb-data of the driver is also the private data
- * for the comedi-device.  This has to be global as the usb subsystem needs
- * global variables. The other reason is that this structure must be there
- * _before_ any comedi command is issued. The usb subsystem must be initialised
- * before comedi can access it.
- */
-static struct usbduxsigma_private usbduxsub[NUMUSBDUX];
-
-static DEFINE_SEMAPHORE(start_stop_sem);
-
 static void usbdux_ai_stop(struct usbduxsigma_private *devpriv, int do_unlink)
 {
 	if (do_unlink) {
@@ -1737,8 +1717,6 @@ static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
 	if (usbduxsub_tmp->interface)
 		usb_set_intfdata(usbduxsub_tmp->interface, NULL);
 
-	usbduxsub_tmp->probed = 0;
-
 	if (usbduxsub_tmp->urbIn) {
 		/* force unlink all urbs */
 		usbdux_ai_stop(usbduxsub_tmp, 1);
@@ -1789,9 +1767,9 @@ static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
 	usbduxsub_tmp->dux_commands = NULL;
 }
 
-static int usbduxsigma_attach_common(struct comedi_device *dev,
-				     struct usbduxsigma_private *uds)
+static int usbduxsigma_attach_common(struct comedi_device *dev)
 {
+	struct usbduxsigma_private *uds = dev->private;
 	int ret;
 	struct comedi_subdevice *s;
 	int n_subdevs;
@@ -1811,8 +1789,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
 		up(&uds->sem);
 		return ret;
 	}
-	/* private structure is also simply the usb-structure */
-	dev->private = uds;
 	/* the first subdevice is the A/D converter */
 	s = &dev->subdevices[SUBDEV_AD];
 	/* the URBs get the comedi subdevice */
@@ -1890,8 +1866,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
 		s->insn_config = usbdux_pwm_config;
 		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
 	}
-	/* finally decide that it's attached */
-	uds->attached = 1;
 	up(&uds->sem);
 	offset = usbdux_getstatusinfo(dev, 0);
 	if (offset < 0)
@@ -1991,34 +1965,51 @@ static int usbduxsigma_alloc_usb_buffers(struct usbduxsigma_private *devpriv)
 static int usbduxsigma_auto_attach(struct comedi_device *dev,
 				   unsigned long context_unused)
 {
-	struct usb_interface *uinterf = comedi_to_usb_interface(dev);
-	struct usbduxsigma_private *uds = usb_get_intfdata(uinterf);
-	struct usb_device *usb = uds->usbdev;
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv;
 	int ret;
 
-	dev->private = uds;	/* This is temporary... */
-	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
-				   usbduxsigma_firmware_upload, 0);
+	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+	if (!devpriv)
+		return -ENOMEM;
+	dev->private = devpriv;
+
+	sema_init(&devpriv->sem, 1);
+	devpriv->usbdev = usb;
+	devpriv->interface = intf;
+	usb_set_intfdata(intf, devpriv);
+
+	ret = usb_set_interface(usb,
+				intf->altsetting->desc.bInterfaceNumber, 3);
 	if (ret < 0) {
-		dev->private = NULL;
+		dev_err(dev->class_dev,
+			"could not set alternate setting 3 in high speed\n");
+		return -ENODEV;
+	}
+
+	/* test if it is high speed (USB 2.0) */
+	devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
+	if (devpriv->high_speed) {
+		devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
+		devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
+	} else {
+		devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
+		devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
+	}
+
+	ret = usbduxsigma_alloc_usb_buffers(devpriv);
+	if (ret) {
+		tidy_up(devpriv);
 		return ret;
 	}
 
-	dev->private = NULL;
+	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
+				   usbduxsigma_firmware_upload, 0);
+	if (ret)
+		return ret;
 
-	down(&start_stop_sem);
-	if (!uds) {
-		dev_err(dev->class_dev,
-			"usbduxsigma: error: auto_attach failed, not connected\n");
-		ret = -ENODEV;
-	} else if (uds->attached) {
-		dev_err(dev->class_dev,
-		       "usbduxsigma: error: auto_attach failed, already attached\n");
-		ret = -ENODEV;
-	} else
-		ret = usbduxsigma_attach_common(dev, uds);
-	up(&start_stop_sem);
-	return ret;
+	return usbduxsigma_attach_common(dev);
 }
 
 static void usbduxsigma_detach(struct comedi_device *dev)
@@ -2032,14 +2023,10 @@ static void usbduxsigma_detach(struct comedi_device *dev)
 	usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
 	usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
 
-	down(&start_stop_sem);
 	down(&devpriv->sem);
-	dev->private = NULL;
-	devpriv->attached = 0;
 	devpriv->comedidev = NULL;
 	tidy_up(devpriv);
 	up(&devpriv->sem);
-	up(&start_stop_sem);
 }
 
 static struct comedi_driver usbduxsigma_driver = {
@@ -2052,66 +2039,6 @@ static struct comedi_driver usbduxsigma_driver = {
 static int usbduxsigma_usb_probe(struct usb_interface *intf,
 				 const struct usb_device_id *id)
 {
-	struct usb_device *usb = interface_to_usbdev(intf);
-	struct device *dev = &intf->dev;
-	struct usbduxsigma_private *devpriv = NULL;
-	int ret;
-	int i;
-
-	down(&start_stop_sem);
-	for (i = 0; i < NUMUSBDUX; i++) {
-		if (!usbduxsub[i].probed) {
-			devpriv = &usbduxsub[i];
-			break;
-		}
-	}
-
-	if (!devpriv) {
-		dev_err(dev, "Too many usbduxsigma-devices connected.\n");
-		up(&start_stop_sem);
-		return -EMFILE;
-	}
-
-	sema_init(&devpriv->sem, 1);
-	devpriv->usbdev = usb;
-	devpriv->interface = intf;
-	devpriv->ifnum = intf->altsetting->desc.bInterfaceNumber;
-	usb_set_intfdata(intf, devpriv);
-
-	ret = usb_set_interface(usb, devpriv->ifnum, 3);
-	if (ret < 0) {
-		dev_err(dev,
-			"could not set alternate setting 3 in high speed\n");
-		tidy_up(devpriv);
-		up(&start_stop_sem);
-		return -ENODEV;
-	}
-
-	/* test if it is high speed (USB 2.0) */
-	devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
-	if (devpriv->high_speed) {
-		devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
-		devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
-	} else {
-		devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
-		devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
-	}
-
-	ret = usbduxsigma_alloc_usb_buffers(devpriv);
-	if (ret) {
-		tidy_up(devpriv);
-		up(&start_stop_sem);
-		return ret;
-	}
-
-	devpriv->ai_cmd_running = 0;
-	devpriv->ao_cmd_running = 0;
-	devpriv->pwm_cmd_running = 0;
-
-	/* we've reached the bottom of the function */
-	devpriv->probed = 1;
-	up(&start_stop_sem);
-
 	return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
 }
 
-- 
1.8.1.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux