Commit 41be28db authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: addi-data: use attach_pci callback



Use the comedi pci auto config mechanism to attach the addi-data
drivers. This allows removing all the PCI bus walking code.

Add a function, addi_find_boardinfo(), to find the driver specific
boardinfo. Since this function is currently in the common code we
have to use the pointer to the boardinfo that is stored in the
comedi_driver pointer.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a43163c9
Loading
Loading
Loading
Loading
+0 −167
Original line number Diff line number Diff line
@@ -190,171 +190,4 @@
#define TARGET_ABORT_INT	0x00200000L
#define BUS_MASTER_INT		0x00200000L

/****************************************************************************/

struct pcilst_struct {
	struct pcilst_struct *next;
	int used;
	struct pci_dev *pcidev;
	unsigned short vendor;
	unsigned short device;
	unsigned char pci_bus;
	unsigned char pci_slot;
	unsigned char pci_func;
};

/* ptr to root list of all amcc devices */
static struct pcilst_struct *amcc_devices;

static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };

/****************************************************************************/

void v_pci_card_list_init(unsigned short pci_vendor);
void v_pci_card_list_cleanup(unsigned short pci_vendor);
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
						       unsigned short
						       device_id);
int i_find_free_pci_card_by_position(unsigned short vendor_id,
				     unsigned short device_id,
				     unsigned short pci_bus,
				     unsigned short pci_slot,
				     struct pcilst_struct **card);
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
						    unsigned short device_id,
						    unsigned short pci_bus,
						    unsigned short pci_slot);

/****************************************************************************/

/* build list of amcc cards in this system */
void v_pci_card_list_init(unsigned short pci_vendor)
{
	struct pci_dev *pcidev = NULL;
	struct pcilst_struct *amcc, *last;
	int i_Count = 0;
	amcc_devices = NULL;
	last = NULL;

	for_each_pci_dev(pcidev) {
		for (i_Count = 0; i_Count < 2; i_Count++) {
			pci_vendor = i_ADDIDATADeviceID[i_Count];
			if (pcidev->vendor == pci_vendor) {
				amcc = kzalloc(sizeof(*amcc), GFP_KERNEL);
				if (amcc == NULL)
					continue;

				amcc->pcidev = pcidev;
				if (last)
					last->next = amcc;
				else
					amcc_devices = amcc;
				last = amcc;

				amcc->vendor = pcidev->vendor;
				amcc->device = pcidev->device;
				amcc->pci_bus = pcidev->bus->number;
				amcc->pci_slot = PCI_SLOT(pcidev->devfn);
				amcc->pci_func = PCI_FUNC(pcidev->devfn);
			}
		}
	}
}

/****************************************************************************/
/* free up list of amcc cards in this system */
void v_pci_card_list_cleanup(unsigned short pci_vendor)
{
	struct pcilst_struct *amcc, *next;

	for (amcc = amcc_devices; amcc; amcc = next) {
		next = amcc->next;
		kfree(amcc);
	}

	amcc_devices = NULL;
}

/****************************************************************************/
/* find first unused card with this device_id */
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
						       unsigned short device_id)
{
	struct pcilst_struct *amcc, *next;

	for (amcc = amcc_devices; amcc; amcc = next) {
		next = amcc->next;
		if ((!amcc->used) && (amcc->device == device_id)
		    && (amcc->vendor == vendor_id))
			return amcc;

	}

	return NULL;
}

/****************************************************************************/
/* find card on requested position */
int i_find_free_pci_card_by_position(unsigned short vendor_id,
				     unsigned short device_id,
				     unsigned short pci_bus,
				     unsigned short pci_slot,
				     struct pcilst_struct **card)
{
	struct pcilst_struct *amcc, *next;

	*card = NULL;
	for (amcc = amcc_devices; amcc; amcc = next) {
		next = amcc->next;
		if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
		    && (amcc->pci_bus == pci_bus)
		    && (amcc->pci_slot == pci_slot)) {
			if (!(amcc->used)) {
				*card = amcc;
				return 0;	/* ok, card is found */
			} else {
				printk(" - \nCard on requested position is used b:s %d:%d!\n",
					  pci_bus, pci_slot);
				return 2;	/* card exist but is used */
			}
		}
	}

	/* no card found */
	return 1;
}

/****************************************************************************/
/* select and alloc card */
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
						    unsigned short device_id,
						    unsigned short pci_bus,
						    unsigned short pci_slot)
{
	struct pcilst_struct *card;

	if ((pci_bus < 1) & (pci_slot < 1)) {
		/* use autodetection */
		card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
		if (card == NULL) {
			printk(" - Unused card not found in system!\n");
			return NULL;
		}
	} else {
		switch (i_find_free_pci_card_by_position(vendor_id, device_id,
							 pci_bus, pci_slot,
							 &card)) {
		case 1:
			printk(" - Card not found on requested position b:s %d:%d!\n",
				  pci_bus, pci_slot);
			return NULL;
		case 2:
			printk(" - Card on requested position is used b:s %d:%d!\n",
				  pci_bus, pci_slot);
			return NULL;
		}
	}

	return card;
}
#endif
+36 −49
Original line number Diff line number Diff line
@@ -36,11 +36,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour
  +-----------------------------------------------------------------------+
  | Description : ADDI COMMON Main Module                                 |
  +-----------------------------------------------------------------------+
  | CONFIG OPTIONS                                                        |
  |	option[0] - PCI bus number - if bus number and slot number are 0, |
  |			         then driver search for first unused card |
  |	option[1] - PCI slot number                                       |
  +----------+-----------+------------------------------------------------+
*/

#ifndef COMEDI_SUBD_TTLIO
@@ -81,42 +76,49 @@ static int i_ADDI_Reset(struct comedi_device *dev)
	return 0;
}

static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
static const void *addi_find_boardinfo(struct comedi_device *dev,
				       struct pci_dev *pcidev)
{
	const struct addi_board *this_board = comedi_board(dev);
	struct pci_dev *pcidev;
	const void *p = dev->driver->board_name;
	const struct addi_board *this_board;
	int i;

	for (i = 0; i < dev->driver->num_names; i++) {
		this_board = p;
		if (this_board->i_VendorId == pcidev->vendor &&
		    this_board->i_DeviceId == pcidev->device)
			return this_board;
		p += dev->driver->offset;
	}
	return NULL;
}

static int addi_attach_pci(struct comedi_device *dev,
			   struct pci_dev *pcidev)
{
	const struct addi_board *this_board;
	struct addi_private *devpriv;
	struct comedi_subdevice *s;
	int ret, pages, i, n_subdevices;
	unsigned int dw_Dummy;
	resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved;
	struct pcilst_struct *card = NULL;

	this_board = addi_find_boardinfo(dev, pcidev);
	if (!this_board)
		return -ENODEV;
	dev->board_ptr = this_board;
	dev->board_name = this_board->pc_DriverName;

	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
	if (!devpriv)
		return -ENOMEM;
	dev->private = devpriv;

	if (!pci_list_builded) {
		v_pci_card_list_init(this_board->i_VendorId);
		pci_list_builded = 1;
	}

	card = ptr_select_and_alloc_pci_card(this_board->i_VendorId,
					     this_board->i_DeviceId,
					     it->options[0],
					     it->options[1]);

	if (card == NULL)
		return -EIO;
	pcidev = card->pcidev;

	ret = comedi_pci_enable(pcidev, "addi_amcc_s5933");
	ret = comedi_pci_enable(pcidev, dev->board_name);
	if (ret)
		return ret;
	if (this_board->i_Dma)
		pci_set_master(pcidev);
	card->used = 1;
	devpriv->allocated = 1;

	iobase_a = pci_resource_start(pcidev, 0);
@@ -136,16 +138,12 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
			dev->iobase = (unsigned long)iobase_a;	/*  DAQ base address... */
		}

		dev->board_name = this_board->pc_DriverName;
		devpriv->amcc = card;
		devpriv->iobase = (int) dev->iobase;
		devpriv->i_IobaseAmcc = (int) iobase_a;	/* AMCC base address... */
		devpriv->i_IobaseAddon = (int) iobase_addon;	/* ADD ON base address.... */
		devpriv->i_IobaseReserved = (int) iobase_reserved;
	} else {
		dev->board_name = this_board->pc_DriverName;
		dev->iobase = pci_resource_start(pcidev, 2);
		devpriv->amcc = card;
		devpriv->iobase = pci_resource_start(pcidev, 2);
		devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
		devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3),
@@ -171,7 +169,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)

	if (pcidev->irq > 0) {
		ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
				  this_board->pc_DriverName, dev);
				  dev->board_name, dev);
		if (ret == 0)
			dev->irq = pcidev->irq;
	}
@@ -181,7 +179,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
	if (this_board->i_PCIEeprom) {
		if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
			/*  Set 3 wait stait */
			if (!(strcmp(this_board->pc_DriverName, "apci035"))) {
			if (!(strcmp(dev->board_name, "apci035"))) {
				outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
			} else {
				outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
@@ -193,11 +191,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
		addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0));
	}

	if (it->options[2] > 0) {
		devpriv->us_UseDma = ADDI_DISABLE;
	} else {
	devpriv->us_UseDma = ADDI_ENABLE;
	}

	if (devpriv->s_EeParameters.i_Dma) {
		if (devpriv->us_UseDma == ADDI_ENABLE) {
@@ -231,7 +225,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
		}
	}

	if (!strcmp(this_board->pc_DriverName, "apci1710")) {
	if (!strcmp(dev->board_name, "apci1710")) {
#ifdef CONFIG_APCI_1710
		i_ADDI_AttachPCI1710(dev);

@@ -393,6 +387,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void i_ADDI_Detach(struct comedi_device *dev)
{
	const struct addi_board *this_board = comedi_board(dev);
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	struct addi_private *devpriv = dev->private;

	if (devpriv) {
@@ -402,10 +397,8 @@ static void i_ADDI_Detach(struct comedi_device *dev)
			free_irq(dev->irq, dev);
		if ((this_board->pc_EepromChip == NULL) ||
		    (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
			if (devpriv->allocated) {
				comedi_pci_disable(devpriv->amcc->pcidev);
				devpriv->amcc->used = 0;
			}
			if (devpriv->allocated)
				comedi_pci_disable(pcidev);
			if (devpriv->ul_DmaBufferVirtual[0]) {
				free_pages((unsigned long)devpriv->
					ul_DmaBufferVirtual[0],
@@ -418,14 +411,8 @@ static void i_ADDI_Detach(struct comedi_device *dev)
			}
		} else {
			iounmap(devpriv->dw_AiBase);
			if (devpriv->allocated) {
				comedi_pci_disable(devpriv->amcc->pcidev);
				devpriv->amcc->used = 0;
			}
		}
		if (pci_list_builded) {
			v_pci_card_list_cleanup(this_board->i_VendorId);
			pci_list_builded = 0;
			if (devpriv->allocated)
				comedi_pci_disable(pcidev);
		}
	}
}
+0 −3
Original line number Diff line number Diff line
@@ -312,7 +312,6 @@ struct addi_private {
	int i_IobaseAddon;	/* addon base address */
	int i_IobaseReserved;
	void __iomem *dw_AiBase;
	struct pcilst_struct *amcc;	/*  ptr too AMCC data */
	unsigned char allocated;		/*  we have blocked card */
	unsigned char b_ValidDriver;	/*  driver is ok */
	unsigned char b_AiContinuous;	/*  we do unlimited AI */
@@ -410,5 +409,3 @@ struct addi_private {
					/*  Minimum Delay in Nano secs */
	} s_EeParameters;
};

static unsigned short pci_list_builded;	/* set to 1 when list of card is known */
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ static const struct addi_board apci035_boardtypes[] = {
static struct comedi_driver apci035_driver = {
	.driver_name	= "addi_apci_035",
	.module		= THIS_MODULE,
	.attach		= i_ADDI_Attach,
	.attach_pci	= addi_attach_pci,
	.detach		= i_ADDI_Detach,
	.num_names	= ARRAY_SIZE(apci035_boardtypes),
	.board_name	= &apci035_boardtypes[0].pc_DriverName,
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ static const struct addi_board apci1032_boardtypes[] = {
static struct comedi_driver apci1032_driver = {
	.driver_name	= "addi_apci_1032",
	.module		= THIS_MODULE,
	.attach		= i_ADDI_Attach,
	.attach_pci	= addi_attach_pci,
	.detach		= i_ADDI_Detach,
	.num_names	= ARRAY_SIZE(apci1032_boardtypes),
	.board_name	= &apci1032_boardtypes[0].pc_DriverName,
Loading