Skip to content

Commit

Permalink
staging: comedi: ni_daq_dio24: convert to auto attach
Browse files Browse the repository at this point in the history
Convert this pcmcia driver to the comedi auto attach mechanism.

This allows getting rid of the "hack" needed to pass the pcmcia_device
pointer from the pcmcia_driver to the comedi_driver as well as the
now unnecessary boardinfo.

Check the call to subdev_8255_init() for success. That function does
a kzalloc and could return -ENOMEM.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
H Hartley Sweeten authored and Greg Kroah-Hartman committed Feb 4, 2013
1 parent 6746dc6 commit 5a1daad
Showing 1 changed file with 31 additions and 101 deletions.
132 changes: 31 additions & 101 deletions drivers/staging/comedi/drivers/ni_daq_dio24.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,142 +49,72 @@ the PCMCIA interface.
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>

static struct pcmcia_device *pcmcia_cur_dev;

#define DIO24_SIZE 4 /* size of io region used by board */

enum dio24_bustype { pcmcia_bustype };

struct dio24_board_struct {
const char *name;
int device_id; /* device id for pcmcia board */
enum dio24_bustype bustype; /* PCMCIA */
int have_dio; /* have 8255 chip */
/* function pointers so we can use inb/outb or readb/writeb as appropriate */
unsigned int (*read_byte) (unsigned int address);
void (*write_byte) (unsigned int byte, unsigned int address);
};
static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
void *priv_data)
{
if (p_dev->config_index == 0)
return -EINVAL;

static const struct dio24_board_struct dio24_boards[] = {
{
.name = "daqcard-dio24",
.device_id = 0x475c, /* 0x10b is manufacturer id, 0x475c is device id */
.bustype = pcmcia_bustype,
.have_dio = 1,
},
{
.name = "ni_daq_dio24",
.device_id = 0x475c, /* 0x10b is manufacturer id, 0x475c is device id */
.bustype = pcmcia_bustype,
.have_dio = 1,
},
};
return pcmcia_request_io(p_dev);
}

static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static int dio24_auto_attach(struct comedi_device *dev,
unsigned long context)
{
const struct dio24_board_struct *thisboard = comedi_board(dev);
struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
struct comedi_subdevice *s;
unsigned long iobase = 0;
struct pcmcia_device *link;
int ret;

/* get base address, irq etc. based on bustype */
switch (thisboard->bustype) {
case pcmcia_bustype:
link = pcmcia_cur_dev; /* XXX hack */
if (!link)
return -EIO;
iobase = link->resource[0]->start;
break;
default:
pr_err("bug! couldn't determine board type\n");
return -EINVAL;
break;
}
pr_debug("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
thisboard->name, iobase);
dev->board_name = dev->driver->driver_name;

if (iobase == 0) {
pr_err("io base address is zero!\n");
return -EINVAL;
}
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
CONF_AUTO_SET_IO;

dev->iobase = iobase;
ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
if (ret)
return ret;

dev->board_name = thisboard->name;
ret = pcmcia_enable_device(link);
if (ret)
return ret;
dev->iobase = link->resource[0]->start;

ret = comedi_alloc_subdevices(dev, 1);
if (ret)
return ret;

/* 8255 dio */
s = &dev->subdevices[0];
subdev_8255_init(dev, s, NULL, dev->iobase);
ret = subdev_8255_init(dev, s, NULL, dev->iobase);
if (ret)
return ret;

return 0;
};
}

static void dio24_detach(struct comedi_device *dev)
{
struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);

if (dev->subdevices)
subdev_8255_cleanup(dev, &dev->subdevices[0]);
if (dev->iobase)
pcmcia_disable_device(link);
}

static struct comedi_driver driver_dio24 = {
.driver_name = "ni_daq_dio24",
.module = THIS_MODULE,
.attach = dio24_attach,
.auto_attach = dio24_auto_attach,
.detach = dio24_detach,
.num_names = ARRAY_SIZE(dio24_boards),
.board_name = &dio24_boards[0].name,
.offset = sizeof(struct dio24_board_struct),
};

static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
void *priv_data)
{
if (p_dev->config_index == 0)
return -EINVAL;

return pcmcia_request_io(p_dev);
}

static int dio24_cs_attach(struct pcmcia_device *link)
{
int ret;

link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
CONF_AUTO_SET_IO;

ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
if (ret) {
dev_warn(&link->dev, "no configuration found\n");
goto failed;
}

if (!link->irq)
goto failed;

ret = pcmcia_enable_device(link);
if (ret)
goto failed;

pcmcia_cur_dev = link;

return 0;

failed:
pcmcia_disable_device(link);
return ret;
}

static void dio24_cs_detach(struct pcmcia_device *link)
{
pcmcia_disable_device(link);
return comedi_pcmcia_auto_config(link, &driver_dio24);
}

static const struct pcmcia_device_id dio24_cs_ids[] = {
/* N.B. These IDs should match those in dio24_boards */
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c), /* daqcard-dio24 */
PCMCIA_DEVICE_NULL
};
Expand All @@ -195,7 +125,7 @@ static struct pcmcia_driver dio24_cs_driver = {
.owner = THIS_MODULE,
.id_table = dio24_cs_ids,
.probe = dio24_cs_attach,
.remove = dio24_cs_detach,
.remove = comedi_pcmcia_auto_unconfig,
};
module_comedi_pcmcia_driver(driver_dio24, dio24_cs_driver);

Expand Down

0 comments on commit 5a1daad

Please sign in to comment.