/*
    comedi/drivers/icp_multi.h

    Stuff for ICP Multi

    Author: Anne Smorthit <anne.smorthit@sfwte.ch>

*/

#ifndef _ICP_MULTI_H_
#define _ICP_MULTI_H_

#include "../comedidev.h"
#include "comedi_pci.h"

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

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;
	resource_size_t io_addr[5];
	unsigned int irq;
};

struct pcilst_struct *inova_devices;
/* ptr to root list of all Inova devices */

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

static void pci_card_list_init(unsigned short pci_vendor, char display);
static void pci_card_list_cleanup(unsigned short pci_vendor);
static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
							  vendor_id,
							  unsigned short
							  device_id);
static int 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);
static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
						       unsigned short device_id,
						       unsigned short pci_bus,
						       unsigned short pci_slot);

static int pci_card_alloc(struct pcilst_struct *amcc);
static int pci_card_free(struct pcilst_struct *amcc);
static void pci_card_list_display(void);
static int pci_card_data(struct pcilst_struct *amcc,
			 unsigned char *pci_bus, unsigned char *pci_slot,
			 unsigned char *pci_func, resource_size_t * io_addr,
			 unsigned int *irq);

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

/* build list of Inova cards in this system */
static void pci_card_list_init(unsigned short pci_vendor, char display)
{
	struct pci_dev *pcidev = NULL;
	struct pcilst_struct *inova, *last;
	int i;

	inova_devices = NULL;
	last = NULL;

	for_each_pci_dev(pcidev) {
		if (pcidev->vendor == pci_vendor) {
			inova = kzalloc(sizeof(*inova), GFP_KERNEL);
			if (!inova) {
				printk
				    ("icp_multi: pci_card_list_init: allocation failed\n");
				pci_dev_put(pcidev);
				break;
			}

			inova->pcidev = pci_dev_get(pcidev);
			if (last) {
				last->next = inova;
			} else {
				inova_devices = inova;
			}
			last = inova;

			inova->vendor = pcidev->vendor;
			inova->device = pcidev->device;
			inova->pci_bus = pcidev->bus->number;
			inova->pci_slot = PCI_SLOT(pcidev->devfn);
			inova->pci_func = PCI_FUNC(pcidev->devfn);
			/* Note: resources may be invalid if PCI device
			 * not enabled, but they are corrected in
			 * pci_card_alloc. */
			for (i = 0; i < 5; i++)
				inova->io_addr[i] =
				    pci_resource_start(pcidev, i);
			inova->irq = pcidev->irq;
		}
	}

	if (display)
		pci_card_list_display();
}

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

	for (inova = inova_devices; inova; inova = next) {
		next = inova->next;
		pci_dev_put(inova->pcidev);
		kfree(inova);
	}

	inova_devices = NULL;
}

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

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

	}

	return NULL;
}

/****************************************************************************/
/* find card on requested position */
static int 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 *inova, *next;

	*card = NULL;
	for (inova = inova_devices; inova; inova = next) {
		next = inova->next;
		if ((inova->vendor == vendor_id) && (inova->device == device_id)
		    && (inova->pci_bus == pci_bus)
		    && (inova->pci_slot == pci_slot)) {
			if (!(inova->used)) {
				*card = inova;
				return 0;	/* ok, card is found */
			} else {
				return 2;	/* card exist but is used */
			}
		}
	}

	return 1;		/* no card found */
}

/****************************************************************************/
/* mark card as used */
static int pci_card_alloc(struct pcilst_struct *inova)
{
	int i;

	if (!inova) {
		printk(" - BUG!! inova is NULL!\n");
		return -1;
	}

	if (inova->used)
		return 1;
	if (comedi_pci_enable(inova->pcidev, "icp_multi")) {
		printk(" - Can't enable PCI device and request regions!\n");
		return -1;
	}
	/* Resources will be accurate now. */
	for (i = 0; i < 5; i++)
		inova->io_addr[i] = pci_resource_start(inova->pcidev, i);
	inova->irq = inova->pcidev->irq;
	inova->used = 1;
	return 0;
}

/****************************************************************************/
/* mark card as free */
static int pci_card_free(struct pcilst_struct *inova)
{
	if (!inova)
		return -1;

	if (!inova->used)
		return 1;
	inova->used = 0;
	comedi_pci_disable(inova->pcidev);
	return 0;
}

/****************************************************************************/
/* display list of found cards */
static void pci_card_list_display(void)
{
	struct pcilst_struct *inova, *next;

	printk("Anne's List of pci cards\n");
	printk("bus:slot:func vendor device io_inova io_daq irq used\n");

	for (inova = inova_devices; inova; inova = next) {
		next = inova->next;
		printk
		    ("%2d   %2d   %2d  0x%4x 0x%4x   0x%8llx 0x%8llx  %2u  %2d\n",
		     inova->pci_bus, inova->pci_slot, inova->pci_func,
		     inova->vendor, inova->device,
		     (unsigned long long)inova->io_addr[0],
		     (unsigned long long)inova->io_addr[2], inova->irq,
		     inova->used);

	}
}

/****************************************************************************/
/* return all card information for driver */
static int pci_card_data(struct pcilst_struct *inova,
			 unsigned char *pci_bus, unsigned char *pci_slot,
			 unsigned char *pci_func, resource_size_t * io_addr,
			 unsigned int *irq)
{
	int i;

	if (!inova)
		return -1;
	*pci_bus = inova->pci_bus;
	*pci_slot = inova->pci_slot;
	*pci_func = inova->pci_func;
	for (i = 0; i < 5; i++)
		io_addr[i] = inova->io_addr[i];
	*irq = inova->irq;
	return 0;
}

/****************************************************************************/
/* select and alloc card */
static struct pcilst_struct *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;
	int err;

	if ((pci_bus < 1) & (pci_slot < 1)) {	/* use autodetection */

		card = 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 (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;
		}
	}

	err = pci_card_alloc(card);
	if (err != 0) {
		if (err > 0)
			printk(" - Can't allocate card!\n");
		/* else: error already printed. */
		return NULL;
	}

	return card;
}

#endif
