Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 197 → Rev 198

/shark/trunk/drivers/pci/pci_scan.c
17,12 → 17,265
static struct pci_bus pci_root;
static struct pci_dev *pci_devices = NULL;
 
#if 0
/* scan the bus to find all the connected devices */
DWORD pci_scan_bus(struct pci_bus *bus)
{
int ndev;
DWORD tmp;
DWORD max;
DWORD max, class;
BYTE hdr;
int ok;
WORD dev;
struct pci_dev **bus_last;
struct pci_dev *device = NULL;
int present;
 
max = bus->secondary;
bus_last = &bus->devices;
 
if (pcibios_present() == 0) return -1;
ndev = 0;
 
for (dev = 0; dev <= 0xFF; dev++) {
present = 0;
if ((dev & 0x07) == 0) {
present = pcibios_read_config_byte(bus->number, dev, 0x0e, &hdr);
}
if (hdr & 0x80) {
present = 1;
}
if (present) {
ok = pcibios_read_config_dword(bus->number, dev, 0, &tmp);
if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) {
/* Got a PCI Device!!! */
device = &(pci_devs[ndev++]);
device->bus = bus;
device->devfn = dev;
device->vendor = tmp & 0xffff;
device->device = (tmp >> 16) & 0xffff;
 
/* PJ: non-destructively determine if device can be a master: */
pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &cmd);
pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &tmp);
dev->master = ((tmp & PCI_COMMAND_MASTER) != 0);
pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd);
 
/* This is by Luca... We need to set base_addr */
pcibios_read_config_dword(bus->number, dev, PCI_BASE_ADDRESS_0, &(device->base_address[0]));
 
 
 
pcibios_read_config_byte(bus->number, dev, PCI_INTERRUPT_LINE, &irq1);
device->irq = irq1;
pcibios_read_config_dword(bus->number, dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
//printk(KERN_INFO "pci_scan_bus: dev=%d, class=%ld", dev, class);
device->class = class;
class >>= 8;
device->hdr_type = hdr;
 
 
 
 
#if 0
switch (hdr & 0x7f) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
goto bad;
/*
* If the card generates interrupts, read IRQ number
* (some architectures change it during pcibios_fixup())
*/
pcibios_read_config_byte(bus->number, device->devfn, PCI_INTERRUPT_PIN, &irq1);
if (irq1)
pcibios_read_config_byte(bus->number, device->devfn, PCI_INTERRUPT_LINE, &irq1);
device->irq = irq1;
/*
* read base address registers, again pcibios_fixup() can
* tweak these
*/
pci_read_bases(device, 6);
pcibios_read_config_dword(bus->number, dev, PCI_ROM_ADDRESS, &l);
device->rom_address = (l == 0xffffffff) ? 0 : l;
break;
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
pci_read_bases(device, 2);
pcibios_read_config_dword(bus->number, dev, PCI_ROM_ADDRESS1, &l);
device->rom_address = (l == 0xffffffff) ? 0 : l;
break;
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
if (class != PCI_CLASS_BRIDGE_CARDBUS)
goto bad;
pci_read_bases(device, 1);
break;
default: /* unknown header */
bad:
printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
bus->number, device->devfn, device->vendor, device->device, class, hdr);
continue;
}
#endif
 
 
 
 
//printk(KERN_DEBUG "PCI: %02x:%02x [%04x/%04x]\n", bus->number, device->devfn, device->vendor, device->device);
 
device->next = pci_devices;
pci_devices = device;
 
/*
* Now insert it into the list of devices held
* by the parent bus.
*/
*bus_last = device;
bus_last = &device->sibling;
 
 
 
}
}
}
 
// PJ: PCI bridges not supported???
#if 0
for(device = bus->devices; device; device = device->sibling) {
/*
* If it's a bridge, scan the bus behind it.
*/
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
unsigned int buses;
unsigned int devfn = dev->devfn;
unsigned short cr;
 
/*
* Insert it into the tree of buses.
*/
child = kmalloc(sizeof(*child), GFP_ATOMIC);
if(child==NULL) {
#ifdef DEBUG_PCISCAN
printk(KERN_ERR "pci: out of memory for bridge.\n");
#endif
continue;
}
memset(child, 0, sizeof(*child));
child->next = bus->children;
bus->children = child;
child->self = dev;
child->parent = bus;
 
/*
* Set up the primary, secondary and subordinate
* bus numbers.
*/
child->number = child->secondary = ++max;
child->primary = bus->secondary;
child->subordinate = 0xff;
/*
* Clear all status bits and turn off memory,
* I/O and master enables.
*/
pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr);
pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000);
pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff);
/*
* Read the existing primary/secondary/subordinate bus
* number configuration to determine if the PCI bridge
* has already been configured by the system. If so,
* do not modify the configuration, merely note it.
*/
pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses);
if ((buses & 0xFFFFFF) != 0) {
unsigned int cmax;
 
child->primary = buses & 0xFF;
child->secondary = (buses >> 8) & 0xFF;
child->subordinate = (buses >> 16) & 0xFF;
child->number = child->secondary;
cmax = pci_scan_bus(child);
if (cmax > max) max = cmax;
} else {
/*
* Configure the bus numbers for this bridge:
*/
buses &= 0xff000000;
buses |= (((unsigned int)(child->primary) << 0) |
((unsigned int)(child->secondary) << 8) |
((unsigned int)(child->subordinate) << 16));
pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
/*
* Now we can scan all subordinate buses:
*/
max = pci_scan_bus(child);
/*
* Set the subordinate bus number to its real
* value:
*/
child->subordinate = max;
buses = (buses & 0xff00ffff)
| ((unsigned int)(child->subordinate) << 16);
pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
}
pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr);
}
}
#endif
return max;
}
 
 
#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* scan the bus to find all the connected devices */
DWORD pci_scan_bus(struct pci_bus *bus)
{
int ndev;
DWORD tmp;
DWORD max, class;
BYTE hdr, irq1;
int ok;
WORD dev;
63,13 → 316,13
pcibios_read_config_byte(bus->number, dev, PCI_INTERRUPT_LINE, &irq1);
device->irq = irq1;
#if 0
pcibios_read_config_dword(bus->number, devfn, PCI_CLASS_REVISION, &class);
pcibios_read_config_dword(bus->number, dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
dev->class = class;
device->class = class;
class >>= 8;
dev->hdr_type = hdr;
device->hdr_type = hdr;
 
#if 0
switch (hdr_type & 0x7f) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
273,3 → 526,25
cprintf("PCI_FIND_SLOT: found %p at bus %d\n", dev, dev->bus->number);
return dev;
}
 
 
void
pci_set_master(struct pci_dev *dev)
{
unsigned short cmd; // was: u16
unsigned char lat; // was: u8
 
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (! (cmd & PCI_COMMAND_MASTER)) {
printk("PCI: Enabling bus mastering for device %02x:%02x\n",
dev->bus->number, dev->devfn);
cmd |= PCI_COMMAND_MASTER;
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
if (lat < 16) {
printk("PCI: Increasing latency timer of device %02x:%02x to 64\n",
dev->bus->number, dev->devfn);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
}
}
/shark/trunk/drivers/pci/pci.c
132,8 → 132,8
r = (struct pci_regs *) pci_devs[i].mem;
printk(KERN_INFO "%d: bus %d dev %d\n",
i, pci_devs[i].bus, pci_devs[i].dev);
printk(KERN_INFO "Vendor: %s", pci_strvendor(r->VendorId));
printk(KERN_INFO "Class: %s\n", pci_strclass(r->ClassCode << 8));
printk(KERN_INFO "Vendor: %s Class: %s\n", pci_strvendor(r->VendorId),
pci_strclass(r->ClassCode << 8));
}
}