minix/lib/libddekit/src/pci.c
2012-03-25 21:58:14 +02:00

449 lines
14 KiB
C

/**
* pci.c
* @author: Dirk Vogt
* @date: 2010-02-18
*/
#include "common.h"
#include <ddekit/pci.h>
#include <ddekit/panic.h>
#include <minix/syslib.h>
#ifdef DDEBUG_LEVEL_PCI
#undef DDEBUG
#define DDEBUG DDEBUG_LEVEL_PCI
#endif
#include "util.h"
#include "debug.h"
#define PCI_MAX_DEVS 32
#define PCI_TAKE_ALL (-1)
struct ddekit_pci_dev {
int devind; /* thats how we identify the defice at the pci server */
ddekit_uint16_t vid; /* as we get them for */
/* free during iteration store them */
ddekit_uint16_t did;
int bus;
int slot; /* slot should equal index in dev array */
int func; /* don't support multiple functionalities yet -> 0 */
};
struct ddekit_pci_dev pci_devs[PCI_MAX_DEVS];
static struct ddekit_pci_dev * ddekit_get_dev_helper(int bus, int slot,
int func);
/****************************************************************************/
/* ddekit_pci_init_only_one */
/****************************************************************************/
void ddekit_pci_init_only_one(int skip)
{
/*
* If skip is not PCI_TAKE_ALL this function will skip skip PCI DEVICES
* and than only take on PCI device.
*/
int res, count, more, take_all = 0;
if (skip == -1) {
take_all = 1;
}
DDEBUG_MSG_INFO("Initializing PCI subsystem...");
pci_init();
/*
* Iterate the PCI-bus
*/
more = 1;
for (count = 0 ; count < PCI_MAX_DEVS ; count++) {
struct ddekit_pci_dev *d = &pci_devs[count];
if (more) {
if ( count==0 ) {
res = pci_first_dev(&d->devind, &d->vid, &d->did);
} else {
d->devind = pci_devs[count-1].devind;
res = pci_next_dev(&d->devind, &d->vid, &d->did);
}
if (res && d->devind!=0 && (take_all || skip == 0)) {
DDEBUG_MSG_VERBOSE("Found pci device: "
"(ind: %x, vid: %x, did: %x) "
"mapped to slot %x",
d->devind, d->vid, d->did, count);
d->slot = count;
d->bus = 0;
d->func = 0;
res = pci_reserve_ok(d->devind);
if (res != 0) {
ddekit_panic("ddekit_pci_init_only_one: "
"pci_reserve_ok failed (%d)\n",res);
}
} else {
/* no more PCI devices */
DDEBUG_MSG_VERBOSE("Found %d PCI devices.", count);
d->devind = -1;
more = 0;
} /*if (res) */
} else {
d->devind = -1;
}
if (!take_all) {
skip--;
}
}
}
/****************************************************************************/
/* ddekit_pci_get_device_id */
/****************************************************************************/
void ddekit_pci_init(void)
{
ddekit_pci_init_only_one(DDEKIT_PCI_ANY_ID);
}
/****************************************************************************/
/* ddekit_pci_get_device_id */
/****************************************************************************/
int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func)
{
if(nr >= 0 && nr < PCI_MAX_DEVS) {
*bus = 0;
*slot = nr;
*func =0;
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_get_device_id */
/****************************************************************************/
static struct ddekit_pci_dev *
ddekit_get_dev_helper(int bus, int slot, int func)
{
/*
* Used internally to look up devices.
* Should make it easier to support multiple buses somewhen
*/
struct ddekit_pci_dev * ret = 0;
if (slot >= 0 && slot < PCI_MAX_DEVS) {
ret = &pci_devs[slot];
}
if (ret->devind == -1) {
ret = 0;
}
return ret;
}
/****************************************************************************/
/* ddekit_pci_read */
/****************************************************************************/
int ddekit_pci_read
(int bus, int slot, int func, int pos, int len, ddekit_uint32_t *val)
{
switch(len) {
case 1:
return ddekit_pci_readb(bus, slot, func, pos,
(ddekit_uint8_t*) val);
case 2:
return ddekit_pci_readw(bus, slot, func, pos,
(ddekit_uint16_t*) val);
case 4:
return ddekit_pci_readl(bus, slot, func, pos, val);
default: return -1;
}
}
/****************************************************************************/
/* ddekit_pci_write */
/****************************************************************************/
int ddekit_pci_write
(int bus, int slot, int func, int pos, int len, ddekit_uint32_t val)
{
switch(len) {
case 1:
return ddekit_pci_writeb(bus, slot, func, pos,
(ddekit_uint8_t) val);
case 2:
return ddekit_pci_writew(bus, slot, func, pos,
(ddekit_uint16_t) val);
case 4:
return ddekit_pci_writel(bus, slot, func, pos, val);
default: return -1;
}
}
/****************************************************************************/
/* ddekit_pci_readb */
/****************************************************************************/
int ddekit_pci_readb (int bus, int slot, int func, int pos, ddekit_uint8_t *val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (func!=0) {
*val=0;
return 0;
}
if (dev) {
*val = pci_attr_r8 (dev->devind, pos);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
bus, slot, func, pos, *val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_readw */
/****************************************************************************/
int ddekit_pci_readw
(int bus, int slot, int func, int pos, ddekit_uint16_t *val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (func!=0) {
*val=0;
return 0;
}
if (dev) {
*val = pci_attr_r16 (dev->devind, pos);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
bus, slot, func, pos, *val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_readl */
/****************************************************************************/
int ddekit_pci_readl
(int bus, int slot, int func, int pos, ddekit_uint32_t *val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (func!=0) {
*val=0;
return 0;
}
if (dev) {
*val = pci_attr_r32 (dev->devind, pos);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
bus, slot, func, pos, *val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_writeb */
/****************************************************************************/
int ddekit_pci_writeb
(int bus, int slot, int func, int pos, ddekit_uint8_t val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (dev) {
pci_attr_w8 (dev->devind, pos, val);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
bus, slot, func, pos, val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_writel */
/****************************************************************************/
int ddekit_pci_writew
(int bus, int slot, int func, int pos, ddekit_uint16_t val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (dev) {
pci_attr_w16 (dev->devind, pos, val);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
bus,slot,func,pos, val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_writel */
/****************************************************************************/
int ddekit_pci_writel
(int bus, int slot, int func, int pos, ddekit_uint32_t val) {
struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
if (dev) {
pci_attr_w32 (dev->devind, pos, val);
DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",bus,slot,func,pos, val);
return 0;
}
return -1;
}
/****************************************************************************/
/* ddekit_pci_find_device */
/****************************************************************************/
struct ddekit_pci_dev *ddekit_pci_find_device
(int *bus, int *slot, int *func, struct ddekit_pci_dev *start)
{
int i,search=0;
if(start)
search = 1;
for(i=0; i < PCI_MAX_DEVS ; i++)
{
/* start searching? */
if (search)
search = (&pci_devs[i]==start);
else
{
struct ddekit_pci_dev * dev = &pci_devs[i];
if ((*slot==dev->slot || *slot == DDEKIT_PCI_ANY_ID)
&& (*func==dev->func || *func == DDEKIT_PCI_ANY_ID))
{
*bus = 0;
*slot = dev->slot;
*func = dev->func;
return dev;
}
}
}
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_vendor */
/****************************************************************************/
unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev)
{
return dev->vid;
}
/****************************************************************************/
/* ddekit_pci_get_device_id */
/****************************************************************************/
unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev)
{
return dev->did;
}
/*
* XXX: Those are neither used be DDEFBSD or DDELinux implement them
* when you need them
*/
/****************************************************************************/
/* ddekit_pci_enable_device */
/****************************************************************************/
int ddekit_pci_enable_device(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_disable_device */
/****************************************************************************/
int ddekit_pci_disable_device(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_set_master */
/****************************************************************************/
void ddekit_pci_set_master(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
}
/****************************************************************************/
/* ddekit_pci_get_sub_vendor */
/****************************************************************************/
unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_sub_device */
/****************************************************************************/
unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_dev_class */
/****************************************************************************/
unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_irq */
/****************************************************************************/
unsigned long
ddekit_pci_get_irq(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_name */
/****************************************************************************/
char *ddekit_pci_get_name(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_slot_name */
/****************************************************************************/
char *ddekit_pci_get_slot_name(struct ddekit_pci_dev *dev)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_get_resource */
/****************************************************************************/
ddekit_pci_res_t *
ddekit_pci_get_resource(struct ddekit_pci_dev *dev, unsigned int idx)
{
WARN_UNIMPL;
return 0;
}
/****************************************************************************/
/* ddekit_pci_irq_enable */
/****************************************************************************/
int ddekit_pci_irq_enable
(int bus, int slot, int func, int pin, int *irq)
{
/* call not needed */
#if 0
WARN_UNIMPL;
#endif
return 0;
}