#include "driver.h"
#include "sndpci.h"

int
snd_pci_find_device(int vendor, int device, unsigned int index, 
		    struct snd_pci_dev *dev)
{
        struct _osinfo                  info;
        unsigned                        lastbus,
                                        version,
                                        hardware,
                                        devfuncnum,
                                        bus;
        int                             rval, idx;
        char                            lattimer = 0x20;

        if (qnx_osinfo(0, &info) < 0) {
                perror("qnx_osinfo");
                return (-errno);
        }

        if (!(info.sflags & _PSF_PCI_BIOS) ||
            (_CA_PCI_BIOS_Present(&lastbus, &version, &hardware) < 0)) {
                fprintf(stderr, "No PCI Bios present on this machine\n");
                return (-ENODEV);
        }

        rval = _CA_PCI_Find_Device(device, vendor, index, &bus, &devfuncnum);
        if (rval != PCI_SUCCESS)
                return (-ENODEV);

        dev->bus = bus;
        dev->devfn = devfuncnum;
        dev->vendor = vendor;
        dev->device = device;
        _CA_PCI_Read_Config_DWord(bus, devfuncnum, 0x08, 1, (char *) &dev->class);
        dev->class &= ~0xff000000;
        _CA_PCI_Read_Config_Byte(bus, devfuncnum, 0x3c, 1, (char *) &dev->irq);

        for (idx = 0; idx < 6; idx++) {
                _CA_PCI_Read_Config_DWord(bus, devfuncnum, 0x10 + (idx*4), 1,
                                          (char *) &dev->base_address[idx]);
        }
        _CA_PCI_Write_Config_Byte(bus, devfuncnum, 0x0d, 1, &lattimer);
        return (EOK);
}


int snd_pci_write_config_word(struct snd_pci_dev *pci, int index, unsigned short value)
{
        return _CA_PCI_Write_Config_Word( pci->bus, pci->devfn, index, 1, (char*) &value );
}

int snd_pci_read_config_word(struct snd_pci_dev *pci, int index, unsigned short *value)
{
        return _CA_PCI_Read_Config_Word( pci->bus, pci->devfn, index, 1, (char*) value );
}

int snd_pci_write_config_dword(struct snd_pci_dev *pci, int index, unsigned long value)
{
        return _CA_PCI_Write_Config_DWord( pci->bus, pci->devfn, index, 1, (char*) &value );
}

int snd_pci_read_config_dword(struct snd_pci_dev *pci, int index, unsigned long *value)
{
        return _CA_PCI_Read_Config_DWord( pci->bus, pci->devfn, index, 1, (char*) value );
}

int snd_pci_write_config_byte( struct snd_pci_dev *pci, int index, unsigned char value)
{
        return _CA_PCI_Write_Config_Byte( pci->bus, pci->devfn, index, 1, &value );
}

int snd_pci_read_config_byte( struct snd_pci_dev *pci, int index, unsigned char *value)
{
        return _CA_PCI_Read_Config_Byte( pci->bus, pci->devfn, index, 1, value );
}
