Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 304319
b: refs/heads/master
c: f401167
h: refs/heads/master
i:
  304317: 72a4655
  304315: 7c40bb4
  304311: 30c8601
  304303: 4044c33
  304287: 244e68e
  304255: 1544a74
v: v3
  • Loading branch information
Ian Abbott authored and Greg Kroah-Hartman committed Apr 10, 2012
1 parent dcb3455 commit 2b22070
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3902a370281d2f2b130f141e8cf94eab40125769
refs/heads/master: f4011670023f28cf9081904f8986c0c1be5c9f1e
6 changes: 5 additions & 1 deletion trunk/drivers/staging/comedi/comedidev.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,18 @@ struct comedi_async {
unsigned int x);
};

struct pci_dev;
struct usb_interface;

struct comedi_driver {
struct comedi_driver *next;

const char *driver_name;
struct module *module;
int (*attach) (struct comedi_device *, struct comedi_devconfig *);
int (*detach) (struct comedi_device *);
int (*attach_pci) (struct comedi_device *, struct pci_dev *);
int (*attach_usb) (struct comedi_device *, struct usb_interface *);

/* number of elements in board_name and board_id arrays */
unsigned int num_names;
Expand Down Expand Up @@ -460,7 +465,6 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s);
int comedi_pci_auto_config(struct pci_dev *pcidev,
struct comedi_driver *driver);
void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
struct usb_interface; /* forward declaration */
int comedi_usb_auto_config(struct usb_interface *intf,
struct comedi_driver *driver);
void comedi_usb_auto_unconfig(struct usb_interface *intf);
Expand Down
92 changes: 90 additions & 2 deletions trunk/drivers/staging/comedi/drivers.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,51 @@ void comedi_reset_async_buf(struct comedi_async *async)
async->events = 0;
}

static int
comedi_auto_config_helper(struct device *hardware_device,
struct comedi_driver *driver,
int (*attach_wrapper) (struct comedi_device *,
void *), void *context)
{
int minor;
struct comedi_device_file_info *dev_file_info;
struct comedi_device *comedi_dev;
int ret;

if (!comedi_autoconfig)
return 0;

minor = comedi_alloc_board_minor(hardware_device);
if (minor < 0)
return minor;

dev_file_info = comedi_get_device_file_info(minor);
comedi_dev = dev_file_info->device;

mutex_lock(&comedi_dev->mutex);
if (comedi_dev->attached)
ret = -EBUSY;
else if (!try_module_get(driver->module)) {
printk(KERN_INFO "comedi: failed to increment module count\n");
ret = -EIO;
} else {
/* set comedi_dev->driver here for attach wrapper */
comedi_dev->driver = driver;
ret = (*attach_wrapper)(comedi_dev, context);
if (ret < 0) {
module_put(driver->module);
__comedi_device_detach(comedi_dev);
} else {
ret = comedi_device_postconfig(comedi_dev);
}
}
mutex_unlock(&comedi_dev->mutex);

if (ret < 0)
comedi_free_board_minor(minor);
return ret;
}

static int comedi_auto_config(struct device *hardware_device,
const char *board_name, const int *options,
unsigned num_options)
Expand Down Expand Up @@ -857,7 +902,8 @@ static void comedi_auto_unconfig(struct device *hardware_device)
comedi_free_board_minor(minor);
}

int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver)
static int comedi_old_pci_auto_config(struct pci_dev *pcidev,
struct comedi_driver *driver)
{
int options[2];

Expand All @@ -869,6 +915,27 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver)
return comedi_auto_config(&pcidev->dev, driver->driver_name,
options, ARRAY_SIZE(options));
}

static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev)
{
return dev->driver->attach_pci(dev, pcidev);
}

static int comedi_new_pci_auto_config(struct pci_dev *pcidev,
struct comedi_driver *driver)
{
return comedi_auto_config_helper(&pcidev->dev, driver,
comedi_pci_attach_wrapper, pcidev);
}

int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver)
{

if (driver->attach_pci)
return comedi_new_pci_auto_config(pcidev, driver);
else
return comedi_old_pci_auto_config(pcidev, driver);
}
EXPORT_SYMBOL_GPL(comedi_pci_auto_config);

void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
Expand All @@ -877,11 +944,32 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
}
EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);

static int comedi_old_usb_auto_config(struct usb_interface *intf,
struct comedi_driver *driver)
{
return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0);
}

static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf)
{
return dev->driver->attach_usb(dev, intf);
}

static int comedi_new_usb_auto_config(struct usb_interface *intf,
struct comedi_driver *driver)
{
return comedi_auto_config_helper(&intf->dev, driver,
comedi_usb_attach_wrapper, intf);
}

int comedi_usb_auto_config(struct usb_interface *intf,
struct comedi_driver *driver)
{
BUG_ON(intf == NULL);
return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0);
if (driver->attach_usb)
return comedi_new_usb_auto_config(intf, driver);
else
return comedi_old_usb_auto_config(intf, driver);
}
EXPORT_SYMBOL_GPL(comedi_usb_auto_config);

Expand Down

0 comments on commit 2b22070

Please sign in to comment.